diff --git a/src/ng/directive/ngModelOptions.js b/src/ng/directive/ngModelOptions.js
index 91b138a241ee..59c63b812789 100644
--- a/src/ng/directive/ngModelOptions.js
+++ b/src/ng/directive/ngModelOptions.js
@@ -331,19 +331,27 @@ defaultModelOptions = new ModelOptions({
*
*/
var ngModelOptionsDirective = function() {
+ NgModelOptionsController.$inject = ['$attrs', '$scope'];
+ function NgModelOptionsController($attrs, $scope) {
+ this.$$attrs = $attrs;
+ this.$$scope = $scope;
+ }
+ NgModelOptionsController.prototype = {
+ $onInit: function() {
+ var parentOptions = this.parentCtrl ? this.parentCtrl.$options : defaultModelOptions;
+ var modelOptionsDefinition = this.$$scope.$eval(this.$$attrs.ngModelOptions);
+
+ this.$options = parentOptions.createChild(modelOptionsDefinition);
+ }
+ };
+
return {
restrict: 'A',
// ngModelOptions needs to run before ngModel and input directives
priority: 10,
- require: ['ngModelOptions', '?^^ngModelOptions'],
- controller: function NgModelOptionsController() {},
- link: {
- pre: function ngModelOptionsPreLinkFn(scope, element, attrs, ctrls) {
- var optionsCtrl = ctrls[0];
- var parentOptions = ctrls[1] ? ctrls[1].$options : defaultModelOptions;
- optionsCtrl.$options = parentOptions.createChild(scope.$eval(attrs.ngModelOptions));
- }
- }
+ require: {parentCtrl: '?^^ngModelOptions'},
+ bindToController: true,
+ controller: NgModelOptionsController
};
};
diff --git a/test/helpers/testabilityPatch.js b/test/helpers/testabilityPatch.js
index d589ac2c67df..91fd5661d516 100644
--- a/test/helpers/testabilityPatch.js
+++ b/test/helpers/testabilityPatch.js
@@ -391,8 +391,7 @@ function generateInputCompilerHelper(helper) {
};
helper.changeInputValueTo = function(value) {
- helper.inputElm.val(value);
- browserTrigger(helper.inputElm, $sniffer.hasEvent('input') ? 'input' : 'change');
+ helper.changeGivenInputTo(helper.inputElm, value);
};
helper.changeGivenInputTo = function(inputElm, value) {
diff --git a/test/ng/directive/ngModelOptionsSpec.js b/test/ng/directive/ngModelOptionsSpec.js
index ad5d0f7e7cfb..62ff8779f3b2 100644
--- a/test/ng/directive/ngModelOptionsSpec.js
+++ b/test/ng/directive/ngModelOptionsSpec.js
@@ -19,817 +19,846 @@ describe('ngModelOptions', function() {
describe('directive', function() {
- var helper = {}, $rootScope, $compile, $timeout, $q;
-
- generateInputCompilerHelper(helper);
-
- beforeEach(inject(function(_$compile_, _$rootScope_, _$timeout_, _$q_) {
- $compile = _$compile_;
- $rootScope = _$rootScope_;
- $timeout = _$timeout_;
- $q = _$q_;
- }));
-
-
- describe('should fall back to `defaultModelOptions`', function() {
- it('if there is no `ngModelOptions` directive', function() {
- var inputElm = helper.compileInput(
- '');
-
- var inputOptions = $rootScope.form.alias.$options;
- expect(inputOptions.getOption('updateOn')).toEqual(defaultModelOptions.getOption('updateOn'));
- expect(inputOptions.getOption('updateOnDefault')).toEqual(defaultModelOptions.getOption('updateOnDefault'));
- expect(inputOptions.getOption('debounce')).toEqual(defaultModelOptions.getOption('debounce'));
- expect(inputOptions.getOption('getterSetter')).toEqual(defaultModelOptions.getOption('getterSetter'));
- expect(inputOptions.getOption('allowInvalid')).toEqual(defaultModelOptions.getOption('allowInvalid'));
- expect(inputOptions.getOption('timezone')).toEqual(defaultModelOptions.getOption('timezone'));
- });
+ describe('basic usage', function() {
+ var helper = {}, $rootScope, $compile, $timeout, $q;
- it('if `ngModelOptions` on the same element does not specify the option', function() {
- var inputElm = helper.compileInput(
- '');
+ generateInputCompilerHelper(helper);
- var inputOptions = $rootScope.form.alias.$options;
- expect(inputOptions.getOption('debounce')).toEqual(defaultModelOptions.getOption('debounce'));
- expect(inputOptions.getOption('updateOnDefault')).toBe(false);
- expect(inputOptions.getOption('updateOnDefault')).not.toEqual(defaultModelOptions.getOption('updateOnDefault'));
- });
+ beforeEach(inject(function(_$compile_, _$rootScope_, _$timeout_, _$q_) {
+ $compile = _$compile_;
+ $rootScope = _$rootScope_;
+ $timeout = _$timeout_;
+ $q = _$q_;
+ }));
- it('if the first `ngModelOptions` ancestor does not specify the option', function() {
- var form = $compile('
')($rootScope);
- var inputOptions = $rootScope.form.alias.$options;
+ describe('should fall back to `defaultModelOptions`', function() {
+ it('if there is no `ngModelOptions` directive', function() {
+ var inputElm = helper.compileInput(
+ '');
- expect(inputOptions.getOption('debounce')).toEqual(defaultModelOptions.getOption('debounce'));
- expect(inputOptions.getOption('updateOnDefault')).toBe(false);
- expect(inputOptions.getOption('updateOnDefault')).not.toEqual(defaultModelOptions.getOption('updateOnDefault'));
- dealoc(form);
- });
- });
+ var inputOptions = $rootScope.form.alias.$options;
+ expect(inputOptions.getOption('updateOn')).toEqual(defaultModelOptions.getOption('updateOn'));
+ expect(inputOptions.getOption('updateOnDefault')).toEqual(defaultModelOptions.getOption('updateOnDefault'));
+ expect(inputOptions.getOption('debounce')).toEqual(defaultModelOptions.getOption('debounce'));
+ expect(inputOptions.getOption('getterSetter')).toEqual(defaultModelOptions.getOption('getterSetter'));
+ expect(inputOptions.getOption('allowInvalid')).toEqual(defaultModelOptions.getOption('allowInvalid'));
+ expect(inputOptions.getOption('timezone')).toEqual(defaultModelOptions.getOption('timezone'));
+ });
- describe('sharing and inheritance', function() {
+ it('if `ngModelOptions` on the same element does not specify the option', function() {
+ var inputElm = helper.compileInput(
+ '');
- it('should not inherit options from ancestor `ngModelOptions` directives by default', function() {
- var container = $compile(
- '
' +
- '' +
- '
')($rootScope);
+ var inputOptions = $rootScope.form.alias.$options;
+ expect(inputOptions.getOption('debounce')).toEqual(defaultModelOptions.getOption('debounce'));
+ expect(inputOptions.getOption('updateOnDefault')).toBe(false);
+ expect(inputOptions.getOption('updateOnDefault')).not.toEqual(defaultModelOptions.getOption('updateOnDefault'));
+ });
- var form = container.find('form');
- var input = container.find('input');
- var containerOptions = container.controller('ngModelOptions').$options;
- var formOptions = form.controller('ngModelOptions').$options;
- var inputOptions = input.controller('ngModelOptions').$options;
+ it('if the first `ngModelOptions` ancestor does not specify the option', function() {
+ var form = $compile('')($rootScope);
+ var inputOptions = $rootScope.form.alias.$options;
- expect(containerOptions.getOption('allowInvalid')).toEqual(true);
- expect(formOptions.getOption('allowInvalid')).toEqual(false);
- expect(inputOptions.getOption('allowInvalid')).toEqual(false);
+ expect(inputOptions.getOption('debounce')).toEqual(defaultModelOptions.getOption('debounce'));
+ expect(inputOptions.getOption('updateOnDefault')).toBe(false);
+ expect(inputOptions.getOption('updateOnDefault')).not.toEqual(defaultModelOptions.getOption('updateOnDefault'));
+ dealoc(form);
+ });
+ });
- expect(containerOptions.getOption('updateOn')).toEqual('');
- expect(containerOptions.getOption('updateOnDefault')).toEqual(true);
- expect(formOptions.getOption('updateOn')).toEqual('blur');
- expect(formOptions.getOption('updateOnDefault')).toEqual(false);
- expect(inputOptions.getOption('updateOn')).toEqual('');
- expect(inputOptions.getOption('updateOnDefault')).toEqual(true);
- dealoc(container);
- });
+ describe('sharing and inheritance', function() {
- it('should inherit options that are marked with "$inherit" from the nearest ancestor `ngModelOptions` directive', function() {
- var container = $compile(
- '
' +
- '' +
- '
')($rootScope);
-
- var form = container.find('form');
- var input = container.find('input');
-
- var containerOptions = container.controller('ngModelOptions').$options;
- var formOptions = form.controller('ngModelOptions').$options;
- var inputOptions = input.controller('ngModelOptions').$options;
-
- expect(containerOptions.getOption('allowInvalid')).toEqual(true);
- expect(formOptions.getOption('allowInvalid')).toEqual(true);
- expect(inputOptions.getOption('allowInvalid')).toEqual(false);
-
- expect(containerOptions.getOption('updateOn')).toEqual('');
- expect(containerOptions.getOption('updateOnDefault')).toEqual(true);
- expect(formOptions.getOption('updateOn')).toEqual('blur');
- expect(formOptions.getOption('updateOnDefault')).toEqual(false);
- expect(inputOptions.getOption('updateOn')).toEqual('');
- expect(inputOptions.getOption('updateOnDefault')).toEqual(true);
-
- dealoc(container);
- });
+ it('should not inherit options from ancestor `ngModelOptions` directives by default', function() {
+ var container = $compile(
+ '
' +
+ '' +
+ '
')($rootScope);
- it('should inherit all unspecified options if the options object contains a `"*"` property with value "$inherit"', function() {
- var container = $compile(
- '
' +
- '' +
- '
')($rootScope);
-
- var form = container.find('form');
- var input = container.find('input');
-
- var containerOptions = container.controller('ngModelOptions').$options;
- var formOptions = form.controller('ngModelOptions').$options;
- var inputOptions = input.controller('ngModelOptions').$options;
-
- expect(containerOptions.getOption('allowInvalid')).toEqual(true);
- expect(formOptions.getOption('allowInvalid')).toEqual(true);
- expect(inputOptions.getOption('allowInvalid')).toEqual(false);
-
- expect(containerOptions.getOption('debounce')).toEqual(100);
- expect(formOptions.getOption('debounce')).toEqual(100);
- expect(inputOptions.getOption('debounce')).toEqual(0);
-
- expect(containerOptions.getOption('updateOn')).toEqual('keyup');
- expect(containerOptions.getOption('updateOnDefault')).toEqual(false);
- expect(formOptions.getOption('updateOn')).toEqual('blur');
- expect(formOptions.getOption('updateOnDefault')).toEqual(false);
- expect(inputOptions.getOption('updateOn')).toEqual('');
- expect(inputOptions.getOption('updateOnDefault')).toEqual(true);
-
- dealoc(container);
- });
+ var form = container.find('form');
+ var input = container.find('input');
- it('should correctly inherit default and another specified event for `updateOn`', function() {
- var container = $compile(
- '
' +
- '' +
- '
')($rootScope);
+ var containerOptions = container.controller('ngModelOptions').$options;
+ var formOptions = form.controller('ngModelOptions').$options;
+ var inputOptions = input.controller('ngModelOptions').$options;
- var input = container.find('input');
- var inputOptions = input.controller('ngModelOptions').$options;
+ expect(containerOptions.getOption('allowInvalid')).toEqual(true);
+ expect(formOptions.getOption('allowInvalid')).toEqual(false);
+ expect(inputOptions.getOption('allowInvalid')).toEqual(false);
- expect(inputOptions.getOption('updateOn')).toEqual('blur');
- expect(inputOptions.getOption('updateOnDefault')).toEqual(true);
+ expect(containerOptions.getOption('updateOn')).toEqual('');
+ expect(containerOptions.getOption('updateOnDefault')).toEqual(true);
+ expect(formOptions.getOption('updateOn')).toEqual('blur');
+ expect(formOptions.getOption('updateOnDefault')).toEqual(false);
+ expect(inputOptions.getOption('updateOn')).toEqual('');
+ expect(inputOptions.getOption('updateOnDefault')).toEqual(true);
- dealoc(container);
- });
+ dealoc(container);
+ });
+ it('should inherit options that are marked with "$inherit" from the nearest ancestor `ngModelOptions` directive', function() {
+ var container = $compile(
+ '
' +
+ '' +
+ '
')($rootScope);
+
+ var form = container.find('form');
+ var input = container.find('input');
+
+ var containerOptions = container.controller('ngModelOptions').$options;
+ var formOptions = form.controller('ngModelOptions').$options;
+ var inputOptions = input.controller('ngModelOptions').$options;
+
+ expect(containerOptions.getOption('allowInvalid')).toEqual(true);
+ expect(formOptions.getOption('allowInvalid')).toEqual(true);
+ expect(inputOptions.getOption('allowInvalid')).toEqual(false);
+
+ expect(containerOptions.getOption('updateOn')).toEqual('');
+ expect(containerOptions.getOption('updateOnDefault')).toEqual(true);
+ expect(formOptions.getOption('updateOn')).toEqual('blur');
+ expect(formOptions.getOption('updateOnDefault')).toEqual(false);
+ expect(inputOptions.getOption('updateOn')).toEqual('');
+ expect(inputOptions.getOption('updateOnDefault')).toEqual(true);
+
+ dealoc(container);
+ });
- it('should `updateOnDefault` as well if we have `updateOn: "$inherit"`', function() {
- var container = $compile(
- '
' +
- '' +
+ it('should inherit all unspecified options if the options object contains a `"*"` property with value "$inherit"', function() {
+ var container = $compile(
+ '
' +
+ '' +
+ '
')($rootScope);
+
+ var form = container.find('form');
+ var input = container.find('input');
+
+ var containerOptions = container.controller('ngModelOptions').$options;
+ var formOptions = form.controller('ngModelOptions').$options;
+ var inputOptions = input.controller('ngModelOptions').$options;
+
+ expect(containerOptions.getOption('allowInvalid')).toEqual(true);
+ expect(formOptions.getOption('allowInvalid')).toEqual(true);
+ expect(inputOptions.getOption('allowInvalid')).toEqual(false);
+
+ expect(containerOptions.getOption('debounce')).toEqual(100);
+ expect(formOptions.getOption('debounce')).toEqual(100);
+ expect(inputOptions.getOption('debounce')).toEqual(0);
+
+ expect(containerOptions.getOption('updateOn')).toEqual('keyup');
+ expect(containerOptions.getOption('updateOnDefault')).toEqual(false);
+ expect(formOptions.getOption('updateOn')).toEqual('blur');
+ expect(formOptions.getOption('updateOnDefault')).toEqual(false);
+ expect(inputOptions.getOption('updateOn')).toEqual('');
+ expect(inputOptions.getOption('updateOnDefault')).toEqual(true);
+
+ dealoc(container);
+ });
+
+ it('should correctly inherit default and another specified event for `updateOn`', function() {
+ var container = $compile(
'
' +
+ '' +
+ '
')($rootScope);
+
+ var input = container.find('input');
+ var inputOptions = input.controller('ngModelOptions').$options;
+
+ expect(inputOptions.getOption('updateOn')).toEqual('blur');
+ expect(inputOptions.getOption('updateOnDefault')).toEqual(true);
+
+ dealoc(container);
+ });
+
+
+ it('should `updateOnDefault` as well if we have `updateOn: "$inherit"`', function() {
+ var container = $compile(
+ '
' +
'' +
- '
' +
- '
')($rootScope);
+ '
' +
+ '' +
+ '
' +
+ '')($rootScope);
- var input1 = container.find('input').eq(0);
- var inputOptions1 = input1.controller('ngModelOptions').$options;
+ var input1 = container.find('input').eq(0);
+ var inputOptions1 = input1.controller('ngModelOptions').$options;
- expect(inputOptions1.getOption('updateOn')).toEqual('keyup');
- expect(inputOptions1.getOption('updateOnDefault')).toEqual(false);
+ expect(inputOptions1.getOption('updateOn')).toEqual('keyup');
+ expect(inputOptions1.getOption('updateOnDefault')).toEqual(false);
- var input2 = container.find('input').eq(1);
- var inputOptions2 = input2.controller('ngModelOptions').$options;
+ var input2 = container.find('input').eq(1);
+ var inputOptions2 = input2.controller('ngModelOptions').$options;
- expect(inputOptions2.getOption('updateOn')).toEqual('blur');
- expect(inputOptions2.getOption('updateOnDefault')).toEqual(true);
+ expect(inputOptions2.getOption('updateOn')).toEqual('blur');
+ expect(inputOptions2.getOption('updateOnDefault')).toEqual(true);
- dealoc(container);
- });
+ dealoc(container);
+ });
- it('should make a copy of the options object', function() {
- $rootScope.options = {updateOn: 'default'};
- var inputElm = helper.compileInput(
- '');
- expect($rootScope.options).toEqual({updateOn: 'default'});
- expect($rootScope.form.alias.$options).not.toBe($rootScope.options);
- });
+ it('should make a copy of the options object', function() {
+ $rootScope.options = {updateOn: 'default'};
+ var inputElm = helper.compileInput(
+ '');
+ expect($rootScope.options).toEqual({updateOn: 'default'});
+ expect($rootScope.form.alias.$options).not.toBe($rootScope.options);
+ });
+
+ it('should be retrieved from an ancestor element containing an `ngModelOptions` directive', function() {
+ var doc = $compile(
+ '')($rootScope);
+ $rootScope.$digest();
+
+ var inputElm = doc.find('input');
+ helper.changeGivenInputTo(inputElm, 'a');
+ expect($rootScope.name).toEqual(undefined);
+ browserTrigger(inputElm, 'blur');
+ expect($rootScope.name).toBeUndefined();
+ $timeout.flush(2000);
+ expect($rootScope.name).toBeUndefined();
+ $timeout.flush(9000);
+ expect($rootScope.name).toEqual('a');
+ dealoc(doc);
+ });
- it('should be retrieved from an ancestor element containing an `ngModelOptions` directive', function() {
- var doc = $compile(
- '')($rootScope);
- $rootScope.$digest();
-
- var inputElm = doc.find('input');
- helper.changeGivenInputTo(inputElm, 'a');
- expect($rootScope.name).toEqual(undefined);
- browserTrigger(inputElm, 'blur');
- expect($rootScope.name).toBeUndefined();
- $timeout.flush(2000);
- expect($rootScope.name).toBeUndefined();
- $timeout.flush(9000);
- expect($rootScope.name).toEqual('a');
- dealoc(doc);
+ it('should allow sharing options between multiple inputs', function() {
+ $rootScope.options = {updateOn: 'default'};
+ var inputElm = helper.compileInput(
+ '' +
+ '');
+
+ helper.changeGivenInputTo(inputElm.eq(0), 'a');
+ helper.changeGivenInputTo(inputElm.eq(1), 'b');
+ expect($rootScope.name1).toEqual('a');
+ expect($rootScope.name2).toEqual('b');
+ });
});
- it('should allow sharing options between multiple inputs', function() {
- $rootScope.options = {updateOn: 'default'};
- var inputElm = helper.compileInput(
- '' +
- '');
- helper.changeGivenInputTo(inputElm.eq(0), 'a');
- helper.changeGivenInputTo(inputElm.eq(1), 'b');
- expect($rootScope.name1).toEqual('a');
- expect($rootScope.name2).toEqual('b');
- });
- });
+ describe('updateOn', function() {
+ it('should allow overriding the model update trigger event on text inputs', function() {
+ var inputElm = helper.compileInput(
+ '');
+ helper.changeInputValueTo('a');
+ expect($rootScope.name).toBeUndefined();
+ browserTrigger(inputElm, 'blur');
+ expect($rootScope.name).toEqual('a');
+ });
- describe('updateOn', function() {
- it('should allow overriding the model update trigger event on text inputs', function() {
- var inputElm = helper.compileInput(
- '');
- helper.changeInputValueTo('a');
- expect($rootScope.name).toBeUndefined();
- browserTrigger(inputElm, 'blur');
- expect($rootScope.name).toEqual('a');
- });
+ it('should not dirty the input if nothing was changed before updateOn trigger', function() {
+ var inputElm = helper.compileInput(
+ '');
+ browserTrigger(inputElm, 'blur');
+ expect($rootScope.form.alias.$pristine).toBeTruthy();
+ });
- it('should not dirty the input if nothing was changed before updateOn trigger', function() {
- var inputElm = helper.compileInput(
- '');
- browserTrigger(inputElm, 'blur');
- expect($rootScope.form.alias.$pristine).toBeTruthy();
- });
+ it('should allow overriding the model update trigger event on text areas', function() {
+ var inputElm = helper.compileInput(
+ '');
+ helper.changeInputValueTo('a');
+ expect($rootScope.name).toBeUndefined();
+ browserTrigger(inputElm, 'blur');
+ expect($rootScope.name).toEqual('a');
+ });
- it('should allow overriding the model update trigger event on text areas', function() {
- var inputElm = helper.compileInput(
- '');
- helper.changeInputValueTo('a');
- expect($rootScope.name).toBeUndefined();
- browserTrigger(inputElm, 'blur');
- expect($rootScope.name).toEqual('a');
- });
+ it('should bind the element to a list of events', function() {
+ var inputElm = helper.compileInput(
+ '');
+ helper.changeInputValueTo('a');
+ expect($rootScope.name).toBeUndefined();
+ browserTrigger(inputElm, 'blur');
+ expect($rootScope.name).toEqual('a');
- it('should bind the element to a list of events', function() {
- var inputElm = helper.compileInput(
- '');
+ helper.changeInputValueTo('b');
+ expect($rootScope.name).toEqual('a');
+ browserTrigger(inputElm, 'mousemove');
+ expect($rootScope.name).toEqual('b');
+ });
- helper.changeInputValueTo('a');
- expect($rootScope.name).toBeUndefined();
- browserTrigger(inputElm, 'blur');
- expect($rootScope.name).toEqual('a');
- helper.changeInputValueTo('b');
- expect($rootScope.name).toEqual('a');
- browserTrigger(inputElm, 'mousemove');
- expect($rootScope.name).toEqual('b');
- });
+ it('should allow keeping the default update behavior on text inputs', function() {
+ var inputElm = helper.compileInput(
+ '');
+ helper.changeInputValueTo('a');
+ expect($rootScope.name).toEqual('a');
+ });
- it('should allow keeping the default update behavior on text inputs', function() {
- var inputElm = helper.compileInput(
- '');
- helper.changeInputValueTo('a');
- expect($rootScope.name).toEqual('a');
- });
+ it('should allow overriding the model update trigger event on checkboxes', function() {
+ var inputElm = helper.compileInput(
+ '');
+ browserTrigger(inputElm, 'click');
+ expect($rootScope.checkbox).toBeUndefined();
- it('should allow overriding the model update trigger event on checkboxes', function() {
- var inputElm = helper.compileInput(
- '');
+ browserTrigger(inputElm, 'blur');
+ expect($rootScope.checkbox).toBe(true);
- browserTrigger(inputElm, 'click');
- expect($rootScope.checkbox).toBeUndefined();
+ browserTrigger(inputElm, 'click');
+ expect($rootScope.checkbox).toBe(true);
+ });
- browserTrigger(inputElm, 'blur');
- expect($rootScope.checkbox).toBe(true);
- browserTrigger(inputElm, 'click');
- expect($rootScope.checkbox).toBe(true);
- });
+ it('should allow keeping the default update behavior on checkboxes', function() {
+ var inputElm = helper.compileInput(
+ '');
+ browserTrigger(inputElm, 'click');
+ expect($rootScope.checkbox).toBe(true);
- it('should allow keeping the default update behavior on checkboxes', function() {
- var inputElm = helper.compileInput(
- '');
+ browserTrigger(inputElm, 'click');
+ expect($rootScope.checkbox).toBe(false);
+ });
- browserTrigger(inputElm, 'click');
- expect($rootScope.checkbox).toBe(true);
- browserTrigger(inputElm, 'click');
- expect($rootScope.checkbox).toBe(false);
- });
+ it('should allow overriding the model update trigger event on radio buttons', function() {
+ var inputElm = helper.compileInput(
+ '' +
+ '' +
+ '');
+ $rootScope.$apply('color = \'white\'');
+ browserTrigger(inputElm[2], 'click');
+ expect($rootScope.color).toBe('white');
- it('should allow overriding the model update trigger event on radio buttons', function() {
- var inputElm = helper.compileInput(
- '' +
- '' +
- '');
+ browserTrigger(inputElm[2], 'blur');
+ expect($rootScope.color).toBe('blue');
- $rootScope.$apply('color = \'white\'');
- browserTrigger(inputElm[2], 'click');
- expect($rootScope.color).toBe('white');
+ });
- browserTrigger(inputElm[2], 'blur');
- expect($rootScope.color).toBe('blue');
+ it('should allow keeping the default update behavior on radio buttons', function() {
+ var inputElm = helper.compileInput(
+ '' +
+ '' +
+ '');
+
+ $rootScope.$apply('color = \'white\'');
+ browserTrigger(inputElm[2], 'click');
+ expect($rootScope.color).toBe('blue');
+ });
});
- it('should allow keeping the default update behavior on radio buttons', function() {
- var inputElm = helper.compileInput(
- '' +
- '' +
- '');
+ describe('debounce', function() {
+ it('should trigger only after timeout in text inputs', function() {
+ var inputElm = helper.compileInput(
+ '');
- $rootScope.$apply('color = \'white\'');
- browserTrigger(inputElm[2], 'click');
- expect($rootScope.color).toBe('blue');
- });
- });
+ helper.changeInputValueTo('a');
+ helper.changeInputValueTo('b');
+ helper.changeInputValueTo('c');
+ expect($rootScope.name).toEqual(undefined);
+ $timeout.flush(2000);
+ expect($rootScope.name).toEqual(undefined);
+ $timeout.flush(9000);
+ expect($rootScope.name).toEqual('c');
+ });
- describe('debounce', function() {
- it('should trigger only after timeout in text inputs', function() {
- var inputElm = helper.compileInput(
- '');
+ it('should trigger only after timeout in checkboxes', function() {
+ var inputElm = helper.compileInput(
+ '');
- helper.changeInputValueTo('a');
- helper.changeInputValueTo('b');
- helper.changeInputValueTo('c');
- expect($rootScope.name).toEqual(undefined);
- $timeout.flush(2000);
- expect($rootScope.name).toEqual(undefined);
- $timeout.flush(9000);
- expect($rootScope.name).toEqual('c');
- });
+ browserTrigger(inputElm, 'click');
+ expect($rootScope.checkbox).toBeUndefined();
+ $timeout.flush(2000);
+ expect($rootScope.checkbox).toBeUndefined();
+ $timeout.flush(9000);
+ expect($rootScope.checkbox).toBe(true);
+ });
- it('should trigger only after timeout in checkboxes', function() {
- var inputElm = helper.compileInput(
- '');
+ it('should trigger only after timeout in radio buttons', function() {
+ var inputElm = helper.compileInput(
+ '' +
+ '' +
+ '');
+
+ browserTrigger(inputElm[0], 'click');
+ expect($rootScope.color).toBe('white');
+ browserTrigger(inputElm[1], 'click');
+ expect($rootScope.color).toBe('white');
+ $timeout.flush(12000);
+ expect($rootScope.color).toBe('white');
+ $timeout.flush(10000);
+ expect($rootScope.color).toBe('red');
- browserTrigger(inputElm, 'click');
- expect($rootScope.checkbox).toBeUndefined();
- $timeout.flush(2000);
- expect($rootScope.checkbox).toBeUndefined();
- $timeout.flush(9000);
- expect($rootScope.checkbox).toBe(true);
- });
+ });
- it('should trigger only after timeout in radio buttons', function() {
- var inputElm = helper.compileInput(
- '' +
- '' +
- '');
+ it('should not trigger digest while debouncing', function() {
+ var inputElm = helper.compileInput(
+ '');
- browserTrigger(inputElm[0], 'click');
- expect($rootScope.color).toBe('white');
- browserTrigger(inputElm[1], 'click');
- expect($rootScope.color).toBe('white');
- $timeout.flush(12000);
- expect($rootScope.color).toBe('white');
- $timeout.flush(10000);
- expect($rootScope.color).toBe('red');
+ var watchSpy = jasmine.createSpy('watchSpy');
+ $rootScope.$watch(watchSpy);
- });
+ helper.changeInputValueTo('a');
+ expect(watchSpy).not.toHaveBeenCalled();
+ $timeout.flush(10000);
+ expect(watchSpy).toHaveBeenCalled();
+ });
- it('should not trigger digest while debouncing', function() {
- var inputElm = helper.compileInput(
- '');
- var watchSpy = jasmine.createSpy('watchSpy');
- $rootScope.$watch(watchSpy);
+ it('should allow selecting different debounce timeouts for each event',
+ function() {
+ var inputElm = helper.compileInput(
+ '');
+
+ helper.changeInputValueTo('a');
+ expect($rootScope.name).toBeUndefined();
+ $timeout.flush(6000);
+ expect($rootScope.name).toBeUndefined();
+ $timeout.flush(4000);
+ expect($rootScope.name).toEqual('a');
+
+ helper.changeInputValueTo('b');
+ browserTrigger(inputElm, 'blur');
+ $timeout.flush(4000);
+ expect($rootScope.name).toEqual('a');
+ $timeout.flush(2000);
+ expect($rootScope.name).toEqual('b');
+
+ helper.changeInputValueTo('c');
+ browserTrigger(helper.inputElm, 'mouseup');
+ // counter-intuitively `default` in `debounce` is a catch-all
+ expect($rootScope.name).toEqual('b');
+ $timeout.flush(10000);
+ expect($rootScope.name).toEqual('c');
+ });
- helper.changeInputValueTo('a');
- expect(watchSpy).not.toHaveBeenCalled();
- $timeout.flush(10000);
- expect(watchSpy).toHaveBeenCalled();
- });
+ it('should trigger immediately for the event if not listed in the debounce list',
+ function() {
+ var inputElm = helper.compileInput(
+ '');
+ helper.changeInputValueTo('a');
+ expect($rootScope.name).toEqual('a');
- it('should allow selecting different debounce timeouts for each event',
- function() {
- var inputElm = helper.compileInput(
- '');
- helper.changeInputValueTo('a');
- expect($rootScope.name).toBeUndefined();
- $timeout.flush(6000);
- expect($rootScope.name).toBeUndefined();
- $timeout.flush(4000);
- expect($rootScope.name).toEqual('a');
-
- helper.changeInputValueTo('b');
- browserTrigger(inputElm, 'blur');
- $timeout.flush(4000);
- expect($rootScope.name).toEqual('a');
- $timeout.flush(2000);
- expect($rootScope.name).toEqual('b');
-
- helper.changeInputValueTo('c');
- browserTrigger(helper.inputElm, 'mouseup');
- // counter-intuitively `default` in `debounce` is a catch-all
- expect($rootScope.name).toEqual('b');
- $timeout.flush(10000);
- expect($rootScope.name).toEqual('c');
- });
+ inputElm[0].checked = false;
+ browserTrigger(inputElm, 'click');
+ expect($rootScope.checkbox).toBeUndefined();
+ $timeout.flush(8000);
+ expect($rootScope.checkbox).toBeUndefined();
+ $timeout.flush(3000);
+ expect($rootScope.checkbox).toBe(true);
+ inputElm[0].checked = true;
+ browserTrigger(inputElm, 'click');
+ browserTrigger(inputElm, 'blur');
+ $timeout.flush(3000);
+ expect($rootScope.checkbox).toBe(true);
+ $timeout.flush(3000);
+ expect($rootScope.checkbox).toBe(false);
+ });
- it('should trigger immediately for the event if not listed in the debounce list',
- function() {
- var inputElm = helper.compileInput(
- '');
- helper.changeInputValueTo('a');
- expect($rootScope.name).toEqual('a');
+ inputElm[0].checked = false;
+ browserTrigger(inputElm, 'click');
+ expect($rootScope.checkbox).toBeUndefined();
+ $timeout.flush(8000);
+ expect($rootScope.checkbox).toBeUndefined();
+ $timeout.flush(3000);
+ expect($rootScope.checkbox).toBe(true);
+ inputElm[0].checked = true;
+ browserTrigger(inputElm, 'click');
+ browserTrigger(inputElm, 'blur');
+ $timeout.flush(0);
+ expect($rootScope.checkbox).toBe(false);
+ });
- helper.changeInputValueTo('b');
- browserTrigger(inputElm, 'foo');
- expect($rootScope.name).toEqual('b');
- });
- it('should allow selecting different debounce timeouts for each event on checkboxes', function() {
- var inputElm = helper.compileInput('');
-
- inputElm[0].checked = false;
- browserTrigger(inputElm, 'click');
- expect($rootScope.checkbox).toBeUndefined();
- $timeout.flush(8000);
- expect($rootScope.checkbox).toBeUndefined();
- $timeout.flush(3000);
- expect($rootScope.checkbox).toBe(true);
- inputElm[0].checked = true;
- browserTrigger(inputElm, 'click');
- browserTrigger(inputElm, 'blur');
- $timeout.flush(3000);
- expect($rootScope.checkbox).toBe(true);
- $timeout.flush(3000);
- expect($rootScope.checkbox).toBe(false);
- });
+ it('should flush debounced events when calling $commitViewValue directly', function() {
+ var inputElm = helper.compileInput(
+ '');
+ helper.changeInputValueTo('a');
+ expect($rootScope.name).toEqual(undefined);
+ $rootScope.form.alias.$commitViewValue();
+ expect($rootScope.name).toEqual('a');
+ });
- it('should allow selecting 0 for non-default debounce timeouts for each event on checkboxes', function() {
- var inputElm = helper.compileInput('');
-
- inputElm[0].checked = false;
- browserTrigger(inputElm, 'click');
- expect($rootScope.checkbox).toBeUndefined();
- $timeout.flush(8000);
- expect($rootScope.checkbox).toBeUndefined();
- $timeout.flush(3000);
- expect($rootScope.checkbox).toBe(true);
- inputElm[0].checked = true;
- browserTrigger(inputElm, 'click');
- browserTrigger(inputElm, 'blur');
- $timeout.flush(0);
- expect($rootScope.checkbox).toBe(false);
- });
+ it('should cancel debounced events when calling $commitViewValue', function() {
+ var inputElm = helper.compileInput(
+ '');
+ helper.changeInputValueTo('a');
+ $rootScope.form.alias.$commitViewValue();
+ expect($rootScope.name).toEqual('a');
- it('should flush debounced events when calling $commitViewValue directly', function() {
- var inputElm = helper.compileInput(
- '');
+ $rootScope.form.alias.$setPristine();
+ $timeout.flush(1000);
+ expect($rootScope.form.alias.$pristine).toBeTruthy();
+ });
- helper.changeInputValueTo('a');
- expect($rootScope.name).toEqual(undefined);
- $rootScope.form.alias.$commitViewValue();
- expect($rootScope.name).toEqual('a');
- });
- it('should cancel debounced events when calling $commitViewValue', function() {
- var inputElm = helper.compileInput(
- '');
+ it('should reset input val if rollbackViewValue called during pending update', function() {
+ var inputElm = helper.compileInput(
+ '');
+
+ helper.changeInputValueTo('a');
+ expect(inputElm.val()).toBe('a');
+ $rootScope.form.alias.$rollbackViewValue();
+ expect(inputElm.val()).toBe('');
+ browserTrigger(inputElm, 'blur');
+ expect(inputElm.val()).toBe('');
+ });
- helper.changeInputValueTo('a');
- $rootScope.form.alias.$commitViewValue();
- expect($rootScope.name).toEqual('a');
- $rootScope.form.alias.$setPristine();
- $timeout.flush(1000);
- expect($rootScope.form.alias.$pristine).toBeTruthy();
- });
+ it('should allow canceling pending updates', function() {
+ var inputElm = helper.compileInput(
+ '');
+
+ helper.changeInputValueTo('a');
+ expect($rootScope.name).toEqual(undefined);
+ $rootScope.form.alias.$rollbackViewValue();
+ expect($rootScope.name).toEqual(undefined);
+ browserTrigger(inputElm, 'blur');
+ expect($rootScope.name).toEqual(undefined);
+ });
- it('should reset input val if rollbackViewValue called during pending update', function() {
- var inputElm = helper.compileInput(
- '');
+ it('should allow canceling debounced updates', function() {
+ var inputElm = helper.compileInput(
+ '');
+
+ helper.changeInputValueTo('a');
+ expect($rootScope.name).toEqual(undefined);
+ $timeout.flush(2000);
+ $rootScope.form.alias.$rollbackViewValue();
+ expect($rootScope.name).toEqual(undefined);
+ $timeout.flush(10000);
+ expect($rootScope.name).toEqual(undefined);
+ });
- helper.changeInputValueTo('a');
- expect(inputElm.val()).toBe('a');
- $rootScope.form.alias.$rollbackViewValue();
- expect(inputElm.val()).toBe('');
- browserTrigger(inputElm, 'blur');
- expect(inputElm.val()).toBe('');
- });
+ it('should handle model updates correctly even if rollbackViewValue is not invoked', function() {
+ var inputElm = helper.compileInput(
+ '');
- it('should allow canceling pending updates', function() {
- var inputElm = helper.compileInput(
- '');
+ helper.changeInputValueTo('a');
+ $rootScope.$apply('name = \'b\'');
+ browserTrigger(inputElm, 'blur');
+ expect($rootScope.name).toBe('b');
+ });
- helper.changeInputValueTo('a');
- expect($rootScope.name).toEqual(undefined);
- $rootScope.form.alias.$rollbackViewValue();
- expect($rootScope.name).toEqual(undefined);
- browserTrigger(inputElm, 'blur');
- expect($rootScope.name).toEqual(undefined);
- });
+ it('should reset input val if rollbackViewValue called during debounce', function() {
+ var inputElm = helper.compileInput(
+ '');
+
+ helper.changeInputValueTo('a');
+ expect(inputElm.val()).toBe('a');
+ $rootScope.form.alias.$rollbackViewValue();
+ expect(inputElm.val()).toBe('');
+ $timeout.flush(3000);
+ expect(inputElm.val()).toBe('');
+ });
+ });
- it('should allow canceling debounced updates', function() {
- var inputElm = helper.compileInput(
- '');
- helper.changeInputValueTo('a');
- expect($rootScope.name).toEqual(undefined);
- $timeout.flush(2000);
- $rootScope.form.alias.$rollbackViewValue();
- expect($rootScope.name).toEqual(undefined);
- $timeout.flush(10000);
- expect($rootScope.name).toEqual(undefined);
- });
+ describe('getterSetter', function() {
+ it('should not try to invoke a model if getterSetter is false', function() {
+ var inputElm = helper.compileInput(
+ '');
+ var spy = $rootScope.name = jasmine.createSpy('setterSpy');
+ helper.changeInputValueTo('a');
+ expect(spy).not.toHaveBeenCalled();
+ expect(inputElm.val()).toBe('a');
+ });
- it('should handle model updates correctly even if rollbackViewValue is not invoked', function() {
- var inputElm = helper.compileInput(
- '');
- helper.changeInputValueTo('a');
- $rootScope.$apply('name = \'b\'');
- browserTrigger(inputElm, 'blur');
- expect($rootScope.name).toBe('b');
- });
+ it('should not try to invoke a model if getterSetter is not set', function() {
+ var inputElm = helper.compileInput('');
+ var spy = $rootScope.name = jasmine.createSpy('setterSpy');
+ helper.changeInputValueTo('a');
+ expect(spy).not.toHaveBeenCalled();
+ expect(inputElm.val()).toBe('a');
+ });
- it('should reset input val if rollbackViewValue called during debounce', function() {
- var inputElm = helper.compileInput(
- '');
- helper.changeInputValueTo('a');
- expect(inputElm.val()).toBe('a');
- $rootScope.form.alias.$rollbackViewValue();
- expect(inputElm.val()).toBe('');
- $timeout.flush(3000);
- expect(inputElm.val()).toBe('');
- });
- });
+ it('should try to invoke a function model if getterSetter is true', function() {
+ var inputElm = helper.compileInput(
+ '');
+ var spy = $rootScope.name = jasmine.createSpy('setterSpy').and.callFake(function() {
+ return 'b';
+ });
+ $rootScope.$apply();
+ expect(inputElm.val()).toBe('b');
- describe('getterSetter', function() {
- it('should not try to invoke a model if getterSetter is false', function() {
- var inputElm = helper.compileInput(
- '');
+ helper.changeInputValueTo('a');
+ expect(inputElm.val()).toBe('b');
+ expect(spy).toHaveBeenCalledWith('a');
+ expect($rootScope.name).toBe(spy);
+ });
- var spy = $rootScope.name = jasmine.createSpy('setterSpy');
- helper.changeInputValueTo('a');
- expect(spy).not.toHaveBeenCalled();
- expect(inputElm.val()).toBe('a');
- });
+ it('should assign to non-function models if getterSetter is true', function() {
+ var inputElm = helper.compileInput(
+ '');
- it('should not try to invoke a model if getterSetter is not set', function() {
- var inputElm = helper.compileInput('');
+ $rootScope.name = 'c';
+ helper.changeInputValueTo('d');
+ expect(inputElm.val()).toBe('d');
+ expect($rootScope.name).toBe('d');
+ });
- var spy = $rootScope.name = jasmine.createSpy('setterSpy');
- helper.changeInputValueTo('a');
- expect(spy).not.toHaveBeenCalled();
- expect(inputElm.val()).toBe('a');
- });
+ it('should fail on non-assignable model binding if getterSetter is false', function() {
+ expect(function() {
+ var inputElm = helper.compileInput('');
+ }).toThrowMinErr('ngModel', 'nonassign', 'Expression \'accessor(user, \'name\')\' is non-assignable.');
+ });
- it('should try to invoke a function model if getterSetter is true', function() {
- var inputElm = helper.compileInput(
- '');
- var spy = $rootScope.name = jasmine.createSpy('setterSpy').and.callFake(function() {
- return 'b';
+ it('should not fail on non-assignable model binding if getterSetter is true', function() {
+ var inputElm = helper.compileInput(
+ '');
});
- $rootScope.$apply();
- expect(inputElm.val()).toBe('b');
- helper.changeInputValueTo('a');
- expect(inputElm.val()).toBe('b');
- expect(spy).toHaveBeenCalledWith('a');
- expect($rootScope.name).toBe(spy);
+
+ it('should invoke a model in the correct context if getterSetter is true', function() {
+ var inputElm = helper.compileInput(
+ '');
+
+ $rootScope.someService = {
+ value: 'a',
+ getterSetter: function(newValue) {
+ this.value = newValue || this.value;
+ return this.value;
+ }
+ };
+ spyOn($rootScope.someService, 'getterSetter').and.callThrough();
+ $rootScope.$apply();
+
+ expect(inputElm.val()).toBe('a');
+ expect($rootScope.someService.getterSetter).toHaveBeenCalledWith();
+ expect($rootScope.someService.value).toBe('a');
+
+ helper.changeInputValueTo('b');
+ expect($rootScope.someService.getterSetter).toHaveBeenCalledWith('b');
+ expect($rootScope.someService.value).toBe('b');
+
+ $rootScope.someService.value = 'c';
+ $rootScope.$apply();
+ expect(inputElm.val()).toBe('c');
+ expect($rootScope.someService.getterSetter).toHaveBeenCalledWith();
+ });
});
- it('should assign to non-function models if getterSetter is true', function() {
- var inputElm = helper.compileInput(
- '');
+ describe('allowInvalid', function() {
+ it('should assign invalid values to the scope if allowInvalid is true', function() {
+ var inputElm = helper.compileInput('');
+ helper.changeInputValueTo('12345');
- $rootScope.name = 'c';
- helper.changeInputValueTo('d');
- expect(inputElm.val()).toBe('d');
- expect($rootScope.name).toBe('d');
- });
+ expect($rootScope.value).toBe('12345');
+ expect(inputElm).toBeInvalid();
+ });
- it('should fail on non-assignable model binding if getterSetter is false', function() {
- expect(function() {
- var inputElm = helper.compileInput('');
- }).toThrowMinErr('ngModel', 'nonassign', 'Expression \'accessor(user, \'name\')\' is non-assignable.');
- });
+ it('should not assign not parsable values to the scope if allowInvalid is true', function() {
+ var inputElm = helper.compileInput('', {
+ valid: false,
+ badInput: true
+ });
+ helper.changeInputValueTo('abcd');
+ expect($rootScope.value).toBeUndefined();
+ expect(inputElm).toBeInvalid();
+ });
- it('should not fail on non-assignable model binding if getterSetter is true', function() {
- var inputElm = helper.compileInput(
- '');
- });
+ it('should update the scope before async validators execute if allowInvalid is true', function() {
+ var inputElm = helper.compileInput('');
+ var defer;
+ $rootScope.form.input.$asyncValidators.promiseValidator = function(value) {
+ defer = $q.defer();
+ return defer.promise;
+ };
+ helper.changeInputValueTo('12345');
+
+ expect($rootScope.value).toBe('12345');
+ expect($rootScope.form.input.$pending.promiseValidator).toBe(true);
+ defer.reject();
+ $rootScope.$digest();
+ expect($rootScope.value).toBe('12345');
+ expect(inputElm).toBeInvalid();
+ });
- it('should invoke a model in the correct context if getterSetter is true', function() {
- var inputElm = helper.compileInput(
- '');
-
- $rootScope.someService = {
- value: 'a',
- getterSetter: function(newValue) {
- this.value = newValue || this.value;
- return this.value;
- }
- };
- spyOn($rootScope.someService, 'getterSetter').and.callThrough();
- $rootScope.$apply();
-
- expect(inputElm.val()).toBe('a');
- expect($rootScope.someService.getterSetter).toHaveBeenCalledWith();
- expect($rootScope.someService.value).toBe('a');
-
- helper.changeInputValueTo('b');
- expect($rootScope.someService.getterSetter).toHaveBeenCalledWith('b');
- expect($rootScope.someService.value).toBe('b');
-
- $rootScope.someService.value = 'c';
- $rootScope.$apply();
- expect(inputElm.val()).toBe('c');
- expect($rootScope.someService.getterSetter).toHaveBeenCalledWith();
- });
- });
+ it('should update the view before async validators execute if allowInvalid is true', function() {
+ var inputElm = helper.compileInput('');
+ var defer;
+ $rootScope.form.input.$asyncValidators.promiseValidator = function(value) {
+ defer = $q.defer();
+ return defer.promise;
+ };
+ $rootScope.$apply('value = \'12345\'');
+
+ expect(inputElm.val()).toBe('12345');
+ expect($rootScope.form.input.$pending.promiseValidator).toBe(true);
+ defer.reject();
+ $rootScope.$digest();
+ expect(inputElm.val()).toBe('12345');
+ expect(inputElm).toBeInvalid();
+ });
- describe('allowInvalid', function() {
- it('should assign invalid values to the scope if allowInvalid is true', function() {
- var inputElm = helper.compileInput('');
- helper.changeInputValueTo('12345');
- expect($rootScope.value).toBe('12345');
- expect(inputElm).toBeInvalid();
- });
+ it('should not call ng-change listeners twice if the model did not change with allowInvalid', function() {
+ var inputElm = helper.compileInput('');
+ $rootScope.changed = jasmine.createSpy('changed');
+ $rootScope.form.input.$parsers.push(function(value) {
+ return 'modelValue';
+ });
+ helper.changeInputValueTo('input1');
+ expect($rootScope.value).toBe('modelValue');
+ expect($rootScope.changed).toHaveBeenCalledOnce();
- it('should not assign not parsable values to the scope if allowInvalid is true', function() {
- var inputElm = helper.compileInput('', {
- valid: false,
- badInput: true
+ helper.changeInputValueTo('input2');
+ expect($rootScope.value).toBe('modelValue');
+ expect($rootScope.changed).toHaveBeenCalledOnce();
});
- helper.changeInputValueTo('abcd');
-
- expect($rootScope.value).toBeUndefined();
- expect(inputElm).toBeInvalid();
});
+ });
- it('should update the scope before async validators execute if allowInvalid is true', function() {
- var inputElm = helper.compileInput('');
- var defer;
- $rootScope.form.input.$asyncValidators.promiseValidator = function(value) {
- defer = $q.defer();
- return defer.promise;
- };
- helper.changeInputValueTo('12345');
-
- expect($rootScope.value).toBe('12345');
- expect($rootScope.form.input.$pending.promiseValidator).toBe(true);
- defer.reject();
- $rootScope.$digest();
- expect($rootScope.value).toBe('12345');
- expect(inputElm).toBeInvalid();
- });
+ describe('on directives with `replace: true`', function() {
+ var $rootScope, $compile;
- it('should update the view before async validators execute if allowInvalid is true', function() {
- var inputElm = helper.compileInput('');
- var defer;
- $rootScope.form.input.$asyncValidators.promiseValidator = function(value) {
- defer = $q.defer();
- return defer.promise;
- };
- $rootScope.$apply('value = \'12345\'');
-
- expect(inputElm.val()).toBe('12345');
- expect($rootScope.form.input.$pending.promiseValidator).toBe(true);
- defer.reject();
- $rootScope.$digest();
- expect(inputElm.val()).toBe('12345');
- expect(inputElm).toBeInvalid();
- });
+ beforeEach(module(function($compileProvider) {
+ $compileProvider.directive('foo', valueFn({
+ replace: true,
+ template: ''
+ }));
+ }));
+ beforeEach(inject(function(_$compile_, _$rootScope_) {
+ $compile = _$compile_;
+ $rootScope = _$rootScope_;
+ }));
- it('should not call ng-change listeners twice if the model did not change with allowInvalid', function() {
- var inputElm = helper.compileInput('');
- $rootScope.changed = jasmine.createSpy('changed');
- $rootScope.form.input.$parsers.push(function(value) {
- return 'modelValue';
- });
- helper.changeInputValueTo('input1');
- expect($rootScope.value).toBe('modelValue');
- expect($rootScope.changed).toHaveBeenCalledOnce();
+ it('should get initialized in time for `ngModel` on the original element', function() {
+ var inputElm = $compile('')($rootScope);
+ var ngModelCtrl = inputElm.controller('ngModel');
- helper.changeInputValueTo('input2');
- expect($rootScope.value).toBe('modelValue');
- expect($rootScope.changed).toHaveBeenCalledOnce();
+ expect(ngModelCtrl.$options.getOption('debounce')).toBe(1000);
});
});
});