Fix bug in test spec parser handling of escaping in ORed patterns

It did not clear out all of its internal state when switching from
one pattern to another, so when it should've escaped `,`, it took
its position from its position in the original user-provided string,
rather than its position in the current pattern.

Fixes #1905
This commit is contained in:
Martin Hořeňovský 2020-04-12 18:44:42 +02:00
parent ca27b0dcc5
commit 87a8b61d5a
No known key found for this signature in database
GPG Key ID: DE48307B8B0D381A
12 changed files with 106 additions and 10 deletions

View File

@ -170,6 +170,7 @@ namespace Catch {
m_pos = m_arg.size();
m_substring.clear();
m_patternName.clear();
m_realPatternPos = 0;
return false;
}
endMode();
@ -188,6 +189,7 @@ namespace Catch {
}
m_patternName.clear();
m_realPatternPos = 0;
return token;
}

View File

@ -13,6 +13,7 @@ This would not be caught previously
Nor would this
:test-result: FAIL #1514: stderr/stdout is not captured in tests aborted by an exception
:test-result: PASS #1548
:test-result: PASS #1905 -- test spec parser properly clears internal state between compound tests
:test-result: XFAIL #748 - captures with unexpected exceptions
:test-result: PASS #809
:test-result: PASS #833

View File

@ -24,6 +24,9 @@ This would not be caught previously
Nor would this
Tricky.tests.cpp:<line number>: failed: explicitly with 1 message: '1514'
Compilation.tests.cpp:<line number>: passed: std::is_same<TypeList<int>, TypeList<int>>::value for: true
CmdLine.tests.cpp:<line number>: passed: spec.matches(*fakeTestCase("spec . char")) for: true
CmdLine.tests.cpp:<line number>: passed: spec.matches(*fakeTestCase("spec , char")) for: true
CmdLine.tests.cpp:<line number>: passed: !(spec.matches(*fakeTestCase(R"(spec \, char)"))) for: !false
Exception.tests.cpp:<line number>: failed: unexpected exception with message: 'answer := 42' with 1 message: 'expected exception'
Exception.tests.cpp:<line number>: failed: unexpected exception with message: 'answer := 42'; expression was: thisThrows() with 1 message: 'expected exception'
Exception.tests.cpp:<line number>: passed: thisThrows() with 1 message: 'answer := 42'

View File

@ -1380,6 +1380,6 @@ due to unexpected exception with message:
Why would you throw a std::string?
===============================================================================
test cases: 332 | 258 passed | 70 failed | 4 failed as expected
assertions: 1873 | 1721 passed | 131 failed | 21 failed as expected
test cases: 333 | 259 passed | 70 failed | 4 failed as expected
assertions: 1876 | 1724 passed | 131 failed | 21 failed as expected

View File

@ -197,6 +197,27 @@ Compilation.tests.cpp:<line number>: PASSED:
with expansion:
true
-------------------------------------------------------------------------------
#1905 -- test spec parser properly clears internal state between compound tests
-------------------------------------------------------------------------------
CmdLine.tests.cpp:<line number>
...............................................................................
CmdLine.tests.cpp:<line number>: PASSED:
REQUIRE( spec.matches(*fakeTestCase("spec . char")) )
with expansion:
true
CmdLine.tests.cpp:<line number>: PASSED:
REQUIRE( spec.matches(*fakeTestCase("spec , char")) )
with expansion:
true
CmdLine.tests.cpp:<line number>: PASSED:
REQUIRE_FALSE( spec.matches(*fakeTestCase(R"(spec \, char)")) )
with expansion:
!false
-------------------------------------------------------------------------------
#748 - captures with unexpected exceptions
outside assertions
@ -14658,6 +14679,6 @@ Misc.tests.cpp:<line number>
Misc.tests.cpp:<line number>: PASSED:
===============================================================================
test cases: 332 | 242 passed | 86 failed | 4 failed as expected
assertions: 1890 | 1721 passed | 148 failed | 21 failed as expected
test cases: 333 | 243 passed | 86 failed | 4 failed as expected
assertions: 1893 | 1724 passed | 148 failed | 21 failed as expected

View File

@ -197,6 +197,27 @@ Compilation.tests.cpp:<line number>: PASSED:
with expansion:
true
-------------------------------------------------------------------------------
#1905 -- test spec parser properly clears internal state between compound tests
-------------------------------------------------------------------------------
CmdLine.tests.cpp:<line number>
...............................................................................
CmdLine.tests.cpp:<line number>: PASSED:
REQUIRE( spec.matches(*fakeTestCase("spec . char")) )
with expansion:
true
CmdLine.tests.cpp:<line number>: PASSED:
REQUIRE( spec.matches(*fakeTestCase("spec , char")) )
with expansion:
true
CmdLine.tests.cpp:<line number>: PASSED:
REQUIRE_FALSE( spec.matches(*fakeTestCase(R"(spec \, char)")) )
with expansion:
!false
-------------------------------------------------------------------------------
#748 - captures with unexpected exceptions
outside assertions
@ -377,6 +398,6 @@ Condition.tests.cpp:<line number>: FAILED:
CHECK( true != true )
===============================================================================
test cases: 20 | 15 passed | 3 failed | 2 failed as expected
assertions: 43 | 36 passed | 4 failed | 3 failed as expected
test cases: 21 | 16 passed | 3 failed | 2 failed as expected
assertions: 46 | 39 passed | 4 failed | 3 failed as expected

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<testsuitesloose text artifact
>
<testsuite name="<exe-name>" errors="17" failures="132" tests="1891" hostname="tbd" time="{duration}" timestamp="{iso8601-timestamp}">
<testsuite name="<exe-name>" errors="17" failures="132" tests="1894" hostname="tbd" time="{duration}" timestamp="{iso8601-timestamp}">
<properties>
<property name="filters" value="~[!nonportable]~[!benchmark]~[approvals] *"/>
<property name="random-seed" value="1"/>
@ -31,6 +31,7 @@ Nor would this
</system-err>
</testcase>
<testcase classname="<exe-name>.global" name="#1548" time="{duration}"/>
<testcase classname="<exe-name>.global" name="#1905 -- test spec parser properly clears internal state between compound tests" time="{duration}"/>
<testcase classname="<exe-name>.global" name="#748 - captures with unexpected exceptions/outside assertions" time="{duration}">
<error type="TEST_CASE">
FAILED:

View File

@ -2,6 +2,7 @@
<testExecutions version="1"loose text artifact
>
<file path="tests/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp">
<testCase name="#1905 -- test spec parser properly clears internal state between compound tests" duration="{duration}"/>
<testCase name="Parse test names and tags/Empty test spec should have no filters" duration="{duration}"/>
<testCase name="Parse test names and tags/Test spec from empty string should have no filters" duration="{duration}"/>
<testCase name="Parse test names and tags/Test spec from just a comma should have no filters" duration="{duration}"/>

View File

@ -46,6 +46,12 @@ Nor would this
not ok {test-number} - explicitly with 1 message: '1514'
# #1548
ok {test-number} - std::is_same<TypeList<int>, TypeList<int>>::value for: true
# #1905 -- test spec parser properly clears internal state between compound tests
ok {test-number} - spec.matches(*fakeTestCase("spec . char")) for: true
# #1905 -- test spec parser properly clears internal state between compound tests
ok {test-number} - spec.matches(*fakeTestCase("spec , char")) for: true
# #1905 -- test spec parser properly clears internal state between compound tests
ok {test-number} - !(spec.matches(*fakeTestCase(R"(spec \, char)"))) for: !false
# #748 - captures with unexpected exceptions
not ok {test-number} - unexpected exception with message: 'answer := 42' with 1 message: 'expected exception'
# #748 - captures with unexpected exceptions
@ -3772,5 +3778,5 @@ ok {test-number} - q3 == 23. for: 23.0 == 23.0
ok {test-number} -
# xmlentitycheck
ok {test-number} -
1..1882
1..1885

