From 0f4435b448f7cffec0afbf6e27ecf4bafb118184 Mon Sep 17 00:00:00 2001 From: Denis Pushkarev Date: Tue, 27 Oct 2015 03:09:18 +0600 Subject: [PATCH] fix old V8 bug - `Weak(Map|Set)#{delete, get, has}` should not throw error on primitive, close #124 --- library/modules/$.collection.js | 8 ++- modules/$.collection.js | 44 +++++++------ modules/library/$.collection.js | 8 ++- tests/library.js | 47 ++++++++++---- tests/library/es6.weak-map.ls | 15 +++-- tests/library/es6.weak-set.ls | 14 +++-- tests/tests.js | 106 ++++++++++++++++++++++++++++---- tests/tests/es6.weak-map.ls | 15 +++-- tests/tests/es6.weak-set.ls | 14 +++-- 9 files changed, 200 insertions(+), 71 deletions(-) diff --git a/library/modules/$.collection.js b/library/modules/$.collection.js index 9e9808f2258d..0cde2f2b9623 100644 --- a/library/modules/$.collection.js +++ b/library/modules/$.collection.js @@ -3,7 +3,8 @@ var $ = require('./$') , $def = require('./$.def') , hide = require('./$.hide') , forOf = require('./$.for-of') - , strictNew = require('./$.strict-new'); + , strictNew = require('./$.strict-new') + , isObject = require('./$.is-object'); module.exports = function(NAME, wrapper, methods, common, IS_MAP, IS_WEAK){ var Base = require('./$.global')[NAME] @@ -24,10 +25,11 @@ module.exports = function(NAME, wrapper, methods, common, IS_MAP, IS_WEAK){ if(iterable != undefined)forOf(iterable, IS_MAP, target[ADDER], target); }); $.each.call('add,clear,delete,forEach,get,has,set,keys,values,entries'.split(','),function(KEY){ - var chain = KEY == 'add' || KEY == 'set'; + var IS_ADDER = KEY == 'add' || KEY == 'set'; if(KEY in proto && !(IS_WEAK && KEY == 'clear'))hide(C.prototype, KEY, function(a, b){ + if(!IS_ADDER && IS_WEAK && !isObject(a))return false; var result = this._c[KEY](a === 0 ? 0 : a, b); - return chain ? this : result; + return IS_ADDER ? this : result; }); }); if('size' in proto)$.setDesc(C.prototype, 'size', { diff --git a/modules/$.collection.js b/modules/$.collection.js index d8f7f295978e..2d5bab7829a8 100644 --- a/modules/$.collection.js +++ b/modules/$.collection.js @@ -2,7 +2,9 @@ var global = require('./$.global') , $def = require('./$.def') , forOf = require('./$.for-of') - , strictNew = require('./$.strict-new'); + , strictNew = require('./$.strict-new') + , isObject = require('./$.is-object') + , fails = require('./$.fails'); module.exports = function(NAME, wrapper, methods, common, IS_MAP, IS_WEAK){ var Base = global[NAME] @@ -13,25 +15,33 @@ module.exports = function(NAME, wrapper, methods, common, IS_MAP, IS_WEAK){ var fixMethod = function(KEY){ var fn = proto[KEY]; require('./$.redef')(proto, KEY, - KEY == 'delete' ? function(a){ return fn.call(this, a === 0 ? 0 : a); } - : KEY == 'has' ? function has(a){ return fn.call(this, a === 0 ? 0 : a); } - : KEY == 'get' ? function get(a){ return fn.call(this, a === 0 ? 0 : a); } - : KEY == 'add' ? function add(a){ fn.call(this, a === 0 ? 0 : a); return this; } - : function set(a, b){ fn.call(this, a === 0 ? 0 : a, b); return this; } + KEY == 'delete' ? function(a){ + return IS_WEAK && !isObject(a) ? false : fn.call(this, a === 0 ? 0 : a); + } : KEY == 'has' ? function has(a){ + return IS_WEAK && !isObject(a) ? false : fn.call(this, a === 0 ? 0 : a); + } : KEY == 'get' ? function get(a){ + return IS_WEAK && !isObject(a) ? false : fn.call(this, a === 0 ? 0 : a); + } : KEY == 'add' ? function add(a){ fn.call(this, a === 0 ? 0 : a); return this; } + : function set(a, b){ fn.call(this, a === 0 ? 0 : a, b); return this; } ); }; - if(typeof C != 'function' || !(IS_WEAK || proto.forEach && !require('./$.fails')(function(){ + if(typeof C != 'function' || !(IS_WEAK || proto.forEach && !fails(function(){ new C().entries().next(); }))){ // create collection constructor C = common.getConstructor(wrapper, NAME, IS_MAP, ADDER); require('./$.mix')(C.prototype, methods); } else { - var inst = new C - , chain = inst[ADDER](IS_WEAK ? {} : -0, 1) - , buggyZero; - // wrap for init collections from iterable - if(!require('./$.iter-detect')(function(iter){ new C(iter); })){ // eslint-disable-line no-new + var instance = new C + // early implementations not supports chaining + , CHAINING = instance[ADDER](IS_WEAK ? {} : -0, 1) + // V8 ~ Chromium 40- weak-collections throws on primitives, but should return false + , THROWS_ON_PRIMITIVES = fails(function(){ instance.has(1); }) + // most early implementations doesn't supports iterables, most modern - not close it correctly + , ACCEPT_ITERABLES = require('./$.iter-detect')(function(iter){ new C(iter); }) // eslint-disable-line no-new + // for early implementations -0 and +0 not the same + , BUGGY_ZERO; + if(!ACCEPT_ITERABLES){ C = wrapper(function(target, iterable){ strictNew(target, C, NAME); var that = new Base; @@ -41,17 +51,15 @@ module.exports = function(NAME, wrapper, methods, common, IS_MAP, IS_WEAK){ C.prototype = proto; proto.constructor = C; } - IS_WEAK || inst.forEach(function(val, key){ - buggyZero = 1 / key === -Infinity; + IS_WEAK || instance.forEach(function(val, key){ + BUGGY_ZERO = 1 / key === -Infinity; }); - // fix converting -0 key to +0 - if(buggyZero){ + if(THROWS_ON_PRIMITIVES || BUGGY_ZERO){ fixMethod('delete'); fixMethod('has'); IS_MAP && fixMethod('get'); } - // + fix .add & .set for chaining - if(buggyZero || chain !== inst)fixMethod(ADDER); + if(BUGGY_ZERO || CHAINING !== instance)fixMethod(ADDER); // weak collections should not contains .clear method if(IS_WEAK && proto.clear)delete proto.clear; } diff --git a/modules/library/$.collection.js b/modules/library/$.collection.js index 9e9808f2258d..0cde2f2b9623 100644 --- a/modules/library/$.collection.js +++ b/modules/library/$.collection.js @@ -3,7 +3,8 @@ var $ = require('./$') , $def = require('./$.def') , hide = require('./$.hide') , forOf = require('./$.for-of') - , strictNew = require('./$.strict-new'); + , strictNew = require('./$.strict-new') + , isObject = require('./$.is-object'); module.exports = function(NAME, wrapper, methods, common, IS_MAP, IS_WEAK){ var Base = require('./$.global')[NAME] @@ -24,10 +25,11 @@ module.exports = function(NAME, wrapper, methods, common, IS_MAP, IS_WEAK){ if(iterable != undefined)forOf(iterable, IS_MAP, target[ADDER], target); }); $.each.call('add,clear,delete,forEach,get,has,set,keys,values,entries'.split(','),function(KEY){ - var chain = KEY == 'add' || KEY == 'set'; + var IS_ADDER = KEY == 'add' || KEY == 'set'; if(KEY in proto && !(IS_WEAK && KEY == 'clear'))hide(C.prototype, KEY, function(a, b){ + if(!IS_ADDER && IS_WEAK && !isObject(a))return false; var result = this._c[KEY](a === 0 ? 0 : a, b); - return chain ? this : result; + return IS_ADDER ? this : result; }); }); if('size' in proto)$.setDesc(C.prototype, 'size', { diff --git a/tests/library.js b/tests/library.js index 562dff51fd45..bc9dc90b3710 100644 --- a/tests/library.js +++ b/tests/library.js @@ -4738,7 +4738,7 @@ return core.getIteratorMethod([]).call(this); }; new WeakMap(a); - return assert.ok(done); + assert.ok(done); }); test('WeakMap#delete', function(assert){ var M, a, b; @@ -4746,7 +4746,12 @@ M = new WeakMap([[a = {}, 42], [b = {}, 21]]); assert.ok(M.has(a) && M.has(b), 'WeakMap has values before .delete()'); M['delete'](a); - return assert.ok(!M.has(a) && M.has(b), 'WeakMap hasn`t value after .delete()'); + assert.ok(!M.has(a) && M.has(b), 'WeakMap hasn`t value after .delete()'); + assert.ok((function(){ + try { + return !M['delete'](1); + } catch (e$) {} + }()), 'return false on primitive'); }); test('WeakMap#get', function(assert){ var M, a; @@ -4756,7 +4761,12 @@ M.set(a = {}, 42); assert.strictEqual(M.get(a), 42, 'WeakMap .get() return value'); M['delete'](a); - return assert.strictEqual(M.get(a), void 8, 'WeakMap .get() after .delete() return undefined'); + assert.strictEqual(M.get(a), void 8, 'WeakMap .get() after .delete() return undefined'); + assert.ok((function(){ + try { + return !M.get(1); + } catch (e$) {} + }()), 'return false on primitive'); }); test('WeakMap#has', function(assert){ var M, a; @@ -4766,13 +4776,18 @@ M.set(a = {}, 42); assert.ok(M.has(a), 'WeakMap .has() return true'); M['delete'](a); - return assert.ok(!M.has(a), 'WeakMap .has() after .delete() return false'); + assert.ok(!M.has(a), 'WeakMap .has() after .delete() return false'); + assert.ok((function(){ + try { + return !M.has(1); + } catch (e$) {} + }()), 'return false on primitive'); }); test('WeakMap#set', function(assert){ var w, a, e; assert.isFunction(WeakMap.prototype.set); assert.ok((w = new WeakMap).set(a = {}, 42) === w, 'chaining'); - return assert.ok((function(){ + assert.ok((function(){ try { new WeakMap().set(42, 42); return false; @@ -4784,7 +4799,7 @@ }); test('WeakMap#@@toStringTag', function(assert){ var ref$; - return assert.strictEqual(WeakMap.prototype[(ref$ = core.Symbol) != null ? ref$.toStringTag : void 8], 'WeakMap', 'WeakMap::@@toStringTag is `WeakMap`'); + assert.strictEqual(WeakMap.prototype[(ref$ = core.Symbol) != null ? ref$.toStringTag : void 8], 'WeakMap', 'WeakMap::@@toStringTag is `WeakMap`'); }); }).call(this); @@ -4829,13 +4844,13 @@ return core.getIteratorMethod([]).call(this); }; new WeakSet(a); - return assert.ok(done); + assert.ok(done); }); test('WeakSet#add', function(assert){ var w, e; assert.isFunction(WeakSet.prototype.add); assert.ok((w = new WeakSet).add({}) === w, 'chaining'); - return assert.ok((function(){ + assert.ok((function(){ try { new WeakSet().add(42); return false; @@ -4851,7 +4866,12 @@ S = new WeakSet().add(a = {}).add(b = {}); assert.ok(S.has(a) && S.has(b), 'WeakSet has values before .delete()'); S['delete'](a); - return assert.ok(!S.has(a) && S.has(b), 'WeakSet has`nt value after .delete()'); + assert.ok(!S.has(a) && S.has(b), 'WeakSet has`nt value after .delete()'); + assert.ok((function(){ + try { + return !S['delete'](1); + } catch (e$) {} + }()), 'return false on primitive'); }); test('WeakSet#has', function(assert){ var M, a; @@ -4861,11 +4881,16 @@ M.add(a = {}); assert.ok(M.has(a), 'WeakSet has value after .add()'); M['delete'](a); - return assert.ok(!M.has(a), 'WeakSet has`nt value after .delete()'); + assert.ok(!M.has(a), 'WeakSet hasn`t value after .delete()'); + assert.ok((function(){ + try { + return !M.has(1); + } catch (e$) {} + }()), 'return false on primitive'); }); test('WeakSet::@@toStringTag', function(assert){ var ref$; - return assert.strictEqual(WeakSet.prototype[(ref$ = core.Symbol) != null ? ref$.toStringTag : void 8], 'WeakSet', 'WeakSet::@@toStringTag is `WeakSet`'); + assert.strictEqual(WeakSet.prototype[(ref$ = core.Symbol) != null ? ref$.toStringTag : void 8], 'WeakSet', 'WeakSet::@@toStringTag is `WeakSet`'); }); }).call(this); diff --git a/tests/library/es6.weak-map.ls b/tests/library/es6.weak-map.ls index d2b4aec916f0..953793778aef 100644 --- a/tests/library/es6.weak-map.ls +++ b/tests/library/es6.weak-map.ls @@ -5,7 +5,7 @@ module \ES6 {freeze} = core.Object {iterator} = core.Symbol -test 'WeakMap' (assert)-> +test 'WeakMap' (assert)!-> assert.isFunction WeakMap assert.ok \delete of WeakMap::, 'delete in WeakMap.prototype' assert.ok \get of WeakMap::, 'get in WeakMap.prototype' @@ -37,14 +37,15 @@ test 'WeakMap' (assert)-> new WeakMap a assert.ok done -test 'WeakMap#delete' (assert)-> +test 'WeakMap#delete' (assert)!-> assert.isFunction WeakMap::delete M = new WeakMap [[a = {}, 42], [b = {}, 21]] assert.ok M.has(a) && M.has(b), 'WeakMap has values before .delete()' M.delete a assert.ok !M.has(a) && M.has(b), 'WeakMap hasn`t value after .delete()' + assert.ok (try !M.delete 1), 'return false on primitive' -test 'WeakMap#get' (assert)-> +test 'WeakMap#get' (assert)!-> assert.isFunction WeakMap::get M = new WeakMap! assert.strictEqual M.get({}), void, 'WeakMap .get() before .set() return undefined' @@ -52,8 +53,9 @@ test 'WeakMap#get' (assert)-> assert.strictEqual M.get(a), 42, 'WeakMap .get() return value' M.delete a assert.strictEqual M.get(a), void, 'WeakMap .get() after .delete() return undefined' + assert.ok (try !M.get 1), 'return false on primitive' -test 'WeakMap#has' (assert)-> +test 'WeakMap#has' (assert)!-> assert.isFunction WeakMap::has M = new WeakMap! assert.ok !M.has({}), 'WeakMap .has() before .set() return false' @@ -61,11 +63,12 @@ test 'WeakMap#has' (assert)-> assert.ok M.has(a), 'WeakMap .has() return true' M.delete a assert.ok !M.has(a), 'WeakMap .has() after .delete() return false' + assert.ok (try !M.has 1), 'return false on primitive' -test 'WeakMap#set' (assert)-> +test 'WeakMap#set' (assert)!-> assert.isFunction WeakMap::set assert.ok (w = new WeakMap)set(a = {}, 42) is w, 'chaining' assert.ok (try new WeakMap!set(42, 42); no; catch => on), 'throws with primitive keys' -test 'WeakMap#@@toStringTag' (assert)-> +test 'WeakMap#@@toStringTag' (assert)!-> assert.strictEqual WeakMap::[core.Symbol?toStringTag], \WeakMap, 'WeakMap::@@toStringTag is `WeakMap`' \ No newline at end of file diff --git a/tests/library/es6.weak-set.ls b/tests/library/es6.weak-set.ls index 25a83743de58..ceab8718aeab 100644 --- a/tests/library/es6.weak-set.ls +++ b/tests/library/es6.weak-set.ls @@ -5,7 +5,7 @@ module \ES6 {freeze} = core.Object {iterator} = core.Symbol -test 'WeakSet' (assert)-> +test 'WeakSet' (assert)!-> assert.isFunction WeakSet assert.ok \add of WeakSet::, 'add in WeakSet.prototype' assert.ok \delete of WeakSet::, 'delete in WeakSet.prototype' @@ -34,12 +34,12 @@ test 'WeakSet' (assert)-> new WeakSet a assert.ok done -test 'WeakSet#add' (assert)-> +test 'WeakSet#add' (assert)!-> assert.isFunction WeakSet::add assert.ok (w = new WeakSet)add({}) is w, 'chaining' assert.ok (try new WeakSet!add(42); no; catch => on), 'throws with primitive keys' -test 'WeakSet#delete' (assert)-> +test 'WeakSet#delete' (assert)!-> assert.isFunction WeakSet::delete S = new WeakSet! .add a = {} @@ -47,15 +47,17 @@ test 'WeakSet#delete' (assert)-> assert.ok S.has(a) && S.has(b), 'WeakSet has values before .delete()' S.delete a assert.ok !S.has(a) && S.has(b), 'WeakSet has`nt value after .delete()' + assert.ok (try !S.delete 1), 'return false on primitive' -test 'WeakSet#has' (assert)-> +test 'WeakSet#has' (assert)!-> assert.isFunction WeakSet::has M = new WeakSet! assert.ok not M.has({}), 'WeakSet has`nt value' M.add a = {} assert.ok M.has(a), 'WeakSet has value after .add()' M.delete a - assert.ok not M.has(a), 'WeakSet has`nt value after .delete()' + assert.ok not M.has(a), 'WeakSet hasn`t value after .delete()' + assert.ok (try !M.has 1), 'return false on primitive' -test 'WeakSet::@@toStringTag' (assert)-> +test 'WeakSet::@@toStringTag' (assert)!-> assert.strictEqual WeakSet::[core.Symbol?toStringTag], \WeakSet, 'WeakSet::@@toStringTag is `WeakSet`' \ No newline at end of file diff --git a/tests/tests.js b/tests/tests.js index c7ec2121a01a..1fd03ce2ead1 100644 --- a/tests/tests.js +++ b/tests/tests.js @@ -1485,6 +1485,27 @@ return Array.prototype.fill.call(void 8, 0); }, TypeError); } + if ((typeof NATIVE != 'undefined' && NATIVE !== null) && function(){ + try { + return 2 === Object.defineProperty({}, 'a', { + get: function(){ + return 2; + } + }).a; + } catch (e$) {} + }()) { + assert.ok((function(){ + try { + return Array.prototype.fill.call(Object.defineProperty({ + length: -1 + }, 0, { + get: function(){ + throw Error; + } + })); + } catch (e$) {} + }()), 'uses ToLength'); + } return assert.ok('fill' in Array.prototype[Symbol.unscopables], 'In Array#@@unscopables'); }); }).call(this); @@ -1524,6 +1545,18 @@ return Array.prototype.findIndex.call(void 8, 0); }, TypeError); } + if (typeof NATIVE != 'undefined' && NATIVE !== null) { + assert.ok((function(){ + try { + return Array.prototype.findIndex.call({ + length: -1, + 0: 1 + }, function(){ + throw 42; + }); + } catch (e$) {} + }()), 'uses ToLength'); + } return assert.ok('findIndex' in Array.prototype[Symbol.unscopables], 'In Array#@@unscopables'); }); }).call(this); @@ -1563,6 +1596,18 @@ return Array.prototype.find.call(void 8, 0); }, TypeError); } + if (typeof NATIVE != 'undefined' && NATIVE !== null) { + assert.ok((function(){ + try { + return Array.prototype.find.call({ + length: -1, + 0: 1 + }, function(){ + throw 42; + }); + } catch (e$) {} + }()), 'uses ToLength'); + } return assert.ok('find' in Array.prototype[Symbol.unscopables], 'In Array#@@unscopables'); }); }).call(this); @@ -1657,7 +1702,19 @@ return [][typeof Symbol != 'undefined' && Symbol !== null ? Symbol.iterator : void 8].call(this); }; assert.deepEqual(from(a), [1, 2, 3]); - return assert.ok(done); + assert.ok(done); + if (typeof NATIVE != 'undefined' && NATIVE !== null) { + return assert.ok((function(){ + try { + return Array.from({ + length: -1, + 0: 1 + }, function(){ + throw 42; + }); + } catch (e$) {} + }()), 'uses ToLength'); + } }); }).call(this); @@ -6639,7 +6696,7 @@ return [][typeof Symbol != 'undefined' && Symbol !== null ? Symbol.iterator : void 8].call(this); }; new WeakMap(a); - return assert.ok(done); + assert.ok(done); }); test('WeakMap#delete', function(assert){ var x$, M, a, b; @@ -6652,7 +6709,12 @@ x$.set(b = {}, 21); assert.ok(M.has(a) && M.has(b), 'WeakMap has values before .delete()'); M['delete'](a); - return assert.ok(!M.has(a) && M.has(b), 'WeakMap hasn`t value after .delete()'); + assert.ok(!M.has(a) && M.has(b), 'WeakMap hasn`t value after .delete()'); + assert.ok((function(){ + try { + return !M['delete'](1); + } catch (e$) {} + }()), 'return false on primitive'); }); test('WeakMap#get', function(assert){ var M, a; @@ -6665,7 +6727,12 @@ M.set(a = {}, 42); assert.strictEqual(M.get(a), 42, 'WeakMap .get() return value'); M['delete'](a); - return assert.strictEqual(M.get(a), void 8, 'WeakMap .get() after .delete() return undefined'); + assert.strictEqual(M.get(a), void 8, 'WeakMap .get() after .delete() return undefined'); + assert.ok((function(){ + try { + return !M.get(1); + } catch (e$) {} + }()), 'return false on primitive'); }); test('WeakMap#has', function(assert){ var M, a; @@ -6678,7 +6745,12 @@ M.set(a = {}, 42); assert.ok(M.has(a), 'WeakMap .has() return true'); M['delete'](a); - return assert.ok(!M.has(a), 'WeakMap .has() after .delete() return false'); + assert.ok(!M.has(a), 'WeakMap .has() after .delete() return false'); + assert.ok((function(){ + try { + return !M.has(1); + } catch (e$) {} + }()), 'return false on primitive'); }); test('WeakMap#set', function(assert){ var x$, a, e, wmap; @@ -6697,10 +6769,10 @@ } }()), 'throws with primitive keys'); wmap = new WeakMap(); - return assert.same(wmap.set({}, 1), wmap, 'return this'); + assert.same(wmap.set({}, 1), wmap, 'return this'); }); test('WeakMap#@@toStringTag', function(assert){ - return assert.strictEqual(WeakMap.prototype[typeof Symbol != 'undefined' && Symbol !== null ? Symbol.toStringTag : void 8], 'WeakMap', 'WeakMap::@@toStringTag is `WeakMap`'); + assert.strictEqual(WeakMap.prototype[typeof Symbol != 'undefined' && Symbol !== null ? Symbol.toStringTag : void 8], 'WeakMap', 'WeakMap::@@toStringTag is `WeakMap`'); }); }).call(this); @@ -6745,7 +6817,7 @@ return [][typeof Symbol != 'undefined' && Symbol !== null ? Symbol.iterator : void 8].call(this); }; new WeakSet(a); - return assert.ok(done); + assert.ok(done); }); test('WeakSet#add', function(assert){ var a, e, wset; @@ -6764,7 +6836,7 @@ } }()), 'throws with primitive keys'); wset = new WeakSet(); - return assert.same(wset.add({}), wset, 'return this'); + assert.same(wset.add({}), wset, 'return this'); }); test('WeakSet#delete', function(assert){ var x$, S, a, b; @@ -6776,7 +6848,12 @@ x$.add(b = {}); assert.ok(S.has(a) && S.has(b), 'WeakSet has values before .delete()'); S['delete'](a); - return assert.ok(!S.has(a) && S.has(b), 'WeakSet has`nt value after .delete()'); + assert.ok(!S.has(a) && S.has(b), 'WeakSet hasn`t value after .delete()'); + assert.ok((function(){ + try { + return !S['delete'](1); + } catch (e$) {} + }()), 'return false on primitive'); }); test('WeakSet#has', function(assert){ var M, a; @@ -6789,10 +6866,15 @@ M.add(a = {}); assert.ok(M.has(a), 'WeakSet has value after .add()'); M['delete'](a); - return assert.ok(!M.has(a), 'WeakSet has`nt value after .delete()'); + assert.ok(!M.has(a), 'WeakSet has`nt value after .delete()'); + assert.ok((function(){ + try { + return !M.has(1); + } catch (e$) {} + }()), 'return false on primitive'); }); test('WeakSet::@@toStringTag', function(assert){ - return assert.strictEqual(WeakSet.prototype[typeof Symbol != 'undefined' && Symbol !== null ? Symbol.toStringTag : void 8], 'WeakSet', 'WeakSet::@@toStringTag is `WeakSet`'); + assert.strictEqual(WeakSet.prototype[typeof Symbol != 'undefined' && Symbol !== null ? Symbol.toStringTag : void 8], 'WeakSet', 'WeakSet::@@toStringTag is `WeakSet`'); }); }).call(this); diff --git a/tests/tests/es6.weak-map.ls b/tests/tests/es6.weak-map.ls index 092b3ae641c9..7368b775dab8 100644 --- a/tests/tests/es6.weak-map.ls +++ b/tests/tests/es6.weak-map.ls @@ -3,7 +3,7 @@ module \ES6 {freeze} = Object -test 'WeakMap' (assert)-> +test 'WeakMap' (assert)!-> assert.isFunction WeakMap assert.name WeakMap, \WeakMap assert.arity WeakMap, 0 @@ -39,7 +39,7 @@ test 'WeakMap' (assert)-> new WeakMap a assert.ok done -test 'WeakMap#delete' (assert)-> +test 'WeakMap#delete' (assert)!-> assert.isFunction WeakMap::delete NATIVE? and assert.name WeakMap::delete, \delete # can't be polyfilled in some environments NATIVE? and assert.arity WeakMap::delete, 1 @@ -50,8 +50,9 @@ test 'WeakMap#delete' (assert)-> assert.ok M.has(a) && M.has(b), 'WeakMap has values before .delete()' M.delete a assert.ok !M.has(a) && M.has(b), 'WeakMap hasn`t value after .delete()' + assert.ok (try !M.delete 1), 'return false on primitive' -test 'WeakMap#get' (assert)-> +test 'WeakMap#get' (assert)!-> assert.isFunction WeakMap::get assert.name WeakMap::get, \get NATIVE? and assert.arity WeakMap::get, 1 @@ -62,8 +63,9 @@ test 'WeakMap#get' (assert)-> assert.strictEqual M.get(a), 42, 'WeakMap .get() return value' M.delete a assert.strictEqual M.get(a), void, 'WeakMap .get() after .delete() return undefined' + assert.ok (try !M.get 1), 'return false on primitive' -test 'WeakMap#has' (assert)-> +test 'WeakMap#has' (assert)!-> assert.isFunction WeakMap::has assert.name WeakMap::has, \has NATIVE? and assert.arity WeakMap::has, 1 @@ -74,8 +76,9 @@ test 'WeakMap#has' (assert)-> assert.ok M.has(a), 'WeakMap .has() return true' M.delete a assert.ok !M.has(a), 'WeakMap .has() after .delete() return false' + assert.ok (try !M.has 1), 'return false on primitive' -test 'WeakMap#set' (assert)-> +test 'WeakMap#set' (assert)!-> assert.isFunction WeakMap::set assert.name WeakMap::set, \set assert.arity WeakMap::set, 2 @@ -87,5 +90,5 @@ test 'WeakMap#set' (assert)-> wmap = new WeakMap! assert.same wmap.set({}, 1), wmap, 'return this' -test 'WeakMap#@@toStringTag' (assert)-> +test 'WeakMap#@@toStringTag' (assert)!-> assert.strictEqual WeakMap::[Symbol?toStringTag], \WeakMap, 'WeakMap::@@toStringTag is `WeakMap`' \ No newline at end of file diff --git a/tests/tests/es6.weak-set.ls b/tests/tests/es6.weak-set.ls index dd6b5b88b4f1..727d2fb3bc1e 100644 --- a/tests/tests/es6.weak-set.ls +++ b/tests/tests/es6.weak-set.ls @@ -3,7 +3,7 @@ module \ES6 {freeze} = Object -test 'WeakSet' (assert)-> +test 'WeakSet' (assert)!-> assert.isFunction WeakSet assert.name WeakSet, \WeakSet assert.arity WeakSet, 0 @@ -36,7 +36,7 @@ test 'WeakSet' (assert)-> new WeakSet a assert.ok done -test 'WeakSet#add' (assert)-> +test 'WeakSet#add' (assert)!-> assert.isFunction WeakSet::add assert.name WeakSet::add, \add assert.arity WeakSet::add, 1 @@ -46,7 +46,7 @@ test 'WeakSet#add' (assert)-> wset = new WeakSet! assert.same wset.add({}), wset, 'return this' -test 'WeakSet#delete' (assert)-> +test 'WeakSet#delete' (assert)!-> assert.isFunction WeakSet::delete NATIVE? and #assert.name WeakSet::delete, \delete # can't be polyfilled in some environments assert.arity WeakSet::delete, 1 @@ -56,9 +56,10 @@ test 'WeakSet#delete' (assert)-> ..add b = {} assert.ok S.has(a) && S.has(b), 'WeakSet has values before .delete()' S.delete a - assert.ok !S.has(a) && S.has(b), 'WeakSet has`nt value after .delete()' + assert.ok !S.has(a) && S.has(b), 'WeakSet hasn`t value after .delete()' + assert.ok (try !S.delete 1), 'return false on primitive' -test 'WeakSet#has' (assert)-> +test 'WeakSet#has' (assert)!-> assert.isFunction WeakSet::has assert.name WeakSet::has, \has assert.arity WeakSet::has, 1 @@ -69,6 +70,7 @@ test 'WeakSet#has' (assert)-> assert.ok M.has(a), 'WeakSet has value after .add()' M.delete a assert.ok not M.has(a), 'WeakSet has`nt value after .delete()' + assert.ok (try !M.has 1), 'return false on primitive' -test 'WeakSet::@@toStringTag' (assert)-> +test 'WeakSet::@@toStringTag' (assert)!-> assert.strictEqual WeakSet::[Symbol?toStringTag], \WeakSet, 'WeakSet::@@toStringTag is `WeakSet`' \ No newline at end of file