fptr == 0
0 == 0
fptr == 0l
0 == 0
y.v == 0
0 == 0
0 == y.v
0 == 0
t1 == t2
{?} == {?}
t1 != t2
{?} != {?}
t1 < t2
{?} < {?}
t1 > t2
{?} > {?}
t1 <= t2
{?} <= {?}
t1 >= t2
{?} >= {?}
uarr := "123"
sarr := "456"
std::memcmp(uarr, "123", sizeof(uarr)) == 0
0 == 0
uarr := "123"
sarr := "456"
std::memcmp(sarr, "456", sizeof(sarr)) == 0
0 == 0

# outside assertions

answer := 42
expected exception

# inside REQUIRE_NOTHROW

answer := 42
thisThrows()
thisThrows()
expected exception

# inside REQUIRE_THROWS

answer := 42
thisThrows()
thisThrows()
42 == f
42 == {?}
a == t
3 == 3
a == t
3 == 3
throws_int(true)
throws_int(true)
throws_int(true), int
throws_int(true), int
throws_int(false)
throws_int(false)
"aaa", Catch::EndsWith("aaa")
"aaa" ends with: "aaa"
templated_tests<int>(3)
true
f() == 0
1 == 0
errno == 1
1 == 1
dummy := 0
x == 4
{?} == 4

# Looped section 0

# Looped section 1

# Looped section 2

# Looped section 3

# Looped section 4

false != false
false != false
true != true
true != true
!true
false
!(true)
!true
!trueValue
false
!(trueValue)
!true
!(1 == 1)
false
!(1 == 1)
!(1 == 1)
false == false
false == false
true == true
true == true
!false
true
!(false)
!false
!falseValue
true
!(falseValue)
!false
!(1 == 2)
true
!(1 == 2)
!(1 == 2)

# compare to true

is_true<true>::value == true
true == true
true == is_true<true>::value
true == true

# compare to false

is_true<false>::value == false
false == false
false == is_true<false>::value
false == false

# negation

!is_true<false>::value
true

# double negation

!!is_true<true>::value
true

# direct

is_true<true>::value
true
!(is_true<false>::value)
!false
s == "world"
"hello" == "world"
s == "hello"
"hello" == "hello"
m_a == 2
1 == 2
m_a == 1
1 == 1

# Outer

## Inner

to infinity and beyond
&o1 == &o2
0x<hex digits> == 0x<hex digits>
o1 == o2
{?} == {?}
104.0 != Approx(100.0)
104.0 != Approx( 100.0 )
104.0 == Approx(100.0).margin(5)
104.0 == Approx( 100.0 )
104.0 == Approx(100.0).margin(4)
104.0 == Approx( 100.0 )
104.0 != Approx(100.0).margin(3)
104.0 != Approx( 100.0 )
100.3 != Approx(100.0)
100.3 != Approx( 100.0 )
100.3 == Approx(100.0).margin(0.5)
100.3 == Approx( 100.0 )
i++ == 7
7 == 7
i++ == 8
8 == 8
1 == 1
1 == 1
{Unknown expression after the reported line}
{Unknown expression after the reported line}
unexpected exception
Approx(0).margin(0)
Approx(0).margin(0)
Approx(0).margin(1234656)
Approx(0).margin(1234656)
Approx(0).margin(-2), std::domain_error
Approx(0).margin(-2), std::domain_error
Approx(0).epsilon(0)
Approx(0).epsilon(0)
Approx(0).epsilon(1)
Approx(0).epsilon(1)
Approx(0).epsilon(-0.001), std::domain_error
Approx(0).epsilon(-0.001), std::domain_error
Approx(0).epsilon(1.0001), std::domain_error
Approx(0).epsilon(1.0001), std::domain_error
0.25f == Approx(0.0f).margin(0.25f)
0.25f == Approx( 0.0 )
0.0f == Approx(0.25f).margin(0.25f)
0.0f == Approx( 0.25 )
0.5f == Approx(0.25f).margin(0.25f)
0.5f == Approx( 0.25 )
245.0f == Approx(245.25f).margin(0.25f)
245.0f == Approx( 245.25 )
245.5f == Approx(245.25f).margin(0.25f)
245.5f == Approx( 245.25 )
divide( 22, 7 ) == Approx( 3.141 ).epsilon( 0.001 )
3.1428571429 == Approx( 3.141 )
divide( 22, 7 ) != Approx( 3.141 ).epsilon( 0.0001 )
3.1428571429 != Approx( 3.141 )
d != Approx( 1.231 )
1.23 != Approx( 1.231 )
d == Approx( 1.231 ).epsilon( 0.1 )
1.23 == Approx( 1.231 )
1.23f == Approx( 1.23f )
1.23f == Approx( 1.2300000191 )
0.0f == Approx( 0.0f )
0.0f == Approx( 0.0 )
1 == Approx( 1 )
1 == Approx( 1.0 )
0 == Approx( 0 )
0 == Approx( 0.0 )
1.0f == Approx( 1 )
1.0f == Approx( 1.0 )
0 == Approx( dZero)
0 == Approx( 0.0 )
0 == Approx( dSmall ).margin( 0.001 )
0 == Approx( 0.00001 )
1.234f == Approx( dMedium )
1.234f == Approx( 1.234 )
dMedium == Approx( 1.234f )
1.234 == Approx( 1.2339999676 )

# Function pointer

1, Predicate<int>(alwaysTrue, "always true")
1 matches predicate: "always true"
1, !Predicate<int>(alwaysFalse, "always false")
1 not matches predicate: "always false"

# Lambdas + different type

"Hello olleH", Predicate<std::string>( [] (std::string const& str) -> bool { return str.front() == str.back(); }, "First and last character should be equal")
"Hello olleH" matches predicate: "First and last character should be equal"
"This wouldn't pass", !Predicate<std::string>( [] (std::string const& str) -> bool { return str.front() == str.back(); } )
"This wouldn't pass" not matches undescribed predicate
true
true

# A section

true
true

## Another section

true
true
true
true

# A section

true
true

## Another other section

true
true
INFINITY == Approx(INFINITY)
inff == Approx( inf )
NAN != Approx(NAN)
nanf != Approx( nan )
!(NAN == Approx(NAN))
!(nanf == Approx( nan ))
y.v == 0
0 == 0
0 == y.v
0 == 0

# Capture should stringify like assertions

i := 2
true
true

# Info should NOT stringify the way assertions do

3
true
true

# Specifically escaped

tab == '\t'
'\t' == '\t'
newline == '\n'
'\n' == '\n'
carr_return == '\r'
'\r' == '\r'
form_feed == '\f'
'\f' == '\f'

# General chars

space == ' '
' ' == ' '
c == chars[i]
'a' == 'a'
c == chars[i]
'z' == 'z'
c == chars[i]
'A' == 'A'
c == chars[i]
'Z' == 'Z'

# Low ASCII

