Minimized the test code

Also, modified the Completer interface to facilitate the minimization of the
test code.
This commit is contained in:
Strahinja Val Markovic 2012-05-07 22:10:28 -07:00
parent 6430677f4f
commit 0110611996
4 changed files with 117 additions and 141 deletions

View File

@ -53,14 +53,14 @@ void ThreadMain( TaskStack &task_stack )
} // unnamed namespace } // unnamed namespace
Completer::Completer( const Pylist &candidates ) Completer::Completer( const std::vector< std::string > &candidates )
: threading_enabled_( false ) : threading_enabled_( false )
{ {
AddCandidatesToDatabase( candidates, "", "" ); AddCandidatesToDatabase( candidates, "", "" );
} }
Completer::Completer( const Pylist &candidates, Completer::Completer( const std::vector< std::string > &candidates,
const std::string &filetype, const std::string &filetype,
const std::string &filepath ) const std::string &filepath )
: threading_enabled_( false ) : threading_enabled_( false )
@ -91,18 +91,35 @@ void Completer::EnableThreading()
void Completer::AddCandidatesToDatabase( const Pylist &new_candidates, void Completer::AddCandidatesToDatabase( const Pylist &new_candidates,
const std::string &filetype, const std::string &filetype,
const std::string &filepath ) const std::string &filepath )
{
int num_candidates = len( new_candidates );
std::vector< std::string > candidates;
candidates.reserve( num_candidates );
for (int i = 0; i < num_candidates; ++i)
{
candidates.push_back( extract< std::string >( new_candidates[ i ] ) );
}
AddCandidatesToDatabase( candidates, filetype, filepath );
}
void Completer::AddCandidatesToDatabase(
const std::vector< std::string > &new_candidates,
const std::string &filetype,
const std::string &filepath )
{ {
std::vector< Candidate *> &candidates = std::vector< Candidate *> &candidates =
GetCandidateVector( filetype, filepath ); GetCandidateVector( filetype, filepath );
int num_candidates = len( new_candidates ); int num_candidates = new_candidates.size();
candidates.clear(); candidates.clear();
candidates.reserve( num_candidates ); candidates.reserve( num_candidates );
std::string candidate_text;
for (int i = 0; i < num_candidates; ++i) for (int i = 0; i < num_candidates; ++i)
{ {
candidate_text = extract< std::string >( new_candidates[ i ] ); const std::string &candidate_text = new_candidates[ i ];
Candidate *&candidate = GetValueElseInsert( candidate_repository_, Candidate *&candidate = GetValueElseInsert( candidate_repository_,
candidate_text, NULL ); candidate_text, NULL );
if ( !candidate ) if ( !candidate )
@ -113,24 +130,26 @@ void Completer::AddCandidatesToDatabase( const Pylist &new_candidates,
} }
void Completer::CandidatesForQuery( const std::string &query, std::vector< std::string > Completer::CandidatesForQuery(
Pylist &candidates ) const const std::string &query ) const
{ {
CandidatesForQueryAndType( query, "", candidates ); return CandidatesForQueryAndType( query, "" );
} }
void Completer::CandidatesForQueryAndType( const std::string &query, std::vector< std::string > Completer::CandidatesForQueryAndType(
const std::string &filetype, const std::string &query,
Pylist &candidates ) const const std::string &filetype ) const
{ {
std::vector< Result > results; std::vector< Result > results;
ResultsForQueryAndType( query, filetype, results ); ResultsForQueryAndType( query, filetype, results );
std::vector< std::string > candidates;
foreach ( const Result& result, results ) foreach ( const Result& result, results )
{ {
candidates.append( *result.Text() ); candidates.push_back( *result.Text() );
} }
return candidates;
} }
@ -156,6 +175,7 @@ Future Completer::CandidatesForQueryAndTypeAsync(
return Future( move( future ) ); return Future( move( future ) );
} }
AsyncResults Completer::ResultsForQueryAndType( AsyncResults Completer::ResultsForQueryAndType(
const std::string &query, const std::string &query,
const std::string &filetype ) const const std::string &filetype ) const
@ -165,6 +185,7 @@ AsyncResults Completer::ResultsForQueryAndType(
return results; return results;
} }
void Completer::ResultsForQueryAndType( const std::string &query, void Completer::ResultsForQueryAndType( const std::string &query,
const std::string &filetype, const std::string &filetype,
std::vector< Result > &results ) const std::vector< Result > &results ) const

View File

@ -56,25 +56,30 @@ class Completer : boost::noncopyable
{ {
public: public:
Completer() {} Completer() {}
Completer( const Pylist &candidates ); Completer( const std::vector< std::string > &candidates );
Completer( const Pylist &candidates, Completer( const std::vector< std::string > &candidates,
const std::string &filetype, const std::string &filetype,
const std::string &filepath ); const std::string &filepath );
~Completer(); ~Completer();
void EnableThreading(); void EnableThreading();
void AddCandidatesToDatabase(
const std::vector< std::string > &new_candidates,
const std::string &filetype,
const std::string &filepath );
void AddCandidatesToDatabase( const Pylist &new_candidates, void AddCandidatesToDatabase( const Pylist &new_candidates,
const std::string &filetype, const std::string &filetype,
const std::string &filepath ); const std::string &filepath );
// Only provided for tests! // Only provided for tests!
void CandidatesForQuery( const std::string &query, std::vector< std::string > CandidatesForQuery(
Pylist &candidates ) const; const std::string &query ) const;
void CandidatesForQueryAndType( const std::string &query, std::vector< std::string > CandidatesForQueryAndType(
const std::string &filetype, const std::string &query,
Pylist &candidates ) const; const std::string &filetype ) const;
Future CandidatesForQueryAndTypeAsync( const std::string &query, Future CandidatesForQueryAndTypeAsync( const std::string &query,
const std::string &filetype ) const; const std::string &filetype ) const;

View File

@ -30,9 +30,14 @@ BOOST_PYTHON_MODULE(indexer)
.def( "ResultsReady", &Future::ResultsReady ) .def( "ResultsReady", &Future::ResultsReady )
.def( "GetResults", &Future::GetResults ); .def( "GetResults", &Future::GetResults );
void (Completer::*actd) (const Pylist&,
const std::string&,
const std::string&) =
&Completer::AddCandidatesToDatabase;
class_< Completer, boost::noncopyable >( "Completer" ) class_< Completer, boost::noncopyable >( "Completer" )
.def( "EnableThreading", &Completer::EnableThreading ) .def( "EnableThreading", &Completer::EnableThreading )
.def( "AddCandidatesToDatabase", &Completer::AddCandidatesToDatabase ) .def( "AddCandidatesToDatabase", actd )
.def( "CandidatesForQueryAndTypeAsync", .def( "CandidatesForQueryAndTypeAsync",
&Completer::CandidatesForQueryAndTypeAsync ); &Completer::CandidatesForQueryAndTypeAsync );
} }

View File

@ -30,189 +30,134 @@ namespace YouCompleteMe
namespace namespace
{ {
std::vector<std::string> ToStringVector( const boost::python::list &pylist ) std::vector< std::string > Candidates( const std::string &a,
const std::string &b = std::string(),
const std::string &c = std::string(),
const std::string &d = std::string(),
const std::string &e = std::string(),
const std::string &f = std::string(),
const std::string &g = std::string(),
const std::string &h = std::string(),
const std::string &i = std::string() )
{ {
std::vector<std::string> values; std::vector< std::string > candidates;
for (int i = 0; i < boost::python::len( pylist ); ++i) candidates.push_back( a );
{
values.push_back(
boost::python::extract< std::string >( pylist[ i ] ) );
}
return values;
}
Pylist Candidates( const std::string &a,
const std::string &b = std::string(),
const std::string &c = std::string(),
const std::string &d = std::string(),
const std::string &e = std::string(),
const std::string &f = std::string(),
const std::string &g = std::string(),
const std::string &h = std::string(),
const std::string &i = std::string() )
{
Pylist candidates;
candidates.append( a );
if ( !b.empty() ) if ( !b.empty() )
candidates.append( b ); candidates.push_back( b );
if ( !c.empty() ) if ( !c.empty() )
candidates.append( c ); candidates.push_back( c );
if ( !d.empty() ) if ( !d.empty() )
candidates.append( d ); candidates.push_back( d );
if ( !e.empty() ) if ( !e.empty() )
candidates.append( e ); candidates.push_back( e );
if ( !f.empty() ) if ( !f.empty() )
candidates.append( f ); candidates.push_back( f );
if ( !g.empty() ) if ( !g.empty() )
candidates.append( g ); candidates.push_back( g );
if ( !h.empty() ) if ( !h.empty() )
candidates.append( h ); candidates.push_back( h );
if ( !i.empty() ) if ( !i.empty() )
candidates.append( i ); candidates.push_back( i );
return candidates; return candidates;
} }
} // unnamed namespace } // unnamed namespace
class CompleterTest : public ::testing::Test
TEST( CompleterTest, OneCandidate )
{ {
protected: EXPECT_THAT( Completer( Candidates(
virtual void SetUp() "foobar" ) ).CandidatesForQuery( "fbr" ),
{ ElementsAre( "foobar" ) );
Py_Initialize();
}
};
TEST_F( CompleterTest, OneCandidate )
{
Pylist results;
Completer( Candidates( "foobar" ) ).CandidatesForQuery( "fbr", results );
EXPECT_THAT( ToStringVector( results ), ElementsAre( "foobar" ) );
} }
TEST_F( CompleterTest, ManyCandidateSimple ) TEST( CompleterTest, ManyCandidateSimple )
{ {
Pylist results; EXPECT_THAT( Completer( Candidates(
Completer( Candidates( "foobar",
"foobar", "foobartest",
"foobartest", "Foobartest" ) ).CandidatesForQuery( "fbr" ),
"Foobartest" ) ).CandidatesForQuery( "fbr", results );
EXPECT_THAT( ToStringVector( results ),
WhenSorted( ElementsAre( "Foobartest", WhenSorted( ElementsAre( "Foobartest",
"foobar", "foobar",
"foobartest" ) ) ); "foobartest" ) ) );
} }
TEST_F( CompleterTest, FirstCharSameAsQueryWins ) TEST( CompleterTest, FirstCharSameAsQueryWins )
{ {
Pylist results; EXPECT_THAT( Completer( Candidates(
Completer( Candidates( "foobar",
"foobar", "afoobar" ) ).CandidatesForQuery( "fbr" ),
"afoobar" ) ).CandidatesForQuery( "fbr", results );
EXPECT_THAT( ToStringVector( results ),
ElementsAre( "foobar", ElementsAre( "foobar",
"afoobar" ) ); "afoobar" ) );
} }
TEST_F( CompleterTest, CompleteMatchForWordBoundaryCharsWins ) TEST( CompleterTest, CompleteMatchForWordBoundaryCharsWins )
{ {
Pylist results; EXPECT_THAT( Completer( Candidates(
Completer( Candidates( "FooBarQux",
"FooBarQux", "FBaqux" ) ).CandidatesForQuery( "fbq" ),
"FBaqux" ) ).CandidatesForQuery( "fbq", results );
EXPECT_THAT( ToStringVector( results ),
ElementsAre( "FooBarQux", ElementsAre( "FooBarQux",
"FBaqux" ) ); "FBaqux" ) );
Pylist results2; EXPECT_THAT( Completer( Candidates(
Completer( Candidates( "CompleterTest",
"CompleterTest", "CompleteMatchForWordBoundaryCharsWins" ) )
"CompleteMatchForWordBoundaryCharsWins" .CandidatesForQuery( "ct" ),
) ).CandidatesForQuery( "ct", results2 );
EXPECT_THAT( ToStringVector( results2 ),
ElementsAre( "CompleterTest", ElementsAre( "CompleterTest",
"CompleteMatchForWordBoundaryCharsWins" ) ); "CompleteMatchForWordBoundaryCharsWins" ) );
Pylist results3; EXPECT_THAT( Completer( Candidates(
Completer( Candidates( "FooBar",
"FooBar", "FooBarRux" ) ).CandidatesForQuery( "fbr" ),
"FooBarRux" ) ).CandidatesForQuery( "fbr", results3 );
EXPECT_THAT( ToStringVector( results3 ),
ElementsAre( "FooBarRux", ElementsAre( "FooBarRux",
"FooBar" ) ); "FooBar" ) );
} }
TEST_F( CompleterTest, RatioUtilizationTieBreak ) TEST( CompleterTest, RatioUtilizationTieBreak )
{ {
Pylist results; EXPECT_THAT( Completer( Candidates(
Completer( Candidates( "FooBarQux",
"FooBarQux", "FooBarQuxZaa" ) ).CandidatesForQuery( "fbq" ),
"FooBarQuxZaa" ) ).CandidatesForQuery( "fbq", results );
EXPECT_THAT( ToStringVector( results ),
ElementsAre( "FooBarQux", ElementsAre( "FooBarQux",
"FooBarQuxZaa" ) ); "FooBarQuxZaa" ) );
Pylist results2; EXPECT_THAT( Completer( Candidates(
Completer( Candidates( "FooBar",
"FooBar", "FooBarRux" ) ).CandidatesForQuery( "fba" ),
"FooBarRux" ) ).CandidatesForQuery( "fba", results2 );
EXPECT_THAT( ToStringVector( results2 ),
ElementsAre( "FooBar", ElementsAre( "FooBar",
"FooBarRux" ) ); "FooBarRux" ) );
} }
TEST_F( CompleterTest, QueryPrefixOfCandidateWins ) TEST( CompleterTest, QueryPrefixOfCandidateWins )
{ {
Pylist results; EXPECT_THAT( Completer( Candidates(
Completer( Candidates( "foobar",
"foobar", "fbaroo" ) ).CandidatesForQuery( "foo" ),
"fbaroo" ) ).CandidatesForQuery( "foo", results );
EXPECT_THAT( ToStringVector( results ),
ElementsAre( "foobar", ElementsAre( "foobar",
"fbaroo" ) ); "fbaroo" ) );
} }
TEST_F( CompleterTest, ShorterCandidateWins ) TEST( CompleterTest, ShorterCandidateWins )
{ {
Pylist results; EXPECT_THAT( Completer( Candidates(
Completer( Candidates( "FooBarQux",
"FooBarQux", "FaBarQux" ) ).CandidatesForQuery( "fbq" ),
"FaBarQux" ) ).CandidatesForQuery( "fbq", results );
EXPECT_THAT( ToStringVector( results ),
ElementsAre( "FaBarQux", ElementsAre( "FaBarQux",
"FooBarQux" ) ); "FooBarQux" ) );
Pylist results2; EXPECT_THAT( Completer( Candidates(
Completer( Candidates( "CompleterT",
"CompleterT", "CompleterTest" ) ).CandidatesForQuery( "co" ),
"CompleterTest" ) ).CandidatesForQuery( "co", results2 );
EXPECT_THAT( ToStringVector( results2 ),
ElementsAre( "CompleterT", ElementsAre( "CompleterT",
"CompleterTest" ) ); "CompleterTest" ) );
} }
TEST_F( CompleterTest, SameLowercaseCandidateWins ) TEST( CompleterTest, SameLowercaseCandidateWins )
{ {
Pylist results; EXPECT_THAT( Completer( Candidates(
Completer( Candidates( "foobar",
"foobar", "Foobar" ) ).CandidatesForQuery( "foo" ),
"Foobar" ) ).CandidatesForQuery( "foo", results );
EXPECT_THAT( ToStringVector( results ),
ElementsAre( "foobar", ElementsAre( "foobar",
"Foobar" ) ); "Foobar" ) );
} }