Skip to content

Commit

Permalink
implement array.of
Browse files Browse the repository at this point in the history
  • Loading branch information
git committed Feb 13, 2021
1 parent 9e0cab5 commit 1b6f275
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 0 deletions.
34 changes: 34 additions & 0 deletions boa/src/builtins/array/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ impl BuiltIn for Array {
.method(Self::entries, "entries", 0)
// Static Methods
.static_method(Self::is_array, "isArray", 1)
.static_method(Self::of, "of", 0)
.build();

(Self::NAME, array.into(), Self::attribute())
Expand Down Expand Up @@ -304,6 +305,39 @@ impl Array {
}
}

/// `Array.of(...arguments)`
///
/// The Array.of method creates a new Array instance from a variable number of arguments,
/// regardless of the number or type of arguments.
///
/// More information:
/// - [ECMAScript reference][spec]
/// - [MDN documentation][mdn]
///
/// [spec]: https://tc39.es/ecma262/#sec-array.of
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/of
pub(crate) fn of(this: &Value, args: &[Value], context: &mut Context) -> Result<Value> {
let is_constructor = this.is_object() && this.as_object().unwrap().is_constructable();

// construct using `this` if it is a constructor
// otherwise use Array
let array = if is_constructor {
this.as_object().unwrap().construct(
&[Value::from(args.len())],
this.clone(),
context,
)?
} else {
Array::array_create(args.len() as u32, None, context)?
};

// add properties and set length
array.set_field("length", 0, context)?;
Array::add_to_array_object(&array, args, context)?;

Ok(array)
}

/// `Array.prototype.concat(...arguments)`
///
/// When the concat method is called with zero or more arguments, it returns an
Expand Down
59 changes: 59 additions & 0 deletions boa/src/builtins/array/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,65 @@ fn is_array() {
}

#[test]
fn of() {
let mut context = Context::new();
assert_eq!(
context
.eval("Array.of(1, 2, 3)")
.unwrap()
.to_string(&mut context)
.unwrap(),
context
.eval("[1, 2, 3]")
.unwrap()
.to_string(&mut context)
.unwrap()
);
assert_eq!(
context
.eval("Array.of(1, 'a', [], undefined, null)")
.unwrap()
.to_string(&mut context)
.unwrap(),
context
.eval("[1, 'a', [], undefined, null]")
.unwrap()
.to_string(&mut context)
.unwrap()
);
assert_eq!(
context
.eval("Array.of()")
.unwrap()
.to_string(&mut context)
.unwrap(),
context.eval("[]").unwrap().to_string(&mut context).unwrap()
);

context.eval(r#"let a = Array.of.call(Date, "a", undefined, 3);"#).unwrap();
assert_eq!(
context.eval("a instanceof Date").unwrap(),
Value::from(true)
);
assert_eq!(
context.eval("a[0]").unwrap(),
Value::from("a")
);
assert_eq!(
context.eval("a[1]").unwrap(),
Value::undefined()
);
assert_eq!(
context.eval("a[2]").unwrap(),
Value::from(3)
);
assert_eq!(
context.eval("a.length").unwrap(),
Value::from(3)
);

}

#[ignore]
fn concat() {
//TODO: array display formatter
Expand Down

0 comments on commit 1b6f275

Please sign in to comment.