null_terminator == '\0'
0 == 0
c == i
2 == 2
c == i
3 == 3
c == i
4 == 4
c == i
5 == 5
std::vector<constructor_throws>{constructor_throws{}, constructor_throws{}}
std::vector<constructor_throws>{constructor_throws{}, constructor_throws{}}
std::vector<constructor_throws>{constructor_throws{}, constructor_throws{}}
std::vector<constructor_throws>{constructor_throws{}, constructor_throws{}}
std::vector<int>{1, 2, 3} == std::vector<int>{1, 2, 3}
std::vector<int>{1, 2, 3} == std::vector<int>{1, 2, 3}
std::vector<int>{1, 2, 3} == std::vector<int>{1, 2, 3}
std::vector<int>{1, 2, 3} == std::vector<int>{1, 2, 3}
std::vector<int>{1, 2} == std::vector<int>{1, 2}
{ 1, 2 } == { 1, 2 }
std::vector<int>{1, 2} == std::vector<int>{1, 2}
{ 1, 2 } == { 1, 2 }
!(std::vector<int>{1, 2} == std::vector<int>{1, 2, 3})
!({ 1, 2 } == { 1, 2, 3 })
!(std::vector<int>{1, 2} == std::vector<int>{1, 2, 3})
!({ 1, 2 } == { 1, 2, 3 })
std::vector<int>{1, 2} == std::vector<int>{1, 2}
{ 1, 2 } == { 1, 2 }
std::vector<int>{1, 2} == std::vector<int>{1, 2}
{ 1, 2 } == { 1, 2 }
true
true
std::vector<int>{1, 2} == std::vector<int>{1, 2}
{ 1, 2 } == { 1, 2 }
a
0x<hex digits>
a == &foo
0x<hex digits> == 0x<hex digits>
td == Approx(10.0)
StrongDoubleTypedef(10) == Approx( 10.0 )
Approx(10.0) == td
Approx( 10.0 ) == StrongDoubleTypedef(10)
td != Approx(11.0)
StrongDoubleTypedef(10) != Approx( 11.0 )
Approx(11.0) != td
Approx( 11.0 ) != StrongDoubleTypedef(10)
td <= Approx(10.0)
StrongDoubleTypedef(10) <= Approx( 10.0 )
td <= Approx(11.0)
StrongDoubleTypedef(10) <= Approx( 11.0 )
Approx(10.0) <= td
Approx( 10.0 ) <= StrongDoubleTypedef(10)
Approx(9.0) <= td
Approx( 9.0 ) <= StrongDoubleTypedef(10)
td >= Approx(9.0)
StrongDoubleTypedef(10) >= Approx( 9.0 )
td >= Approx(td)
StrongDoubleTypedef(10) >= Approx( 10.0 )
Approx(td) >= td
Approx( 10.0 ) >= StrongDoubleTypedef(10)
Approx(11.0) >= td
Approx( 11.0 ) >= StrongDoubleTypedef(10)
54 == 6*9
54 == 54
( -1 > 2u )
true
-1 > 2u
-1 > 2
( 2u < -1 )
true
2u < -1
2 < -1
( minInt > 2u )
true
minInt > 2u
-2147483648 > 2
i == 1
1 == 1
ui == 2
2 == 2
l == 3
3 == 3
ul == 4
4 == 4
c == 5
5 == 5
uc == 6
6 == 6
1 == i
1 == 1
2 == ui
2 == 2
3 == l
3 == 3
4 == ul
4 == 4
5 == c
5 == 5
6 == uc
6 == 6
(std::numeric_limits<uint32_t>::max)() > ul
4294967295 (0x<hex digits>) > 4
testStringForMatching(), Contains("not there", Catch::CaseSensitive::No)
"this string contains 'abc' as a substring" contains: "not there" (case insensitive)
testStringForMatching(), Contains("STRING")
"this string contains 'abc' as a substring" contains: "STRING"
throwCustom()
throwCustom()
custom exception - not std
throwCustom(), std::exception
throwCustom(), std::exception
custom exception - not std
custom std exception
101.000001 != Approx(100).epsilon(0.01)
101.000001 != Approx( 100.0 )
std::pow(10, -5) != Approx(std::pow(10, -7))
0.00001 != Approx( 0.0000001 )
testStringForMatching(), EndsWith("Substring")
"this string contains 'abc' as a substring" ends with: "Substring"
testStringForMatching(), EndsWith("this", Catch::CaseSensitive::No)
"this string contains 'abc' as a substring" ends with: "this" (case insensitive)
101.01 != Approx(100).epsilon(0.01)
101.01 != Approx( 100.0 )
data.int_seven == 6
7 == 6
data.int_seven == 8
7 == 8
data.int_seven == 0
7 == 0
data.float_nine_point_one == Approx( 9.11f )
9.1f == Approx( 9.1099996567 )
data.float_nine_point_one == Approx( 9.0f )
9.1f == Approx( 9.0 )
data.float_nine_point_one == Approx( 1 )
9.1f == Approx( 1.0 )
data.float_nine_point_one == Approx( 0 )
9.1f == Approx( 0.0 )
data.double_pi == Approx( 3.1415 )
3.1415926535 == Approx( 3.1415 )
data.str_hello == "goodbye"
"hello" == "goodbye"
data.str_hello == "hell"
"hello" == "hell"
data.str_hello == "hello1"
"hello" == "hello1"
data.str_hello.size() == 6
5 == 6
x == Approx( 1.301 )
1.3 == Approx( 1.301 )
data.int_seven == 7
7 == 7
data.float_nine_point_one == Approx( 9.1f )
9.1f == Approx( 9.1000003815 )
data.double_pi == Approx( 3.1415926535 )
3.1415926535 == Approx( 3.1415926535 )
data.str_hello == "hello"
"hello" == "hello"
"hello" == data.str_hello
"hello" == "hello"
data.str_hello.size() == 5
5 == 5
x == Approx( 1.3 )
1.3 == Approx( 1.3 )
testStringForMatching(), Equals("this string contains 'abc' as a substring")
"this string contains 'abc' as a substring" equals: "this string contains 'abc' as a substring"
testStringForMatching(), Equals("this string contains 'ABC' as a substring", Catch::CaseSensitive::No)
"this string contains 'abc' as a substring" equals: "this string contains 'abc' as a substring" (case insensitive)
testStringForMatching(), Equals("this string contains 'ABC' as a substring")
"this string contains 'abc' as a substring" equals: "this string contains 'ABC' as a substring"
testStringForMatching(), Equals("something else", Catch::CaseSensitive::No)
"this string contains 'abc' as a substring" equals: "something else" (case insensitive)

# No exception

doesNotThrow(), SpecialException, ExceptionMatcher{1}
doesNotThrow(), SpecialException, ExceptionMatcher{1}
doesNotThrow(), SpecialException, ExceptionMatcher{1}
doesNotThrow(), SpecialException, ExceptionMatcher{1}

# Type mismatch

throwsAsInt(1), SpecialException, ExceptionMatcher{1}
throwsAsInt(1), SpecialException, ExceptionMatcher{1}
Unknown exception
throwsAsInt(1), SpecialException, ExceptionMatcher{1}
throwsAsInt(1), SpecialException, ExceptionMatcher{1}
Unknown exception

# Contents are wrong

throws(3), SpecialException, ExceptionMatcher{1}
{?} special exception has value of 1
throws(4), SpecialException, ExceptionMatcher{1}
{?} special exception has value of 1
throws(1), SpecialException, ExceptionMatcher{1}
{?} special exception has value of 1
throws(2), SpecialException, ExceptionMatcher{2}
{?} special exception has value of 2

# exact match

thisThrows(), "expected exception"
"expected exception" equals: "expected exception"

# different case

thisThrows(), Equals( "expecteD Exception", Catch::CaseSensitive::No )
"expected exception" equals: "expected exception" (case insensitive)

# wildcarded

thisThrows(), StartsWith( "expected" )
"expected exception" starts with: "expected"
thisThrows(), EndsWith( "exception" )
"expected exception" ends with: "exception"
thisThrows(), Contains( "except" )
"expected exception" contains: "except"
thisThrows(), Contains( "exCept", Catch::CaseSensitive::No )
"expected exception" contains: "except" (case insensitive)
thisThrows(), std::string
thisThrows(), std::string
expected exception
thisDoesntThrow(), std::domain_error
thisDoesntThrow(), std::domain_error
thisThrows()
thisThrows()
expected exception
This is a failure
This is a failure

This message appears in the output

Factorial(0) == 1
1 == 1
Factorial(1) == 1
1 == 1
Factorial(2) == 2
2 == 2
Factorial(3) == 6
6 == 6
Factorial(10) == 3628800
3628800 (0x<hex digits>) == 3628800 (0x<hex digits>)

# Margin

1., WithinAbs(1., 0)
1.0 is within 0.0 of 1.0
0., WithinAbs(1., 1)
0.0 is within 1.0 of 1.0
0., !WithinAbs(1., 0.99)
0.0 not is within 0.99 of 1.0
0., !WithinAbs(1., 0.99)
0.0 not is within 0.99 of 1.0
NAN, !WithinAbs(NAN, 0)
nanf not is within 0.0 of nan
11., !WithinAbs(10., 0.5)
11.0 not is within 0.5 of 10.0
10., !WithinAbs(11., 0.5)
10.0 not is within 0.5 of 11.0
-10., WithinAbs(-10., 0.5)
-10.0 is within 0.5 of -10.0
-10., WithinAbs(-9.6, 0.5)
-10.0 is within 0.5 of -9.6

# ULPs

1., WithinULP(1., 0)
1.0 is within 0 ULPs of 1.0
nextafter(1., 2.), WithinULP(1., 1)
1.0 is within 1 ULPs of 1.0
nextafter(1., 0.), WithinULP(1., 1)
1.0 is within 1 ULPs of 1.0
nextafter(1., 2.), !WithinULP(1., 0)
1.0 not is within 0 ULPs of 1.0
1., WithinULP(1., 0)
1.0 is within 0 ULPs of 1.0
-0., WithinULP(0., 0)
-0.0 is within 0 ULPs of 0.0
NAN, !WithinULP(NAN, 123)
nanf not is within 123 ULPs of nanf

# Composed

1., WithinAbs(1., 0.5) || WithinULP(2., 1)
1.0 ( is within 0.5 of 1.0 or is within 1 ULPs of 2.0 )
1., WithinAbs(2., 0.5) || WithinULP(1., 0)
1.0 ( is within 0.5 of 2.0 or is within 0 ULPs of 1.0 )
NAN, !(WithinAbs(NAN, 100) || WithinULP(NAN, 123))
nanf not ( is within 100.0 of nan or is within 123 ULPs of nanf )

# Constructor validation

WithinAbs(1., 0.)
WithinAbs(1., 0.)
WithinAbs(1., -1.), std::domain_error
WithinAbs(1., -1.), std::domain_error
WithinULP(1., 0)
WithinULP(1., 0)
WithinULP(1., -1), std::domain_error
WithinULP(1., -1), std::domain_error

# Margin

1.f, WithinAbs(1.f, 0)
1.0f is within 0.0 of 1.0
0.f, WithinAbs(1.f, 1)
0.0f is within 1.0 of 1.0
0.f, !WithinAbs(1.f, 0.99f)
0.0f not is within 0.9900000095 of 1.0
0.f, !WithinAbs(1.f, 0.99f)
0.0f not is within 0.9900000095 of 1.0
0.f, WithinAbs(-0.f, 0)
0.0f is within 0.0 of -0.0
NAN, !WithinAbs(NAN, 0)
nanf not is within 0.0 of nan
11.f, !WithinAbs(10.f, 0.5f)
11.0f not is within 0.5 of 10.0
10.f, !WithinAbs(11.f, 0.5f)
10.0f not is within 0.5 of 11.0
-10.f, WithinAbs(-10.f, 0.5f)
-10.0f is within 0.5 of -10.0
-10.f, WithinAbs(-9.6f, 0.5f)
-10.0f is within 0.5 of -9.6000003815

