@@ -109,7 +109,65 @@ describe('ng-model', () {
109
109
}));
110
110
});
111
111
112
+ /* An input of type number can only have assigned to its [value] field
113
+ * a string that represents a valid number. Any attempts to assign
114
+ * any other string will have no effect on the [value] field.
115
+ *
116
+ * This function simulates typing the given string value into the input
117
+ * field regardless of whether it represents a valid number or not. It
118
+ * has the side-effect of setting the window focus to the input.
119
+ */
120
+ void setNumberInputValue (InputElement input, String value) {
121
+ input..focus ()
122
+ ..dispatchEvent (new TextEvent ('textInput' , data: value));
123
+ }
124
+
112
125
describe ('type="number" like' , () {
126
+
127
+ it ('should leave input unchanged when text does not represent a valid number' , inject ((Injector i) {
128
+ var modelFieldName = 'modelForNumFromInvalid1' ;
129
+ var element = _.compile ('<input type="number" ng-model="$modelFieldName ">' );
130
+ dom.querySelector ('body' ).append (element);
131
+
132
+ // Subcase: text not representing a valid number.
133
+ var piX = '3.141x' ;
134
+ setNumberInputValue (element, piX);
135
+ // Because the text is not a valid number, the element value is empty.
136
+ expect (element.value).toEqual ('' );
137
+ // But the selection can confirm that the text is there:
138
+ element.selectionStart = 0 ;
139
+ element.selectionEnd = piX.length;
140
+ expect (dom.window.getSelection ().toString ()).toEqual (piX);
141
+ // When the input is invalid, the model is [double.NAN]:
142
+ _.triggerEvent (element, 'change' );
143
+ expect (_.rootScope[modelFieldName].isNaN).toBeTruthy ();
144
+
145
+ // Subcase: text representing a valid number (as if the user had erased
146
+ // the trailing 'x').
147
+ num pi = 3.14159 ;
148
+ setNumberInputValue (element, pi.toString ());
149
+ _.triggerEvent (element, 'change' );
150
+ expect (element.value).toEqual (pi.toString ());
151
+ expect (_.rootScope[modelFieldName]).toEqual (pi);
152
+ }));
153
+
154
+ it ('should not reformat user input to equivalent numeric representation' , inject ((Injector i) {
155
+ var modelFieldName = 'modelForNumFromInvalid2' ;
156
+ var element = _.compile ('<input type="number" ng-model="$modelFieldName ">' );
157
+ dom.querySelector ('body' ).append (element);
158
+
159
+ var ten = '1e1' ;
160
+ setNumberInputValue (element, ten);
161
+ _.triggerEvent (element, 'change' );
162
+ expect (_.rootScope[modelFieldName]).toEqual (10 );
163
+ // Ensure that the input text is literally the same
164
+ element.selectionStart = 0 ;
165
+ // Set the selectionEnd to one beyond ten.length in
166
+ // case angular added some extra text.
167
+ element.selectionEnd = ten.length + 1 ;
168
+ expect (dom.window.getSelection ().toString ()).toEqual (ten);
169
+ }));
170
+
113
171
it ('should update input value from model' , inject (() {
114
172
_.compile ('<input type="number" ng-model="model">' );
115
173
_.rootScope.$digest ();
@@ -142,15 +200,15 @@ describe('ng-model', () {
142
200
expect (_.rootScope.model).toEqual (43 );
143
201
}));
144
202
145
- it ('should update model to null from a blank input value' , inject (() {
203
+ it ('should update model to NaN from a blank input value' , inject (() {
146
204
_.compile ('<input type="number" ng-model="model" probe="p">' );
147
205
Probe probe = _.rootScope.p;
148
206
var ngModel = probe.directive (NgModel );
149
207
InputElement inputElement = probe.element;
150
208
151
209
inputElement.value = '' ;
152
210
_.triggerEvent (inputElement, 'change' );
153
- expect (_.rootScope.model). toBeNull ();
211
+ expect (_.rootScope.model.isNaN). toBeTruthy ();
154
212
}));
155
213
156
214
it ('should update model from the input value for range inputs' , inject (() {
0 commit comments