Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/UnityChangeLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ Significant Bugfixes:

- Default `UNITY_INCLUDE_EXEC_TIME` macros compile as ISO C99, are statement-safe, and accept `-Wsign-conversion` (#838)
- `unity_test_summary.rb` honors its own default result directory and root path again. @youdie006
- Test name filters (`-f`, `-n`, `-x`) no longer split at a comma inside parentheses, so parameterized tests like `test_first(0,0)` can be selected (#779) @jadhavgaurav

### Unity 2.7.0 (July 2026)

Expand Down
3 changes: 3 additions & 0 deletions docs/UnityHelperScriptsGuide.md
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,9 @@ These are the available options:
| `-v` | increase Verbosity |
| `-x NAME` | eXclude tests whose name includes NAME |

Several names can be given as a comma-separated list. A comma inside parentheses is
part of the name, so `-f "test_first(0,0)"` selects one parameterized test case.

##### `:setup_name`

Override the default test `setUp` function name.
Expand Down
29 changes: 28 additions & 1 deletion src/unity.c
Original file line number Diff line number Diff line change
Expand Up @@ -2706,6 +2706,7 @@ static int IsStringInBiggerString(const char* longstring, const char* shortstrin
const char* lptr = longstring;
const char* sptr = shortstring;
const char* lnext = lptr;
int depth = 0; /* parenthesis nesting inside the match string; a comma only ends a match at depth 0 */

if (*sptr == '*')
{
Expand All @@ -2719,9 +2720,24 @@ static int IsStringInBiggerString(const char* longstring, const char* shortstrin
/* If they current bytes match, go on to the next bytes */
while (*lptr && *sptr && (*lptr == *sptr))
{
if (*sptr == '(')
{
depth++;
}
else if ((*sptr == ')') && (depth > 0))
{
depth--;
}

lptr++;
sptr++;

/* a comma inside parentheses belongs to the name, e.g. test_foo(1,2) */
if ((*sptr == ',') && (depth > 0))
{
continue;
}

switch (*sptr)
{
case '*': /* we encountered a wild-card */
Expand Down Expand Up @@ -2750,6 +2766,7 @@ static int IsStringInBiggerString(const char* longstring, const char* shortstrin
/* Otherwise we start in the long pointer 1 character further and try again */
lptr = lnext;
sptr = shortstring;
depth = 0;
}

return 0;
Expand All @@ -2762,6 +2779,7 @@ static int UnityStringArgumentMatches(const char* str)
const char* ptr1;
const char* ptr2;
const char* ptrf;
int depth; /* parenthesis nesting; commas inside parentheses do not separate filters */

/* Go through the options and get the substrings for matching one at a time */
ptr1 = str;
Expand All @@ -2775,14 +2793,23 @@ static int UnityStringArgumentMatches(const char* str)
/* look for the start of the next partial */
ptr2 = ptr1;
ptrf = 0;
depth = (ptr1[0] == '(') ? 1 : 0;
do
{
ptr2++;
if (ptr2[0] == '(')
{
depth++;
}
else if ((ptr2[0] == ')') && (depth > 0))
{
depth--;
}
if ((ptr2[0] == ':') && (ptr2[1] != 0) && (ptr2[0] != '\'') && (ptr2[0] != '"') && (ptr2[0] != ','))
{
ptrf = &ptr2[1];
}
} while ((ptr2[0] != 0) && (ptr2[0] != '\'') && (ptr2[0] != '"') && (ptr2[0] != ','));
} while ((ptr2[0] != 0) && (ptr2[0] != '\'') && (ptr2[0] != '"') && ((ptr2[0] != ',') || (depth > 0)));

while ((ptr2[0] != 0) && ((ptr2[0] == ':') || (ptr2[0] == '\'') || (ptr2[0] == '"') || (ptr2[0] == ',')))
{
Expand Down
34 changes: 34 additions & 0 deletions test/testdata/testRunnerGeneratorParameterizedArgs.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/* =========================================================================
Unity - A Test Framework for C
ThrowTheSwitch.org
Copyright (c) 2007-26 Mike Karlesky, Mark VanderVoord, & Greg Williams
SPDX-License-Identifier: MIT
========================================================================= */

/* This Test File Is Used To Verify Name Filters Applied To Parameterized Tests With More Than One Argument */

#include "unity.h"

void setUp(void) {}
void tearDown(void) {}

TEST_CASE(0,0)
TEST_CASE(1,1)
TEST_CASE(10,10)
void paratest_First(int a, int b)
{
TEST_ASSERT_EQUAL_INT(a, b);
}

TEST_CASE(0,0)
TEST_CASE(2,2)
TEST_CASE(20,20)
void paratest_Second(int a, int b)
{
TEST_ASSERT_EQUAL_INT(a, b);
}

void paratest_Plain(void)
{
TEST_PASS();
}
100 changes: 100 additions & 0 deletions test/tests/test_generate_test_runner.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1119,6 +1119,106 @@
}
},

{ :name => 'ArgsIncludeParameterizedWithComma',
:testfile => 'testdata/testRunnerGeneratorParameterizedArgs.c',
:testdefines => ['TEST', 'UNITY_USE_COMMAND_LINE_ARGS'],
:options => {
:test_prefix => "paratest",
:use_param_tests => true,
:cmdline_args => true,
},
:cmdline_args => "-f 'paratest_First(0,0)'",
:features => [ :parameterized ],
:expected => {
:to_pass => [
'paratest_First\(0,0\)',
],
:to_fail => [ ],
:to_ignore => [ ],
}
},

{ :name => 'ArgsPreciseMatchParameterizedWithComma',
:testfile => 'testdata/testRunnerGeneratorParameterizedArgs.c',
:testdefines => ['TEST', 'UNITY_USE_COMMAND_LINE_ARGS'],
:options => {
:test_prefix => "paratest",
:use_param_tests => true,
:cmdline_args => true,
},
:cmdline_args => "-n 'paratest_First(0,0)'",
:features => [ :parameterized ],
:expected => {
:to_pass => [
'paratest_First\(0,0\)',
],
:to_fail => [ ],
:to_ignore => [ ],
}
},

{ :name => 'ArgsIncludeParameterizedWithCommaNoMatch',
:testfile => 'testdata/testRunnerGeneratorParameterizedArgs.c',
:testdefines => ['TEST', 'UNITY_USE_COMMAND_LINE_ARGS'],
:options => {
:test_prefix => "paratest",
:use_param_tests => true,
:cmdline_args => true,
},
:cmdline_args => "-f 'paratest_First(0,100)'",
:features => [ :parameterized ],
:expected => {
:to_pass => [ ],
:to_fail => [ ],
:to_ignore => [ ],
}
},

{ :name => 'ArgsIncludeParameterizedWithCommaAlternatives',
:testfile => 'testdata/testRunnerGeneratorParameterizedArgs.c',
:testdefines => ['TEST', 'UNITY_USE_COMMAND_LINE_ARGS'],
:options => {
:test_prefix => "paratest",
:use_param_tests => true,
:cmdline_args => true,
},
:cmdline_args => "-f 'paratest_First(1,1),paratest_Second(2,2),paratest_Plain'",
:features => [ :parameterized ],
:expected => {
:to_pass => [
'paratest_First\(1,1\)',
'paratest_Second\(2,2\)',
'paratest_Plain',
],
:to_fail => [ ],
:to_ignore => [ ],
}
},

{ :name => 'ArgsExcludeParameterizedWithComma',
:testfile => 'testdata/testRunnerGeneratorParameterizedArgs.c',
:testdefines => ['TEST', 'UNITY_USE_COMMAND_LINE_ARGS'],
:options => {
:test_prefix => "paratest",
:use_param_tests => true,
:cmdline_args => true,
},
:cmdline_args => "-x 'paratest_First(0,0)'",
:features => [ :parameterized ],
:expected => {
:to_pass => [
'paratest_First\(1,1\)',
'paratest_First\(10,10\)',
'paratest_Second\(0,0\)',
'paratest_Second\(2,2\)',
'paratest_Second\(20,20\)',
'paratest_Plain',
],
:to_fail => [ ],
:to_ignore => [ ],
}
},

{ :name => 'ArgsList',
:testfile => 'testdata/testRunnerGenerator.c',
:testdefines => ['TEST', 'UNITY_USE_COMMAND_LINE_ARGS'],
Expand Down