# ULPs

1.f, WithinULP(1.f, 0)
1.0f is within 0 ULPs of 1.0f
nextafter(1.f, 2.f), WithinULP(1.f, 1)
1.0f is within 1 ULPs of 1.0f
nextafter(1.f, 0.f), WithinULP(1.f, 1)
1.0f is within 1 ULPs of 1.0f
nextafter(1.f, 2.f), !WithinULP(1.f, 0)
1.0f not is within 0 ULPs of 1.0f
1.f, WithinULP(1.f, 0)
1.0f is within 0 ULPs of 1.0f
-0.f, WithinULP(0.f, 0)
-0.0f is within 0 ULPs of 0.0f
NAN, !WithinULP(NAN, 123)
nanf not is within 123 ULPs of nanf

# Composed

1.f, WithinAbs(1.f, 0.5) || WithinULP(1.f, 1)
1.0f ( is within 0.5 of 1.0 or is within 1 ULPs of 1.0f )
1.f, WithinAbs(2.f, 0.5) || WithinULP(1.f, 0)
1.0f ( is within 0.5 of 2.0 or is within 0 ULPs of 1.0f )
NAN, !(WithinAbs(NAN, 100) || WithinULP(NAN, 123))
nanf not ( is within 100.0 of nan or is within 123 ULPs of nanf )

# Constructor validation

WithinAbs(1.f, 0.f)
WithinAbs(1.f, 0.f)
WithinAbs(1.f, -1.f), std::domain_error
WithinAbs(1.f, -1.f), std::domain_error
WithinULP(1.f, 0)
WithinULP(1.f, 0)
WithinULP(1.f, -1), std::domain_error
WithinULP(1.f, -1), std::domain_error
d >= Approx( 1.22 )
1.23 >= Approx( 1.22 )
d >= Approx( 1.23 )
1.23 >= Approx( 1.23 )
!(d >= Approx( 1.24 ))
!(1.23 >= Approx( 1.24 ))
d >= Approx( 1.24 ).epsilon(0.1)
1.23 >= Approx( 1.24 )
this is a message

this is a warning

this message should be logged
so should this
a == 1
2 == 1
this message may be logged later
a == 2
2 == 2
this message may be logged later
this message should be logged
a == 1
2 == 1
this message may be logged later
this message should be logged
and this, but later
a == 0
2 == 0
this message may be logged later
this message should be logged
and this, but later
but not this
a == 2
2 == 2
current counter 0
i := 0
i < 10
0 < 10
current counter 1
i := 1
i < 10
1 < 10
current counter 2
i := 2
i < 10
2 < 10
current counter 3
i := 3
i < 10
3 < 10
current counter 4
i := 4
i < 10
4 < 10
current counter 5
i := 5
i < 10
5 < 10
current counter 6
i := 6
i < 10
6 < 10
current counter 7
i := 7
i < 10
7 < 10
current counter 8
i := 8
i < 10
8 < 10
current counter 9
i := 9
i < 10
9 < 10
current counter 10
i := 10
i < 10
10 < 10
data.int_seven != 7
7 != 7
data.float_nine_point_one != Approx( 9.1f )
9.1f != Approx( 9.1000003815 )
data.double_pi != Approx( 3.1415926535 )
3.1415926535 != Approx( 3.1415926535 )
data.str_hello != "hello"
"hello" != "hello"
data.str_hello.size() != 5
5 != 5
data.int_seven != 6
7 != 6
data.int_seven != 8
7 != 8
data.float_nine_point_one != Approx( 9.11f )
9.1f != Approx( 9.1099996567 )
data.float_nine_point_one != Approx( 9.0f )
9.1f != Approx( 9.0 )
data.float_nine_point_one != Approx( 1 )
9.1f != Approx( 1.0 )
data.float_nine_point_one != Approx( 0 )
9.1f != Approx( 0.0 )
data.double_pi != Approx( 3.1415 )
3.1415926535 != Approx( 3.1415 )
data.str_hello != "goodbye"
"hello" != "goodbye"
data.str_hello != "hell"
"hello" != "hell"
data.str_hello != "hello1"
"hello" != "hello1"
data.str_hello.size() != 6
5 != 6
d <= Approx( 1.24 )
1.23 <= Approx( 1.24 )
d <= Approx( 1.23 )
1.23 <= Approx( 1.23 )
!(d <= Approx( 1.22 ))
!(1.23 <= Approx( 1.22 ))
d <= Approx( 1.22 ).epsilon(0.1)
1.23 <= Approx( 1.22 )
testStringForMatching(), Contains("string") && Contains("abc") && Contains("substring") && Contains("contains")
"this string contains 'abc' as a substring" ( contains: "string" and contains: "abc" and contains: "substring" and contains: "contains" )
testStringForMatching(), Contains("string") || Contains("different") || Contains("random")
"this string contains 'abc' as a substring" ( contains: "string" or contains: "different" or contains: "random" )
testStringForMatching2(), Contains("string") || Contains("different") || Contains("random")
"some completely different text that contains one common word" ( contains: "string" or contains: "different" or contains: "random" )
testStringForMatching(), (Contains("string") || Contains("different")) && Contains("substring")
"this string contains 'abc' as a substring" ( ( contains: "string" or contains: "different" ) and contains: "substring" )
testStringForMatching(), (Contains("string") || Contains("different")) && Contains("random")
"this string contains 'abc' as a substring" ( ( contains: "string" or contains: "different" ) and contains: "random" )
testStringForMatching(), !Contains("different")
"this string contains 'abc' as a substring" not contains: "different"
testStringForMatching(), !Contains("substring")
"this string contains 'abc' as a substring" not contains: "substring"
thisThrows(), "expected exception"
"expected exception" equals: "expected exception"
thisThrows(), "should fail"
"expected exception" equals: "should fail"

This one ran

custom exception
True
{?}
!False
true
!(False)
!{?}
data.int_seven > 7
7 > 7
data.int_seven < 7
7 < 7
data.int_seven > 8
7 > 8
data.int_seven < 6
7 < 6
data.int_seven < 0
7 < 0
data.int_seven < -1
7 < -1
data.int_seven >= 8
7 >= 8
data.int_seven <= 6
7 <= 6
data.float_nine_point_one < 9
9.1f < 9
data.float_nine_point_one > 10
9.1f > 10
data.float_nine_point_one > 9.2
9.1f > 9.2
data.str_hello > "hello"
"hello" > "hello"
data.str_hello < "hello"
"hello" < "hello"
data.str_hello > "hellp"
"hello" > "hellp"
data.str_hello > "z"
"hello" > "z"
data.str_hello < "hellm"
"hello" < "hellm"
data.str_hello < "a"
"hello" < "a"
data.str_hello >= "z"
"hello" >= "z"
data.str_hello <= "a"
"hello" <= "a"
data.int_seven < 8
7 < 8
data.int_seven > 6
7 > 6
data.int_seven > 0
7 > 0
data.int_seven > -1
7 > -1
data.int_seven >= 7
7 >= 7
data.int_seven >= 6
7 >= 6
data.int_seven <= 7
7 <= 7
data.int_seven <= 8
7 <= 8
data.float_nine_point_one > 9
9.1f > 9
data.float_nine_point_one < 10
9.1f < 10
data.float_nine_point_one < 9.2
9.1f < 9.2
data.str_hello <= "hello"
"hello" <= "hello"
data.str_hello >= "hello"
"hello" >= "hello"
data.str_hello < "hellp"
"hello" < "hellp"
data.str_hello < "zebra"
"hello" < "zebra"
data.str_hello > "hellm"
"hello" > "hellm"
data.str_hello > "a"
"hello" > "a"

# one

Message from section one

# two

Message from section two

# Empty test spec should have no filters

spec.hasFilters() == false
false == false
spec.matches( tcA ) == false
false == false
spec.matches( tcB ) == false
false == false

# Test spec from empty string should have no filters

spec.hasFilters() == false
false == false
spec.matches(tcA ) == false
false == false
spec.matches( tcB ) == false
false == false

# Test spec from just a comma should have no filters

spec.hasFilters() == false
false == false
spec.matches( tcA ) == false
false == false
spec.matches( tcB ) == false
false == false

# Test spec from name should have one filter

spec.hasFilters() == true
true == true
spec.matches( tcA ) == false
false == false
spec.matches( tcB ) == true
true == true

# Test spec from quoted name should have one filter

spec.hasFilters() == true
true == true
spec.matches( tcA ) == false
false == false
spec.matches( tcB ) == true
true == true

# Test spec from name should have one filter

spec.hasFilters() == true
true == true
spec.matches( tcA ) == false
false == false
spec.matches( tcB ) == true
true == true
spec.matches( tcC ) == false
false == false

# Wildcard at the start

spec.hasFilters() == true
true == true
spec.matches( tcA ) == false
false == false
spec.matches( tcB ) == false
false == false
spec.matches( tcC ) == true
true == true
spec.matches( tcD ) == false
false == false
parseTestSpec( "*a" ).matches( tcA ) == true
true == true

# Wildcard at the end

