Skip to content

Commit

Permalink
[exec Map] Map.prototype.values and Map.prototype.keys implementation (
Browse files Browse the repository at this point in the history
…#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
  • Loading branch information
croraf committed Oct 15, 2020
1 parent e6a28e6 commit 5ac5b5d
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 0 deletions.
30 changes: 30 additions & 0 deletions boa/src/builtins/map/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -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 {
Expand Down
54 changes: 54 additions & 0 deletions boa/src/builtins/map/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -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();
Expand Down

0 comments on commit 5ac5b5d

Please sign in to comment.