summaryrefslogtreecommitdiffstats
path: root/toolkit/content/tests/chrome/test_textbox_number.xul
blob: 369e9278512b02740649df98ac3b6b6f6fc7e9c2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
<!--
  XUL Widget Test for textbox type="number"
  -->
<window title="Textbox type='number' test" width="500" height="600"
        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
  <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>  
  <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>  

<hbox>
  <textbox id="n1" type="number" size="4"/>
  <textbox id="n2" type="number" value="10" min="5" max="15" wraparound="true"/>
</hbox>
<hbox>
  <textbox id="n3" type="number" size="4" value="25" min="1" max="12" increment="3"/>
</hbox>
<hbox>
  <textbox id="n4" type="number" size="4" value="-2" min="-8" max="18"/>
  <textbox id="n5" type="number" value="-17" min="-10" max="-3"/>
</hbox>
<hbox>
  <textbox id="n6" type="number" size="4" value="9" min="12" max="8"/>
</hbox>
<hbox>
  <textbox id="n7" type="number" size="4" value="4.678" min="2" max="10.5" decimalplaces="2"/>
  <textbox id="n8" type="number" hidespinbuttons="true"/>
</hbox>
<hbox>
  <textbox id="n9" type="number" size="4" oninput="updateInputEventCount();"/>