spec.hasFilters() == true
true == true
spec.matches( tcA ) == false
false == false
spec.matches( tcB ) == false
false == false
spec.matches( tcC ) == true
true == true
spec.matches( tcD ) == false
false == false
parseTestSpec( "a*" ).matches( tcA ) == true
true == true

# Wildcard at both ends

spec.hasFilters() == true
true == true
spec.matches( tcA ) == false
false == false
spec.matches( tcB ) == false
false == false
spec.matches( tcC ) == true
true == true
spec.matches( tcD ) == true
true == true
parseTestSpec( "*a*" ).matches( tcA ) == true
true == true

# Redundant wildcard at the start

spec.hasFilters() == true
true == true
spec.matches( tcA ) == true
true == true
spec.matches( tcB ) == false
false == false

# Redundant wildcard at the end

spec.hasFilters() == true
true == true
spec.matches( tcA ) == true
true == true
spec.matches( tcB ) == false
false == false

# Redundant wildcard at both ends

spec.hasFilters() == true
true == true
spec.matches( tcA ) == true
true == true
spec.matches( tcB ) == false
false == false

# Wildcard at both ends, redundant at start

spec.hasFilters() == true
true == true
spec.matches( tcA ) == false
false == false
spec.matches( tcB ) == false
false == false
spec.matches( tcC ) == true
true == true
spec.matches( tcD ) == true
true == true

# Just wildcard

spec.hasFilters() == true
true == true
spec.matches( tcA ) == true
true == true
spec.matches( tcB ) == true
true == true
spec.matches( tcC ) == true
true == true
spec.matches( tcD ) == true
true == true

# Single tag

spec.hasFilters() == true
true == true
spec.matches( tcA ) == false
false == false
spec.matches( tcB ) == true
true == true
spec.matches( tcC ) == false
false == false

# Single tag, two matches

spec.hasFilters() == true
true == true
spec.matches( tcA ) == false
false == false
spec.matches( tcB ) == true
true == true
spec.matches( tcC ) == true
true == true

# Two tags

spec.hasFilters() == true
true == true
spec.matches( tcA ) == false
false == false
spec.matches( tcB ) == false
false == false
spec.matches( tcC ) == true
true == true

# Two tags, spare separated

spec.hasFilters() == true
true == true
spec.matches( tcA ) == false
false == false
spec.matches( tcB ) == false
false == false
spec.matches( tcC ) == true
true == true

# Wildcarded name and tag

spec.hasFilters() == true
true == true
spec.matches( tcA ) == false
false == false
spec.matches( tcB ) == false
false == false
spec.matches( tcC ) == true
true == true
spec.matches( tcD ) == false
false == false

# Single tag exclusion

spec.hasFilters() == true
true == true
spec.matches( tcA ) == true
true == true
spec.matches( tcB ) == false
false == false
spec.matches( tcC ) == true
true == true

# One tag exclusion and one tag inclusion

spec.hasFilters() == true
true == true
spec.matches( tcA ) == false
false == false
spec.matches( tcB ) == true
true == true
spec.matches( tcC ) == false
false == false

# One tag exclusion and one wldcarded name inclusion

spec.hasFilters() == true
true == true
spec.matches( tcA ) == false
false == false
spec.matches( tcB ) == false
false == false
spec.matches( tcC ) == false
false == false
spec.matches( tcD ) == true
true == true

# One tag exclusion, using exclude:, and one wldcarded name inclusion

spec.hasFilters() == true
true == true
spec.matches( tcA ) == false
false == false
spec.matches( tcB ) == false
false == false
spec.matches( tcC ) == false
false == false
spec.matches( tcD ) == true
true == true

# name exclusion

spec.hasFilters() == true
true == true
spec.matches( tcA ) == true
true == true
spec.matches( tcB ) == false
false == false
spec.matches( tcC ) == true
true == true
spec.matches( tcD ) == true
true == true

# wildcarded name exclusion

spec.hasFilters() == true
true == true
spec.matches( tcA ) == true
true == true
spec.matches( tcB ) == true
true == true
spec.matches( tcC ) == false
false == false
spec.matches( tcD ) == false
false == false

# wildcarded name exclusion with tag inclusion

spec.hasFilters() == true
true == true
spec.matches( tcA ) == true
true == true
spec.matches( tcB ) == true
true == true
spec.matches( tcC ) == true
true == true
spec.matches( tcD ) == false
false == false

# wildcarded name exclusion, using exclude:, with tag inclusion

spec.hasFilters() == true
true == true
spec.matches( tcA ) == true
true == true
spec.matches( tcB ) == true
true == true
spec.matches( tcC ) == true
true == true
spec.matches( tcD ) == false
false == false

# two wildcarded names

spec.hasFilters() == true
true == true
spec.matches( tcA ) == false
false == false
spec.matches( tcB ) == false
false == false
spec.matches( tcC ) == true
true == true
spec.matches( tcD ) == false
false == false

# empty tag

spec.hasFilters() == false
false == false
spec.matches( tcA ) == false
false == false
spec.matches( tcB ) == false
false == false
spec.matches( tcC ) == false
false == false
spec.matches( tcD ) == false
false == false

# empty quoted name

spec.hasFilters() == false
false == false
spec.matches( tcA ) == false
false == false
spec.matches( tcB ) == false
false == false
spec.matches( tcC ) == false
false == false
spec.matches( tcD ) == false
false == false

# quoted string followed by tag exclusion

spec.hasFilters() == true
true == true
spec.matches( tcA ) == false
false == false
spec.matches( tcB ) == false
false == false
spec.matches( tcC ) == false
false == false
spec.matches( tcD ) == true
true == true
(std::pair<int, int>( 1, 2 )) == aNicePair
{?} == {?}
p == 0
0 == 0
p == pNULL
0 == 0
p != 0
0x<hex digits> != 0
cp != 0
0x<hex digits> != 0
cpc != 0
0x<hex digits> != 0
returnsNull() == 0
{null string} == 0
returnsConstNull() == 0
{null string} == 0
0 != p
0 != 0x<hex digits>

# empty args don't cause a crash

result
{?}
config.processName == ""
"" == ""

# default - no arguments

result
{?}
config.processName == "test"
"test" == "test"
config.shouldDebugBreak == false
false == false
config.abortAfter == -1
-1 == -1
config.noThrow == false
false == false
config.reporterNames.empty()
true
!(cfg.hasTestFilters())
!false

# test lists

## 1 test

Specify one test case using

result
{?}
cfg.hasTestFilters()
true
cfg.testSpec().matches(fakeTestCase("notIncluded")) == false
false == false
cfg.testSpec().matches(fakeTestCase("test1"))
true

# test lists

## Specify one test case exclusion using exclude:

result
{?}
cfg.hasTestFilters()
true
cfg.testSpec().matches(fakeTestCase("test1")) == false
false == false
cfg.testSpec().matches(fakeTestCase("alwaysIncluded"))
true

# test lists

## Specify one test case exclusion using ~

result
{?}
cfg.hasTestFilters()
true
cfg.testSpec().matches(fakeTestCase("test1")) == false
false == false
cfg.testSpec().matches(fakeTestCase("alwaysIncluded"))
true

# reporter

## -r/console

cli.parse({"test", "-r", "console"})
{?}
config.reporterNames[0] == "console"
"console" == "console"

# reporter

## -r/xml

cli.parse({"test", "-r", "xml"})
{?}
config.reporterNames[0] == "xml"
"xml" == "xml"

# reporter

## -r xml and junit

cli.parse({"test", "-r", "xml", "-r", "junit"})
{?}
config.reporterNames.size() == 2
2 == 2
config.reporterNames[0] == "xml"
"xml" == "xml"
config.reporterNames[1] == "junit"
"junit" == "junit"

# reporter

## --reporter/junit

cli.parse({"test", "--reporter", "junit"})
{?}
config.reporterNames[0] == "junit"
"junit" == "junit"

# debugger

## -b

cli.parse({"test", "-b"})
{?}
config.shouldDebugBreak == true
true == true

# debugger

## --break

cli.parse({"test", "--break"})
{?}
config.shouldDebugBreak
true

# abort

## -a aborts after first failure

cli.parse({"test", "-a"})
{?}
config.abortAfter == 1
1 == 1

# abort

## -x 2 aborts after two failures

cli.parse({"test", "-x", "2"})
{?}
config.abortAfter == 2
2 == 2

# abort

## -x must be numeric

!result
true
result.errorMessage(), Contains("convert") && Contains("oops")
"Unable to convert 'oops' to destination type" ( contains: "convert" and contains: "oops" )

# nothrow

## -e

cli.parse({"test", "-e"})
{?}
config.noThrow
true

# nothrow

## --nothrow

cli.parse({"test", "--nothrow"})
{?}
config.noThrow
true

# output filename

## -o filename

cli.parse({"test", "-o", "filename.ext"})
{?}
config.outputFilename == "filename.ext"
"filename.ext" == "filename.ext"

# output filename

## --out

cli.parse({"test", "--out", "filename.ext"})
{?}
config.outputFilename == "filename.ext"
"filename.ext" == "filename.ext"

# combinations

## Single character flags can be combined

cli.parse({"test", "-abe"})
{?}
config.abortAfter == 1
1 == 1
config.shouldDebugBreak
true
config.noThrow == true
true == true

# use-colour

## without option

cli.parse({"test"})
{?}
config.useColour == UseColour::Auto
0 == 0

# use-colour

## auto

cli.parse({"test", "--use-colour", "auto"})
{?}
config.useColour == UseColour::Auto
0 == 0

# use-colour

## yes

cli.parse({"test", "--use-colour", "yes"})
{?}
config.useColour == UseColour::Yes
1 == 1

# use-colour

## no

cli.parse({"test", "--use-colour", "no"})
{?}
config.useColour == UseColour::No
2 == 2

# use-colour

## error

!result
true
result.errorMessage(), Contains( "colour mode must be one of" )
"colour mode must be one of: auto, yes or no. 'wrong' not recognised" contains: "colour mode must be one of"
truthy(false)
Hey, its truthy!
testStringForMatching(), Matches("this STRING contains 'abc' as a substring")
"this string contains 'abc' as a substring" matches "this STRING contains 'abc' as a substring" case sensitively
testStringForMatching(), Matches("contains 'abc' as a substring")
"this string contains 'abc' as a substring" matches "contains 'abc' as a substring" case sensitively
testStringForMatching(), Matches("this string contains 'abc' as a")
"this string contains 'abc' as a substring" matches "this string contains 'abc' as a" case sensitively

# Given: No operations precede me

before == 0
0 == 0

## When: We get the count

### Then: Subsequently values are higher

after > before
1 > 0

# Given: This stuff exists

## When: I do this

### Then: it should do this

itDoesThis()
true

#### And: do that

itDoesThat()
true

# Given: A section name that is so long that it cannot fit in a single console width

## When: The test headers are printed as part of the normal running of the scenario

### Then: The, deliberately very long and overly verbose (you see what I did there?) section names must wrap, along with an indent

# Given: an empty vector

v.size() == 0
0 == 0

## When: it is made larger

### Then: the size and capacity go up

v.size() == 10
10 == 10
v.capacity() >= 10
10 >= 10

#### And when: it is made smaller again

##### Then: the size goes down but the capacity stays the same

v.size() == 5
5 == 5
v.capacity() >= 10
10 >= 10

# Given: an empty vector

v.size() == 0
0 == 0

## When: we reserve more space

### Then: The capacity is increased but the size remains the same

v.capacity() >= 10
10 >= 10
v.size() == 0
0 == 0
A string sent directly to stdout
A string sent directly to stderr A string sent to stderr via clog
d == Approx( 1.23 )
1.23 == Approx( 1.23 )
d != Approx( 1.22 )
1.23 != Approx( 1.22 )
d != Approx( 1.24 )
1.23 != Approx( 1.24 )
Approx( d ) == 1.23
Approx( 1.23 ) == 1.23
Approx( d ) != 1.22
Approx( 1.23 ) != 1.22
Approx( d ) != 1.24
Approx( 1.23 ) != 1.24
INFINITY == Approx(INFINITY)
inff == Approx( inf )

# one

# two

Message from section one Message from section two
testStringForMatching(), StartsWith("This String")
"this string contains 'abc' as a substring" starts with: "This String"
testStringForMatching(), StartsWith("string", Catch::CaseSensitive::No)
"this string contains 'abc' as a substring" starts with: "string" (case insensitive)

# Single item

Catch::Detail::stringify(singular) == "{ 1 }"
"{ 1 }" == "{ 1 }"

# Multiple

Catch::Detail::stringify(arr) == "{ 3, 2, 1 }"
"{ 3, 2, 1 }" == "{ 3, 2, 1 }"

# Non-trivial inner items

Catch::Detail::stringify(arr) == R"({ { "1:1", "1:2", "1:3" }, { "2:1", "2:2" } })"
"{ { "1:1", "1:2", "1:3" }, { "2:1", "2:2" } }" == "{ { "1:1", "1:2", "1:3" }, { "2:1", "2:2" } }"
testStringForMatching(), Contains("string")
"this string contains 'abc' as a substring" contains: "string"
testStringForMatching(), Contains("string", Catch::CaseSensitive::No)
"this string contains 'abc' as a substring" contains: "string" (case insensitive)
testStringForMatching(), Contains("abc")
"this string contains 'abc' as a substring" contains: "abc"
testStringForMatching(), Contains("aBC", Catch::CaseSensitive::No)
"this string contains 'abc' as a substring" contains: "abc" (case insensitive)
testStringForMatching(), StartsWith("this")
"this string contains 'abc' as a substring" starts with: "this"
testStringForMatching(), StartsWith("THIS", Catch::CaseSensitive::No)
"this string contains 'abc' as a substring" starts with: "this" (case insensitive)
testStringForMatching(), EndsWith("substring")
"this string contains 'abc' as a substring" ends with: "substring"
testStringForMatching(), EndsWith(" SuBsTrInG", Catch::CaseSensitive::No)
"this string contains 'abc' as a substring" ends with: " substring" (case insensitive)

# Empty string

empty.empty()
true
empty.size() == 0
0 == 0
std::strcmp( empty.c_str(), "" ) == 0
0 == 0

# From string literal

s.empty() == false
false == false
s.size() == 5
5 == 5
isSubstring( s ) == false
false == false
std::strcmp( rawChars, "hello" ) == 0
0 == 0

## c_str() does not cause copy

isOwned( s ) == false
false == false
s.c_str() == rawChars
"hello" == "hello"
isOwned( s ) == false
false == false

# From sub-string

original == "original"
original == "original"
isSubstring( original )
true
isOwned( original ) == false
false == false
isSubstring( original ) == false
false == false
isOwned( original )
true

# Substrings

## zero-based substring

ss.empty() == false
false == false
ss.size() == 5
5 == 5
std::strcmp( ss.c_str(), "hello" ) == 0
0 == 0
ss == "hello"
hello == "hello"

# Substrings

## c_str() causes copy

isSubstring( ss )
true
isOwned( ss ) == false
false == false
rawChars == s.currentData()
"hello world!" == "hello world!"
ss.c_str() != rawChars
"hello" != "hello world!"
isSubstring( ss ) == false
false == false
isOwned( ss )
true
ss.currentData() != s.currentData()
"hello" != "hello world!"

# Substrings

## non-zero-based substring

ss.size() == 6
6 == 6
std::strcmp( ss.c_str(), "world!" ) == 0
0 == 0

# Substrings

## Pointer values of full refs should match

s.c_str() == s2.c_str()
"hello world!" == "hello world!"

# Substrings

## Pointer values of substring refs should not match

s.c_str() != ss.c_str()
"hello world!" != "hello"

# Comparisons

StringRef("hello") == StringRef("hello")
hello == hello
StringRef("hello") != StringRef("cello")
hello != cello

# from std::string

## implicitly constructed

sr == "a standard string"
a standard string == "a standard string"
sr.size() == stdStr.size()
17 == 17

# from std::string

## explicitly constructed

sr == "a standard string"
a standard string == "a standard string"
sr.size() == stdStr.size()
17 == 17

# from std::string

## assigned

sr == "a standard string"
a standard string == "a standard string"
sr.size() == stdStr.size()
17 == 17

# to std::string

## implicitly constructed

stdStr == "a stringref"
"a stringref" == "a stringref"
stdStr.size() == sr.size()
11 == 11

# to std::string

## explicitly constructed

stdStr == "a stringref"
"a stringref" == "a stringref"
stdStr.size() == sr.size()
11 == 11

# to std::string

## assigned

stdStr == "a stringref"
"a stringref" == "a stringref"
stdStr.size() == sr.size()
11 == 11

# Counting utf-8 codepoints

ascii.numberOfCharacters() == ascii.size()
39 == 39
simpleu8.numberOfCharacters() == 30
30 == 30
emojis.numberOfCharacters() == 9
9 == 9
minute == seconds
1 m == 60 s
hour != seconds
1 h != 60 s
micro != milli
1 us != 1 ms
nano != micro
1 ns != 1 us
half_minute != femto_second
1 [30/1]s != 1 fs
pico_second != atto_second
1 ps != 1 as
now != later
{iso8601-timestamp} != {iso8601-timestamp}
s1 == s2
"if ($b == 10) { $a = 20; }" == "if ($b == 10) { $a = 20; } "

# The same tag alias can only be registered once

what, Contains( "[@zzz]" )
"error: tag alias, '[@zzz]' already registered. First seen at: file:2 Redefined at: file:10" contains: "[@zzz]"
what, Contains( "file" )
"error: tag alias, '[@zzz]' already registered. First seen at: file:2 Redefined at: file:10" contains: "file"
what, Contains( "2" )
"error: tag alias, '[@zzz]' already registered. First seen at: file:2 Redefined at: file:10" contains: "2"
what, Contains( "10" )
"error: tag alias, '[@zzz]' already registered. First seen at: file:2 Redefined at: file:10" contains: "10"

# Tag aliases must be of the form [@name]

registry.add( "[no ampersat]", "", Catch::SourceLineInfo( "file", 3 ) )
registry.add( "[no ampersat]", "", Catch::SourceLineInfo( "file", 3 ) )
registry.add( "[the @ is not at the start]", "", Catch::SourceLineInfo( "file", 3 ) )
registry.add( "[the @ is not at the start]", "", Catch::SourceLineInfo( "file", 3 ) )
registry.add( "@no square bracket at start]", "", Catch::SourceLineInfo( "file", 3 ) )
registry.add( "@no square bracket at start]", "", Catch::SourceLineInfo( "file", 3 ) )
registry.add( "[@no square bracket at end", "", Catch::SourceLineInfo( "file", 3 ) )
registry.add( "[@no square bracket at end", "", Catch::SourceLineInfo( "file", 3 ) )
0x<hex digits> == bit30and31
3221225472 (0x<hex digits>) == 3221225472
1 == 2
1 == 2
For some reason someone is throwing a string literal!
testCase.isOpen()
true
s1.isOpen()
true

