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(TagCacheSearchFixtureClass, ExactTags) { wxString code = wxT("<?php class ActionYou { function w() {} }"); CreateSubDirectory(wxT("src")); CreateFixtureFile(wxT("src") + wxString(wxFileName::GetPathSeparator()) + wxT("file1.php"), code); t4p::TagFinderListClass* cache = CreateTagFinderList(wxT("src")); TagCache.RegisterGlobal(cache); // empty means search all dirs std::vector<wxFileName> searchDirs; t4p::TagResultClass* result = TagCache.ExactTags(UNICODE_STRING_SIMPLE("ActionYou"), searchDirs); CHECK(result); if (!result) { return; } CHECK(result->More()); result->Next(); CHECK_UNISTR_EQUALS("ActionYou", result->Tag.Identifier); CHECK_UNISTR_EQUALS("ActionYou", result->Tag.ClassName); CHECK_EQUAL(false, result->More()); // do this now so that we dont use the inherited Session delete result; }
TEST_FIXTURE(MysqlResourceFinderFixtureClass, FindColumnsCaseInsensitive) { 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("idiservice")); CHECK_VECTOR_SIZE(2, columns); CHECK_UNISTR_EQUALS("idIServiceLocation", columns[0]); CHECK_UNISTR_EQUALS("idIServiceName", columns[1]); }
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(ExpressionCompletionMatchesFixtureClass, TagMatchesWithTagFinderList) { // in this test we will create a class in file2; file1 will use that class // the ResourceUpdate object should be able to detect the variable type of // the variable in file1 Code1 = UNICODE_STRING_SIMPLE("<?php $action = new ActionYou(); $action->w(); "); GlobalCode = wxT("<?php class ActionYou { function w() {} }"); 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("w")); TagCache.ResourceMatches(File1, ParsedVariable, Scope, SourceDirs, TagMatches, DoDuckTyping, DoFullyQualifiedMatchOnly, Error); CHECK_VECTOR_SIZE(1, TagMatches); CHECK_UNISTR_EQUALS("w", TagMatches[0].Identifier); CHECK_UNISTR_EQUALS("ActionYou", TagMatches[0].ClassName); }
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(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, 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(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(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, 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); }