From 141c94fa7a7225360d15a4e977a786b4d4c2cfb0 Mon Sep 17 00:00:00 2001 From: Cyril Adrian Date: Wed, 28 Oct 2015 21:40:45 +0100 Subject: [PATCH] mocker enhancements --- src/lib/tests/mock/matcher/mock_any.e | 10 ++ src/lib/tests/mock/matcher/mock_eq.e | 13 +++ src/lib/tests/mock/mock_argument.e | 7 ++ src/lib/tests/mock/mock_arguments.e | 27 ++++++ src/lib/tests/mock/mock_expectation.e | 19 ++++ src/lib/tests/mock/mock_expectation_group.e | 8 ++ src/lib/tests/mock/mock_expectation_groups.e | 3 +- .../tests/mock/mock_function_expectation.e | 2 +- src/lib/tests/mock/mock_matcher.e | 6 ++ src/lib/tests/mock/mock_matchers.e | 95 +++++++++++++++++++ src/lib/tests/mock/mock_object.e | 24 +++++ .../tests/mock/mock_procedure_expectation.e | 2 +- src/lib/tests/mock/mock_scenario.e | 10 +- src/lib/tests/mock/mock_typed_argument.e | 5 + src/lib/tests/mock/mock_typed_expectation.e | 15 ++- src/tools/mocker/mocker_expect.e | 12 ++- 16 files changed, 251 insertions(+), 7 deletions(-) diff --git a/src/lib/tests/mock/matcher/mock_any.e b/src/lib/tests/mock/matcher/mock_any.e index ed0758a4d8..29fce6ca06 100644 --- a/src/lib/tests/mock/matcher/mock_any.e +++ b/src/lib/tests/mock/matcher/mock_any.e @@ -6,6 +6,16 @@ class MOCK_ANY[E_] inherit MOCK_TYPED_MATCHER[E_] +feature {ANY} + out_in_tagged_out_memory + local + e: E_ + do + tagged_out_memory.append(once "') + end + feature {MOCK_EXPECTATION} match (a: MOCK_TYPED_ARGUMENT[E_]): BOOLEAN do diff --git a/src/lib/tests/mock/matcher/mock_eq.e b/src/lib/tests/mock/matcher/mock_eq.e index bf96889c76..69457e9dc6 100644 --- a/src/lib/tests/mock/matcher/mock_eq.e +++ b/src/lib/tests/mock/matcher/mock_eq.e @@ -8,10 +8,23 @@ inherit insert SAFE_EQUAL[E_] + redefine + out_in_tagged_out_memory + end create {ANY} make +feature {ANY} + out_in_tagged_out_memory + do + if item = Void then + tagged_out_memory.append(once "Void") + else + item.out_in_tagged_out_memory + end + end + feature {MOCK_EXPECTATION} match (a: MOCK_TYPED_ARGUMENT[E_]): BOOLEAN do diff --git a/src/lib/tests/mock/mock_argument.e b/src/lib/tests/mock/mock_argument.e index d1a50f11b7..0c6a4bde4b 100644 --- a/src/lib/tests/mock/mock_argument.e +++ b/src/lib/tests/mock/mock_argument.e @@ -5,6 +5,13 @@ deferred class MOCK_ARGUMENT -- -- Tag type used by the mock framework -- + +insert + ANY + undefine + out_in_tagged_out_memory + end + end -- class MOCK_ARGUMENT -- -- Copyright (c) 2013-2015 Cyril ADRIAN diff --git a/src/lib/tests/mock/mock_arguments.e b/src/lib/tests/mock/mock_arguments.e index a5fbbc9235..fcee055b8e 100644 --- a/src/lib/tests/mock/mock_arguments.e +++ b/src/lib/tests/mock/mock_arguments.e @@ -3,6 +3,12 @@ -- class MOCK_ARGUMENTS +insert + ANY + redefine + out_in_tagged_out_memory + end + create {MOCK_EXPECT, MOCK_OBJECT} make0, make1, make2, make3, make4, make5, make6, make7, make8, make9, make10 @@ -24,6 +30,27 @@ feature {ANY} Result := arguments.item(i - 1) end + out_in_tagged_out_memory + local + i: INTEGER + do + if count > 0 then + tagged_out_memory.extend('(') + from + i := arguments.lower + until + i > arguments.upper + loop + if i > arguments.lower then + tagged_out_memory.append(once ", ") + end + arguments.item(i).out_in_tagged_out_memory + i := i + 1 + end + tagged_out_memory.extend(')') + end + end + feature {} make0 do diff --git a/src/lib/tests/mock/mock_expectation.e b/src/lib/tests/mock/mock_expectation.e index 1ec32e3ad6..81eeb88b4b 100644 --- a/src/lib/tests/mock/mock_expectation.e +++ b/src/lib/tests/mock/mock_expectation.e @@ -3,6 +3,12 @@ -- deferred class MOCK_EXPECTATION +insert + ANY + undefine + out_in_tagged_out_memory + end + feature {ANY} ready: BOOLEAN deferred @@ -23,9 +29,20 @@ feature {ANY} a_feature_name.is_interned a_arguments /= Void deferred + ensure + Result implies target.missing_expectations /= Void end feature {MOCK_EXPECTATION_GROUP} + replay (missing_expectations: COLLECTION[MOCK_EXPECTATION]) + require + missing_expectations /= Void + do + target.replay(missing_expectations) + ensure + target.missing_expectations = missing_expectations + end + done deferred ensure @@ -34,6 +51,8 @@ feature {MOCK_EXPECTATION_GROUP} all_called deferred + ensure + target.missing_expectations = Void end all_done_message_in (message: STRING) diff --git a/src/lib/tests/mock/mock_expectation_group.e b/src/lib/tests/mock/mock_expectation_group.e index 724105561b..8ec65556f6 100644 --- a/src/lib/tests/mock/mock_expectation_group.e +++ b/src/lib/tests/mock/mock_expectation_group.e @@ -57,6 +57,14 @@ feature {MOCK_EXPECTATION_GROUPS} Result /= Void implies Result.can_call(a_target, a_feature_name, a_arguments) end + replay_all (missing_expectations: COLLECTION[MOCK_EXPECTATION]) + do + expectations.for_each(agent (mexps: COLLECTION[MOCK_EXPECTATION]; exps: FAST_ARRAY[MOCK_EXPECTATION]) + do + exps.for_each(agent {MOCK_EXPECTATION}.replay(mexps)) + end (missing_expectations, ?)) + end + all_called do expectations.for_each(agent {FAST_ARRAY[MOCK_EXPECTATION]}.for_each(agent {MOCK_EXPECTATION}.all_called)) diff --git a/src/lib/tests/mock/mock_expectation_groups.e b/src/lib/tests/mock/mock_expectation_groups.e index cbe34bf49a..9053b192c1 100644 --- a/src/lib/tests/mock/mock_expectation_groups.e +++ b/src/lib/tests/mock/mock_expectation_groups.e @@ -25,11 +25,12 @@ feature {MOCK_SCENARIO} groups.add_last(create {MOCK_EXPECTATION_GROUP}.make) end - replay_all + replay_all (missing_expectations: COLLECTION[MOCK_EXPECTATION]) require not is_replaying do check_index.set_item(groups.lower) + groups.for_each(agent {MOCK_EXPECTATION_GROUP}.replay_all(missing_expectations)) ensure is_replaying end diff --git a/src/lib/tests/mock/mock_function_expectation.e b/src/lib/tests/mock/mock_function_expectation.e index f967b9176e..3dd7555cca 100644 --- a/src/lib/tests/mock/mock_function_expectation.e +++ b/src/lib/tests/mock/mock_function_expectation.e @@ -4,7 +4,7 @@ class MOCK_FUNCTION_EXPECTATION[T_ -> TUPLE, R_] inherit - MOCK_TYPED_EXPECTATION + MOCK_TYPED_EXPECTATION[T_] create {MOCK_EXPECT} make diff --git a/src/lib/tests/mock/mock_matcher.e b/src/lib/tests/mock/mock_matcher.e index 4c73e57292..8775017527 100644 --- a/src/lib/tests/mock/mock_matcher.e +++ b/src/lib/tests/mock/mock_matcher.e @@ -6,6 +6,12 @@ deferred class MOCK_MATCHER -- Tag type used by the mock framework -- +insert + ANY + undefine + out_in_tagged_out_memory + end + feature {MOCK_EXPECTATION} match (a: MOCK_ARGUMENT): BOOLEAN require diff --git a/src/lib/tests/mock/mock_matchers.e b/src/lib/tests/mock/mock_matchers.e index 0364633f68..fdff940005 100644 --- a/src/lib/tests/mock/mock_matchers.e +++ b/src/lib/tests/mock/mock_matchers.e @@ -3,6 +3,12 @@ -- class MOCK_MATCHERS +insert + ANY + redefine + out_in_tagged_out_memory + end + create {MOCK_EXPECT} make0, make1, make2, make3, make4, make5, make6, make7, make8, make9, make10 @@ -24,6 +30,27 @@ feature {MOCK_EXPECTATION} Result := matchers.item(i - 1) end + out_in_tagged_out_memory + local + i: INTEGER + do + if count > 0 then + tagged_out_memory.extend('(') + from + i := matchers.lower + until + i > matchers.upper + loop + if i > matchers.lower then + tagged_out_memory.append(once ", ") + end + matchers.item(i).out_in_tagged_out_memory + i := i + 1 + end + tagged_out_memory.extend(')') + end + end + feature {} make0 do @@ -31,57 +58,125 @@ feature {} end make1 (a1: MOCK_MATCHER) + require + a1 /= Void do matchers := {FAST_ARRAY[MOCK_MATCHER] << a1 >> } end make2 (a1, a2: MOCK_MATCHER) + require + a1 /= Void + a2 /= Void do matchers := {FAST_ARRAY[MOCK_MATCHER] << a1, a2 >> } end make3 (a1, a2, a3: MOCK_MATCHER) + require + a1 /= Void + a2 /= Void + a3 /= Void do matchers := {FAST_ARRAY[MOCK_MATCHER] << a1, a2, a3 >> } end make4 (a1, a2, a3, a4: MOCK_MATCHER) + require + a1 /= Void + a2 /= Void + a3 /= Void + a4 /= Void do matchers := {FAST_ARRAY[MOCK_MATCHER] << a1, a2, a3, a4 >> } end make5 (a1, a2, a3, a4, a5: MOCK_MATCHER) + require + a1 /= Void + a2 /= Void + a3 /= Void + a4 /= Void + a5 /= Void do matchers := {FAST_ARRAY[MOCK_MATCHER] << a1, a2, a3, a4, a5 >> } end make6 (a1, a2, a3, a4, a5, a6: MOCK_MATCHER) + require + a1 /= Void + a2 /= Void + a3 /= Void + a4 /= Void + a5 /= Void + a6 /= Void do matchers := {FAST_ARRAY[MOCK_MATCHER] << a1, a2, a3, a4, a5, a6 >> } end make7 (a1, a2, a3, a4, a5, a6, a7: MOCK_MATCHER) + require + a1 /= Void + a2 /= Void + a3 /= Void + a4 /= Void + a5 /= Void + a6 /= Void + a7 /= Void do matchers := {FAST_ARRAY[MOCK_MATCHER] << a1, a2, a3, a4, a5, a6, a7 >> } end make8 (a1, a2, a3, a4, a5, a6, a7, a8: MOCK_MATCHER) + require + a1 /= Void + a2 /= Void + a3 /= Void + a4 /= Void + a5 /= Void + a6 /= Void + a7 /= Void + a8 /= Void do matchers := {FAST_ARRAY[MOCK_MATCHER] << a1, a2, a3, a4, a5, a6, a7, a8 >> } end make9 (a1, a2, a3, a4, a5, a6, a7, a8, a9: MOCK_MATCHER) + require + a1 /= Void + a2 /= Void + a3 /= Void + a4 /= Void + a5 /= Void + a6 /= Void + a7 /= Void + a8 /= Void + a9 /= Void do matchers := {FAST_ARRAY[MOCK_MATCHER] << a1, a2, a3, a4, a5, a6, a7, a8, a9 >> } end make10 (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10: MOCK_MATCHER) + require + a1 /= Void + a2 /= Void + a3 /= Void + a4 /= Void + a5 /= Void + a6 /= Void + a7 /= Void + a8 /= Void + a9 /= Void + a10 /= Void do matchers := {FAST_ARRAY[MOCK_MATCHER] << a1, a2, a3, a4, a5, a6, a7, a8, a9, a10 >> } end matchers: FAST_ARRAY[MOCK_MATCHER] +invariant + matchers.for_all(agent (m: MOCK_MATCHER): BOOLEAN do then m /= Void end(?)) + end -- class MOCK_MATCHERS -- -- Copyright (c) 2013-2015 Cyril ADRIAN diff --git a/src/lib/tests/mock/mock_object.e b/src/lib/tests/mock/mock_object.e index 671f9effb4..aa2b0293ae 100644 --- a/src/lib/tests/mock/mock_object.e +++ b/src/lib/tests/mock/mock_object.e @@ -5,6 +5,30 @@ deferred class MOCK_OBJECT -- -- Tag type used by the mock framework -- + +feature {MOCK_EXPECT} + add_missing_expectation(expectation: MOCK_EXPECTATION) + require + expectation /= Void + do + missing_expectations.add_last(expectation) + end + + can_add_missing_expectation: BOOLEAN + do + Result := missing_expectations /= Void + end + +feature {MOCK_EXPECTATION} + missing_expectations: COLLECTION[MOCK_EXPECTATION] + + replay (a_missing_expectations: like missing_expectations) + do + missing_expectations := a_missing_expectations + ensure + missing_expectations = a_missing_expectations + end + end -- class MOCK_OBJECT -- -- Copyright (c) 2013-2015 Cyril ADRIAN diff --git a/src/lib/tests/mock/mock_procedure_expectation.e b/src/lib/tests/mock/mock_procedure_expectation.e index 31d571ff16..e2fbf0f388 100644 --- a/src/lib/tests/mock/mock_procedure_expectation.e +++ b/src/lib/tests/mock/mock_procedure_expectation.e @@ -4,7 +4,7 @@ class MOCK_PROCEDURE_EXPECTATION[T_ -> TUPLE] inherit - MOCK_TYPED_EXPECTATION + MOCK_TYPED_EXPECTATION[T_] export {MOCK_OBJECT} call end diff --git a/src/lib/tests/mock/mock_scenario.e b/src/lib/tests/mock/mock_scenario.e index 31cfb44e45..1e38338c43 100644 --- a/src/lib/tests/mock/mock_scenario.e +++ b/src/lib/tests/mock/mock_scenario.e @@ -21,10 +21,15 @@ feature {EIFFELTEST_TOOLS} replay_all require not is_replaying + local + mexps: FAST_ARRAY[MOCK_EXPECTATION] do - groups.replay_all + create mexps.with_capacity(0) + missing_expectations := mexps + groups.replay_all(mexps) ensure is_replaying + missing_expectations.is_empty end is_replaying: BOOLEAN @@ -32,6 +37,9 @@ feature {EIFFELTEST_TOOLS} Result := groups.is_replaying end +feature {ANY} + missing_expectations: TRAVERSABLE[MOCK_EXPECTATION] + feature {MOCK_EXPECT} check_call (a_target: MOCK_OBJECT; a_feature_name: FIXED_STRING; a_arguments: MOCK_ARGUMENTS): MOCK_EXPECTATION require diff --git a/src/lib/tests/mock/mock_typed_argument.e b/src/lib/tests/mock/mock_typed_argument.e index f0e31f2158..f1764bf806 100644 --- a/src/lib/tests/mock/mock_typed_argument.e +++ b/src/lib/tests/mock/mock_typed_argument.e @@ -12,6 +12,11 @@ create {MOCK_EXPECT, MOCK_OBJECT} feature {ANY} item: E_ + out_in_tagged_out_memory + do + item.out_in_tagged_out_memory + end + feature {} make (e: E_) do diff --git a/src/lib/tests/mock/mock_typed_expectation.e b/src/lib/tests/mock/mock_typed_expectation.e index d0fc491835..3ca40ccdf4 100644 --- a/src/lib/tests/mock/mock_typed_expectation.e +++ b/src/lib/tests/mock/mock_typed_expectation.e @@ -1,13 +1,16 @@ -- This file is part of a Liberty Eiffel library. -- See the full copyright at the end. -- -deferred class MOCK_TYPED_EXPECTATION +deferred class MOCK_TYPED_EXPECTATION[T_ -> TUPLE] inherit MOCK_EXPECTATION insert EIFFELTEST_TOOLS + redefine + out_in_tagged_out_memory + end feature {ANY} ready: BOOLEAN @@ -21,6 +24,14 @@ feature {ANY} Result := counter /= Void end + out_in_tagged_out_memory + do + target.out_in_tagged_out_memory + tagged_out_memory.extend('.') + tagged_out_memory.append(feature_name) + arg_matchers.out_in_tagged_out_memory + end + feature {ANY} times, infix "*" (how_many: INTEGER): like Current require @@ -59,6 +70,7 @@ feature {ANY} and then feature_name = a_feature_name and then match_arguments(a_arguments) and then counter.can_call + and then target.missing_expectations /= Void end feature {} @@ -100,6 +112,7 @@ feature {MOCK_EXPECTATION_GROUP} all_called do counter.all_called + target.replay(Void) end all_done_message_in (message: STRING) diff --git a/src/tools/mocker/mocker_expect.e b/src/tools/mocker/mocker_expect.e index b78bad54db..021da95e75 100644 --- a/src/tools/mocker/mocker_expect.e +++ b/src/tools/mocker/mocker_expect.e @@ -144,7 +144,14 @@ feature {#(1)} assert_#(2)#(3): #(4) do Result ::= scenario.check_call(target, feature_name_#(2), #(5)) - label_assert(feature_name_#(2), Result /= Void) + if Result = Void then + label_assert("Unexpected call to #(2) - missing expect?", False) + if target.can_add_missing_expectation then + target.add_missing_expectation(create {#(4)}.make(target, feature_name_#(2), #(6))) + else + label_assert("Unwanted call to #(2) - missing replay_all?", False) + end + end end feature_name_#(2): FIXED_STRING @@ -157,7 +164,8 @@ feature {#(1)} # signature.feature_name # signature.simple_arguments_signature # expectation_type - # signature.argument_arguments) + # signature.argument_arguments + # signature.matcher_arguments) else Precursor(node) end