chore(tests): update to jasmine 2.x

Closes #3469
Implements #3458
This commit is contained in:
Jesus Rodriguez
2015-03-30 15:25:08 +02:00
committed by Wesley Cho
parent dfe9854be3
commit 7de7a8ea28
14 changed files with 273 additions and 149 deletions
+49 -17
View File
@@ -1,25 +1,57 @@
// jasmine matcher for expecting an element to have a css class
// https://github.com/angular/angular.js/blob/master/test/matchers.js
beforeEach(function() {
this.addMatchers({
toHaveClass: function(cls) {
this.message = function() {
return "Expected '" + this.actual + "'" + (this.isNot ? ' not ' : ' ') + "to have class '" + cls + "'.";
};
jasmine.addMatchers({
toHaveClass: function(util, customEqualityTesters) {
return {
compare: function(actual, expected) {
var result = {
pass: actual.hasClass(expected)
};
return this.actual.hasClass(cls);
},
toBeHidden: function () {
var element = angular.element(this.actual);
return element.hasClass('ng-hide') ||
element.css('display') == 'none';
},
toHaveFocus: function () {
this.message = function () {
return 'Expected \'' + angular.mock.dump(this.actual) + '\' to have focus';
};
if (result.pass) {
result.message = 'Expected "' + actual + '" not to have the "' + expected + '" class.';
} else {
result.message = 'Expected "' + actual + '" to have the "' + expected + '" class.';
}
return document.activeElement === this.actual[0];
return result;
}
}
},
toBeHidden: function(util, customEqualityTesters) {
return {
compare: function(actual) {
var result = {
pass: actual.hasClass('ng-hide') || actual.css('display') === 'none'
};
if (result.pass) {
result.message = 'Expected "' + actual + '" not to be hidden';
} else {
result.message = 'Expected "' + actual + '" to be hidden';
}
return result;
}
}
},
toHaveFocus: function(util, customEqualityTesters) {
return {
compare: function(actual) {
var result = {
pass: document.activeElement === actual[0]
};
if (result.pass) {
result.message = 'Expected "' + actual + '" not to have focus';
} else {
result.message = 'Expected "' + actual + '" to have focus';
}
return result;
}
}
}
});
});
+2 -1
View File
@@ -22,11 +22,12 @@
"grunt-html2js": "^0.3.0",
"grunt-karma": "^0.10.1",
"grunt-ngdocs": "~0.1.1",
"jasmine-core": "^2.2.0",
"karma": "^0.12.31",
"karma-chrome-launcher": "^0.1.7",
"karma-coverage": "^0.2.7",
"karma-firefox-launcher": "^0.1.4",
"karma-jasmine": "^0.1.5",
"karma-jasmine": "^0.3.5",
"node-markdown": "0.1.1",
"semver": "^4.3.3",
"shelljs": "^0.4.0"
+2 -2
View File
@@ -201,7 +201,7 @@ describe('buttons', function () {
expect(btns.eq(1)).not.toHaveClass('active');
btns.eq(0).click();
expect($scope.model).toEqual(undefined);
expect($scope.model).toBeNull();
expect(btns.eq(1)).not.toHaveClass('active');
expect(btns.eq(0)).not.toHaveClass('active');
});
@@ -225,4 +225,4 @@ describe('buttons', function () {
});
});
});
});
});
+4 -4
View File
@@ -262,7 +262,7 @@ describe('carousel', function() {
testSlideActive(2);
$interval.flush(scope.interval);
testSlideActive(0);
spyOn($interval, 'cancel').andCallThrough();
spyOn($interval, 'cancel').and.callThrough();
scope.$destroy();
expect($interval.cancel).toHaveBeenCalled();
});
@@ -396,17 +396,17 @@ describe('carousel', function() {
});
it('issue 1414 - should not continue running timers after scope is destroyed', function() {
spyOn(scope, 'next').andCallThrough();
spyOn(scope, 'next').and.callThrough();
scope.interval = 2000;
scope.$digest();
$interval.flush(scope.interval);
expect(scope.next.calls.length).toBe(1);
expect(scope.next.calls.count()).toBe(1);
scope.$destroy();
$interval.flush(scope.interval);
expect(scope.next.calls.length).toBe(1);
expect(scope.next.calls.count()).toBe(1);
});
});
});
+1 -1
View File
@@ -107,4 +107,4 @@ describe('collapse directive', function () {
});
});
});
});
+16 -16
View File
@@ -942,20 +942,20 @@ describe('datepicker directive', function () {
});
it('executes the dateDisabled expression for each visible day plus one for validation', function() {
expect($rootScope.dateDisabledHandler.calls.length).toEqual(42 + 1);
expect($rootScope.dateDisabledHandler.calls.count()).toEqual(42 + 1);
});
it('executes the dateDisabled expression for each visible month plus one for validation', function() {
$rootScope.dateDisabledHandler.reset();
$rootScope.dateDisabledHandler.calls.reset();
clickTitleButton();
expect($rootScope.dateDisabledHandler.calls.length).toEqual(12 + 1);
expect($rootScope.dateDisabledHandler.calls.count()).toEqual(12 + 1);
});
it('executes the dateDisabled expression for each visible year plus one for validation', function() {
clickTitleButton();
$rootScope.dateDisabledHandler.reset();
$rootScope.dateDisabledHandler.calls.reset();
clickTitleButton();
expect($rootScope.dateDisabledHandler.calls.length).toEqual(20 + 1);
expect($rootScope.dateDisabledHandler.calls.count()).toEqual(20 + 1);
});
});
@@ -967,20 +967,20 @@ describe('datepicker directive', function () {
});
it('executes the customClass expression for each visible day plus one for validation', function() {
expect($rootScope.customClassHandler.calls.length).toEqual(42);
expect($rootScope.customClassHandler.calls.count()).toEqual(42);
});
it('executes the customClass expression for each visible month plus one for validation', function() {
$rootScope.customClassHandler.reset();
$rootScope.customClassHandler.calls.reset();
clickTitleButton();
expect($rootScope.customClassHandler.calls.length).toEqual(12);
expect($rootScope.customClassHandler.calls.count()).toEqual(12);
});
it('executes the customClass expression for each visible year plus one for validation', function() {
clickTitleButton();
$rootScope.customClassHandler.reset();
$rootScope.customClassHandler.calls.reset();
clickTitleButton();
expect($rootScope.customClassHandler.calls.length).toEqual(20);
expect($rootScope.customClassHandler.calls.count()).toEqual(20);
});
});
@@ -1316,13 +1316,13 @@ describe('datepicker directive', function () {
expect(dropdownEl).toBeHidden();
expect(document.activeElement.tagName).toBe('INPUT');
});
it('stops the ESC key from propagating if the dropdown is open, but not when closed', function() {
expect(dropdownEl).not.toBeHidden();
dropdownEl.find('button').eq(0).focus();
expect(document.activeElement.tagName).toBe('BUTTON');
var documentKey = -1;
var getKey = function(evt) { documentKey = evt.which; };
$document.bind('keydown', getKey);
@@ -1331,10 +1331,10 @@ describe('datepicker directive', function () {
$rootScope.$digest();
expect(dropdownEl).toBeHidden();
expect(documentKey).toBe(-1);
triggerKeyDown(inputEl, 'esc');
expect(documentKey).toBe(27);
$document.unbind('keydown', getKey);
});
});
@@ -1731,7 +1731,7 @@ describe('datepicker directive', function () {
var $body = $document.find('body'),
bodyLength = $body.children().length,
elm = angular.element(
'<div><input datepicker-popup ng-model="date" datepicker-append-to-body="true"></input></div>'
'<div><input datepicker-popup ng-model="date" datepicker-append-to-body="true" /></div>'
);
$compile(elm)($rootScope);
$rootScope.$digest();
@@ -1744,7 +1744,7 @@ describe('datepicker directive', function () {
bodyLength = $body.children().length,
isolatedScope = $rootScope.$new(),
elm = angular.element(
'<input datepicker-popup ng-model="date" datepicker-append-to-body="true"></input>'
'<input datepicker-popup ng-model="date" datepicker-append-to-body="true" />'
);
$compile(elm)(isolatedScope);
isolatedScope.$digest();
+85 -38
View File
@@ -27,60 +27,107 @@ describe('$modal', function () {
}));
beforeEach(function () {
this.addMatchers({
jasmine.addMatchers({
toBeResolvedWith: function(util, customEqualityTesters) {
return {
compare: function(promise, expected) {
promise.then(function(result) {
expect(result).toEqual(expected);
toBeResolvedWith: function(value) {
var resolved;
this.message = function() {
return 'Expected "' + angular.mock.dump(resolved) + '" to be resolved with "' + value + '".';
if (result === expected) {
result.message = 'Expected "' + angular.mock.dump(result) + '" not to be resolved with "' + expected + '".';
} else {
result.message = 'Expected "' + angular.mock.dump(result) + '" to be resolved with "' + expected + '".';
}
});
$rootScope.$digest();
return {pass: true};
}
};
this.actual.then(function(result){
resolved = result;
});
$rootScope.$digest();
return resolved === value;
},
toBeRejectedWith: function(util, customEqualityTesters) {
return {
compare: function(promise, expected) {
var result = {};
toBeRejectedWith: function(value) {
var rejected;
this.message = function() {
return 'Expected "' + angular.mock.dump(rejected) + '" to be rejected with "' + value + '".';
promise.then(function() {
}, function(result) {
expect(result).toEqual(expected);
if (result === expected) {
result.message = 'Expected "' + angular.mock.dump(result) + '" not to be rejected with "' + expected + '".';
} else {
result.message = 'Expected "' + angular.mock.dump(result) + '" to be rejected with "' + expected + '".';
}
});
$rootScope.$digest();
return {pass: true};
}
};
this.actual.then(angular.noop, function(reason){
rejected = reason;
});
$rootScope.$digest();
return rejected === value;
},
toHaveModalOpenWithContent: function(util, customEqualityTesters) {
return {
compare: function(actual, content, selector) {
var contentToCompare, modalDomEls = actual.find('body > div.modal > div.modal-dialog > div.modal-content');
toHaveModalOpenWithContent: function(content, selector) {
contentToCompare = selector ? modalDomEls.find(selector) : modalDomEls;
var contentToCompare, modalDomEls = this.actual.find('body > div.modal > div.modal-dialog > div.modal-content');
var result = {
pass: modalDomEls.css('display') === 'block' && contentToCompare.html() === content
};
this.message = function() {
return '"Expected "' + angular.mock.dump(modalDomEls) + '" to be open with "' + content + '".';
if (result.pass) {
result.message = '"Expected "' + angular.mock.dump(modalDomEls) + '" not to be open with "' + content + '".';
} else {
result.message = '"Expected "' + angular.mock.dump(modalDomEls) + '" to be open with "' + content + '".';
}
return result;
}
};
contentToCompare = selector ? modalDomEls.find(selector) : modalDomEls;
return modalDomEls.css('display') === 'block' && contentToCompare.html() == content;
},
toHaveModalsOpen: function(util, customEqualityTesters) {
return {
compare: function(actual, expected) {
var modalDomEls = actual.find('body > div.modal');
toHaveModalsOpen: function(noOfModals) {
var result = {
pass: util.equals(modalDomEls.length, expected, customEqualityTesters)
};
var modalDomEls = this.actual.find('body > div.modal');
return modalDomEls.length === noOfModals;
},
if (result.pass) {
result.message = 'Expected "' + angular.mock.dump(modalDomEls) + '" not to have "' + expected + '" modals opened.';
} else {
result.message = 'Expected "' + angular.mock.dump(modalDomEls) + '" to have "' + expected + '" modals opened.';
}
toHaveBackdrop: function() {
var backdropDomEls = this.actual.find('body > div.modal-backdrop');
this.message = function() {
return 'Expected "' + angular.mock.dump(backdropDomEls) + '" to be a backdrop element".';
return result;
}
};
},
toHaveBackdrop: function(util, customEqualityTesters) {
return {
compare: function(actual, expected) {
var backdropDomEls = actual.find('body > div.modal-backdrop');
return backdropDomEls.length === 1;
var result = {
pass: util.equals(backdropDomEls.length, 1, customEqualityTesters)
};
if (result.pass) {
result.message = 'Expected "' + angular.mock.dump(backdropDomEls) + '" not to be a backdrop element".';
} else {
result.message = 'Expected "' + angular.mock.dump(backdropDomEls) + '" to be a backdrop element".';
}
return result;
}
};
}
});
});
+18 -8
View File
@@ -16,18 +16,28 @@ describe('position elements', function () {
$position = _$position_;
}));
beforeEach(function () {
this.addMatchers({
toBePositionedAt: function(top, left) {
this.message = function() {
return 'Expected "(' + this.actual.top + ', ' + this.actual.left + ')" to be positioned at (' + top + ', ' + left + ')';
};
jasmine.addMatchers({
toBePositionedAt: function(util, customEqualityTesters) {
return {
compare: function(actual, top, left) {
var result = {
pass: util.equals(actual.top, top, customEqualityTesters) &&
util.equals(actual.left, left, customEqualityTesters)
};
return this.actual.top == top && this.actual.left == left;
if (result.pass) {
result.message = 'Expected "(' + actual.top + ', ' + actual.left + ')" not to be positioned at (' + top + ', ' + left + ')';
} else {
result.message = 'Expected "(' + actual.top + ', ' + actual.left + ')" to be positioned at (' + top + ', ' + left + ')';
}
return result;
}
};
}
});
});
describe('append-to-body: false', function () {
beforeEach(function () {
@@ -96,4 +106,4 @@ describe('position elements', function () {
});
});
});
});
+1 -1
View File
@@ -596,7 +596,7 @@ describe('tabs', function() {
angular.forEach(scope.tabs, function(tab, i) {
if (activeTab === tab) {
expect(tab.active).toBe(true);
expect(tab.select.callCount).toBe( (tab.disabled) ? 0 : 1 );
expect(tab.select.calls.count()).toBe( (tab.disabled) ? 0 : 1 );
expect(_titles.eq(i)).toHaveClass('active');
expect(contents().eq(i).text().trim()).toBe('content ' + i);
expect(contents().eq(i)).toHaveClass('active');
+1 -1
View File
@@ -961,7 +961,7 @@ describe('timepicker directive', function () {
doClick(btn1, 2);
doClick(btn2, 3);
$rootScope.$digest();
expect($rootScope.changeHandler.callCount).toBe(5);
expect($rootScope.changeHandler.calls.count()).toBe(5);
});
it('should not be called when model changes programatically', function() {
+6 -6
View File
@@ -460,7 +460,7 @@ describe( 'tooltip positioning', function() {
beforeEach(inject(function($rootScope, $compile, _$position_) {
$position = _$position_;
spyOn($position, 'positionElements').andCallThrough();
spyOn($position, 'positionElements').and.callThrough();
scope = $rootScope;
scope.text = 'Some Text';
@@ -479,19 +479,19 @@ describe( 'tooltip positioning', function() {
scope.$digest();
$timeout.flush();
var startingPositionCalls = $position.positionElements.calls.length;
var startingPositionCalls = $position.positionElements.calls.count();
scope.$digest();
$timeout.flush();
expect($position.positionElements.calls.length).toEqual(startingPositionCalls + 1);
expect($position.positionElements.calls.count()).toEqual(startingPositionCalls + 1);
// Check that positionElements was called with elm
expect($position.positionElements.calls[startingPositionCalls].args[0][0])
expect($position.positionElements.calls.argsFor(startingPositionCalls)[0][0])
.toBe(elm[0]);
scope.$digest();
$timeout.flush();
expect($position.positionElements.calls.length).toEqual(startingPositionCalls + 2);
expect($position.positionElements.calls[startingPositionCalls + 1].args[0][0])
expect($position.positionElements.calls.count()).toEqual(startingPositionCalls + 2);
expect($position.positionElements.calls.argsFor(startingPositionCalls + 1)[0][0])
.toBe(elm[0]);
scope.$digest();
}));
+18 -8
View File
@@ -12,16 +12,26 @@ describe('tooltip directive', function () {
}));
beforeEach(function(){
this.addMatchers({
toHaveOpenTooltips: function(noOfOpened) {
var ttipElements = this.actual.find('div.tooltip');
noOfOpened = noOfOpened || 1;
jasmine.addMatchers({
toHaveOpenTooltips: function(util, customEqualityTesters) {
return {
compare: function(actual, noOfOpened) {
var ttipElements = actual.find('div.tooltip');
noOfOpened = noOfOpened || 1;
this.message = function() {
return 'Expected "' + angular.mock.dump(ttipElements) + '" to have "' + ttipElements.length + '" opened tooltips.';
var result = {
pass: util.equals(ttipElements.length, noOfOpened, customEqualityTesters)
};
if (result.message) {
result.message = 'Expected "' + angular.mock.dump(ttipElements) + '" not to have "' + ttipElements.length + '" opened tooltips.';
} else {
result.message = 'Expected "' + angular.mock.dump(ttipElements) + '" to have "' + ttipElements.length + '" opened tooltips.';
}
return result;
}
};
return ttipElements.length === noOfOpened;
}
});
});
+1 -1
View File
@@ -62,7 +62,7 @@ describe('$transition', function() {
beforeEach(function() {
element = angular.element('<div></div>');
// Mock up the element.bind method
spyOn(element, 'bind').andCallFake(function(element, handler) {
spyOn(element, 'bind').and.callFake(function(element, handler) {
// Store the handler to be used to simulate the end of the transition later
triggerTransitionEnd = handler;
});
+69 -45
View File
@@ -71,28 +71,48 @@ describe('typeahead tests', function () {
//custom matchers
beforeEach(function () {
this.addMatchers({
toBeClosed: function () {
var typeaheadEl = findDropDown(this.actual);
this.message = function () {
return 'Expected "' + angular.mock.dump(typeaheadEl) + '" to be closed.';
jasmine.addMatchers({
toBeClosed: function(util, customEqualityTesters) {
return {
compare: function(actual, expected) {
var typeaheadEl = findDropDown(actual);
var result = {
pass: util.equals(typeaheadEl.hasClass('ng-hide'), true, customEqualityTesters)
};
if (result.pass) {
result.message = 'Expected "' + angular.mock.dump(typeaheadEl) + '" not to be closed.';
} else {
result.message = 'Expected "' + angular.mock.dump(typeaheadEl) + '" to be closed.';
}
return result;
}
};
return typeaheadEl.hasClass('ng-hide') === true;
},
toBeOpenWithActive: function(util, customEqualityTesters) {
return {
compare: function(actual, noOfMatches, activeIdx) {
var typeaheadEl = findDropDown(actual);
var liEls = findMatches(actual);
}, toBeOpenWithActive: function (noOfMatches, activeIdx) {
var result = {
pass: util.equals(typeaheadEl.length, 1, customEqualityTesters) &&
util.equals(typeaheadEl.hasClass('ng-hide'), false, customEqualityTesters) &&
util.equals(liEls.length, noOfMatches, customEqualityTesters) &&
activeIdx === -1 ? !$(liEls).hasClass('active') : $(liEls[activeIdx]).hasClass('active')
};
var typeaheadEl = findDropDown(this.actual);
var liEls = findMatches(this.actual);
if (result.pass) {
result.message = 'Expected "' + actual + '" not to be opened.';
} else {
result.message = 'Expected "' + actual + '" to be opened.';
}
this.message = function () {
return 'Expected "' + this.actual + '" to be opened.';
return result;
}
};
return (typeaheadEl.length === 1 &&
typeaheadEl.hasClass('ng-hide') === false &&
liEls.length === noOfMatches &&
(activeIdx === -1 ? !$(liEls).hasClass('active') : $(liEls[activeIdx]).hasClass('active'))
);
}
});
});
@@ -614,21 +634,42 @@ describe('typeahead tests', function () {
expect(values).not.toContain('match');
}));
it('does not close matches popup on click in input', function () {
var element = prepareInputEl('<div><input ng-model="result" typeahead="item for item in source | filter:$viewValue"></div>');
var inputEl = findInput(element);
describe('', function() {
// Dummy describe to be able to create an after hook for this tests
var element;
// Note that this bug can only be found when element is in the document
$document.find('body').append(element);
// Extra teardown for this spec
this.after(function () { element.remove(); });
it('does not close matches popup on click in input', function () {
element = prepareInputEl('<div><input ng-model="result" typeahead="item for item in source | filter:$viewValue"></div>');
var inputEl = findInput(element);
changeInputValueTo(element, 'b');
// Note that this bug can only be found when element is in the document
$document.find('body').append(element);
inputEl.click();
$scope.$digest();
changeInputValueTo(element, 'b');
expect(element).toBeOpenWithActive(2, 0);
inputEl.click();
$scope.$digest();
expect(element).toBeOpenWithActive(2, 0);
});
it('issue #1773 - should not trigger an error when used with ng-focus', function () {
element = prepareInputEl('<div><input ng-model="result" typeahead="item for item in source | filter:$viewValue" ng-focus="foo()"></div>');
var inputEl = findInput(element);
// Note that this bug can only be found when element is in the document
$document.find('body').append(element);
changeInputValueTo(element, 'b');
var match = $(findMatches(element)[1]).find('a')[0];
$(match).click();
$scope.$digest();
});
afterEach(function() {
element.remove();
});
});
it('issue #1238 - allow names like "query" to be used inside "in" expressions ', function () {
@@ -643,23 +684,6 @@ describe('typeahead tests', function () {
expect(element).toBeOpenWithActive(2, 0);
});
it('issue #1773 - should not trigger an error when used with ng-focus', function () {
var element = prepareInputEl('<div><input ng-model="result" typeahead="item for item in source | filter:$viewValue" ng-focus="foo()"></div>');
var inputEl = findInput(element);
// Note that this bug can only be found when element is in the document
$document.find('body').append(element);
// Extra teardown for this spec
this.after(function () { element.remove(); });
changeInputValueTo(element, 'b');
var match = $(findMatches(element)[1]).find('a')[0];
$(match).click();
$scope.$digest();
});
it('issue #3318 - should set model validity to true when set manually', function () {
var element = prepareInputEl(