</hbox>

  <!-- test results are displayed in the html:body -->
  <body xmlns="http://www.w3.org/1999/xhtml" style="height: 300px; overflow: auto;"/>

  <!-- test code goes here -->
  <script type="application/javascript"><![CDATA[
SimpleTest.waitForExplicitFinish();

// ---- NOTE: the numbers used in these tests are carefully chosen to avoid
// ----       floating point rounding issues

function doTests() {
  var n1 = $("n1");
  var n2 = $("n2");
  var n3 = $("n3");
  var n4 = $("n4");
  var n5 = $("n5");
  var n6 = $("n6");
  var n7 = $("n7");

  testValsMinMax(n1, "initial n1", 0, 0, Infinity);
  testValsMinMax(n2, "initial n2", 10, 5, 15);
  testValsMinMax(n3, "initial n3", 12, 1, 12);
  testValsMinMax(n4, "initial n4", -2, -8, 18);
  testValsMinMax(n5, "initial n5", -10, -10, -3);
  testValsMinMax(n6, "initial n6", 12, 12, 12);
  testValsMinMax(n7, "initial n7", 4.68, 2, 10.5); // value should be rounded

  ok(n1.spinButtons != null && n1.spinButtons.localName == "spinbuttons", "spinButtons set");
  isnot(n1.decimalSymbol, "", "n1.decimalSymbol is set to something");
  n1.decimalSymbol = ".";
  SimpleTest.is(n1.decimalSymbol, ".", "n1.decimalSymbol set to '.'");
  SimpleTest.is(n1.wrapAround, false, "wrapAround defaults to false");
  SimpleTest.is(n1.increment, 1, "increment defaults to 1");
  SimpleTest.is(n1.decimalPlaces, 0, "decimalPlaces defaults to 0");

  SimpleTest.is(n2.wrapAround, true, "wrapAround when set to true");
  SimpleTest.is(n3.increment, 3, "increment when set to 1");
  SimpleTest.is(n7.decimalPlaces, 2, "decimalPlaces when set to 2");

  // test changing the value
  n1.value = "1700";
  testVals(n1, "set value,", 1700);
  n1.value = 1600;
  testVals(n1, "set value int,", 1600);
  n2.value = "2";
  testVals(n2, "set value below min,", 5);
  n2.value = 2;
  testVals(n2, "set value below min int,", 5);
  n2.value = 18;
  testVals(n2, "set value above max,", 15);
  n2.value = -6;
  testVals(n2, "set value below min negative,", 5);
  n5.value = -2;
  testVals(n5, "set value above max positive,", -3);
  n7.value = 5.999;
  testVals(n7, "set value to decimal,", 6, "6.00");
  n7.value = "1.42";
  testVals(n7, "set value to decimal below min,", 2.00, "2.00");
  n7.value = 24.1;
  testVals(n7, "set value to decimal above max,", 10.5, "10.50");
  n1.value = 4.75;
  testVals(n1, "set value to decimal round,", 5);

  // test changing the valueNumber
  n1.valueNumber = 27;
  testVals(n1, "set valueNumber,", 27);
  n2.valueNumber = 1;
  testVals(n2, "set valueNumber below min,", 5);
  n2.valueNumber = 77;
  testVals(n2, "set valueNumber above max,", 15);
  n2.valueNumber = -5;
  testVals(n2, "set valueNumber below min negative,", 5);
  n5.valueNumber = -8;
  n5.valueNumber = -1;
  testVals(n5, "set valueNumber above max positive,", -3);
  n7.valueNumber = 8.23;
  testVals(n7, "set valueNumber to decimal,", 8.23);
  n7.valueNumber = 0.77;
  testVals(n7, "set valueNumber to decimal below min,", 2.00, "2.00");
  n7.valueNumber = 29.157;
  testVals(n7, "set valueNumber to decimal above max,", 10.5, "10.50");
  n1.value = 8.9;
  testVals(n1, "set valueNumber to decimal round,", 9);

  // test changing the min
  n1.value = 6;
  n1.min = 8;
  testValsMinMax(n1, "set integer min,", 8, 8, Infinity);
  n7.value = 5.5;
  n7.min = 6.7;
  testValsMinMax(n7, "set decimal min,", 6.7, 6.7, 10.5, "6.70");

  // test changing the max
  n1.value = 25;
  n1.max = 22;
  testValsMinMax(n1, "set integer max,", 22, 8, 22);
  n7.value = 10.2;
  n7.max = 10.1;
  testValsMinMax(n7, "set decimal max,", 10.1, 6.7, 10.1, "10.10");

  // test decrease() and increase() methods
  testIncreaseDecrease(n1, "integer", 1, 0, 8, 22);
  testIncreaseDecrease(n7, "decimal", 1, 2, 6.7, 10.1);
  testIncreaseDecrease(n3, "integer with increment", 3, 0, 1, 12);

  n7.min = 2.7;
  n7.value = 10.1;
  n7.increment = 4.3;
  SimpleTest.is(n7.increment, 4.3, "increment changed");
  testIncreaseDecrease(n7, "integer with increment", 4.3, 2, 2.7, 10.1);

  n2.value = n2.min;
  n2.decrease();
  testVals(n2, "integer wraparound decrease method", n2.max);
  n2.increase();
  testVals(n2, "integer wraparound decrease method", n2.min);

  n7.wrapAround = true;
  SimpleTest.is(n7.wrapAround, true, "change wrapAround");
  n7.value = n7.min + 0.01;
  n7.decrease();
  testVals(n7, "decimal wraparound decrease method", n7.max, n7.max.toFixed(2));
  n7.increase();
  testVals(n7, "decimal wraparound decrease method", n7.min, n7.min.toFixed(2));

  n1.value = 22;
  n1.decimalPlaces = 3;
  testVals(n1, "set decimalPlaces 3", 22, "22.000");
  n1.value = 10.624;
  testVals(n1, "set decimalPlaces 3 set value,", 10.624);
  n1.decimalPlaces = 0;
  testVals(n1, "set decimalPlaces 0 set value,", 11);
  n1.decimalPlaces = Infinity;
  n1.value = 10.678123;
  testVals(n1, "set decimalPlaces Infinity set value,", 10.678123);

  n1.decimalSymbol = ",";
  SimpleTest.is(n1.decimalSymbol, ",", "n1.decimalSymbol set to ','");
  n1.value = "9.67";
  testVals(n1, "set decimalPlaces set value,", 9.67);

  n1.decimalSymbol = ".";
  SimpleTest.is(n1.decimalSymbol, ".", "n1.decimalSymbol set back to '.'");
  n1.decimalPlaces = 0;

  // UI tests
  n1.min = 5;
  n1.max = 15;
  n1.value = 5;
  n1.focus();

  var sb = n1.spinButtons;
  var sbbottom = sb.getBoundingClientRect().bottom - sb.getBoundingClientRect().top - 2;

  synthesizeKey("VK_UP", {});
  testVals(n1, "key up", 6);

  synthesizeKey("VK_DOWN", {});
  testVals(n1, "key down", 5);

  synthesizeMouse(sb, 2, 2, {});
  testVals(n1, "spinbuttons up", 6);
  synthesizeMouse(sb, 2, sbbottom, {});
  testVals(n1, "spinbuttons down", 5);

  n1.value = 15;
  synthesizeKey("VK_UP", {});
  testVals(n1, "key up at max", 15);
  synthesizeMouse(sb, 2, 2, {});
  testVals(n1, "spinbuttons up at max", 15);

  n1.value = 5;
  synthesizeKey("VK_DOWN", {});
  testVals(n1, "key down at min", 5);
  synthesizeMouse(sb, 2, sbbottom, {});
  testVals(n1, "spinbuttons down at min", 5);

  n1.wrapAround = true;
  n1.value = 15;
  synthesizeKey("VK_UP", {});
  testVals(n1, "key up wraparound at max", 5);
  n1.value = 5;
  synthesizeKey("VK_DOWN", {});
  testVals(n1, "key down wraparound at min", 15);

  n1.value = 15;
  synthesizeMouse(sb, 2, 2, {});
  testVals(n1, "spinbuttons up wraparound at max", 5);
  n1.value = 5;
  synthesizeMouse(sb, 2, sbbottom, {});
  testVals(n1, "spinbuttons down wraparound at min", 15);

  // check read only state
  n1.readOnly = true;
  n1.min = -10;
  n1.max = 15;
  n1.value = 12;
  // no events should fire and no changes should occur when the field is read only
  synthesizeKeyExpectEvent("VK_UP", { }, n1, "!change", "key up read only");
  is(n1.value, "12", "key up read only value");
  synthesizeKeyExpectEvent("VK_DOWN", { }, n1, "!change", "key down read only");
  is(n1.value, "12", "key down read only value");

  synthesizeMouseExpectEvent(sb, 2, 2, { }, n1, "!change", "mouse up read only");
  is(n1.value, "12", "mouse up read only value");
  synthesizeMouseExpectEvent(sb, 2, sbbottom, { }, n1, "!change", "mouse down read only");
  is(n1.value, "12", "mouse down read only value");

  n1.readOnly = false;
  n1.disabled = true;
  synthesizeMouseExpectEvent(sb, 2, 2, { }, n1, "!change", "mouse up disabled");
  is(n1.value, "12", "mouse up disabled value");
  synthesizeMouseExpectEvent(sb, 2, sbbottom, { }, n1, "!change", "mouse down disabled");
  is(n1.value, "12", "mouse down disabled value");

  var nsbrect = $("n8").spinButtons.getBoundingClientRect();
  ok(nsbrect.left == 0 && nsbrect.top == 0 && nsbrect.right == 0, nsbrect.bottom == 0,
     "hidespinbuttons");

  var n9 = $("n9");
  is(n9.value, "0", "initial value");
  n9.select();
  synthesizeKey("4", {});
  is(inputEventCount, 1, "input event count");
  is(inputEventValue, "4", "input value");
  is(n9.value, "4", "updated value");
  synthesizeKey("2", {});
  is(inputEventCount, 2, "input event count");
  is(inputEventValue, "42", "input value");
  is(n9.value, "42", "updated value");
  synthesizeKey("VK_BACK_SPACE", {});
  is(inputEventCount, 3, "input event count");
  is(inputEventValue, "4", "input value");
  is(n9.value, "4", "updated value");
  synthesizeKey("A", {accelKey: true});
  synthesizeKey("VK_DELETE", {});
  is(inputEventCount, 4, "input event count");
  is(inputEventValue, "0", "input value");
  is(n9.value, "0", "updated value");

  SimpleTest.finish();
}

var inputEventCount = 0;
var inputEventValue = null;
function updateInputEventCount() {
  inputEventValue = $("n9").value;
  inputEventCount++;
};

function testVals(nb, name, valueNumber, valueFieldNumber) {
  if (valueFieldNumber === undefined)
    valueFieldNumber = "" + valueNumber;

  SimpleTest.is(nb.value, "" + valueNumber, name + " value is '" + valueNumber + "'");
  SimpleTest.is(nb.valueNumber, valueNumber, name + " valueNumber is " + valueNumber);

  // This value format depends on the localized decimal symbol.
  var localizedValue = valueFieldNumber.replace(/\./, nb.decimalSymbol);
  SimpleTest.is(nb.inputField.value, localizedValue,
      name + " inputField value is '" + localizedValue + "'");
}

function testValsMinMax(nb, name, valueNumber, min, max, valueFieldNumber) {
  testVals(nb, name, valueNumber, valueFieldNumber);
  SimpleTest.is(nb.min, min, name + " min is " + min);
  SimpleTest.is(nb.max, max, name + " max is " + max);
}

function testIncreaseDecrease(nb, testid, increment, fixedCount, min, max)
{
  testid += " ";

  nb.value = max;
  nb.decrease();
  testVals(nb, testid + "decrease method", max - increment,
           (max - increment).toFixed(fixedCount));
  nb.increase();
  testVals(nb, testid + "increase method", max, max.toFixed(fixedCount));
  nb.value = min;
  nb.decrease();
  testVals(nb, testid + "decrease method at min", min, min.toFixed(fixedCount));
  nb.value = max;
  nb.increase();
  testVals(nb, testid + "increase method at max", max, max.toFixed(fixedCount));

  nb.focus();
  nb.value = min;

  // pressing the cursor up and down keys should adjust the value
  synthesizeKeyExpectEvent("VK_UP", { }, nb, "change", testid + "key up");
  is(nb.value, String(min + increment), testid + "key up");
  nb.value = max;
  synthesizeKeyExpectEvent("VK_UP", { }, nb, "!change", testid + "key up at max");
  is(nb.value, String(max), testid + "key up at max");
  synthesizeKeyExpectEvent("VK_DOWN", { }, nb, "change", testid + "key down");
  is(nb.value, String(max - increment), testid + "key down");
  nb.value = min;
  synthesizeKeyExpectEvent("VK_DOWN", { }, nb, "!change", testid + "key down at min");
  is(nb.value, String(min), testid + "key down at min");

  // check pressing the spinbutton arrows
  var sb = nb.spinButtons;
  var sbbottom = sb.getBoundingClientRect().bottom - sb.getBoundingClientRect().top - 2;
  nb.value = min;
  synthesizeMouseExpectEvent(sb, 2, 2, { }, nb, "change", testid + "mouse up");
  is(nb.value, String(min + increment), testid + "mouse up");
  nb.value = max;
  synthesizeMouseExpectEvent(sb, 2, 2, { }, nb, "!change", testid + "mouse up at max");
  synthesizeMouseExpectEvent(sb, 2, sbbottom, { }, nb, "change", testid + "mouse down");
  is(nb.value, String(max - increment), testid + "mouse down");
  nb.value = min;
  synthesizeMouseExpectEvent(sb, 2, sbbottom, { }, nb, "!change", testid + "mouse down at min");
}

SimpleTest.waitForFocus(doTests);

  ]]></script>

</window>