# successfully close one section

s1.isSuccessfullyCompleted()
true
testCase.isComplete() == false
false == false
ctx.completedCycle()
true
testCase.isSuccessfullyCompleted()
true
testCase.isOpen()
true
s1.isOpen()
true

# fail one section

s1.isComplete()
true
s1.isSuccessfullyCompleted() == false
false == false
testCase.isComplete() == false
false == false
ctx.completedCycle()
true
testCase.isSuccessfullyCompleted() == false
false == false

## re-enter after failed section

testCase2.isOpen()
true
s1b.isOpen() == false
false == false
ctx.completedCycle()
true
testCase.isComplete()
true
testCase.isSuccessfullyCompleted()
true
testCase.isOpen()
true
s1.isOpen()
true

# fail one section

s1.isComplete()
true
s1.isSuccessfullyCompleted() == false
false == false
testCase.isComplete() == false
false == false
ctx.completedCycle()
true
testCase.isSuccessfullyCompleted() == false
false == false

## re-enter after failed section and find next section

testCase2.isOpen()
true
s1b.isOpen() == false
false == false
s2.isOpen()
true
ctx.completedCycle()
true
testCase.isComplete()
true
testCase.isSuccessfullyCompleted()
true
testCase.isOpen()
true
s1.isOpen()
true

# successfully close one section, then find another

s2.isOpen() == false
false == false
testCase.isComplete() == false
false == false

## Re-enter - skips S1 and enters S2

testCase2.isOpen()
true
s1b.isOpen() == false
false == false
s2b.isOpen()
true
ctx.completedCycle() == false
false == false

### Successfully close S2

ctx.completedCycle()
true
s2b.isSuccessfullyCompleted()
true
testCase2.isComplete() == false
false == false
testCase2.isSuccessfullyCompleted()
true
testCase.isOpen()
true
s1.isOpen()
true

# successfully close one section, then find another

s2.isOpen() == false
false == false
testCase.isComplete() == false
false == false

## Re-enter - skips S1 and enters S2

testCase2.isOpen()
true
s1b.isOpen() == false
false == false
s2b.isOpen()
true
ctx.completedCycle() == false
false == false

### fail S2

ctx.completedCycle()
true
s2b.isComplete()
true
s2b.isSuccessfullyCompleted() == false
false == false
testCase2.isSuccessfullyCompleted() == false
false == false
testCase3.isOpen()
true
s1c.isOpen() == false
false == false
s2c.isOpen() == false
false == false
testCase3.isSuccessfullyCompleted()
true
testCase.isOpen()
true
s1.isOpen()
true

# open a nested section

s2.isOpen()
true
s2.isComplete()
true
s1.isComplete() == false
false == false
s1.isComplete()
true
testCase.isComplete() == false
false == false
testCase.isComplete()
true
testCase.isOpen()
true
s1.isOpen()
true

# start a generator

g1.isOpen()
true
g1.index() == 0
0 == 0
g1.isComplete() == false
false == false
s1.isComplete() == false
false == false

## close outer section

s1.isComplete() == false
false == false
testCase.isSuccessfullyCompleted() == false
false == false

### Re-enter for second generation

testCase2.isOpen()
true
s1b.isOpen()
true
g1b.isOpen()
true
g1b.index() == 1
1 == 1
s1.isComplete() == false
false == false
s1b.isComplete()
true
g1b.isComplete()
true
testCase2.isComplete()
true
testCase.isOpen()
true
s1.isOpen()
true

# start a generator

g1.isOpen()
true
g1.index() == 0
0 == 0
g1.isComplete() == false
false == false
s1.isComplete() == false
false == false

## Start a new inner section

s2.isOpen()
true
s2.isComplete()
true
s1.isComplete() == false
false == false
testCase.isComplete() == false
false == false

### Re-enter for second generation

testCase2.isOpen()
true
s1b.isOpen()
true
g1b.isOpen()
true
g1b.index() == 1
1 == 1
s2b.isOpen()
true
s2b.isComplete()
true
g1b.isComplete()
true
s1b.isComplete()
true
testCase2.isComplete()
true
testCase.isOpen()
true
s1.isOpen()
true

# start a generator

g1.isOpen()
true
g1.index() == 0
0 == 0
g1.isComplete() == false
false == false
s1.isComplete() == false
false == false

## Fail an inner section

s2.isOpen()
true
s2.isComplete()
true
s2.isSuccessfullyCompleted() == false
false == false
s1.isComplete() == false
false == false
testCase.isComplete() == false
false == false

### Re-enter for second generation

testCase2.isOpen()
true
s1b.isOpen()
true
g1b.isOpen()
true
g1b.index() == 0
0 == 0
s2b.isOpen() == false
false == false
g1b.isComplete() == false
false == false
s1b.isComplete() == false
false == false
testCase2.isComplete() == false
false == false
testCase3.isOpen()
true
s1c.isOpen()
true
g1c.isOpen()
true
g1c.index() == 1
1 == 1
s2c.isOpen()
true
s2c.isComplete()
true
g1c.isComplete()
true
s1c.isComplete()
true
testCase3.isComplete()
true
3.14
d == approx( 1.23 )
1.23 == Approx( 1.23 )
d == approx( 1.22 )
1.23 == Approx( 1.22 )
d == approx( 1.24 )
1.23 == Approx( 1.24 )
d != approx( 1.25 )
1.23 != Approx( 1.25 )
approx( d ) == 1.23
Approx( 1.23 ) == 1.23
approx( d ) == 1.22
Approx( 1.23 ) == 1.22
approx( d ) == 1.24
Approx( 1.23 ) == 1.24
approx( d ) != 1.25
Approx( 1.23 ) != 1.25

# Section with one argument

# Contains (element)

v, VectorContains(1)
{ 1, 2, 3 } Contains: 1
v, VectorContains(2)
{ 1, 2, 3 } Contains: 2

# Contains (vector)

v, Contains(v2)
{ 1, 2, 3 } Contains: { 1, 2 }
v, Contains(v2)
{ 1, 2, 3 } Contains: { 1, 2, 3 }
v, Contains(empty)
{ 1, 2, 3 } Contains: { }
empty, Contains(empty)
{ } Contains: { }

# Contains (element), composed

v, VectorContains(1) && VectorContains(2)
{ 1, 2, 3 } ( Contains: 1 and Contains: 2 )

# Equals

v, Equals(v)
{ 1, 2, 3 } Equals: { 1, 2, 3 }
empty, Equals(empty)
{ } Equals: { }
v, Equals(v2)
{ 1, 2, 3 } Equals: { 1, 2, 3 }

# UnorderedEquals

v, UnorderedEquals(v)
{ 1, 2, 3 } UnorderedEquals: { 1, 2, 3 }
empty, UnorderedEquals(empty)
{ } UnorderedEquals: { }
permuted, UnorderedEquals(v)
{ 1, 3, 2 } UnorderedEquals: { 1, 2, 3 }
permuted, UnorderedEquals(v)
{ 2, 3, 1 } UnorderedEquals: { 1, 2, 3 }

# Contains (element)

v, VectorContains(-1)
{ 1, 2, 3 } Contains: -1
empty, VectorContains(1)
{ } Contains: 1

# Contains (vector)

empty, Contains(v)
{ } Contains: { 1, 2, 3 }
v, Contains(v2)
{ 1, 2, 3 } Contains: { 1, 2, 4 }

# Equals

v, Equals(v2)
{ 1, 2, 3 } Equals: { 1, 2 }
v2, Equals(v)
{ 1, 2 } Equals: { 1, 2, 3 }
empty, Equals(v)
{ } Equals: { 1, 2, 3 }
v, Equals(empty)
{ 1, 2, 3 } Equals: { }

# UnorderedEquals

v, UnorderedEquals(empty)
{ 1, 2, 3 } UnorderedEquals: { }
empty, UnorderedEquals(v)
{ } UnorderedEquals: { 1, 2, 3 }
permuted, UnorderedEquals(v)
{ 1, 3 } UnorderedEquals: { 1, 2, 3 }
permuted, UnorderedEquals(v)
{ 3, 1 } UnorderedEquals: { 1, 2, 3 }
thisThrows(), std::domain_error
thisThrows(), std::domain_error
thisDoesntThrow()
thisDoesntThrow()
thisThrows()
thisThrows()
unexpected exception
thisThrows() == 0
thisThrows() == 0
expected exception
thisThrows() == 0
thisThrows() == 0
expected exception
thisThrows() == 0
thisThrows() == 0
expected exception

# section name

unexpected exception

Uncomment the code in this test to check that it gives a sensible compiler error

Uncomment the code in this test to check that it gives a sensible compiler error

# normal string

encode( "normal string" ) == "normal string"
"normal string" == "normal string"

# empty string

encode( "" ) == ""
"" == ""

# string with ampersand

encode( "smith & jones" ) == "smith &amp; jones"
"smith &amp; jones" == "smith &amp; jones"

