+2015-11-02 Keith Rollin <krollin@apple.com>
+
+ input[type=number] does not increment/decrement integers with trailing decimal characters
+ https://bugs.webkit.org/show_bug.cgi?id=148867
+ rdar://problem/22589693
+
+ Reviewed by Chris Dumez.
+
+ New tests for input[type=number].skipUp/Down when .value ends in a
+ decimal point (with no additional trailing digits). Also some coverage
+ for input[type=range] which shares some same code.
+
+ * fast/forms/number/number-stepup-stepdown-expected.txt:
+ * fast/forms/number/number-stepup-stepdown-from-renderer-expected.txt:
+ * fast/forms/number/number-stepup-stepdown-from-renderer.html:
+ * fast/forms/number/number-stepup-stepdown.html:
+ * fast/forms/range/range-stepup-stepdown-expected.txt:
+ * fast/forms/range/range-stepup-stepdown-from-renderer-expected.txt:
+ * fast/forms/range/range-stepup-stepdown-from-renderer.html:
+ * fast/forms/range/range-stepup-stepdown.html:
+ * fast/forms/range/input-appearance-range-decimals-expected.html: Added
+ * fast/forms/range/input-appearance-range-decimals.html: Added
+
2015-11-02 Myles C. Maxfield <mmaxfield@apple.com>
[Cocoa] Fix tests
Number type
+
Invalid value
PASS stepUp("", null, null) threw exception Error: InvalidStateError: DOM Exception 11.
PASS stepDown("", null, null) threw exception Error: InvalidStateError: DOM Exception 11.
+
Non-number arguments
PASS stepUp("0", null, null, "0") is "0"
PASS stepDown("0", null, null, "0") is "0"
PASS stepDown("0", null, null, "foo") is "0"
PASS stepUp("0", null, null, null) is "0"
PASS stepDown("0", null, null, null) is "0"
+
Normal cases
PASS stepUp("0", null, null) is "1"
PASS stepUp("1", null, null, 2) is "3"
PASS stepDown("2", null, null) is "1"
PASS stepDown("1", null, null, 2) is "-1"
PASS stepDown("-1", null, null, -1) is "0"
+
+Fractional cases
+PASS stepUp("0.1", 1, null) is "1.1"
+PASS stepUp("0.2", 1, null) is "1.2"
+PASS stepUp("1.0", 1, null) is "2"
+PASS stepUp("1.1", 1, null) is "2.1"
+PASS stepUp("1.2", 1, null) is "2.2"
+PASS stepUp("2.0", 1, null) is "3"
+
+PASS stepUp("-0.1", 1, null) is "0.9"
+PASS stepUp("-0.2", 1, null) is "0.8"
+PASS stepUp("-1.0", 1, null) is "0"
+PASS stepUp("-1.1", 1, null) is "-0.1"
+PASS stepUp("-1.2", 1, null) is "-0.2"
+PASS stepUp("-2.0", 1, null) is "-1"
+
+PASS stepDown("0.1", 1, null) is "-0.9"
+PASS stepDown("0.2", 1, null) is "-0.8"
+PASS stepDown("1.0", 1, null) is "0"
+PASS stepDown("1.1", 1, null) is "0.1"
+PASS stepDown("1.2", 1, null) is "0.2"
+PASS stepDown("2.0", 1, null) is "1"
+
+PASS stepDown("-0.1", 1, null) is "-1.1"
+PASS stepDown("-0.2", 1, null) is "-1.2"
+PASS stepDown("-1.0", 1, null) is "-2"
+PASS stepDown("-1.1", 1, null) is "-2.1"
+PASS stepDown("-1.2", 1, null) is "-2.2"
+PASS stepDown("-2.0", 1, null) is "-3"
+
+PASS stepUp(".1", 1, null) is "1.1"
+PASS stepUp(".2", 1, null) is "1.2"
+PASS stepUp("1.", 1, null) is "2"
+PASS stepUp("2.", 1, null) is "3"
+
+PASS stepUp("-.1", 1, null) is "0.9"
+PASS stepUp("-.2", 1, null) is "0.8"
+PASS stepUp("-1.", 1, null) is "0"
+PASS stepUp("-2.", 1, null) is "-1"
+
+PASS stepDown(".1", 1, null) is "-0.9"
+PASS stepDown(".2", 1, null) is "-0.8"
+PASS stepDown("1.", 1, null) is "0"
+PASS stepDown("2.", 1, null) is "1"
+
+PASS stepDown("-.1", 1, null) is "-1.1"
+PASS stepDown("-.2", 1, null) is "-1.2"
+PASS stepDown("-1.", 1, null) is "-2"
+PASS stepDown("-2.", 1, null) is "-3"
+
+PASS stepUp("0.1", .1, null) is "0.2"
+PASS stepUp("0.2", .1, null) is "0.3"
+PASS stepUp("1.0", .1, null) is "1.1"
+PASS stepUp("1.1", .1, null) is "1.2"
+PASS stepUp("1.2", .1, null) is "1.3"
+PASS stepUp("2.0", .1, null) is "2.1"
+
+PASS stepUp("-0.1", .1, null) is "0"
+PASS stepUp("-0.2", .1, null) is "-0.1"
+PASS stepUp("-1.0", .1, null) is "-0.9"
+PASS stepUp("-1.1", .1, null) is "-1"
+PASS stepUp("-1.2", .1, null) is "-1.1"
+PASS stepUp("-2.0", .1, null) is "-1.9"
+
+PASS stepDown("0.1", .1, null) is "0"
+PASS stepDown("0.2", .1, null) is "0.1"
+PASS stepDown("1.0", .1, null) is "0.9"
+PASS stepDown("1.1", .1, null) is "1"
+PASS stepDown("1.2", .1, null) is "1.1"
+PASS stepDown("2.0", .1, null) is "1.9"
+
+PASS stepDown("-0.1", .1, null) is "-0.2"
+PASS stepDown("-0.2", .1, null) is "-0.3"
+PASS stepDown("-1.0", .1, null) is "-1.1"
+PASS stepDown("-1.1", .1, null) is "-1.2"
+PASS stepDown("-1.2", .1, null) is "-1.3"
+PASS stepDown("-2.0", .1, null) is "-2.1"
+
+PASS stepUp(".1", .1, null) is "0.2"
+PASS stepUp(".2", .1, null) is "0.3"
+PASS stepUp("1.", .1, null) is "1.1"
+PASS stepUp("2.", .1, null) is "2.1"
+
+PASS stepUp("-.1", .1, null) is "0"
+PASS stepUp("-.2", .1, null) is "-0.1"
+PASS stepUp("-1.", .1, null) is "-0.9"
+PASS stepUp("-2.", .1, null) is "-1.9"
+
+PASS stepDown(".1", .1, null) is "0"
+PASS stepDown(".2", .1, null) is "0.1"
+PASS stepDown("1.", .1, null) is "0.9"
+PASS stepDown("2.", .1, null) is "1.9"
+
+PASS stepDown("-.1", .1, null) is "-0.2"
+PASS stepDown("-.2", .1, null) is "-0.3"
+PASS stepDown("-1.", .1, null) is "-1.1"
+PASS stepDown("-2.", .1, null) is "-2.1"
+
Extra arguments
PASS input.value = "0"; input.min = null; input.step = null; input.stepUp(1, 2); input.value is "1"
PASS input.value = "1"; input.stepDown(1, 3); input.value is "0"
+
Invalid step value
PASS stepUp("0", "foo", null) is "1"
PASS stepUp("1", "0", null) is "2"
PASS stepUp("2", "-1", null) is "3"
+
Step=any
PASS stepUp("0", "any", null) threw exception Error: InvalidStateError: DOM Exception 11.
PASS stepDown("0", "any", null) threw exception Error: InvalidStateError: DOM Exception 11.
+
Step=any corner case
PASS stepUpExplicitBounds("0", "100", "any", "1.5", "1") threw exception Error: InvalidStateError: DOM Exception 11.
PASS stepDownExplicitBounds("0", "100", "any", "1.5", "1") threw exception Error: InvalidStateError: DOM Exception 11.
+
Overflow/underflow
PASS stepDown("1", "1", "0") is "0"
PASS stepDown("0", "1", "0") threw exception Error: InvalidStateError: DOM Exception 11.
PASS stepUp("-1", "1", "0", 2) threw exception Error: InvalidStateError: DOM Exception 11.
PASS input.value is "-1"
PASS stepUp("1", "3.40282346e+38", "", 2) threw exception Error: InvalidStateError: DOM Exception 11.
+
stepDown()/stepUp() for stepMismatch values
PASS stepUp("1", "2", "") is "3"
PASS input.stepDown(); input.value is "1"
PASS input.min = "0"; stepUp("9", "10", "", 9) is "99"
PASS stepDown("19", "10", "0") is "9"
PASS stepUp("89", "10", "99") is "99"
+
Huge value and small step
PASS input.min = ""; stepUp("1e+38", "1", "", 999999) is "1e+38"
PASS input.max = ""; stepDown("1e+38", "1", "", 999999) is "1e+38"
+
Fractional numbers
PASS input.min = ""; stepUp("0", "0.33333333333333333", "", 3) is "1"
PASS stepUp("1", "0.1", "", 10) is "2"
PASS input.stepUp(); input.stepUp(); input.stepUp(); input.stepUp(); input.stepUp(); input.stepUp(); input.stepUp(); input.stepUp(); input.stepUp(); input.stepUp(); input.value is "3"
PASS input.min = "0"; stepUp("0", "0.003921568627450980", "1", 255) is "1"
PASS for (var i = 0; i < 255; i++) { input.stepDown(); }; input.value is "0"
+
Rounding
PASS stepUp("5.005", "0.005", "", 2) is "5.015"
PASS stepUp("5.005", "0.005", "", 11) is "5.06"
PASS stepUpExplicitBounds("4", "9", "0.005", "5.005", 2) is "5.015"
PASS stepUpExplicitBounds("4", "9", "0.005", "5.005", 11) is "5.06"
PASS stepUpExplicitBounds("4", "9", "0.005", "5.005", 12) is "5.065"
+
PASS successfullyParsed is true
TEST COMPLETE
Number type
Function arguments are (value, step, {min or max}, [stepCount]).
+
Invalid value
PASS stepUp("", null, null) is "1"
PASS stepDown("", null, null) is "-1"
PASS stepDown("foo", "any", null) is "-1"
PASS stepUp("foo", "foo", null) is "1"
PASS stepDown("foo", "foo", null) is "-1"
+
Normal cases
PASS stepUp("0", null, null) is "1"
PASS stepUp("1", null, null, 2) is "3"
PASS stepDown("2", null, null) is "1"
PASS stepDown("1", null, null, 2) is "-1"
PASS stepDown("-1", null, null, -1) is "0"
+
+Fractional cases
+PASS stepUp("0.1", 1, null) is "1"
+PASS stepUp("0.2", 1, null) is "1"
+PASS stepUp("1.0", 1, null) is "2"
+PASS stepUp("1.1", 1, null) is "2"
+PASS stepUp("1.2", 1, null) is "2"
+PASS stepUp("2.0", 1, null) is "3"
+
+PASS stepUp("-0.1", 1, null) is "0"
+PASS stepUp("-0.2", 1, null) is "0"
+PASS stepUp("-1.0", 1, null) is "0"
+PASS stepUp("-1.1", 1, null) is "-1"
+PASS stepUp("-1.2", 1, null) is "-1"
+PASS stepUp("-2.0", 1, null) is "-1"
+
+PASS stepDown("0.1", 1, null) is "0"
+PASS stepDown("0.2", 1, null) is "0"
+PASS stepDown("1.0", 1, null) is "0"
+PASS stepDown("1.1", 1, null) is "1"
+PASS stepDown("1.2", 1, null) is "1"
+PASS stepDown("2.0", 1, null) is "1"
+
+PASS stepDown("-0.1", 1, null) is "-1"
+PASS stepDown("-0.2", 1, null) is "-1"
+PASS stepDown("-1.0", 1, null) is "-2"
+PASS stepDown("-1.1", 1, null) is "-2"
+PASS stepDown("-1.2", 1, null) is "-2"
+PASS stepDown("-2.0", 1, null) is "-3"
+
+PASS stepUp(".1", 1, null) is "1"
+PASS stepUp(".2", 1, null) is "1"
+PASS stepUp("1.", 1, null) is "2"
+PASS stepUp("2.", 1, null) is "3"
+
+PASS stepUp("-.1", 1, null) is "0"
+PASS stepUp("-.2", 1, null) is "0"
+PASS stepUp("-1.", 1, null) is "0"
+PASS stepUp("-2.", 1, null) is "-1"
+
+PASS stepDown(".1", 1, null) is "0"
+PASS stepDown(".2", 1, null) is "0"
+PASS stepDown("1.", 1, null) is "0"
+PASS stepDown("2.", 1, null) is "1"
+
+PASS stepDown("-.1", 1, null) is "-1"
+PASS stepDown("-.2", 1, null) is "-1"
+PASS stepDown("-1.", 1, null) is "-2"
+PASS stepDown("-2.", 1, null) is "-3"
+
+PASS stepUp("0.1", .1, null) is "0.2"
+PASS stepUp("0.2", .1, null) is "0.3"
+PASS stepUp("1.0", .1, null) is "1.1"
+PASS stepUp("1.1", .1, null) is "1.2"
+PASS stepUp("1.2", .1, null) is "1.3"
+PASS stepUp("2.0", .1, null) is "2.1"
+
+PASS stepUp("-0.1", .1, null) is "0"
+PASS stepUp("-0.2", .1, null) is "-0.1"
+PASS stepUp("-1.0", .1, null) is "-0.9"
+PASS stepUp("-1.1", .1, null) is "-1"
+PASS stepUp("-1.2", .1, null) is "-1.1"
+PASS stepUp("-2.0", .1, null) is "-1.9"
+
+PASS stepDown("0.1", .1, null) is "0"
+PASS stepDown("0.2", .1, null) is "0.1"
+PASS stepDown("1.0", .1, null) is "0.9"
+PASS stepDown("1.1", .1, null) is "1"
+PASS stepDown("1.2", .1, null) is "1.1"
+PASS stepDown("2.0", .1, null) is "1.9"
+
+PASS stepDown("-0.1", .1, null) is "-0.2"
+PASS stepDown("-0.2", .1, null) is "-0.3"
+PASS stepDown("-1.0", .1, null) is "-1.1"
+PASS stepDown("-1.1", .1, null) is "-1.2"
+PASS stepDown("-1.2", .1, null) is "-1.3"
+PASS stepDown("-2.0", .1, null) is "-2.1"
+
+PASS stepUp(".1", .1, null) is "0.2"
+PASS stepUp(".2", .1, null) is "0.3"
+PASS stepUp("1.", .1, null) is "1.1"
+PASS stepUp("2.", .1, null) is "2.1"
+
+PASS stepUp("-.1", .1, null) is "0"
+PASS stepUp("-.2", .1, null) is "-0.1"
+PASS stepUp("-1.", .1, null) is "-0.9"
+PASS stepUp("-2.", .1, null) is "-1.9"
+PASS stepDown(".1", .1, null) is "0"
+PASS stepDown(".2", .1, null) is "0.1"
+PASS stepDown("1.", .1, null) is "0.9"
+PASS stepDown("2.", .1, null) is "1.9"
+
+PASS stepDown("-.1", .1, null) is "-0.2"
+PASS stepDown("-.2", .1, null) is "-0.3"
+PASS stepDown("-1.", .1, null) is "-1.1"
+PASS stepDown("-2.", .1, null) is "-2.1"
+
Invalid step value
PASS stepUp("0", "foo", null) is "1"
PASS stepUp("1", "0", null) is "2"
PASS stepUp("2", "-1", null) is "3"
+
Step=any
PASS stepUp("0", "any", null) is "1"
PASS stepDown("0", "any", null) is "-1"
+
Step=any corner case
PASS stepUpExplicitBounds("0", "100", "any", "1.5", "1") is "2.5"
PASS stepDownExplicitBounds("0", "100", "any", "1.5", "1") is "0.5"
+
Overflow/underflow
PASS stepDown("1", "1", "0") is "0"
PASS stepDown("0", "1", "0") is "0"
PASS stepUp("0", "1", "0") is "0"
PASS stepUp("-1", "1", "0", 2) is "0"
PASS stepUp("1", "3.40282346e+38", "", 2) is "3.40282346e+38"
+
stepDown()/stepUp() for stepMismatch values
PASS stepUp("1", "2", "") is "2"
PASS input.min = "0"; stepUp("9", "10", "") is "10"
PASS stepUp("-7", "300", "") is "0"
PASS stepDown("7", "300", "") is "0"
PASS stepDown("-7", "300", "") is "-300"
+
Huge value and small step
PASS input.min = ""; stepUp("1e+38", "1", "", 999) is "1e+38"
PASS input.max = ""; stepDown("1e+38", "1", "", 999) is "1e+38"
+
Fractional numbers
PASS input.min = ""; stepUp("0", "0.33333333333333333", "", 3) is "1"
PASS stepUp("1", "0.1", "", 10) is "2"
PASS input.min = "0"; stepUp("0", "0.003921568627450980", "1", 255) is "1"
+
Rounding
PASS stepUp("5.005", "0.005", "", 2) is "5.015"
PASS stepUp("5.005", "0.005", "", 11) is "5.06"
debug('Number type');
input.type = 'number';
debug('Function arguments are (value, step, {min or max}, [stepCount]).');
+
+debug('');
debug('Invalid value');
shouldBe('stepUp("", null, null)', '"1"');
shouldBe('stepDown("", null, null)', '"-1"');
shouldBe('stepDown("foo", "any", null)', '"-1"');
shouldBe('stepUp("foo", "foo", null)', '"1"');
shouldBe('stepDown("foo", "foo", null)', '"-1"');
+
+debug('');
debug('Normal cases');
shouldBe('stepUp("0", null, null)', '"1"');
shouldBe('stepUp("1", null, null, 2)', '"3"');
shouldBe('stepDown("2", null, null)', '"1"');
shouldBe('stepDown("1", null, null, 2)', '"-1"');
shouldBe('stepDown("-1", null, null, -1)', '"0"');
+
+debug('');
+debug('Fractional cases')
+
+// Note: these tests also appear in number-stepup-stepdown.html. However, the
+// results here differ from the results there. According to:
+//
+// https://html.spec.whatwg.org/multipage/forms.html#number-state-(type=number)
+//
+// The browser is allowed to clamp resulting values to the nearest multiple of
+// the [step] value:
+//
+// When the element is suffering from a step mismatch, the user agent may
+// round the element's value to the nearest number for which the element
+// would not suffer from a step mismatch. If there are two such numbers,
+// user agents are encouraged to pick the one nearest positive infinity.
+//
+// WebKit seesm to perform this clamping when stepping from the UI, but not
+// from the API.
+//
+// See also the function comment for InputType::stepUpFromRenderer.
+
+// Base/model/template tests
+shouldBe('stepUp("0.1", 1, null)', '"1"') // Is 1.1 in non-render test
+shouldBe('stepUp("0.2", 1, null)', '"1"'); // Is 1.1 in non-render test
+shouldBe('stepUp("1.0", 1, null)', '"2"');
+shouldBe('stepUp("1.1", 1, null)', '"2"'); // Is 2.1 in non-render test
+shouldBe('stepUp("1.2", 1, null)', '"2"'); // Is 2.2 in non-render test
+shouldBe('stepUp("2.0", 1, null)', '"3"');
+
+debug('');
+// Same as above, but with negative numbers.
+shouldBe('stepUp("-0.1", 1, null)', '"0"'); // Is 0.9 in non-render test
+shouldBe('stepUp("-0.2", 1, null)', '"0"'); // Is 0.8 in non-render test
+shouldBe('stepUp("-1.0", 1, null)', '"0"');
+shouldBe('stepUp("-1.1", 1, null)', '"-1"'); // Is -0.1 in non-render test
+shouldBe('stepUp("-1.2", 1, null)', '"-1"'); // Is -0.2 in non-render test
+shouldBe('stepUp("-2.0", 1, null)', '"-1"');
+
+debug('');
+// Same as above, but stepping down rather than up.
+shouldBe('stepDown("0.1", 1, null)', '"0"'); // Is -0.9 in non-render test
+shouldBe('stepDown("0.2", 1, null)', '"0"'); // Is -0.8 in non-render test
+shouldBe('stepDown("1.0", 1, null)', '"0"');
+shouldBe('stepDown("1.1", 1, null)', '"1"'); // Is 0.1 in non-render test
+shouldBe('stepDown("1.2", 1, null)', '"1"'); // Is 0.2 in non-render test
+shouldBe('stepDown("2.0", 1, null)', '"1"');
+
+debug('');
+shouldBe('stepDown("-0.1", 1, null)', '"-1"'); // Is -1.1 in non-render test
+shouldBe('stepDown("-0.2", 1, null)', '"-1"'); // Is -1.2 in non-render test
+shouldBe('stepDown("-1.0", 1, null)', '"-2"');
+shouldBe('stepDown("-1.1", 1, null)', '"-2"'); // Is -2.1 in non-render test
+shouldBe('stepDown("-1.2", 1, null)', '"-2"'); // Is -2.2 in non-render test
+shouldBe('stepDown("-2.0", 1, null)', '"-3"');
+
+// Same as above, but with leading/trailing zeros removed.
+debug('');
+shouldBe('stepUp(".1", 1, null)', '"1"'); // Is 1.1 in non-render test
+shouldBe('stepUp(".2", 1, null)', '"1"'); // Is 1.2 in non-render test
+shouldBe('stepUp("1.", 1, null)', '"2"');
+shouldBe('stepUp("2.", 1, null)', '"3"');
+
+debug('');
+shouldBe('stepUp("-.1", 1, null)', '"0"'); // Is 0.9 in non-render test
+shouldBe('stepUp("-.2", 1, null)', '"0"'); // Is 0.8 in non-render test
+shouldBe('stepUp("-1.", 1, null)', '"0"');
+shouldBe('stepUp("-2.", 1, null)', '"-1"');
+
+debug('');
+shouldBe('stepDown(".1", 1, null)', '"0"'); // Is -0.9 in non-render test
+shouldBe('stepDown(".2", 1, null)', '"0"'); // Is -0.8 in non-render test
+shouldBe('stepDown("1.", 1, null)', '"0"');
+shouldBe('stepDown("2.", 1, null)', '"1"');
+
+debug('');
+shouldBe('stepDown("-.1", 1, null)', '"-1"'); // Is -1.1 in non-render test
+shouldBe('stepDown("-.2", 1, null)', '"-1"'); // Is -1.2 in non-render test
+shouldBe('stepDown("-1.", 1, null)', '"-2"');
+shouldBe('stepDown("-2.", 1, null)', '"-3"');
+
+// Same as above, but stepping by .1 rather than 1.
+debug('');
+shouldBe('stepUp("0.1", .1, null)', '"0.2"');
+shouldBe('stepUp("0.2", .1, null)', '"0.3"');
+shouldBe('stepUp("1.0", .1, null)', '"1.1"');
+shouldBe('stepUp("1.1", .1, null)', '"1.2"');
+shouldBe('stepUp("1.2", .1, null)', '"1.3"');
+shouldBe('stepUp("2.0", .1, null)', '"2.1"');
+
+debug('');
+shouldBe('stepUp("-0.1", .1, null)', '"0"');
+shouldBe('stepUp("-0.2", .1, null)', '"-0.1"');
+shouldBe('stepUp("-1.0", .1, null)', '"-0.9"');
+shouldBe('stepUp("-1.1", .1, null)', '"-1"');
+shouldBe('stepUp("-1.2", .1, null)', '"-1.1"');
+shouldBe('stepUp("-2.0", .1, null)', '"-1.9"');
+
+debug('');
+shouldBe('stepDown("0.1", .1, null)', '"0"');
+shouldBe('stepDown("0.2", .1, null)', '"0.1"');
+shouldBe('stepDown("1.0", .1, null)', '"0.9"');
+shouldBe('stepDown("1.1", .1, null)', '"1"');
+shouldBe('stepDown("1.2", .1, null)', '"1.1"');
+shouldBe('stepDown("2.0", .1, null)', '"1.9"');
+
+debug('');
+shouldBe('stepDown("-0.1", .1, null)', '"-0.2"');
+shouldBe('stepDown("-0.2", .1, null)', '"-0.3"');
+shouldBe('stepDown("-1.0", .1, null)', '"-1.1"');
+shouldBe('stepDown("-1.1", .1, null)', '"-1.2"');
+shouldBe('stepDown("-1.2", .1, null)', '"-1.3"');
+shouldBe('stepDown("-2.0", .1, null)', '"-2.1"');
+
+debug('');
+shouldBe('stepUp(".1", .1, null)', '"0.2"');
+shouldBe('stepUp(".2", .1, null)', '"0.3"');
+shouldBe('stepUp("1.", .1, null)', '"1.1"');
+shouldBe('stepUp("2.", .1, null)', '"2.1"');
+
+debug('');
+shouldBe('stepUp("-.1", .1, null)', '"0"');
+shouldBe('stepUp("-.2", .1, null)', '"-0.1"');
+shouldBe('stepUp("-1.", .1, null)', '"-0.9"');
+shouldBe('stepUp("-2.", .1, null)', '"-1.9"');
+
+shouldBe('stepDown(".1", .1, null)', '"0"');
+shouldBe('stepDown(".2", .1, null)', '"0.1"');
+shouldBe('stepDown("1.", .1, null)', '"0.9"');
+shouldBe('stepDown("2.", .1, null)', '"1.9"');
+
+debug('');
+shouldBe('stepDown("-.1", .1, null)', '"-0.2"');
+shouldBe('stepDown("-.2", .1, null)', '"-0.3"');
+shouldBe('stepDown("-1.", .1, null)', '"-1.1"');
+shouldBe('stepDown("-2.", .1, null)', '"-2.1"');
+
+debug('');
debug('Invalid step value');
shouldBe('stepUp("0", "foo", null)', '"1"');
shouldBe('stepUp("1", "0", null)', '"2"');
shouldBe('stepUp("2", "-1", null)', '"3"');
+
+debug('');
debug('Step=any');
shouldBe('stepUp("0", "any", null)', '"1"');
shouldBe('stepDown("0", "any", null)', '"-1"');
+
+debug('');
debug('Step=any corner case');
shouldBe('stepUpExplicitBounds("0", "100", "any", "1.5", "1")', '"2.5"');
shouldBe('stepDownExplicitBounds("0", "100", "any", "1.5", "1")', '"0.5"');
+
+debug('');
debug('Overflow/underflow');
shouldBe('stepDown("1", "1", "0")', '"0"');
shouldBe('stepDown("0", "1", "0")', '"0"');
shouldBe('stepUp("0", "1", "0")', '"0"');
shouldBe('stepUp("-1", "1", "0", 2)', '"0"');
shouldBe('stepUp("1", "3.40282346e+38", "", 2)', '"3.40282346e+38"');
+
+debug('');
debug('stepDown()/stepUp() for stepMismatch values');
shouldBe('stepUp("1", "2", "")', '"2"');
shouldBe('input.min = "0"; stepUp("9", "10", "")', '"10"');
shouldBe('stepUp("-7", "300", "")', '"0"');
shouldBe('stepDown("7", "300", "")', '"0"');
shouldBe('stepDown("-7", "300", "")', '"-300"');
+
+debug('');
debug('Huge value and small step');
shouldBe('input.min = ""; stepUp("1e+38", "1", "", 999)', '"1e+38"');
shouldBe('input.max = ""; stepDown("1e+38", "1", "", 999)', '"1e+38"');
+
+debug('');
debug('Fractional numbers');
shouldBe('input.min = ""; stepUp("0", "0.33333333333333333", "", 3)', '"1"');
shouldBe('stepUp("1", "0.1", "", 10)', '"2"');
shouldBe('input.min = "0"; stepUp("0", "0.003921568627450980", "1", 255)', '"1"');
+
+debug('');
debug('Rounding');
shouldBe('stepUp("5.005", "0.005", "", 2)', '"5.015"');
shouldBe('stepUp("5.005", "0.005", "", 11)', '"5.06"');
debug('Number type');
input.type = 'number';
+
+debug('');
debug('Invalid value');
shouldThrow('stepUp("", null, null)', invalidStateErr);
shouldThrow('stepDown("", null, null)', invalidStateErr);
+
+debug('');
debug('Non-number arguments');
shouldBe('stepUp("0", null, null, "0")', '"0"');
shouldBe('stepDown("0", null, null, "0")', '"0"');
shouldBe('stepDown("0", null, null, "foo")', '"0"');
shouldBe('stepUp("0", null, null, null)', '"0"');
shouldBe('stepDown("0", null, null, null)', '"0"');
+
+debug('');
debug('Normal cases');
shouldBe('stepUp("0", null, null)', '"1"');
shouldBe('stepUp("1", null, null, 2)', '"3"');
shouldBe('stepDown("2", null, null)', '"1"');
shouldBe('stepDown("1", null, null, 2)', '"-1"');
shouldBe('stepDown("-1", null, null, -1)', '"0"');
+
+debug('');
+debug('Fractional cases')
+// Base/model/template tests
+shouldBe('stepUp("0.1", 1, null)', '"1.1"');
+shouldBe('stepUp("0.2", 1, null)', '"1.2"');
+shouldBe('stepUp("1.0", 1, null)', '"2"');
+shouldBe('stepUp("1.1", 1, null)', '"2.1"');
+shouldBe('stepUp("1.2", 1, null)', '"2.2"');
+shouldBe('stepUp("2.0", 1, null)', '"3"');
+
+// Same as above, but with negative numbers.
+debug('');
+shouldBe('stepUp("-0.1", 1, null)', '"0.9"');
+shouldBe('stepUp("-0.2", 1, null)', '"0.8"');
+shouldBe('stepUp("-1.0", 1, null)', '"0"');
+shouldBe('stepUp("-1.1", 1, null)', '"-0.1"');
+shouldBe('stepUp("-1.2", 1, null)', '"-0.2"');
+shouldBe('stepUp("-2.0", 1, null)', '"-1"');
+
+// Same as above, but stepping down rather than up.
+debug('');
+shouldBe('stepDown("0.1", 1, null)', '"-0.9"');
+shouldBe('stepDown("0.2", 1, null)', '"-0.8"');
+shouldBe('stepDown("1.0", 1, null)', '"0"');
+shouldBe('stepDown("1.1", 1, null)', '"0.1"');
+shouldBe('stepDown("1.2", 1, null)', '"0.2"');
+shouldBe('stepDown("2.0", 1, null)', '"1"');
+
+debug('');
+shouldBe('stepDown("-0.1", 1, null)', '"-1.1"');
+shouldBe('stepDown("-0.2", 1, null)', '"-1.2"');
+shouldBe('stepDown("-1.0", 1, null)', '"-2"');
+shouldBe('stepDown("-1.1", 1, null)', '"-2.1"');
+shouldBe('stepDown("-1.2", 1, null)', '"-2.2"');
+shouldBe('stepDown("-2.0", 1, null)', '"-3"');
+
+// Same as above, but with leading/trailing zeros removed.
+debug('');
+shouldBe('stepUp(".1", 1, null)', '"1.1"');
+shouldBe('stepUp(".2", 1, null)', '"1.2"');
+shouldBe('stepUp("1.", 1, null)', '"2"');
+shouldBe('stepUp("2.", 1, null)', '"3"');
+
+debug('');
+shouldBe('stepUp("-.1", 1, null)', '"0.9"');
+shouldBe('stepUp("-.2", 1, null)', '"0.8"');
+shouldBe('stepUp("-1.", 1, null)', '"0"');
+shouldBe('stepUp("-2.", 1, null)', '"-1"');
+
+debug('');
+shouldBe('stepDown(".1", 1, null)', '"-0.9"');
+shouldBe('stepDown(".2", 1, null)', '"-0.8"');
+shouldBe('stepDown("1.", 1, null)', '"0"');
+shouldBe('stepDown("2.", 1, null)', '"1"');
+
+debug('');
+shouldBe('stepDown("-.1", 1, null)', '"-1.1"');
+shouldBe('stepDown("-.2", 1, null)', '"-1.2"');
+shouldBe('stepDown("-1.", 1, null)', '"-2"');
+shouldBe('stepDown("-2.", 1, null)', '"-3"');
+
+// Same as above, but stepping by .1 rather than 1.
+debug('');
+shouldBe('stepUp("0.1", .1, null)', '"0.2"');
+shouldBe('stepUp("0.2", .1, null)', '"0.3"');
+shouldBe('stepUp("1.0", .1, null)', '"1.1"');
+shouldBe('stepUp("1.1", .1, null)', '"1.2"');
+shouldBe('stepUp("1.2", .1, null)', '"1.3"');
+shouldBe('stepUp("2.0", .1, null)', '"2.1"');
+
+debug('');
+shouldBe('stepUp("-0.1", .1, null)', '"0"');
+shouldBe('stepUp("-0.2", .1, null)', '"-0.1"');
+shouldBe('stepUp("-1.0", .1, null)', '"-0.9"');
+shouldBe('stepUp("-1.1", .1, null)', '"-1"');
+shouldBe('stepUp("-1.2", .1, null)', '"-1.1"');
+shouldBe('stepUp("-2.0", .1, null)', '"-1.9"');
+
+debug('');
+shouldBe('stepDown("0.1", .1, null)', '"0"');
+shouldBe('stepDown("0.2", .1, null)', '"0.1"');
+shouldBe('stepDown("1.0", .1, null)', '"0.9"');
+shouldBe('stepDown("1.1", .1, null)', '"1"');
+shouldBe('stepDown("1.2", .1, null)', '"1.1"');
+shouldBe('stepDown("2.0", .1, null)', '"1.9"');
+
+debug('');
+shouldBe('stepDown("-0.1", .1, null)', '"-0.2"');
+shouldBe('stepDown("-0.2", .1, null)', '"-0.3"');
+shouldBe('stepDown("-1.0", .1, null)', '"-1.1"');
+shouldBe('stepDown("-1.1", .1, null)', '"-1.2"');
+shouldBe('stepDown("-1.2", .1, null)', '"-1.3"');
+shouldBe('stepDown("-2.0", .1, null)', '"-2.1"');
+
+debug('');
+shouldBe('stepUp(".1", .1, null)', '"0.2"');
+shouldBe('stepUp(".2", .1, null)', '"0.3"');
+shouldBe('stepUp("1.", .1, null)', '"1.1"');
+shouldBe('stepUp("2.", .1, null)', '"2.1"');
+
+debug('');
+shouldBe('stepUp("-.1", .1, null)', '"0"');
+shouldBe('stepUp("-.2", .1, null)', '"-0.1"');
+shouldBe('stepUp("-1.", .1, null)', '"-0.9"');
+shouldBe('stepUp("-2.", .1, null)', '"-1.9"');
+
+debug('');
+shouldBe('stepDown(".1", .1, null)', '"0"');
+shouldBe('stepDown(".2", .1, null)', '"0.1"');
+shouldBe('stepDown("1.", .1, null)', '"0.9"');
+shouldBe('stepDown("2.", .1, null)', '"1.9"');
+
+debug('');
+shouldBe('stepDown("-.1", .1, null)', '"-0.2"');
+shouldBe('stepDown("-.2", .1, null)', '"-0.3"');
+shouldBe('stepDown("-1.", .1, null)', '"-1.1"');
+shouldBe('stepDown("-2.", .1, null)', '"-2.1"');
+
+debug('');
debug('Extra arguments');
shouldBe('input.value = "0"; input.min = null; input.step = null; input.stepUp(1, 2); input.value', '"1"');
shouldBe('input.value = "1"; input.stepDown(1, 3); input.value', '"0"');
+
+debug('');
debug('Invalid step value');
shouldBe('stepUp("0", "foo", null)', '"1"');
shouldBe('stepUp("1", "0", null)', '"2"');
shouldBe('stepUp("2", "-1", null)', '"3"');
+
+debug('');
debug('Step=any');
shouldThrow('stepUp("0", "any", null)', invalidStateErr);
shouldThrow('stepDown("0", "any", null)', invalidStateErr);
+
+debug('');
debug('Step=any corner case');
shouldThrow('stepUpExplicitBounds("0", "100", "any", "1.5", "1")', invalidStateErr);
shouldThrow('stepDownExplicitBounds("0", "100", "any", "1.5", "1")', invalidStateErr);
+
+debug('');
debug('Overflow/underflow');
shouldBe('stepDown("1", "1", "0")', '"0"');
shouldThrow('stepDown("0", "1", "0")', invalidStateErr);
shouldThrow('stepUp("-1", "1", "0", 2)', invalidStateErr);
shouldBe('input.value', '"-1"');
shouldThrow('stepUp("1", "3.40282346e+38", "", 2)', invalidStateErr);
+
+debug('');
debug('stepDown()/stepUp() for stepMismatch values');
shouldBe('stepUp("1", "2", "")', '"3"');
shouldBe('input.stepDown(); input.value', '"1"');
shouldBe('input.min = "0"; stepUp("9", "10", "", 9)', '"99"');
shouldBe('stepDown("19", "10", "0")', '"9"');
shouldBe('stepUp("89", "10", "99")', '"99"');
+
+debug('');
debug('Huge value and small step');
shouldBe('input.min = ""; stepUp("1e+38", "1", "", 999999)', '"1e+38"');
shouldBe('input.max = ""; stepDown("1e+38", "1", "", 999999)', '"1e+38"');
+
+debug('');
debug('Fractional numbers');
shouldBe('input.min = ""; stepUp("0", "0.33333333333333333", "", 3)', '"1"');
shouldBe('stepUp("1", "0.1", "", 10)', '"2"');
shouldBe('input.stepUp(); input.stepUp(); input.stepUp(); input.stepUp(); input.stepUp(); input.stepUp(); input.stepUp(); input.stepUp(); input.stepUp(); input.stepUp(); input.value', '"3"');
shouldBe('input.min = "0"; stepUp("0", "0.003921568627450980", "1", 255)', '"1"');
shouldBe('for (var i = 0; i < 255; i++) { input.stepDown(); }; input.value', '"0"');
+
+debug('');
debug('Rounding');
shouldBe('stepUp("5.005", "0.005", "", 2)', '"5.015"');
shouldBe('stepUp("5.005", "0.005", "", 11)', '"5.06"');
shouldBe('stepUpExplicitBounds("4", "9", "0.005", "5.005", 2)', '"5.015"');
shouldBe('stepUpExplicitBounds("4", "9", "0.005", "5.005", 11)', '"5.06"');
shouldBe('stepUpExplicitBounds("4", "9", "0.005", "5.005", 12)', '"5.065"');
+
+debug('');
</script>
<script src="../../../resources/js-test-post.js"></script>
</body>
--- /dev/null
+<!DOCTYPE html>
+<body>
+<input type=range value="0.4" min="-0.4" max="1.0">
+<body>
+
--- /dev/null
+<!DOCTYPE html>
+<body>
+<!-- These numbers should parse the same as 0.4, -0.4, and 1.0 -->
+<input type=range value=".4" min="-.4" max="1.">
+<body>
+
Using the default values
PASS stepUpExplicitBounds(null, null, null, "") is "51"
PASS stepDownExplicitBounds(null, null, null, "") is "49"
+
Non-number arguments (stepCount)
PASS stepUpExplicitBounds(null, null, null, "0", "0") is "0"
PASS stepDownExplicitBounds(null, null, null, "0", "0") is "0"
PASS stepDownExplicitBounds(null, null, null, "0", "foo") is "0"
PASS stepUpExplicitBounds(null, null, null, "0", null) is "0"
PASS stepDownExplicitBounds(null, null, null, "0", null) is "0"
+
Normal cases
PASS stepUpExplicitBounds(null, null, null, "0") is "1"
PASS stepUpExplicitBounds(null, null, null, "1", 2) is "3"
PASS stepDownExplicitBounds("-100", null, null, "2") is "1"
PASS stepDownExplicitBounds("-100", null, null, "1", 2) is "-1"
PASS stepDownExplicitBounds("-100", null, null, "-1", -1) is "0"
+
+Fractional cases
+PASS stepUpExplicitBounds(-10, 10, 1, "0.1") is "1"
+PASS stepUpExplicitBounds(-10, 10, 1, "0.2") is "1"
+PASS stepUpExplicitBounds(-10, 10, 1, "1.0") is "2"
+PASS stepUpExplicitBounds(-10, 10, 1, "1.1") is "2"
+PASS stepUpExplicitBounds(-10, 10, 1, "1.2") is "2"
+PASS stepUpExplicitBounds(-10, 10, 1, "2.0") is "3"
+
+PASS stepUpExplicitBounds(-10, 10, 1, "-0.1") is "1"
+PASS stepUpExplicitBounds(-10, 10, 1, "-0.2") is "1"
+PASS stepUpExplicitBounds(-10, 10, 1, "-1.0") is "0"
+PASS stepUpExplicitBounds(-10, 10, 1, "-1.1") is "0"
+PASS stepUpExplicitBounds(-10, 10, 1, "-1.2") is "0"
+PASS stepUpExplicitBounds(-10, 10, 1, "-2.0") is "-1"
+
+PASS stepDownExplicitBounds(-10, 10, 1, "0.1") is "-1"
+PASS stepDownExplicitBounds(-10, 10, 1, "0.2") is "-1"
+PASS stepDownExplicitBounds(-10, 10, 1, "1.0") is "0"
+PASS stepDownExplicitBounds(-10, 10, 1, "1.1") is "0"
+PASS stepDownExplicitBounds(-10, 10, 1, "1.2") is "0"
+PASS stepDownExplicitBounds(-10, 10, 1, "2.0") is "1"
+
+PASS stepDownExplicitBounds(-10, 10, 1, "-0.1") is "-1"
+PASS stepDownExplicitBounds(-10, 10, 1, "-0.2") is "-1"
+PASS stepDownExplicitBounds(-10, 10, 1, "-1.0") is "-2"
+PASS stepDownExplicitBounds(-10, 10, 1, "-1.1") is "-2"
+PASS stepDownExplicitBounds(-10, 10, 1, "-1.2") is "-2"
+PASS stepDownExplicitBounds(-10, 10, 1, "-2.0") is "-3"
+
+PASS stepUpExplicitBounds(-10, 10, 1, ".1") is "1"
+PASS stepUpExplicitBounds(-10, 10, 1, ".2") is "1"
+PASS stepUpExplicitBounds(-10, 10, 1, "1.") is "2"
+PASS stepUpExplicitBounds(-10, 10, 1, "2.") is "3"
+
+PASS stepUpExplicitBounds(-10, 10, 1, "-.1") is "1"
+PASS stepUpExplicitBounds(-10, 10, 1, "-.2") is "1"
+PASS stepUpExplicitBounds(-10, 10, 1, "-1.") is "0"
+PASS stepUpExplicitBounds(-10, 10, 1, "-2.") is "-1"
+
+PASS stepDownExplicitBounds(-10, 10, 1, ".1") is "-1"
+PASS stepDownExplicitBounds(-10, 10, 1, ".2") is "-1"
+PASS stepDownExplicitBounds(-10, 10, 1, "1.") is "0"
+PASS stepDownExplicitBounds(-10, 10, 1, "2.") is "1"
+
+PASS stepDownExplicitBounds(-10, 10, 1, "-.1") is "-1"
+PASS stepDownExplicitBounds(-10, 10, 1, "-.2") is "-1"
+PASS stepDownExplicitBounds(-10, 10, 1, "-1.") is "-2"
+PASS stepDownExplicitBounds(-10, 10, 1, "-2.") is "-3"
+
+PASS stepUpExplicitBounds(-10, 10, .1, "0.1") is "0.2"
+PASS stepUpExplicitBounds(-10, 10, .1, "0.2") is "0.3"
+PASS stepUpExplicitBounds(-10, 10, .1, "1.0") is "1.1"
+PASS stepUpExplicitBounds(-10, 10, .1, "1.1") is "1.2"
+PASS stepUpExplicitBounds(-10, 10, .1, "1.2") is "1.3"
+PASS stepUpExplicitBounds(-10, 10, .1, "2.0") is "2.1"
+
+PASS stepUpExplicitBounds(-10, 10, .1, "-0.1") is "0"
+PASS stepUpExplicitBounds(-10, 10, .1, "-0.2") is "-0.1"
+PASS stepUpExplicitBounds(-10, 10, .1, "-1.0") is "-0.9"
+PASS stepUpExplicitBounds(-10, 10, .1, "-1.1") is "-1"
+PASS stepUpExplicitBounds(-10, 10, .1, "-1.2") is "-1.1"
+PASS stepUpExplicitBounds(-10, 10, .1, "-2.0") is "-1.9"
+
+PASS stepDownExplicitBounds(-10, 10, .1, "0.1") is "0"
+PASS stepDownExplicitBounds(-10, 10, .1, "0.2") is "0.1"
+PASS stepDownExplicitBounds(-10, 10, .1, "1.0") is "0.9"
+PASS stepDownExplicitBounds(-10, 10, .1, "1.1") is "1"
+PASS stepDownExplicitBounds(-10, 10, .1, "1.2") is "1.1"
+PASS stepDownExplicitBounds(-10, 10, .1, "2.0") is "1.9"
+
+PASS stepDownExplicitBounds(-10, 10, .1, "-0.1") is "-0.2"
+PASS stepDownExplicitBounds(-10, 10, .1, "-0.2") is "-0.3"
+PASS stepDownExplicitBounds(-10, 10, .1, "-1.0") is "-1.1"
+PASS stepDownExplicitBounds(-10, 10, .1, "-1.1") is "-1.2"
+PASS stepDownExplicitBounds(-10, 10, .1, "-1.2") is "-1.3"
+PASS stepDownExplicitBounds(-10, 10, .1, "-2.0") is "-2.1"
+
+PASS stepUpExplicitBounds(-10, 10, .1, ".1") is "0.2"
+PASS stepUpExplicitBounds(-10, 10, .1, ".2") is "0.3"
+PASS stepUpExplicitBounds(-10, 10, .1, "1.") is "1.1"
+PASS stepUpExplicitBounds(-10, 10, .1, "2.") is "2.1"
+
+PASS stepUpExplicitBounds(-10, 10, .1, "-.1") is "0"
+PASS stepUpExplicitBounds(-10, 10, .1, "-.2") is "-0.1"
+PASS stepUpExplicitBounds(-10, 10, .1, "-1.") is "-0.9"
+PASS stepUpExplicitBounds(-10, 10, .1, "-2.") is "-1.9"
+
+PASS stepDownExplicitBounds(-10, 10, .1, ".1") is "0"
+PASS stepDownExplicitBounds(-10, 10, .1, ".2") is "0.1"
+PASS stepDownExplicitBounds(-10, 10, .1, "1.") is "0.9"
+PASS stepDownExplicitBounds(-10, 10, .1, "2.") is "1.9"
+
+PASS stepDownExplicitBounds(-10, 10, .1, "-.1") is "-0.2"
+PASS stepDownExplicitBounds(-10, 10, .1, "-.2") is "-0.3"
+PASS stepDownExplicitBounds(-10, 10, .1, "-1.") is "-1.1"
+PASS stepDownExplicitBounds(-10, 10, .1, "-2.") is "-2.1"
+
Extra arguments
PASS setInputAttributes(null, null, null, "0"); input.stepUp(1,2); input.value is "1"
PASS setInputAttributes(null, null, null, "1"); input.stepDown(1,3); input.value is "0"
+
Invalid step value
PASS stepUpExplicitBounds(null, null, "foo", "0") is "1"
PASS stepUpExplicitBounds(null, null, "0", "1") is "2"
PASS stepDownExplicitBounds(null, null, "foo", "1") is "0"
PASS stepDownExplicitBounds(null, null, "0", "2") is "1"
PASS stepDownExplicitBounds(null, null, "-1", "3") is "2"
+
Step=any
PASS stepUpExplicitBounds(null, null, "any", "1") threw exception Error: InvalidStateError: DOM Exception 11.
PASS stepDownExplicitBounds(null, null, "any", "1") threw exception Error: InvalidStateError: DOM Exception 11.
+
Overflow/underflow
PASS stepUpExplicitBounds(null, "100", "1", "99") is "100"
PASS stepUpExplicitBounds(null, "100", "1", "100") threw exception Error: InvalidStateError: DOM Exception 11.
PASS stepUpExplicitBounds(-100, 0, 1, -1, 2) threw exception Error: InvalidStateError: DOM Exception 11.
PASS input.value is "-1"
PASS stepUpExplicitBounds(null, null, "3.40282346e+38", "1", "2") threw exception Error: InvalidStateError: DOM Exception 11.
+
stepDown()/stepUp() for stepMismatch values
PASS stepUpExplicitBounds(null, null, 2, 1) is "4"
PASS input.stepDown(); input.value is "2"
PASS stepUpExplicitBounds(0, null, 10, 9, 9) is "100"
PASS stepDownExplicitBounds(0, null, 10, 19) is "10"
+
value + step is <= max, but rounded result would be > max.
PASS stepUpExplicitBounds(null, 99, 10, 89) threw exception Error: InvalidStateError: DOM Exception 11.
+
Huge value and small step
PASS stepUpExplicitBounds(0, 1e38, 1, 1e38, 999999) is "1e+38"
PASS stepDownExplicitBounds(0, 1e38, 1, 1e38, 999999) is "1e+38"
+
Fractional numbers
PASS stepUpExplicitBounds(null, null, 0.33333333333333333, 0, 3) is "1"
PASS stepUpExplicitBounds(null, null, 0.1, 1) is "1.1"
PASS for (var i = 0; i < 255; i++) { input.stepDown(); }; input.value is "0"
PASS stepDownExplicitBounds(null, null, 0.1, 1, 8) is "0.2"
PASS stepDownExplicitBounds(null, null, 0.1, 1) is "0.9"
+
PASS successfullyParsed is true
TEST COMPLETE
PASS stepDownExplicitBounds(null, null, "any", "foo") is "49"
PASS stepUpExplicitBounds(null, null, "foo", "foo") is "51"
PASS stepDownExplicitBounds(null, null, "foo", "foo") is "49"
+
Normal cases
PASS stepUpExplicitBounds(null, null, null, "0") is "1"
PASS stepUpExplicitBounds(null, null, null, "1", 2) is "3"
PASS stepDownExplicitBounds("-100", null, null, "2") is "1"
PASS stepDownExplicitBounds("-100", null, null, "1", 2) is "-1"
PASS stepDownExplicitBounds("-100", null, null, "-1", -1) is "0"
+
+Fractional cases
+PASS stepUpExplicitBounds(-10, 10, 1, "0.1") is "1"
+PASS stepUpExplicitBounds(-10, 10, 1, "0.2") is "1"
+PASS stepUpExplicitBounds(-10, 10, 1, "1.0") is "2"
+PASS stepUpExplicitBounds(-10, 10, 1, "1.1") is "2"
+PASS stepUpExplicitBounds(-10, 10, 1, "1.2") is "2"
+PASS stepUpExplicitBounds(-10, 10, 1, "2.0") is "3"
+
+PASS stepUpExplicitBounds(-10, 10, 1, "-0.1") is "1"
+PASS stepUpExplicitBounds(-10, 10, 1, "-0.2") is "1"
+PASS stepUpExplicitBounds(-10, 10, 1, "-1.0") is "0"
+PASS stepUpExplicitBounds(-10, 10, 1, "-1.1") is "0"
+PASS stepUpExplicitBounds(-10, 10, 1, "-1.2") is "0"
+PASS stepUpExplicitBounds(-10, 10, 1, "-2.0") is "-1"
+
+PASS stepDownExplicitBounds(-10, 10, 1, "0.1") is "-1"
+PASS stepDownExplicitBounds(-10, 10, 1, "0.2") is "-1"
+PASS stepDownExplicitBounds(-10, 10, 1, "1.0") is "0"
+PASS stepDownExplicitBounds(-10, 10, 1, "1.1") is "0"
+PASS stepDownExplicitBounds(-10, 10, 1, "1.2") is "0"
+PASS stepDownExplicitBounds(-10, 10, 1, "2.0") is "1"
+
+PASS stepDownExplicitBounds(-10, 10, 1, "-0.1") is "-1"
+PASS stepDownExplicitBounds(-10, 10, 1, "-0.2") is "-1"
+PASS stepDownExplicitBounds(-10, 10, 1, "-1.0") is "-2"
+PASS stepDownExplicitBounds(-10, 10, 1, "-1.1") is "-2"
+PASS stepDownExplicitBounds(-10, 10, 1, "-1.2") is "-2"
+PASS stepDownExplicitBounds(-10, 10, 1, "-2.0") is "-3"
+
+PASS stepUpExplicitBounds(-10, 10, 1, ".1") is "1"
+PASS stepUpExplicitBounds(-10, 10, 1, ".2") is "1"
+PASS stepUpExplicitBounds(-10, 10, 1, "1.") is "2"
+PASS stepUpExplicitBounds(-10, 10, 1, "2.") is "3"
+
+PASS stepUpExplicitBounds(-10, 10, 1, "-.1") is "1"
+PASS stepUpExplicitBounds(-10, 10, 1, "-.2") is "1"
+PASS stepUpExplicitBounds(-10, 10, 1, "-1.") is "0"
+PASS stepUpExplicitBounds(-10, 10, 1, "-2.") is "-1"
+
+PASS stepDownExplicitBounds(-10, 10, 1, ".1") is "-1"
+PASS stepDownExplicitBounds(-10, 10, 1, ".2") is "-1"
+PASS stepDownExplicitBounds(-10, 10, 1, "1.") is "0"
+PASS stepDownExplicitBounds(-10, 10, 1, "2.") is "1"
+
+PASS stepDownExplicitBounds(-10, 10, 1, "-.1") is "-1"
+PASS stepDownExplicitBounds(-10, 10, 1, "-.2") is "-1"
+PASS stepDownExplicitBounds(-10, 10, 1, "-1.") is "-2"
+PASS stepDownExplicitBounds(-10, 10, 1, "-2.") is "-3"
+
+PASS stepUpExplicitBounds(-10, 10, .1, "0.1") is "0.2"
+PASS stepUpExplicitBounds(-10, 10, .1, "0.2") is "0.3"
+PASS stepUpExplicitBounds(-10, 10, .1, "1.0") is "1.1"
+PASS stepUpExplicitBounds(-10, 10, .1, "1.1") is "1.2"
+PASS stepUpExplicitBounds(-10, 10, .1, "1.2") is "1.3"
+PASS stepUpExplicitBounds(-10, 10, .1, "2.0") is "2.1"
+
+PASS stepUpExplicitBounds(-10, 10, .1, "-0.1") is "0"
+PASS stepUpExplicitBounds(-10, 10, .1, "-0.2") is "-0.1"
+PASS stepUpExplicitBounds(-10, 10, .1, "-1.0") is "-0.9"
+PASS stepUpExplicitBounds(-10, 10, .1, "-1.1") is "-1"
+PASS stepUpExplicitBounds(-10, 10, .1, "-1.2") is "-1.1"
+PASS stepUpExplicitBounds(-10, 10, .1, "-2.0") is "-1.9"
+
+PASS stepDownExplicitBounds(-10, 10, .1, "0.1") is "0"
+PASS stepDownExplicitBounds(-10, 10, .1, "0.2") is "0.1"
+PASS stepDownExplicitBounds(-10, 10, .1, "1.0") is "0.9"
+PASS stepDownExplicitBounds(-10, 10, .1, "1.1") is "1"
+PASS stepDownExplicitBounds(-10, 10, .1, "1.2") is "1.1"
+PASS stepDownExplicitBounds(-10, 10, .1, "2.0") is "1.9"
+
+PASS stepDownExplicitBounds(-10, 10, .1, "-0.1") is "-0.2"
+PASS stepDownExplicitBounds(-10, 10, .1, "-0.2") is "-0.3"
+PASS stepDownExplicitBounds(-10, 10, .1, "-1.0") is "-1.1"
+PASS stepDownExplicitBounds(-10, 10, .1, "-1.1") is "-1.2"
+PASS stepDownExplicitBounds(-10, 10, .1, "-1.2") is "-1.3"
+PASS stepDownExplicitBounds(-10, 10, .1, "-2.0") is "-2.1"
+
+PASS stepUpExplicitBounds(-10, 10, .1, ".1") is "0.2"
+PASS stepUpExplicitBounds(-10, 10, .1, ".2") is "0.3"
+PASS stepUpExplicitBounds(-10, 10, .1, "1.") is "1.1"
+PASS stepUpExplicitBounds(-10, 10, .1, "2.") is "2.1"
+
+PASS stepUpExplicitBounds(-10, 10, .1, "-.1") is "0"
+PASS stepUpExplicitBounds(-10, 10, .1, "-.2") is "-0.1"
+PASS stepUpExplicitBounds(-10, 10, .1, "-1.") is "-0.9"
+PASS stepUpExplicitBounds(-10, 10, .1, "-2.") is "-1.9"
+PASS stepDownExplicitBounds(-10, 10, .1, ".1") is "0"
+PASS stepDownExplicitBounds(-10, 10, .1, ".2") is "0.1"
+PASS stepDownExplicitBounds(-10, 10, .1, "1.") is "0.9"
+PASS stepDownExplicitBounds(-10, 10, .1, "2.") is "1.9"
+
+PASS stepDownExplicitBounds(-10, 10, .1, "-.1") is "-0.2"
+PASS stepDownExplicitBounds(-10, 10, .1, "-.2") is "-0.3"
+PASS stepDownExplicitBounds(-10, 10, .1, "-1.") is "-1.1"
+PASS stepDownExplicitBounds(-10, 10, .1, "-2.") is "-2.1"
+
Invalid step value
PASS stepUpExplicitBounds(null, null, "foo", "0") is "1"
PASS stepUpExplicitBounds(null, null, "0", "1") is "2"
PASS stepDownExplicitBounds(null, null, "foo", "1") is "0"
PASS stepDownExplicitBounds(null, null, "0", "2") is "1"
PASS stepDownExplicitBounds(null, null, "-1", "3") is "2"
+
Step=any
PASS stepUpExplicitBounds(null, null, "any", "1") is "2"
PASS stepDownExplicitBounds(null, null, "any", "1") is "0"
+
Overflow/underflow
PASS stepUpExplicitBounds(null, "100", "1", "99") is "100"
PASS stepUpExplicitBounds(null, "100", "1", "100") is "100"
PASS stepUpExplicitBounds(null, 0, 1, 0) is "0"
PASS stepUpExplicitBounds(-100, 0, 1, -1, 2) is "0"
PASS stepUpExplicitBounds(null, null, "3.40282346e+38", "1", 2) is "0"
+
stepDown()/stepUp() for stepMismatch values
PASS stepUpExplicitBounds(null, null, 2, 1) is "4"
PASS stepUpExplicitBounds(0, null, 10, 9, 9) is "100"
PASS stepDownExplicitBounds(0, null, 10, 19) is "10"
+
value + step is <= max, but rounded result would be > max.
PASS stepUpExplicitBounds(null, 99, 10, 89) is "90"
+
Huge value and small step
PASS stepUpExplicitBounds(0, 1e38, 1, 1e38, 999) is "1e+38"
PASS stepDownExplicitBounds(0, 1e38, 1, 1e38, 999) is "1e+38"
+
Fractional numbers
PASS stepUpExplicitBounds(null, null, 0.33333333333333333, 0, 3) is "1"
PASS stepUpExplicitBounds(null, null, 0.1, 1) is "1.1"
shouldBe('stepDownExplicitBounds(null, null, "any", "foo")', '"49"');
shouldBe('stepUpExplicitBounds(null, null, "foo", "foo")', '"51"');
shouldBe('stepDownExplicitBounds(null, null, "foo", "foo")', '"49"');
+
+debug('');
debug('Normal cases');
shouldBe('stepUpExplicitBounds(null, null, null, "0")', '"1"');
shouldBe('stepUpExplicitBounds(null, null, null, "1", 2)', '"3"');
shouldBe('stepDownExplicitBounds("-100", null, null, "2")', '"1"');
shouldBe('stepDownExplicitBounds("-100", null, null, "1", 2)', '"-1"');
shouldBe('stepDownExplicitBounds("-100", null, null, "-1", -1)', '"0"');
+
+
+debug('');
+debug('Fractional cases')
+// "When the element is suffering from a step mismatch, the user agent must
+// round the element's value to the nearest number for which the element would
+// not suffer from a step mismatch, and which is greater than or equal to the
+// minimum, and, if the maximum is not less than the minimum, which is less
+// than or equal to the maximum, if there is a number that matches these
+// constraints. If two numbers match these constraints, then user agents must
+// use the one nearest to positive infinity.""
+
+// Base/model/template tests
+shouldBe('stepUpExplicitBounds(-10, 10, 1, "0.1")', '"1"');
+shouldBe('stepUpExplicitBounds(-10, 10, 1, "0.2")', '"1"');
+shouldBe('stepUpExplicitBounds(-10, 10, 1, "1.0")', '"2"');
+shouldBe('stepUpExplicitBounds(-10, 10, 1, "1.1")', '"2"');
+shouldBe('stepUpExplicitBounds(-10, 10, 1, "1.2")', '"2"');
+shouldBe('stepUpExplicitBounds(-10, 10, 1, "2.0")', '"3"');
+
+// Same as above, but with negative numbers.
+debug('');
+shouldBe('stepUpExplicitBounds(-10, 10, 1, "-0.1")', '"1"');
+shouldBe('stepUpExplicitBounds(-10, 10, 1, "-0.2")', '"1"');
+shouldBe('stepUpExplicitBounds(-10, 10, 1, "-1.0")', '"0"');
+shouldBe('stepUpExplicitBounds(-10, 10, 1, "-1.1")', '"0"');
+shouldBe('stepUpExplicitBounds(-10, 10, 1, "-1.2")', '"0"');
+shouldBe('stepUpExplicitBounds(-10, 10, 1, "-2.0")', '"-1"');
+
+// Same as above, but stepping down rather than up.
+debug('');
+shouldBe('stepDownExplicitBounds(-10, 10, 1, "0.1")', '"-1"');
+shouldBe('stepDownExplicitBounds(-10, 10, 1, "0.2")', '"-1"');
+shouldBe('stepDownExplicitBounds(-10, 10, 1, "1.0")', '"0"');
+shouldBe('stepDownExplicitBounds(-10, 10, 1, "1.1")', '"0"');
+shouldBe('stepDownExplicitBounds(-10, 10, 1, "1.2")', '"0"');
+shouldBe('stepDownExplicitBounds(-10, 10, 1, "2.0")', '"1"');
+
+debug('');
+shouldBe('stepDownExplicitBounds(-10, 10, 1, "-0.1")', '"-1"');
+shouldBe('stepDownExplicitBounds(-10, 10, 1, "-0.2")', '"-1"');
+shouldBe('stepDownExplicitBounds(-10, 10, 1, "-1.0")', '"-2"');
+shouldBe('stepDownExplicitBounds(-10, 10, 1, "-1.1")', '"-2"');
+shouldBe('stepDownExplicitBounds(-10, 10, 1, "-1.2")', '"-2"');
+shouldBe('stepDownExplicitBounds(-10, 10, 1, "-2.0")', '"-3"');
+
+// Same as above, but with leading/trailing zeros removed.
+debug('');
+shouldBe('stepUpExplicitBounds(-10, 10, 1, ".1")', '"1"');
+shouldBe('stepUpExplicitBounds(-10, 10, 1, ".2")', '"1"');
+shouldBe('stepUpExplicitBounds(-10, 10, 1, "1.")', '"2"');
+shouldBe('stepUpExplicitBounds(-10, 10, 1, "2.")', '"3"');
+
+debug('');
+shouldBe('stepUpExplicitBounds(-10, 10, 1, "-.1")', '"1"');
+shouldBe('stepUpExplicitBounds(-10, 10, 1, "-.2")', '"1"');
+shouldBe('stepUpExplicitBounds(-10, 10, 1, "-1.")', '"0"');
+shouldBe('stepUpExplicitBounds(-10, 10, 1, "-2.")', '"-1"');
+
+debug('');
+shouldBe('stepDownExplicitBounds(-10, 10, 1, ".1")', '"-1"');
+shouldBe('stepDownExplicitBounds(-10, 10, 1, ".2")', '"-1"');
+shouldBe('stepDownExplicitBounds(-10, 10, 1, "1.")', '"0"');
+shouldBe('stepDownExplicitBounds(-10, 10, 1, "2.")', '"1"');
+
+debug('');
+shouldBe('stepDownExplicitBounds(-10, 10, 1, "-.1")', '"-1"');
+shouldBe('stepDownExplicitBounds(-10, 10, 1, "-.2")', '"-1"');
+shouldBe('stepDownExplicitBounds(-10, 10, 1, "-1.")', '"-2"');
+shouldBe('stepDownExplicitBounds(-10, 10, 1, "-2.")', '"-3"');
+
+// Same as above, but stepping by .1 rather than 1.
+debug('');
+shouldBe('stepUpExplicitBounds(-10, 10, .1, "0.1")', '"0.2"');
+shouldBe('stepUpExplicitBounds(-10, 10, .1, "0.2")', '"0.3"');
+shouldBe('stepUpExplicitBounds(-10, 10, .1, "1.0")', '"1.1"');
+shouldBe('stepUpExplicitBounds(-10, 10, .1, "1.1")', '"1.2"');
+shouldBe('stepUpExplicitBounds(-10, 10, .1, "1.2")', '"1.3"');
+shouldBe('stepUpExplicitBounds(-10, 10, .1, "2.0")', '"2.1"');
+
+debug('');
+shouldBe('stepUpExplicitBounds(-10, 10, .1, "-0.1")', '"0"');
+shouldBe('stepUpExplicitBounds(-10, 10, .1, "-0.2")', '"-0.1"');
+shouldBe('stepUpExplicitBounds(-10, 10, .1, "-1.0")', '"-0.9"');
+shouldBe('stepUpExplicitBounds(-10, 10, .1, "-1.1")', '"-1"');
+shouldBe('stepUpExplicitBounds(-10, 10, .1, "-1.2")', '"-1.1"');
+shouldBe('stepUpExplicitBounds(-10, 10, .1, "-2.0")', '"-1.9"');
+
+debug('');
+shouldBe('stepDownExplicitBounds(-10, 10, .1, "0.1")', '"0"');
+shouldBe('stepDownExplicitBounds(-10, 10, .1, "0.2")', '"0.1"');
+shouldBe('stepDownExplicitBounds(-10, 10, .1, "1.0")', '"0.9"');
+shouldBe('stepDownExplicitBounds(-10, 10, .1, "1.1")', '"1"');
+shouldBe('stepDownExplicitBounds(-10, 10, .1, "1.2")', '"1.1"');
+shouldBe('stepDownExplicitBounds(-10, 10, .1, "2.0")', '"1.9"');
+
+debug('');
+shouldBe('stepDownExplicitBounds(-10, 10, .1, "-0.1")', '"-0.2"');
+shouldBe('stepDownExplicitBounds(-10, 10, .1, "-0.2")', '"-0.3"');
+shouldBe('stepDownExplicitBounds(-10, 10, .1, "-1.0")', '"-1.1"');
+shouldBe('stepDownExplicitBounds(-10, 10, .1, "-1.1")', '"-1.2"');
+shouldBe('stepDownExplicitBounds(-10, 10, .1, "-1.2")', '"-1.3"');
+shouldBe('stepDownExplicitBounds(-10, 10, .1, "-2.0")', '"-2.1"');
+
+debug('');
+shouldBe('stepUpExplicitBounds(-10, 10, .1, ".1")', '"0.2"');
+shouldBe('stepUpExplicitBounds(-10, 10, .1, ".2")', '"0.3"');
+shouldBe('stepUpExplicitBounds(-10, 10, .1, "1.")', '"1.1"');
+shouldBe('stepUpExplicitBounds(-10, 10, .1, "2.")', '"2.1"');
+
+debug('');
+shouldBe('stepUpExplicitBounds(-10, 10, .1, "-.1")', '"0"');
+shouldBe('stepUpExplicitBounds(-10, 10, .1, "-.2")', '"-0.1"');
+shouldBe('stepUpExplicitBounds(-10, 10, .1, "-1.")', '"-0.9"');
+shouldBe('stepUpExplicitBounds(-10, 10, .1, "-2.")', '"-1.9"');
+
+shouldBe('stepDownExplicitBounds(-10, 10, .1, ".1")', '"0"');
+shouldBe('stepDownExplicitBounds(-10, 10, .1, ".2")', '"0.1"');
+shouldBe('stepDownExplicitBounds(-10, 10, .1, "1.")', '"0.9"');
+shouldBe('stepDownExplicitBounds(-10, 10, .1, "2.")', '"1.9"');
+
+debug('');
+shouldBe('stepDownExplicitBounds(-10, 10, .1, "-.1")', '"-0.2"');
+shouldBe('stepDownExplicitBounds(-10, 10, .1, "-.2")', '"-0.3"');
+shouldBe('stepDownExplicitBounds(-10, 10, .1, "-1.")', '"-1.1"');
+shouldBe('stepDownExplicitBounds(-10, 10, .1, "-2.")', '"-2.1"');
+
+debug('');
debug('Invalid step value');
shouldBe('stepUpExplicitBounds(null, null, "foo", "0")', '"1"');
shouldBe('stepUpExplicitBounds(null, null, "0", "1")', '"2"');
shouldBe('stepDownExplicitBounds(null, null, "foo", "1")', '"0"');
shouldBe('stepDownExplicitBounds(null, null, "0", "2")', '"1"');
shouldBe('stepDownExplicitBounds(null, null, "-1", "3")', '"2"');
+
+debug('');
debug('Step=any');
shouldBe('stepUpExplicitBounds(null, null, "any", "1")', '"2"');
shouldBe('stepDownExplicitBounds(null, null, "any", "1")', '"0"');
+
+debug('');
debug('Overflow/underflow');
shouldBe('stepUpExplicitBounds(null, "100", "1", "99")', '"100"');
shouldBe('stepUpExplicitBounds(null, "100", "1", "100")', '"100"');
shouldBe('stepUpExplicitBounds(null, 0, 1, 0)', '"0"');
shouldBe('stepUpExplicitBounds(-100, 0, 1, -1, 2)', '"0"');
shouldBe('stepUpExplicitBounds(null, null, "3.40282346e+38", "1", 2)', '"0"');
+
+debug('');
debug('stepDown()/stepUp() for stepMismatch values');
shouldBe('stepUpExplicitBounds(null, null, 2, 1)', '"4"');
shouldBe('stepUpExplicitBounds(0, null, 10, 9, 9)', '"100"');
shouldBe('stepDownExplicitBounds(0, null, 10, 19)', '"10"');
+
+debug('');
debug('value + step is <= max, but rounded result would be > max.');
shouldBe('stepUpExplicitBounds(null, 99, 10, 89)', '"90"');
+
+debug('');
debug('Huge value and small step');
shouldBe('stepUpExplicitBounds(0, 1e38, 1, 1e38, 999)', '"1e+38"');
shouldBe('stepDownExplicitBounds(0, 1e38, 1, 1e38, 999)', '"1e+38"');
+
+debug('');
debug('Fractional numbers');
shouldBe('stepUpExplicitBounds(null, null, 0.33333333333333333, 0, 3)', '"1"');
shouldBe('stepUpExplicitBounds(null, null, 0.1, 1)', '"1.1"');
debug('Using the default values');
shouldBe('stepUpExplicitBounds(null, null, null, "")', '"51"');
shouldBe('stepDownExplicitBounds(null, null, null, "")', '"49"');
+
+debug('');
debug('Non-number arguments (stepCount)');
shouldBe('stepUpExplicitBounds(null, null, null, "0", "0")', '"0"');
shouldBe('stepDownExplicitBounds(null, null, null, "0", "0")', '"0"');
shouldBe('stepDownExplicitBounds(null, null, null, "0", "foo")', '"0"');
shouldBe('stepUpExplicitBounds(null, null, null, "0", null)', '"0"');
shouldBe('stepDownExplicitBounds(null, null, null, "0", null)', '"0"');
+
+debug('');
debug('Normal cases');
shouldBe('stepUpExplicitBounds(null, null, null, "0")', '"1"');
shouldBe('stepUpExplicitBounds(null, null, null, "1", 2)', '"3"');
shouldBe('stepDownExplicitBounds("-100", null, null, "2")', '"1"');
shouldBe('stepDownExplicitBounds("-100", null, null, "1", 2)', '"-1"');
shouldBe('stepDownExplicitBounds("-100", null, null, "-1", -1)', '"0"');
+
+debug('');
+debug('Fractional cases')
+// "When the element is suffering from a step mismatch, the user agent must
+// round the element's value to the nearest number for which the element would
+// not suffer from a step mismatch, and which is greater than or equal to the
+// minimum, and, if the maximum is not less than the minimum, which is less
+// than or equal to the maximum, if there is a number that matches these
+// constraints. If two numbers match these constraints, then user agents must
+// use the one nearest to positive infinity.""
+
+// Base/model/template tests
+shouldBe('stepUpExplicitBounds(-10, 10, 1, "0.1")', '"1"');
+shouldBe('stepUpExplicitBounds(-10, 10, 1, "0.2")', '"1"');
+shouldBe('stepUpExplicitBounds(-10, 10, 1, "1.0")', '"2"');
+shouldBe('stepUpExplicitBounds(-10, 10, 1, "1.1")', '"2"');
+shouldBe('stepUpExplicitBounds(-10, 10, 1, "1.2")', '"2"');
+shouldBe('stepUpExplicitBounds(-10, 10, 1, "2.0")', '"3"');
+
+// Same as above, but with negative numbers.
+debug('');
+shouldBe('stepUpExplicitBounds(-10, 10, 1, "-0.1")', '"1"');
+shouldBe('stepUpExplicitBounds(-10, 10, 1, "-0.2")', '"1"');
+shouldBe('stepUpExplicitBounds(-10, 10, 1, "-1.0")', '"0"');
+shouldBe('stepUpExplicitBounds(-10, 10, 1, "-1.1")', '"0"');
+shouldBe('stepUpExplicitBounds(-10, 10, 1, "-1.2")', '"0"');
+shouldBe('stepUpExplicitBounds(-10, 10, 1, "-2.0")', '"-1"');
+
+// Same as above, but stepping down rather than up.
+debug('');
+shouldBe('stepDownExplicitBounds(-10, 10, 1, "0.1")', '"-1"');
+shouldBe('stepDownExplicitBounds(-10, 10, 1, "0.2")', '"-1"');
+shouldBe('stepDownExplicitBounds(-10, 10, 1, "1.0")', '"0"');
+shouldBe('stepDownExplicitBounds(-10, 10, 1, "1.1")', '"0"');
+shouldBe('stepDownExplicitBounds(-10, 10, 1, "1.2")', '"0"');
+shouldBe('stepDownExplicitBounds(-10, 10, 1, "2.0")', '"1"');
+
+debug('');
+shouldBe('stepDownExplicitBounds(-10, 10, 1, "-0.1")', '"-1"');
+shouldBe('stepDownExplicitBounds(-10, 10, 1, "-0.2")', '"-1"');
+shouldBe('stepDownExplicitBounds(-10, 10, 1, "-1.0")', '"-2"');
+shouldBe('stepDownExplicitBounds(-10, 10, 1, "-1.1")', '"-2"');
+shouldBe('stepDownExplicitBounds(-10, 10, 1, "-1.2")', '"-2"');
+shouldBe('stepDownExplicitBounds(-10, 10, 1, "-2.0")', '"-3"');
+
+// Same as above, but with leading/trailing zeros removed.
+debug('');
+shouldBe('stepUpExplicitBounds(-10, 10, 1, ".1")', '"1"');
+shouldBe('stepUpExplicitBounds(-10, 10, 1, ".2")', '"1"');
+shouldBe('stepUpExplicitBounds(-10, 10, 1, "1.")', '"2"');
+shouldBe('stepUpExplicitBounds(-10, 10, 1, "2.")', '"3"');
+
+debug('');
+shouldBe('stepUpExplicitBounds(-10, 10, 1, "-.1")', '"1"');
+shouldBe('stepUpExplicitBounds(-10, 10, 1, "-.2")', '"1"');
+shouldBe('stepUpExplicitBounds(-10, 10, 1, "-1.")', '"0"');
+shouldBe('stepUpExplicitBounds(-10, 10, 1, "-2.")', '"-1"');
+
+debug('');
+shouldBe('stepDownExplicitBounds(-10, 10, 1, ".1")', '"-1"');
+shouldBe('stepDownExplicitBounds(-10, 10, 1, ".2")', '"-1"');
+shouldBe('stepDownExplicitBounds(-10, 10, 1, "1.")', '"0"');
+shouldBe('stepDownExplicitBounds(-10, 10, 1, "2.")', '"1"');
+
+debug('');
+shouldBe('stepDownExplicitBounds(-10, 10, 1, "-.1")', '"-1"');
+shouldBe('stepDownExplicitBounds(-10, 10, 1, "-.2")', '"-1"');
+shouldBe('stepDownExplicitBounds(-10, 10, 1, "-1.")', '"-2"');
+shouldBe('stepDownExplicitBounds(-10, 10, 1, "-2.")', '"-3"');
+
+// Same as above, but stepping by .1 rather than 1.
+debug('');
+shouldBe('stepUpExplicitBounds(-10, 10, .1, "0.1")', '"0.2"');
+shouldBe('stepUpExplicitBounds(-10, 10, .1, "0.2")', '"0.3"');
+shouldBe('stepUpExplicitBounds(-10, 10, .1, "1.0")', '"1.1"');
+shouldBe('stepUpExplicitBounds(-10, 10, .1, "1.1")', '"1.2"');
+shouldBe('stepUpExplicitBounds(-10, 10, .1, "1.2")', '"1.3"');
+shouldBe('stepUpExplicitBounds(-10, 10, .1, "2.0")', '"2.1"');
+
+debug('');
+shouldBe('stepUpExplicitBounds(-10, 10, .1, "-0.1")', '"0"');
+shouldBe('stepUpExplicitBounds(-10, 10, .1, "-0.2")', '"-0.1"');
+shouldBe('stepUpExplicitBounds(-10, 10, .1, "-1.0")', '"-0.9"');
+shouldBe('stepUpExplicitBounds(-10, 10, .1, "-1.1")', '"-1"');
+shouldBe('stepUpExplicitBounds(-10, 10, .1, "-1.2")', '"-1.1"');
+shouldBe('stepUpExplicitBounds(-10, 10, .1, "-2.0")', '"-1.9"');
+
+debug('');
+shouldBe('stepDownExplicitBounds(-10, 10, .1, "0.1")', '"0"');
+shouldBe('stepDownExplicitBounds(-10, 10, .1, "0.2")', '"0.1"');
+shouldBe('stepDownExplicitBounds(-10, 10, .1, "1.0")', '"0.9"');
+shouldBe('stepDownExplicitBounds(-10, 10, .1, "1.1")', '"1"');
+shouldBe('stepDownExplicitBounds(-10, 10, .1, "1.2")', '"1.1"');
+shouldBe('stepDownExplicitBounds(-10, 10, .1, "2.0")', '"1.9"');
+
+debug('');
+shouldBe('stepDownExplicitBounds(-10, 10, .1, "-0.1")', '"-0.2"');
+shouldBe('stepDownExplicitBounds(-10, 10, .1, "-0.2")', '"-0.3"');
+shouldBe('stepDownExplicitBounds(-10, 10, .1, "-1.0")', '"-1.1"');
+shouldBe('stepDownExplicitBounds(-10, 10, .1, "-1.1")', '"-1.2"');
+shouldBe('stepDownExplicitBounds(-10, 10, .1, "-1.2")', '"-1.3"');
+shouldBe('stepDownExplicitBounds(-10, 10, .1, "-2.0")', '"-2.1"');
+
+debug('');
+shouldBe('stepUpExplicitBounds(-10, 10, .1, ".1")', '"0.2"');
+shouldBe('stepUpExplicitBounds(-10, 10, .1, ".2")', '"0.3"');
+shouldBe('stepUpExplicitBounds(-10, 10, .1, "1.")', '"1.1"');
+shouldBe('stepUpExplicitBounds(-10, 10, .1, "2.")', '"2.1"');
+
+debug('');
+shouldBe('stepUpExplicitBounds(-10, 10, .1, "-.1")', '"0"');
+shouldBe('stepUpExplicitBounds(-10, 10, .1, "-.2")', '"-0.1"');
+shouldBe('stepUpExplicitBounds(-10, 10, .1, "-1.")', '"-0.9"');
+shouldBe('stepUpExplicitBounds(-10, 10, .1, "-2.")', '"-1.9"');
+
+debug('');
+shouldBe('stepDownExplicitBounds(-10, 10, .1, ".1")', '"0"');
+shouldBe('stepDownExplicitBounds(-10, 10, .1, ".2")', '"0.1"');
+shouldBe('stepDownExplicitBounds(-10, 10, .1, "1.")', '"0.9"');
+shouldBe('stepDownExplicitBounds(-10, 10, .1, "2.")', '"1.9"');
+
+debug('');
+shouldBe('stepDownExplicitBounds(-10, 10, .1, "-.1")', '"-0.2"');
+shouldBe('stepDownExplicitBounds(-10, 10, .1, "-.2")', '"-0.3"');
+shouldBe('stepDownExplicitBounds(-10, 10, .1, "-1.")', '"-1.1"');
+shouldBe('stepDownExplicitBounds(-10, 10, .1, "-2.")', '"-2.1"');
+
+debug('');
debug('Extra arguments');
shouldBe('setInputAttributes(null, null, null, "0"); input.stepUp(1,2); input.value', '"1"');
shouldBe('setInputAttributes(null, null, null, "1"); input.stepDown(1,3); input.value', '"0"');
+
+debug('');
debug('Invalid step value');
shouldBe('stepUpExplicitBounds(null, null, "foo", "0")', '"1"');
shouldBe('stepUpExplicitBounds(null, null, "0", "1")', '"2"');
shouldBe('stepDownExplicitBounds(null, null, "foo", "1")', '"0"');
shouldBe('stepDownExplicitBounds(null, null, "0", "2")', '"1"');
shouldBe('stepDownExplicitBounds(null, null, "-1", "3")', '"2"');
+
+debug('');
debug('Step=any');
shouldThrow('stepUpExplicitBounds(null, null, "any", "1")', invalidStateErr);
shouldThrow('stepDownExplicitBounds(null, null, "any", "1")', invalidStateErr);
+
+debug('');
debug('Overflow/underflow');
shouldBe('stepUpExplicitBounds(null, "100", "1", "99")', '"100"');
shouldThrow('stepUpExplicitBounds(null, "100", "1", "100")', invalidStateErr);
shouldThrow('stepUpExplicitBounds(-100, 0, 1, -1, 2)', invalidStateErr);
shouldBe('input.value', '"-1"');
shouldThrow('stepUpExplicitBounds(null, null, "3.40282346e+38", "1", "2")', invalidStateErr);
+
+debug('');
debug('stepDown()/stepUp() for stepMismatch values');
shouldBe('stepUpExplicitBounds(null, null, 2, 1)', '"4"');
shouldBe('input.stepDown(); input.value', '"2"');
shouldBe('stepUpExplicitBounds(0, null, 10, 9, 9)', '"100"');
shouldBe('stepDownExplicitBounds(0, null, 10, 19)', '"10"');
+
+debug('');
debug('value + step is <= max, but rounded result would be > max.');
shouldThrow('stepUpExplicitBounds(null, 99, 10, 89)', invalidStateErr);
+
+debug('');
debug('Huge value and small step');
shouldBe('stepUpExplicitBounds(0, 1e38, 1, 1e38, 999999)', '"1e+38"');
shouldBe('stepDownExplicitBounds(0, 1e38, 1, 1e38, 999999)', '"1e+38"');
+
+debug('');
debug('Fractional numbers');
shouldBe('stepUpExplicitBounds(null, null, 0.33333333333333333, 0, 3)', '"1"');
shouldBe('stepUpExplicitBounds(null, null, 0.1, 1)', '"1.1"');
shouldBe('for (var i = 0; i < 255; i++) { input.stepDown(); }; input.value', '"0"');
shouldBe('stepDownExplicitBounds(null, null, 0.1, 1, 8)', '"0.2"');
shouldBe('stepDownExplicitBounds(null, null, 0.1, 1)', '"0.9"');
+
+debug('');
</script>
<script src="../../../resources/js-test-post.js"></script>
</body>
+2015-11-02 Keith Rollin <krollin@apple.com>
+
+ input[type=number] does not increment/decrement integers with trailing decimal characters
+ https://bugs.webkit.org/show_bug.cgi?id=148867
+ rdar://problem/22589693
+
+ Reviewed by Chris Dumez.
+
+ Support input[type=number].value attributes of the form "###." (that
+ is, leading digits with a decimal but no trailing digits). This form
+ was supported in the setting of the attribute, but not when changing
+ it through stepUp/Down.
+
+ Testing turned up similarly incorrect processing of -.###, so
+ addressed that, too.
+
+ Test: fast/forms/range/input-appearance-range-decimals.html
+
+ Updated the following tests:
+ - fast/forms/number/number-stepup-stepdown-from-renderer.html
+ - fast/forms/number/number-stepup-stepdown.html
+ - fast/forms/range/range-stepup-stepdown-from-renderer.html
+ - fast/forms/range/range-stepup-stepdown.html
+
+ * html/InputType.cpp:
+ (WebCore::InputType::stepUpFromRenderer):
+ * platform/Decimal.cpp:
+ (WebCore::Decimal::fromString):
+
2015-11-02 Jiewen Tan <jiewen_tan@apple.com>
Null dereference loading Blink layout test fast/css/background-repeat-null-y-crash.html
// * If 0 is in-range, but not matched to step value
// - The value should be the larger matched value nearest to 0 if n > 0
// e.g. <input type=number min=-100 step=3> -> 2
- // - The value should be the smaler matched value nearest to 0 if n < 0
+ // - The value should be the smaller matched value nearest to 0 if n < 0
// e.g. <input type=number min=-100 step=3> -> -1
// As for date/datetime-local/month/time/week types, the current value is assumed as "the current local date/time".
// As for datetime type, the current value is assumed as "the current date/time in UTC".
// If the current value is not matched to step value:
// - The value should be the larger matched value nearest to 0 if n > 0
// e.g. <input type=number value=3 min=-100 step=3> -> 5
- // - The value should be the smaler matched value nearest to 0 if n < 0
+ // - The value should be the smaller matched value nearest to 0 if n < 0
// e.g. <input type=number value=3 min=-100 step=3> -> 2
//
// n is assumed as -n if step < 0.
}
HandleCharAndBreak('0', StateZero);
+ HandleCharAndBreak('.', StateDot);
return nan();
case StateStart:
if (state == StateZero)
return zero(sign);
- if (state == StateDigit || state == StateEDigit || state == StateDotDigit) {
+ if (state == StateDigit || state == StateDot || state == StateDotDigit || state == StateEDigit) {
int resultExponent = exponent * (exponentSign == Negative ? -1 : 1) - numberOfDigitsAfterDot + numberOfExtraDigits;
if (resultExponent < ExponentMin)
return zero(Positive);