|
|
@ -271,6 +271,41 @@ pub fn unshift(this: &Value, args: &[Value], _: &mut Interpreter) -> ResultValue |
|
|
|
Ok(to_value(temp)) |
|
|
|
Ok(to_value(temp)) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// Array.prototype.every ( callback, [ thisArg ] )
|
|
|
|
|
|
|
|
///
|
|
|
|
|
|
|
|
/// The every method executes the provided callback function once for each
|
|
|
|
|
|
|
|
/// element present in the array until it finds the one where callback returns
|
|
|
|
|
|
|
|
/// a falsy value. It returns `false` if it finds such element, otherwise it
|
|
|
|
|
|
|
|
/// returns `true`.
|
|
|
|
|
|
|
|
/// <https://tc39.es/ecma262/#sec-array.prototype.every/>
|
|
|
|
|
|
|
|
pub fn every(this: &Value, args: &[Value], interpreter: &mut Interpreter) -> ResultValue { |
|
|
|
|
|
|
|
if args.is_empty() { |
|
|
|
|
|
|
|
return Err(to_value( |
|
|
|
|
|
|
|
"missing callback when calling function Array.prototype.every".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(&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(false)); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
len = std::cmp::min(max_len, from_value(this.get_field_slice("length")).unwrap()); |
|
|
|
|
|
|
|
i += 1; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
Ok(to_value(true)) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/// Array.prototype.indexOf ( searchElement[, fromIndex ] )
|
|
|
|
/// Array.prototype.indexOf ( searchElement[, fromIndex ] )
|
|
|
|
///
|
|
|
|
///
|
|
|
|
///
|
|
|
|
///
|
|
|
@ -431,6 +466,7 @@ pub fn create_constructor(global: &Value) -> Value { |
|
|
|
array_prototype.set_field_slice("reverse", to_value(reverse as NativeFunctionData)); |
|
|
|
array_prototype.set_field_slice("reverse", to_value(reverse as NativeFunctionData)); |
|
|
|
array_prototype.set_field_slice("shift", to_value(shift as NativeFunctionData)); |
|
|
|
array_prototype.set_field_slice("shift", to_value(shift as NativeFunctionData)); |
|
|
|
array_prototype.set_field_slice("unshift", to_value(unshift as NativeFunctionData)); |
|
|
|
array_prototype.set_field_slice("unshift", to_value(unshift as NativeFunctionData)); |
|
|
|
|
|
|
|
array_prototype.set_field_slice("every", to_value(every as NativeFunctionData)); |
|
|
|
array_prototype.set_field_slice("find", to_value(find as NativeFunctionData)); |
|
|
|
array_prototype.set_field_slice("find", to_value(find as NativeFunctionData)); |
|
|
|
array_prototype.set_field_slice("indexOf", index_of_func); |
|
|
|
array_prototype.set_field_slice("indexOf", index_of_func); |
|
|
|
array_prototype.set_field_slice("lastIndexOf", last_index_of_func); |
|
|
|
array_prototype.set_field_slice("lastIndexOf", last_index_of_func); |
|
|
@ -493,6 +529,51 @@ mod tests { |
|
|
|
assert_eq!(many, String::from("a.b.c")); |
|
|
|
assert_eq!(many, String::from("a.b.c")); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#[test] |
|
|
|
|
|
|
|
fn every() { |
|
|
|
|
|
|
|
let realm = Realm::create(); |
|
|
|
|
|
|
|
let mut engine = Executor::new(realm); |
|
|
|
|
|
|
|
// taken from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/every
|
|
|
|
|
|
|
|
let init = r#" |
|
|
|
|
|
|
|
let empty = []; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let array = [11, 23, 45]; |
|
|
|
|
|
|
|
function callback(element) { |
|
|
|
|
|
|
|
return element > 10; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
function callback2(element) { |
|
|
|
|
|
|
|
return element < 10; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let appendArray = [1,2,3,4]; |
|
|
|
|
|
|
|
function appendingCallback(elem,index,arr) { |
|
|
|
|
|
|
|
arr.push('new'); |
|
|
|
|
|
|
|
return elem !== "new"; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let 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.every(callback);"); |
|
|
|
|
|
|
|
assert_eq!(result, "true"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let result = forward(&mut engine, "empty.every(callback);"); |
|
|
|
|
|
|
|
assert_eq!(result, "true"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let result = forward(&mut engine, "array.every(callback2);"); |
|
|
|
|
|
|
|
assert_eq!(result, "false"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let result = forward(&mut engine, "appendArray.every(appendingCallback);"); |
|
|
|
|
|
|
|
assert_eq!(result, "true"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let result = forward(&mut engine, "delArray.every(deletingCallback);"); |
|
|
|
|
|
|
|
assert_eq!(result, "true"); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
#[test] |
|
|
|
#[test] |
|
|
|
fn find() { |
|
|
|
fn find() { |
|
|
|
let realm = Realm::create(); |
|
|
|
let realm = Realm::create(); |
|
|
|