LibJS: Implement Temporal.PlainDate.prototype.equals & Required AO

This commit is contained in:
Idan Horowitz 2021-07-21 22:21:45 +03:00 committed by Linus Groh
parent cf78efaef5
commit d804ce830d
Notes: sideshowbarker 2024-07-18 08:37:18 +09:00
5 changed files with 69 additions and 0 deletions

View file

@ -231,6 +231,31 @@ PlainDate* date_from_fields(GlobalObject& global_object, Object& calendar, Objec
return static_cast<PlainDate*>(date_object);
}
// 12.1.28 CalendarEquals ( one, two ), https://tc39.es/proposal-temporal/#sec-temporal-calendarequals
bool calendar_equals(GlobalObject& global_object, Object& one, Object& two)
{
auto& vm = global_object.vm();
// 1. If one and two are the same Object value, return true.
if (&one == &two)
return true;
// 2. Let calendarOne be ? ToString(one).
auto calendar_one = Value(&one).to_string(global_object);
if (vm.exception())
return {};
// 3. Let calendarTwo be ? ToString(two).
auto calendar_two = Value(&two).to_string(global_object);
if (vm.exception())
return {};
// 4. If calendarOne is calendarTwo, return true.
if (calendar_one == calendar_two)
return true;
// 5. Return false.
return false;
}
// 12.1.30 IsISOLeapYear ( year ), https://tc39.es/proposal-temporal/#sec-temporal-isisoleapyear
bool is_iso_leap_year(i32 year)
{

View file

@ -38,6 +38,7 @@ Object* to_temporal_calendar(GlobalObject&, Value);
Object* to_temporal_calendar_with_iso_default(GlobalObject&, Value);
Object* get_temporal_calendar_with_iso_default(GlobalObject&, Object&);
PlainDate* date_from_fields(GlobalObject&, Object& calendar, Object& fields, Object& options);
bool calendar_equals(GlobalObject&, Object& one, Object& two);
bool is_iso_leap_year(i32 year);
i32 iso_days_in_month(i32 year, i32 month);
String build_iso_month_code(i32 month);

View file

@ -5,6 +5,7 @@
*/
#include <LibJS/Runtime/GlobalObject.h>
#include <LibJS/Runtime/Temporal/Calendar.h>
#include <LibJS/Runtime/Temporal/PlainDate.h>
#include <LibJS/Runtime/Temporal/PlainDatePrototype.h>
@ -28,6 +29,7 @@ void PlainDatePrototype::initialize(GlobalObject& global_object)
define_native_accessor(vm.names.calendar, calendar_getter, {}, Attribute::Configurable);
u8 attr = Attribute::Writable | Attribute::Configurable;
define_native_function(vm.names.equals, equals, 1, attr);
define_native_function(vm.names.valueOf, value_of, 0, attr);
}
@ -57,6 +59,33 @@ JS_DEFINE_NATIVE_FUNCTION(PlainDatePrototype::calendar_getter)
return Value(&temporal_date->calendar());
}
// 3.3.25 Temporal.PlainDate.prototype.equals ( other ), https://tc39.es/proposal-temporal/#sec-temporal.plaindate.prototype.equals
JS_DEFINE_NATIVE_FUNCTION(PlainDatePrototype::equals)
{
// 1. Let temporalDate be the this value.
// 2. Perform ? RequireInternalSlot(temporalDate, [[InitializedTemporalDate]]).
auto* temporal_date = typed_this(global_object);
if (vm.exception())
return {};
// 3. Set other to ? ToTemporalDate(other).
auto* other = to_temporal_date(global_object, vm.argument(0));
if (vm.exception())
return {};
// 4. If temporalDate.[[ISOYear]] ≠ other.[[ISOYear]], return false.
if (temporal_date->iso_year() != other->iso_year())
return Value(false);
// 5. If temporalDate.[[ISOMonth]] ≠ other.[[ISOMonth]], return false.
if (temporal_date->iso_month() != other->iso_month())
return Value(false);
// 6. If temporalDate.[[ISODay]] ≠ other.[[ISODay]], return false.
if (temporal_date->iso_day() != other->iso_day())
return Value(false);
// 7. Return ? CalendarEquals(temporalDate.[[Calendar]], other.[[Calendar]]).
return Value(calendar_equals(global_object, temporal_date->calendar(), other->calendar()));
}
// 3.3.31 Temporal.PlainDate.prototype.valueOf ( ), https://tc39.es/proposal-temporal/#sec-temporal.plaindate.prototype.valueof
JS_DEFINE_NATIVE_FUNCTION(PlainDatePrototype::value_of)
{

View file

@ -21,6 +21,7 @@ public:
private:
JS_DECLARE_NATIVE_FUNCTION(calendar_getter);
JS_DECLARE_NATIVE_FUNCTION(equals);
JS_DECLARE_NATIVE_FUNCTION(value_of);
};

View file

@ -0,0 +1,13 @@
describe("correct behavior", () => {
test("length is 1", () => {
expect(Temporal.PlainDate.prototype.equals).toHaveLength(1);
});
test("basic functionality", () => {
const calendar = { hello: "friends" };
const first_plain_date = new Temporal.PlainDate(1, 1, 1, calendar);
const second_plain_date = new Temporal.PlainDate(0, 1, 1, calendar);
expect(first_plain_date.equals(first_plain_date));
expect(!first_plain_date.equals(second_plain_date));
});
});