Map constructor

This commit is contained in:
Leonardo Balter 2015-06-25 12:06:04 -07:00
parent 6f22dad152
commit a55385c716
25 changed files with 726 additions and 2 deletions

View File

@ -0,0 +1,10 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
es6id: 23.1.1
description: >
The Map constructor is the %Map% intrinsic object and the initial value of the
Map property of the global object.
---*/
assert.sameValue(typeof Map, 'function', 'typeof Map is "function"');

View File

@ -0,0 +1,29 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
es6id: 23.1.1.1
description: >
Creating a new Map object without arguments doesn't throw if `set` is not
callable
info: >
Map ( [ iterable ] )
When the Set function is called with optional argument iterable the following steps are taken:
...
5. If iterable is not present, let iterable be undefined.
6. If iterable is either undefined or null, let iter be undefined.
7. Else,
a. Let adder be Get(map, "set").
b. ReturnIfAbrupt(adder).
c. If IsCallable(adder) is false, throw a TypeError exception.
...
8. If iter is undefined, return map.
...
---*/
Map.prototype.set = null;
var m = new Map();
assert.sameValue(m.size, 0, 'The value of `m.size` is `0`');

View File

@ -0,0 +1,26 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
es6id: 23.1.1.1
description: >
new Map returns abrupt from getting Map.prototype.set.
description: >
Map ( [ iterable ] )
...
7. Else,
a. Let adder be Get(map, "add").
b. ReturnIfAbrupt(adder).
---*/
Object.defineProperty(Map.prototype, 'set', {
get: function() {
throw new Test262Error();
}
});
new Map();
assert.throws(Test262Error, function() {
new Map([]);
});

View File

@ -0,0 +1,39 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
es6id: 23.1.1.1
description: >
new Map calls `set` for each item on the iterable argument in order.
info: >
Map ( [ iterable ] )
...
9. Repeat
...
k. Let status be Call(adder, map, «k.[[value]], v.[[value]]»).
...
includes: [compareArray.js]
---*/
var mapSet = Map.prototype.set;
var counter = 0;
var iterable = [["foo", 1], ["bar", 2]];
var results = [];
var _this = [];
Map.prototype.set = function(k, v) {
counter++;
results.push([k, v]);
_this.push(this);
mapSet.call(this, k, v);
};
var map = new Map(iterable);
assert.sameValue(counter, 2, "`Map.prototype.set` called twice.");
assert(compareArray(results[0], iterable[0]));
assert(compareArray(results[1], iterable[1]));
assert.sameValue(_this[0], map);
assert.sameValue(_this[1], map);

View File

@ -0,0 +1,36 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
es6id: 23.1.1.1
description: >
The iterator is closed when `Map.prototype.set` throws an error.
info: >
Map ( [ iterable ] )
...
9. Repeat
...
k. Let status be Call(adder, map, «k.[[value]], v.[[value]]»).
l. If status is an abrupt completion, return IteratorClose(iter, status).
features: [Symbol.iterator]
---*/
var count = 0;
var iterable = {};
iterable[Symbol.iterator] = function() {
return {
next: function() {
return { value: [], done: false };
},
return: function() {
count += 1;
}
};
};
Map.prototype.set = function() { throw new Test262Error(); }
assert.throws(Test262Error, function() {
new Map(iterable);
});
assert.sameValue(count, 1);

View File

@ -0,0 +1,47 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
es6id: 23.1.1.1
description: >
Closes iterator if item first entry completes abruptly.
info: >
Map ( [ iterable ] )
...
9. Repeat
...
d. Let nextItem be IteratorValue(next).
...
g. Let k be Get(nextItem, "0").
h. If k is an abrupt completion, return IteratorClose(iter, k).
...
features: [Symbol.iterator]
---*/
var count = 0;
var item = ['foo', 'bar'];
Object.defineProperty(item, 0, {
get: function() {
throw new Test262Error();
}
});
var iterable = {};
iterable[Symbol.iterator] = function() {
return {
next: function() {
return {
value: item,
done: false
};
},
return: function() {
count++;
}
};
};
assert.throws(Test262Error, function() {
new Map(iterable);
});
assert.sameValue(count, 1, 'The get error closed the iterator');

View File

