mirror of
https://github.com/Hopiu/angular.js.git
synced 2026-03-16 23:30:23 +00:00
refactor(mock): moved mocks into its own module
This commit is contained in:
parent
c27aba4354
commit
a87f2fb9e4
11 changed files with 219 additions and 139 deletions
|
|
@ -426,6 +426,17 @@ function trim(value) {
|
|||
return isString(value) ? value.replace(/^\s*/, '').replace(/\s*$/, '') : value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @ngdoc function
|
||||
* @name angular.isElement
|
||||
* @function
|
||||
*
|
||||
* @description
|
||||
* Determines if a reference is a DOM element (or wrapped jQuery element).
|
||||
*
|
||||
* @param {*} value Reference to check.
|
||||
* @returns {boolean} True if `value` is a DOM element (or wrapped jQuery element).
|
||||
*/
|
||||
function isElement(node) {
|
||||
return node &&
|
||||
(node.nodeName // we are a direct element
|
||||
|
|
@ -1012,7 +1023,7 @@ function assertArg(arg, name, reason) {
|
|||
|
||||
function assertArgFn(arg, name) {
|
||||
assertArg(isFunction(arg), name, 'not a function, got ' +
|
||||
(typeof arg == 'object' ? arg.constructor.name : typeof arg));
|
||||
(typeof arg == 'object' ? arg.constructor.name || 'Object' : typeof arg));
|
||||
return arg;
|
||||
}
|
||||
|
||||
|
|
@ -1034,6 +1045,7 @@ function publishExternalAPI(angular){
|
|||
'isFunction': isFunction,
|
||||
'isObject': isObject,
|
||||
'isNumber': isNumber,
|
||||
'isElement': isElement,
|
||||
'isArray': isArray,
|
||||
'version': version,
|
||||
'isDate': isDate,
|
||||
|
|
|
|||
106
src/angular-mocks.js
vendored
106
src/angular-mocks.js
vendored
|
|
@ -363,16 +363,21 @@ angular.mock.$ExceptionHandlerProvider = function(){
|
|||
var handler;
|
||||
|
||||
this.mode = function(mode){
|
||||
handler = {
|
||||
rethrow: function(e) {
|
||||
throw e;
|
||||
},
|
||||
log: angular.extend(function log(e) {
|
||||
log.errors.push(e);
|
||||
}, {errors:[]})
|
||||
}[mode];
|
||||
if (!handler) {
|
||||
throw Error("Unknown mode '" + mode + "', only 'log'/'rethrow' modes are allowed!");
|
||||
switch(mode) {
|
||||
case 'rethrow':
|
||||
handler = function(e) {
|
||||
throw e;
|
||||
}
|
||||
break;
|
||||
case 'log':
|
||||
var errors = [];
|
||||
handler = function(e) {
|
||||
errors.push(e);
|
||||
}
|
||||
handler.errors = errors;
|
||||
break;
|
||||
default:
|
||||
throw Error("Unknown mode '" + mode + "', only 'log'/'rethrow' modes are allowed!");
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -396,6 +401,12 @@ angular.mock.$ExceptionHandlerProvider = function(){
|
|||
* See {@link angular.mock} for more info on angular mocks.
|
||||
*/
|
||||
angular.mock.$LogProvider = function(){
|
||||
|
||||
function concat(array1, array2, index) {
|
||||
return array1.concat(Array.prototype.slice.call(array2, index));
|
||||
}
|
||||
|
||||
|
||||
this.$get = function () {
|
||||
var $log = {
|
||||
log: function() { $log.log.logs.push(concat([], arguments, 0)); },
|
||||
|
|
@ -416,7 +427,7 @@ angular.mock.$LogProvider = function(){
|
|||
angular.forEach(['error', 'warn', 'info', 'log'], function(logLevel) {
|
||||
angular.forEach($log[logLevel].logs, function(log) {
|
||||
angular.forEach(log, function (logItem) {
|
||||
errors.push('MOCK $log (' + logLevel + '): ' + (logItem.stack || logItem));
|
||||
errors.push('MOCK $log (' + logLevel + '): ' + String(logItem) + '\n' + (logItem.stack || ''));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -569,3 +580,76 @@ angular.mock.TzDate = function (offset, timestamp) {
|
|||
|
||||
//make "tzDateInstance instanceof Date" return true
|
||||
angular.mock.TzDate.prototype = Date.prototype;
|
||||
|
||||
|
||||
/**
|
||||
* Method for serializing common objects into strings, useful for debugging.
|
||||
* @param {*} object - any object to turn into string.
|
||||
* @return a serialized string of the argument
|
||||
*/
|
||||
angular.mock.dump = function(object){
|
||||
var out;
|
||||
if (angular.isElement(object)) {
|
||||
object = angular.element(object);
|
||||
out = angular.element('<div></div>')
|
||||
angular.forEach(object, function(element){
|
||||
out.append(angular.element(element).clone());
|
||||
});
|
||||
out = out.html();
|
||||
} else if (angular.isObject(object)) {
|
||||
if (angular.isFunction(object.$eval) && angular.isFunction(object.$apply)) {
|
||||
out = serializeScope(object);
|
||||
} else {
|
||||
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 (scope.hasOwnProperty(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);
|
||||
}
|
||||
};
|
||||
|
||||
window.jstestdriver && (function(window){
|
||||
/**
|
||||
* Global method to output any number of objects into JSTD console. Useful for debugging.
|
||||
*/
|
||||
window.dump = function() {
|
||||
var args = [];
|
||||
angular.forEach(arguments, function(arg){
|
||||
args.push(angular.mock.dump(arg));
|
||||
});
|
||||
jstestdriver.console.log.apply(jstestdriver.console, args);
|
||||
};
|
||||
})(window);
|
||||
|
||||
|
||||
window.jasmine && (function(window){
|
||||
window.inject = function (){
|
||||
var blockFns = Array.prototype.slice.call(arguments, 0);
|
||||
return function(){
|
||||
var injector = this.$injector;
|
||||
if (!injector) {
|
||||
injector = this.$injector = angular.injector('NG', 'NG_MOCK');
|
||||
}
|
||||
for(var i = 0, ii = blockFns.length; i < ii; i++) {
|
||||
injector.invoke(this, blockFns[i]);
|
||||
}
|
||||
};
|
||||
}
|
||||
})(window);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,11 @@
|
|||
'use strict';
|
||||
|
||||
describe('Binder', function() {
|
||||
|
||||
function childNode(element, index) {
|
||||
return jqLite(element[0].childNodes[index]);
|
||||
}
|
||||
|
||||
beforeEach(function() {
|
||||
this.compileToHtml = function (content) {
|
||||
var html;
|
||||
|
|
|
|||
|
|
@ -3,6 +3,10 @@
|
|||
describe("resource", function() {
|
||||
var resource, CreditCard, callback;
|
||||
|
||||
function nakedExpect(obj) {
|
||||
return expect(angular.fromJson(angular.toJson(obj)));
|
||||
}
|
||||
|
||||
beforeEach(inject(
|
||||
function($provide) {
|
||||
$provide.value('$xhr.error', jasmine.createSpy('xhr.error'));
|
||||
|
|
|
|||
54
test/angular-mocksSpec.js
vendored
54
test/angular-mocksSpec.js
vendored
|
|
@ -283,4 +283,58 @@ describe('mocks', function() {
|
|||
}).toThrow("Unknown mode 'XXX', only 'log'/'rethrow' modes are allowed!");
|
||||
}));
|
||||
});
|
||||
|
||||
|
||||
describe('angular.mock.debug', function(){
|
||||
var d = angular.mock.dump;
|
||||
|
||||
|
||||
it('should serialize primitive types', function(){
|
||||
expect(d(undefined)).toEqual('undefined');
|
||||
expect(d(1)).toEqual('1');
|
||||
expect(d(null)).toEqual('null');
|
||||
expect(d('abc')).toEqual('abc');
|
||||
});
|
||||
|
||||
|
||||
it('should serialize element', function(){
|
||||
var e = angular.element('<div>abc</div><span>xyz</span>');
|
||||
expect(d(e).toLowerCase()).toEqual('<div>abc</div><span>xyz</span>');
|
||||
expect(d(e[0]).toLowerCase()).toEqual('<div>abc</div>');
|
||||
});
|
||||
|
||||
it('should serialize scope', inject(function($rootScope){
|
||||
$rootScope.obj = {abc:'123'};
|
||||
expect(d($rootScope)).toMatch(/Scope\(.*\): \{/);
|
||||
expect(d($rootScope)).toMatch(/{"abc":"123"}/);
|
||||
}));
|
||||
|
||||
|
||||
it('should be published on window', function(){
|
||||
expect(window.dump instanceof Function).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('jasmine inject', function(){
|
||||
it('should call invoke', function(){
|
||||
var count = 0;
|
||||
function fn1(){
|
||||
expect(this).toBe(self);
|
||||
count++;
|
||||
}
|
||||
function fn2(){
|
||||
expect(this).toBe(self);
|
||||
count++;
|
||||
}
|
||||
var fn = inject(fn1, fn2);
|
||||
var self = {
|
||||
$injector: {
|
||||
invoke: function(self, fn) { fn.call(self); }
|
||||
}
|
||||
};
|
||||
|
||||
fn.call(self);
|
||||
expect(count).toBe(2);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -23,6 +23,13 @@ beforeEach(function() {
|
|||
};
|
||||
}
|
||||
|
||||
function indexOf(array, obj) {
|
||||
for ( var i = 0; i < array.length; i++) {
|
||||
if (obj === array[i]) return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
this.addMatchers({
|
||||
toBeInvalid: cssMatcher('ng-invalid', 'ng-valid'),
|
||||
toBeValid: cssMatcher('ng-valid', 'ng-invalid'),
|
||||
|
|
@ -84,6 +91,16 @@ beforeEach(function() {
|
|||
|
||||
toBeOneOf: function() {
|
||||
return indexOf(arguments, this.actual) !== -1;
|
||||
},
|
||||
|
||||
toHaveClass: function(clazz) {
|
||||
this.message = function() {
|
||||
return "Expected '" + angular.mock.dump(this.actual) + "' to have class '" + clazz + "'.";
|
||||
};
|
||||
return this.actual.hasClass ?
|
||||
this.actual.hasClass(clazz) :
|
||||
angular.element(this.actual).hasClass(clazz);
|
||||
}
|
||||
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -46,8 +46,8 @@ describe('angular.scenario.Runner', function() {
|
|||
runner.createSpecRunner_ = function(scope) {
|
||||
return scope.$new(MockSpecRunner);
|
||||
};
|
||||
runner.on('SpecError', rethrow);
|
||||
runner.on('StepError', rethrow);
|
||||
runner.on('SpecError', angular.mock.rethrow);
|
||||
runner.on('StepError', angular.mock.rethrow);
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
|
|
|
|||
|
|
@ -42,4 +42,10 @@ describe('angular.scenario.matchers', function () {
|
|||
expectMatcher(3, function() { matchers.toBeLessThan(10); });
|
||||
expectMatcher(3, function() { matchers.toBeGreaterThan(-5); });
|
||||
});
|
||||
|
||||
it('should have toHaveClass matcher', function(){
|
||||
var e = angular.element('<div class="abc">');
|
||||
expect(e).not.toHaveClass('none');
|
||||
expect(e).toHaveClass('abc');
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -12,18 +12,15 @@ describe('Filter: orderBy', function() {
|
|||
});
|
||||
|
||||
it('shouldSortArrayInReverse', function() {
|
||||
assertJsonEquals([{a:15},{a:2}], orderBy([{a:15},{a:2}], 'a', true));
|
||||
assertJsonEquals([{a:15},{a:2}], orderBy([{a:15},{a:2}], 'a', "T"));
|
||||
assertJsonEquals([{a:15},{a:2}], orderBy([{a:15},{a:2}], 'a', "reverse"));
|
||||
expect(orderBy([{a:15}, {a:2}], 'a', true)).toEqualData([{a:15}, {a:2}]);
|
||||
expect(orderBy([{a:15}, {a:2}], 'a', "T")).toEqualData([{a:15}, {a:2}]);
|
||||
expect(orderBy([{a:15}, {a:2}], 'a', "reverse")).toEqualData([{a:15}, {a:2}]);
|
||||
});
|
||||
|
||||
it('should sort array by predicate', function() {
|
||||
assertJsonEquals([{a:2, b:1},{a:15, b:1}],
|
||||
orderBy([{a:15, b:1},{a:2, b:1}], ['a', 'b']));
|
||||
assertJsonEquals([{a:2, b:1},{a:15, b:1}],
|
||||
orderBy([{a:15, b:1},{a:2, b:1}], ['b', 'a']));
|
||||
assertJsonEquals([{a:15, b:1},{a:2, b:1}],
|
||||
orderBy([{a:15, b:1},{a:2, b:1}], ['+b', '-a']));
|
||||
expect(orderBy([{a:15, b:1}, {a:2, b:1}], ['a', 'b'])).toEqualData([{a:2, b:1}, {a:15, b:1}]);
|
||||
expect(orderBy([{a:15, b:1}, {a:2, b:1}], ['b', 'a'])).toEqualData([{a:2, b:1}, {a:15, b:1}]);
|
||||
expect(orderBy([{a:15, b:1}, {a:2, b:1}], ['+b', '-a'])).toEqualData([{a:15, b:1}, {a:2, b:1}]);
|
||||
});
|
||||
|
||||
it('should use function', function() {
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ describe('$log', function() {
|
|||
$window = {};
|
||||
logger = '';
|
||||
$provide.service('$log', $LogProvider);
|
||||
$provide.value('$exceptionHandler', rethrow);
|
||||
$provide.value('$exceptionHandler', angular.mock.rethrow);
|
||||
$provide.value('$window', $window);
|
||||
}));
|
||||
|
||||
|
|
|
|||
|
|
@ -9,46 +9,10 @@
|
|||
_jQuery.event.special.change = undefined;
|
||||
|
||||
|
||||
if (window.jstestdriver) {
|
||||
window.jstd = jstestdriver;
|
||||
window.dump = function dump() {
|
||||
var args = [];
|
||||
forEach(arguments, function(arg){
|
||||
if (isElement(arg)) {
|
||||
arg = sortedHtml(arg);
|
||||
} else if (isObject(arg)) {
|
||||
if (isFunction(arg.$eval) && isFunction(arg.$apply)) {
|
||||
arg = dumpScope(arg);
|
||||
} else {
|
||||
arg = toJson(arg, true);
|
||||
}
|
||||
}
|
||||
args.push(arg);
|
||||
});
|
||||
jstd.console.log.apply(jstd.console, args);
|
||||
};
|
||||
}
|
||||
|
||||
function dumpScope(scope, offset) {
|
||||
offset = offset || ' ';
|
||||
var log = [offset + 'Scope(' + scope.$id + '): {'];
|
||||
for ( var key in scope ) {
|
||||
if (scope.hasOwnProperty(key) && !key.match(/^(\$|this)/)) {
|
||||
log.push(' ' + key + ': ' + toJson(scope[key]));
|
||||
}
|
||||
}
|
||||
var child = scope.$$childHead;
|
||||
while(child) {
|
||||
log.push(dumpScope(child, offset + ' '));
|
||||
child = child.$$nextSibling;
|
||||
}
|
||||
log.push('}');
|
||||
return log.join('\n' + offset);
|
||||
}
|
||||
|
||||
publishExternalAPI(angular)
|
||||
publishExternalAPI(angular);
|
||||
bindJQuery();
|
||||
beforeEach(function() {
|
||||
publishExternalAPI(angular)
|
||||
publishExternalAPI(angular);
|
||||
|
||||
// workaround for IE bug https://plus.google.com/104744871076396904202/posts/Kqjuj6RSbbT
|
||||
// IE overwrite window.jQuery with undefined because of empty jQuery var statement, so we have to
|
||||
|
|
@ -63,43 +27,20 @@ beforeEach(function() {
|
|||
// reset to jQuery or default to us.
|
||||
bindJQuery();
|
||||
jqLite(document.body).html('');
|
||||
|
||||
this.addMatchers({
|
||||
toHaveClass: function(clazz) {
|
||||
this.message = function() {
|
||||
return "Expected '" + sortedHtml(this.actual) + "' to have class '" + clazz + "'.";
|
||||
};
|
||||
return this.actual.hasClass ?
|
||||
this.actual.hasClass(clazz) :
|
||||
jqLite(this.actual).hasClass(clazz);
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
function inject(){
|
||||
var blockFns = sliceArgs(arguments);
|
||||
return function(){
|
||||
var spec = this;
|
||||
spec.$injector = spec.$injector || angular.injector('NG', 'NG_MOCK');
|
||||
angular.forEach(blockFns, function(fn){
|
||||
spec.$injector.invoke(spec, fn);
|
||||
});
|
||||
};
|
||||
}
|
||||
afterEach(function() {
|
||||
if (this.$injector) {
|
||||
var $rootScope = this.$injector('$rootScope');
|
||||
var $log = this.$injector('$log');
|
||||
// release the injector
|
||||
dealoc($rootScope);
|
||||
|
||||
// check $log mock
|
||||
$log.assertEmpty && $log.assertEmpty();
|
||||
}
|
||||
|
||||
afterEach(inject(function($rootScope, $log) {
|
||||
// release the injector
|
||||
dealoc($rootScope);
|
||||
|
||||
// check $log mock
|
||||
$log.assertEmpty && $log.assertEmpty();
|
||||
|
||||
clearJqCache();
|
||||
}));
|
||||
|
||||
function clearJqCache() {
|
||||
// complain about uncleared jqCache references
|
||||
var count = 0;
|
||||
forEachSorted(jqCache, function(value, key){
|
||||
count ++;
|
||||
|
|
@ -115,15 +56,8 @@ function clearJqCache() {
|
|||
if (count) {
|
||||
fail('Found jqCache references that were not deallocated!');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
function nakedExpect(obj) {
|
||||
return expect(angular.fromJson(angular.toJson(obj)));
|
||||
}
|
||||
|
||||
function childNode(element, index) {
|
||||
return jqLite(element[0].childNodes[index]);
|
||||
}
|
||||
|
||||
function dealoc(obj) {
|
||||
if (obj) {
|
||||
|
|
@ -240,43 +174,10 @@ function isCssVisible(node) {
|
|||
}
|
||||
|
||||
function assertHidden(node) {
|
||||
assertFalse("Node should be hidden but vas visible: " + sortedHtml(node), isCssVisible(node));
|
||||
assertFalse("Node should be hidden but vas visible: " + angular.mock.dump(node), isCssVisible(node));
|
||||
}
|
||||
|
||||
function assertVisible(node) {
|
||||
assertTrue("Node should be visible but vas hidden: " + sortedHtml(node), isCssVisible(node));
|
||||
assertTrue("Node should be visible but vas hidden: " + angular.mock.dump(node), isCssVisible(node));
|
||||
}
|
||||
|
||||
function assertJsonEquals(expected, actual) {
|
||||
assertEquals(toJson(expected), toJson(actual));
|
||||
}
|
||||
|
||||
function assertUndefined(value) {
|
||||
assertEquals('undefined', typeof value);
|
||||
}
|
||||
|
||||
function assertDefined(value) {
|
||||
assertTrue(toJson(value), !!value);
|
||||
}
|
||||
|
||||
function assertThrows(error, fn){
|
||||
var exception = null;
|
||||
try {
|
||||
fn();
|
||||
} catch(e) {
|
||||
exception = e;
|
||||
}
|
||||
if (!exception) {
|
||||
fail("Expecting exception, none thrown");
|
||||
}
|
||||
assertEquals(error, exception);
|
||||
}
|
||||
|
||||
window.log = noop;
|
||||
window.error = noop;
|
||||
|
||||
function rethrow(e) {
|
||||
if(e) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue