@@ -34,7 +34,7 @@ class Mock {
3434
3535 dynamic noSuchMethod (Invocation invocation) {
3636 if (_typedArgs.isNotEmpty || _typedNamedArgs.isNotEmpty) {
37- invocation = _reconstituteInvocation (invocation);
37+ invocation = new _InvocationForTypedArguments (invocation);
3838 }
3939 if (_whenInProgress) {
4040 _whenCall = new _WhenCall (this , invocation);
@@ -60,26 +60,20 @@ class Mock {
6060 String toString () => _givenName != null ? _givenName : runtimeType.toString ();
6161}
6262
63- // Return a new [Invocation], reconstituted from [invocation], [_typedArgs],
64- // and [_typedNamedArgs].
65- Invocation _reconstituteInvocation (Invocation invocation) {
66- var newInvocation = new FakeInvocation (invocation);
67- return newInvocation;
68- }
69-
70- /// An Invocation implementation that allows all attributes to be passed into
71- /// the constructor.
72- class FakeInvocation extends Invocation {
63+ /// An Invocation implementation that takes arguments from [_typedArgs] and
64+ /// [_typedNamedArgs] .
65+ class _InvocationForTypedArguments extends Invocation {
7366 final Symbol memberName;
7467 final Map <Symbol , dynamic > namedArguments;
7568 final List <dynamic > positionalArguments;
7669 final bool isGetter;
7770 final bool isMethod;
7871 final bool isSetter;
7972
80- factory FakeInvocation (Invocation invocation) {
73+ factory _InvocationForTypedArguments (Invocation invocation) {
8174 if (_typedArgs.isEmpty && _typedNamedArgs.isEmpty) {
82- throw new StateError ("FakeInvocation called when no typed calls have been saved." );
75+ throw new StateError (
76+ "_InvocationForTypedArguments called when no typed calls have been saved." );
8377 }
8478
8579 // Handle named arguments first, so that we can provide useful errors for
@@ -92,7 +86,7 @@ class FakeInvocation extends Invocation {
9286 _typedArgs.clear ();
9387 _typedNamedArgs.clear ();
9488
95- return new FakeInvocation ._(
89+ return new _InvocationForTypedArguments ._(
9690 invocation.memberName,
9791 positionalArguments,
9892 namedArguments,
@@ -101,42 +95,52 @@ class FakeInvocation extends Invocation {
10195 invocation.isSetter);
10296 }
10397
98+ // Reconstitutes the named arguments in an invocation from [_typedNamedArgs].
99+ //
100+ // The namedArguments in [invocation] which are null should be represented
101+ // by a stored value in [_typedNamedArgs]. The null presumably came from
102+ // [typed].
104103 static Map <Symbol ,dynamic > _reconstituteNamedArgs (Invocation invocation) {
105104 var namedArguments = < Symbol , dynamic > {};
106105 var _typedNamedArgSymbols = _typedNamedArgs.keys.map ((name) => new Symbol (name));
106+
107+ // Iterate through [invocation]'s named args, validate them, and add them
108+ // to the return map.
107109 invocation.namedArguments.forEach ((name, arg) {
108110 if (arg == null ) {
109111 if (! _typedNamedArgSymbols.contains (name)) {
110112 // Incorrect usage of [typed], something like:
111113 // `when(obj.fn(a: typed(any)))`.
112114 throw new ArgumentError (
113115 'A typed argument was passed in as a named argument named "$name ", '
114- 'but did not a value for its name . Each typed argument that is '
115- 'passed as a named argument needs to specify the `name ` argument. '
116- 'For example: `when(obj.fn(x: typed(any, name : "x")))`.' );
116+ 'but did not pass a value for `named` . Each typed argument that is '
117+ 'passed as a named argument needs to specify the `named ` argument. '
118+ 'For example: `when(obj.fn(x: typed(any, named : "x")))`.' );
117119 }
118120 } else {
119121 // Add each real named argument that was _not_ passed with [typed].
120122 namedArguments[name] = arg;
121123 }
122124 });
123125
126+ // Iterate through the stored named args (stored with [typed]), validate
127+ // them, and add them to the return map.
124128 _typedNamedArgs.forEach ((name, arg) {
125129 Symbol nameSymbol = new Symbol (name);
126130 if (! invocation.namedArguments.containsKey (nameSymbol)) {
127- // Incorrect usage of [name], something like:
128- // `when(obj.fn(typed(any, name: 'a')))`.
129131 throw new ArgumentError (
130- 'A typed argument was declared with name $name , but was not passed '
131- 'as an argument named $name .' );
132+ 'A typed argument was declared as named $name , but was not passed '
133+ 'as an argument named $name .\n\n '
134+ 'BAD: when(obj.fn(typed(any, named: "a")))\n '
135+ 'GOOD: when(obj.fn(a: typed(any, named: "a")))' );
132136 }
133137 if (invocation.namedArguments[nameSymbol] != null ) {
134- // Incorrect usage of [name], something like:
135- // `when(obj.fn(a: typed(any, name: 'b'), b: "string"))`.
136138 throw new ArgumentError (
137- 'A typed argument was declared with name $name , but a different '
139+ 'A typed argument was declared as named $name , but a different '
138140 'value (${invocation .namedArguments [nameSymbol ]}) was passed as '
139- '$name .' );
141+ '$name .\n\n '
142+ 'BAD: when(obj.fn(b: typed(any, name: "a")))\n '
143+ 'GOOD: when(obj.fn(b: typed(any, name: "b")))' );
140144 }
141145 namedArguments[nameSymbol] = arg;
142146 });
@@ -153,31 +157,32 @@ class FakeInvocation extends Invocation {
153157 'null arguments are not allowed alongside typed(); use '
154158 '"typed(eq(null))"' );
155159 }
156- int i = 0 ;
157- int j = 0 ;
158- while (i < _typedArgs.length && j < invocation.positionalArguments.length) {
159- var arg = _typedArgs[i];
160- if (invocation.positionalArguments[j] == null ) {
160+ int typedIndex = 0 ;
161+ int positionalIndex = 0 ;
162+ while (typedIndex < _typedArgs.length &&
163+ positionalIndex < invocation.positionalArguments.length) {
164+ var arg = _typedArgs[typedIndex];
165+ if (invocation.positionalArguments[positionalIndex] == null ) {
161166 // [typed] was used; add the [_ArgMatcher] given to [typed].
162167 positionalArguments.add (arg);
163- i ++ ;
164- j ++ ;
168+ typedIndex ++ ;
169+ positionalIndex ++ ;
165170 } else {
166171 // [typed] was not used; add the [_ArgMatcher] from [invocation].
167- positionalArguments.add (invocation.positionalArguments[j ]);
168- j ++ ;
172+ positionalArguments.add (invocation.positionalArguments[positionalIndex ]);
173+ positionalIndex ++ ;
169174 }
170175 }
171- while (j < invocation.positionalArguments.length) {
176+ while (positionalIndex < invocation.positionalArguments.length) {
172177 // Some trailing non-[typed] arguments.
173- positionalArguments.add (invocation.positionalArguments[j ]);
174- j ++ ;
178+ positionalArguments.add (invocation.positionalArguments[positionalIndex ]);
179+ positionalIndex ++ ;
175180 }
176181
177182 return positionalArguments;
178183 }
179184
180- FakeInvocation ._(
185+ _InvocationForTypedArguments ._(
181186 this .memberName,
182187 this .positionalArguments,
183188 this .namedArguments,
@@ -431,11 +436,11 @@ get captureAny => new _ArgMatcher(anything, true);
431436captureThat (Matcher matcher) => new _ArgMatcher (matcher, true );
432437argThat (Matcher matcher) => new _ArgMatcher (matcher, false );
433438
434- /*=T*/ typed/*<T>*/ (_ArgMatcher matcher, {String name }) {
435- if (name == null ) {
439+ /*=T*/ typed/*<T>*/ (_ArgMatcher matcher, {String named }) {
440+ if (named == null ) {
436441 _typedArgs.add (matcher);
437442 } else {
438- _typedNamedArgs[name ] = matcher;
443+ _typedNamedArgs[named ] = matcher;
439444 }
440445 return null ;
441446}
0 commit comments