diff --git a/Base/home/anon/js/date.js b/Base/home/anon/js/date.js new file mode 100644 index 00000000000..56a40d619c1 --- /dev/null +++ b/Base/home/anon/js/date.js @@ -0,0 +1,29 @@ +var now = Date.now(); +console.log("Unix timestamp: " + now / 1000); + +// FIXME: We need String.prototype.padStart() :^) +var d = new Date(); +var year = d.getFullYear(); +var month = d.getMonth() + 1; +if (month < 10) + month = "0" + month; +var day = d.getDate(); +if (day < 10) + day = "0" + day; +var hours = d.getHours(); +if (hours < 10) + hours = "0" + hours; +var minutes = d.getMinutes(); +if (minutes < 10) + minutes = "0" + minutes; +var seconds = d.getSeconds(); +if (seconds < 10) + seconds = "0" + seconds; +var milliseconds = d.getMilliseconds(); +if (milliseconds < 10) { + milliseconds = "00" + milliseconds; +} else if (milliseconds < 100) { + milliseconds = "0" + milliseconds; +} +console.log("Date: " + year + "-" + month + "-" + day); +console.log("Time: " + hours + ":" + minutes + ":" + seconds + "." + milliseconds); diff --git a/Libraries/LibJS/Interpreter.cpp b/Libraries/LibJS/Interpreter.cpp index 6af4b7971ab..83f6c9bd71f 100644 --- a/Libraries/LibJS/Interpreter.cpp +++ b/Libraries/LibJS/Interpreter.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -46,6 +47,7 @@ Interpreter::Interpreter() m_string_prototype = heap().allocate(); m_array_prototype = heap().allocate(); m_error_prototype = heap().allocate(); + m_date_prototype = heap().allocate(); m_global_object = heap().allocate(); } @@ -165,6 +167,7 @@ void Interpreter::gather_roots(Badge, HashTable& roots) roots.set(m_object_prototype); roots.set(m_array_prototype); roots.set(m_error_prototype); + roots.set(m_date_prototype); roots.set(m_exception); diff --git a/Libraries/LibJS/Interpreter.h b/Libraries/LibJS/Interpreter.h index 70e6af0d80b..2902cabdb85 100644 --- a/Libraries/LibJS/Interpreter.h +++ b/Libraries/LibJS/Interpreter.h @@ -111,6 +111,7 @@ public: Object* object_prototype() { return m_object_prototype; } Object* array_prototype() { return m_array_prototype; } Object* error_prototype() { return m_error_prototype; } + Object* date_prototype() { return m_date_prototype; } Exception* exception() { return m_exception; } void clear_exception() { m_exception = nullptr; } @@ -138,6 +139,7 @@ private: Object* m_object_prototype { nullptr }; Object* m_array_prototype { nullptr }; Object* m_error_prototype { nullptr }; + Object* m_date_prototype { nullptr }; Exception* m_exception { nullptr }; diff --git a/Libraries/LibJS/Makefile b/Libraries/LibJS/Makefile index ad85857e3f4..6e1cff91fc7 100644 --- a/Libraries/LibJS/Makefile +++ b/Libraries/LibJS/Makefile @@ -10,6 +10,9 @@ OBJS = \ Runtime/ArrayPrototype.o \ Runtime/Cell.o \ Runtime/ConsoleObject.o \ + Runtime/Date.o \ + Runtime/DateConstructor.o \ + Runtime/DatePrototype.o \ Runtime/Error.o \ Runtime/ErrorPrototype.o \ Runtime/Exception.o \ diff --git a/Libraries/LibJS/Runtime/Date.cpp b/Libraries/LibJS/Runtime/Date.cpp new file mode 100644 index 00000000000..faa3942075d --- /dev/null +++ b/Libraries/LibJS/Runtime/Date.cpp @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2020, Linus Groh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include + +namespace JS { + +Date::Date(Core::DateTime datetime, u16 milliseconds) + : m_datetime(datetime) + , m_milliseconds(milliseconds) +{ + set_prototype(interpreter().date_prototype()); +} + +Date::~Date() +{ +} + +} diff --git a/Libraries/LibJS/Runtime/Date.h b/Libraries/LibJS/Runtime/Date.h new file mode 100644 index 00000000000..c4d374e9e1d --- /dev/null +++ b/Libraries/LibJS/Runtime/Date.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2020, Linus Groh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include + +namespace JS { + +class Date final : public Object { +public: + Date(Core::DateTime datetime, u16 milliseconds); + virtual ~Date() override; + + Core::DateTime& datetime() { return m_datetime; } + u16 milliseconds() { return m_milliseconds; } + virtual Value value_of() const override + { + return Value(static_cast(m_datetime.timestamp() * 1000 + m_milliseconds)); + } + +private: + virtual bool is_date() const final { return true; } + virtual const char* class_name() const override { return "Date"; } + + Core::DateTime m_datetime; + u16 m_milliseconds; +}; + +} diff --git a/Libraries/LibJS/Runtime/DateConstructor.cpp b/Libraries/LibJS/Runtime/DateConstructor.cpp new file mode 100644 index 00000000000..7e4f9ed41c5 --- /dev/null +++ b/Libraries/LibJS/Runtime/DateConstructor.cpp @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2020, Linus Groh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include + +namespace JS { + +DateConstructor::DateConstructor() +{ + put("prototype", interpreter().date_prototype()); + put("length", Value(7)); + + put_native_function("now", now); +} + +DateConstructor::~DateConstructor() +{ +} + +Value DateConstructor::call(Interpreter& interpreter) +{ + // TODO: Support args + struct timeval tv; + gettimeofday(&tv, nullptr); + auto datetime = Core::DateTime::now(); + auto milliseconds = static_cast(tv.tv_usec / 1000); + return interpreter.heap().allocate(datetime, milliseconds); +} + +Value DateConstructor::now(Interpreter&) +{ + struct timeval tv; + gettimeofday(&tv, nullptr); + return Value(tv.tv_sec * 1000.0 + tv.tv_usec / 1000.0); +} + +} diff --git a/Libraries/LibJS/Runtime/DateConstructor.h b/Libraries/LibJS/Runtime/DateConstructor.h new file mode 100644 index 00000000000..82a3f2eb0b9 --- /dev/null +++ b/Libraries/LibJS/Runtime/DateConstructor.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2020, Linus Groh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include + +namespace JS { + +class DateConstructor final : public NativeFunction { +public: + DateConstructor(); + virtual ~DateConstructor() override; + + virtual Value call(Interpreter&) override; + +private: + virtual const char* class_name() const override { return "DateConstructor"; } + + static Value now(Interpreter&); +}; + +} diff --git a/Libraries/LibJS/Runtime/DatePrototype.cpp b/Libraries/LibJS/Runtime/DatePrototype.cpp new file mode 100644 index 00000000000..9be2217c968 --- /dev/null +++ b/Libraries/LibJS/Runtime/DatePrototype.cpp @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2020, Linus Groh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace JS { + +static Date* this_date_from_interpreter(Interpreter& interpreter) +{ + auto* this_object = interpreter.this_value().to_object(interpreter.heap()); + if (!this_object) + return nullptr; + if (!this_object->is_date()) { + interpreter.throw_exception("TypeError", "object must be of type Date"); + return nullptr; + } + return static_cast(this_object); +} + +DatePrototype::DatePrototype() +{ + put_native_function("getDate", get_date); + put_native_function("getDay", get_day); + put_native_function("getFullYear", get_full_year); + put_native_function("getHours", get_hours); + put_native_function("getMilliseconds", get_milliseconds); + put_native_function("getMinutes", get_minutes); + put_native_function("getMonth", get_month); + put_native_function("getSeconds", get_seconds); + put_native_function("getTime", get_time); +} + +DatePrototype::~DatePrototype() +{ +} + +Value DatePrototype::get_date(Interpreter& interpreter) +{ + auto* this_object = this_date_from_interpreter(interpreter); + if (!this_object) + return {}; + auto date = this_object->datetime().day(); + return Value(static_cast(date)); +} + +Value DatePrototype::get_day(Interpreter& interpreter) +{ + auto* this_object = this_date_from_interpreter(interpreter); + if (!this_object) + return {}; + auto day = this_object->datetime().weekday(); + return Value(static_cast(day)); +} + +Value DatePrototype::get_full_year(Interpreter& interpreter) +{ + auto* this_object = this_date_from_interpreter(interpreter); + if (!this_object) + return {}; + auto full_year = this_object->datetime().year(); + return Value(static_cast(full_year)); +} + +Value DatePrototype::get_hours(Interpreter& interpreter) +{ + auto* this_object = this_date_from_interpreter(interpreter); + if (!this_object) + return {}; + auto hours = this_object->datetime().hour(); + return Value(static_cast(hours)); +} + +Value DatePrototype::get_milliseconds(Interpreter& interpreter) +{ + auto* this_object = this_date_from_interpreter(interpreter); + if (!this_object) + return {}; + auto milliseconds = this_object->milliseconds(); + return Value(static_cast(milliseconds)); +} + +Value DatePrototype::get_minutes(Interpreter& interpreter) +{ + auto* this_object = this_date_from_interpreter(interpreter); + if (!this_object) + return {}; + auto minutes = this_object->datetime().minute(); + return Value(static_cast(minutes)); +} + +Value DatePrototype::get_month(Interpreter& interpreter) +{ + auto* this_object = this_date_from_interpreter(interpreter); + if (!this_object) + return {}; + auto months = this_object->datetime().month() - 1; + return Value(static_cast(months)); +} + +Value DatePrototype::get_seconds(Interpreter& interpreter) +{ + auto* this_object = this_date_from_interpreter(interpreter); + if (!this_object) + return {}; + auto seconds = this_object->datetime().second(); + return Value(static_cast(seconds)); +} + +Value DatePrototype::get_time(Interpreter& interpreter) +{ + auto* this_object = this_date_from_interpreter(interpreter); + if (!this_object) + return {}; + auto seconds = this_object->datetime().timestamp(); + auto milliseconds = this_object->milliseconds(); + return Value(static_cast(seconds * 1000 + milliseconds)); +} + +} diff --git a/Libraries/LibJS/Runtime/DatePrototype.h b/Libraries/LibJS/Runtime/DatePrototype.h new file mode 100644 index 00000000000..9ed93a092cc --- /dev/null +++ b/Libraries/LibJS/Runtime/DatePrototype.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2020, Linus Groh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include + +namespace JS { + +class DatePrototype final : public Object { +public: + DatePrototype(); + virtual ~DatePrototype() override; + +private: + virtual const char* class_name() const override { return "DatePrototype"; } + + static Value get_date(Interpreter&); + static Value get_day(Interpreter&); + static Value get_full_year(Interpreter&); + static Value get_hours(Interpreter&); + static Value get_milliseconds(Interpreter&); + static Value get_minutes(Interpreter&); + static Value get_month(Interpreter&); + static Value get_seconds(Interpreter&); + static Value get_time(Interpreter&); +}; + +} diff --git a/Libraries/LibJS/Runtime/GlobalObject.cpp b/Libraries/LibJS/Runtime/GlobalObject.cpp index b637b2e23b7..627a7b97761 100644 --- a/Libraries/LibJS/Runtime/GlobalObject.cpp +++ b/Libraries/LibJS/Runtime/GlobalObject.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -17,6 +18,7 @@ GlobalObject::GlobalObject() put_native_function("isNaN", is_nan); put("console", heap().allocate()); + put("Date", heap().allocate()); put("Math", heap().allocate()); put("Object", heap().allocate()); } diff --git a/Libraries/LibJS/Runtime/Object.h b/Libraries/LibJS/Runtime/Object.h index 537037dfa8d..026668b9785 100644 --- a/Libraries/LibJS/Runtime/Object.h +++ b/Libraries/LibJS/Runtime/Object.h @@ -49,12 +49,13 @@ public: void put_native_function(const FlyString& property_name, AK::Function); void put_native_property(const FlyString& property_name, AK::Function getter, AK::Function setter); - virtual bool is_error() const { return false; } virtual bool is_array() const { return false; } + virtual bool is_date() const { return false; } + virtual bool is_error() const { return false; } virtual bool is_function() const { return false; } virtual bool is_native_function() const { return false; } - virtual bool is_string_object() const { return false; } virtual bool is_native_property() const { return false; } + virtual bool is_string_object() const { return false; } virtual const char* class_name() const override { return "Object"; } virtual void visit_children(Cell::Visitor&) override; diff --git a/Libraries/LibJS/Runtime/Value.cpp b/Libraries/LibJS/Runtime/Value.cpp index 50fd735b41c..809f7b57565 100644 --- a/Libraries/LibJS/Runtime/Value.cpp +++ b/Libraries/LibJS/Runtime/Value.cpp @@ -58,7 +58,7 @@ String Value::to_string() const return "NaN"; // FIXME: This needs improvement. - return String::number((i32)as_double()); + return String::format("%f", as_double()); } if (is_object()) diff --git a/Libraries/LibJS/Runtime/Value.h b/Libraries/LibJS/Runtime/Value.h index 5559eacbcfb..920abd9a5c6 100644 --- a/Libraries/LibJS/Runtime/Value.h +++ b/Libraries/LibJS/Runtime/Value.h @@ -53,7 +53,7 @@ public: bool is_cell() const { return is_string() || is_object(); } bool is_array() const; - bool is_nan() const { return is_number() && __builtin_isnan( as_double()); } + bool is_nan() const { return is_number() && __builtin_isnan(as_double()); } Value() : m_type(Type::Undefined) diff --git a/Libraries/LibJS/Tests/Date.now.js b/Libraries/LibJS/Tests/Date.now.js new file mode 100644 index 00000000000..53eb00d6bbf --- /dev/null +++ b/Libraries/LibJS/Tests/Date.now.js @@ -0,0 +1,15 @@ +function assert(x) { if (!x) throw 1; } + +try { + var last = 0; + for (var i = 0; i < 100; ++i) { + var now = Date.now(); + assert(!isNaN(now)) + assert(now > 1580000000000); + assert(now >= last); + last = now; + } + console.log("PASS"); +} catch (e) { + console.log("FAIL: " + e); +} diff --git a/Libraries/LibJS/Tests/Date.prototype.getDate.js b/Libraries/LibJS/Tests/Date.prototype.getDate.js new file mode 100644 index 00000000000..d8a9df88a37 --- /dev/null +++ b/Libraries/LibJS/Tests/Date.prototype.getDate.js @@ -0,0 +1,11 @@ +function assert(x) { if (!x) throw 1; } + +try { + var d = new Date(); + assert(!isNaN(d.getDate())); + assert(1 <= d.getDate() <= 31); + assert(d.getDate() === d.getDate()); + console.log("PASS"); +} catch (e) { + console.log("FAIL: " + e); +} diff --git a/Libraries/LibJS/Tests/Date.prototype.getDay.js b/Libraries/LibJS/Tests/Date.prototype.getDay.js new file mode 100644 index 00000000000..572dd57b737 --- /dev/null +++ b/Libraries/LibJS/Tests/Date.prototype.getDay.js @@ -0,0 +1,11 @@ +function assert(x) { if (!x) throw 1; } + +try { + var d = new Date(); + assert(!isNaN(d.getDay())); + assert(0 <= d.getDay() <= 6); + assert(d.getDay() === d.getDay()); + console.log("PASS"); +} catch (e) { + console.log("FAIL: " + e); +} diff --git a/Libraries/LibJS/Tests/Date.prototype.getFullYear.js b/Libraries/LibJS/Tests/Date.prototype.getFullYear.js new file mode 100644 index 00000000000..1f5b9a443d5 --- /dev/null +++ b/Libraries/LibJS/Tests/Date.prototype.getFullYear.js @@ -0,0 +1,11 @@ +function assert(x) { if (!x) throw 1; } + +try { + var d = new Date(); + assert(!isNaN(d.getFullYear())); + assert(d.getFullYear() >= 2020); + assert(d.getFullYear() === d.getFullYear()); + console.log("PASS"); +} catch (e) { + console.log("FAIL: " + e); +} diff --git a/Libraries/LibJS/Tests/Date.prototype.getHours.js b/Libraries/LibJS/Tests/Date.prototype.getHours.js new file mode 100644 index 00000000000..799e1e2247e --- /dev/null +++ b/Libraries/LibJS/Tests/Date.prototype.getHours.js @@ -0,0 +1,11 @@ +function assert(x) { if (!x) throw 1; } + +try { + var d = new Date(); + assert(!isNaN(d.getHours())); + assert(0 <= d.getHours() <= 23); + assert(d.getHours() === d.getHours()); + console.log("PASS"); +} catch (e) { + console.log("FAIL: " + e); +} diff --git a/Libraries/LibJS/Tests/Date.prototype.getMilliseconds.js b/Libraries/LibJS/Tests/Date.prototype.getMilliseconds.js new file mode 100644 index 00000000000..04f7e82b401 --- /dev/null +++ b/Libraries/LibJS/Tests/Date.prototype.getMilliseconds.js @@ -0,0 +1,11 @@ +function assert(x) { if (!x) throw 1; } + +try { + var d = new Date(); + assert(!isNaN(d.getMilliseconds())); + assert(0 <= d.getMilliseconds() <= 999); + assert(d.getMilliseconds() === d.getMilliseconds()); + console.log("PASS"); +} catch (e) { + console.log("FAIL: " + e); +} diff --git a/Libraries/LibJS/Tests/Date.prototype.getMinutes.js b/Libraries/LibJS/Tests/Date.prototype.getMinutes.js new file mode 100644 index 00000000000..13910bbd994 --- /dev/null +++ b/Libraries/LibJS/Tests/Date.prototype.getMinutes.js @@ -0,0 +1,11 @@ +function assert(x) { if (!x) throw 1; } + +try { + var d = new Date(); + assert(!isNaN(d.getMinutes())); + assert(0 <= d.getMinutes() <= 59); + assert(d.getMinutes() === d.getMinutes()); + console.log("PASS"); +} catch (e) { + console.log("FAIL: " + e); +} diff --git a/Libraries/LibJS/Tests/Date.prototype.getMonth.js b/Libraries/LibJS/Tests/Date.prototype.getMonth.js new file mode 100644 index 00000000000..4ece401aca3 --- /dev/null +++ b/Libraries/LibJS/Tests/Date.prototype.getMonth.js @@ -0,0 +1,11 @@ +function assert(x) { if (!x) throw 1; } + +try { + var d = new Date(); + assert(!isNaN(d.getMonth())); + assert(0 <= d.getMonth() <= 11); + assert(d.getMonth() === d.getMonth()); + console.log("PASS"); +} catch (e) { + console.log("FAIL: " + e); +} diff --git a/Libraries/LibJS/Tests/Date.prototype.getSeconds.js b/Libraries/LibJS/Tests/Date.prototype.getSeconds.js new file mode 100644 index 00000000000..b3cd3524733 --- /dev/null +++ b/Libraries/LibJS/Tests/Date.prototype.getSeconds.js @@ -0,0 +1,11 @@ +function assert(x) { if (!x) throw 1; } + +try { + var d = new Date(); + assert(!isNaN(d.getSeconds())); + assert(0 <= d.getSeconds() <= 59); + assert(d.getSeconds() === d.getSeconds()); + console.log("PASS"); +} catch (e) { + console.log("FAIL: " + e); +} diff --git a/Libraries/LibJS/Tests/Date.prototype.getTime.js b/Libraries/LibJS/Tests/Date.prototype.getTime.js new file mode 100644 index 00000000000..4f1da2db8d6 --- /dev/null +++ b/Libraries/LibJS/Tests/Date.prototype.getTime.js @@ -0,0 +1,11 @@ +function assert(x) { if (!x) throw 1; } + +try { + var d = new Date(); + assert(!isNaN(d.getTime())); + assert(d.getTime() > 1580000000000); + assert(d.getTime() === d.getTime()); + console.log("PASS"); +} catch (e) { + console.log("FAIL: " + e); +} diff --git a/Userland/Makefile b/Userland/Makefile index f54982312e9..81b72b61b64 100644 --- a/Userland/Makefile +++ b/Userland/Makefile @@ -4,7 +4,7 @@ APPS = ${SRCS:.cpp=} EXTRA_CLEAN = $(APPS) -LIB_DEPS = Web GUI Gfx Audio Protocol IPC Thread Pthread Core PCIDB Markdown JS +LIB_DEPS = Web GUI Gfx Audio Protocol IPC Thread Pthread PCIDB Markdown JS Core include ../Makefile.common