From 3f3f60c474bdedbbdccd37683782f9d84016eef8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matias=20Niemel=C3=A4?= Date: Wed, 3 Sep 2014 15:02:46 -0400 Subject: [PATCH 1/5] fix(ngModel): revalidate the model when min/max expression values change for number inputs As of this fix if the max or min value is changed via scope or by another ngModel then it will trigger the model containing the min/max attributes to revalidate itself. Closes #2404 --- src/ng/directive/input.js | 24 +++++++++++++++++-- test/ng/directive/inputSpec.js | 44 ++++++++++++++++++++++++---------- 2 files changed, 54 insertions(+), 14 deletions(-) diff --git a/src/ng/directive/input.js b/src/ng/directive/input.js index 977be6c7bfa6..48e218f51e5b 100644 --- a/src/ng/directive/input.js +++ b/src/ng/directive/input.js @@ -1129,15 +1129,35 @@ function numberInputType(scope, element, attr, ctrl, $sniffer, $browser) { }); if (attr.min) { + var minVal; ctrl.$validators.min = function(value) { - return ctrl.$isEmpty(value) || isUndefined(attr.min) || value >= parseFloat(attr.min); + return ctrl.$isEmpty(value) || isUndefined(minVal) || value >= minVal; }; + + attr.$observe('min', function(val) { + if (isDefined(val) && !isNumber(val)) { + val = parseFloat(val, 10); + } + minVal = isNumber(val) && !isNaN(val) ? val : undefined; + // TODO(matsko): implement validateLater to reduce number of validations + ctrl.$validate(); + }); } if (attr.max) { + var maxVal; ctrl.$validators.max = function(value) { - return ctrl.$isEmpty(value) || isUndefined(attr.max) || value <= parseFloat(attr.max); + return ctrl.$isEmpty(value) || isUndefined(maxVal) || value <= maxVal; }; + + attr.$observe('max', function(val) { + if (isDefined(val) && !isNumber(val)) { + val = parseFloat(val, 10); + } + maxVal = isNumber(val) && !isNaN(val) ? val : undefined; + // TODO(matsko): implement validateLater to reduce number of validations + ctrl.$validate(); + }); } } diff --git a/test/ng/directive/inputSpec.js b/test/ng/directive/inputSpec.js index 3c5e6d437cb1..3bcf7a781edf 100644 --- a/test/ng/directive/inputSpec.js +++ b/test/ng/directive/inputSpec.js @@ -2894,18 +2894,28 @@ describe('input', function() { expect(scope.form.alias.$error.min).toBeFalsy(); }); - it('should validate even if min value changes on-the-fly', function(done) { + it('should validate even if min value changes on-the-fly', function() { scope.min = 10; compileInput(''); - changeInputValueTo('5'); + changeInputValueTo('15'); + expect(inputElm).toBeValid(); + + scope.min = 20; + scope.$digest(); expect(inputElm).toBeInvalid(); - scope.min = 0; - scope.$digest(function () { - expect(inputElm).toBeValid(); - done(); - }); + scope.min = null; + scope.$digest(); + expect(inputElm).toBeValid(); + + scope.min = '20'; + scope.$digest(); + expect(inputElm).toBeInvalid(); + + scope.min = 'abc'; + scope.$digest(); + expect(inputElm).toBeValid(); }); }); @@ -2926,7 +2936,7 @@ describe('input', function() { expect(scope.form.alias.$error.max).toBeFalsy(); }); - it('should validate even if max value changes on-the-fly', function(done) { + it('should validate even if max value changes on-the-fly', function() { scope.max = 10; compileInput(''); @@ -2934,10 +2944,20 @@ describe('input', function() { expect(inputElm).toBeValid(); scope.max = 0; - scope.$digest(function () { - expect(inputElm).toBeInvalid(); - done(); - }); + scope.$digest(); + expect(inputElm).toBeInvalid(); + + scope.max = null; + scope.$digest(); + expect(inputElm).toBeValid(); + + scope.max = '4'; + scope.$digest(); + expect(inputElm).toBeInvalid(); + + scope.max = 'abc'; + scope.$digest(); + expect(inputElm).toBeValid(); }); }); From b64857097e2fcfc780efe5d0aafa675f88a35e44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matias=20Niemel=C3=A4?= Date: Wed, 3 Sep 2014 15:12:47 -0400 Subject: [PATCH 2/5] fix(ngModel): consider ngMin/ngMax values when validating number input types With this fix ngModel will treat ngMin as a min error and ngMax as a max error. This also means that when either of these two values is changed then ngModel will revaliate itself. --- src/jqLite.js | 2 + src/ng/directive/input.js | 4 +- test/ng/directive/inputSpec.js | 82 ++++++++++++++++++++++++++++++++++ 3 files changed, 86 insertions(+), 2 deletions(-) diff --git a/src/jqLite.js b/src/jqLite.js index 73b76f930739..61955850178d 100644 --- a/src/jqLite.js +++ b/src/jqLite.js @@ -506,6 +506,8 @@ forEach('input,select,option,textarea,button,form,details'.split(','), function( var ALIASED_ATTR = { 'ngMinlength' : 'minlength', 'ngMaxlength' : 'maxlength', + 'ngMin' : 'min', + 'ngMax' : 'max', 'ngPattern' : 'pattern' }; diff --git a/src/ng/directive/input.js b/src/ng/directive/input.js index 48e218f51e5b..9ad168927fb1 100644 --- a/src/ng/directive/input.js +++ b/src/ng/directive/input.js @@ -1128,7 +1128,7 @@ function numberInputType(scope, element, attr, ctrl, $sniffer, $browser) { return value; }); - if (attr.min) { + if (attr.min || attr.ngMin) { var minVal; ctrl.$validators.min = function(value) { return ctrl.$isEmpty(value) || isUndefined(minVal) || value >= minVal; @@ -1144,7 +1144,7 @@ function numberInputType(scope, element, attr, ctrl, $sniffer, $browser) { }); } - if (attr.max) { + if (attr.max || attr.ngMax) { var maxVal; ctrl.$validators.max = function(value) { return ctrl.$isEmpty(value) || isUndefined(maxVal) || value <= maxVal; diff --git a/test/ng/directive/inputSpec.js b/test/ng/directive/inputSpec.js index 3bcf7a781edf..48f4b9bd153c 100644 --- a/test/ng/directive/inputSpec.js +++ b/test/ng/directive/inputSpec.js @@ -2919,6 +2919,47 @@ describe('input', function() { }); }); + describe('ngMin', function() { + + it('should validate', function() { + compileInput(''); + + changeInputValueTo('1'); + expect(inputElm).toBeInvalid(); + expect(scope.value).toBeFalsy(); + expect(scope.form.alias.$error.min).toBeTruthy(); + + changeInputValueTo('100'); + expect(inputElm).toBeValid(); + expect(scope.value).toBe(100); + expect(scope.form.alias.$error.min).toBeFalsy(); + }); + + it('should validate even if the ngMin value changes on-the-fly', function() { + scope.min = 10; + compileInput(''); + + changeInputValueTo('15'); + expect(inputElm).toBeValid(); + + scope.min = 20; + scope.$digest(); + expect(inputElm).toBeInvalid(); + + scope.min = null; + scope.$digest(); + expect(inputElm).toBeValid(); + + scope.min = '20'; + scope.$digest(); + expect(inputElm).toBeInvalid(); + + scope.min = 'abc'; + scope.$digest(); + expect(inputElm).toBeValid(); + }); + }); + describe('max', function() { @@ -2961,6 +3002,47 @@ describe('input', function() { }); }); + describe('ngMax', function() { + + it('should validate', function() { + compileInput(''); + + changeInputValueTo('20'); + expect(inputElm).toBeInvalid(); + expect(scope.value).toBeUndefined(); + expect(scope.form.alias.$error.max).toBeTruthy(); + + changeInputValueTo('0'); + expect(inputElm).toBeValid(); + expect(scope.value).toBe(0); + expect(scope.form.alias.$error.max).toBeFalsy(); + }); + + it('should validate even if the ngMax value changes on-the-fly', function() { + scope.max = 10; + compileInput(''); + + changeInputValueTo('5'); + expect(inputElm).toBeValid(); + + scope.max = 0; + scope.$digest(); + expect(inputElm).toBeInvalid(); + + scope.max = null; + scope.$digest(); + expect(inputElm).toBeValid(); + + scope.max = '4'; + scope.$digest(); + expect(inputElm).toBeInvalid(); + + scope.max = 'abc'; + scope.$digest(); + expect(inputElm).toBeValid(); + }); + }); + describe('required', function() { From 4102ff18d9f70804e9e7eb015b5b9b0aa95ca17c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matias=20Niemel=C3=A4?= Date: Wed, 3 Sep 2014 15:42:44 -0400 Subject: [PATCH 3/5] fix(ngModel): revalidate the model when min/max expression values change for date inputs Closes #6755 --- src/ng/directive/input.js | 22 ++++- test/ng/directive/inputSpec.js | 172 ++++++++++++++++++++++++++------- 2 files changed, 155 insertions(+), 39 deletions(-) diff --git a/src/ng/directive/input.js b/src/ng/directive/input.js index 9ad168927fb1..aef4d1571229 100644 --- a/src/ng/directive/input.js +++ b/src/ng/directive/input.js @@ -1082,16 +1082,30 @@ function createDateInputType(type, regexp, parseDate, format) { return ''; }); - if (attr.min) { + if (attr.min || attr.ngMin) { + var minVal; ctrl.$validators.min = function(value) { - return ctrl.$isEmpty(value) || isUndefined(attr.min) || parseDate(value) >= parseDate(attr.min); + return ctrl.$isEmpty(value) || isUndefined(minVal) || parseDate(value) >= minVal; }; + attr.$observe('min', function(val) { + minVal = parseObservedDateValue(val); + ctrl.$validate(); + }); } - if (attr.max) { + if (attr.max || attr.ngMax) { + var maxVal; ctrl.$validators.max = function(value) { - return ctrl.$isEmpty(value) || isUndefined(attr.max) || parseDate(value) <= parseDate(attr.max); + return ctrl.$isEmpty(value) || isUndefined(maxVal) || parseDate(value) <= maxVal; }; + attr.$observe('max', function(val) { + maxVal = parseObservedDateValue(val); + ctrl.$validate(); + }); + } + + function parseObservedDateValue(val) { + return isDefined(val) ? (isDate(val) ? val : parseDate(val)) : undefined; } }; } diff --git a/test/ng/directive/inputSpec.js b/test/ng/directive/inputSpec.js index 48f4b9bd153c..751172ac622d 100644 --- a/test/ng/directive/inputSpec.js +++ b/test/ng/directive/inputSpec.js @@ -2063,9 +2063,12 @@ describe('input', function() { }); describe('min', function (){ - beforeEach(function (){ - compileInput(''); - }); + var scope; + beforeEach(inject(function ($rootScope){ + scope = $rootScope; + $rootScope.minVal = '2013-01'; + compileInput(''); + })); it('should invalidate', function (){ changeInputValueTo('2012-12'); @@ -2080,12 +2083,27 @@ describe('input', function() { expect(+scope.value).toBe(+new Date(2013, 6, 1)); expect(scope.form.alias.$error.min).toBeFalsy(); }); + + it('should revalidate when the min value changes', function (){ + changeInputValueTo('2013-07'); + expect(inputElm).toBeValid(); + expect(scope.form.alias.$error.min).toBeFalsy(); + + scope.minVal = '2014-01'; + scope.$digest(); + + expect(inputElm).toBeInvalid(); + expect(scope.form.alias.$error.min).toBeTruthy(); + }); }); describe('max', function(){ - beforeEach(function (){ - compileInput(''); - }); + var scope; + beforeEach(inject(function ($rootScope){ + scope = $rootScope; + $rootScope.maxVal = '2013-01'; + compileInput(''); + })); it('should validate', function (){ changeInputValueTo('2012-03'); @@ -2100,6 +2118,18 @@ describe('input', function() { expect(scope.value).toBeUndefined(); expect(scope.form.alias.$error.max).toBeTruthy(); }); + + it('should revalidate when the max value changes', function (){ + changeInputValueTo('2012-07'); + expect(inputElm).toBeValid(); + expect(scope.form.alias.$error.max).toBeFalsy(); + + scope.maxVal = '2012-01'; + scope.$digest(); + + expect(inputElm).toBeInvalid(); + expect(scope.form.alias.$error.max).toBeTruthy(); + }); }); }); @@ -2204,9 +2234,12 @@ describe('input', function() { }); describe('min', function (){ - beforeEach(function (){ - compileInput(''); - }); + var scope; + beforeEach(inject(function ($rootScope){ + scope = $rootScope; + $rootScope.minVal = '2013-W01'; + compileInput(''); + })); it('should invalidate', function (){ changeInputValueTo('2012-W12'); @@ -2221,12 +2254,26 @@ describe('input', function() { expect(+scope.value).toBe(+new Date(2013, 0, 17)); expect(scope.form.alias.$error.min).toBeFalsy(); }); + + it('should revalidate when the min value changes', function (){ + changeInputValueTo('2013-W03'); + expect(inputElm).toBeValid(); + expect(scope.form.alias.$error.min).toBeFalsy(); + + scope.minVal = '2014-W01'; + scope.$digest(); + + expect(inputElm).toBeInvalid(); + expect(scope.form.alias.$error.min).toBeTruthy(); + }); }); describe('max', function(){ - beforeEach(function (){ - compileInput(''); - }); + beforeEach(inject(function ($rootScope){ + $rootScope.maxVal = '2013-W01'; + scope = $rootScope; + compileInput(''); + })); it('should validate', function (){ changeInputValueTo('2012-W01'); @@ -2241,6 +2288,18 @@ describe('input', function() { expect(scope.value).toBeUndefined(); expect(scope.form.alias.$error.max).toBeTruthy(); }); + + it('should revalidate when the max value changes', function (){ + changeInputValueTo('2012-W03'); + expect(inputElm).toBeValid(); + expect(scope.form.alias.$error.max).toBeFalsy(); + + scope.maxVal = '2012-W01'; + scope.$digest(); + + expect(inputElm).toBeInvalid(); + expect(scope.form.alias.$error.max).toBeTruthy(); + }); }); }); @@ -2363,9 +2422,12 @@ describe('input', function() { }); describe('min', function (){ - beforeEach(function (){ - compileInput(''); - }); + var scope; + beforeEach(inject(function ($rootScope){ + $rootScope.minVal = '2000-01-01T12:30:00'; + scope = $rootScope; + compileInput(''); + })); it('should invalidate', function (){ changeInputValueTo('1999-12-31T01:02:00'); @@ -2380,12 +2442,27 @@ describe('input', function() { expect(+scope.value).toBe(+new Date(2000, 0, 1, 23, 2, 0)); expect(scope.form.alias.$error.min).toBeFalsy(); }); + + it('should revalidate when the min value changes', function (){ + changeInputValueTo('2000-02-01T01:02:00'); + expect(inputElm).toBeValid(); + expect(scope.form.alias.$error.min).toBeFalsy(); + + scope.minVal = '2010-01-01T01:02:00'; + scope.$digest(); + + expect(inputElm).toBeInvalid(); + expect(scope.form.alias.$error.min).toBeTruthy(); + }); }); describe('max', function (){ - beforeEach(function (){ - compileInput(''); - }); + var scope; + beforeEach(inject(function ($rootScope){ + $rootScope.maxVal = '2019-01-01T01:02:00'; + scope = $rootScope; + compileInput(''); + })); it('should invalidate', function (){ changeInputValueTo('2019-12-31T01:02:00'); @@ -2400,6 +2477,18 @@ describe('input', function() { expect(+scope.value).toBe(+new Date(2000, 0, 1, 1, 2, 0)); expect(scope.form.alias.$error.max).toBeFalsy(); }); + + it('should revalidate when the max value changes', function (){ + changeInputValueTo('2000-02-01T01:02:00'); + expect(inputElm).toBeValid(); + expect(scope.form.alias.$error.max).toBeFalsy(); + + scope.maxVal = '2000-01-01T01:02:00'; + scope.$digest(); + + expect(inputElm).toBeInvalid(); + expect(scope.form.alias.$error.max).toBeTruthy(); + }); }); it('should validate even if max value changes on-the-fly', function(done) { @@ -2550,9 +2639,12 @@ describe('input', function() { }); describe('min', function (){ - beforeEach(function (){ - compileInput(''); - }); + var scope; + beforeEach(inject(function ($rootScope){ + $rootScope.minVal = '09:30:00'; + scope = $rootScope; + compileInput(''); + })); it('should invalidate', function (){ changeInputValueTo('01:02:00'); @@ -2567,6 +2659,18 @@ describe('input', function() { expect(+scope.value).toBe(+new Date(1970, 0, 1, 23, 2, 0)); expect(scope.form.alias.$error.min).toBeFalsy(); }); + + it('should revalidate when the min value changes', function (){ + changeInputValueTo('23:02:00'); + expect(inputElm).toBeValid(); + expect(scope.form.alias.$error.min).toBeFalsy(); + + scope.minVal = '23:55:00'; + scope.$digest(); + + expect(inputElm).toBeInvalid(); + expect(scope.form.alias.$error.min).toBeTruthy(); + }); }); describe('max', function (){ @@ -2589,32 +2693,30 @@ describe('input', function() { }); }); - it('should validate even if max value changes on-the-fly', function(done) { - scope.max = '21:02:00'; + it('should validate even if max value changes on-the-fly', function() { + scope.max = '4:02:00'; compileInput(''); - changeInputValueTo('22:34:00'); + changeInputValueTo('05:34:00'); expect(inputElm).toBeInvalid(); - scope.max = '12:34:00'; - scope.$digest(function () { - expect(inputElm).toBeValid(); - done(); - }); + scope.max = '06:34:00'; + scope.$digest(); + + expect(inputElm).toBeValid(); }); - it('should validate even if min value changes on-the-fly', function(done) { + it('should validate even if min value changes on-the-fly', function() { scope.min = '08:45:00'; compileInput(''); changeInputValueTo('06:15:00'); expect(inputElm).toBeInvalid(); - scope.min = '13:50:00'; - scope.$digest(function () { - expect(inputElm).toBeValid(); - done(); - }); + scope.min = '05:50:00'; + scope.$digest(); + + expect(inputElm).toBeValid(); }); }); From a17a1d5da69d2ba32b8df750659f341872720ba4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matias=20Niemel=C3=A4?= Date: Thu, 4 Sep 2014 10:21:17 -0400 Subject: [PATCH 4/5] fix(ngModel): properly parse min/max date values as strings Due to the nature of how date objects are rendered when JSON.stringify is called, the resulting string contains two sets of quotes surrounding it. This commit fixes that issue. Closes #6755 --- src/ng/directive/input.js | 14 +++++- test/ng/directive/inputSpec.js | 90 ++++++++++++++++++++++++++-------- 2 files changed, 82 insertions(+), 22 deletions(-) diff --git a/src/ng/directive/input.js b/src/ng/directive/input.js index aef4d1571229..0c8d21a4b336 100644 --- a/src/ng/directive/input.js +++ b/src/ng/directive/input.js @@ -11,6 +11,7 @@ var URL_REGEXP = /^(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?$/; var EMAIL_REGEXP = /^[a-z0-9!#$%&'*+\/=?^_`{|}~.-]+@[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$/i; var NUMBER_REGEXP = /^\s*(\-|\+)?(\d+|(\d*(\.\d*)))\s*$/; +var ISO_DATE_REGEXP = /\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d\.\d+([+-][0-2]\d:[0-5]\d|Z)/; var DATE_REGEXP = /^(\d{4})-(\d{2})-(\d{2})$/; var DATETIMELOCAL_REGEXP = /^(\d{4})-(\d\d)-(\d\d)T(\d\d):(\d\d)(?::(\d\d))?$/; var WEEK_REGEXP = /^(\d{4})-W(\d\d)$/; @@ -1036,6 +1037,15 @@ function createDateParser(regexp, mapping) { } if (isString(iso)) { + // When a date is JSON'ified to wraps itself inside of an extra + // set of double quotes. This makes the date parsing code unable + // to match the date string and parse it as a date. + if (iso.charAt(0) == '"' && iso.charAt(iso.length-1) == '"') { + iso = iso.substring(1, iso.length-1); + } + if (ISO_DATE_REGEXP.test(iso)) { + return new Date(iso); + } regexp.lastIndex = 0; parts = regexp.exec(iso); @@ -1082,7 +1092,7 @@ function createDateInputType(type, regexp, parseDate, format) { return ''; }); - if (attr.min || attr.ngMin) { + if (isDefined(attr.min) || attr.ngMin) { var minVal; ctrl.$validators.min = function(value) { return ctrl.$isEmpty(value) || isUndefined(minVal) || parseDate(value) >= minVal; @@ -1093,7 +1103,7 @@ function createDateInputType(type, regexp, parseDate, format) { }); } - if (attr.max || attr.ngMax) { + if (isDefined(attr.max) || attr.ngMax) { var maxVal; ctrl.$validators.max = function(value) { return ctrl.$isEmpty(value) || isUndefined(maxVal) || parseDate(value) <= maxVal; diff --git a/test/ng/directive/inputSpec.js b/test/ng/directive/inputSpec.js index 751172ac622d..e3c0d7a53fae 100644 --- a/test/ng/directive/inputSpec.js +++ b/test/ng/directive/inputSpec.js @@ -2491,7 +2491,7 @@ describe('input', function() { }); }); - it('should validate even if max value changes on-the-fly', function(done) { + it('should validate even if max value changes on-the-fly', function() { scope.max = '2013-01-01T01:02:00'; compileInput(''); @@ -2499,13 +2499,17 @@ describe('input', function() { expect(inputElm).toBeInvalid(); scope.max = '2001-01-01T01:02:00'; - scope.$digest(function () { - expect(inputElm).toBeValid(); - done(); - }); + scope.$digest(); + + expect(inputElm).toBeInvalid(); + + scope.max = '2024-01-01T01:02:00'; + scope.$digest(); + + expect(inputElm).toBeValid(); }); - it('should validate even if min value changes on-the-fly', function(done) { + it('should validate even if min value changes on-the-fly', function() { scope.min = '2013-01-01T01:02:00'; compileInput(''); @@ -2513,10 +2517,14 @@ describe('input', function() { expect(inputElm).toBeInvalid(); scope.min = '2014-01-01T01:02:00'; - scope.$digest(function () { - expect(inputElm).toBeValid(); - done(); - }); + scope.$digest(); + + expect(inputElm).toBeInvalid(); + + scope.min = '2009-01-01T01:02:00'; + scope.$digest(); + + expect(inputElm).toBeValid(); }); }); @@ -2837,6 +2845,23 @@ describe('input', function() { expect(+scope.value).toBe(+new Date(2000, 0, 1)); expect(scope.form.alias.$error.min).toBeFalsy(); }); + + it('should parse ISO-based date strings as a valid min date value', inject(function($rootScope) { + var scope = $rootScope.$new(); + var element = $compile('
' + + '' + + '
')(scope); + + var inputElm = element.find('input'); + + scope.value = new Date(2010, 1, 1, 0, 0, 0); + scope.min = new Date(2014, 10, 10, 0, 0, 0); + scope.$digest(); + + expect(scope.myForm.myControl.$error.min).toBeTruthy(); + + dealoc(element); + })); }); describe('max', function (){ @@ -2857,9 +2882,26 @@ describe('input', function() { expect(+scope.value).toBe(+new Date(2000, 0, 1)); expect(scope.form.alias.$error.max).toBeFalsy(); }); + + it('should parse ISO-based date strings as a valid max date value', inject(function($rootScope) { + var scope = $rootScope.$new(); + var element = $compile('
' + + '' + + '
')(scope); + + var inputElm = element.find('input'); + + scope.value = new Date(2020, 1, 1, 0, 0, 0); + scope.max = new Date(2014, 10, 10, 0, 0, 0); + scope.$digest(); + + expect(scope.myForm.myControl.$error.max).toBeTruthy(); + + dealoc(element); + })); }); - it('should validate even if max value changes on-the-fly', function(done) { + it('should validate even if max value changes on-the-fly', function() { scope.max = '2013-01-01'; compileInput(''); @@ -2867,13 +2909,17 @@ describe('input', function() { expect(inputElm).toBeInvalid(); scope.max = '2001-01-01'; - scope.$digest(function () { - expect(inputElm).toBeValid(); - done(); - }); + scope.$digest(); + + expect(inputElm).toBeInvalid(); + + scope.max = '2021-01-01'; + scope.$digest(); + + expect(inputElm).toBeValid(); }); - it('should validate even if min value changes on-the-fly', function(done) { + it('should validate even if min value changes on-the-fly', function() { scope.min = '2013-01-01'; compileInput(''); @@ -2881,10 +2927,14 @@ describe('input', function() { expect(inputElm).toBeInvalid(); scope.min = '2014-01-01'; - scope.$digest(function () { - expect(inputElm).toBeValid(); - done(); - }); + scope.$digest(); + + expect(inputElm).toBeInvalid(); + + scope.min = '2009-01-01'; + scope.$digest(); + + expect(inputElm).toBeValid(); }); }); From ee5988301b0e776250271bf7bbfaa0aaaea9ad57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matias=20Niemel=C3=A4?= Date: Thu, 4 Sep 2014 10:48:49 -0400 Subject: [PATCH 5/5] test(ngModel): add missing tests for ngMin/ngMax for date inputs --- test/ng/directive/inputSpec.js | 98 ++++++++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) diff --git a/test/ng/directive/inputSpec.js b/test/ng/directive/inputSpec.js index e3c0d7a53fae..2ddda2e6ea32 100644 --- a/test/ng/directive/inputSpec.js +++ b/test/ng/directive/inputSpec.js @@ -2526,6 +2526,42 @@ describe('input', function() { expect(inputElm).toBeValid(); }); + + it('should validate even if ng-max value changes on-the-fly', function() { + scope.max = '2013-01-01T01:02:00'; + compileInput(''); + + changeInputValueTo('2014-01-01T12:34:00'); + expect(inputElm).toBeInvalid(); + + scope.max = '2001-01-01T01:02:00'; + scope.$digest(); + + expect(inputElm).toBeInvalid(); + + scope.max = '2024-01-01T01:02:00'; + scope.$digest(); + + expect(inputElm).toBeValid(); + }); + + it('should validate even if ng-min value changes on-the-fly', function() { + scope.min = '2013-01-01T01:02:00'; + compileInput(''); + + changeInputValueTo('2010-01-01T12:34:00'); + expect(inputElm).toBeInvalid(); + + scope.min = '2014-01-01T01:02:00'; + scope.$digest(); + + expect(inputElm).toBeInvalid(); + + scope.min = '2009-01-01T01:02:00'; + scope.$digest(); + + expect(inputElm).toBeValid(); + }); }); describe('time', function () { @@ -2726,6 +2762,32 @@ describe('input', function() { expect(inputElm).toBeValid(); }); + + it('should validate even if ng-max value changes on-the-fly', function() { + scope.max = '4:02:00'; + compileInput(''); + + changeInputValueTo('05:34:00'); + expect(inputElm).toBeInvalid(); + + scope.max = '06:34:00'; + scope.$digest(); + + expect(inputElm).toBeValid(); + }); + + it('should validate even if ng-min value changes on-the-fly', function() { + scope.min = '08:45:00'; + compileInput(''); + + changeInputValueTo('06:15:00'); + expect(inputElm).toBeInvalid(); + + scope.min = '05:50:00'; + scope.$digest(); + + expect(inputElm).toBeValid(); + }); }); describe('date', function () { @@ -2936,6 +2998,42 @@ describe('input', function() { expect(inputElm).toBeValid(); }); + + it('should validate even if ng-max value changes on-the-fly', function() { + scope.max = '2013-01-01'; + compileInput(''); + + changeInputValueTo('2014-01-01'); + expect(inputElm).toBeInvalid(); + + scope.max = '2001-01-01'; + scope.$digest(); + + expect(inputElm).toBeInvalid(); + + scope.max = '2021-01-01'; + scope.$digest(); + + expect(inputElm).toBeValid(); + }); + + it('should validate even if ng-min value changes on-the-fly', function() { + scope.min = '2013-01-01'; + compileInput(''); + + changeInputValueTo('2010-01-01'); + expect(inputElm).toBeInvalid(); + + scope.min = '2014-01-01'; + scope.$digest(); + + expect(inputElm).toBeInvalid(); + + scope.min = '2009-01-01'; + scope.$digest(); + + expect(inputElm).toBeValid(); + }); }); describe('number', function() {