Commit 42a73985 authored by Stephen Sigwart's avatar Stephen Sigwart Committed by Commit Bot

Added additional number input validation tests.

Bug: 365196
Change-Id: I71f74169589ac768f8c8299c9683ec82be2eb9b5
Cq-Do-Not-Cancel-Tryjobs: true
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2331518
Commit-Queue: Stephen Sigwart <ssigwart@gmail.com>
Reviewed-by: default avatarKent Tamura <tkent@chromium.org>
Reviewed-by: default avatarMason Freed <masonfreed@chromium.org>
Cr-Commit-Position: refs/heads/master@{#797984}
parent 5c606c3c
...@@ -709,6 +709,22 @@ void HTMLInputElement::setSelectionRangeForBinding( ...@@ -709,6 +709,22 @@ void HTMLInputElement::setSelectionRangeForBinding(
TextControlElement::setSelectionRangeForBinding(start, end, direction); TextControlElement::setSelectionRangeForBinding(start, end, direction);
} }
// This function can be used to allow tests to set the selection
// range for Number inputs, which do not support the ordinary
// selection API.
void HTMLInputElement::SetSelectionRangeForTesting(
unsigned start,
unsigned end,
ExceptionState& exception_state) {
if (FormControlType() != input_type_names::kNumber) {
exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
"The input element's type ('" +
input_type_->FormControlType() +
"') is not a number input.");
}
TextControlElement::setSelectionRangeForBinding(start, end);
}
void HTMLInputElement::AccessKeyAction(bool send_mouse_events) { void HTMLInputElement::AccessKeyAction(bool send_mouse_events) {
input_type_view_->AccessKeyAction(send_mouse_events); input_type_view_->AccessKeyAction(send_mouse_events);
} }
......
...@@ -196,6 +196,12 @@ class CORE_EXPORT HTMLInputElement ...@@ -196,6 +196,12 @@ class CORE_EXPORT HTMLInputElement
unsigned end, unsigned end,
const String& direction, const String& direction,
ExceptionState&); ExceptionState&);
// This function can be used to allow tests to set the selection
// range for Number inputs, which do not support the ordinary
// selection API.
void SetSelectionRangeForTesting(unsigned start,
unsigned end,
ExceptionState&);
bool LayoutObjectIsNeeded(const ComputedStyle&) const final; bool LayoutObjectIsNeeded(const ComputedStyle&) const final;
LayoutObject* CreateLayoutObject(const ComputedStyle&, LegacyLayout) override; LayoutObject* CreateLayoutObject(const ComputedStyle&, LegacyLayout) override;
......
...@@ -1476,6 +1476,23 @@ void Internals::setAutofilled(Element* element, ...@@ -1476,6 +1476,23 @@ void Internals::setAutofilled(Element* element,
enabled ? WebAutofillState::kAutofilled : WebAutofillState::kNotFilled); enabled ? WebAutofillState::kAutofilled : WebAutofillState::kNotFilled);
} }
void Internals::setSelectionRangeForNumberType(
Element* input_element,
uint32_t start,
uint32_t end,
ExceptionState& exception_state) {
DCHECK(input_element);
auto* html_input_element = DynamicTo<HTMLInputElement>(input_element);
if (!html_input_element) {
exception_state.ThrowDOMException(
DOMExceptionCode::kInvalidNodeTypeError,
"The element provided is not an input element.");
return;
}
html_input_element->SetSelectionRangeForTesting(start, end, exception_state);
}
Range* Internals::rangeFromLocationAndLength(Element* scope, Range* Internals::rangeFromLocationAndLength(Element* scope,
int range_location, int range_location,
int range_length) { int range_length) {
......
...@@ -237,6 +237,10 @@ class Internals final : public ScriptWrappable { ...@@ -237,6 +237,10 @@ class Internals final : public ScriptWrappable {
void setAutofilledValue(Element*, const String&, ExceptionState&); void setAutofilledValue(Element*, const String&, ExceptionState&);
void setEditingValue(Element* input_element, const String&, ExceptionState&); void setEditingValue(Element* input_element, const String&, ExceptionState&);
void setAutofilled(Element*, bool enabled, ExceptionState&); void setAutofilled(Element*, bool enabled, ExceptionState&);
void setSelectionRangeForNumberType(Element* input_element,
uint32_t start,
uint32_t end,
ExceptionState&);
Range* rangeFromLocationAndLength(Element* scope, Range* rangeFromLocationAndLength(Element* scope,
int range_location, int range_location,
......
...@@ -130,6 +130,7 @@ ...@@ -130,6 +130,7 @@
[RaisesException] void setAutofilledValue(Element inputElement, DOMString value); [RaisesException] void setAutofilledValue(Element inputElement, DOMString value);
[RaisesException] void setEditingValue(Element inputElement, DOMString value); [RaisesException] void setEditingValue(Element inputElement, DOMString value);
[RaisesException] void setAutofilled(Element inputElement, boolean enabled); [RaisesException] void setAutofilled(Element inputElement, boolean enabled);
[RaisesException] void setSelectionRangeForNumberType(Element inputElement, unsigned long start, unsigned long end);
Range rangeFromLocationAndLength(Element scope, long rangeLocation, long rangeLength); Range rangeFromLocationAndLength(Element scope, long rangeLocation, long rangeLength);
unsigned long locationFromRange(Element scope, Range range); unsigned long locationFromRange(Element scope, Range range);
......
...@@ -293,9 +293,9 @@ void Locale::SetLocaleData(const Vector<String, kDecimalSymbolsSize>& symbols, ...@@ -293,9 +293,9 @@ void Locale::SetLocaleData(const Vector<String, kDecimalSymbolsSize>& symbols,
// zero length positive prefix. // zero length positive prefix.
uses_single_char_number_filtering_ = false; uses_single_char_number_filtering_ = false;
if (decimal_symbols_[kDecimalSeparatorIndex].length() == 1 && if (decimal_symbols_[kDecimalSeparatorIndex].length() == 1 &&
(positive_prefix_.length() == 0 || positive_prefix_.length() == 1) && positive_prefix_.length() <= 1 && negative_prefix_.length() == 1 &&
negative_prefix_.length() == 1 && positive_suffix_.length() == 0 && positive_suffix_.length() == 0 && negative_suffix_.length() == 0 &&
negative_suffix_.length() == 0) { !IsRTL()) {
uses_single_char_number_filtering_ = true; uses_single_char_number_filtering_ = true;
for (wtf_size_t i = 0; i <= 9; ++i) { for (wtf_size_t i = 0; i <= 9; ++i) {
if (decimal_symbols_[i].length() != 1) { if (decimal_symbols_[i].length() != 1) {
......
Arabic number input should accept ASCII digits and Arabic digits, and reject others. Arabic number input should accept ASCII digits and Arabic digits, and reject others.
PASS displayValueForKeyInput(arabicInput, "123.4") is "123.4" PASS 123.4 is 123.4
PASS displayValueForKeyInput(arabicInput, "1.23E+19") is "1.23E+19" PASS displayValueForKeyInput(input_ar, "123.4", "", 123.4) is "123.4"
PASS displayValueForKeyInput(arabicInput, "1.23e-1") is "1.23e-1" PASS 1.23E+19 is 12300000000000000000
PASS displayValueForKeyInput(arabicInput, "١٩٠") is "١٩٠" PASS displayValueForKeyInput(input_ar, "1.23E+19", "", 12300000000000000000) is "1.23E+19"
PASS displayValueForKeyInput(arabicInput, "acdef") is "e" PASS 1.23e-1 is 0.123
PASS displayValueForKeyInput(input_ar, "1.23e-1", "", 0.123) is "1.23e-1"
PASS 190 is 190
PASS displayValueForKeyInput(input_ar, "١٩٠", "", 190) is "١٩٠"
PASS is undefined.
PASS displayValueForKeyInput(input_ar, "acdef", "", undefined) is "e"
French number input should accept ASCII digits, comma, and full stop. French number input should accept ASCII digits, comma, and full stop.
PASS displayValueForKeyInput(frenchInput, "1234.56") is "1234.56" PASS 1234.56 is 1234.56
FAIL displayValueForKeyInput(frenchInput, "1234,56") should be 1234.56. Was 1234,56. PASS displayValueForKeyInput(input_fr, "1234.56", "", 1234.56) is "1234.56"
PASS 1234.56 is 1234.56
PASS displayValueForKeyInput(input_fr, "1234,56", "", 1234.56) is "1234,56"
English number input should accept ASCII digits and full stop, and no comma. English number input should accept ASCII digits and full stop, and no comma.
PASS displayValueForKeyInput(englishInput, "1234.56") is "1234.56" PASS 1234.56 is 1234.56
PASS displayValueForKeyInput(englishInput, "-1234,56") is "-123456" PASS displayValueForKeyInput(input_en, "1234.56", "", 1234.56) is "1234.56"
PASS displayValueForKeyInput(englishInput, " 1234.56 ") is "1234.56" PASS -123456 is -123456
PASS displayValueForKeyInput(englishInput, "123,456,789E+10") is "123456789E+10" PASS displayValueForKeyInput(input_en, "-1234,56", "", -123456) is "-123456"
PASS displayValueForKeyInput(englishInput, ".", "1|e2") is "1.e2" PASS 1234.56 is 1234.56
PASS displayValueForKeyInput(englishInput, ".", "1e2|") is "1e2" PASS displayValueForKeyInput(input_en, " 1234.56 ", "", 1234.56) is "1234.56"
PASS displayValueForKeyInput(englishInput, ".", "|-12") is "-12" PASS window.getSelection().toString() is "-1-1"
PASS displayValueForKeyInput(englishInput, ".", "|1e-12") is ".1e-12" PASS -1e-1 is -0.1
PASS displayValueForKeyInput(englishInput, "e", "12|34") is "12e34" PASS displayValueForKeyInput(input_en, "e", "-1|-1", -0.1) is "-1e-1"
PASS displayValueForKeyInput(englishInput, "e", "12|3e4") is "123e4"
PASS displayValueForKeyInput(englishInput, "e", "123|.4") is "123.4"
PASS displayValueForKeyInput(englishInput, "e", "12.3|4") is "12.3e4" Test all locales.
PASS displayValueForKeyInput(englishInput, "+", "12|34") is "12+34" PASS 123456789E+10 is 1234567890000000000
PASS displayValueForKeyInput(englishInput, "+", "-1|2e-34") is "-12e-34" PASS displayValueForKeyInput(input_en, "123,456,789E+10", "", 1234567890000000000) is "123456789E+10"
PASS displayValueForKeyInput(englishInput, "+", "|1234") is "+1234" PASS window.getSelection().toString() is "1e2"
PASS displayValueForKeyInput(englishInput, "-", "123e|4") is "123e-4" PASS 1.e2 is 100
PASS displayValueForKeyInput(englishInput, "-", "1|23e4") is "123e4" PASS displayValueForKeyInput(input_fr, ".", "1|e2", 100) is "1.e2"
PASS displayValueForKeyInput(englishInput, "-", "123e4|") is "123e4" PASS window.getSelection().toString() is "1e2"
PASS displayValueForKeyInput(englishInput, "9", "|-1") is "-1" PASS 1.e2 is 100
PASS displayValueForKeyInput(englishInput, "9", "-|1") is "-91" PASS displayValueForKeyInput(input_en, ".", "1|e2", 100) is "1.e2"
PASS displayValueForKeyInput(englishInput, "9", "1e|+2") is "1e+2" PASS window.getSelection().toString() is "1e2"
PASS displayValueForKeyInput(englishInput, "9", "1e+|2") is "1e+92" PASS 1e2 is 100
PASS displayValueForKeyInput(englishInput, " abcdef ") is "e" PASS displayValueForKeyInput(input_fr, ",", "1e2|", 100) is "1e2"
PASS displayValueForKeyInput(englishInput, "+1-2") is "+1-2" PASS window.getSelection().toString() is "1e2"
PASS displayValueForKeyInput(englishInput, "+1-2+2-3") is "+1-223" PASS 1e2 is 100
PASS displayValueForKeyInput(englishInput, "0-123-123+123") is "0-123-123123" PASS displayValueForKeyInput(input_en, ".", "1e2|", 100) is "1e2"
PASS displayValueForKeyInput(englishInput, "10e123123e1231233e") is "10e1231231231233" PASS window.getSelection().toString() is "-12"
PASS displayValueForKeyInput(englishInput, "1e2eee") is "1e2" PASS -12 is -12
PASS displayValueForKeyInput(englishInput, "1e1e1e1e") is "1e111" PASS displayValueForKeyInput(input_fr, ",", "|-12", -12) is "-12"
PASS window.getSelection().toString() is "-12"
PASS -12 is -12
PASS displayValueForKeyInput(input_en, ".", "|-12", -12) is "-12"
PASS window.getSelection().toString() is "1e-12"
PASS .1e-12 is 1e-13
PASS displayValueForKeyInput(input_fr, ".", "|1e-12", 1e-13) is ".1e-12"
PASS window.getSelection().toString() is "1e-12"
PASS .1e-12 is 1e-13
PASS displayValueForKeyInput(input_en, ".", "|1e-12", 1e-13) is ".1e-12"
PASS window.getSelection().toString() is "3412"
PASS 34e12 is 34000000000000
PASS displayValueForKeyInput(input_fr, "e", "34|12", 34000000000000) is "34e12"
PASS window.getSelection().toString() is "3412"
PASS 34e12 is 34000000000000
PASS displayValueForKeyInput(input_en, "e", "34|12", 34000000000000) is "34e12"
PASS window.getSelection().toString() is "123e4"
PASS 123e4 is 1230000
PASS displayValueForKeyInput(input_fr, "e", "12|3e4", 1230000) is "123e4"
PASS window.getSelection().toString() is "123e4"
PASS 123e4 is 1230000
PASS displayValueForKeyInput(input_en, "e", "12|3e4", 1230000) is "123e4"
PASS window.getSelection().toString() is "123,4"
PASS 123.4 is 123.4
PASS displayValueForKeyInput(input_fr, "e", "123|,4", 123.4) is "123,4"
PASS window.getSelection().toString() is "123.4"
PASS 123.4 is 123.4
PASS displayValueForKeyInput(input_en, "e", "123|.4", 123.4) is "123.4"
PASS window.getSelection().toString() is "12.34"
PASS 12.3e4 is 123000
PASS displayValueForKeyInput(input_fr, "e", "12.3|4", 123000) is "12.3e4"
PASS window.getSelection().toString() is "12.34"
PASS 12.3e4 is 123000
PASS displayValueForKeyInput(input_en, "e", "12.3|4", 123000) is "12.3e4"
PASS window.getSelection().toString() is "١٢٣٤"
PASS is undefined.
PASS displayValueForKeyInput(input_ar, "+", "١٢|٣٤", undefined) is "١٢+٣٤"
PASS window.getSelection().toString() is "1234"
PASS is undefined.
PASS displayValueForKeyInput(input_fr, "+", "12|34", undefined) is "12+34"
PASS window.getSelection().toString() is "1234"
PASS is undefined.
PASS displayValueForKeyInput(input_en, "+", "12|34", undefined) is "12+34"
PASS window.getSelection().toString() is "-34e-12"
PASS -34e-12 is -3.4e-11
PASS displayValueForKeyInput(input_fr, "+", "-3|4e-12", -3.4e-11) is "-34e-12"
PASS window.getSelection().toString() is "-34e-12"
PASS -34e-12 is -3.4e-11
PASS displayValueForKeyInput(input_en, "+", "-3|4e-12", -3.4e-11) is "-34e-12"
PASS window.getSelection().toString() is "١٢٣٤"
PASS 1234 is 1234
PASS displayValueForKeyInput(input_ar, "+", "|١٢٣٤", 1234) is "+١٢٣٤"
PASS window.getSelection().toString() is "1234"
PASS 1234 is 1234
PASS displayValueForKeyInput(input_fr, "+", "|1234", 1234) is "+1234"
PASS window.getSelection().toString() is "1234"
PASS 1234 is 1234
PASS displayValueForKeyInput(input_en, "+", "|1234", 1234) is "+1234"
PASS window.getSelection().toString() is "123e4"
PASS 123e-4 is 0.0123
PASS displayValueForKeyInput(input_fr, "-", "123e|4", 0.0123) is "123e-4"
PASS window.getSelection().toString() is "123e4"
PASS 123e-4 is 0.0123
PASS displayValueForKeyInput(input_en, "-", "123e|4", 0.0123) is "123e-4"
PASS window.getSelection().toString() is "123e4"
PASS 123e4 is 1230000
PASS displayValueForKeyInput(input_fr, "-", "1|23e4", 1230000) is "123e4"
PASS window.getSelection().toString() is "123e4"
PASS 123e4 is 1230000
PASS displayValueForKeyInput(input_en, "-", "1|23e4", 1230000) is "123e4"
PASS window.getSelection().toString() is "123e4"
PASS 123e4 is 1230000
PASS displayValueForKeyInput(input_fr, "-", "123e4|", 1230000) is "123e4"
PASS window.getSelection().toString() is "123e4"
PASS 123e4 is 1230000
PASS displayValueForKeyInput(input_en, "-", "123e4|", 1230000) is "123e4"
PASS window.getSelection().toString() is "-1"
PASS -1 is -1
PASS displayValueForKeyInput(input_fr, "9", "|-1", -1) is "-1"
PASS window.getSelection().toString() is "-1"
PASS -1 is -1
PASS displayValueForKeyInput(input_en, "9", "|-1", -1) is "-1"
PASS window.getSelection().toString() is "-1"
PASS -91 is -91
PASS displayValueForKeyInput(input_fr, "9", "-|1", -91) is "-91"
PASS window.getSelection().toString() is "-1"
PASS -91 is -91
PASS displayValueForKeyInput(input_en, "9", "-|1", -91) is "-91"
PASS window.getSelection().toString() is "1e+2"
PASS 1e+2 is 100
PASS displayValueForKeyInput(input_fr, "9", "1e|+2", 100) is "1e+2"
PASS window.getSelection().toString() is "1e+2"
PASS 1e+2 is 100
PASS displayValueForKeyInput(input_en, "9", "1e|+2", 100) is "1e+2"
PASS window.getSelection().toString() is "1e+2"
PASS 1e+12 is 1000000000000
PASS displayValueForKeyInput(input_fr, "1", "1e+|2", 1000000000000) is "1e+12"
PASS window.getSelection().toString() is "1e+2"
PASS 1e+12 is 1000000000000
PASS displayValueForKeyInput(input_en, "1", "1e+|2", 1000000000000) is "1e+12"
PASS is undefined.
PASS displayValueForKeyInput(input_fr, " abcdef ", "", undefined) is "e"
PASS is undefined.
PASS displayValueForKeyInput(input_en, " abcdef ", "", undefined) is "e"
PASS is undefined.
PASS displayValueForKeyInput(input_ar, "+١-٢", "", undefined) is "+١-٢"
PASS is undefined.
PASS displayValueForKeyInput(input_fr, "+1-2", "", undefined) is "+1-2"
PASS is undefined.
PASS displayValueForKeyInput(input_en, "+1-2", "", undefined) is "+1-2"
PASS is undefined.
PASS displayValueForKeyInput(input_ar, "+١-٢+٢-٣", "", undefined) is "+١-٢+٢-٣"
PASS is undefined.
PASS displayValueForKeyInput(input_fr, "+1-2+2-3", "", undefined) is "+1-223"
PASS is undefined.
PASS displayValueForKeyInput(input_en, "+1-2+2-3", "", undefined) is "+1-223"
PASS is undefined.
PASS displayValueForKeyInput(input_ar, "٠-١٢٣-١٢٣+١٢٣", "", undefined) is "٠-١٢٣-١٢٣+١٢٣"
PASS is undefined.
PASS displayValueForKeyInput(input_fr, "0-123-123+123", "", undefined) is "0-123-123123"
PASS is undefined.
PASS displayValueForKeyInput(input_en, "0-123-123+123", "", undefined) is "0-123-123123"
PASS is undefined.
PASS displayValueForKeyInput(input_fr, "10e123123e1231233e", "", undefined) is "10e1231231231233"
PASS is undefined.
PASS displayValueForKeyInput(input_en, "10e123123e1231233e", "", undefined) is "10e1231231231233"
PASS 1e2 is 100
PASS displayValueForKeyInput(input_fr, "1e2eee", "", 100) is "1e2"
PASS 1e2 is 100
PASS displayValueForKeyInput(input_en, "1e2eee", "", 100) is "1e2"
PASS 1e11 is 100000000000
PASS displayValueForKeyInput(input_fr, "1e1e1e", "", 100000000000) is "1e11"
PASS 1e11 is 100000000000
PASS displayValueForKeyInput(input_en, "1e1e1e", "", 100000000000) is "1e11"
PASS successfullyParsed is true PASS successfullyParsed is true
TEST COMPLETE TEST COMPLETE
......
<!DOCTYPE html> <!DOCTYPE html>
<script src="../../../resources/js-test.js"></script> <script src="../../../resources/js-test.js"></script>
<script> <script>
if (window.internals) if (window.internals)
internals.settings.setLangAttributeAwareFormControlUIEnabled(true); internals.settings.setLangAttributeAwareFormControlUIEnabled(true);
else else
...@@ -12,7 +13,7 @@ else ...@@ -12,7 +13,7 @@ else
<input id="input-en" lang="en-us" type="number"> <input id="input-en" lang="en-us" type="number">
<script> <script>
function displayValueForKeyInput(inputElement, keyInputs, optionalOldString) { function displayValueForKeyInput(inputElement, keyInputs, optionalOldString, expectedValue) {
inputElement.value = ''; inputElement.value = '';
inputElement.focus(); inputElement.focus();
if (optionalOldString) { if (optionalOldString) {
...@@ -20,64 +21,217 @@ function displayValueForKeyInput(inputElement, keyInputs, optionalOldString) { ...@@ -20,64 +21,217 @@ function displayValueForKeyInput(inputElement, keyInputs, optionalOldString) {
if (caretPosition < 0) if (caretPosition < 0)
caretPosition = optionalOldString.length; caretPosition = optionalOldString.length;
else else
optionalOldString = optionalOldString.substr(0, caretPosition) + optionalOldString.substr(caretPosition + 1); optionalOldString = optionalOldString.replace("|", "");
document.execCommand('InsertText', false, optionalOldString); document.execCommand('InsertText', false, optionalOldString);
inputElement.type = "text";
inputElement.selectionStart = caretPosition; // Check that the value is what we expect
inputElement.selectionEnd = caretPosition; inputElement.select();
inputElement.type = "number"; shouldBeEqualToString("window.getSelection().toString()", optionalOldString);
// Update selection
internals.setSelectionRangeForNumberType(inputElement, caretPosition, caretPosition);
} }
document.execCommand('InsertText', false, keyInputs); document.execCommand('InsertText', false, keyInputs);
inputElement.select(); inputElement.select();
// Check expected value
if (expectedValue === undefined)
shouldBeUndefined(inputElement.value);
else
shouldBeEqualToNumber(inputElement.value, expectedValue);
return window.getSelection().toString(); return window.getSelection().toString();
} }
// Get language formats
var langs = ["ar-eg", "fr-fr", "en-us"];
var langSpecs = {};
var numberCharMapByLang = {};
// Check local formatting options
for (var lang of langs)
{
var formatted = Number(123456.7).toLocaleString(lang);
var oneFormatted = Number(1).toLocaleString(lang);
var negativeFormatted = Number(-1).toLocaleString(lang);
var oneIndex = negativeFormatted.indexOf(oneFormatted);
var negativePrefix = "";
if (oneIndex > 0)
negativePrefix = negativeFormatted.substr(0, oneIndex);
var negativeSuffix = "";
if (negativeSuffix === oneFormatted)
negativeSuffix = negativeFormatted.substr(oneIndex + 1);
var specs = {
"usesCommas": /123,456/.test(formatted),
"usesArabicDecimalSeparator": formatted.indexOf("\u066b") !== -1,
"latinDigits": formatted.indexOf("1") !== -1,
"negativePrefix": negativePrefix,
"negativePrefixLength": negativePrefix.length,
"negativeSuffix": negativeSuffix,
"negativeSuffixLength": negativeSuffix.length,
"usesE": /[eE]/.test(Number(1e2).toLocaleString(lang, {"notation": "scientific"}))
};
specs.usesSingleCharFiltering = (specs.negativePrefixLength == 1 && specs.negativeSuffixLength == 0);
langSpecs[lang] = specs;
// Get replacement digits
numberCharMapByLang[lang] = {};
var formattedDigits = Number(1234567890.1).toLocaleString(lang, {
useGrouping: false
});
for (var i = 1; i <= 10; i++)
{
var num = i % 10;
var index = i - 1;
numberCharMapByLang[lang][num] = formattedDigits[index];
}
numberCharMapByLang[lang]["."] = formattedDigits[10];
var groupingSeparator = formatted[3];
if (formattedDigits.indexOf(groupingSeparator) !== -1)
formattedDigits = "";
numberCharMapByLang[lang][","] = groupingSeparator;
}
function convertLocal(enValue, lang) {
var value = "";
var map = numberCharMapByLang[lang] || {};
for (var i = 0; i < enValue.length; i++)
{
var c = enValue[i];
value += (c in map) ? map[c] : c;
}
// Update sign if needed
var specs = langSpecs[lang];
if (enValue[0] === "-" && specs.negativePrefix !== "-")
value = specs.negativePrefix + value.substr(1);
if (enValue.substr(0, 2) === "|-" && specs.negativePrefix !== "-")
value = "|" + specs.negativePrefix + value.substr(2);
return value;
}
debug('Arabic number input should accept ASCII digits and Arabic digits, and reject others.'); debug('Arabic number input should accept ASCII digits and Arabic digits, and reject others.');
var arabicInput = document.getElementById('input-ar'); var input_ar = document.getElementById('input-ar');
shouldBeEqualToString('displayValueForKeyInput(arabicInput, "123.4")', '123.4'); shouldBeEqualToString('displayValueForKeyInput(input_ar, "123.4", "", 123.4)', '123.4');
shouldBeEqualToString('displayValueForKeyInput(arabicInput, "1.23E+19")', '1.23E+19'); shouldBeEqualToString('displayValueForKeyInput(input_ar, "1.23E+19", "", 12300000000000000000)', '1.23E+19');
shouldBeEqualToString('displayValueForKeyInput(arabicInput, "1.23e-1")', '1.23e-1'); shouldBeEqualToString('displayValueForKeyInput(input_ar, "1.23e-1", "", 0.123)', '1.23e-1');
shouldBeEqualToString('displayValueForKeyInput(arabicInput, "\u0661\u0669\u0660")', '\u0661\u0669\u0660'); shouldBeEqualToString('displayValueForKeyInput(input_ar, "\u0661\u0669\u0660", "", 190)', '\u0661\u0669\u0660');
shouldBeEqualToString('displayValueForKeyInput(arabicInput, "acdef")', 'e'); shouldBeEqualToString('displayValueForKeyInput(input_ar, "acdef", "", undefined)', 'e');
debug(''); debug('');
debug('French number input should accept ASCII digits, comma, and full stop.'); debug('French number input should accept ASCII digits, comma, and full stop.');
var frenchInput = document.getElementById('input-fr'); var input_fr = document.getElementById('input-fr');
shouldBeEqualToString('displayValueForKeyInput(frenchInput, "1234.56")', '1234.56'); shouldBeEqualToString('displayValueForKeyInput(input_fr, "1234.56", "", 1234.56)', '1234.56');
shouldBeEqualToString('displayValueForKeyInput(frenchInput, "1234,56")', '1234.56'); shouldBeEqualToString('displayValueForKeyInput(input_fr, "1234,56", "", 1234.56)', '1234,56');
debug(''); debug('');
debug('English number input should accept ASCII digits and full stop, and no comma.'); debug('English number input should accept ASCII digits and full stop, and no comma.');
var englishInput = document.getElementById('input-en'); var input_en = document.getElementById('input-en');
shouldBeEqualToString('displayValueForKeyInput(englishInput, "1234.56")', '1234.56'); shouldBeEqualToString('displayValueForKeyInput(input_en, "1234.56", "", 1234.56)', '1234.56');
shouldBeEqualToString('displayValueForKeyInput(englishInput, "-1234,56")', '-123456'); shouldBeEqualToString('displayValueForKeyInput(input_en, "-1234,56", "", -123456)', '-123456');
shouldBeEqualToString('displayValueForKeyInput(englishInput, " 1234.56 ")', '1234.56'); shouldBeEqualToString('displayValueForKeyInput(input_en, " 1234.56 ", "", 1234.56)', '1234.56');
shouldBeEqualToString('displayValueForKeyInput(englishInput, "123,456,789E+10")', '123456789E+10'); shouldBeEqualToString('displayValueForKeyInput(input_en, "e", "-1|-1", -0.1)', '-1e-1');
shouldBeEqualToString('displayValueForKeyInput(englishInput, ".", "1|e2")', '1.e2');
shouldBeEqualToString('displayValueForKeyInput(englishInput, ".", "1e2|")', '1e2'); debug('');
shouldBeEqualToString('displayValueForKeyInput(englishInput, ".", "|-12")', '-12'); debug('Test all locales.');
shouldBeEqualToString('displayValueForKeyInput(englishInput, ".", "|1e-12")', '.1e-12'); var tests = [
shouldBeEqualToString('displayValueForKeyInput(englishInput, "e", "12|34")', '12e34'); ["123,456,789E+10", "", 1234567890000000000, '123456789E+10'],
shouldBeEqualToString('displayValueForKeyInput(englishInput, "e", "12|3e4")', '123e4'); [".", "1|e2", 100, '1.e2'],
shouldBeEqualToString('displayValueForKeyInput(englishInput, "e", "123|.4")', '123.4'); [".", "1e2|", 100, '1e2'],
shouldBeEqualToString('displayValueForKeyInput(englishInput, "e", "12.3|4")', '12.3e4'); [".", "|-12", -12, '-12'],
shouldBeEqualToString('displayValueForKeyInput(englishInput, "+", "12|34")', '12+34'); [".", "|1e-12", 0.0000000000001, '.1e-12'],
shouldBeEqualToString('displayValueForKeyInput(englishInput, "+", "-1|2e-34")', '-12e-34'); ["e", "34|12", 34000000000000, '34e12'],
shouldBeEqualToString('displayValueForKeyInput(englishInput, "+", "|1234")', '+1234'); ["e", "12|3e4", 1230000, '123e4'],
shouldBeEqualToString('displayValueForKeyInput(englishInput, "-", "123e|4")', '123e-4'); ["e", "123|.4", 123.4, '123.4'],
shouldBeEqualToString('displayValueForKeyInput(englishInput, "-", "1|23e4")', '123e4'); ["e", "12.3|4", 123000, '12.3e4'],
shouldBeEqualToString('displayValueForKeyInput(englishInput, "-", "123e4|")', '123e4'); ["+", "12|34", undefined, '12+34'],
shouldBeEqualToString('displayValueForKeyInput(englishInput, "9", "|-1")', '-1'); ["+", "-3|4e-12", -0.000000000034, '-34e-12'],
shouldBeEqualToString('displayValueForKeyInput(englishInput, "9", "-|1")', '-91'); ["+", "|1234", 1234, '+1234'],
shouldBeEqualToString('displayValueForKeyInput(englishInput, "9", "1e|+2")', '1e+2'); ["-", "123e|4", 0.0123, '123e-4'],
shouldBeEqualToString('displayValueForKeyInput(englishInput, "9", "1e+|2")', '1e+92'); ["-", "1|23e4", 1230000, '123e4'],
// Invalid ["-", "123e4|", 1230000, '123e4'],
shouldBeEqualToString('displayValueForKeyInput(englishInput, " abcdef ")', 'e'); ["9", "|-1", -1, '-1'],
shouldBeEqualToString('displayValueForKeyInput(englishInput, "+1-2")', '+1-2'); ["9", "-|1", -91, '-91'],
shouldBeEqualToString('displayValueForKeyInput(englishInput, "+1-2+2-3")', '+1-223'); ["9", "1e|+2", 100, '1e+2'],
shouldBeEqualToString('displayValueForKeyInput(englishInput, "0-123-123+123")', '0-123-123123'); ["1", "1e+|2", 1000000000000, '1e+12'],
shouldBeEqualToString('displayValueForKeyInput(englishInput, "10e123123e1231233e")', '10e1231231231233'); // Invalid
shouldBeEqualToString('displayValueForKeyInput(englishInput, "1e2eee")', '1e2'); [" abcdef ", "", undefined, 'e'],
shouldBeEqualToString('displayValueForKeyInput(englishInput, "1e1e1e1e")', '1e111'); ["+1-2", "", undefined, '+1-2'],
["+1-2+2-3", "", undefined, '+1-223'],
["0-123-123+123", "", undefined, '0-123-123123'],
["10e123123e1231233e", "", undefined, '10e1231231231233'],
["1e2eee", "", 100, '1e2'],
["1e1e1e", "", 100000000000, '1e11'],
];
for (var test of tests)
{
for (var lang of langs)
{
var specs = langSpecs[lang];
var keyInputs = test[0];
var oldString = test[1];
var expectedNumericValue = test[2];
var expectedStringValue = test[3];
// Build raw new text.
var rawNewText = keyInputs;
if (oldString !== "")
{
var pos = oldString.indexOf("|");
rawNewText = oldString.substr(0, pos) + keyInputs + oldString.substr(pos + 1);
}
// Skip test if there's a comma, but locale doesn't use commas.
// Otherwise, it will be converted to a decimal separator, breaking the expected value.
if (rawNewText.indexOf(",") !== -1 && !specs.usesCommas)
continue;
// Skip test if scientific notation doesn't use "e".
if (rawNewText.toLowerCase().indexOf("e") !== -1 && !specs.usesE)
continue;
// Not uses_single_char_number_filtering_, so build actual value.
if (!specs.usesSingleCharFiltering)
{
// Remove commas.
expectedStringValue = rawNewText.replace(/,/g, "");
// Figure out how this number will parse.
var cleanExpectedStringValue = expectedStringValue.replace(/[^0-9.e+-]/gi, "");
var scientificMatch = /e([+-]?[0-9]+)$/i.exec(cleanExpectedStringValue);
var multiplier = 1;
if (scientificMatch !== null)
{
cleanExpectedStringValue = cleanExpectedStringValue.replace(/e([+-]?[0-9]+)$/gi, "");
multiplier = Math.pow(10, parseInt(scientificMatch[1], 10));
}
expectedNumericValue = Number(cleanExpectedStringValue);
if (isNaN(expectedNumericValue))
expectedNumericValue = undefined;
else
expectedNumericValue *= multiplier;
}
// Skip if a negative number and negative prefix is more than 1 character.
// For ar-eg, Windows seems to strip \u061c when setting the initial text
// causing results to differ.
if (/^\|?-/.test(oldString) && specs.negativePrefixLength > 1)
continue;
// Change to locale if not in scientific notation (and valid).
if (/^[+-]?([0-9]+(\.[0-9]*)|\.[0-9]+)?e[+-]?[0-9]+$/i.exec(expectedStringValue) === null)
{
keyInputs = convertLocal(keyInputs, lang);
oldString = convertLocal(oldString, lang);
expectedStringValue = convertLocal(expectedStringValue, lang);
}
// Skip if it includes the Arabic decimal separator. Windows differs from Mac/Linux.
if (expectedStringValue.indexOf("\u066b") !== -1)
continue;
shouldBeEqualToString('displayValueForKeyInput(input_' + lang.replace(/-.*$/, '') + ', "' + keyInputs + '", "' + oldString + '", ' + expectedNumericValue + ')', expectedStringValue);
}
}
</script> </script>
</body> </body>
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment