{I" class:ETI"ProcessedAsset; FI"logical_path; TI"helpers/angular-mocks.js; FI" pathname; TI"X/Users/ems408/workspace/social_networking/spec/javascripts/helpers/angular-mocks.js; FI"content_type; TI"application/javascript; TI" mtime; Tl+ζ#\TI"length; Ti"+I"digest; TI"%06c07f13c3ddcb0dac2f13158406ec29; FI"source; TI""+/** * @license AngularJS v1.3.0 * (c) 2010-2014 Google, Inc. http://angularjs.org * License: MIT */ (function(window, angular, undefined) { 'use strict'; /** * @ngdoc object * @name angular.mock * @description * * Namespace from 'angular-mocks.js' which contains testing related code. */ angular.mock = {}; /** * ! This is a private undocumented service ! * * @name $browser * * @description * This service is a mock implementation of {@link ng.$browser}. It provides fake * implementation for commonly used browser apis that are hard to test, e.g. setTimeout, xhr, * cookies, etc... * * The api of this service is the same as that of the real {@link ng.$browser $browser}, except * that there are several helper methods available which can be used in tests. */ angular.mock.$BrowserProvider = function() { this.$get = function() { return new angular.mock.$Browser(); }; }; angular.mock.$Browser = function() { var self = this; this.isMock = true; self.$$url = "http://server/"; self.$$lastUrl = self.$$url; // used by url polling fn self.pollFns = []; // TODO(vojta): remove this temporary api self.$$completeOutstandingRequest = angular.noop; self.$$incOutstandingRequestCount = angular.noop; // register url polling fn self.onUrlChange = function(listener) { self.pollFns.push( function() { if (self.$$lastUrl !== self.$$url || self.$$state !== self.$$lastState) { self.$$lastUrl = self.$$url; self.$$lastState = self.$$state; listener(self.$$url, self.$$state); } } ); return listener; }; self.$$checkUrlChange = angular.noop; self.cookieHash = {}; self.lastCookieHash = {}; self.deferredFns = []; self.deferredNextId = 0; self.defer = function(fn, delay) { delay = delay || 0; self.deferredFns.push({time:(self.defer.now + delay), fn:fn, id: self.deferredNextId}); self.deferredFns.sort(function(a,b){ return a.time - b.time;}); return self.deferredNextId++; }; /** * @name $browser#defer.now * * @description * Current milliseconds mock time. */ self.defer.now = 0; self.defer.cancel = function(deferId) { var fnIndex; angular.forEach(self.deferredFns, function(fn, index) { if (fn.id === deferId) fnIndex = index; }); if (fnIndex !== undefined) { self.deferredFns.splice(fnIndex, 1); return true; } return false; }; /** * @name $browser#defer.flush * * @description * Flushes all pending requests and executes the defer callbacks. * * @param {number=} number of milliseconds to flush. See {@link #defer.now} */ self.defer.flush = function(delay) { if (angular.isDefined(delay)) { self.defer.now += delay; } else { if (self.deferredFns.length) { self.defer.now = self.deferredFns[self.deferredFns.length-1].time; } else { throw new Error('No deferred tasks to be flushed'); } } while (self.deferredFns.length && self.deferredFns[0].time <= self.defer.now) { self.deferredFns.shift().fn(); } }; self.$$baseHref = '/'; self.baseHref = function() { return this.$$baseHref; }; }; angular.mock.$Browser.prototype = { /** * @name $browser#poll * * @description * run all fns in pollFns */ poll: function poll() { angular.forEach(this.pollFns, function(pollFn){ pollFn(); }); }, addPollFn: function(pollFn) { this.pollFns.push(pollFn); return pollFn; }, url: function(url, replace, state) { if (angular.isUndefined(state)) { state = null; } if (url) { this.$$url = url; // Native pushState serializes & copies the object; simulate it. this.$$state = angular.copy(state); return this; } return this.$$url; }, state: function() { return this.$$state; }, cookies: function(name, value) { if (name) { if (angular.isUndefined(value)) { delete this.cookieHash[name]; } else { if (angular.isString(value) && //strings only value.length <= 4096) { //strict cookie storage limits this.cookieHash[name] = value; } } } else { if (!angular.equals(this.cookieHash, this.lastCookieHash)) { this.lastCookieHash = angular.copy(this.cookieHash); this.cookieHash = angular.copy(this.cookieHash); } return this.cookieHash; } }, notifyWhenNoOutstandingRequests: function(fn) { fn(); } }; /** * @ngdoc provider * @name $exceptionHandlerProvider * * @description * Configures the mock implementation of {@link ng.$exceptionHandler} to rethrow or to log errors * passed to the `$exceptionHandler`. */ /** * @ngdoc service * @name $exceptionHandler * * @description * Mock implementation of {@link ng.$exceptionHandler} that rethrows or logs errors passed * to it. See {@link ngMock.$exceptionHandlerProvider $exceptionHandlerProvider} for configuration * information. * * * ```js * describe('$exceptionHandlerProvider', function() { * * it('should capture log messages and exceptions', function() { * * module(function($exceptionHandlerProvider) { * $exceptionHandlerProvider.mode('log'); * }); * * inject(function($log, $exceptionHandler, $timeout) { * $timeout(function() { $log.log(1); }); * $timeout(function() { $log.log(2); throw 'banana peel'; }); * $timeout(function() { $log.log(3); }); * expect($exceptionHandler.errors).toEqual([]); * expect($log.assertEmpty()); * $timeout.flush(); * expect($exceptionHandler.errors).toEqual(['banana peel']); * expect($log.log.logs).toEqual([[1], [2], [3]]); * }); * }); * }); * ``` */ angular.mock.$ExceptionHandlerProvider = function() { var handler; /** * @ngdoc method * @name $exceptionHandlerProvider#mode * * @description * Sets the logging mode. * * @param {string} mode Mode of operation, defaults to `rethrow`. * * - `rethrow`: If any errors are passed to the handler in tests, it typically means that there * is a bug in the application or test, so this mock will make these tests fail. * - `log`: Sometimes it is desirable to test that an error is thrown, for this case the `log` * mode stores an array of errors in `$exceptionHandler.errors`, to allow later * assertion of them. See {@link ngMock.$log#assertEmpty assertEmpty()} and * {@link ngMock.$log#reset reset()} */ this.mode = function(mode) { switch(mode) { case 'rethrow': handler = function(e) { throw e; }; break; case 'log': var errors = []; handler = function(e) { if (arguments.length == 1) { errors.push(e); } else { errors.push([].slice.call(arguments, 0)); } }; handler.errors = errors; break; default: throw new Error("Unknown mode '" + mode + "', only 'log'/'rethrow' modes are allowed!"); } }; this.$get = function() { return handler; }; this.mode('rethrow'); }; /** * @ngdoc service * @name $log * * @description * Mock implementation of {@link ng.$log} that gathers all logged messages in arrays * (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 (angular.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)); }, debug: function() { if (debug) { $log.debug.logs.push(concat([], arguments, 0)); } } }; /** * @ngdoc method * @name $log#reset * * @description * Reset all of the logging arrays to empty. */ $log.reset = function () { /** * @ngdoc property * @name $log#log.logs * * @description * Array of messages logged using {@link ng.$log#log `log()`}. * * @example * ```js * $log.log('Some Log'); * var first = $log.log.logs.unshift(); * ``` */ $log.log.logs = []; /** * @ngdoc property * @name $log#info.logs * * @description * Array of messages logged using {@link ng.$log#info `info()`}. * * @example * ```js * $log.info('Some Info'); * var first = $log.info.logs.unshift(); * ``` */ $log.info.logs = []; /** * @ngdoc property * @name $log#warn.logs * * @description * Array of messages logged using {@link ng.$log#warn `warn()`}. * * @example * ```js * $log.warn('Some Warning'); * var first = $log.warn.logs.unshift(); * ``` */ $log.warn.logs = []; /** * @ngdoc property * @name $log#error.logs * * @description * Array of messages logged using {@link ng.$log#error `error()`}. * * @example * ```js * $log.error('Some Error'); * var first = $log.error.logs.unshift(); * ``` */ $log.error.logs = []; /** * @ngdoc property * @name $log#debug.logs * * @description * Array of messages logged using {@link ng.$log#debug `debug()`}. * * @example * ```js * $log.debug('Some Error'); * var first = $log.debug.logs.unshift(); * ``` */ $log.debug.logs = []; }; /** * @ngdoc method * @name $log#assertEmpty * * @description * Assert that all of the logging methods have no logged messages. If any messages are present, * an exception is thrown. */ $log.assertEmpty = function() { var errors = []; 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 || '')); }); }); }); if (errors.length) { errors.unshift("Expected $log to be empty! Either a message was logged unexpectedly, or "+ "an expected log message was not checked and removed:"); errors.push(''); throw new Error(errors.join('\n---------\n')); } }; $log.reset(); return $log; }; }; /** * @ngdoc service * @name $interval * * @description * Mock implementation of the $interval service. * * Use {@link ngMock.$interval#flush `$interval.flush(millis)`} to * move forward by `millis` milliseconds and trigger any functions scheduled to run in that * time. * * @param {function()} fn A function that should be called repeatedly. * @param {number} delay Number of milliseconds between each function call. * @param {number=} [count=0] Number of times to repeat. If not set, or 0, will repeat * indefinitely. * @param {boolean=} [invokeApply=true] If set to `false` skips model dirty checking, otherwise * will invoke `fn` within the {@link ng.$rootScope.Scope#$apply $apply} block. * @returns {promise} A promise which will be notified on each iteration. */ angular.mock.$IntervalProvider = function() { this.$get = ['$rootScope', '$q', function($rootScope, $q) { var repeatFns = [], nextRepeatId = 0, now = 0; var $interval = function(fn, delay, count, invokeApply) { var deferred = $q.defer(), promise = deferred.promise, iteration = 0, skipApply = (angular.isDefined(invokeApply) && !invokeApply); count = (angular.isDefined(count)) ? count : 0; promise.then(null, null, fn); promise.$$intervalId = nextRepeatId; function tick() { deferred.notify(iteration++); if (count > 0 && iteration >= count) { var fnIndex; deferred.resolve(iteration); angular.forEach(repeatFns, function(fn, index) { if (fn.id === promise.$$intervalId) fnIndex = index; }); if (fnIndex !== undefined) { repeatFns.splice(fnIndex, 1); } } if (!skipApply) $rootScope.$apply(); } repeatFns.push({ nextTime:(now + delay), delay: delay, fn: tick, id: nextRepeatId, deferred: deferred }); repeatFns.sort(function(a,b){ return a.nextTime - b.nextTime;}); nextRepeatId++; return promise; }; /** * @ngdoc method * @name $interval#cancel * * @description * Cancels a task associated with the `promise`. * * @param {promise} promise A promise from calling the `$interval` function. * @returns {boolean} Returns `true` if the task was successfully cancelled. */ $interval.cancel = function(promise) { if(!promise) return false; var fnIndex; angular.forEach(repeatFns, function(fn, index) { if (fn.id === promise.$$intervalId) fnIndex = index; }); if (fnIndex !== undefined) { repeatFns[fnIndex].deferred.reject('canceled'); repeatFns.splice(fnIndex, 1); return true; } return false; }; /** * @ngdoc method * @name $interval#flush * @description * * Runs interval tasks scheduled to be run in the next `millis` milliseconds. * * @param {number=} millis maximum timeout amount to flush up until. * * @return {number} The amount of time moved forward. */ $interval.flush = function(millis) { now += millis; while (repeatFns.length && repeatFns[0].nextTime <= now) { var task = repeatFns[0]; task.fn(); task.nextTime += task.delay; repeatFns.sort(function(a,b){ return a.nextTime - b.nextTime;}); } return millis; }; return $interval; }]; }; /* jshint -W101 */ /* The R_ISO8061_STR regex is never going to fit into the 100 char limit! * This directive should go inside the anonymous function but a bug in JSHint means that it would * not be enacted early enough to prevent the warning. */ var R_ISO8061_STR = /^(\d{4})-?(\d\d)-?(\d\d)(?:T(\d\d)(?:\:?(\d\d)(?:\:?(\d\d)(?:\.(\d{3}))?)?)?(Z|([+-])(\d\d):?(\d\d)))?$/; function jsonStringToDate(string) { var match; if (match = string.match(R_ISO8061_STR)) { var date = new Date(0), tzHour = 0, tzMin = 0; if (match[9]) { tzHour = int(match[9] + match[10]); tzMin = int(match[9] + match[11]); } date.setUTCFullYear(int(match[1]), int(match[2]) - 1, int(match[3])); date.setUTCHours(int(match[4]||0) - tzHour, int(match[5]||0) - tzMin, int(match[6]||0), int(match[7]||0)); return date; } return string; } function int(str) { return parseInt(str, 10); } function padNumber(num, digits, trim) { var neg = ''; if (num < 0) { neg = '-'; num = -num; } num = '' + num; while(num.length < digits) num = '0' + num; if (trim) num = num.substr(num.length - digits); return neg + num; } /** * @ngdoc type * @name angular.mock.TzDate * @description * * *NOTE*: this is not an injectable instance, just a globally available mock class of `Date`. * * Mock of the Date type which has its timezone specified via constructor arg. * * The main purpose is to create Date-like instances with timezone fixed to the specified timezone * offset, so that we can test code that depends on local timezone settings without dependency on * the time zone settings of the machine where the code is running. * * @param {number} offset Offset of the *desired* timezone in hours (fractions will be honored) * @param {(number|string)} timestamp Timestamp representing the desired time in *UTC* * * @example * !!!! WARNING !!!!! * This is not a complete Date object so only methods that were implemented can be called safely. * To make matters worse, TzDate instances inherit stuff from Date via a prototype. * * We do our best to intercept calls to "unimplemented" methods, but since the list of methods is * incomplete we might be missing some non-standard methods. This can result in errors like: * "Date.prototype.foo called on incompatible Object". * * ```js * var newYearInBratislava = new TzDate(-1, '2009-12-31T23:00:00Z'); * newYearInBratislava.getTimezoneOffset() => -60; * newYearInBratislava.getFullYear() => 2010; * newYearInBratislava.getMonth() => 0; * newYearInBratislava.getDate() => 1; * newYearInBratislava.getHours() => 0; * newYearInBratislava.getMinutes() => 0; * newYearInBratislava.getSeconds() => 0; * ``` * */ angular.mock.TzDate = function (offset, timestamp) { var self = new Date(0); if (angular.isString(timestamp)) { var tsStr = timestamp; self.origDate = jsonStringToDate(timestamp); timestamp = self.origDate.getTime(); if (isNaN(timestamp)) throw { name: "Illegal Argument", message: "Arg '" + tsStr + "' passed into TzDate constructor is not a valid date string" }; } else { self.origDate = new Date(timestamp); } var localOffset = new Date(timestamp).getTimezoneOffset(); self.offsetDiff = localOffset*60*1000 - offset*1000*60*60; self.date = new Date(timestamp + self.offsetDiff); self.getTime = function() { return self.date.getTime() - self.offsetDiff; }; self.toLocaleDateString = function() { return self.date.toLocaleDateString(); }; self.getFullYear = function() { return self.date.getFullYear(); }; self.getMonth = function() { return self.date.getMonth(); }; self.getDate = function() { return self.date.getDate(); }; self.getHours = function() { return self.date.getHours(); }; self.getMinutes = function() { return self.date.getMinutes(); }; self.getSeconds = function() { return self.date.getSeconds(); }; self.getMilliseconds = function() { return self.date.getMilliseconds(); }; self.getTimezoneOffset = function() { return offset * 60; }; self.getUTCFullYear = function() { return self.origDate.getUTCFullYear(); }; self.getUTCMonth = function() { return self.origDate.getUTCMonth(); }; self.getUTCDate = function() { return self.origDate.getUTCDate(); }; self.getUTCHours = function() { return self.origDate.getUTCHours(); }; self.getUTCMinutes = function() { return self.origDate.getUTCMinutes(); }; self.getUTCSeconds = function() { return self.origDate.getUTCSeconds(); }; self.getUTCMilliseconds = function() { return self.origDate.getUTCMilliseconds(); }; self.getDay = function() { return self.date.getDay(); }; // provide this method only on browsers that already have it if (self.toISOString) { self.toISOString = function() { return padNumber(self.origDate.getUTCFullYear(), 4) + '-' + padNumber(self.origDate.getUTCMonth() + 1, 2) + '-' + padNumber(self.origDate.getUTCDate(), 2) + 'T' + padNumber(self.origDate.getUTCHours(), 2) + ':' + padNumber(self.origDate.getUTCMinutes(), 2) + ':' + padNumber(self.origDate.getUTCSeconds(), 2) + '.' + padNumber(self.origDate.getUTCMilliseconds(), 3) + 'Z'; }; } //hide all methods not implemented in this mock that the Date prototype exposes 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']; angular.forEach(unimplementedMethods, function(methodName) { self[methodName] = function() { throw new Error("Method '" + methodName + "' is not implemented in the TzDate mock"); }; }); return self; }; //make "tzDateInstance instanceof Date" return true angular.mock.TzDate.prototype = Date.prototype; /* jshint +W101 */ angular.mock.animate = angular.module('ngAnimateMock', ['ng']) .config(['$provide', function($provide) { var reflowQueue = []; $provide.value('$$animateReflow', function(fn) { var index = reflowQueue.length; reflowQueue.push(fn); return function cancel() { reflowQueue.splice(index, 1); }; }); $provide.decorator('$animate', ['$delegate', '$$asyncCallback', '$timeout', '$browser', function($delegate, $$asyncCallback, $timeout, $browser) { var animate = { queue : [], cancel : $delegate.cancel, enabled : $delegate.enabled, triggerCallbackEvents : function() { $$asyncCallback.flush(); }, triggerCallbackPromise : function() { $timeout.flush(0); }, triggerCallbacks : function() { this.triggerCallbackEvents(); this.triggerCallbackPromise(); }, triggerReflow : function() { angular.forEach(reflowQueue, function(fn) { fn(); }); reflowQueue = []; } }; angular.forEach( ['animate','enter','leave','move','addClass','removeClass','setClass'], function(method) { animate[method] = function() { animate.queue.push({ event : method, element : arguments[0], options : arguments[arguments.length-1], args : arguments }); return $delegate[method].apply($delegate, arguments); }; }); return animate; }]); }]); /** * @ngdoc function * @name angular.mock.dump * @description * * *NOTE*: this is not an injectable instance, just a globally available function. * * Method for serializing common angular objects (scope, elements, etc..) into strings, useful for * debugging. * * This method is also available on window, where it can be used to display objects on debug * console. * * @param {*} object - any object to turn into string. * @return {string} a serialized string of the argument */ angular.mock.dump = function(object) { return serialize(object); function serialize(object) { var out; if (angular.isElement(object)) { object = angular.element(object); out = angular.element('
'); angular.forEach(object, function(element) { out.append(angular.element(element).clone()); }); out = out.html(); } else if (angular.isArray(object)) { out = []; angular.forEach(object, function(o) { out.push(serialize(o)); }); out = '[ ' + out.join(', ') + ' ]'; } else if (angular.isObject(object)) { 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 being logged, // we should have a better way to serialize objects out = angular.toJson(object, true); } } else { out = String(object); } return out; } function serializeScope(scope, offset) { offset = offset || ' '; var log = [offset + 'Scope(' + scope.$id + '): {']; for ( var key in scope ) { if (Object.prototype.hasOwnProperty.call(scope, key) && !key.match(/^(\$|this)/)) { log.push(' ' + key + ': ' + angular.toJson(scope[key])); } } var child = scope.$$childHead; while(child) { log.push(serializeScope(child, offset + ' ')); child = child.$$nextSibling; } log.push('}'); return log.join('\n' + offset); } }; /** * @ngdoc service * @name $httpBackend * @description * Fake HTTP backend implementation suitable for unit testing applications that use the * {@link ng.$http $http service}. * * *Note*: For fake HTTP backend implementation suitable for end-to-end testing or backend-less * development please see {@link ngMockE2E.$httpBackend e2e $httpBackend mock}. * * During unit testing, we want our unit tests to run quickly and have no external dependencies so * we donβt want to send [XHR](https://developer.mozilla.org/en/xmlhttprequest) or * [JSONP](http://en.wikipedia.org/wiki/JSONP) requests to a real server. All we really need is * to verify whether a certain request has been sent or not, or alternatively just let the * application make requests, respond with pre-trained responses and assert that the end result is * what we expect it to be. * * This mock implementation can be used to respond with static or dynamic responses via the * `expect` and `when` apis and their shortcuts (`expectGET`, `whenPOST`, etc). * * When an Angular application needs some data from a server, it calls the $http service, which * sends the request to a real server using $httpBackend service. With dependency injection, it is * easy to inject $httpBackend mock (which has the same API as $httpBackend) and use it to verify * the requests and respond with some testing data without sending a request to a real server. * * There are two ways to specify what test data should be returned as http responses by the mock * backend when the code under test makes http requests: * * - `$httpBackend.expect` - specifies a request expectation * - `$httpBackend.when` - specifies a backend definition * * * # Request Expectations vs Backend Definitions * * Request expectations provide a way to make assertions about requests made by the application and * to define responses for those requests. The test will fail if the expected requests are not made * or they are made in the wrong order. * * Backend definitions allow you to define a fake backend for your application which doesn't assert * if a particular request was made or not, it just returns a trained response if a request is made. * The test will pass whether or not the request gets made during testing. * * *Request expectations | Backend definitions | |
---|---|---|
Syntax | *.expect(...).respond(...) | *.when(...).respond(...) | *
Typical usage | *strict unit tests | *loose (black-box) unit testing | *
Fulfills multiple requests | *NO | *YES | *
Order of requests matters | *YES | *NO | *
Request required | *YES | *NO | *
Response required | *optional (see below) | *YES | *