diff options
| author | Misko Hevery | 2012-03-23 14:03:24 -0700 | 
|---|---|---|
| committer | Misko Hevery | 2012-03-28 11:16:35 -0700 | 
| commit | 2430f52bb97fa9d682e5f028c977c5bf94c5ec38 (patch) | |
| tree | e7529b741d70199f36d52090b430510bad07f233 /test/ngScenario/dslSpec.js | |
| parent | 944098a4e0f753f06b40c73ca3e79991cec6c2e2 (diff) | |
| download | angular.js-2430f52bb97fa9d682e5f028c977c5bf94c5ec38.tar.bz2 | |
chore(module): move files around in preparation for more modules
Diffstat (limited to 'test/ngScenario/dslSpec.js')
| -rw-r--r-- | test/ngScenario/dslSpec.js | 629 | 
1 files changed, 629 insertions, 0 deletions
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('<div class="body"></div>').find('.body'); +    })); + +    describe('Select', function() { +      it('should select single option', function() { +        doc.append( +          '<select ng-model="test">' + +          '  <option value=A>one</option>' + +          '  <option value=B selected>two</option>' + +          '</select>' +        ); +        $root.dsl.select('test').option('A'); +        expect(doc.find('[ng-model="test"]').val()).toEqual('A'); +      }); + +      it('should select option by name', function() { +        doc.append( +            '<select ng-model="test">' + +            '  <option value=A>one</option>' + +            '  <option value=B selected>two</option>' + +            '</select>' +          ); +          $root.dsl.select('test').option('one'); +          expect(doc.find('[ng-model="test"]').val()).toEqual('A'); +      }); + +      it('should select multiple options', function() { +        doc.append( +          '<select ng-model="test" multiple>' + +          '  <option>A</option>' + +          '  <option selected>B</option>' + +          '  <option>C</option>' + +          '</select>' +        ); +        $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('<select ng-model="test"></select>'); +        $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('<a href="#"></a>'); +        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('<a href="#foo"></a>'); +        $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('<a href="#foo"></a>'); + +        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('<span></span><span></span>'); +        $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('<div id="test" class="foo"></div>'); +        $root.dsl.element('#test').attr('class'); +        expect($root.futureResult).toEqual('foo'); +      }); + +      it('should set attribute', function() { +        doc.append('<div id="test" class="foo"></div>'); +        $root.dsl.element('#test').attr('class', 'bam'); +        expect(doc.find('#test').attr('class')).toEqual('bam'); +      }); + +      it('should get property', function() { +        doc.append('<div id="test" class="foo"></div>'); +        $root.dsl.element('#test').prop('className'); +        expect($root.futureResult).toEqual('foo'); +      }); + +      it('should set property', function() { +        doc.append('<div id="test" class="foo"></div>'); +        $root.dsl.element('#test').prop('className', 'bam'); +        expect(doc.find('#test').prop('className')).toEqual('bam'); +      }); + +      it('should get css', function() { +        doc.append('<div id="test" style="height: 30px"></div>'); +        $root.dsl.element('#test').css('height'); +        expect($root.futureResult).toMatch(/30px/); +      }); + +      it('should set css', function() { +        doc.append('<div id="test" style="height: 10px"></div>'); +        $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('<input value="bar">'); +        $root.dsl.element('input').val(); +        expect($root.futureResult).toEqual('bar'); +      }); + +      it('should set val', function() { +        doc.append('<input value="bar">'); +        $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('<input value="bar">'); +        $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('<input value="bar">'); +        $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('<a id="test" href="http://example.com/myUrl"></a>'); +        $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( +          '<ul><li ng-repeat="i in items">{{i.name}}  {{i.gender}}</li></ul>')($rootScope); +        $rootScope.items = [{name:'misko', gender:'male'}, {name:'felisa', gender:'female'}]; +        $rootScope.$apply(); +        doc.append(element); +        chain = $root.dsl.repeater('ul li'); +      })); + +      it('should get the row count', function() { +        chain.count(); +        expect($root.futureResult).toEqual(2); +      }); + +      it('should return 0 if repeater doesnt match', inject(function($rootScope) { +        $rootScope.items = []; +        $rootScope.$apply(); +        chain.count(); +        expect($root.futureResult).toEqual(0); +      })); + +      it('should get a row of bindings', function() { +        chain.row(1); +        expect($root.futureResult).toEqual(['felisa', 'female']); +      }); + +      it('should get a column of bindings', function() { +        chain.column('i.gender'); +        expect($root.futureResult).toEqual(['male', 'female']); +      }); + +      it('should use the selector as label if none is given', function() { +        expect($root.label).toEqual('ul li'); +      }); + +      it('should include the selector in paren when a label is given', function() { +        $root.dsl.repeater('mySelector', 'myLabel'); +        expect($root.label).toEqual('myLabel ( ul li mySelector )'); +      }); +    }); + +    describe('Binding', function() { +      var compile; + +      beforeEach(inject(function($compile, $rootScope) { +        compile = function(html, value) { +          element = $compile(html)($rootScope); +          doc.append(element); +          $rootScope.foo = {bar: value || 'some value'}; +          $rootScope.$apply(); +        }; +      })); + + +      it('should select binding in interpolation', function() { +        compile('<span>{{ foo.bar }}</span>'); +        $root.dsl.binding('foo.bar'); +        expect($root.futureResult).toEqual('some value'); +      }); + +      it('should select binding in multiple interpolations', function() { +        compile('<span>{{ foo.bar }}<hr/> {{ true }}</span>'); +        $root.dsl.binding('foo.bar'); +        expect($root.futureResult).toEqual('some value'); + +        $root.dsl.binding('true'); +        expect($root.futureResult).toEqual('true'); +      }); + +      it('should select binding by name', function() { +        compile('<span ng-bind=" foo.bar "></span>'); +        $root.dsl.binding('foo.bar'); +        expect($root.futureResult).toEqual('some value'); +      }); + +      it('should select binding by regexp', function() { +        compile('<span ng-bind="foo.bar">some value</span>'); +        $root.dsl.binding(/^foo\..+/); +        expect($root.futureResult).toEqual('some value'); +      }); + +      it('should return innerHTML for all the other elements', function() { +        compile('<div ng-bind-html="foo.bar"></div>', 'some <b>value</b>'); +        $root.dsl.binding('foo.bar'); +        expect($root.futureResult.toLowerCase()).toEqual('some <b>value</b>'); +      }); + +      it('should select binding in template by name', function() { +        compile('<pre ng-bind-template="foo {{foo.bar}} baz"></pre>', 'bar'); +        $root.dsl.binding('foo.bar'); +        expect($root.futureResult).toEqual('bar'); +      }); + +      it('should match bindings by substring match', function() { +        compile('<pre ng-bind="foo.bar | filter"></pre>', 'binding value'); +        $root.dsl.binding('foo . bar'); +        expect($root.futureResult).toEqual('binding value'); +      }); + +      it('should return error if no bindings in document', function() { +        $root.dsl.binding('foo.bar'); +        expect($root.futureError).toMatch(/did not match/); +      }); + +      it('should return error if no binding matches', function() { +        compile('<span ng-bind="foo">some value</span>'); +        $root.dsl.binding('foo.bar'); +        expect($root.futureError).toMatch(/did not match/); +      }); +    }); + +    describe('Using', function() { +      it('should prefix selector in $document.elements()', function() { +        var chain; +        doc.append( +          '<div id="test1"><input ng-model="test.input" value="something"></div>' + +          '<div id="test2"><input ng-model="test.input" value="something"></div>' +        ); +        chain = $root.dsl.using('div#test2'); +        chain.input('test.input').enter('foo'); +        var inputs = _jQuery('input[ng-model="test.input"]'); +        expect(inputs.first().val()).toEqual('something'); +        expect(inputs.last().val()).toEqual('foo'); +      }); + +      it('should use the selector as label if none is given', function() { +        $root.dsl.using('mySelector'); +        expect($root.label).toEqual('mySelector'); +      }); + +      it('should include the selector in paren when a label is given', function() { +        $root.dsl.using('mySelector', 'myLabel'); +        expect($root.label).toEqual('myLabel ( mySelector )'); +      }); + +    }); + +    describe('Input', function() { +      it('should change value in text input', function() { +        doc.append('<input ng-model="test.input" value="something">'); +        var chain = $root.dsl.input('test.input'); +        chain.enter('foo'); +        expect(_jQuery('input[ng-model="test.input"]').val()).toEqual('foo'); +      }); + +      it('should change value in text input in dash form', function() { +        doc.append('<input ng-model="test.input" value="something">'); +        var chain = $root.dsl.input('test.input'); +        chain.enter('foo'); +        expect(_jQuery('input[ng-model="test.input"]').val()).toEqual('foo'); +      }); + +      it('should return error if no input exists', function() { +        var chain = $root.dsl.input('test.input'); +        chain.enter('foo'); +        expect($root.futureError).toMatch(/did not match/); +      }); + +      it('should toggle checkbox state', function() { +        doc.append('<input type="checkbox" ng-model="test.input" checked>'); +        expect(_jQuery('input[ng-model="test.input"]'). +          prop('checked')).toBe(true); +        var chain = $root.dsl.input('test.input'); +        chain.check(); +        expect(_jQuery('input[ng-model="test.input"]'). +          prop('checked')).toBe(false); +        $window.angular.reset(); +        chain.check(); +        expect(_jQuery('input[ng-model="test.input"]'). +          prop('checked')).toBe(true); +      }); + +      it('should return error if checkbox did not match', function() { +        var chain = $root.dsl.input('test.input'); +        chain.check(); +        expect($root.futureError).toMatch(/did not match/); +      }); + +      it('should select option from radio group', function() { +        doc.append( +          '<input type="radio" name="r" ng:model="test.input" value="foo">' + +          '<input type="radio" name="r" ng:model="test.input" value="bar" checked="checked">' +        ); +        // HACK! We don't know why this is sometimes false on chrome +        _jQuery('input[ng\\:model="test.input"][value="bar"]').prop('checked', true); +        expect(_jQuery('input[ng\\:model="test.input"][value="bar"]'). +          prop('checked')).toBe(true); +        expect(_jQuery('input[ng\\:model="test.input"][value="foo"]'). +          prop('checked')).toBe(false); +        var chain = $root.dsl.input('test.input'); +        chain.select('foo'); +        expect(_jQuery('input[ng\\:model="test.input"][value="bar"]'). +          prop('checked')).toBe(false); +        expect(_jQuery('input[ng\\:model="test.input"][value="foo"]'). +          prop('checked')).toBe(true); +      }); + +      it('should return error if radio button did not match', function() { +        var chain = $root.dsl.input('test.input'); +        chain.select('foo'); +        expect($root.futureError).toMatch(/did not match/); +      }); + +      describe('val', function() { +        it('should return value in text input', function() { +          doc.append('<input ng-model="test.input" value="something">'); +          $root.dsl.input('test.input').val(); +          expect($root.futureResult).toEqual("something"); +        }); +      }); +    }); + +    describe('Textarea', function() { + +      it('should change value in textarea', function() { +        doc.append('<textarea ng-model="test.textarea">something</textarea>'); +        var chain = $root.dsl.input('test.textarea'); +        chain.enter('foo'); +        expect(_jQuery('textarea[ng-model="test.textarea"]').val()).toEqual('foo'); +      }); + +      it('should return error if no textarea exists', function() { +        var chain = $root.dsl.input('test.textarea'); +        chain.enter('foo'); +        expect($root.futureError).toMatch(/did not match/); +      }); +    }); +  }); +});  | 
