From 2430f52bb97fa9d682e5f028c977c5bf94c5ec38 Mon Sep 17 00:00:00 2001 From: Misko Hevery Date: Fri, 23 Mar 2012 14:03:24 -0700 Subject: chore(module): move files around in preparation for more modules --- test/ngScenario/dslSpec.js | 629 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 629 insertions(+) create mode 100644 test/ngScenario/dslSpec.js (limited to 'test/ngScenario/dslSpec.js') diff --git a/test/ngScenario/dslSpec.js b/test/ngScenario/dslSpec.js new file mode 100644 index 00000000..0a8ab762 --- /dev/null +++ b/test/ngScenario/dslSpec.js @@ -0,0 +1,629 @@ +'use strict'; + +describe("angular.scenario.dsl", function() { + var element; + var $window, $root; + var eventLog; + + afterEach(function() { + dealoc(element); + }); + + beforeEach(inject(function($injector) { + eventLog = []; + $window = { + document: window.document.body, + angular: new angular.scenario.testing.MockAngular() + }; + jqLite($window.document).data('$injector', $injector).attr('ng-app', '').addClass('html'); + $root = $injector.get('$rootScope'); + $root.emit = function(eventName) { + eventLog.push(eventName); + }; + $root.on = function(eventName) { + eventLog.push('Listener Added for ' + eventName); + }; + $root.futures = []; + $root.futureLog = []; + $root.$window = $window; + $root.addFuture = function(name, fn) { + this.futures.push(name); + fn.call(this, function(error, result) { + $root.futureError = error; + $root.futureResult = result; + $root.futureLog.push(name); + }); + }; + $root.dsl = {}; + angular.forEach(angular.scenario.dsl, function(fn, name) { + $root.dsl[name] = function() { + return fn.call($root).apply($root, arguments); + }; + }); + $root.application = new angular.scenario.Application(jqLite($window.document)); + $root.application.getWindow_ = function() { + return $window; + }; + $root.application.navigateTo = function(url, callback) { + $window.location = url; + callback(); + }; + // Just use the real one since it delegates to this.addFuture + $root.addFutureAction = angular.scenario. + SpecRunner.prototype.addFutureAction; + jqLite($window.document).html(''); + })); + + afterEach(function(){ + jqLite($window.document).removeData('$injector'); + }); + + describe('Pause', function() { + it('should pause until resume to complete', function() { + expect($window.resume).toBeUndefined(); + $root.dsl.pause(); + expect(angular.isFunction($window.resume)).toBeTruthy(); + expect($root.futureLog).toEqual([]); + $window.resume(); + expect($root.futureLog). + toEqual(['pausing for you to resume']); + expect(eventLog).toContain('InteractivePause'); + }); + }); + + describe('Sleep', function() { + beforeEach(function() { + $root.$window.setTimeout = function(fn, value) { + $root.timerValue = value; + fn(); + }; + }); + + it('should sleep for specified seconds', function() { + $root.dsl.sleep(10); + expect($root.timerValue).toEqual(10000); + expect($root.futureResult).toEqual(10000); + }); + }); + + describe('Expect', function() { + it('should chain and execute matcher', function() { + var future = {value: 10}; + var result = $root.dsl.expect(future); + result.toEqual(10); + expect($root.futureError).toBeUndefined(); + expect($root.futureResult).toBeUndefined(); + result = $root.dsl.expect(future); + result.toEqual(20); + expect($root.futureError).toBeDefined(); + }); + }); + + describe('Browser', function() { + describe('Reload', function() { + it('should navigateTo', function() { + $window.location = { + href: '#foo' + }; + $root.dsl.browser().reload(); + expect($root.futureResult).toEqual('#foo'); + expect($window.location).toEqual('#foo'); + }); + }); + + describe('NavigateTo', function() { + it('should allow a string url', function() { + $root.dsl.browser().navigateTo('http://myurl'); + expect($window.location).toEqual('http://myurl'); + expect($root.futureResult).toEqual('http://myurl'); + }); + + it('should allow a future url', function() { + $root.dsl.browser().navigateTo('http://myurl', function() { + return 'http://futureUrl/'; + }); + expect($window.location).toEqual('http://futureUrl/'); + expect($root.futureResult).toEqual('http://futureUrl/'); + }); + + it('should complete if angular is missing from app frame', function() { + delete $window.angular; + $root.dsl.browser().navigateTo('http://myurl'); + expect($window.location).toEqual('http://myurl'); + expect($root.futureResult).toEqual('http://myurl'); + }); + }); + + describe('window', function() { + beforeEach(function() { + $window.location = { + href: 'http://myurl/some/path?foo=10#/bar?x=2', + pathname: '/some/path', + search: '?foo=10', + hash: '#bar?x=2' + }; + }); + + it('should return full URL for href', function() { + $root.dsl.browser().window().href(); + expect($root.futureResult).toEqual($window.location.href); + }); + + it('should return the pathname', function() { + $root.dsl.browser().window().path(); + expect($root.futureResult).toEqual($window.location.pathname); + }); + + it('should return the search part', function() { + $root.dsl.browser().window().search(); + expect($root.futureResult).toEqual($window.location.search); + }); + + it('should return the hash without the #', function() { + $root.dsl.browser().window().hash(); + expect($root.futureResult).toEqual('bar?x=2'); + }); + }); + + describe('location', function() { + beforeEach(function() { + $window.angular.injector = function() { + return { + get: function(serviceId) { + if (serviceId == '$location') { + return { + url: function() {return '/path?search=a#hhh';}, + path: function() {return '/path';}, + search: function() {return {search: 'a'};}, + hash: function() {return 'hhh';} + }; + } + throw new Error('unknown service id ' + serviceId); + } + }; + }; + }); + + it('should return full url', function() { + $root.dsl.browser().location().url(); + expect($root.futureResult).toEqual('/path?search=a#hhh'); + }); + + it('should return the pathname', function() { + $root.dsl.browser().location().path(); + expect($root.futureResult).toEqual('/path'); + }); + + it('should return the query string as an object', function() { + $root.dsl.browser().location().search(); + expect($root.futureResult).toEqual({search: 'a'}); + }); + + it('should return the hash without the #', function() { + $root.dsl.browser().location().hash(); + expect($root.futureResult).toEqual('hhh'); + }); + }); + }); + + describe('Element Finding', function() { + var doc; + beforeEach(inject(function($injector) { + doc = _jQuery($window.document).append('
').find('.body'); + })); + + describe('Select', function() { + it('should select single option', function() { + doc.append( + '' + ); + $root.dsl.select('test').option('A'); + expect(doc.find('[ng-model="test"]').val()).toEqual('A'); + }); + + it('should select option by name', function() { + doc.append( + '' + ); + $root.dsl.select('test').option('one'); + expect(doc.find('[ng-model="test"]').val()).toEqual('A'); + }); + + it('should select multiple options', function() { + doc.append( + '' + ); + $root.dsl.select('test').options('A', 'B'); + expect(doc.find('[ng-model="test"]').val()).toEqual(['A','B']); + }); + + it('should fail to select multiple options on non-multiple select', function() { + doc.append(''); + $root.dsl.select('test').options('A', 'B'); + expect($root.futureError).toMatch(/did not match/); + }); + }); + + describe('Element', function() { + it('should execute click', function() { + var clicked; + // Hash is important, otherwise we actually + // go to a different page and break the runner + doc.append(''); + doc.find('a').click(function() { + clicked = true; + }); + $root.dsl.element('a').click(); + }); + + it('should navigate page if click on anchor', function() { + expect($window.location).not.toEqual('#foo'); + doc.append(''); + $root.dsl.element('a').click(); + expect($window.location).toMatch(/#foo$/); + }); + + it('should not navigate if click event was cancelled', function() { + var initLocation = $window.location, + elm = jqLite(''); + + doc.append(elm); + elm.bind('click', function(event) { + event.preventDefault(); + }); + + $root.dsl.element('a').click(); + expect($window.location).toBe(initLocation); + dealoc(elm); + }); + + it('should count matching elements', function() { + doc.append(''); + $root.dsl.element('span').count(); + expect($root.futureResult).toEqual(2); + }); + + it('should return count of 0 if no matching elements', function() { + $root.dsl.element('span').count(); + expect($root.futureResult).toEqual(0); + }); + + it('should get attribute', function() { + doc.append(''); + $root.dsl.element('#test').attr('class'); + expect($root.futureResult).toEqual('foo'); + }); + + it('should set attribute', function() { + doc.append(''); + $root.dsl.element('#test').attr('class', 'bam'); + expect(doc.find('#test').attr('class')).toEqual('bam'); + }); + + it('should get property', function() { + doc.append(''); + $root.dsl.element('#test').prop('className'); + expect($root.futureResult).toEqual('foo'); + }); + + it('should set property', function() { + doc.append(''); + $root.dsl.element('#test').prop('className', 'bam'); + expect(doc.find('#test').prop('className')).toEqual('bam'); + }); + + it('should get css', function() { + doc.append(''); + $root.dsl.element('#test').css('height'); + expect($root.futureResult).toMatch(/30px/); + }); + + it('should set css', function() { + doc.append(''); + $root.dsl.element('#test').css('height', '20px'); + expect(doc.find('#test').css('height')).toEqual('20px'); + }); + + it('should add all jQuery key/value methods', function() { + var METHODS = ['css', 'attr']; + var chain = $root.dsl.element('input'); + angular.forEach(METHODS, function(name) { + expect(angular.isFunction(chain[name])).toBeTruthy(); + }); + }); + + it('should get val', function() { + doc.append(''); + $root.dsl.element('input').val(); + expect($root.futureResult).toEqual('bar'); + }); + + it('should set val', function() { + doc.append(''); + $root.dsl.element('input').val('baz'); + expect(doc.find('input').val()).toEqual('baz'); + }); + + it('should use correct future name for generated set methods', function() { + doc.append(''); + $root.dsl.element('input').val(false); + expect($root.futures.pop()).toMatch(/element 'input' set val/); + }); + + it('should use correct future name for generated get methods', function() { + doc.append(''); + $root.dsl.element('input').val(); + expect($root.futures.pop()).toMatch(/element 'input' val/); + }); + + it('should add all jQuery property methods', function() { + var METHODS = [ + 'val', 'text', 'html', 'height', 'innerHeight', 'outerHeight', 'width', + 'innerWidth', 'outerWidth', 'position', 'scrollLeft', 'scrollTop', 'offset' + ]; + var chain = $root.dsl.element('input'); + angular.forEach(METHODS, function(name) { + expect(angular.isFunction(chain[name])).toBeTruthy(); + }); + }); + + it('should execute custom query', function() { + doc.append(''); + $root.dsl.element('#test').query(function(elements, done) { + done(null, elements.attr('href')); + }); + expect($root.futureResult).toEqual('http://example.com/myUrl'); + }); + + it('should use the selector as label if none is given', function() { + $root.dsl.element('mySelector'); + expect($root.label).toEqual('mySelector'); + }); + + it('should include the selector in paren when a label is given', function() { + $root.dsl.element('mySelector', 'myLabel'); + expect($root.label).toEqual('myLabel ( mySelector )'); + }); + }); + + describe('Repeater', function() { + var chain; + beforeEach(inject(function($compile, $rootScope) { + element = $compile( + '