@@ -11,6 +11,8 @@ _WhenCall _whenCall = null;
1111final List <_VerifyCall > _verifyCalls = < _VerifyCall > [];
1212final _TimeStampProvider _timer = new _TimeStampProvider ();
1313final List _capturedArgs = [];
14+ final List <_ArgMatcher > _typedArgs = < _ArgMatcher > [];
15+ final Map <String , _ArgMatcher > _typedNamedArgs = < String , _ArgMatcher > {};
1416
1517class Mock {
1618 final List <RealCall > _realCalls = < RealCall > [];
@@ -25,7 +27,18 @@ class Mock {
2527
2628 dynamic noSuchMethod (Invocation invocation) {
2729 if (_whenInProgress) {
28- _whenCall = new _WhenCall (this , invocation);
30+ if (_typedArgs.isEmpty && _typedNamedArgs.isEmpty) {
31+ _whenCall = new _WhenCall (this , invocation);
32+ } else {
33+ try {
34+ _whenCall = new _WhenCall (this , new FakeInvocation (invocation));
35+ } catch (e) {
36+ print ("Boo" );
37+ } finally {
38+ _typedArgs.clear ();
39+ _typedNamedArgs.clear ();
40+ }
41+ }
2942 return null ;
3043 } else if (_verificationInProgress) {
3144 _verifyCalls.add (new _VerifyCall (this , invocation));
@@ -48,6 +61,56 @@ class Mock {
4861 String toString () => _givenName != null ? _givenName : runtimeType.toString ();
4962}
5063
64+ class FakeInvocation extends Invocation {
65+ final bool isAccessor;
66+ final bool isGetter;
67+ final bool isMethod;
68+ final bool isSetter;
69+ final Symbol memberName;
70+ final Map <Symbol , dynamic > namedArguments;
71+ final List <dynamic > positionalArguments;
72+
73+ factory FakeInvocation (Invocation invocation) {
74+ if (_typedArgs.isEmpty && _typedNamedArgs.isEmpty) {
75+ throw 'What?' ;
76+ }
77+ var positionalArguments = < _ArgMatcher > [];
78+ var namedArguments = < Symbol , dynamic > {};
79+ if (_typedArgs.length != invocation.positionalArguments.length) {
80+ throw 'All positional args must be typed, but ${_typedArgs .length }, ${invocation .positionalArguments .length }' ;
81+ }
82+ _typedArgs.forEach ((arg) {
83+ positionalArguments.add (arg);
84+ });
85+
86+ // TODO: this can maybe be relaxed.
87+ if (_typedNamedArgs.length != invocation.namedArguments.length) {
88+ throw 'All named args must be typed' ;
89+ }
90+ _typedNamedArgs.forEach ((name, arg) {
91+ namedArguments[new Symbol (name)] = arg;
92+ });
93+
94+ return new FakeInvocation ._(
95+ invocation.isAccessor,
96+ invocation.isGetter,
97+ invocation.isMethod,
98+ invocation.isSetter,
99+ invocation.memberName,
100+ namedArguments,
101+ positionalArguments);
102+ }
103+
104+ FakeInvocation ._(
105+ this .isAccessor,
106+ this .isGetter,
107+ this .isMethod,
108+ this .isSetter,
109+ this .memberName,
110+ this .namedArguments,
111+ this .positionalArguments);
112+ }
113+
51114named (var mock, {String name, int hashCode}) => mock
52115 .._givenName = name
53116 .._givenHashCode = hashCode;
@@ -291,6 +354,15 @@ get captureAny => new _ArgMatcher(anything, true);
291354captureThat (Matcher matcher) => new _ArgMatcher (matcher, true );
292355argThat (Matcher matcher) => new _ArgMatcher (matcher, false );
293356
357+ /*=T*/ typed/*<T>*/ (_ArgMatcher matcher, {String name}) {
358+ if (name == null ) {
359+ _typedArgs.add (matcher);
360+ } else {
361+ _typedNamedArgs[name] = matcher;
362+ }
363+ return null ;
364+ }
365+
294366class VerificationResult {
295367 List captured = [];
296368 int callCount;
0 commit comments