@ -0,0 +1,47 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
es6id: 23.1.1.1
description: >
Closes iterator if item second entry completes abruptly.
info: >
Map ( [ iterable ] )
...
9. Repeat
...
d. Let nextItem be IteratorValue(next).
...
i. Let v be Get(nextItem, "1").
j. If v is an abrupt completion, return IteratorClose(iter, v).
...
features: [Symbol.iterator]
---*/
var count = 0;
var item = ['foo', 'bar'];
Object.defineProperty(item, 1, {
get: function() {
throw new Test262Error();
}
});
var iterable = {};
iterable[Symbol.iterator] = function() {
return {
next: function() {
return {
value: item,
done: false
};
},
return: function() {
count++;
}
};
};
assert.throws(Test262Error, function() {
new Map(iterable);
});
assert.sameValue(count, 1, 'The get error closed the iterator');

View File

@ -0,0 +1,72 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
es6id: 23.1.1.1
description: >
Closes the iterator after `not Object` error.
info: >
Map ( [ iterable ] )
...
9. Repeat
...
d. Let nextItem be IteratorValue(next).
e. ReturnIfAbrupt(nextItem).
f. If Type(nextItem) is not Object,
i. Let error be Completion{[[type]]: throw, [[value]]: a newly created
TypeError object, [[target]]:empty}.
ii. Return IteratorClose(iter, error).
features:
- Symbol
- Symbol.iterator
---*/
var count = 0;
var nextItem;
var iterable = {};
iterable[Symbol.iterator] = function() {
return {
next: function() {
return { value: nextItem, done: false };
},
return: function() {
count += 1;
}
};
};
nextItem = 1;
assert.throws(TypeError, function() {
new Map(iterable);
});
assert.sameValue(count, 1);
nextItem = true;
assert.throws(TypeError, function() {
new Map(iterable);
});
assert.sameValue(count, 2);
nextItem = '';
assert.throws(TypeError, function() {
new Map(iterable);
});
assert.sameValue(count, 3);
nextItem = null;
assert.throws(TypeError, function() {
new Map(iterable);
});
assert.sameValue(count, 4);
nextItem = undefined;
assert.throws(TypeError, function() {
new Map(iterable);
});
assert.sameValue(count, 5);
nextItem = Symbol('a');
assert.throws(TypeError, function() {
new Map(iterable);
});
assert.sameValue(count, 6);

View File

@ -0,0 +1,48 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
es6id: 23.1.1.1
description: >
Throws a TypeError if iterable itens are not Objects.
info: >
Map ( [ iterable ] )
...
9. Repeat
...
d. Let nextItem be IteratorValue(next).
e. ReturnIfAbrupt(nextItem).
f. If Type(nextItem) is not Object,
i. Let error be Completion{[[type]]: throw, [[value]]: a newly created
TypeError object, [[target]]:empty}.
ii. Return IteratorClose(iter, error).
features: [Symbol]
---*/
assert.throws(TypeError, function() {
new Map([1]);
});
assert.throws(TypeError, function() {
new Map(['']);
});
assert.throws(TypeError, function() {
new Map([true]);
});
assert.throws(TypeError, function() {
new Map([null]);
});
assert.throws(TypeError, function() {
new Map([Symbol('a')]);
});
assert.throws(TypeError, function() {
new Map([undefined]);
});
assert.throws(TypeError, function() {
new Map([['a', 1], 2]);
});

View File

@ -0,0 +1,28 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
es6id: 23.1.1.1
description: >
The iterator is closed when iterable `next` throws an error.
info: >
Map ( [ iterable ] )
...
9. Repeat
a. Let next be IteratorStep(iter).
b. ReturnIfAbrupt(next).
features: [Symbol.iterator]
---*/
var iterable = {};
iterable[Symbol.iterator] = function() {
return {
next: function() {
throw new Test262Error();
}
};
};
assert.throws(Test262Error, function() {
new Map(iterable);
});

View File

@ -0,0 +1,34 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
es6id: 23.1.1.1
description: >
The iterator is closed when iterable `next` value throws an error.
info: >
Map ( [ iterable ] )
...
9. Repeat
...
d. Let nextItem be IteratorValue(next).
e. ReturnIfAbrupt(nextItem).
features: [Symbol.iterator]
---*/
var iterable = {};
iterable[Symbol.iterator] = function() {
return {
next: function() {
return {
get value() {
throw new Test262Error();
},
done: false
};
}
};
};
assert.throws(Test262Error, function() {
new Map(iterable);
});

