@@ -2792,7 +2792,6 @@ describe('input', function() {
27922792 } ) ;
27932793
27942794 describe ( 'range' , function ( ) {
2795-
27962795 var scope ;
27972796
27982797 var rangeTestEl = angular . element ( '<input type="range">' ) ;
@@ -2859,7 +2858,6 @@ describe('input', function() {
28592858 expect ( scope . age ) . toBe ( 50 ) ;
28602859 expect ( inputElm ) . toBeValid ( ) ;
28612860 } ) ;
2862-
28632861 } else {
28642862
28652863 it ( 'should reset the model if view is invalid' , function ( ) {
@@ -3249,16 +3247,16 @@ describe('input', function() {
32493247 expect ( scope . value ) . toBe ( 40 ) ;
32503248 } ) ;
32513249 } ) ;
3252-
32533250 }
32543251
32553252
32563253 describe ( 'step' , function ( ) {
32573254
32583255 if ( supportsRange ) {
32593256 // Browsers that implement range will never allow you to set a value that doesn't match the step value
3260- // However, currently only Firefox fully inplements the spec when setting the value after the step value changes.
3257+ // However, currently only Firefox fully implements the spec when setting the value after the step value changes.
32613258 // Other browsers fail in various edge cases, which is why they are not tested here.
3259+
32623260 it ( 'should round the input value to the nearest step on user input' , function ( ) {
32633261 var inputElm = compileRangeInput ( 'ng-model="value" name="alias" step="5"' ) ;
32643262
@@ -3321,8 +3319,8 @@ describe('input', function() {
33213319 expect ( scope . value ) . toBe ( 10 ) ;
33223320 expect ( scope . form . alias . $error . step ) . toBeFalsy ( ) ;
33233321 } ) ;
3324-
33253322 } else {
3323+
33263324 it ( 'should validate if "range" is not implemented' , function ( ) {
33273325 scope . step = 10 ;
33283326 scope . value = 20 ;
@@ -3395,6 +3393,86 @@ describe('input', function() {
33953393 expect ( inputElm . val ( ) ) . toBe ( '10' ) ;
33963394 expect ( scope . form . alias . $error . step ) . toBeFalsy ( ) ;
33973395 } ) ;
3396+
3397+ it ( 'should use the correct "step base" when `[min]` is specified' , function ( ) {
3398+ $rootScope . min = 5 ;
3399+ $rootScope . step = 10 ;
3400+ $rootScope . value = 10 ;
3401+ var inputElm = compileRangeInput ( 'ng-model="value" min="{{min}}" step="{{step}}"' ) ;
3402+ var ngModel = inputElm . controller ( 'ngModel' ) ;
3403+
3404+ expect ( inputElm . val ( ) ) . toBe ( '10' ) ;
3405+ expect ( inputElm ) . toBeInvalid ( ) ;
3406+ expect ( ngModel . $error . step ) . toBe ( true ) ;
3407+ expect ( $rootScope . value ) . toBeUndefined ( ) ;
3408+
3409+ helper . changeInputValueTo ( '15' ) ;
3410+ expect ( inputElm ) . toBeValid ( ) ;
3411+ expect ( $rootScope . value ) . toBe ( 15 ) ;
3412+
3413+ $rootScope . $apply ( 'step = 3' ) ;
3414+ expect ( inputElm . val ( ) ) . toBe ( '15' ) ;
3415+ expect ( inputElm ) . toBeInvalid ( ) ;
3416+ expect ( ngModel . $error . step ) . toBe ( true ) ;
3417+ expect ( $rootScope . value ) . toBeUndefined ( ) ;
3418+
3419+ helper . changeInputValueTo ( '8' ) ;
3420+ expect ( inputElm ) . toBeValid ( ) ;
3421+ expect ( $rootScope . value ) . toBe ( 8 ) ;
3422+
3423+ $rootScope . $apply ( 'min = 10; step = 20; value = 30' ) ;
3424+ expect ( inputElm . val ( ) ) . toBe ( '30' ) ;
3425+ expect ( inputElm ) . toBeValid ( ) ;
3426+ expect ( $rootScope . value ) . toBe ( 30 ) ;
3427+
3428+ $rootScope . $apply ( 'min = 5' ) ;
3429+ expect ( inputElm . val ( ) ) . toBe ( '30' ) ;
3430+ expect ( inputElm ) . toBeInvalid ( ) ;
3431+ expect ( ngModel . $error . step ) . toBe ( true ) ;
3432+ expect ( $rootScope . value ) . toBeUndefined ( ) ;
3433+
3434+ $rootScope . $apply ( 'step = 0.00000001' ) ;
3435+ expect ( inputElm . val ( ) ) . toBe ( '30' ) ;
3436+ expect ( inputElm ) . toBeValid ( ) ;
3437+ expect ( $rootScope . value ) . toBe ( 30 ) ;
3438+
3439+ // 0.3 - 0.2 === 0.09999999999999998
3440+ $rootScope . $apply ( 'min = 0.2; step = 0.09999999999999998; value = 0.3' ) ;
3441+ expect ( inputElm . val ( ) ) . toBe ( '0.3' ) ;
3442+ expect ( inputElm ) . toBeInvalid ( ) ;
3443+ expect ( ngModel . $error . step ) . toBe ( true ) ;
3444+ expect ( $rootScope . value ) . toBeUndefined ( ) ;
3445+ } ) ;
3446+
3447+ it ( 'should correctly validate even in cases where the JS floating point arithmetic fails' ,
3448+ function ( ) {
3449+ var inputElm = compileRangeInput ( 'ng-model="value" step="0.1"' ) ;
3450+ var ngModel = inputElm . controller ( 'ngModel' ) ;
3451+
3452+ expect ( inputElm . val ( ) ) . toBe ( '' ) ;
3453+ expect ( inputElm ) . toBeValid ( ) ;
3454+ expect ( $rootScope . value ) . toBeUndefined ( ) ;
3455+
3456+ helper . changeInputValueTo ( '0.3' ) ;
3457+ expect ( inputElm ) . toBeValid ( ) ;
3458+ expect ( $rootScope . value ) . toBe ( 0.3 ) ;
3459+
3460+ helper . changeInputValueTo ( '2.9999999999999996' ) ;
3461+ expect ( inputElm ) . toBeInvalid ( ) ;
3462+ expect ( ngModel . $error . step ) . toBe ( true ) ;
3463+ expect ( $rootScope . value ) . toBeUndefined ( ) ;
3464+
3465+ // 0.5 % 0.1 === 0.09999999999999998
3466+ helper . changeInputValueTo ( '0.5' ) ;
3467+ expect ( inputElm ) . toBeValid ( ) ;
3468+ expect ( $rootScope . value ) . toBe ( 0.5 ) ;
3469+
3470+ // 3.5 % 0.1 === 0.09999999999999981
3471+ helper . changeInputValueTo ( '3.5' ) ;
3472+ expect ( inputElm ) . toBeValid ( ) ;
3473+ expect ( $rootScope . value ) . toBe ( 3.5 ) ;
3474+ }
3475+ ) ;
33983476 }
33993477 } ) ;
34003478
0 commit comments