TEST_FIXTURE(MysqlResourceFinderFixtureClass, FindColumns) { std::string query = "CREATE TABLE web_users(idIUser int);"; CHECK(DatabaseTestFixtureClass::Exec(query)); query = "CREATE TABLE service_names(idIServiceName int);"; CHECK(DatabaseTestFixtureClass::Exec(query)); query = "CREATE TABLE service_locations(idIServiceLocation int);"; CHECK(DatabaseTestFixtureClass::Exec(query)); query = "CREATE TABLE deleted_users(idIUser int, idIDeletedBy int);"; CHECK(DatabaseTestFixtureClass::Exec(query)); UnicodeString error; CHECK(Fetcher.Fetch(DatabaseTag, error)); std::vector<UnicodeString> columns = Finder.FindColumns(DatabaseTag, UNICODE_STRING_SIMPLE("idIServiceL")); CHECK_VECTOR_SIZE(1, columns); CHECK_UNISTR_EQUALS_NO_CASE("idIServiceLocation", columns[0]); columns = Finder.FindColumns(DatabaseTag, UNICODE_STRING_SIMPLE("idI")); CHECK_VECTOR_SIZE(4, columns); CHECK_UNISTR_EQUALS_NO_CASE("idIDeletedBy", columns[0]); CHECK_UNISTR_EQUALS_NO_CASE("idIServiceLocation", columns[1]); CHECK_UNISTR_EQUALS_NO_CASE("idIServiceName", columns[2]); CHECK_UNISTR_EQUALS_NO_CASE("idIUser", columns[3]); }
TEST_FIXTURE(ExpressionCompletionMatchesFixtureClass, TagMatchesWithStaleMatches) { // create a class in global file with methodA // file2 will use the class from global file; file2 will be registered // then global file will be registered with file2 (invalidating methodA) // perform a search // methodA should not be a hit since it has been removed GlobalCode = wxT("<?php class ActionMy { function methodA() {} }"); Code1 = UNICODE_STRING_SIMPLE("<?php $action = new ActionMy(); "); Code2 = UNICODE_STRING_SIMPLE("<?php class ActionMy { function methodB() {} }"); CreateFixtureFile(GlobalFile, GlobalCode); t4p::WorkingCacheClass* cache1 = CreateWorkingCache(File1, Code1); t4p::TagFinderListClass* cache2 = CreateTagFinderList(wxT("src")); CHECK(TagCache.RegisterWorking(File1, cache1)); TagCache.RegisterGlobal(cache2); ToProperty(UNICODE_STRING_SIMPLE("$action"), UNICODE_STRING_SIMPLE("methodA")); TagCache.ResourceMatches(File1, ParsedVariable, Scope, SourceDirs, TagMatches, DoDuckTyping, DoFullyQualifiedMatchOnly, Error); CHECK_VECTOR_SIZE(1, TagMatches); CHECK_UNISTR_EQUALS("methodA", TagMatches[0].Identifier); CHECK_UNISTR_EQUALS("ActionMy", TagMatches[0].ClassName); // now update the code by creating a working version of the global code. // ie. the user opening a file. t4p::WorkingCacheClass* cache3 = CreateWorkingCache(GlobalFile, Code2); CHECK(TagCache.RegisterWorking(GlobalFile, cache3)); TagMatches.clear(); TagCache.ResourceMatches(GlobalFile, ParsedVariable, Scope, SourceDirs, TagMatches, DoDuckTyping, DoFullyQualifiedMatchOnly, Error); CHECK_VECTOR_SIZE(0, TagMatches); }
TEST_FIXTURE(MysqlResourceFinderFixtureClass, FindTableShouldLocateInformationSchema) { UnicodeString error; CHECK(Fetcher.Fetch(DatabaseTag, error)); std::vector<UnicodeString> tables = Finder.FindTables(DatabaseTag, UNICODE_STRING_SIMPLE("information_sche")); CHECK_VECTOR_SIZE(1, tables); CHECK_UNISTR_EQUALS_NO_CASE("information_schema", tables[0]); tables = Finder.FindTables(DatabaseTag, UNICODE_STRING_SIMPLE("colum")); CHECK_VECTOR_SIZE(2, tables); CHECK_UNISTR_EQUALS_NO_CASE("column_privileges", tables[0]); CHECK_UNISTR_EQUALS_NO_CASE("columns", tables[1]); }
TEST_FIXTURE(DatabaseTagTestFixtureClass, ConnectQueryAndResults) { Exec("CREATE TABLE names (id INT, name VARCHAR(255));"); // without the explicit transaction, this test fails on // ubuntu 12.04 and mysql 5.5 Exec("BEGIN"); Exec("INSERT INTO names(id, name) VALUES(1, 'one')"); Exec("INSERT INTO names(id, name) VALUES(2, 'two')"); Exec("INSERT INTO names(id, name) VALUES(3, 'three')"); Exec("COMMIT"); soci::session session; t4p::SqlQueryClass query; UnicodeString error; query.DatabaseTag.Copy(DatabaseTag); CHECK(query.Connect(session, error)); CHECK_EQUAL(0, error.length()); t4p::SqlResultClass results; CHECK(query.Execute(session, results, UNICODE_STRING_SIMPLE("SELECT * FROM names ORDER BY id;"))); CHECK_EQUAL(0, results.Error.length()); CHECK(results.Success); CHECK_EQUAL(3, results.AffectedRows); CHECK_EQUAL(0, error.length()); CHECK_VECTOR_SIZE(3, results.StringResults); CHECK_UNISTR_EQUALS("1", results.StringResults[0][0]); CHECK_UNISTR_EQUALS("one", results.StringResults[0][1]); CHECK_UNISTR_EQUALS("2", results.StringResults[1][0]); CHECK_UNISTR_EQUALS("two", results.StringResults[1][1]); CHECK_UNISTR_EQUALS("3", results.StringResults[2][0]); CHECK_UNISTR_EQUALS("three", results.StringResults[2][1]); }
TEST_FIXTURE(MysqlResourceFinderFixtureClass, FindDatabaseTagrmationSchemaColumns) { UnicodeString error; CHECK(Fetcher.Fetch(DatabaseTag, error)); std::vector<UnicodeString> columns = Finder.FindColumns(DatabaseTag, UNICODE_STRING_SIMPLE("table_nam")); CHECK_VECTOR_SIZE(1, columns); CHECK_UNISTR_EQUALS_NO_CASE("table_name", columns[0]); }
TEST_FIXTURE(PhpFunctionCallLintTestFixtureClass, NativeFunctionArgumentMissing) { UnicodeString code = t4p::CharToIcu( "<?php\n" "stripos('123 today is');\n"); Parse(code); CHECK_EQUAL(true, HasError); CHECK_VECTOR_SIZE(1, Results); CHECK_EQUAL(t4p::PhpFunctionCallLintResultClass::TOO_FEW_ARGS, Results[0].Type); CHECK_UNISTR_EQUALS("stripos", Results[0].Identifier); CHECK_EQUAL(2, Results[0].ExpectedCount); CHECK_EQUAL(1, Results[0].ActualCount); }
TEST_FIXTURE(PhpFunctionCallLintTestFixtureClass, FunctionArgumentTooMany) { UnicodeString code = t4p::CharToIcu( "<?php\n" "function myFunc($a) {\n" "}\n" "myFunc('123', 888);\n"); Parse(code); CHECK_EQUAL(true, HasError); CHECK_VECTOR_SIZE(1, Results); CHECK_EQUAL(t4p::PhpFunctionCallLintResultClass::TOO_MANY_ARGS, Results[0].Type); CHECK_EQUAL(1, Results[0].ExpectedCount); CHECK_EQUAL(2, Results[0].ActualCount); }
TEST_FIXTURE(Parser55FeaturesTestClass, ParserTernaryWithDefault) { Parser.SetClassObserver(&Observer); UnicodeString code = _U( "<?php\n" "class MyClass {\n" " function stop($name) {\n" " $this->name = $name ?: new MyClass(); \n" " }\n" "}\n" ); CHECK(Parser.ScanString(code, LintResults)); CHECK_VECTOR_SIZE(1, Observer.ClassName); CHECK_UNISTR_EQUALS("MyClass", Observer.ClassName[0]); }
TEST_FIXTURE(PhpFunctionCallLintTestFixtureClass, FunctionArgumentMissing) { UnicodeString code = t4p::CharToIcu( "<?php\n" "function myFunc($a) {\n" "}\n" "myFunc();\n"); Parse(code); CHECK_EQUAL(true, HasError); CHECK_VECTOR_SIZE(1, Results); CHECK_EQUAL(t4p::PhpFunctionCallLintResultClass::TOO_FEW_ARGS, Results[0].Type); CHECK_UNISTR_EQUALS("myFunc", Results[0].Identifier); CHECK_EQUAL(1, Results[0].ExpectedCount); CHECK_EQUAL(0, Results[0].ActualCount); }
TEST_FIXTURE(SqliteResourceFinderFixtureClass, FindTable) { std::string query = "CREATE TABLE web_users(idUser int);"; CHECK(ExecIntoTest(query)); query = "CREATE TABLE service_names(idServiceName int);"; CHECK(ExecIntoTest(query)); query = "CREATE TABLE service_locations(idServiceLocation int);"; CHECK(ExecIntoTest(query)); query = "CREATE TABLE deleted_users(idUser int, deletedDate datetime);"; CHECK(ExecIntoTest(query)); UnicodeString error; CHECK(Fetcher.Fetch(DatabaseTag, error)); std::vector<UnicodeString> tables = Finder.FindTables(DatabaseTag, UNICODE_STRING_SIMPLE("service")); CHECK_VECTOR_SIZE(2, tables); CHECK_UNISTR_EQUALS_NO_CASE("service_locations", tables[0]); CHECK_UNISTR_EQUALS_NO_CASE("service_names", tables[1]); }
TEST_FIXTURE(Parser55FeaturesTestClass, ParserClassStaticIndirectVariable) { Parser.SetClassObserver(&Observer); Parser.SetClassMemberObserver(&Observer); Parser.SetVariableObserver(&Observer); UnicodeString code = _U( "<?php\n" "class MyClass {\n" " function stop() {\n" " $this::$appname = null;\n" " }\n" "}\n" ); CHECK(Parser.ScanString(code, LintResults)); // not capturing indirect variables for now CHECK_VECTOR_SIZE(0, Observer.VariableExpressions); }
TEST_FIXTURE(PhpFunctionCallLintTestFixtureClass, MethodArgumentMissing) { UnicodeString code = t4p::CharToIcu( "<?php\n" "class MyClass {\n" " function myFunc($a, $b, $c) {\n" " }\n" "}\n" "$obj = new MyClass();\n" "$obj->myFunc('123', '0000');\n"); Parse(code); CHECK_EQUAL(true, HasError); CHECK_VECTOR_SIZE(1, Results); CHECK_EQUAL(t4p::PhpFunctionCallLintResultClass::TOO_FEW_ARGS, Results[0].Type); CHECK_UNISTR_EQUALS("myFunc", Results[0].Identifier); CHECK_EQUAL(3, Results[0].ExpectedCount); CHECK_EQUAL(2, Results[0].ActualCount); }
TEST_FIXTURE(Parser55FeaturesTestClass, ParserListInForeach) { Parser.SetClassObserver(&Observer); Parser.SetClassMemberObserver(&Observer); Parser.SetVariableObserver(&Observer); UnicodeString code = _U( "<?php\n" "$array = [2, 5];\n" "foreach ($array as list($a, $b)) {\n" " echo \"A: $a; B: $b\n\";\n" "}\n" ); CHECK(Parser.ScanString(code, LintResults)); // not capturing indirect variables for now CHECK_VECTOR_SIZE(3, Observer.VariableName); CHECK_UNISTR_EQUALS("$array", Observer.VariableName[0]); CHECK_UNISTR_EQUALS("$a", Observer.VariableName[1]); CHECK_UNISTR_EQUALS("$b", Observer.VariableName[2]); }
TEST_FIXTURE(DatabaseTagTestFixtureClass, MultipleQueries) { Exec("CREATE TABLE names (id INT, name VARCHAR(255));"); Exec("CREATE TABLE places (id INT, name VARCHAR(255));"); // without the explicit transaction, this test fails on // ubuntu 12.04 and mysql 5.5 Exec("BEGIN"); Exec("INSERT INTO names(id, name) VALUES(1, 'one')"); Exec("INSERT INTO names(id, name) VALUES(2, 'two')"); Exec("INSERT INTO names(id, name) VALUES(3, 'three')"); Exec("COMMIT"); soci::session session; t4p::SqlQueryClass query; UnicodeString error; query.DatabaseTag.Copy(DatabaseTag); CHECK(query.Connect(session, error)); CHECK_EQUAL(0, error.length()); t4p::SqlResultClass results; CHECK(query.Execute(session, results, UNICODE_STRING_SIMPLE("DELETE FROM places;"))); CHECK_EQUAL(0, results.Error.length()); CHECK(results.Success); CHECK_EQUAL(false, results.HasRows); results.Close(); t4p::SqlResultClass results2; CHECK(query.Execute(session, results2, UNICODE_STRING_SIMPLE("SELECT * FROM names ORDER BY id;"))); CHECK_EQUAL(0, results2.Error.length()); CHECK(results2.Success); CHECK_VECTOR_SIZE(3, results2.StringResults); CHECK_EQUAL(3, results2.AffectedRows); results2.Close(); t4p::SqlResultClass results3; CHECK(query.Execute(session, results3, UNICODE_STRING_SIMPLE("DELETE FROM names;"))); CHECK_EQUAL(0, results3.Error.length()); CHECK(results3.Success); CHECK_EQUAL(false, results3.HasRows); results3.Close(); }
TEST_FIXTURE(ExpressionCompletionMatchesFixtureClass, CompletionMatchesWithTagFinderList) { // in this test we will create a class in file1; file2 will use that class // the TagCache object should be able to detect the variable type of // the variable in file2 wxString code1 = wxT("<?php class ActionYou { function w() {} }"); Code2 = UNICODE_STRING_SIMPLE("<?php $action = new ActionYou(); $action->w(); "); CreateFixtureFile(File1, code1); t4p::WorkingCacheClass* cache1 = CreateWorkingCache(File2, Code2); t4p::TagFinderListClass* cache2 = CreateTagFinderList(wxT("src")); CHECK(TagCache.RegisterWorking(File2, cache1)); TagCache.RegisterGlobal(cache2); ToProperty(UNICODE_STRING_SIMPLE("$action"), UNICODE_STRING_SIMPLE("w")); TagCache.ExpressionCompletionMatches(File2, ParsedVariable, Scope, SourceDirs, VariableMatches, TagMatches, DoDuckTyping, Error); CHECK_VECTOR_SIZE(1, TagMatches); CHECK_UNISTR_EQUALS("w", TagMatches[0].Identifier); }
TEST_FIXTURE(MysqlResourceFinderFixtureClass, FindTableCaseInsensitive) { std::string query = "SHOW VARIABLES WHERE Variable_name='version_compile_os' AND Value IN('Win64', 'Win32');"; if (DatabaseTestFixtureClass::Exec(query)) { // skip this test on windows, MySQL always creates tables with lowercase names return; } query = "CREATE TABLE WebUsers(idUser int);"; CHECK(DatabaseTestFixtureClass::Exec(query)); query = "CREATE TABLE ServiceNames(idServiceName int);"; CHECK(DatabaseTestFixtureClass::Exec(query)); query = "CREATE TABLE ServiceLocations(idServiceLocation int);"; CHECK(DatabaseTestFixtureClass::Exec(query)); query = "CREATE TABLE Deleted_Users(idUser int, deletedDate datetime);"; CHECK(DatabaseTestFixtureClass::Exec(query)); UnicodeString error; CHECK(Fetcher.Fetch(DatabaseTag, error)); std::vector<UnicodeString> tables = Finder.FindTables(DatabaseTag, UNICODE_STRING_SIMPLE("service")); CHECK_VECTOR_SIZE(2, tables); CHECK_UNISTR_EQUALS("ServiceLocations", tables[0]); CHECK_UNISTR_EQUALS("ServiceNames", tables[1]); }
TEST_FIXTURE(UrlTagFixtureClass, FilterUrl) { std::vector<t4p::UrlTagClass> urls; Finder.FilterUrls(wxT("front"), SourceDirs, urls); CHECK_VECTOR_SIZE(1, urls); CHECK_EQUAL(wxT("http://localhost/frontend.php"), urls[0].Url.BuildURI()); }
TEST_FIXTURE(UrlTagFixtureClass, FilterUrlNoMatches) { std::vector<t4p::UrlTagClass> urls; Finder.FilterUrls(wxT("back"), SourceDirs, urls); CHECK_VECTOR_SIZE(0, urls); }