diff --git a/boa/src/builtins/object/mod.rs b/boa/src/builtins/object/mod.rs index 3659c81932..9ed8997bbe 100644 --- a/boa/src/builtins/object/mod.rs +++ b/boa/src/builtins/object/mod.rs @@ -31,6 +31,7 @@ use std::{ }; use super::function::{make_builtin_fn, make_constructor_fn}; +use crate::builtins::value::same_value; pub use internal_state::{InternalState, InternalStateCell}; pub mod internal_methods; @@ -406,6 +407,16 @@ pub fn make_object(_: &mut Value, args: &[Value], ctx: &mut Interpreter) -> Resu Ok(object) } +/// Uses the SameValue algorithm to check equality of objects +pub fn is(_: &mut Value, args: &[Value], _: &mut Interpreter) -> ResultValue { + let x = args.get(0).cloned().unwrap_or_else(Value::undefined); + let y = args.get(1).cloned().unwrap_or_else(Value::undefined); + + let result = same_value(&x, &y, false); + + Ok(Value::boolean(result)) +} + /// Get the `prototype` of an object. pub fn get_prototype_of(_: &mut Value, args: &[Value], _: &mut Interpreter) -> ResultValue { let obj = args.get(0).expect("Cannot get object"); @@ -511,6 +522,7 @@ pub fn create(global: &Value) -> Value { make_builtin_fn(set_prototype_of, "setPrototypeOf", &object, 2); make_builtin_fn(get_prototype_of, "getPrototypeOf", &object, 1); make_builtin_fn(define_property, "defineProperty", &object, 3); + make_builtin_fn(is, "is", &object, 2); object } diff --git a/boa/src/builtins/object/tests.rs b/boa/src/builtins/object/tests.rs index 82659ae43e..f4411b3bc9 100644 --- a/boa/src/builtins/object/tests.rs +++ b/boa/src/builtins/object/tests.rs @@ -1,5 +1,29 @@ use crate::{exec::Interpreter, forward, realm::Realm}; +#[test] +fn object_is() { + let realm = Realm::create(); + let mut engine = Interpreter::new(realm); + + let init = r#" + var foo = { a: 1}; + var bar = { a: 1}; + "#; + + forward(&mut engine, init); + + assert_eq!(forward(&mut engine, "Object.is('foo', 'foo')"), "true"); + assert_eq!(forward(&mut engine, "Object.is('foo', 'bar')"), "false"); + assert_eq!(forward(&mut engine, "Object.is([], [])"), "false"); + assert_eq!(forward(&mut engine, "Object.is(foo, foo)"), "true"); + assert_eq!(forward(&mut engine, "Object.is(foo, bar)"), "false"); + assert_eq!(forward(&mut engine, "Object.is(null, null)"), "true"); + assert_eq!(forward(&mut engine, "Object.is(0, -0)"), "false"); + assert_eq!(forward(&mut engine, "Object.is(-0, -0)"), "true"); + assert_eq!(forward(&mut engine, "Object.is(NaN, 0/0)"), "true"); + assert_eq!(forward(&mut engine, "Object.is()"), "true"); + assert_eq!(forward(&mut engine, "Object.is(undefined)"), "true"); +} #[test] fn object_has_own_property() { let realm = Realm::create();