# string with less-than

encode( "smith < jones" ) == "smith &lt; jones"
"smith &lt; jones" == "smith &lt; jones"

# string with greater-than

encode( "smith > jones" ) == "smith > jones"
"smith > jones" == "smith > jones"
encode( "smith ]]> jones" ) == "smith ]]&gt; jones"
"smith ]]&gt; jones" == "smith ]]&gt; jones"

# string with quotes

encode( stringWithQuotes ) == stringWithQuotes
"don't "quote" me on that" == "don't "quote" me on that"
encode( stringWithQuotes, Catch::XmlEncode::ForAttributes ) == "don't &quot;quote&quot; me on that"
"don't &quot;quote&quot; me on that" == "don't &quot;quote&quot; me on that"

# string with control char (1)

encode( "[\x01]" ) == "[\\x01]"
"[\x01]" == "[\x01]"

# string with control char (x7F)

encode( "[\x7F]" ) == "[\\x7F]"
"[\x7F]" == "[\x7F]"

# Valid utf-8 strings

encode(u8"Here be ðŸ‘¾") == u8"Here be ðŸ‘¾"
"Here be ðŸ‘¾" == "Here be ðŸ‘¾"
encode(u8"Å¡Å¡") == u8"Å¡Å¡"
"Å¡Å¡" == "Å¡Å¡"
encode("\xDF\xBF") == "\xDF\xBF"
"ß¿" == "ß¿"
encode("\xE0\xA0\x80") == "\xE0\xA0\x80"
"à €" == "à €"
encode("\xED\x9F\xBF") == "\xED\x9F\xBF"
"íŸ¿" == "íŸ¿"
encode("\xEE\x80\x80") == "\xEE\x80\x80"
"î€€" == "î€€"
encode("\xEF\xBF\xBF") == "\xEF\xBF\xBF"
"ï¿¿" == "ï¿¿"
encode("\xF0\x90\x80\x80") == "\xF0\x90\x80\x80"
"ð�€€" == "ð�€€"
encode("\xF4\x8F\xBF\xBF") == "\xF4\x8F\xBF\xBF"
"ô�¿¿" == "ô�¿¿"

# Invalid utf-8 strings

## Various broken strings

encode("Here \xFF be ðŸ‘¾") == u8"Here \\xFF be ðŸ‘¾"
"Here \xFF be ðŸ‘¾" == "Here \xFF be ðŸ‘¾"
encode("\xFF") == "\\xFF"
"\xFF" == "\xFF"
encode("\xC5\xC5\xA0") == u8"\\xC5Å "
"\xC5Å " == "\xC5Å "
encode("\xF4\x90\x80\x80") == u8"\\xF4\\x90\\x80\\x80"
"\xF4\x90\x80\x80" == "\xF4\x90\x80\x80"

# Invalid utf-8 strings

## Overlong encodings

encode("\xC0\x80") == u8"\\xC0\\x80"
"\xC0\x80" == "\xC0\x80"
encode("\xF0\x80\x80\x80") == u8"\\xF0\\x80\\x80\\x80"
"\xF0\x80\x80\x80" == "\xF0\x80\x80\x80"
encode("\xC1\xBF") == u8"\\xC1\\xBF"
"\xC1\xBF" == "\xC1\xBF"
encode("\xE0\x9F\xBF") == u8"\\xE0\\x9F\\xBF"
"\xE0\x9F\xBF" == "\xE0\x9F\xBF"
encode("\xF0\x8F\xBF\xBF") == u8"\\xF0\\x8F\\xBF\\xBF"
"\xF0\x8F\xBF\xBF" == "\xF0\x8F\xBF\xBF"

# Invalid utf-8 strings

## Surrogate pairs

encode("\xED\xA0\x80") == "\xED\xA0\x80"
"í €" == "í €"
encode("\xED\xAF\xBF") == "\xED\xAF\xBF"
"í¯¿" == "í¯¿"
encode("\xED\xB0\x80") == "\xED\xB0\x80"
"í°€" == "í°€"
encode("\xED\xBF\xBF") == "\xED\xBF\xBF"
"í¿¿" == "í¿¿"

# Invalid utf-8 strings

## Invalid start byte

encode("\x80") == u8"\\x80"
"\x80" == "\x80"
encode("\x81") == u8"\\x81"
"\x81" == "\x81"
encode("\xBC") == u8"\\xBC"
"\xBC" == "\xBC"
encode("\xBF") == u8"\\xBF"
"\xBF" == "\xBF"
encode("\xF5\x80\x80\x80") == u8"\\xF5\\x80\\x80\\x80"
"\xF5\x80\x80\x80" == "\xF5\x80\x80\x80"
encode("\xF6\x80\x80\x80") == u8"\\xF6\\x80\\x80\\x80"
"\xF6\x80\x80\x80" == "\xF6\x80\x80\x80"
encode("\xF7\x80\x80\x80") == u8"\\xF7\\x80\\x80\\x80"
"\xF7\x80\x80\x80" == "\xF7\x80\x80\x80"

# Invalid utf-8 strings

## Missing continuation byte(s)

encode("\xDE") == u8"\\xDE"
"\xDE" == "\xDE"
encode("\xDF") == u8"\\xDF"
"\xDF" == "\xDF"
encode("\xE0") == u8"\\xE0"
"\xE0" == "\xE0"
encode("\xEF") == u8"\\xEF"
"\xEF" == "\xEF"
encode("\xF0") == u8"\\xF0"
"\xF0" == "\xF0"
encode("\xF4") == u8"\\xF4"
"\xF4" == "\xF4"
encode("\xE0\x80") == u8"\\xE0\\x80"
"\xE0\x80" == "\xE0\x80"
encode("\xE0\xBF") == u8"\\xE0\\xBF"
"\xE0\xBF" == "\xE0\xBF"
encode("\xE1\x80") == u8"\\xE1\\x80"
"\xE1\x80" == "\xE1\x80"
encode("\xF0\x80") == u8"\\xF0\\x80"
"\xF0\x80" == "\xF0\x80"
encode("\xF4\x80") == u8"\\xF4\\x80"
"\xF4\x80" == "\xF4\x80"
encode("\xF0\x80\x80") == u8"\\xF0\\x80\\x80"
"\xF0\x80\x80" == "\xF0\x80\x80"
encode("\xF4\x80\x80") == u8"\\xF4\\x80\\x80"
"\xF4\x80\x80" == "\xF4\x80\x80"
Catch::Detail::stringify( empty ) == "{ }"
"{ }" == "{ }"
Catch::Detail::stringify( oneValue ) == "{ 42 }"
"{ 42 }" == "{ 42 }"
Catch::Detail::stringify( twoValues ) == "{ 42, 250 }"
"{ 42, 250 }" == "{ 42, 250 }"
x == 0
0 == 0
obj.prop != 0
0x<hex digits> != 0
flag
true
testCheckedElse( true )
true
flag
false
testCheckedElse( false )
false
flag
true
testCheckedIf( true )
true
flag
false
testCheckedIf( false )
false
unsigned_char_var == 1
1 == 1
unsigned_short_var == 1
1 == 1
unsigned_int_var == 1
1 == 1
unsigned_long_var == 1
1 == 1
long_var == unsigned_char_var
1 == 1
long_var == unsigned_short_var
1 == 1
long_var == unsigned_int_var
1 == 1
long_var == unsigned_long_var
1 == 1

# c

## d (leaf)

# c

## e (leaf)

# f (leaf)

loose text artifact
Previous info should not be seen
l == std::numeric_limits<long long>::max()
9223372036854775807 (0x<hex digits>) == 9223372036854775807 (0x<hex digits>)

# s1

b is currently: 0

b > a
0 > 1
Testing if fib[0] (1) is even
( fib[i] % 2 ) == 0
1 == 0
Testing if fib[1] (1) is even
( fib[i] % 2 ) == 0
1 == 0
Testing if fib[2] (2) is even
( fib[i] % 2 ) == 0
0 == 0
Testing if fib[3] (3) is even
( fib[i] % 2 ) == 0
1 == 0
Testing if fib[4] (5) is even
( fib[i] % 2 ) == 0
1 == 0
Testing if fib[5] (8) is even
( fib[i] % 2 ) == 0
0 == 0
Testing if fib[6] (13) is even
( fib[i] % 2 ) == 0
1 == 0
Testing if fib[7] (21) is even
( fib[i] % 2 ) == 0
1 == 0

# s1

doesn't equal

## s2

equal

a == b
1 == 2

# s1

doesn't equal

## s3

not equal

a != b
1 != 2

# s1

doesn't equal

## s4

less than

a < b
1 < 2

# s1

doesn't equal

a != b
1 != 2
b != a
2 != 1

## s2

not equal

a != b
1 != 2
s == "7"
"7" == "7"
ti == typeid(int)
{?} == {?}
makeString( false ) != static_cast<char*>(0)
"valid string" != {null string}
makeString( true ) == static_cast<char*>(0)
{null string} == {null string}
ptr.get() == 0
0 == 0
::Catch::Detail::stringify( pair ) == "{ { 42, \"Arthur\" }, { \"Ford\", 24 } }"
"{ { 42, "Arthur" }, { "Ford", 24 } }" == "{ { 42, "Arthur" }, { "Ford", 24 } }"
p == 0
0 == 0

# s1

doesn't equal

