diff --git a/src/unity.c b/src/unity.c index b9c5c3bf2c5da2c4fdcb1b2d78562abe714e97bc..c0323f62866300e300d14c731b1eab38c7039db7 100644 --- a/src/unity.c +++ b/src/unity.c @@ -1323,8 +1323,10 @@ int UnityParseOptions(int argc, char** argv) case 'l': /* list tests */ return -1; case 'n': /* include tests with name including this string */ - i++; - if (i < argc) + case 'f': /* an alias for -n */ + if (argv[i][2] == '=') + UnityOptionIncludeNamed = &argv[i][3]; + else if (++i < argc) UnityOptionIncludeNamed = argv[i]; else { @@ -1340,8 +1342,9 @@ int UnityParseOptions(int argc, char** argv) UnityVerbosity = 2; break; case 'x': /* exclude tests with name including this string */ - i++; - if (i < argc) + if (argv[i][2] == '=') + UnityOptionExcludeNamed = &argv[i][3]; + else if (++i < argc) UnityOptionExcludeNamed = argv[i]; else { @@ -1381,6 +1384,14 @@ int IsStringInBiggerString(const char* longstring, const char* shortstring) /* We're done if we match the entire string or up to a wildcard */ if (*sptr == '*') return 1; + if (*sptr == ',') + return 1; + if (*sptr == '"') + return 1; + if (*sptr == '\'') + return 1; + if (*sptr == ':') + return 2; if (*sptr == 0) return 1; } @@ -1394,12 +1405,46 @@ int IsStringInBiggerString(const char* longstring, const char* shortstring) int UnityStringArgumentMatches(const char* str) { - if (IsStringInBiggerString(Unity.TestFile, str)) - return 1; - else if (IsStringInBiggerString(Unity.CurrentTestName, str)) - return 1; - else - return 0; + int retval; + const char* ptr1; + const char* ptr2; + + //Go through the options and get the substrings for matching one at a time + ptr1 = str; + while (ptr1[0] != 0) + { + if ((ptr1[0] == '"') || (ptr1[0] == '\'')) + ptr1++; + + //look for the start of the next partial + ptr2 = ptr1; + do { + ptr2++; + } while ((ptr2[0] != 0) && (ptr2[0] != ':') && (ptr2[0] != '\'') && (ptr2[0] != '"') && (ptr2[0] != ',')); + while ((ptr2[0] == ':') || (ptr2[0] == '\'') || (ptr2[0] == '"') || (ptr2[0] == ',')) + ptr2++; + + //done if complete filename match + retval = IsStringInBiggerString(Unity.TestFile, ptr1); + if (retval == 1) + return retval; + + //done if testname match after filename partial match + if (retval == 2) + { + if (IsStringInBiggerString(Unity.CurrentTestName, ptr2)) + return 1; + } + + //done if complete testname match + if (IsStringInBiggerString(Unity.CurrentTestName, ptr1) == 1) + return 1; + + ptr1 = ptr2; + } + + //we couldn't find a match for any substrings + return 0; } int UnityTestMatches(void) diff --git a/test/tests/test_generate_test_runner.rb b/test/tests/test_generate_test_runner.rb index fff7cdb30b860f8de01fbbd9210cc99c07cc4ad8..902b79aade8a0c709b30fe1f34bf31247d39f399 100644 --- a/test/tests/test_generate_test_runner.rb +++ b/test/tests/test_generate_test_runner.rb @@ -756,6 +756,24 @@ RUNNER_TESTS = [ } }, + { :name => 'ArgsNameFilterTestAndShould', + :testfile => 'testdata/testRunnerGenerator.c', + :testdefines => ['TEST', 'UNITY_USE_COMMAND_LINE_ARGS'], + :options => { + :cmdline_args => true, + }, + :cmdline_args => "-n should_,test_", + :expected => { + :to_pass => [ 'test_ThisTestAlwaysPasses', + 'test_NotBeConfusedByLongComplicatedStrings', + 'test_NotDisappearJustBecauseTheTestBeforeAndAfterHaveCrazyStrings', + 'test_StillNotBeConfusedByLongComplicatedStrings', + 'should_RunTestsStartingWithShouldByDefault' ], + :to_fail => [ 'test_ThisTestAlwaysFails' ], + :to_ignore => [ 'test_ThisTestAlwaysIgnored' ], + } + }, + { :name => 'ArgsExcludeFilterJustTest', :testfile => 'testdata/testRunnerGenerator.c', :testdefines => ['TEST', 'UNITY_USE_COMMAND_LINE_ARGS'], @@ -807,6 +825,76 @@ RUNNER_TESTS = [ } }, + { :name => 'ArgsIncludeSingleTestInSpecificFile', + :testfile => 'testdata/testRunnerGenerator.c', + :testdefines => ['TEST', 'UNITY_USE_COMMAND_LINE_ARGS'], + :options => { + :cmdline_args => true, + }, + :cmdline_args => "-n testRunnerGenerator:ThisTestAlwaysPasses", + :expected => { + :to_pass => [ 'test_ThisTestAlwaysPasses' ], + :to_fail => [ ], + :to_ignore => [ ], + } + }, + + { :name => 'ArgsIncludeTestFileWithExtension', + :testfile => 'testdata/testRunnerGenerator.c', + :testdefines => ['TEST', 'UNITY_USE_COMMAND_LINE_ARGS'], + :options => { + :cmdline_args => true, + }, + :cmdline_args => "-n testRunnerGenerator.c:ThisTestAlwaysPasses", + :expected => { + :to_pass => [ 'test_ThisTestAlwaysPasses' ], + :to_fail => [ ], + :to_ignore => [ ], + } + }, + + { :name => 'ArgsIncludeDoubleQuotes', + :testfile => 'testdata/testRunnerGenerator.c', + :testdefines => ['TEST', 'UNITY_USE_COMMAND_LINE_ARGS'], + :options => { + :cmdline_args => true, + }, + :cmdline_args => "-n \"testRunnerGenerator:ThisTestAlwaysPasses,test_ThisTestAlwaysFails\"", + :expected => { + :to_pass => [ 'test_ThisTestAlwaysPasses' ], + :to_fail => [ 'test_ThisTestAlwaysFails' ], + :to_ignore => [ ], + } + }, + + { :name => 'ArgsIncludeSingleQuotes', + :testfile => 'testdata/testRunnerGenerator.c', + :testdefines => ['TEST', 'UNITY_USE_COMMAND_LINE_ARGS'], + :options => { + :cmdline_args => true, + }, + :cmdline_args => "-n 'testRunnerGenerator:ThisTestAlwaysPasses,test_ThisTestAlwaysFails'", + :expected => { + :to_pass => [ 'test_ThisTestAlwaysPasses' ], + :to_fail => [ 'test_ThisTestAlwaysFails' ], + :to_ignore => [ ], + } + }, + + { :name => 'ArgsIncludeAValidTestForADifferentFile', + :testfile => 'testdata/testRunnerGenerator.c', + :testdefines => ['TEST', 'UNITY_USE_COMMAND_LINE_ARGS'], + :options => { + :cmdline_args => true, + }, + :cmdline_args => "-n AnotherFile:ThisTestDoesNotExist", + :expected => { + :to_pass => [ ], + :to_fail => [ ], + :to_ignore => [ ], + } + }, + { :name => 'ArgsIncludeNoTests', :testfile => 'testdata/testRunnerGenerator.c', :testdefines => ['TEST', 'UNITY_USE_COMMAND_LINE_ARGS'], @@ -857,6 +945,20 @@ RUNNER_TESTS = [ } }, + { :name => 'ArgsIncludeWithAlternateFlag', + :testfile => 'testdata/testRunnerGenerator.c', + :testdefines => ['TEST', 'UNITY_USE_COMMAND_LINE_ARGS'], + :options => { + :cmdline_args => true, + }, + :cmdline_args => "-f=\"testRunnerGenerator:ThisTestAlwaysPasses,test_ThisTestAlwaysFails\"", + :expected => { + :to_pass => [ 'test_ThisTestAlwaysPasses' ], + :to_fail => [ 'test_ThisTestAlwaysFails' ], + :to_ignore => [ ], + } + }, + { :name => 'ArgsIncludeWithParameterized', :testfile => 'testdata/testRunnerGenerator.c', :testdefines => ['TEST', 'UNITY_USE_COMMAND_LINE_ARGS'],