Expect

An Expect is a single expression whose evaluation is monitored and recorded. Tests are generally composed of one or more Expectations.

The structure of an Expect is as follows:

Expect<That, Should=Should::Pass>(value, expected_value);

Some expectations have additional arguments, but the template parameters are the same throughout.

Macros

An Expect is executed in a Test via one of three macros: REQUIRE, UNLESS, or CHECK.

Typically, these macros would be used in the run() function of a Test, but they can also be used anywhere else in the Test where you need to verify an expectation before continuing.

REQUIRE

Requires an Expect to be met, else the function will fail.

REQUIRE(Expect<That::IsEqual>(40, 40));  // okay
REQUIRE(Expect<That::IsEqual>(2, 3));  // causes function to return false

CHECK

Evaluates an Expect, but never causes the function to fail.

CHECK(Expect<That::IsEqual>(40, 40));  // okay
CHECK(Expect<That::IsEqual>(2, 3));  // okay, although Expect failed

UNLESS

Requires an Expect to fail, else the function will fail. Unlike Should::Fail, this lets the Expect still fail as normal, but the function succeeds.

In practice, you’re usually better off using Should::Fail in your Expect instead of this macro. This is only if you want the Expect itself to fail, but the function to pass as a result.

UNLESS(Expect<That::IsEqual>(true, false));  // okay
UNLESS(Expect<That::IsEqual>(2, 2);  // causes function to return false

That

The behavior of the Expect is primarily determined by the That:: template parameter.

Most of these expectations depend on the indicated comparison operator being supported by all data types passed to the That::`. For example, if you use ``Expect<That::IsLess>(foo, bar), then the types of foo and bar must be comparable via foo < bar.

IsTrue

Expect<That::IsTrue>(op)

Expects op to implicitly evaluate to true:

return (op == true);

If op is a non-null pointer, dereferences op and evaluates value. If op is nullptr, the Expect fails.

IsFalse

Expect<That::IsFalse>(op)

Expects op to implicitly evaluate to false:

return (op == false);

If op is a non-null pointer, dereferences op and evaluates value. If op is nullptr, the Expect fails.

IsEqual

Expect<That::IsEqual>(left, right)

Expects left and right to evaluate as equal:

return (left == right);

If either left or right are non-null pointers, they are dereferenced as appropriate, and the evaluation is run against the two values. If either is nullptr, the Expect fails.

IsNotEqual

Expect<That::IsNotEqual>(left, right)

Expects left and right to evaluate as not equal:

return (left != right);

If either left or right are non-null pointers, they are dereferenced as appropriate, and the evaluation is run against the two values. If either is nullptr, the Expect fails.

IsLess

Expect<That::IsLess>(left, right)

Expects left evaluates to less than right:

return (left < right);

If either left or right are non-null pointers, they are dereferenced as appropriate, and the evaluation is run against the two values. If either is nullptr, the Expect fails.

IsLessEqual

Expect<That::IsLessEqual>(left, right)

Expects left evaluates to less than or equal to right:

return (left <= right);

If either left or right are non-null pointers, they are dereferenced as appropriate, and the evaluation is run against the two values. If either is nullptr, the Expect fails.

IsGreater

Expect<That::IsGreater>(left, right)

Expects left evaluates to greater than right:

return (left > right);

If either left or right are non-null pointers, they are dereferenced as appropriate, and the evaluation is run against the two values. If either is nullptr, the Expect fails.

IsGreaterEqual

Expect<That::IsGreaterEqual>(left, right)

Expects left evaluates to greater than or equal to right:

return (left >= right);

If either left or right are non-null pointers, they are dereferenced as appropriate, and the evaluation is run against the two values. If either is nullptr, the Expect fails.

PtrIsNull

Expect<That::PtrIsNull>(ptr)

You must pass a pointer to this. Expects the pointer ptr to be nullptr:

return (ptr == nullptr);

PtrIsNotNull

Expect<That::PtrIsNotNull>(ptr)

You must pass a pointer to this. Expects the pointer ptr to not be nullptr:

return (ptr != nullptr);

PtrIsEqual

Expect<That::PtrIsEqual>(left, right)

You must pass pointers to this. Expects the pointers left and right to point to the same address in memory:

return (left == right);

This does not check that the pointers are non-null or valid, nor does it check that the pointers can be dereferenced.

PtrIsNotEqual

Expect<That::PtrIsNotEqual>(left, right)

You must pass pointers to this. Expects the pointers left and right to not point to the same address in memory:

return (left != right);

This does not check that the pointers are non-null or valid, nor does it check that the pointers can be dereferenced.

FuncReturns

Expect<That::FuncReturns>(target, name_hint, func, args...)

Passes the arguments args... to the function func, and expects the returned value to match target.

return (func(args...) == target);

The argument name_hint is a string. It is used only for displaying the name of the function in the test report.

FuncThrows

Expect<That::FuncThrows>(target, name_hint, func, args...)

Passes the arguments args... to the function func, and expects the returned value to throw the exception target.

try {
    func(args...);
} catch (const T& e) { // T is type of target
    return true;
} catch (...) {
    return false;
}
return false;

If the function is not supposed to throw anything, you can pass the value Nothing() to target.

The argument name_hint is used only for displaying the name of the function in the test report.

IsApproxEqual

Expect<That::IsApproxEqual>(value, target, margin)

Expects value to be approximately equal to target, within the margin.

return ((value - target) < 0 ? ((value - target) * (-1.0)) < margin : (value - target) < margin));

If value is a non-null pointer, dereferences value and evaluates. If value is nullptr, returns false.

return (value != nullptr && (*value - target) < 0 ? ((*value - target) * (-1.0)) < margin : (*value - target) < margin);

IsApproxNotEqual

Expect<That::IsApproxNotEqual>(value, target, margin)

Expects value to not be approximately equal to target, within the margin.

return ((value - target) < 0 ? ((value - target) * (-1.0)) > margin : (value - target) > margin);

If value is a non-null pointer, dereferences value and evaluates. If value is nullptr, returns false.

return (value != nullptr && (*value - target) < 0 ? ((*value - target) * (-1.0)) > margin : (*value - target) > margin));

IsInRange

Expect<That::IsInRange>(value, lower, upper)

Expects value to be in the inclusive range defined by lower and upper.

return (value >= lower && value <= upper);

If value is a non-null pointer, dereferences value and evaluates. If op is nullptr, returns false.

return (value != nullptr && *value >= lower && *value <= upper);

IsNotInRange

Expect<That::IsNotInRange>(value, lower, upper)

Expects value to be outside the inclusive range defined by lower and upper.

return (value < lower || value > upper);

If value is a non-null pointer, dereferences value and evaluates. If op is nullptr, returns false.

return (value != nullptr && (*value < lower || *value > upper));

Should

The Should template parameter determines how the outcome of the evaluation is interpreted.

Should::Pass means the evaluation should succeed for the expectation to be met. This is the default.

Should::Fail means the evaluation is NOT supposed to succeed for the expectation to be met. This is useful for guarding against false positives.

Minute min(60);
Hour hour(1);
Hour bad_hour(2);

// Check min == hour
REQUIRE(Expect<That::IsEqual>(min, hour));

// Check min != hour
REQUIRE(Expect<That::IsNotEqual>(min, bad_hour));

// Check min == bad_hour FAILS
REQUIRE(Expect<That::IsEqual, Should::Fail>(min, bad_hour));

// If the last Expect was OK, that would mean `min == bad_hour`, throwing
// the reliability of `min == hour` into doubt.

Should::Pass_Silent and Should::Fail_Silent are the same as their non-silent counterparts, but if the expectation is met, no output is produced. Instead, output is only produced if the expectation is NOT met.