View File

@ -28,6 +28,8 @@ Tricky.tests.cpp:<line number>|nexplicit failure with message:|n "1514"']
##teamcity[testFinished name='#1514: stderr/stdout is not captured in tests aborted by an exception' duration="{duration}"]
##teamcity[testStarted name='#1548']
##teamcity[testFinished name='#1548' duration="{duration}"]
##teamcity[testStarted name='#1905 -- test spec parser properly clears internal state between compound tests']
##teamcity[testFinished name='#1905 -- test spec parser properly clears internal state between compound tests' duration="{duration}"]
##teamcity[testStarted name='#748 - captures with unexpected exceptions']
Exception.tests.cpp:<line number>|nunexpected exception with messages:|n "answer := 42"|n "expected exception"- failure ignore as test marked as |'ok to fail|'|n']
Exception.tests.cpp:<line number>|nunexpected exception with messages:|n "answer := 42"|n "expected exception"|n REQUIRE_NOTHROW( thisThrows() )|nwith expansion:|n thisThrows()|n- failure ignore as test marked as |'ok to fail|'|n']

View File

@ -202,6 +202,33 @@ Nor would this
</Expression>
<OverallResult success="true"/>
</TestCase>
<TestCase name="#1905 -- test spec parser properly clears internal state between compound tests" tags="[command-line][test-spec]" filename="tests/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
<Expression success="true" type="REQUIRE" filename="tests/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
<Original>
spec.matches(*fakeTestCase("spec . char"))
</Original>
<Expanded>
true
</Expanded>
</Expression>
<Expression success="true" type="REQUIRE" filename="tests/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
<Original>
spec.matches(*fakeTestCase("spec , char"))
</Original>
<Expanded>
true
</Expanded>
</Expression>
<Expression success="true" type="REQUIRE_FALSE" filename="tests/<exe-name>/IntrospectiveTests/CmdLine.tests.cpp" >
<Original>
!(spec.matches(*fakeTestCase(R"(spec \, char)")))
</Original>
<Expanded>
!false
</Expanded>
</Expression>
<OverallResult success="true"/>
</TestCase>
<TestCase name="#748 - captures with unexpected exceptions" tags="[!shouldfail][!throws][.][failing]" filename="tests/<exe-name>/UsageTests/Exception.tests.cpp" >
<Section name="outside assertions" filename="tests/<exe-name>/UsageTests/Exception.tests.cpp" >
<Info>
@ -17568,7 +17595,7 @@ loose text artifact
</Section>
<OverallResult success="true"/>
</TestCase>
<OverallResults successes="1721" failures="149" expectedFailures="21"/>
<OverallResults successes="1724" failures="149" expectedFailures="21"/>
</Group>
<OverallResults successes="1721" failures="148" expectedFailures="21"/>
<OverallResults successes="1724" failures="148" expectedFailures="21"/>
</Catch>

View File

@ -296,6 +296,17 @@ TEST_CASE( "Parse test names and tags", "[command-line][test-spec]" ) {
}
}
TEST_CASE("#1905 -- test spec parser properly clears internal state between compound tests", "[command-line][test-spec]") {
using Catch::parseTestSpec;
using Catch::TestSpec;
// We ask for one of 2 different tests and the latter one of them has a , in name that needs escaping
TestSpec spec = parseTestSpec(R"("spec . char","spec \, char")");
REQUIRE(spec.matches(*fakeTestCase("spec . char")));
REQUIRE(spec.matches(*fakeTestCase("spec , char")));
REQUIRE_FALSE(spec.matches(*fakeTestCase(R"(spec \, char)")));
}
TEST_CASE( "Process can be configured on command line", "[config][command-line]" ) {
using namespace Catch::Matchers;