map.js 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622
  1. // Big thanks to V8 folks for test ideas.
  2. // v8/test/mjsunit/harmony/collections.js
  3. var Assertion = expect().constructor;
  4. Assertion.addMethod('theSameSet', function (otherArray) {
  5. var array = this._obj;
  6. expect(Array.isArray(array)).to.equal(true);
  7. expect(Array.isArray(otherArray)).to.equal(true);
  8. var diff = array.filter(function (value) {
  9. return otherArray.every(function (otherValue) {
  10. var areBothNaN = typeof value === 'number' && typeof otherValue === 'number' && value !== value && otherValue !== otherValue;
  11. return !areBothNaN && value !== otherValue;
  12. });
  13. });
  14. this.assert(
  15. diff.length === 0,
  16. 'expected #{this} to be equal to #{exp} (as sets, i.e. no order)',
  17. array,
  18. otherArray
  19. );
  20. });
  21. Assertion.addMethod('entries', function (expected) {
  22. var collection = this._obj;
  23. expect(Array.isArray(expected)).to.equal(true);
  24. var expectedEntries = expected.slice();
  25. var iterator = collection.entries();
  26. var result;
  27. do {
  28. result = iterator.next();
  29. expect(result.value).to.be.eql(expectedEntries.shift());
  30. } while (!result.done);
  31. });
  32. describe('Map', function () {
  33. var functionsHaveNames = (function foo() {}).name === 'foo';
  34. var ifFunctionsHaveNamesIt = functionsHaveNames ? it : xit;
  35. var ifShimIt = (typeof process !== 'undefined' && process.env.NO_ES6_SHIM) ? it.skip : it;
  36. var ifGetPrototypeOfIt = Object.getPrototypeOf ? it : xit;
  37. var range = function range(from, to) {
  38. var result = [];
  39. for (var value = from; value < to; value++) {
  40. result.push(value);
  41. }
  42. return result;
  43. };
  44. var prototypePropIsEnumerable = Object.prototype.propertyIsEnumerable.call(function () {}, 'prototype');
  45. var expectNotEnumerable = function (object) {
  46. if (prototypePropIsEnumerable && typeof object === 'function') {
  47. expect(Object.keys(object)).to.eql(['prototype']);
  48. } else {
  49. expect(Object.keys(object)).to.eql([]);
  50. }
  51. };
  52. var Sym = typeof Symbol === 'undefined' ? {} : Symbol;
  53. var isSymbol = function (sym) {
  54. return typeof Sym === 'function' && typeof sym === 'symbol';
  55. };
  56. var ifSymbolIteratorIt = isSymbol(Sym.iterator) ? it : xit;
  57. var testMapping = function (map, key, value) {
  58. expect(map.has(key)).to.equal(false);
  59. expect(map.get(key)).to.equal(undefined);
  60. expect(map.set(key, value)).to.equal(map);
  61. expect(map.get(key)).to.equal(value);
  62. expect(map.has(key)).to.equal(true);
  63. };
  64. if (typeof Map === 'undefined') {
  65. return it('exists', function () {
  66. expect(typeof Map).to.equal('function');
  67. });
  68. }
  69. var map;
  70. beforeEach(function () {
  71. map = new Map();
  72. });
  73. afterEach(function () {
  74. map = null;
  75. });
  76. ifShimIt('is on the exported object', function () {
  77. var exported = require('../');
  78. expect(exported.Map).to.equal(Map);
  79. });
  80. it('should exist in global namespace', function () {
  81. expect(typeof Map).to.equal('function');
  82. });
  83. it('should have the right arity', function () {
  84. expect(Map).to.have.property('length', 0);
  85. });
  86. it('should has valid getter and setter calls', function () {
  87. ['get', 'set', 'has', 'delete'].forEach(function (method) {
  88. expect(function () {
  89. map[method]({});
  90. }).to.not['throw']();
  91. });
  92. });
  93. it('should accept an iterable as argument', function () {
  94. testMapping(map, 'a', 'b');
  95. testMapping(map, 'c', 'd');
  96. var map2;
  97. expect(function () { map2 = new Map(map); }).not.to['throw'](Error);
  98. expect(map2).to.be.an.instanceOf(Map);
  99. expect(map2.has('a')).to.equal(true);
  100. expect(map2.has('c')).to.equal(true);
  101. expect(map2).to.have.entries([['a', 'b'], ['c', 'd']]);
  102. });
  103. it('should throw with iterables that return primitives', function () {
  104. expect(function () { return new Map('123'); }).to['throw'](TypeError);
  105. expect(function () { return new Map([1, 2, 3]); }).to['throw'](TypeError);
  106. expect(function () { return new Map(['1', '2', '3']); }).to['throw'](TypeError);
  107. expect(function () { return new Map([true]); }).to['throw'](TypeError);
  108. });
  109. it('should not be callable without "new"', function () {
  110. expect(Map).to['throw'](TypeError);
  111. });
  112. it('should be subclassable', function () {
  113. if (!Object.setPrototypeOf) { return; } // skip test if on IE < 11
  114. var MyMap = function MyMap() {
  115. var testMap = new Map([['a', 'b']]);
  116. Object.setPrototypeOf(testMap, MyMap.prototype);
  117. return testMap;
  118. };
  119. Object.setPrototypeOf(MyMap, Map);
  120. MyMap.prototype = Object.create(Map.prototype, {
  121. constructor: { value: MyMap }
  122. });
  123. var myMap = new MyMap();
  124. testMapping(myMap, 'c', 'd');
  125. expect(myMap).to.have.entries([['a', 'b'], ['c', 'd']]);
  126. });
  127. it('uses SameValueZero even on a Map of size > 4', function () {
  128. // Chrome 38-42, node 0.11/0.12, iojs 1/2 have a bug when the Map has a size > 4
  129. var firstFour = [[1, 0], [2, 0], [3, 0], [4, 0]];
  130. var fourMap = new Map(firstFour);
  131. expect(fourMap.size).to.equal(4);
  132. expect(fourMap.has(-0)).to.equal(false);
  133. expect(fourMap.has(0)).to.equal(false);
  134. fourMap.set(-0, fourMap);
  135. expect(fourMap.has(0)).to.equal(true);
  136. expect(fourMap.has(-0)).to.equal(true);
  137. });
  138. it('treats positive and negative zero the same', function () {
  139. var value1 = {};
  140. var value2 = {};
  141. testMapping(map, +0, value1);
  142. expect(map.has(-0)).to.equal(true);
  143. expect(map.get(-0)).to.equal(value1);
  144. expect(map.set(-0, value2)).to.equal(map);
  145. expect(map.get(-0)).to.equal(value2);
  146. expect(map.get(+0)).to.equal(value2);
  147. });
  148. it('should map values correctly', function () {
  149. // Run this test twice, one with the "fast" implementation (which only
  150. // allows string and numeric keys) and once with the "slow" impl.
  151. [true, false].forEach(function (slowkeys) {
  152. map = new Map();
  153. range(1, 20).forEach(function (number) {
  154. if (slowkeys) { testMapping(map, number, {}); }
  155. testMapping(map, number / 100, {});
  156. testMapping(map, 'key-' + number, {});
  157. testMapping(map, String(number), {});
  158. if (slowkeys) { testMapping(map, Object(String(number)), {}); }
  159. });
  160. var testkeys = [Infinity, -Infinity, NaN];
  161. if (slowkeys) {
  162. testkeys.push(true, false, null, undefined);
  163. }
  164. testkeys.forEach(function (key) {
  165. testMapping(map, key, {});
  166. testMapping(map, String(key), {});
  167. });
  168. testMapping(map, '', {});
  169. // verify that properties of Object don't peek through.
  170. [
  171. 'hasOwnProperty',
  172. 'constructor',
  173. 'toString',
  174. 'isPrototypeOf',
  175. '__proto__',
  176. '__parent__',
  177. '__count__'
  178. ].forEach(function (key) {
  179. testMapping(map, key, {});
  180. });
  181. });
  182. });
  183. it('should map empty values correctly', function () {
  184. testMapping(map, {}, true);
  185. testMapping(map, null, true);
  186. testMapping(map, undefined, true);
  187. testMapping(map, '', true);
  188. testMapping(map, NaN, true);
  189. testMapping(map, 0, true);
  190. });
  191. it('should has correct querying behavior', function () {
  192. var key = {};
  193. testMapping(map, key, 'to-be-present');
  194. expect(map.has(key)).to.equal(true);
  195. expect(map.has({})).to.equal(false);
  196. expect(map.set(key, void 0)).to.equal(map);
  197. expect(map.get(key)).to.equal(undefined);
  198. expect(map.has(key)).to.equal(true);
  199. expect(map.has({})).to.equal(false);
  200. });
  201. it('should allow NaN values as keys', function () {
  202. expect(map.has(NaN)).to.equal(false);
  203. expect(map.has(NaN + 1)).to.equal(false);
  204. expect(map.has(23)).to.equal(false);
  205. expect(map.set(NaN, 'value')).to.equal(map);
  206. expect(map.has(NaN)).to.equal(true);
  207. expect(map.has(NaN + 1)).to.equal(true);
  208. expect(map.has(23)).to.equal(false);
  209. });
  210. it('should not have [[Enumerable]] props', function () {
  211. expectNotEnumerable(Map);
  212. expectNotEnumerable(Map.prototype);
  213. expectNotEnumerable(new Map());
  214. });
  215. it('should not have an own constructor', function () {
  216. var m = new Map();
  217. expect(m).not.to.haveOwnPropertyDescriptor('constructor');
  218. expect(m.constructor).to.equal(Map);
  219. });
  220. it('should allow common ecmascript idioms', function () {
  221. expect(map).to.be.an.instanceOf(Map);
  222. expect(typeof Map.prototype.get).to.equal('function');
  223. expect(typeof Map.prototype.set).to.equal('function');
  224. expect(typeof Map.prototype.has).to.equal('function');
  225. expect(typeof Map.prototype['delete']).to.equal('function');
  226. });
  227. it('should have a unique constructor', function () {
  228. expect(Map.prototype).to.not.equal(Object.prototype);
  229. });
  230. describe('#clear()', function () {
  231. ifFunctionsHaveNamesIt('has the right name', function () {
  232. expect(Map.prototype.clear).to.have.property('name', 'clear');
  233. });
  234. it('is not enumerable', function () {
  235. expect(Map.prototype).ownPropertyDescriptor('clear').to.have.property('enumerable', false);
  236. });
  237. it('has the right arity', function () {
  238. expect(Map.prototype.clear).to.have.property('length', 0);
  239. });
  240. it('should have #clear method', function () {
  241. expect(map.set(1, 2)).to.equal(map);
  242. expect(map.set(5, 2)).to.equal(map);
  243. expect(map.size).to.equal(2);
  244. expect(map.has(5)).to.equal(true);
  245. map.clear();
  246. expect(map.size).to.equal(0);
  247. expect(map.has(5)).to.equal(false);
  248. });
  249. });
  250. describe('#keys()', function () {
  251. if (!Object.prototype.hasOwnProperty.call(Map.prototype, 'keys')) {
  252. return it('exists', function () {
  253. expect(Map.prototype).to.have.property('keys');
  254. });
  255. }
  256. ifFunctionsHaveNamesIt('has the right name', function () {
  257. expect(Map.prototype.keys).to.have.property('name', 'keys');
  258. });
  259. it('is not enumerable', function () {
  260. expect(Map.prototype).ownPropertyDescriptor('keys').to.have.property('enumerable', false);
  261. });
  262. it('has the right arity', function () {
  263. expect(Map.prototype.keys).to.have.property('length', 0);
  264. });
  265. });
  266. describe('#values()', function () {
  267. if (!Object.prototype.hasOwnProperty.call(Map.prototype, 'values')) {
  268. return it('exists', function () {
  269. expect(Map.prototype).to.have.property('values');
  270. });
  271. }
  272. ifFunctionsHaveNamesIt('has the right name', function () {
  273. expect(Map.prototype.values).to.have.property('name', 'values');
  274. });
  275. it('is not enumerable', function () {
  276. expect(Map.prototype).ownPropertyDescriptor('values').to.have.property('enumerable', false);
  277. });
  278. it('has the right arity', function () {
  279. expect(Map.prototype.values).to.have.property('length', 0);
  280. });
  281. });
  282. describe('#entries()', function () {
  283. if (!Object.prototype.hasOwnProperty.call(Map.prototype, 'entries')) {
  284. return it('exists', function () {
  285. expect(Map.prototype).to.have.property('entries');
  286. });
  287. }
  288. ifFunctionsHaveNamesIt('has the right name', function () {
  289. expect(Map.prototype.entries).to.have.property('name', 'entries');
  290. });
  291. it('is not enumerable', function () {
  292. expect(Map.prototype).ownPropertyDescriptor('entries').to.have.property('enumerable', false);
  293. });
  294. it('has the right arity', function () {
  295. expect(Map.prototype.entries).to.have.property('length', 0);
  296. });
  297. it('throws when called on a non-Map', function () {
  298. var expectedMessage = /^(Method )?Map.prototype.entries called on incompatible receiver |^entries method called on incompatible |^Cannot create a Map entry iterator for a non-Map object.|^Map\.prototype\.entries: 'this' is not a Map object$|^std_Map_iterator method called on incompatible \w$|Map.prototype.entries requires that \|this\| be Map+$|is not an object \(evaluating 'Map.prototype.entries.call\(nonMap\)'\)|Map operation called on non-Map object/;
  299. var nonMaps = [true, false, 'abc', NaN, new Set([1, 2]), { a: true }, [1], Object('abc'), Object(NaN)];
  300. nonMaps.forEach(function (nonMap) {
  301. expect(function () { return Map.prototype.entries.call(nonMap); }).to['throw'](TypeError, expectedMessage);
  302. });
  303. });
  304. });
  305. describe('#size', function () {
  306. it('throws TypeError when accessed directly', function () {
  307. // see https://github.com/paulmillr/es6-shim/issues/176
  308. expect(function () { return Map.prototype.size; }).to['throw'](TypeError);
  309. expect(function () { return Map.prototype.size; }).to['throw'](TypeError);
  310. });
  311. it('is an accessor function on the prototype', function () {
  312. expect(Map.prototype).ownPropertyDescriptor('size').to.have.property('get');
  313. expect(typeof Object.getOwnPropertyDescriptor(Map.prototype, 'size').get).to.equal('function');
  314. expect(new Map()).not.to.haveOwnPropertyDescriptor('size');
  315. });
  316. });
  317. it('should return false when deleting a nonexistent key', function () {
  318. expect(map.has('a')).to.equal(false);
  319. expect(map['delete']('a')).to.equal(false);
  320. });
  321. it('should have keys, values and size props', function () {
  322. expect(map.set('a', 1)).to.equal(map);
  323. expect(map.set('b', 2)).to.equal(map);
  324. expect(map.set('c', 3)).to.equal(map);
  325. expect(typeof map.keys).to.equal('function');
  326. expect(typeof map.values).to.equal('function');
  327. expect(map.size).to.equal(3);
  328. expect(map['delete']('a')).to.equal(true);
  329. expect(map.size).to.equal(2);
  330. });
  331. it('should have an iterator that works with Array.from', function () {
  332. expect(Array).to.have.property('from');
  333. expect(map.set('a', 1)).to.equal(map);
  334. expect(map.set('b', NaN)).to.equal(map);
  335. expect(map.set('c', false)).to.equal(map);
  336. expect(Array.from(map)).to.eql([['a', 1], ['b', NaN], ['c', false]]);
  337. expect(Array.from(map.keys())).to.eql(['a', 'b', 'c']);
  338. expect(Array.from(map.values())).to.eql([1, NaN, false]);
  339. expect(map).to.have.entries(Array.from(map.entries()));
  340. });
  341. ifSymbolIteratorIt('has the right default iteration function', function () {
  342. // fixed in Webkit https://bugs.webkit.org/show_bug.cgi?id=143838
  343. expect(Map.prototype).to.have.property(Sym.iterator, Map.prototype.entries);
  344. });
  345. describe('#forEach', function () {
  346. var mapToIterate;
  347. beforeEach(function () {
  348. mapToIterate = new Map();
  349. expect(mapToIterate.set('a', 1)).to.equal(mapToIterate);
  350. expect(mapToIterate.set('b', 2)).to.equal(mapToIterate);
  351. expect(mapToIterate.set('c', 3)).to.equal(mapToIterate);
  352. });
  353. afterEach(function () {
  354. mapToIterate = null;
  355. });
  356. ifFunctionsHaveNamesIt('has the right name', function () {
  357. expect(Map.prototype.forEach).to.have.property('name', 'forEach');
  358. });
  359. it('is not enumerable', function () {
  360. expect(Map.prototype).ownPropertyDescriptor('forEach').to.have.property('enumerable', false);
  361. });
  362. it('has the right arity', function () {
  363. expect(Map.prototype.forEach).to.have.property('length', 1);
  364. });
  365. it('should be iterable via forEach', function () {
  366. var expectedMap = {
  367. a: 1,
  368. b: 2,
  369. c: 3
  370. };
  371. var foundMap = {};
  372. mapToIterate.forEach(function (value, key, entireMap) {
  373. expect(entireMap).to.equal(mapToIterate);
  374. foundMap[key] = value;
  375. });
  376. expect(foundMap).to.eql(expectedMap);
  377. });
  378. it('should iterate over empty keys', function () {
  379. var mapWithEmptyKeys = new Map();
  380. var expectedKeys = [{}, null, undefined, '', NaN, 0];
  381. expectedKeys.forEach(function (key) {
  382. expect(mapWithEmptyKeys.set(key, true)).to.equal(mapWithEmptyKeys);
  383. });
  384. var foundKeys = [];
  385. mapWithEmptyKeys.forEach(function (value, key, entireMap) {
  386. expect(entireMap.get(key)).to.equal(value);
  387. foundKeys.push(key);
  388. });
  389. expect(foundKeys).to.be.theSameSet(expectedKeys);
  390. });
  391. it('should support the thisArg', function () {
  392. var context = function () {};
  393. mapToIterate.forEach(function () {
  394. expect(this).to.equal(context);
  395. }, context);
  396. });
  397. it('should have a length of 1', function () {
  398. expect(Map.prototype.forEach.length).to.equal(1);
  399. });
  400. it('should not revisit modified keys', function () {
  401. var hasModifiedA = false;
  402. mapToIterate.forEach(function (value, key) {
  403. if (!hasModifiedA && key === 'a') {
  404. expect(mapToIterate.set('a', 4)).to.equal(mapToIterate);
  405. hasModifiedA = true;
  406. } else {
  407. expect(key).not.to.equal('a');
  408. }
  409. });
  410. });
  411. it('returns the map from #set() for chaining', function () {
  412. expect(mapToIterate.set({}, {})).to.equal(mapToIterate);
  413. expect(mapToIterate.set(42, {})).to.equal(mapToIterate);
  414. expect(mapToIterate.set(0, {})).to.equal(mapToIterate);
  415. expect(mapToIterate.set(NaN, {})).to.equal(mapToIterate);
  416. expect(mapToIterate.set(-0, {})).to.equal(mapToIterate);
  417. });
  418. it('visits keys added in the iterator', function () {
  419. var hasAdded = false;
  420. var hasFoundD = false;
  421. mapToIterate.forEach(function (value, key) {
  422. if (!hasAdded) {
  423. mapToIterate.set('d', 5);
  424. hasAdded = true;
  425. } else if (key === 'd') {
  426. hasFoundD = true;
  427. }
  428. });
  429. expect(hasFoundD).to.equal(true);
  430. });
  431. it('visits keys added in the iterator when there is a deletion', function () {
  432. var hasSeenFour = false;
  433. var mapToMutate = new Map();
  434. mapToMutate.set('0', 42);
  435. mapToMutate.forEach(function (value, key) {
  436. if (key === '0') {
  437. expect(mapToMutate['delete']('0')).to.equal(true);
  438. mapToMutate.set('4', 'a value');
  439. } else if (key === '4') {
  440. hasSeenFour = true;
  441. }
  442. });
  443. expect(hasSeenFour).to.equal(true);
  444. });
  445. it('does not visit keys deleted before a visit', function () {
  446. var hasVisitedC = false;
  447. var hasDeletedC = false;
  448. mapToIterate.forEach(function (value, key) {
  449. if (key === 'c') {
  450. hasVisitedC = true;
  451. }
  452. if (!hasVisitedC && !hasDeletedC) {
  453. hasDeletedC = mapToIterate['delete']('c');
  454. expect(hasDeletedC).to.equal(true);
  455. }
  456. });
  457. expect(hasVisitedC).to.equal(false);
  458. });
  459. it('should work after deletion of the current key', function () {
  460. var expectedMap = {
  461. a: 1,
  462. b: 2,
  463. c: 3
  464. };
  465. var foundMap = {};
  466. mapToIterate.forEach(function (value, key) {
  467. foundMap[key] = value;
  468. expect(mapToIterate['delete'](key)).to.equal(true);
  469. });
  470. expect(foundMap).to.eql(expectedMap);
  471. });
  472. it('should convert key -0 to +0', function () {
  473. var zeroMap = new Map();
  474. var result = [];
  475. zeroMap.set(-0, 'a');
  476. zeroMap.forEach(function (value, key) {
  477. result.push(String(1 / key) + ' ' + value);
  478. });
  479. zeroMap.set(1, 'b');
  480. zeroMap.set(0, 'c'); // shouldn't cause reordering
  481. zeroMap.forEach(function (value, key) {
  482. result.push(String(1 / key) + ' ' + value);
  483. });
  484. expect(result.join(', ')).to.equal('Infinity a, Infinity c, 1 b');
  485. });
  486. });
  487. it('should preserve insertion order', function () {
  488. var convertToPairs = function (item) { return [item, true]; };
  489. var arr1 = ['d', 'a', 'b'];
  490. var arr2 = [3, 2, 'z', 'a', 1];
  491. var arr3 = [3, 2, 'z', {}, 'a', 1];
  492. [arr1, arr2, arr3].forEach(function (array) {
  493. var entries = array.map(convertToPairs);
  494. expect(new Map(entries)).to.have.entries(entries);
  495. });
  496. });
  497. it('map iteration', function () {
  498. var map = new Map();
  499. map.set('a', 1);
  500. map.set('b', 2);
  501. map.set('c', 3);
  502. map.set('d', 4);
  503. var keys = [];
  504. var iterator = map.keys();
  505. keys.push(iterator.next().value);
  506. expect(map['delete']('a')).to.equal(true);
  507. expect(map['delete']('b')).to.equal(true);
  508. expect(map['delete']('c')).to.equal(true);
  509. map.set('e');
  510. keys.push(iterator.next().value);
  511. keys.push(iterator.next().value);
  512. expect(iterator.next().done).to.equal(true);
  513. map.set('f');
  514. expect(iterator.next().done).to.equal(true);
  515. expect(keys).to.eql(['a', 'd', 'e']);
  516. });
  517. ifGetPrototypeOfIt('MapIterator identification test prototype inequality', function () {
  518. var mapEntriesProto = Object.getPrototypeOf(new Map().entries());
  519. var setEntriesProto = Object.getPrototypeOf(new Set().entries());
  520. expect(mapEntriesProto).to.not.equal(setEntriesProto);
  521. });
  522. it('MapIterator identification', function () {
  523. var fnMapValues = Map.prototype.values;
  524. var mapSentinel = new Map([[1, 'MapSentinel']]);
  525. var testMap = new Map();
  526. var testMapValues = testMap.values();
  527. expect(testMapValues.next.call(fnMapValues.call(mapSentinel)).value).to.equal('MapSentinel');
  528. var testSet = new Set();
  529. var testSetValues = testSet.values();
  530. expect(function () {
  531. return testSetValues.next.call(fnMapValues.call(mapSentinel)).value;
  532. }).to['throw'](TypeError);
  533. });
  534. });