a != b
1 != 2
b != a
2 != 1

# s2

not equal

a != b
1 != 2

# replace single char

Catch::replaceInPlace( letters, "b", "z" )
true
letters == "azcdefcg"
"azcdefcg" == "azcdefcg"

# replace two chars

Catch::replaceInPlace( letters, "c", "z" )
true
letters == "abzdefzg"
"abzdefzg" == "abzdefzg"

# replace first char

Catch::replaceInPlace( letters, "a", "z" )
true
letters == "zbcdefcg"
"zbcdefcg" == "zbcdefcg"

# replace last char

Catch::replaceInPlace( letters, "g", "z" )
true
letters == "abcdefcz"
"abcdefcz" == "abcdefcz"

# replace all chars

Catch::replaceInPlace( letters, letters, "replaced" )
true
letters == "replaced"
"replaced" == "replaced"

# replace no chars

!(Catch::replaceInPlace( letters, "x", "z" ))
!false
letters == letters
"abcdefcg" == "abcdefcg"

# escape '

Catch::replaceInPlace( s, "'", "|'" )
true
s == "didn|'t"
"didn|'t" == "didn|'t"
3
false
false
hi
i := 7
false
false

# empty

Catch::Detail::stringify( emptyMap ) == "{ }"
"{ }" == "{ }"

# single item

Catch::Detail::stringify( map ) == "{ { \"one\", 1 } }"
"{ { "one", 1 } }" == "{ { "one", 1 } }"

# several items

Catch::Detail::stringify( map ) == "{ { \"abc\", 1 }, { \"def\", 2 }, { \"ghi\", 3 } }"
"{ { "abc", 1 }, { "def", 2 }, { "ghi", 3 } }" == "{ { "abc", 1 }, { "def", 2 }, { "ghi", 3 } }"
::Catch::Detail::stringify(value) == "{ 34, \"xyzzy\" }"
"{ 34, "xyzzy" }" == "{ 34, "xyzzy" }"
::Catch::Detail::stringify( value ) == "{ 34, \"xyzzy\" }"
"{ 34, "xyzzy" }" == "{ 34, "xyzzy" }"

# empty

Catch::Detail::stringify( emptySet ) == "{ }"
"{ }" == "{ }"

# single item

Catch::Detail::stringify( set ) == "{ \"one\" }"
"{ "one" }" == "{ "one" }"

# several items

Catch::Detail::stringify( set ) == "{ \"abc\", \"def\", \"ghi\" }"
"{ "abc", "def", "ghi" }" == "{ "abc", "def", "ghi" }"
::Catch::Detail::stringify( pr ) == "{ { \"green\", 55 } }"
"{ { "green", 55 } }" == "{ { "green", 55 } }"
std::string( "first" ) == "second"
"first" == "second"
::Catch::Detail::stringify(streamable_range{}) == "op<<(streamable_range)"
"op<<(streamable_range)" == "op<<(streamable_range)"
::Catch::Detail::stringify(stringmaker_range{}) == "stringmaker(streamable_range)"
"stringmaker(streamable_range)" == "stringmaker(streamable_range)"
::Catch::Detail::stringify(just_range{}) == "{ 1, 2, 3, 4 }"
"{ 1, 2, 3, 4 }" == "{ 1, 2, 3, 4 }"
::Catch::Detail::stringify(disabled_range{}) == "{ !!! }"
"{ !!! }" == "{ !!! }"
::Catch::Detail::stringify( item ) == "StringMaker<has_maker>"
"StringMaker<has_maker>" == "StringMaker<has_maker>"
::Catch::Detail::stringify( item ) == "StringMaker<has_maker_and_operator>"
"StringMaker<has_maker_and_operator>" == "StringMaker<has_maker_and_operator>"
::Catch::Detail::stringify(item) == "{ !!! }"
"{ !!! }" == "{ !!! }"
::Catch::Detail::stringify( item ) == "operator<<( has_operator )"
"operator<<( has_operator )" == "operator<<( has_operator )"
::Catch::Detail::stringify( v ) == "{ StringMaker<has_maker> }"
"{ StringMaker<has_maker> }" == "{ StringMaker<has_maker> }"
::Catch::Detail::stringify( v ) == "{ StringMaker<has_maker_and_operator> }"
"{ StringMaker<has_maker_and_operator> }" == "{ StringMaker<has_maker_and_operator> }"
::Catch::Detail::stringify( v ) == "{ operator<<( has_operator ) }"
"{ operator<<( has_operator ) }" == "{ operator<<( has_operator ) }"
Why would you throw a std::string?
result == "\"wide load\""
""wide load"" == ""wide load""
result == "\"wide load\""
""wide load"" == ""wide load""
result == "\"wide load\""
""wide load"" == ""wide load""
result == "\"wide load\""
""wide load"" == ""wide load""
::Catch::Detail::stringify(e0) == "E2/V0"
"E2/V0" == "E2/V0"
::Catch::Detail::stringify(e1) == "E2/V1"
"E2/V1" == "E2/V1"
::Catch::Detail::stringify(e3) == "Unknown enum value 10"
"Unknown enum value 10" == "Unknown enum value 10"
::Catch::Detail::stringify(e0) == "0"
"0" == "0"
::Catch::Detail::stringify(e1) == "1"
"1" == "1"
::Catch::Detail::stringify(e0) == "E2{0}"
"E2{0}" == "E2{0}"
::Catch::Detail::stringify(e1) == "E2{1}"
"E2{1}" == "E2{1}"
::Catch::Detail::stringify(e0) == "0"
"0" == "0"
::Catch::Detail::stringify(e1) == "1"
"1" == "1"
"{ }" == ::Catch::Detail::stringify(type{})
"{ }" == "{ }"
"{ }" == ::Catch::Detail::stringify(value)
"{ }" == "{ }"
"1.2f" == ::Catch::Detail::stringify(float(1.2))
"1.2f" == "1.2f"
"{ 1.2f, 0 }" == ::Catch::Detail::stringify(type{1.2f,0})
"{ 1.2f, 0 }" == "{ 1.2f, 0 }"
"{ 0 }" == ::Catch::Detail::stringify(type{0})
"{ 0 }" == "{ 0 }"
"{ 0, 42, \"Catch me\" }" == ::Catch::Detail::stringify(value)
"{ 0, 42, "Catch me" }" == "{ 0, 42, "Catch me" }"
"{ \"hello\", \"world\" }" == ::Catch::Detail::stringify(type{"hello","world"})
"{ "hello", "world" }" == "{ "hello", "world" }"
"{ { 42 }, { }, 1.2f }" == ::Catch::Detail::stringify(value)
"{ { 42 }, { }, 1.2f }" == "{ { 42 }, { }, 1.2f }"
::Catch::Detail::stringify(v) == "{ }"
"{ }" == "{ }"
::Catch::Detail::stringify(v) == "{ { \"hello\" }, { \"world\" } }"
"{ { "hello" }, { "world" } }" == "{ { "hello" }, { "world" } }"
::Catch::Detail::stringify(bools) == "{ }"
"{ }" == "{ }"
::Catch::Detail::stringify(bools) == "{ true }"
"{ true }" == "{ true }"
::Catch::Detail::stringify(bools) == "{ true, false }"
"{ true, false }" == "{ true, false }"
::Catch::Detail::stringify(vv) == "{ }"
"{ }" == "{ }"
::Catch::Detail::stringify(vv) == "{ 42 }"
"{ 42 }" == "{ 42 }"
::Catch::Detail::stringify(vv) == "{ 42, 250 }"
"{ 42, 250 }" == "{ 42, 250 }"
::Catch::Detail::stringify(vv) == "{ }"
"{ }" == "{ }"
::Catch::Detail::stringify(vv) == "{ 42 }"
"{ 42 }" == "{ 42 }"
::Catch::Detail::stringify(vv) == "{ 42, 250 }"
"{ 42, 250 }" == "{ 42, 250 }"
::Catch::Detail::stringify(vv) == "{ }"
"{ }" == "{ }"
::Catch::Detail::stringify(vv) == "{ \"hello\" }"
"{ "hello" }" == "{ "hello" }"
::Catch::Detail::stringify(vv) == "{ \"hello\", \"world\" }"
"{ "hello", "world" }" == "{ "hello", "world" }"
v.size() == 5
5 == 5
v.capacity() >= 5
5 >= 5

# resizing bigger changes size and capacity

v.size() == 10
10 == 10
v.capacity() >= 10
10 >= 10
v.size() == 5
5 == 5
v.capacity() >= 5
5 >= 5

# resizing smaller changes size but not capacity

v.size() == 0
0 == 0
v.capacity() >= 5
5 >= 5

## We can use the 'swap trick' to reset the capacity

v.capacity() == 0
0 == 0
v.size() == 5
5 == 5
v.capacity() >= 5
5 >= 5

# reserving bigger changes capacity but not size

v.size() == 5
5 == 5
v.capacity() >= 10
10 >= 10
v.size() == 5
5 == 5
v.capacity() >= 5
5 >= 5

# reserving smaller does not change size or capacity

v.size() == 5
5 == 5
v.capacity() >= 5
5 >= 5

# embedded xml

<test>it should be possible to embed xml characters, such as <, " or &, or even whole <xml>documents</xml> within an attribute</test>

# encoded chars

these should all be encoded: &&&"""<<<&"<<&"