vendor/assets/javascripts/angular-mocks.js in angularjs-rails-1.0.8 vs vendor/assets/javascripts/angular-mocks.js in angularjs-rails-1.2.0.rc1
- old
+ new
@@ -1,7 +1,7 @@
/**
- * @license AngularJS v1.0.8
+ * @license AngularJS v1.2.0rc1
* (c) 2010-2012 Google, Inc. http://angularjs.org
* License: MIT
*
* TODO(vojta): wrap whole file into closure during build
*/
@@ -116,11 +116,27 @@
while (self.deferredFns.length && self.deferredFns[0].time <= self.defer.now) {
self.deferredFns.shift().fn();
}
};
+
/**
+ * @name ngMock.$browser#defer.flushNext
+ * @methodOf ngMock.$browser
+ *
+ * @description
+ * Flushes next pending request and compares it to the provided delay
+ *
+ * @param {number=} expectedDelay the delay value that will be asserted against the delay of the next timeout function
+ */
+ self.defer.flushNext = function(expectedDelay) {
+ var tick = self.deferredFns.shift();
+ expect(tick.time).toEqual(expectedDelay);
+ tick.fn();
+ };
+
+ /**
* @name ngMock.$browser#defer.now
* @propertyOf ngMock.$browser
*
* @description
* Current milliseconds mock time.
@@ -291,22 +307,36 @@
* (one array per logging level). These arrays are exposed as `logs` property of each of the
* level-specific log function, e.g. for level `error` the array is exposed as `$log.error.logs`.
*
*/
angular.mock.$LogProvider = function() {
+ var debug = true;
function concat(array1, array2, index) {
return array1.concat(Array.prototype.slice.call(array2, index));
}
+ this.debugEnabled = function(flag) {
+ if (isDefined(flag)) {
+ debug = flag;
+ return this;
+ } else {
+ return debug;
+ }
+ };
this.$get = function () {
var $log = {
log: function() { $log.log.logs.push(concat([], arguments, 0)); },
warn: function() { $log.warn.logs.push(concat([], arguments, 0)); },
info: function() { $log.info.logs.push(concat([], arguments, 0)); },
- error: function() { $log.error.logs.push(concat([], arguments, 0)); }
+ error: function() { $log.error.logs.push(concat([], arguments, 0)); },
+ debug: function() {
+ if (debug) {
+ $log.debug.logs.push(concat([], arguments, 0));
+ }
+ }
};
/**
* @ngdoc method
* @name ngMock.$log#reset
@@ -331,38 +361,38 @@
* </pre>
*/
$log.log.logs = [];
/**
* @ngdoc property
- * @name ngMock.$log#warn.logs
+ * @name ngMock.$log#info.logs
* @propertyOf ngMock.$log
*
* @description
- * Array of messages logged using {@link ngMock.$log#warn}.
+ * Array of messages logged using {@link ngMock.$log#info}.
*
* @example
* <pre>
- * $log.warn('Some Warning');
- * var first = $log.warn.logs.unshift();
+ * $log.info('Some Info');
+ * var first = $log.info.logs.unshift();
* </pre>
*/
- $log.warn.logs = [];
+ $log.info.logs = [];
/**
* @ngdoc property
- * @name ngMock.$log#info.logs
+ * @name ngMock.$log#warn.logs
* @propertyOf ngMock.$log
*
* @description
- * Array of messages logged using {@link ngMock.$log#info}.
+ * Array of messages logged using {@link ngMock.$log#warn}.
*
* @example
* <pre>
- * $log.info('Some Info');
- * var first = $log.info.logs.unshift();
+ * $log.warn('Some Warning');
+ * var first = $log.warn.logs.unshift();
* </pre>
*/
- $log.info.logs = [];
+ $log.warn.logs = [];
/**
* @ngdoc property
* @name ngMock.$log#error.logs
* @propertyOf ngMock.$log
*
@@ -374,10 +404,25 @@
* $log.log('Some Error');
* var first = $log.error.logs.unshift();
* </pre>
*/
$log.error.logs = [];
+ /**
+ * @ngdoc property
+ * @name ngMock.$log#debug.logs
+ * @propertyOf ngMock.$log
+ *
+ * @description
+ * Array of messages logged using {@link ngMock.$log#debug}.
+ *
+ * @example
+ * <pre>
+ * $log.debug('Some Error');
+ * var first = $log.debug.logs.unshift();
+ * </pre>
+ */
+ $log.debug.logs = []
};
/**
* @ngdoc method
* @name ngMock.$log#assertEmpty
@@ -386,11 +431,11 @@
* @description
* Assert that the all of the logging methods have no logged messages. If messages present, an exception is thrown.
*/
$log.assertEmpty = function() {
var errors = [];
- angular.forEach(['error', 'warn', 'info', 'log'], function(logLevel) {
+ angular.forEach(['error', 'warn', 'info', 'log', 'debug'], function(logLevel) {
angular.forEach($log[logLevel].logs, function(log) {
angular.forEach(log, function (logItem) {
errors.push('MOCK $log (' + logLevel + '): ' + String(logItem) + '\n' + (logItem.stack || ''));
});
});
@@ -478,10 +523,11 @@
* newYearInBratislava.getFullYear() => 2010;
* newYearInBratislava.getMonth() => 0;
* newYearInBratislava.getDate() => 1;
* newYearInBratislava.getHours() => 0;
* newYearInBratislava.getMinutes() => 0;
+ * newYearInBratislava.getSeconds() => 0;
* </pre>
*
*/
angular.mock.TzDate = function (offset, timestamp) {
var self = new Date(0);
@@ -534,10 +580,14 @@
self.getSeconds = function() {
return self.date.getSeconds();
};
+ self.getMilliseconds = function() {
+ return self.date.getMilliseconds();
+ };
+
self.getTimezoneOffset = function() {
return offset * 60;
};
self.getUTCFullYear = function() {
@@ -584,11 +634,11 @@
padNumber(self.origDate.getUTCMilliseconds(), 3) + 'Z'
}
}
//hide all methods not implemented in this mock that the Date prototype exposes
- var unimplementedMethods = ['getMilliseconds', 'getUTCDay',
+ var unimplementedMethods = ['getUTCDay',
'getYear', 'setDate', 'setFullYear', 'setHours', 'setMilliseconds',
'setMinutes', 'setMonth', 'setSeconds', 'setTime', 'setUTCDate', 'setUTCFullYear',
'setUTCHours', 'setUTCMilliseconds', 'setUTCMinutes', 'setUTCMonth', 'setUTCSeconds',
'setYear', 'toDateString', 'toGMTString', 'toJSON', 'toLocaleFormat', 'toLocaleString',
'toLocaleTimeString', 'toSource', 'toString', 'toTimeString', 'toUTCString', 'valueOf'];
@@ -604,11 +654,48 @@
//make "tzDateInstance instanceof Date" return true
angular.mock.TzDate.prototype = Date.prototype;
})();
+angular.mock.animate = angular.module('mock.animate', ['ng'])
+ .config(['$provide', function($provide) {
+
+ $provide.decorator('$animate', function($delegate) {
+ var animate = {
+ queue : [],
+ enabled : $delegate.enabled,
+ flushNext : function(name) {
+ var tick = animate.queue.shift();
+ expect(tick.method).toBe(name);
+ tick.fn();
+ return tick;
+ }
+ };
+
+ forEach(['enter','leave','move','addClass','removeClass'], function(method) {
+ animate[method] = function() {
+ var params = arguments;
+ animate.queue.push({
+ method : method,
+ params : params,
+ element : angular.isElement(params[0]) && params[0],
+ parent : angular.isElement(params[1]) && params[1],
+ after : angular.isElement(params[2]) && params[2],
+ fn : function() {
+ $delegate[method].apply($delegate, params);
+ }
+ });
+ };
+ });
+
+ return animate;
+ });
+
+ }]);
+
+
/**
* @ngdoc function
* @name angular.mock.dump
* @description
*
@@ -644,10 +731,11 @@
if (angular.isFunction(object.$eval) && angular.isFunction(object.$apply)) {
out = serializeScope(object);
} else if (object instanceof Error) {
out = object.stack || ('' + object.name + ': ' + object.message);
} else {
+ // TODO(i): this prevents methods to be logged, we should have a better way to serialize objects
out = angular.toJson(object, true);
}
} else {
out = String(object);
}
@@ -868,11 +956,11 @@
});
});
</pre>
*/
angular.mock.$HttpBackendProvider = function() {
- this.$get = [createHttpBackendMock];
+ this.$get = ['$rootScope', createHttpBackendMock];
};
/**
* General factory function for $httpBackend mock.
* Returns instance for unit testing (when no arguments specified):
@@ -885,11 +973,11 @@
*
* @param {Object=} $delegate Real $httpBackend instance (allow passing through if specified)
* @param {Object=} $browser Auto-flushing enabled if specified
* @return {Object} Instance of $httpBackend mock
*/
-function createHttpBackendMock($delegate, $browser) {
+function createHttpBackendMock($rootScope, $delegate, $browser) {
var definitions = [],
expectations = [],
responses = [],
responsesPush = angular.bind(responses, responses.push);
@@ -902,64 +990,77 @@
: [200, status, data];
};
}
// TODO(vojta): change params to: method, url, data, headers, callback
- function $httpBackend(method, url, data, callback, headers) {
+ function $httpBackend(method, url, data, callback, headers, timeout, withCredentials) {
var xhr = new MockXhr(),
expectation = expectations[0],
wasExpected = false;
function prettyPrint(data) {
return (angular.isString(data) || angular.isFunction(data) || data instanceof RegExp)
? data
: angular.toJson(data);
}
+ function wrapResponse(wrapped) {
+ if (!$browser && timeout && timeout.then) timeout.then(handleTimeout);
+
+ return handleResponse;
+
+ function handleResponse() {
+ var response = wrapped.response(method, url, data, headers);
+ xhr.$$respHeaders = response[2];
+ callback(response[0], response[1], xhr.getAllResponseHeaders());
+ }
+
+ function handleTimeout() {
+ for (var i = 0, ii = responses.length; i < ii; i++) {
+ if (responses[i] === handleResponse) {
+ responses.splice(i, 1);
+ callback(-1, undefined, '');
+ break;
+ }
+ }
+ }
+ }
+
if (expectation && expectation.match(method, url)) {
if (!expectation.matchData(data))
- throw Error('Expected ' + expectation + ' with different data\n' +
+ throw new Error('Expected ' + expectation + ' with different data\n' +
'EXPECTED: ' + prettyPrint(expectation.data) + '\nGOT: ' + data);
if (!expectation.matchHeaders(headers))
- throw Error('Expected ' + expectation + ' with different headers\n' +
- 'EXPECTED: ' + prettyPrint(expectation.headers) + '\nGOT: ' +
- prettyPrint(headers));
+ throw new Error('Expected ' + expectation + ' with different headers\n' +
+ 'EXPECTED: ' + prettyPrint(expectation.headers) + '\nGOT: ' + prettyPrint(headers));
expectations.shift();
if (expectation.response) {
- responses.push(function() {
- var response = expectation.response(method, url, data, headers);
- xhr.$$respHeaders = response[2];
- callback(response[0], response[1], xhr.getAllResponseHeaders());
- });
+ responses.push(wrapResponse(expectation));
return;
}
wasExpected = true;
}
var i = -1, definition;
while ((definition = definitions[++i])) {
if (definition.match(method, url, data, headers || {})) {
if (definition.response) {
// if $browser specified, we do auto flush all requests
- ($browser ? $browser.defer : responsesPush)(function() {
- var response = definition.response(method, url, data, headers);
- xhr.$$respHeaders = response[2];
- callback(response[0], response[1], xhr.getAllResponseHeaders());
- });
+ ($browser ? $browser.defer : responsesPush)(wrapResponse(definition));
} else if (definition.passThrough) {
- $delegate(method, url, data, callback, headers);
+ $delegate(method, url, data, callback, headers, timeout, withCredentials);
} else throw Error('No response defined !');
return;
}
}
throw wasExpected ?
- Error('No response defined !') :
- Error('Unexpected request: ' + method + ' ' + url + '\n' +
- (expectation ? 'Expected ' + expectation : 'No more request expected'));
+ new Error('No response defined !') :
+ new Error('Unexpected request: ' + method + ' ' + url + '\n' +
+ (expectation ? 'Expected ' + expectation : 'No more request expected'));
}
/**
* @ngdoc method
* @name ngMock.$httpBackend#when
@@ -967,11 +1068,12 @@
* @description
* Creates a new backend definition.
*
* @param {string} method HTTP method.
* @param {string|RegExp} url HTTP url.
- * @param {(string|RegExp)=} data HTTP request body.
+ * @param {(string|RegExp|function(string))=} data HTTP request body or function that receives
+ * data string and returns true if the data is as expected.
* @param {(Object|function(Object))=} headers HTTP headers or function that receives http header
* object and returns true if the headers match the current definition.
* @returns {requestHandler} Returns an object with `respond` method that control how a matched
* request is handled.
*
@@ -1043,11 +1145,12 @@
* @methodOf ngMock.$httpBackend
* @description
* Creates a new backend definition for POST requests. For more info see `when()`.
*
* @param {string|RegExp} url HTTP url.
- * @param {(string|RegExp)=} data HTTP request body.
+ * @param {(string|RegExp|function(string))=} data HTTP request body or function that receives
+ * data string and returns true if the data is as expected.
* @param {(Object|function(Object))=} headers HTTP headers.
* @returns {requestHandler} Returns an object with `respond` method that control how a matched
* request is handled.
*/
@@ -1057,11 +1160,12 @@
* @methodOf ngMock.$httpBackend
* @description
* Creates a new backend definition for PUT requests. For more info see `when()`.
*
* @param {string|RegExp} url HTTP url.
- * @param {(string|RegExp)=} data HTTP request body.
+ * @param {(string|RegExp|function(string))=} data HTTP request body or function that receives
+ * data string and returns true if the data is as expected.
* @param {(Object|function(Object))=} headers HTTP headers.
* @returns {requestHandler} Returns an object with `respond` method that control how a matched
* request is handled.
*/
@@ -1223,10 +1327,11 @@
* @param {number=} count Number of responses to flush (in the order they arrived). If undefined,
* all pending requests will be flushed. If there are no pending requests when the flush method
* is called an exception is thrown (as this typically a sign of programming error).
*/
$httpBackend.flush = function(count) {
+ $rootScope.$digest();
if (!responses.length) throw Error('No pending request to flush !');
if (angular.isDefined(count)) {
while (count--) {
if (!responses.length) throw Error('No more pending request to flush !');
@@ -1255,12 +1360,13 @@
* <pre>
* afterEach($httpBackend.verifyNoOutstandingExpectation);
* </pre>
*/
$httpBackend.verifyNoOutstandingExpectation = function() {
+ $rootScope.$digest();
if (expectations.length) {
- throw Error('Unsatisfied requests: ' + expectations.join(', '));
+ throw new Error('Unsatisfied requests: ' + expectations.join(', '));
}
};
/**
@@ -1342,10 +1448,11 @@
};
this.matchData = function(d) {
if (angular.isUndefined(data)) return true;
if (data && angular.isFunction(data.test)) return data.test(d);
+ if (data && angular.isFunction(data)) return data(d);
if (data && !angular.isString(data)) return angular.toJson(data) == d;
return data == d;
};
this.toString = function() {
@@ -1407,22 +1514,70 @@
* @ngdoc function
* @name ngMock.$timeout
* @description
*
* This service is just a simple decorator for {@link ng.$timeout $timeout} service
- * that adds a "flush" method.
+ * that adds a "flush" and "verifyNoPendingTasks" methods.
*/
-/**
- * @ngdoc method
- * @name ngMock.$timeout#flush
- * @methodOf ngMock.$timeout
- * @description
- *
- * Flushes the queue of pending tasks.
- */
+angular.mock.$TimeoutDecorator = function($delegate, $browser) {
+ /**
+ * @ngdoc method
+ * @name ngMock.$timeout#flush
+ * @methodOf ngMock.$timeout
+ * @description
+ *
+ * Flushes the queue of pending tasks.
+ *
+ * @param {number=} delay maximum timeout amount to flush up until
+ */
+ $delegate.flush = function(delay) {
+ $browser.defer.flush(delay);
+ };
+
+ /**
+ * @ngdoc method
+ * @name ngMock.$timeout#flushNext
+ * @methodOf ngMock.$timeout
+ * @description
+ *
+ * Flushes the next timeout in the queue and compares it to the provided delay
+ *
+ * @param {number=} expectedDelay the delay value that will be asserted against the delay of the next timeout function
+ */
+ $delegate.flushNext = function(expectedDelay) {
+ $browser.defer.flushNext(expectedDelay);
+ };
+
+ /**
+ * @ngdoc method
+ * @name ngMock.$timeout#verifyNoPendingTasks
+ * @methodOf ngMock.$timeout
+ * @description
+ *
+ * Verifies that there are no pending tasks that need to be flushed.
+ */
+ $delegate.verifyNoPendingTasks = function() {
+ if ($browser.deferredFns.length) {
+ throw new Error('Deferred tasks to flush (' + $browser.deferredFns.length + '): ' +
+ formatPendingTasksAsString($browser.deferredFns));
+ }
+ };
+
+ function formatPendingTasksAsString(tasks) {
+ var result = [];
+ angular.forEach(tasks, function(task) {
+ result.push('{id: ' + task.id + ', ' + 'time: ' + task.time + '}');
+ });
+
+ return result.join(', ');
+ }
+
+ return $delegate;
+};
+
/**
*
*/
angular.mock.$RootElementProvider = function() {
this.$get = function() {
@@ -1443,19 +1598,13 @@
$exceptionHandler: angular.mock.$ExceptionHandlerProvider,
$log: angular.mock.$LogProvider,
$httpBackend: angular.mock.$HttpBackendProvider,
$rootElement: angular.mock.$RootElementProvider
}).config(function($provide) {
- $provide.decorator('$timeout', function($delegate, $browser) {
- $delegate.flush = function(delay) {
- $browser.defer.flush(delay);
- };
- return $delegate;
- });
+ $provide.decorator('$timeout', angular.mock.$TimeoutDecorator);
});
-
/**
* @ngdoc overview
* @name ngMockE2E
* @description
*
@@ -1630,40 +1779,46 @@
* @param {string|RegExp} url HTTP url.
* @returns {requestHandler} Returns an object with `respond` and `passThrough` methods that
* control how a matched request is handled.
*/
angular.mock.e2e = {};
-angular.mock.e2e.$httpBackendDecorator = ['$delegate', '$browser', createHttpBackendMock];
+angular.mock.e2e.$httpBackendDecorator = ['$rootScope', '$delegate', '$browser', createHttpBackendMock];
angular.mock.clearDataCache = function() {
var key,
cache = angular.element.cache;
for(key in cache) {
if (cache.hasOwnProperty(key)) {
var handle = cache[key].handle;
- handle && angular.element(handle.elem).unbind();
+ handle && angular.element(handle.elem).off();
delete cache[key];
}
}
};
-window.jasmine && (function(window) {
+(window.jasmine || window.mocha) && (function(window) {
+ var currentSpec = null;
+
+ beforeEach(function() {
+ currentSpec = this;
+ });
+
afterEach(function() {
- var spec = getCurrentSpec();
- var injector = spec.$injector;
+ var injector = currentSpec.$injector;
- spec.$injector = null;
- spec.$modules = null;
+ currentSpec.$injector = null;
+ currentSpec.$modules = null;
+ currentSpec = null;
if (injector) {
- injector.get('$rootElement').unbind();
+ injector.get('$rootElement').off();
injector.get('$browser').pollFns.length = 0;
}
angular.mock.clearDataCache();
@@ -1678,26 +1833,20 @@
delete angular.callbacks[key];
});
angular.callbacks.counter = 0;
});
- function getCurrentSpec() {
- return jasmine.getEnv().currentSpec;
- }
-
function isSpecRunning() {
- var spec = getCurrentSpec();
- return spec && spec.queue.running;
+ return currentSpec && (window.mocha || currentSpec.queue.running);
}
/**
* @ngdoc function
* @name angular.mock.module
* @description
*
* *NOTE*: This function is also published on window for easy access.<br>
- * *NOTE*: Only available with {@link http://pivotal.github.com/jasmine/ jasmine}.
*
* This function registers a module configuration code. It collects the configuration information
* which will be used when the injector is created by {@link angular.mock.inject inject}.
*
* See {@link angular.mock.inject inject} for usage example
@@ -1709,15 +1858,14 @@
window.module = angular.mock.module = function() {
var moduleFns = Array.prototype.slice.call(arguments, 0);
return isSpecRunning() ? workFn() : workFn;
/////////////////////
function workFn() {
- var spec = getCurrentSpec();
- if (spec.$injector) {
+ if (currentSpec.$injector) {
throw Error('Injector already created, can not register a module!');
} else {
- var modules = spec.$modules || (spec.$modules = []);
+ var modules = currentSpec.$modules || (currentSpec.$modules = []);
angular.forEach(moduleFns, function(module) {
modules.push(module);
});
}
}
@@ -1727,11 +1875,10 @@
* @ngdoc function
* @name angular.mock.inject
* @description
*
* *NOTE*: This function is also published on window for easy access.<br>
- * *NOTE*: Only available with {@link http://pivotal.github.com/jasmine/ jasmine}.
*
* The inject function wraps a function into an injectable function. The inject() creates new
* instance of {@link AUTO.$injector $injector} per test, which is then used for
* resolving references.
*
@@ -1780,16 +1927,16 @@
var blockFns = Array.prototype.slice.call(arguments, 0);
var errorForStack = new Error('Declaration Location');
return isSpecRunning() ? workFn() : workFn;
/////////////////////
function workFn() {
- var spec = getCurrentSpec();
- var modules = spec.$modules || [];
+ var modules = currentSpec.$modules || [];
+
modules.unshift('ngMock');
modules.unshift('ng');
- var injector = spec.$injector;
+ var injector = currentSpec.$injector;
if (!injector) {
- injector = spec.$injector = angular.injector(modules);
+ injector = currentSpec.$injector = angular.injector(modules);
}
for(var i = 0, ii = blockFns.length; i < ii; i++) {
try {
injector.invoke(blockFns[i] || angular.noop, this);
} catch (e) {