Skip to content

Commit e0e0480

Browse files
authored
Merge pull request #13 from amoldavsky/unit-test-minified
various updates to unit tests
2 parents bb9319a + 007b945 commit e0e0480

File tree

8 files changed

+28289
-13
lines changed

8 files changed

+28289
-13
lines changed

README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,16 @@ You may use this API the same way for POST, PUT, UPDATE, and DELETE.
8080
8181
The code adds a custom decorator function to the existing angular mock namespace which already hold similar decorator functions - angular.mock.$HttpBackendAsyncDecorator.
8282
83+
## Developing & Testing
84+
85+
gulpfile.js has the following tasks:
86+
```
87+
compile
88+
test-unminified
89+
test-minified
90+
```
91+
Please be sure to run these tests when making changes
92+
8393
8494
## License
8595
MIT

circle.yml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,21 @@
11
machine:
22
node:
33
version:
4-
6.3.0
4+
6.9.4
55

66
dependencies:
77
pre:
88
#- npm install -g karma
9-
- npm install -g karma-cli
9+
#- npm install -g karma-cli
1010
cache_directories:
1111
- ~/nvm
1212

1313
test:
1414
override:
1515
- npm install
16-
#- nohup bash -c "karma start &"
17-
#- bash -c "karma start"
18-
#- bash -c "./node_modules/karma-cli/bin/karma start &"
19-
- ./node_modules/karma-cli/bin/karma start karma.conf.js --single-run
16+
#- ./node_modules/karma-cli/bin/karma start karma.conf.js --single-run
17+
- ./node_modules/gulp-cli/bin/gulp.js test-unminified
18+
- ./node_modules/gulp-cli/bin/gulp.js test-minified
19+
2020
post:
2121
- bash <(curl -s https://codecov.io/bash)

dist/angular-mocks-async.js

Lines changed: 219 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,219 @@
1+
/**
2+
* An abstraction on top of ngMockE2E to support async calls using
3+
* promises.
4+
*
5+
* If you need to make an async operation ( such as working
6+
* with WebSQL ) the orignial ngMockE2E will fall through and you will never
7+
* have the chance to respond with your own response.
8+
*
9+
* ngMockE2EAsync decorates the $httpBackend by utilizing promises. Responses
10+
* can now be in a form of a promise where the $httpBackend will original function
11+
* will not be called until your promise has been resolved. Once resolved the original
12+
* $httpBackend APIs will be called and things will flow their natural ways back to the
13+
* caller.
14+
*
15+
* @ngdoc module
16+
* @namespace ngMockE2EAsync
17+
* @author Assaf Moldavsky
18+
* @version 0.9b
19+
*/
20+
(function( ng ) {
21+
22+
var httpMock = ng.module( "ngMockE2EAsync", [ 'ngMockE2E' ] );
23+
24+
ng.mock.$HttpBackendAsyncDecorator = [ '$rootScope', '$q', '$delegate', '$browser', createHttpBackendAsyncMock ];
25+
26+
function createHttpBackendAsyncMock( $rootScope, $q, $delegate, $browser ) {
27+
28+
var definnitionsAsync = [];
29+
30+
function $httpBackendAsync( method, url, data, callback, headers, timeout, withCredentials ) {
31+
32+
var d = match( method, url, data, headers );
33+
if ( !d || d.passThrough || !d.getPromise ) {
34+
return $delegate.call(this, method, url, data, callback, headers);
35+
}
36+
37+
if( !d.getPromise || ! typeof d.getPromise === 'function' ) {
38+
throw 'unexpected response: ' + d.getPromise;
39+
}
40+
41+
// we will define an interceptor which will be executed
42+
// before the actual function is executed. Thsi way
43+
// we first execute our code and than call the original
44+
var interceptor = function ( /* arguments we don't care about */ ) {
45+
46+
var whenAsyncConfig = ng.copy( d );
47+
delete whenAsyncConfig.getPromise;
48+
49+
var promise = d.getPromise( method, url, data, headers, whenAsyncConfig );
50+
51+
if( !promise || ( typeof promise.then !== 'function' ) ) {
52+
throw 'unexpected response: ' + promise;
53+
}
54+
55+
promise.then( function( response ) {
56+
57+
if( !response ) {
58+
throw 'response was unexpected: ' + response;
59+
}
60+
61+
// callback is the orignial function which we are wrapping / decorating
62+
callback.apply( this, response );
63+
64+
});
65+
66+
};
67+
68+
return $delegate.call(this, method, url, data, interceptor, headers);
69+
70+
}
71+
72+
// copy all existing APIs from the $delegate into the decorator
73+
for( var key in $delegate ) {
74+
$httpBackendAsync[ key ] = $delegate[ key ];
75+
}
76+
77+
// matchers just like in AgnularJS itself
78+
function match( method, url, data, headers ) {
79+
80+
var defs = definnitionsAsync;
81+
82+
for (var i = -1; ++i < defs.length;) {
83+
84+
var def = definnitionsAsync[i];
85+
86+
if ( def.method.toUpperCase() === method.toUpperCase() ) {
87+
if ( matchUrl( def.url, url )
88+
&& (!angular.isDefined( data ) || matchData( def.data, data ))
89+
&& (!angular.isDefined( headers ) || matchHeaders( def.headers, headers ))) {
90+
91+
return def;
92+
}
93+
}
94+
}
95+
};
96+
97+
function matchUrl( url, u ) {
98+
99+
if (!url) return true;
100+
if (angular.isFunction(url.test))return url.test(u);
101+
if (angular.isFunction(url))return url(u);
102+
return url == u;
103+
104+
};
105+
function matchHeaders( headers, h ) {
106+
107+
if (angular.isUndefined(headers))return true;
108+
if (angular.isFunction(headers)) return headers(h);
109+
return angular.equals(headers, h);
110+
111+
};
112+
function matchData( data, d ) {
113+
114+
if (angular.isUndefined(data)) return true;
115+
if (data && angular.isFunction(data.test)) return data.test(d);
116+
if (data && angular.isFunction(data)) return data(d);
117+
if (data && !angular.isString(data)) {
118+
return angular.equals(angular.fromJson(angular.toJson(data)), angular.fromJson(d));
119+
}
120+
return ( data == d );
121+
122+
};
123+
124+
// decorate $httpBackend#when() and $httpBackend#expect()
125+
function argumentsToArray( arguments ) {
126+
var array = [];
127+
for( var i = 0, len = arguments.length; i < len; i++ ) {
128+
array.push( arguments[i] );
129+
}
130+
131+
return array;
132+
}
133+
$httpBackendAsync.whenAsync = function() {
134+
return whenAsync.apply( $httpBackendAsync, [ $delegate.when ].concat( argumentsToArray( arguments ) ) );
135+
};
136+
$httpBackendAsync.expectAsync = function() {
137+
return expectAsync.apply( $httpBackendAsync, [ $delegate.expect ].concat( argumentsToArray( arguments ) ) );
138+
};
139+
140+
var expectAsync = whenAsync;
141+
function whenAsync( deletageMethod, method, url, data, headers, keys ) {
142+
143+
function MockHttpExpectation( method, url, data, headers, keys, promiseFn ) {
144+
145+
this.method = method;
146+
this.url = url;
147+
this.data = data;
148+
this.header = headers;
149+
this.keys = keys;
150+
this.getPromise = promiseFn; // this will be called in our decorated constructor when the $http provider is used
151+
152+
};
153+
154+
var def = new MockHttpExpectation( method, url, data, headers, keys, null );
155+
var chain = deletageMethod.call( $delegate, method, url, data, headers );
156+
157+
var ret = {
158+
respond: function ( response ) {
159+
160+
// we want to differentiate between a function and a promise
161+
162+
if( response ) {
163+
164+
if( typeof response === 'function' ) {
165+
166+
// we ASSUME that when executed this function will return a promise
167+
def.getPromise = response;
168+
169+
} else if( response.then && ( typeof response.then === 'function' ) ) {
170+
171+
// we got a raw promise, we need to wrap it in a function
172+
def.getPromise = function( method, url, data, headers, keys ) {
173+
return response;
174+
};
175+
176+
} else {
177+
178+
throw 'unexpected response ' + response;
179+
180+
}
181+
182+
// call the real function
183+
chain.respond.apply( chain, function() {} );
184+
185+
} else {
186+
// call the real function
187+
chain.respond.apply( chain, arguments );
188+
}
189+
190+
return ret;
191+
},
192+
passThrough: function () { // TODO: Assaf: not sure what to do with passthrough for now
193+
/*
194+
// the def used be have these parameters: [ method, url, data, headers, 0, undefined ];
195+
196+
def[4] = 0;
197+
def[5] = true;
198+
chain.passThrough.apply(chain);
199+
return ret;
200+
*/
201+
}
202+
};
203+
204+
definnitionsAsync.push( def );
205+
return ret;
206+
};
207+
208+
return $httpBackendAsync;
209+
210+
}
211+
212+
httpMock.config(['$provide',function( $provide ) {
213+
214+
$provide.decorator( '$httpBackend', angular.mock.$HttpBackendAsyncDecorator );
215+
216+
}]);
217+
218+
219+
})( angular );

dist/angular-mocks-async.min.js

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)