Browse Source

[exec Map] Map.prototype.values and Map.prototype.keys implementation (#874)

* Initial commit

* Improving on Map iterator

* Improvements on the iterator

* Almost finish the next method of MapIterator

* Add different kinds to next

* fmt

* Add function description. Add test.

* Added symbol_iterator method. Refactor to use exactly the same function as "entries". Added test for it, unignored pending test.

* Remove TODOs

* [exec Map] keys and values prototype methods
pull/878/head
croraf 4 years ago committed by GitHub
parent
commit
5ac5b5d93e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 30
      boa/src/builtins/map/mod.rs
  2. 54
      boa/src/builtins/map/tests.rs

30
boa/src/builtins/map/mod.rs

@ -50,12 +50,14 @@ impl BuiltIn for Map {
entries_function,
Attribute::WRITABLE | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE,
)
.method(Self::keys, "keys", 0)
.method(Self::set, "set", 2)
.method(Self::delete, "delete", 1)
.method(Self::get, "get", 1)
.method(Self::clear, "clear", 0)
.method(Self::has, "has", 1)
.method(Self::for_each, "forEach", 1)
.method(Self::values, "values", 0)
.callable(false)
.build();
@ -134,6 +136,20 @@ impl Map {
MapIterator::create_map_iterator(ctx, this.clone(), MapIterationKind::KeyAndValue)
}
/// `Map.prototype.keys()`
///
/// Returns a new Iterator object that contains the keys for each element in the Map object in insertion order.
///
/// More information:
/// - [ECMAScript reference][spec]
/// - [MDN documentation][mdn]
///
/// [spec]: https://tc39.es/ecma262/#sec-map.prototype.keys
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/keys
pub(crate) fn keys(this: &Value, _: &[Value], ctx: &mut Context) -> Result<Value> {
MapIterator::create_map_iterator(ctx, this.clone(), MapIterationKind::Key)
}
/// Helper function to set the size property.
fn set_size(this: &Value, size: usize) {
let size = DataDescriptor::new(
@ -321,6 +337,20 @@ impl Map {
Ok(Value::Undefined)
}
/// `Map.prototype.values()`
///
/// Returns a new Iterator object that contains the values for each element in the Map object in insertion order.
///
/// More information:
/// - [ECMAScript reference][spec]
/// - [MDN documentation][mdn]
///
/// [spec]: https://tc39.es/ecma262/#sec-map.prototype.values
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/values
pub(crate) fn values(this: &Value, _: &[Value], ctx: &mut Context) -> Result<Value> {
MapIterator::create_map_iterator(ctx, this.clone(), MapIterationKind::Value)
}
/// Helper function to get a key-value pair from an array.
fn get_key_value(value: &Value) -> Option<(Value, Value)> {
if let Value::Object(object) = value {

54
boa/src/builtins/map/tests.rs

@ -210,6 +210,33 @@ fn has() {
assert_eq!(result, "false");
}
#[test]
fn keys() {
let mut engine = Context::new();
let init = r#"
const map1 = new Map();
map1.set('0', 'foo');
map1.set(1, 'bar');
const keysIterator = map1.keys();
let item1 = keysIterator.next();
let item2 = keysIterator.next();
let item3 = keysIterator.next();
"#;
forward(&mut engine, init);
let result = forward(&mut engine, "item1.value");
assert_eq!(result, "\"0\"");
let result = forward(&mut engine, "item1.done");
assert_eq!(result, "false");
let result = forward(&mut engine, "item2.value");
assert_eq!(result, "1");
let result = forward(&mut engine, "item2.done");
assert_eq!(result, "false");
let result = forward(&mut engine, "item3.value");
assert_eq!(result, "undefined");
let result = forward(&mut engine, "item3.done");
assert_eq!(result, "true");
}
#[test]
fn for_each() {
let mut engine = Context::new();
@ -231,6 +258,33 @@ fn for_each() {
assert_eq!(forward(&mut engine, "sizeSum"), "9");
}
#[test]
fn values() {
let mut engine = Context::new();
let init = r#"
const map1 = new Map();
map1.set('0', 'foo');
map1.set(1, 'bar');
const valuesIterator = map1.values();
let item1 = valuesIterator.next();
let item2 = valuesIterator.next();
let item3 = valuesIterator.next();
"#;
forward(&mut engine, init);
let result = forward(&mut engine, "item1.value");
assert_eq!(result, "\"foo\"");
let result = forward(&mut engine, "item1.done");
assert_eq!(result, "false");
let result = forward(&mut engine, "item2.value");
assert_eq!(result, "\"bar\"");
let result = forward(&mut engine, "item2.done");
assert_eq!(result, "false");
let result = forward(&mut engine, "item3.value");
assert_eq!(result, "undefined");
let result = forward(&mut engine, "item3.done");
assert_eq!(result, "true");
}
#[test]
fn modify_key() {
let mut engine = Context::new();

Loading…
Cancel
Save