diff options
| author | Misko Hevery | 2010-04-21 12:50:05 -0700 | 
|---|---|---|
| committer | Misko Hevery | 2010-04-21 12:50:05 -0700 | 
| commit | e78405f6ed82fcd2e9a1cdffb7f1103d52752623 (patch) | |
| tree | 1854bda08d6aa5e3c9e62056388eb7b83236f02b | |
| parent | 22d93e0a3bc2a6dc0f64c63c68bc8f8489ea9068 (diff) | |
| download | angular.js-e78405f6ed82fcd2e9a1cdffb7f1103d52752623.tar.bz2 | |
more if tests pass
| -rw-r--r-- | lib/nodeserver/server.js | 1 | ||||
| -rw-r--r-- | src/Angular.js | 15 | ||||
| -rw-r--r-- | src/directives.js | 2 | ||||
| -rw-r--r-- | src/jqLite.js | 15 | ||||
| -rw-r--r-- | src/widgets.js | 19 | ||||
| -rw-r--r-- | test/FiltersTest.js | 6 | ||||
| -rw-r--r-- | test/ValidatorsTest.js | 2 | ||||
| -rw-r--r-- | test/directivesSpec.js | 38 | ||||
| -rw-r--r-- | test/markupSpec.js | 7 | ||||
| -rw-r--r-- | test/testabilityPatch.js | 10 | ||||
| -rw-r--r-- | test/widgetsSpec.js | 447 | 
11 files changed, 298 insertions, 264 deletions
| diff --git a/lib/nodeserver/server.js b/lib/nodeserver/server.js index 306eeb7c..13eb2826 100644 --- a/lib/nodeserver/server.js +++ b/lib/nodeserver/server.js @@ -1,6 +1,7 @@  var sys = require('sys'),      http = require('http'),      fs = require('fs'); +  http.createServer(function (req, res) {    res.writeHead(200, {});    sys.p('GET ' + req.url); diff --git a/src/Angular.js b/src/Angular.js index 613aee67..11ac7c1c 100644 --- a/src/Angular.js +++ b/src/Angular.js @@ -27,7 +27,8 @@ var consoleNode,      angularFilter     = extensionMap(angular, 'filter'),      angularFormatter  = extensionMap(angular, 'formatter'),      angularService    = extensionMap(angular, 'service'), -    angularCallbacks  = extensionMap(angular, 'callbacks'); +    angularCallbacks  = extensionMap(angular, 'callbacks'), +    nodeName;  function angularAlert(){    log(arguments); window.alert.apply(window, arguments); @@ -110,13 +111,23 @@ function isTextNode(node) { return nodeName(node) == '#text'; }  function lowercase(value){ return isString(value) ? value.toLowerCase() : value; }  function uppercase(value){ return isString(value) ? value.toUpperCase() : value; }  function trim(value) { return isString(value) ? value.replace(/^\s*/, '').replace(/\s*$/, '') : value; } -function nodeName(element) { return (element[0] || element).nodeName; }  function isElement(node) {    if (node && !node.item && isDefined(node.length) && isDefined(node[0]))      node = node[0];    return node && node.nodeName;  } +if (msie) { +  nodeName = function(element) { +    element = element[0] || element; +    return (element.scopeName && element.scopeName != 'HTML' ) ? uppercase(element.scopeName + ':' + element.nodeName) : element.nodeName; +  }; +} else { +  nodeName = function(element) { +    return (element[0] || element).nodeName; +  }; +} +  function isVisible(element) {    var rect = element[0].getBoundingClientRect(),        width = (rect.width || (rect.right||0 - rect.left||0)), diff --git a/src/directives.js b/src/directives.js index 2f393b5d..bdcdcc1d 100644 --- a/src/directives.js +++ b/src/directives.js @@ -109,7 +109,7 @@ angularDirective("ng-bind-attr", function(expression){          var value = compileBindTemplate(bindExp).call(this, element);          if (REMOVE_ATTRIBUTES[lowercase(key)]) {            if (!toBoolean(value)) { -            element.removeAttr('disabled'); +            element.removeAttr(key);            } else {              element.attr(key, value);            } diff --git a/src/jqLite.js b/src/jqLite.js index 1bf6e083..0867f9c9 100644 --- a/src/jqLite.js +++ b/src/jqLite.js @@ -185,7 +185,9 @@ JQLite.prototype = {      } else if (isDefined(value)) {        e.setAttribute(name, value);      } else { -      return e.getAttribute ? e.getAttribute(name) : undefined; +      var attributes = e.attributes, +          item = attributes ? attributes.getNamedItem(name) : undefined; +      return item ? item.value : undefined;      }    }, @@ -205,8 +207,11 @@ JQLite.prototype = {    html: function(value) {      if (isDefined(value)) { -      for ( var i = 0, children = this[0].childNodes; i < children.length; i++) { -        jqLite(children[i]).dealoc(); +      var parent = this[0], child; +      while(parent.childNodes.length) { +        child = parent.childNodes[0]; +        jqLite(child).dealoc(); +        parent.removeChild(child);        }        this[0].innerHTML = value;      } @@ -229,6 +234,10 @@ if (msie) {      },      trigger: function(type) { + +      if (nodeName(this) == 'INPUT' && (lowercase(this.attr('type')) == 'radio' || lowercase(this.attr('type')) == 'checkbox')) { +        this[0].checked = ! this[0].checked; +      }        this[0].fireEvent('on' + type);      }    }); diff --git a/src/widgets.js b/src/widgets.js index b296c354..2c084e29 100644 --- a/src/widgets.js +++ b/src/widgets.js @@ -211,24 +211,25 @@ angularWidget('NG:INCLUDE', function(element){    }  }); -angularWidget('NG:SWITCH', function ngSwitch(element){ +var ngSwitch = angularWidget('NG:SWITCH', function (element){    var compiler = this,        watchExpr = element.attr("on"), -      whenExpr = (element.attr("using") || 'equals').split(":"), -      whenFn = ngSwitch[whenExpr.shift()], +      usingExpr = (element.attr("using") || 'equals'), +      usingExprParams = usingExpr.split(":"); +      usingFn = ngSwitch[usingExprParams.shift()],        changeExpr = element.attr('change') || '',        cases = []; -  if (!whenFn) throw "Using expression '" + usingExpr + "' unknown."; +  if (!usingFn) throw "Using expression '" + usingExpr + "' unknown.";    eachNode(element, function(caseElement){      var when = caseElement.attr('ng-switch-when');      if (when) {        cases.push({          when: function(scope, value){            var args = [value, when]; -          foreach(whenExpr, function(arg){ +          foreach(usingExprParams, function(arg){              args.push(arg);            }); -          return whenFn.apply(scope, args); +          return usingFn.apply(scope, args);          },          change: changeExpr,          element: caseElement, @@ -236,6 +237,7 @@ angularWidget('NG:SWITCH', function ngSwitch(element){        });      }    }); +    element.html('');    return function(element){      var scope = this, childScope; @@ -244,9 +246,10 @@ angularWidget('NG:SWITCH', function ngSwitch(element){        childScope = createScope(scope);        foreach(cases, function(switchCase){          if (switchCase.when(childScope, value)) { -          element.append(switchCase.element); +          var caseElement = switchCase.element.clone(); +          element.append(caseElement);            childScope.$tryEval(switchCase.change, element); -          switchCase.template(switchCase.element, childScope); +          switchCase.template(caseElement, childScope);            if (scope.$invalidWidgets)              scope.$invalidWidgets.clearOrphans();            childScope.$init(); diff --git a/test/FiltersTest.js b/test/FiltersTest.js index ad38b94d..0fd80056 100644 --- a/test/FiltersTest.js +++ b/test/FiltersTest.js @@ -135,7 +135,7 @@ FiltersTest.prototype.testGoogleChartApiEncode = function() {  FiltersTest.prototype.testHtml = function() {    var div = jqLite('<div></div>');    div.append(angular.filter.html("a<b>c</b>d")); -  assertEquals("a<b>c</b>d", div.html()); +  assertEquals("a<b>c</b>d", lowercase(div.html()));  };  FiltersTest.prototype.testLinky = function() { @@ -143,9 +143,9 @@ FiltersTest.prototype.testLinky = function() {    assertEquals(        '<a href="http://ab">http://ab</a> ' +        '(<a href="http://a">http://a</a>) ' + -      '<<a href="http://a">http://a</a>> \n ' + +      '<<a href="http://a">http://a</a>> ' +        '<a href="http://1.2/v:~-123">http://1.2/v:~-123</a>. c', -      sortedHtml(linky("http://ab (http://a) <http://a> \n http://1.2/v:~-123. c"))); +      sortedHtml(linky("http://ab (http://a) <http://a> http://1.2/v:~-123. c")));    assertEquals(undefined, linky(undefined));  }; diff --git a/test/ValidatorsTest.js b/test/ValidatorsTest.js index b2403eab..573c340d 100644 --- a/test/ValidatorsTest.js +++ b/test/ValidatorsTest.js @@ -12,7 +12,7 @@ ValidatorTest.prototype.testItShouldHaveThisSet = function() {    scope.$init();    assertEquals('misko', validator.first);    assertEquals('hevery', validator.last); -  assertSame(scope, validator._this.__proto__); +  expect(validator._this.$id).toEqual(scope.$id);    delete angular.validator.myValidator;    scope.$element.remove();  }; diff --git a/test/directivesSpec.js b/test/directivesSpec.js index f7024bdb..d012fdd0 100644 --- a/test/directivesSpec.js +++ b/test/directivesSpec.js @@ -41,7 +41,7 @@ describe("directives", function(){      var scope = compile('<div ng-bind="html|html"></div>');      scope.html = '<div>hello</div>';      scope.$eval(); -    expect(element.html()).toEqual('<div>hello</div>'); +    expect(lowercase(element.html())).toEqual('<div>hello</div>');    });    it('should ng-bind-template', function() { @@ -58,7 +58,7 @@ describe("directives", function(){    });    it('should remove special attributes on false', function(){ -    var scope = compile('<div disabled="{{disabled}}"  readonly="{{readonly}}" checked="{{checked}}"/>'); +    var scope = compile('<div ng-bind-attr="{disabled:\'{{disabled}}\', readonly:\'{{readonly}}\', checked:\'{{checked}}\'}"/>');      expect(scope.$element.attr('disabled')).toEqual(null);      expect(scope.$element.attr('readonly')).toEqual(null);      expect(scope.$element.attr('checked')).toEqual(null); @@ -180,22 +180,24 @@ describe("directives", function(){      expect(isCssVisible(scope.$element)).toEqual(true);    }); -  it('should ng-controller', function(){ -    window.Greeter = function(){ -      this.greeting = 'hello'; -    }; -    window.Greeter.prototype = { -      init: function(){ -       this.suffix = '!'; -      }, -      greet: function(name) { -        return this.greeting + ' ' + name + this.suffix; -      } -    }; -    var scope = compile('<div ng-controller="Greeter"></div>'); -    expect(scope.greeting).toEqual('hello'); -    expect(scope.greet('misko')).toEqual('hello misko!'); -    delete window.Greeter; +  describe('ng-controller', function(){ +    it('should bind', function(){ +      window.Greeter = function(){ +        this.greeting = 'hello'; +      }; +      window.Greeter.prototype = { +        init: function(){ +          this.suffix = '!'; +        }, +        greet: function(name) { +          return this.greeting + ' ' + name + this.suffix; +        } +      }; +      var scope = compile('<div ng-controller="Greeter"></div>'); +      expect(scope.greeting).toEqual('hello'); +      expect(scope.greet('misko')).toEqual('hello misko!'); +      window.Greeter = undefined; +    });    });    it('should eval things according to ng-eval-order', function(){ diff --git a/test/markupSpec.js b/test/markupSpec.js index a1112490..cfc0f899 100644 --- a/test/markupSpec.js +++ b/test/markupSpec.js @@ -43,13 +43,14 @@ describe("markups", function(){    });    it('should populate value attribute on OPTION', function(){ -    compile('<select name="x"><option>A</option></select>'); -    expect(element.html()).toEqual('<option value="A">A</option>'); +    compile('<select name="x"><option>a</option></select>'); +    expect(sortedHtml(element)).toEqual('<select name="x"><option value="a">a</option></select>');    });    it('should process all bindings when we have leading space', function(){      compile('<a> {{a}}<br/>{{b}}</a>'); -    expect(sortedHtml(scope.$element)).toEqual('<a> <span ng-bind="a"></span><br></br><span ng-bind="b"></span></a>'); +    var space = msie ? '<span>' + NBSP + '</span>': ' '; +    expect(sortedHtml(scope.$element)).toEqual('<a>' + space + '<span ng-bind="a"></span><br></br><span ng-bind="b"></span></a>');    });  }); diff --git a/test/testabilityPatch.js b/test/testabilityPatch.js index 17341575..a2d67923 100644 --- a/test/testabilityPatch.js +++ b/test/testabilityPatch.js @@ -1,6 +1,8 @@  jstd = jstestdriver;  dump = bind(jstd.console, jstd.console.log); +var NBSP = jqLite(' ').text(); +  function nakedExpect(obj) {    return expect(angular.fromJson(angular.toJson(obj)));  } @@ -46,6 +48,7 @@ function sortedHtml(element) {              attr.value !='inherit' &&              attr.value !='0' &&              attr.name !='loop' && +            attr.name !='complete' &&              attr.name !='maxLength' &&              attr.name !='size' &&              attr.name !='start' && @@ -53,7 +56,8 @@ function sortedHtml(element) {              attr.name !='style' &&              attr.name.substr(0, 6) != 'jQuery') {            // in IE we need to check for all of these. -          attrs.push(' ' + attr.name + '="' + attr.value + '"'); +          if (!/ng-\d+/.exec(attr.name)) +            attrs.push(' ' + attr.name + '="' + attr.value + '"');          }        }        attrs.sort(); @@ -64,14 +68,14 @@ function sortedHtml(element) {            foreach(node.style.cssText.split(';'), function(value){              value = trim(value);              if (value) { -              style.push(value); +              style.push(lowercase(value));              }            });          }          for(var css in node.style){            var value = node.style[css];            if (isString(value) && isString(css) && css != 'cssText' && value && (1*css != css)) { -            var text = css + ': ' + value; +            var text = lowercase(css + ': ' + value);              if (value != 'false' && indexOf(style, text) == -1) {                style.push(text);              } diff --git a/test/widgetsSpec.js b/test/widgetsSpec.js index 2cfe216c..c6c57557 100644 --- a/test/widgetsSpec.js +++ b/test/widgetsSpec.js @@ -1,5 +1,4 @@ -describe("input widget", function(){ - +describe("widget", function(){    var compile, element, scope;    beforeEach(function() { @@ -19,265 +18,269 @@ describe("input widget", function(){      expect(size(jqCache)).toEqual(0);    }); -  it('should input-text auto init and handle keyup/change events', function(){ -    compile('<input type="Text" name="name" value="Misko" ng-change="count = count + 1" ng-init="count=0"/>'); -    expect(scope.$get('name')).toEqual("Misko"); -    expect(scope.$get('count')).toEqual(0); +  describe("input", function(){ -    scope.$set('name', 'Adam'); -    scope.$eval(); -    expect(element.val()).toEqual("Adam"); +    it('should input-text auto init and handle keyup/change events', function(){ +      compile('<input type="Text" name="name" value="Misko" ng-change="count = count + 1" ng-init="count=0"/>'); +      expect(scope.$get('name')).toEqual("Misko"); +      expect(scope.$get('count')).toEqual(0); -    element.val('Shyam'); -    element.trigger('keyup'); -    expect(scope.$get('name')).toEqual('Shyam'); -    expect(scope.$get('count')).toEqual(1); +      scope.$set('name', 'Adam'); +      scope.$eval(); +      expect(element.val()).toEqual("Adam"); -    element.val('Kai'); -    element.trigger('change'); -    expect(scope.$get('name')).toEqual('Kai'); -    expect(scope.$get('count')).toEqual(2); -  }); +      element.val('Shyam'); +      element.trigger('keyup'); +      expect(scope.$get('name')).toEqual('Shyam'); +      expect(scope.$get('count')).toEqual(1); -  it("should process ng-format", function(){ -    compile('<input type="Text" name="list" value="a,b,c" ng-format="list"/>'); -    expect(scope.$get('list')).toEqual(['a', 'b', 'c']); +      element.val('Kai'); +      element.trigger('change'); +      expect(scope.$get('name')).toEqual('Kai'); +      expect(scope.$get('count')).toEqual(2); +    }); -    scope.$set('list', ['x', 'y', 'z']); -    scope.$eval(); -    expect(element.val()).toEqual("x, y, z"); +    it("should process ng-format", function(){ +      compile('<input type="Text" name="list" value="a,b,c" ng-format="list"/>'); +      expect(scope.$get('list')).toEqual(['a', 'b', 'c']); -    element.val('1, 2, 3'); -    element.trigger('keyup'); -    expect(scope.$get('list')).toEqual(['1', '2', '3']); -  }); +      scope.$set('list', ['x', 'y', 'z']); +      scope.$eval(); +      expect(element.val()).toEqual("x, y, z"); -  it("should process ng-format for booleans", function(){ -    compile('<input type="checkbox" name="name" value="true" ng-format="boolean"/>', function(){ -      scope.name = false; +      element.val('1, 2, 3'); +      element.trigger('keyup'); +      expect(scope.$get('list')).toEqual(['1', '2', '3']);      }); -    expect(scope.name).toEqual(false); -    expect(scope.$element[0].checked).toEqual(false); -  }); -  it("should process ng-validate", function(){ -    compile('<input type="text" name="price" value="abc" ng-validate="number"/>'); -    expect(element.hasClass('ng-validation-error')).toBeTruthy(); -    expect(element.attr('ng-validation-error')).toEqual('Not a number'); +    it("should process ng-format for booleans", function(){ +      compile('<input type="checkbox" name="name" value="true" ng-format="boolean"/>', function(){ +        scope.name = false; +      }); +      expect(scope.name).toEqual(false); +      expect(scope.$element[0].checked).toEqual(false); +    }); -    scope.$set('price', '123'); -    scope.$eval(); -    expect(element.hasClass('ng-validation-error')).toBeFalsy(); -    expect(element.attr('ng-validation-error')).toBeFalsy(); +    it("should process ng-validate", function(){ +      compile('<input type="text" name="price" value="abc" ng-validate="number"/>'); +      expect(element.hasClass('ng-validation-error')).toBeTruthy(); +      expect(element.attr('ng-validation-error')).toEqual('Not a number'); -    element.val('x'); -    element.trigger('keyup'); -    expect(element.hasClass('ng-validation-error')).toBeTruthy(); -    expect(element.attr('ng-validation-error')).toEqual('Not a number'); -  }); +      scope.$set('price', '123'); +      scope.$eval(); +      expect(element.hasClass('ng-validation-error')).toBeFalsy(); +      expect(element.attr('ng-validation-error')).toBeFalsy(); -  it("should not call validator if undefinde/empty", function(){ -    var lastValue = "NOT_CALLED"; -    angularValidator.myValidator = function(value){lastValue = value;}; -    compile('<input type="text" name="url" ng-validate="myValidator"/>'); -    expect(lastValue).toEqual("NOT_CALLED"); +      element.val('x'); +      element.trigger('keyup'); +      expect(element.hasClass('ng-validation-error')).toBeTruthy(); +      expect(element.attr('ng-validation-error')).toEqual('Not a number'); +    }); -    scope.url = 'http://server'; -    scope.$eval(); -    expect(lastValue).toEqual("http://server"); +    it("should not call validator if undefinde/empty", function(){ +      var lastValue = "NOT_CALLED"; +      angularValidator.myValidator = function(value){lastValue = value;}; +      compile('<input type="text" name="url" ng-validate="myValidator"/>'); +      expect(lastValue).toEqual("NOT_CALLED"); -    delete angularValidator.myValidator; -  }); +      scope.url = 'http://server'; +      scope.$eval(); +      expect(lastValue).toEqual("http://server"); -  it("should ignore disabled widgets", function(){ -    compile('<input type="text" name="price" ng-required disabled/>'); -    expect(element.hasClass('ng-validation-error')).toBeFalsy(); -    expect(element.attr('ng-validation-error')).toBeFalsy(); -  }); +      delete angularValidator.myValidator; +    }); -  it("should ignore readonly widgets", function(){ -    compile('<input type="text" name="price" ng-required readonly/>'); -    expect(element.hasClass('ng-validation-error')).toBeFalsy(); -    expect(element.attr('ng-validation-error')).toBeFalsy(); -  }); +    it("should ignore disabled widgets", function(){ +      compile('<input type="text" name="price" ng-required disabled/>'); +      expect(element.hasClass('ng-validation-error')).toBeFalsy(); +      expect(element.attr('ng-validation-error')).toBeFalsy(); +    }); -  it("should process ng-required", function(){ -    compile('<input type="text" name="price" ng-required/>'); -    expect(element.hasClass('ng-validation-error')).toBeTruthy(); -    expect(element.attr('ng-validation-error')).toEqual('Required'); +    it("should ignore readonly widgets", function(){ +      compile('<input type="text" name="price" ng-required readonly/>'); +      expect(element.hasClass('ng-validation-error')).toBeFalsy(); +      expect(element.attr('ng-validation-error')).toBeFalsy(); +    }); -    scope.$set('price', 'xxx'); -    scope.$eval(); -    expect(element.hasClass('ng-validation-error')).toBeFalsy(); -    expect(element.attr('ng-validation-error')).toBeFalsy(); +    it("should process ng-required", function(){ +      compile('<input type="text" name="price" ng-required/>'); +      expect(element.hasClass('ng-validation-error')).toBeTruthy(); +      expect(element.attr('ng-validation-error')).toEqual('Required'); -    element.val(''); -    element.trigger('keyup'); -    expect(element.hasClass('ng-validation-error')).toBeTruthy(); -    expect(element.attr('ng-validation-error')).toEqual('Required'); -  }); +      scope.$set('price', 'xxx'); +      scope.$eval(); +      expect(element.hasClass('ng-validation-error')).toBeFalsy(); +      expect(element.attr('ng-validation-error')).toBeFalsy(); -  it("should process ng-required2", function() { -    compile('<textarea name="name">Misko</textarea>'); -    expect(scope.$get('name')).toEqual("Misko"); +      element.val(''); +      element.trigger('keyup'); +      expect(element.hasClass('ng-validation-error')).toBeTruthy(); +      expect(element.attr('ng-validation-error')).toEqual('Required'); +    }); -    scope.$set('name', 'Adam'); -    scope.$eval(); -    expect(element.val()).toEqual("Adam"); +    it("should process ng-required2", function() { +      compile('<textarea name="name">Misko</textarea>'); +      expect(scope.$get('name')).toEqual("Misko"); -    element.val('Shyam'); -    element.trigger('keyup'); -    expect(scope.$get('name')).toEqual('Shyam'); +      scope.$set('name', 'Adam'); +      scope.$eval(); +      expect(element.val()).toEqual("Adam"); -    element.val('Kai'); -    element.trigger('change'); -    expect(scope.$get('name')).toEqual('Kai'); -  }); +      element.val('Shyam'); +      element.trigger('keyup'); +      expect(scope.$get('name')).toEqual('Shyam'); -  it('should call ng-change on button click', function(){ -    compile('<input type="button" value="Click Me" ng-change="clicked = true"/>'); -    element.trigger('click'); -    expect(scope.$get('clicked')).toEqual(true); -  }); +      element.val('Kai'); +      element.trigger('change'); +      expect(scope.$get('name')).toEqual('Kai'); +    }); -  it('should support button alias', function(){ -    compile('<button ng-change="clicked = true">Click Me</button>'); -    element.trigger('click'); -    expect(scope.$get('clicked')).toEqual(true); -  }); +    it('should call ng-change on button click', function(){ +      compile('<input type="button" value="Click Me" ng-change="clicked = true"/>'); +      element.trigger('click'); +      expect(scope.$get('clicked')).toEqual(true); +    }); -  it('should type="checkbox"', function(){ -    compile('<input type="checkbox" name="checkbox" checked ng-change="action = true"/>'); -    expect(scope.checkbox).toEqual(true); -    element.trigger('click'); -    expect(scope.checkbox).toEqual(false); -    expect(scope.action).toEqual(true); -    element.trigger('click'); -    expect(scope.checkbox).toEqual(true); -  }); +    it('should support button alias', function(){ +      compile('<button ng-change="clicked = true">Click Me</button>'); +      element.trigger('click'); +      expect(scope.$get('clicked')).toEqual(true); +    }); -  it('should type="radio"', function(){ -    compile('<div>' + -        '<input type="radio" name="chose" value="A" ng-change="clicked = 1"/>' + -        '<input type="radio" name="chose" value="B" checked ng-change="clicked = 2"/>' + -        '<input type="radio" name="chose" value="C" ng-change="clicked = 3"/>' + -      '</div>'); -    var a = element[0].childNodes[0]; -    var b = element[0].childNodes[1]; -    expect(b.name.split('@')[1]).toEqual('chose'); -    expect(scope.chose).toEqual('B'); -    scope.chose = 'A'; -    scope.$eval(); -    expect(a.checked).toEqual(true); - -    scope.chose = 'B'; -    scope.$eval(); -    expect(a.checked).toEqual(false); -    expect(b.checked).toEqual(true); -    expect(scope.clicked).not.toBeDefined(); - -    jqLite(a).trigger('click'); -    expect(scope.chose).toEqual('A'); -    expect(scope.clicked).toEqual(1); -  }); +    it('should support type="checkbox"', function(){ +      compile('<input type="checkBox" name="checkbox" checked ng-change="action = true"/>'); +      expect(scope.checkbox).toEqual(true); +      element.trigger('click'); +      expect(scope.checkbox).toEqual(false); +      expect(scope.action).toEqual(true); +      element.trigger('click'); +      expect(scope.checkbox).toEqual(true); +    }); -  it('should type="select-one"', function(){ -    compile( -      '<select name="selection">' + -        '<option>A</option>' + -        '<option selected>B</option>' + -      '</select>'); -    expect(scope.selection).toEqual('B'); -    scope.selection = 'A'; -    scope.$eval(); -    expect(scope.selection).toEqual('A'); -    expect(element[0].childNodes[0].selected).toEqual(true); -  }); +    it('should support type="radio"', function(){ +      compile('<div>' + +          '<input type="radio" name="chose" value="A" ng-change="clicked = 1"/>' + +          '<input type="raDio" name="chose" value="B" checked ng-change="clicked = 2"/>' + +          '<input type="radio" name="chose" value="C" ng-change="clicked = 3"/>' + +        '</div>'); +      var a = element[0].childNodes[0]; +      var b = element[0].childNodes[1]; +      expect(b.name.split('@')[1]).toEqual('chose'); +      expect(scope.chose).toEqual('B'); +      scope.chose = 'A'; +      scope.$eval(); +      expect(a.checked).toEqual(true); + +      scope.chose = 'B'; +      scope.$eval(); +      expect(a.checked).toEqual(false); +      expect(b.checked).toEqual(true); +      expect(scope.clicked).not.toBeDefined(); + +      jqLite(a).trigger('click'); +      expect(scope.chose).toEqual('A'); +      expect(scope.clicked).toEqual(1); +    }); -  it('should type="select-multiple"', function(){ -    compile( -      '<select name="selection" multiple>' + -        '<option>A</option>' + -        '<option selected>B</option>' + -      '</select>'); -    expect(scope.selection).toEqual(['B']); -    scope.selection = ['A']; -    scope.$eval(); -    expect(element[0].childNodes[0].selected).toEqual(true); -  }); +    it('should support type="select-one"', function(){ +      compile( +        '<select name="selection">' + +          '<option>A</option>' + +          '<option selected>B</option>' + +        '</select>'); +      expect(scope.selection).toEqual('B'); +      scope.selection = 'A'; +      scope.$eval(); +      expect(scope.selection).toEqual('A'); +      expect(element[0].childNodes[0].selected).toEqual(true); +    }); -  it('should report error on missing field', function(){ -    compile('<input type="text"/>'); -    expect(element.hasClass('ng-exception')).toBeTruthy(); -  }); +    it('should support type="select-multiple"', function(){ +      compile( +        '<select name="selection" multiple>' + +          '<option>A</option>' + +          '<option selected>B</option>' + +        '</select>'); +      expect(scope.selection).toEqual(['B']); +      scope.selection = ['A']; +      scope.$eval(); +      expect(element[0].childNodes[0].selected).toEqual(true); +    }); -  it('should report error on assignment error', function(){ -    compile('<input type="text" name="throw \'\'" value="x"/>'); -    expect(element.hasClass('ng-exception')).toBeTruthy(); -  }); +    it('should report error on missing field', function(){ +      compile('<input type="text"/>'); +      expect(element.hasClass('ng-exception')).toBeTruthy(); +    }); -  it('should report error on ng-change exception', function(){ -    compile('<button ng-change="a-2=x">click</button>'); -    element.trigger('click'); -    expect(element.hasClass('ng-exception')).toBeTruthy(); -  }); +    it('should report error on assignment error', function(){ +      compile('<input type="text" name="throw \'\'" value="x"/>'); +      expect(element.hasClass('ng-exception')).toBeTruthy(); +    }); -  it('should switch on value change', function(){ -    compile('<ng:switch on="select"><div ng-switch-when="1">first:{{name}}</div><div ng-switch-when="2">second:{{name}}</div></ng:switch>'); -    expect(element.html()).toEqual(''); -    scope.select = 1; -    scope.$eval(); -    expect(element.text()).toEqual('first:'); -    scope.name="shyam"; -    scope.$eval(); -    expect(element.text()).toEqual('first:shyam'); -    scope.select = 2; -    scope.$eval(); -    scope.name = 'misko'; -    scope.$eval(); -    expect(element.text()).toEqual('second:misko'); +    it('should report error on ng-change exception', function(){ +      compile('<button ng-change="a-2=x">click</button>'); +      element.trigger('click'); +      expect(element.hasClass('ng-exception')).toBeTruthy(); +    });    }); -}); -describe('ng:switch', function(){ -  it("should match urls", function(){ -    var scope = compile('<ng:switch on="url" using="route:params"><div ng-switch-when="/Book/:name">{{params.name}}</div></ng:include>'); -    scope.url = '/Book/Moby'; -    scope.$init(); -    expect(scope.$element.text()).toEqual('Moby'); -  }); +  describe('ng:switch', function(){ +    it('should switch on value change', function(){ +      compile('<ng:switch on="select"><div ng-switch-when="1">first:{{name}}</div><div ng-switch-when="2">second:{{name}}</div></ng:switch>'); +      expect(element.html()).toEqual(''); +      scope.select = 1; +      scope.$eval(); +      expect(element.text()).toEqual('first:'); +      scope.name="shyam"; +      scope.$eval(); +      expect(element.text()).toEqual('first:shyam'); +      scope.select = 2; +      scope.$eval(); +      expect(element.text()).toEqual('second:shyam'); +      scope.name = 'misko'; +      scope.$eval(); +      expect(element.text()).toEqual('second:misko'); +    }); -  it("should match sandwich ids", function(){ -    var scope = {}; -    var match = angular.widget['NG:SWITCH'].route.call(scope, '/a/123/b', '/a/:id'); -    expect(match).toBeFalsy(); -  }); +    it("should match urls", function(){ +      var scope = angular.compile('<ng:switch on="url" using="route:params"><div ng-switch-when="/Book/:name">{{params.name}}</div></ng:include>'); +      scope.url = '/Book/Moby'; +      scope.$init(); +      expect(scope.$element.text()).toEqual('Moby'); +    }); + +    it("should match sandwich ids", function(){ +      var scope = {}; +      var match = angular.widget['NG:SWITCH'].route.call(scope, '/a/123/b', '/a/:id'); +      expect(match).toBeFalsy(); +    }); -  it('should call init on switch', function(){ -    var scope = compile('<ng:switch on="url" change="name=\'works\'"><div ng-switch-when="a">{{name}}</div></ng:include>'); -    var cleared = false; -    scope.url = 'a'; -    scope.$invalidWidgets = {clearOrphans: function(){ -      cleared = true; -    }}; -    scope.$init(); -    expect(scope.name).toEqual(undefined); -    expect(scope.$element.text()).toEqual('works'); -    expect(cleared).toEqual(true); +    it('should call init on switch', function(){ +      var scope = angular.compile('<ng:switch on="url" change="name=\'works\'"><div ng-switch-when="a">{{name}}</div></ng:include>'); +      var cleared = false; +      scope.url = 'a'; +      scope.$invalidWidgets = {clearOrphans: function(){ +        cleared = true; +      }}; +      scope.$init(); +      expect(scope.name).toEqual(undefined); +      expect(scope.$element.text()).toEqual('works'); +      expect(cleared).toEqual(true); +    });    }); -}); -describe('ng:include', function(){ -  it('should include on external file', function() { -    var element = jqLite('<ng:include src="url" scope="childScope"></ng:include>'); -    var scope = compile(element); -    scope.childScope = createScope(); -    scope.childScope.name = 'misko'; -    scope.url = 'myUrl'; -    scope.$browser.xhr.expect('GET', 'myUrl').respond('{{name}}'); -    scope.$init(); -    scope.$browser.xhr.flush(); -    expect(element.text()).toEqual('misko'); +  describe('ng:include', function(){ +    it('should include on external file', function() { +      var element = jqLite('<ng:include src="url" scope="childScope"></ng:include>'); +      var scope = angular.compile(element); +      scope.childScope = createScope(); +      scope.childScope.name = 'misko'; +      scope.url = 'myUrl'; +      scope.$browser.xhr.expect('GET', 'myUrl').respond('{{name}}'); +      scope.$init(); +      scope.$browser.xhr.flush(); +      expect(element.text()).toEqual('misko'); +    });    });  }); | 
