%% Licensed under the Apache License, Version 2.0 (the "License"); you may %% not use this file except in compliance with the License. You may obtain %% a copy of the License at %% %% Unless required by applicable law or agreed to in writing, software %% distributed under the License is distributed on an "AS IS" BASIS, %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %% See the License for the specific language governing permissions and %% limitations under the License. %% %% Copyright (C) 2004-2012 Richard Carlsson, Mickaël Rémond -ifndef(ASSERT_HRL). -define(ASSERT_HRL, true). %% Asserts are enabled unless NOASSERT is defined, and ASSERT can be used to %% override it: if both ASSERT and NOASSERT are defined, then ASSERT takes %% precedence, and NOASSERT will become undefined. %% %% Furthermore, if NODEBUG is defined, it implies NOASSERT, unless DEBUG or %% ASSERT are defined. %% allow NODEBUG to imply NOASSERT, unless DEBUG -ifdef(NODEBUG). -ifndef(DEBUG). -ifndef(NOASSERT). -define(NOASSERT, true). -endif. -endif. -endif. %% allow ASSERT to override NOASSERT -ifdef(ASSERT). -undef(NOASSERT). -endif. %% Assert macros must not depend on any non-kernel or stdlib libraries. %% %% We must use fun-call wrappers ((fun () -> ... end)()) to avoid %% exporting local variables, and furthermore we only use variable names %% prefixed with "__", that hopefully will not be bound outside the fun. %% It is not possible to nest assert macros. %% The plain assert macro should be defined to do nothing if this file is %% included when asserts are turned off, but avoid getting a compilation %% error if a macro called assert is already defined for some reason. -ifdef(NOASSERT). -ifndef(assert). -define(assert(BoolExpr),ok). -endif. -else. %% The assert macro is written the way it is so as not to cause warnings %% for clauses that cannot match, even if the expression is a constant. -undef(assert). -define(assert(BoolExpr), ((fun () -> case (BoolExpr) of true -> ok; __V -> erlang:error({assertion_failed, [{module, ?MODULE}, {line, ?LINE}, {expression, (??BoolExpr)}, {expected, true}, {value, case __V of false -> __V; _ -> {not_a_boolean,__V} end}]}) end end)())). -endif. -define(assertNot(BoolExpr), ?assert(not (BoolExpr))). %% This is mostly a convenience which gives more detailed reports. %% Note: Guard is a guarded pattern, and can not be used for value. -ifdef(NOASSERT). -define(assertMatch(Guard, Expr), ok). -else. -define(assertMatch(Guard, Expr), ((fun () -> case (Expr) of Guard -> ok; __V -> erlang:error({assertMatch_failed, [{module, ?MODULE}, {line, ?LINE}, {expression, (??Expr)}, {pattern, (??Guard)}, {value, __V}]}) end end)())). -endif. %% This is the inverse case of assertMatch, for convenience. -ifdef(NOASSERT). -define(assertNotMatch(Guard, Expr), ok). -else. -define(assertNotMatch(Guard, Expr), ((fun () -> __V = (Expr), case __V of Guard -> erlang:error({assertNotMatch_failed, [{module, ?MODULE}, {line, ?LINE}, {expression, (??Expr)}, {pattern, (??Guard)}, {value, __V}]}); _ -> ok end end)())). -endif. %% This is a convenience macro which gives more detailed reports when %% the expected LHS value is not a pattern, but a computed value -ifdef(NOASSERT). -define(assertEqual(Expect, Expr), ok). -else. -define(assertEqual(Expect, Expr), ((fun (__X) -> case (Expr) of __X -> ok; __V -> erlang:error({assertEqual_failed, [{module, ?MODULE}, {line, ?LINE}, {expression, (??Expr)}, {expected, __X}, {value, __V}]}) end end)(Expect))). -endif. %% This is the inverse case of assertEqual, for convenience. -ifdef(NOASSERT). -define(assertNotEqual(Unexpected, Expr), ok). -else. -define(assertNotEqual(Unexpected, Expr), ((fun (__X) -> case (Expr) of __X -> erlang:error({assertNotEqual_failed, [{module, ?MODULE}, {line, ?LINE}, {expression, (??Expr)}, {value, __X}]}); _ -> ok end end)(Unexpected))). -endif. %% Note: Class and Term are patterns, and can not be used for value. %% Term can be a guarded pattern, but Class cannot. -ifdef(NOASSERT). -define(assertException(Class, Term, Expr), ok). -else. -define(assertException(Class, Term, Expr), ((fun () -> try (Expr) of __V -> erlang:error({assertException_failed, [{module, ?MODULE}, {line, ?LINE}, {expression, (??Expr)}, {pattern, "{ "++(??Class)++" , "++(??Term) ++" , [...] }"}, {unexpected_success, __V}]}) catch Class:Term -> ok; __C:__T -> erlang:error({assertException_failed, [{module, ?MODULE}, {line, ?LINE}, {expression, (??Expr)}, {pattern, "{ "++(??Class)++" , "++(??Term) ++" , [...] }"}, {unexpected_exception, {__C, __T, erlang:get_stacktrace()}}]}) end end)())). -endif. -define(assertError(Term, Expr), ?assertException(error, Term, Expr)). -define(assertExit(Term, Expr), ?assertException(exit, Term, Expr)). -define(assertThrow(Term, Expr), ?assertException(throw, Term, Expr)). %% This is the inverse case of assertException, for convenience. %% Note: Class and Term are patterns, and can not be used for value. %% Both Class and Term can be guarded patterns. -ifdef(NOASSERT). -define(assertNotException(Class, Term, Expr), ok). -else. -define(assertNotException(Class, Term, Expr), ((fun () -> try (Expr) of _ -> ok catch __C:__T -> case __C of Class -> case __T of Term -> erlang:error({assertNotException_failed, [{module, ?MODULE}, {line, ?LINE}, {expression, (??Expr)}, {pattern, "{ "++(??Class)++" , " ++(??Term)++" , [...] }"}, {unexpected_exception, {__C, __T, erlang:get_stacktrace() }}]}); _ -> ok end; _ -> ok end end end)())). -endif. -endif. % ASSERT_HRL