Browse Source

Implemented the Array.prototype.some method. (#280)

- Implementd Array.prototype.some method.
- Added tests for Array.prototype.some method.
pull/295/head
HalidOdat 5 years ago committed by GitHub
parent
commit
c365576f37
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 39
      boa/src/builtins/array/mod.rs
  2. 49
      boa/src/builtins/array/tests.rs

39
boa/src/builtins/array/mod.rs

@ -778,6 +778,44 @@ pub fn filter(this: &Value, args: &[Value], interpreter: &mut Interpreter) -> Re
construct_array(&new, &values)
}
/// Array.prototype.some ( callbackfn [ , thisArg ] )
///
/// The some method tests whether at least one element in the array passes
/// the test implemented by the provided callback function. It returns a Boolean value,
/// true if the callback function returns a truthy value for at least one element
/// in the array. Otherwise, false.
///
/// Caution: Calling this method on an empty array returns false for any condition!
/// <https://tc39.es/ecma262/#sec-array.prototype.some/>
pub fn some(this: &Value, args: &[Value], interpreter: &mut Interpreter) -> ResultValue {
if args.is_empty() {
return Err(to_value(
"missing callback when calling function Array.prototype.some".to_string(),
));
}
let callback = &args[0];
let this_arg = if args.len() > 1 {
args[1].clone()
} else {
Gc::new(ValueData::Undefined)
};
let mut i = 0;
let max_len: i32 = from_value(this.get_field_slice("length")).unwrap();
let mut len = max_len;
while i < len {
let element = this.get_field_slice(&i.to_string());
let arguments = vec![element.clone(), to_value(i), this.clone()];
let result = interpreter.call(callback, &this_arg, arguments)?.is_true();
if result {
return Ok(to_value(true));
}
// the length of the array must be updated because the callback can mutate it.
len = min(max_len, from_value(this.get_field_slice("length")).unwrap());
i += 1;
}
Ok(to_value(false))
}
/// Create a new `Array` object
pub fn create_constructor(global: &Value) -> Value {
// Create Constructor
@ -812,6 +850,7 @@ pub fn create_constructor(global: &Value) -> Value {
make_builtin_fn!(find, named "find", with length 1, of array_prototype);
make_builtin_fn!(find_index, named "findIndex", with length 1, of array_prototype);
make_builtin_fn!(slice, named "slice", with length 2, of array_prototype);
make_builtin_fn!(some, named "some", with length 2, of array_prototype);
let array = to_value(array_constructor);
make_builtin_fn!(is_array, named "isArray", with length 1, of array);

49
boa/src/builtins/array/tests.rs

@ -742,3 +742,52 @@ fn filter() {
String::from("0")
);
}
#[test]
fn some() {
let realm = Realm::create();
let mut engine = Executor::new(realm);
let init = r#"
var empty = [];
var array = [11, 23, 45];
function lessThan10(element) {
return element > 10;
}
function greaterThan10(element) {
return element < 10;
}
// Cases where callback mutates the array.
var appendArray = [1,2,3,4];
function appendingCallback(elem,index,arr) {
arr.push('new');
return elem !== "new";
}
var delArray = [1,2,3,4];
function deletingCallback(elem,index,arr) {
arr.pop()
return elem < 3;
}
"#;
forward(&mut engine, init);
let result = forward(&mut engine, "array.some(lessThan10);");
assert_eq!(result, "true");
let result = forward(&mut engine, "empty.some(lessThan10);");
assert_eq!(result, "false");
let result = forward(&mut engine, "array.some(greaterThan10);");
assert_eq!(result, "false");
let result = forward(&mut engine, "appendArray.some(appendingCallback);");
let append_array_length = forward(&mut engine, "appendArray.length");
assert_eq!(append_array_length, "5");
assert_eq!(result, "true");
let result = forward(&mut engine, "delArray.some(deletingCallback);");
let del_array_length = forward(&mut engine, "delArray.length");
assert_eq!(del_array_length, "3");
assert_eq!(result, "true");
}

Loading…
Cancel
Save