diff options
author | Linus Groh <mail@linusgroh.de> | 2020-05-17 15:12:34 +0100 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-05-17 16:21:33 +0200 |
commit | 6f6b089aa01ad88041f3da8120b99c03ccd9d1d4 (patch) | |
tree | 3382bc68630a89ee87d13f1c5b8c04c1b61d13de | |
parent | cc42d75209424bc6fcaecbf82b95d980863de7f1 (diff) | |
download | serenity-6f6b089aa01ad88041f3da8120b99c03ccd9d1d4.zip |
LibJS: Add parseFloat()
-rw-r--r-- | Libraries/LibJS/Runtime/GlobalObject.cpp | 15 | ||||
-rw-r--r-- | Libraries/LibJS/Runtime/GlobalObject.h | 1 | ||||
-rw-r--r-- | Libraries/LibJS/Tests/parseFloat.js | 71 |
3 files changed, 87 insertions, 0 deletions
diff --git a/Libraries/LibJS/Runtime/GlobalObject.cpp b/Libraries/LibJS/Runtime/GlobalObject.cpp index 4b9497efd1..e81179168b 100644 --- a/Libraries/LibJS/Runtime/GlobalObject.cpp +++ b/Libraries/LibJS/Runtime/GlobalObject.cpp @@ -1,5 +1,6 @@ /* * Copyright (c) 2020, Andreas Kling <kling@serenityos.org> + * Copyright (c) 2020, Linus Groh <mail@linusgroh.de> * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -82,6 +83,7 @@ void GlobalObject::initialize() put_native_function("gc", gc, 0, attr); put_native_function("isNaN", is_nan, 1, attr); put_native_function("isFinite", is_finite, 1, attr); + put_native_function("parseFloat", parse_float, 1, attr); put("NaN", js_nan(), 0); put("Infinity", js_infinity(), 0); @@ -140,4 +142,17 @@ Value GlobalObject::is_finite(Interpreter& interpreter) return Value(interpreter.argument(0).to_number().is_finite_number()); } +Value GlobalObject::parse_float(Interpreter& interpreter) +{ + auto string = interpreter.argument(0).to_string(interpreter); + if (interpreter.exception()) + return {}; + for (size_t length = string.length(); length > 0; --length) { + auto number = Value(js_string(interpreter, string.substring(0, length))).to_number(); + if (!number.is_nan()) + return number; + } + return js_nan(); +} + } diff --git a/Libraries/LibJS/Runtime/GlobalObject.h b/Libraries/LibJS/Runtime/GlobalObject.h index 214a447a25..42a99b37fe 100644 --- a/Libraries/LibJS/Runtime/GlobalObject.h +++ b/Libraries/LibJS/Runtime/GlobalObject.h @@ -58,6 +58,7 @@ private: static Value gc(Interpreter&); static Value is_nan(Interpreter&); static Value is_finite(Interpreter&); + static Value parse_float(Interpreter&); Shape* m_empty_object_shape { nullptr }; diff --git a/Libraries/LibJS/Tests/parseFloat.js b/Libraries/LibJS/Tests/parseFloat.js new file mode 100644 index 0000000000..89045b2900 --- /dev/null +++ b/Libraries/LibJS/Tests/parseFloat.js @@ -0,0 +1,71 @@ +load("test-common.js"); + +try { + const NUMBER_TEST_CASES = [ + [0, 0], + [1, 1], + [.23, 0.23], + [1.23, 1.23], + [0.0123E+2, 1.23], + [1.23e4, 12300], + [Infinity, Infinity] + ]; + + NUMBER_TEST_CASES.forEach(test => { + const value = test[0]; + const result = test[1]; + assert(parseFloat(value) === result); + assert(parseFloat(+value) === result); + assert(parseFloat(-value) === -result); + }); + + const STRING_TEST_CASES = [ + ["0", 0], + ["1", 1], + [".23", 0.23], + ["1.23", 1.23], + ["0.0123E+2", 1.23], + ["1.23e4", 12300], + ["Infinity", Infinity] + ]; + + STRING_TEST_CASES.forEach(test => { + const value = test[0]; + const result = test[1]; + assert(parseFloat(value) === result); + assert(parseFloat(`+${value}`) === result); + assert(parseFloat(`-${value}`) === -result); + assert(parseFloat(`${value}foo`) === result); + assert(parseFloat(`+${value}foo`) === result); + assert(parseFloat(`-${value}foo`) === -result); + assert(parseFloat(` \n \t ${value} \v foo `) === result); + assert(parseFloat(` \r -${value} \f \n\n foo `) === -result); + assert(parseFloat({ toString: () => value }) === result); + }); + + const NAN_TEST_CASES = [ + "", + [], + [], + true, + false, + null, + undefined, + NaN, + "foo123", + "foo+123", + "fooInfinity", + "foo+Infinity" + ]; + + assert(isNaN(parseFloat())); + assert(isNaN(parseFloat("", 123, Infinity))); + + NAN_TEST_CASES.forEach(value => { + assert(isNaN(parseFloat(value))); + }); + + console.log("PASS"); +} catch (e) { + console.log("FAIL: " + e) +} |