View File

@ -0,0 +1,17 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
es6id: 23.1.2
description: Map.length is 0.
info: >
Properties of the Map Constructor
Besides the length property (whose value is 0)
includes: [propertyHelper.js]
---*/
assert.sameValue(Map.length, 0, 'The value of Map.length is 0');
verifyNotEnumerable(Map, 'length');
verifyNotWritable(Map, 'length');
verifyConfigurable(Map, 'length');

View File

@ -0,0 +1,31 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
es6id: 23.1.1.1
description: >
A Map constructed with an empty iterable argument does not call set.
info: >
Map ( [ iterable ] )
When the Map function is called with optional argument the following steps are
taken:
...
8. If iter is undefined, return map.
9. Repeat
a. Let next be IteratorStep(iter).
b. ReturnIfAbrupt(next).
c. If next is false, return map.
---*/
var set = Map.prototype.set;
var counter = 0;
Map.prototype.set = function(value) {
counter++;
set.call(this, value);
};
new Map([]);
assert.sameValue(counter, 0, '`Map.prototype.set` was not called.');

View File

@ -0,0 +1,27 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
es6id: 23.1.1.1
description: >
Throws a TypeError if `set` is not callable on Map constructor with a
iterable argument.
info: >
Map ( [ iterable ] )
When the Map function is called with optional argument the following steps are
taken:
...
5. If iterable is not present, let iterable be undefined.
6. If iterable is either undefined or null, let iter be undefined.
7. Else,
a. Let adder be Get(map, "set").
b. ReturnIfAbrupt(adder).
c. If IsCallable(adder) is false, throw a TypeError exception.
---*/
Map.prototype.set = null;
assert.throws(TypeError, function() {
new Map([[1,1], [2,2]]);
});

View File

@ -0,0 +1,26 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
es6id: 23.1.1.1
description: >
Contructor returns a map object set with the elements from the iterable
argument.
info: >
Map ( [ iterable ] )
...
9. Repeat
a. Let next be IteratorStep(iter).
b. ReturnIfAbrupt(next).
c. If next is false, return map.
...
---*/
var m = new Map([
[ "attr", 1 ],
[ "foo", 2 ]
]);
assert.sameValue(m.size, 2, 'The value of `m.size` is `2`');
assert.sameValue(m.get("attr"), 1);
assert.sameValue(m.get("foo"), 2);

View File

@ -0,0 +1,35 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
es6id: 23.1.1.1
description: >
A Map constructed without a iterable argument does not call set.
info: >
Map ( [ iterable ] )
When the Map function is called with optional argument the following steps are
taken:
...
5. If iterable is not present, let iterable be undefined.
6. If iterable is either undefined or null, let iter be undefined.
7. Else,
a. Let adder be Get(map, "set").
b. ReturnIfAbrupt(adder).
c. If IsCallable(adder) is false, throw a TypeError exception.
d. Let iter be GetIterator(iterable).
e. ReturnIfAbrupt(iter).
8. If iter is undefined, return map.
---*/
var set = Map.prototype.set;
var counter = 0;
Map.prototype.set = function(value) {
counter++;
set.call(this, value);
};
new Map();
assert.sameValue(counter, 0, '`Map.prototype.set` was not called.');

View File

@ -0,0 +1,32 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
es6id: 23.1.1.1
description: >
Returns the new Map object with the new empty list if the iterable argument is
undefined.
info: >
Map ( [ iterable ] )
...
2. Let map be OrdinaryCreateFromConstructor(NewTarget, "%MapPrototype%",
«[[MapData]]» ).
...
4. Map maps [[MapData]] internal slot to a new empty List.
5. If iterable is not present, let iterable be undefined.
6. If iterable is either undefined or null, let iter be undefined.
...
8. If iter is undefined, return map.
---*/
var m1 = new Map();
var m2 = new Map(undefined);
var m3 = new Map(null);
assert.sameValue(m1.size, 0, 'The value of `new Map().size` is `0`');
assert.sameValue(m2.size, 0, 'The value of `new Map(undefined).size` is `0`');
assert.sameValue(m3.size, 0, 'The value of `new Map(null).size` is `0`');
assert(m1 instanceof Map);
assert(m2 instanceof Map);
assert(m3 instanceof Map);

17
test/built-ins/Map/map.js Normal file
View File

@ -0,0 +1,17 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
es6id: 23.1.1.1
description: >
Map descriptor as a standard built-in object.
info: >
Map ( [ iterable ] )
17 ECMAScript Standard Built-in Objects
includes: [propertyHelper.js]
---*/
verifyNotEnumerable(this, 'Map');
verifyWritable(this, 'Map');
verifyConfigurable(this, 'Map');

View File

@ -0,0 +1,18 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
es6id: 23.1.1.1
description: Map.name value and descriptor.
info: >
Map ( [ iterable ] )
17 ECMAScript Standard Built-in Objects
includes: [propertyHelper.js]
---*/
assert.sameValue(Map.name, 'Map', 'The value of Map.name is "Map"');
verifyNotEnumerable(Map, 'name');
verifyNotWritable(Map, 'name');
verifyConfigurable(Map, 'name');

View File

@ -0,0 +1,34 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
es6id: 23.1.1.1
description: >
The new Map object's prototype is Map.prototype
info: >
Map ( [ iterable ] )
When the Map function is called with optional argument the following steps
are taken:
...
2. Let map be OrdinaryCreateFromConstructor(NewTarget, "%MapPrototype%",
«[[MapData]]» ).
...
---*/
var m1 = new Map();
assert.sameValue(
Object.getPrototypeOf(m1),
Map.prototype,
"`Object.getPrototypeOf(m1)` returns `Map.prototype`"
);
var m2 = new Map([[1, 1], [2, 2]]);
assert.sameValue(
Object.getPrototypeOf(m2),
Map.prototype,
"`Object.getPrototypeOf(m2)` returns `Map.prototype`"
);

View File

@ -0,0 +1,14 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
es6id: 23.1.4
description: >
Map instances are ordinary objects that inherit properties from the Map
prototype.
---*/
assert.sameValue(
Object.getPrototypeOf(new Map()),
Map.prototype,
'`Object.getPrototypeOf(new Map())` returns `Map.prototype`'
);

View File

@ -0,0 +1,18 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
es6id: 23.1.3
description: >
The prototype of Map.prototype is Object.prototype.
info: >
The Map prototype object is the intrinsic object %MapPrototype%. The value
of the [[Prototype]] internal slot of the Map prototype object is the
intrinsic object %ObjectPrototype% (19.1.3). The Map prototype object is an
ordinary object. It does not have a [[MapData]] internal slot.
---*/
assert.sameValue(
Object.getPrototypeOf(Map.prototype),
Object.prototype,
'Object.getPrototypeOf(Map.prototype) returns Object.prototype'
);

16
test/built-ins/Map/prototype-of-map.js vendored Normal file
View File

@ -0,0 +1,16 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
es6id: 23.1.2
description: >
The prototype of Map is the intrinsic FunctionPrototype.
info: >
The value of the [[Prototype]] internal slot of the Map constructor is the
intrinsic object %FunctionPrototype% (19.2.3).
---*/
assert.sameValue(
Object.getPrototypeOf(Map),
Function.prototype,
'`Object.getPrototypeOf(Map)` returns `Function.prototype`'
);

View File

@ -4,7 +4,7 @@
es6id: 19.4
description: >
Symbol as Map key
features: [Map]
features: [Symbol]
---*/
var map = new Map();
var sym = Symbol();
@ -16,4 +16,3 @@ assert.sameValue(map.has(sym), true, "`map.has(sym)` returns `true`");
assert.sameValue(map.get(sym), 1, "`map.get(sym)` returns `1`");
assert.sameValue(map.delete(sym), true, "`map.delete(sym)` returns `true`");
assert.sameValue(map.size, 0, "The value of `map.size` is `0`");

View File

@ -0,0 +1,24 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
es6id: 23.1.1.1
description: >
Throws a TypeError if Map is called without a newTarget.
info: >
Map ( [ iterable ] )
When the Map function is called with optional argument the following steps
are taken:
1. If NewTarget is undefined, throw a TypeError exception.
...
---*/
assert.throws(TypeError, function() {
Map();
});
assert.throws(TypeError, function() {
Map([]);
});