#include using namespace bandit::Matchers; SPEC_BEGIN(Matchers::ThrowException) describe("throw_exception", []{ describe("when no exception is specified", [&]{ std::exception exception; std::function exception_block = [&]{ throw exception; }; describe("when the block throws an exception", [&]{ it("must pass a positive match", [&]{ exception_block must throw_exception; }); it("must reject a negative match", [&]{ AssertThrows(MatcherException, [&]{ exception_block must_not throw_exception; }()); }); }); describe("when the block does not throw an exception", [&]{ std::function quiet_block = [&]{}; it("must pass a negative match", [&]{ quiet_block must_not throw_exception; }); it("must reject a positive match", [&]{ AssertThrows(std::exception, [&]{ quiet_block must throw_exception; }()); }); }); }); describe("with an exception class specified", [&]{ std::logic_error expected_exception("logic_error"); describe("when the block throws the expected exception", [&]{ std::function exception_block = [&]{ throw expected_exception; }; it("must pass a positive match", [&]{ exception_block must throw_exception.operator()(); }); it("must reject a negative match", [&]{ AssertThrows(std::exception, [&]{ exception_block must_not throw_exception.operator()(); }()); }); }); // TODO: Because C++ lacks reflection, there's no way to implement // subclass-checking. I'm leaving these tests here for when the // language has evolved sufficiently. xdescribe("when the block throws a sublass of the specified exception", [&]{ std::function subclass_block = [&]{ throw std::invalid_argument("invalid argument"); }; describe("when subclasses are expected", [&]{ it("must pass a positive match", [&]{ subclass_block must throw_exception.operator()().or_subclass(); }); it("must reject a negative match", [&]{ AssertThrows(std::exception, [&]{ subclass_block must_not throw_exception.operator()().or_subclass(); }()); }); }); describe("when subclasses are not expected", [&]{ it("must pass a negative match", [&]{ subclass_block must_not throw_exception.operator()(); }); it("must reject a positive match", [&]{ AssertThrows(std::exception, [&]{ subclass_block must throw_exception.operator()(); }()); }); }); }); describe("when the block throws an unrelated exception", [&]{ std::function unrelated_block = [&]{ throw std::range_error("range error"); }; it("must pass a negative match", [&]{ unrelated_block must_not throw_exception.operator()(); }); it("must reject a positive match", [&]{ AssertThrows(std::exception, [&]{ unrelated_block must throw_exception.operator()(); }()); }); }); describe("when the block does not throw an exception", [&]{ std::function quiet_block = [&]{}; it("must pass a negative match", [&]{ quiet_block must_not throw_exception.operator()(); }); it("must reject a positive match", [&]{ AssertThrows(std::exception, [&]{ quiet_block must throw_exception.operator()(); }()); }); }); }); }); SPEC_END