├── .editorconfig ├── .github ├── FUNDING.yml └── workflows │ ├── integrate.yml │ ├── publish.yml │ └── validate.yml ├── .gitignore ├── .npmignore ├── CHANGELOG.md ├── CHANGES ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── SECURITY.md ├── commitlint.config.js ├── ext ├── copy.js ├── every.js ├── filter.js ├── get-first.js ├── get-last.js └── some.js ├── implement.js ├── index.js ├── is-implemented.js ├── is-native-implemented.js ├── is-set.js ├── lib ├── iterator.js └── primitive-iterator.js ├── package.json ├── polyfill.js ├── primitive └── index.js ├── test ├── ext │ ├── copy.js │ ├── every.js │ ├── filter.js │ ├── get-first.js │ ├── get-last.js │ └── some.js ├── implement.js ├── index.js ├── is-implemented.js ├── is-native-implemented.js ├── is-set.js ├── lib │ ├── iterator.js │ └── primitive-iterator.js ├── polyfill.js ├── primitive │ └── index.js └── valid-set.js └── valid-set.js /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig is awesome: http://EditorConfig.org 2 | 3 | # top-most EditorConfig file 4 | root = true 5 | 6 | [*] 7 | charset = utf-8 8 | end_of_line = lf 9 | insert_final_newline = true 10 | indent_style = tab 11 | trim_trailing_whitespace = true 12 | 13 | [*.{md,yml}] 14 | indent_size = 2 15 | indent_style = space 16 | 17 | [*.md] 18 | trim_trailing_whitespace = false 19 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: medikoo 2 | tidelift: "npm/es6-set" 3 | -------------------------------------------------------------------------------- /.github/workflows/integrate.yml: -------------------------------------------------------------------------------- 1 | # main only 2 | 3 | name: Integrate 4 | 5 | on: 6 | push: 7 | branches: [main] 8 | 9 | permissions: read-all 10 | 11 | env: 12 | FORCE_COLOR: 1 13 | 14 | jobs: 15 | _: 16 | uses: medikoo/github-actions-workflows/.github/workflows/0.12-integrate.yml@main 17 | secrets: 18 | USER_GITHUB_TOKEN: ${{ secrets.USER_GITHUB_TOKEN }} 19 | -------------------------------------------------------------------------------- /.github/workflows/publish.yml: -------------------------------------------------------------------------------- 1 | # Version tags only 2 | 3 | name: Publish 4 | 5 | on: 6 | push: 7 | tags: 8 | - v[0-9]+.[0-9]+.[0-9]+ 9 | 10 | permissions: read-all 11 | 12 | env: 13 | FORCE_COLOR: 1 14 | 15 | jobs: 16 | _: 17 | uses: medikoo/github-actions-workflows/.github/workflows/publish.yml@main 18 | secrets: 19 | USER_GITHUB_TOKEN: ${{ secrets.USER_GITHUB_TOKEN }} 20 | NPM_TOKEN: ${{ secrets.NPM_TOKEN }} 21 | -------------------------------------------------------------------------------- /.github/workflows/validate.yml: -------------------------------------------------------------------------------- 1 | # PR's only 2 | 3 | name: Validate 4 | 5 | on: 6 | pull_request: 7 | branches: [main] 8 | 9 | permissions: read-all 10 | 11 | env: 12 | FORCE_COLOR: 1 13 | 14 | jobs: 15 | _: 16 | uses: medikoo/github-actions-workflows/.github/workflows/0.12-validate.yml@main 17 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /.nyc_output 2 | /coverage 3 | /node_modules 4 | npm-debug.log 5 | /package-lock.json 6 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | /.editorconfig 2 | /.github 3 | /CHANGES 4 | /commitlint.config.js 5 | /test 6 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. 4 | 5 | ### [0.1.6](https://github.com/medikoo/es6-set/compare/v0.1.5...v0.1.6) (2022-08-17) 6 | 7 | ### Maintenance Improvements 8 | 9 | - Switch LICENSE from MIT to ISC ([50f0cae](https://github.com/medikoo/es6-set/commit/50f0cae11ec08b108a1aac10ef19a3b9b801db74)) 10 | - Add .editorconfig ([c1f97aa](https://github.com/medikoo/es6-set/commit/c1f97aa741796efa69b79a26cf8876da67b43021)) 11 | - Add CONTRIBUTING.md ([2c9907c](https://github.com/medikoo/es6-set/commit/2c9907c5cdf6e77725a599cd6c7fa4fdb44acdb2)) 12 | - Configure `coverage` script ([3a1fb7a](https://github.com/medikoo/es6-set/commit/3a1fb7ab99393115a7b56bb89f9213cab1e178c1)) 13 | - Configure Prettier ([192cbf2](https://github.com/medikoo/es6-set/commit/192cbf23c7270b9b049b39efe52cf29e68ec2fc1)) 14 | - Switch linter from `xlint` to `eslint` ([1d77dc3](https://github.com/medikoo/es6-set/commit/1d77dc3853bf3269e8e61fc1c3faf7b814a41d29)) 15 | 16 | ## Changelog for previous versions 17 | 18 | See `CHANGES` file 19 | -------------------------------------------------------------------------------- /CHANGES: -------------------------------------------------------------------------------- 1 | For recent changelog see CHANGELOG.md 2 | 3 | --- 4 | 5 | v0.1.5 -- 2017.03.16 6 | 7 | - Improve documentation 8 | - Update dependencies 9 | 10 | v0.1.4 -- 2016.01.19 11 | 12 | - Ensure Set polyfill function name is `Set` (#2) 13 | 14 | v0.1.3 -- 2015.11.18 15 | 16 | - Relax validation of native implementation (do not require proper stringification of Set.prototype) 17 | 18 | v0.1.2 -- 2015.10.02 19 | 20 | - Improve native Set detection 21 | - Fix spelling of LICENSE 22 | - Set.prototype.filter extension 23 | - Update dependencies 24 | 25 | v0.1.1 -- 2014.10.07 26 | 27 | - Fix isImplemented so it validates native Set properly 28 | - Add getFirst and getLast extensions 29 | - Configure linter scripts 30 | 31 | v0.1.0 -- 2014.04.29 32 | 33 | - Assure strictly npm hosted dependencies 34 | - Introduce faster 'primitive' alternative (doesn't guarantee order of iteration) 35 | - Add isNativeImplemented, and some, every and copy method extensions 36 | - If native Set is provided polyfill extends it 37 | - Optimize forEach iteration 38 | - Remove comparator support (as it was removed from spec) 39 | - Provide @@toStringTag symbol, ad @@iterator symbols on iterators 40 | - Update to use latest dependencies versions 41 | - Improve interals 42 | 43 | v0.0.0 -- 2013.10.12 44 | Initial (dev) version 45 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing Guidelines 2 | 3 | ## Setup 4 | 5 | To begin development fork repository and run `npm install` in its root folder. 6 | 7 | ## When you propose a new feature or bug fix 8 | 9 | Please make sure there is an open issue discussing your contribution before jumping into a Pull Request! 10 | 11 | There are just a few situations (listed below) in which it is fine to submit PR without a corresponding issue: 12 | 13 | - Documentation update 14 | - Obvious bug fix 15 | - Maintenance improvement 16 | 17 | In all other cases please check if there's an open an issue discussing the given proposal, if there is not, create an issue respecting all its template remarks. 18 | 19 | In non-trivial cases please propose and let us review an implementation spec (in the corresponding issue) before jumping into implementation. 20 | 21 | Do not submit draft PRs. Submit only finalized work which is ready for merge. If you have any doubts related to implementation work please discuss in the corresponding issue. 22 | 23 | Once a PR has been reviewed and some changes are suggested, please ensure to **re-request review** after all new changes are pushed. It's the best and quietest way to inform maintainers that your work is ready to be checked again. 24 | 25 | ## When you want to work on an existing issue 26 | 27 | **Note:** Please write a quick comment in the corresponding issue and ask if the feature is still relevant and that you want to jump into the implementation. 28 | 29 | Check out our [help wanted](https://github.com/medikoo/es6-set/labels/help%20wanted) or [good first issue](https://github.com/medikoo/es6-set/labels/good%20first%20issue) labels to find issues we want to move forward with your help. 30 | 31 | We will do our best to respond/review/merge your PR according to priority. 32 | 33 | ## Writing / improving documentation 34 | 35 | Do you see a typo or other ways to improve it? Feel free to edit it and submit a Pull Request! 36 | 37 | # Code Style 38 | 39 | We aim for a clean, consistent code style. We're using [Prettier](https://prettier.io/) to confirm one code formatting style and [ESlint](https://eslint.org/) helps us to stay away from obvious issues that can be picked via static analysis. 40 | 41 | Ideally, you should have Prettier and ESlint integrated into your code editor, which will help you not think about specific rules and be sure you submit the code that follows guidelines. 42 | 43 | ## Verifying prettier formatting 44 | 45 | ``` 46 | npm run prettier-check 47 | ``` 48 | 49 | ## Verifying linting style 50 | 51 | ``` 52 | npm run lint 53 | ``` 54 | 55 | # Testing 56 | 57 | This package needs to work in any ES5 environment, therefore it's good to confirm it passes tests in Node.js v0.12 release. 58 | 59 | Any new feature or enhancement should be covered with respective tests 60 | 61 | Run tests via: 62 | 63 | ``` 64 | npm test 65 | ``` 66 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | ISC License 2 | 3 | Copyright (c) 2013-022, Mariusz Nowak, @medikoo, medikoo.com 4 | 5 | Permission to use, copy, modify, and/or distribute this software for any 6 | purpose with or without fee is hereby granted, provided that the above 7 | copyright notice and this permission notice appear in all copies. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 10 | REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 11 | AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 12 | INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 13 | LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 14 | OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 15 | PERFORMANCE OF THIS SOFTWARE. 16 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Build status][build-image]][build-url] 2 | [![Tests coverage][cov-image]][cov-url] 3 | [![npm version][npm-image]][npm-url] 4 | [![CII Best Practices][cii-image]][cii-url] 5 | 6 | # es6-set 7 | 8 | ## Set collection as specified in ECMAScript6 9 | 10 | **Warning: 11 | v0.1 version does not ensure O(1) algorithm complexity (but O(n)). This shortcoming will be addressed in v1.0** 12 | 13 | ### Usage 14 | 15 | If you want to make sure your environment implements `Set`, do: 16 | 17 | ```javascript 18 | require("es6-set/implement"); 19 | ``` 20 | 21 | If you'd like to use native version when it exists and fallback to polyfill if it doesn't, but without implementing `Set` on global scope, do: 22 | 23 | ```javascript 24 | var Set = require("es6-set"); 25 | ``` 26 | 27 | If you strictly want to use polyfill even if native `Set` exists, do: 28 | 29 | ```javascript 30 | var Set = require("es6-set/polyfill"); 31 | ``` 32 | 33 | ### Installation 34 | 35 | $ npm install es6-set 36 | 37 | To port it to Browser or any other (non CJS) environment, use your favorite CJS bundler. No favorite yet? Try: [Browserify](http://browserify.org/), [Webmake](https://github.com/medikoo/modules-webmake) or [Webpack](http://webpack.github.io/) 38 | 39 | #### API 40 | 41 | Best is to refer to [specification](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-set-objects). Still if you want quick look, follow examples: 42 | 43 | ```javascript 44 | var Set = require("es6-set"); 45 | 46 | var set = new Set(["raz", "dwa", {}]); 47 | 48 | set.size; // 3 49 | set.has("raz"); // true 50 | set.has("foo"); // false 51 | set.add("foo"); // set 52 | set.size; // 4 53 | set.has("foo"); // true 54 | set.has("dwa"); // true 55 | set.delete("dwa"); // true 56 | set.size; // 3 57 | 58 | set.forEach(function (value) { 59 | // 'raz', {}, 'foo' iterated 60 | }); 61 | 62 | // FF nightly only: 63 | for (value of set) { 64 | // 'raz', {}, 'foo' iterated 65 | } 66 | 67 | var iterator = set.values(); 68 | 69 | iterator.next(); // { done: false, value: 'raz' } 70 | iterator.next(); // { done: false, value: {} } 71 | iterator.next(); // { done: false, value: 'foo' } 72 | iterator.next(); // { done: true, value: undefined } 73 | 74 | set.clear(); // undefined 75 | set.size; // 0 76 | ``` 77 | 78 | ## Tests 79 | 80 | $ npm test 81 | 82 | ## Security contact information 83 | 84 | To report a security vulnerability, please use the [Tidelift security contact](https://tidelift.com/security). Tidelift will coordinate the fix and disclosure. 85 | 86 | --- 87 | 88 |
89 | 90 | Get professional support for d with a Tidelift subscription 91 | 92 |
93 | 94 | Tidelift helps make open source sustainable for maintainers while giving companies
assurances about security, maintenance, and licensing for their dependencies. 95 |
96 |
97 | 98 | [build-image]: https://github.com/medikoo/es6-set/workflows/Integrate/badge.svg 99 | [build-url]: https://github.com/medikoo/es6-set/actions?query=workflow%3AIntegrate 100 | [cov-image]: https://img.shields.io/codecov/c/github/medikoo/es6-set.svg 101 | [cov-url]: https://codecov.io/gh/medikoo/es6-set 102 | [npm-image]: https://img.shields.io/npm/v/es6-set.svg 103 | [npm-url]: https://www.npmjs.com/package/es6-set 104 | [cii-image]: https://bestpractices.coreinfrastructure.org/projects/6368/badge 105 | [cii-url]: https://bestpractices.coreinfrastructure.org/projects/6368 106 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | ## Supported Versions 4 | 5 | | Version | Supported | 6 | | ------- | ------------------ | 7 | | 0.1.x | :white_check_mark: | 8 | 9 | ## Reporting a Vulnerability 10 | 11 | To report a security vulnerability, please use the [Tidelift security contact](https://tidelift.com/docs/security). Tidelift will coordinate the fix and disclosure. 12 | -------------------------------------------------------------------------------- /commitlint.config.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | module.exports = { 4 | rules: { 5 | "body-leading-blank": [2, "always"], 6 | "body-max-line-length": [2, "always", 72], 7 | "footer-leading-blank": [2, "always"], 8 | "footer-max-line-length": [2, "always", 72], 9 | "header-max-length": [2, "always", 72], 10 | "scope-case": [2, "always", "start-case"], 11 | "scope-enum": [2, "always", [""]], 12 | "subject-case": [2, "always", "sentence-case"], 13 | "subject-empty": [2, "never"], 14 | "subject-full-stop": [2, "never", "."], 15 | "type-case": [2, "always", "lower-case"], 16 | "type-empty": [2, "never"], 17 | "type-enum": [ 18 | 2, "always", 19 | ["build", "chore", "ci", "docs", "feat", "fix", "perf", "refactor", "style", "test"] 20 | ] 21 | } 22 | }; 23 | -------------------------------------------------------------------------------- /ext/copy.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var SetConstructor = require("../"); 4 | 5 | module.exports = function () { return new SetConstructor(this); }; 6 | -------------------------------------------------------------------------------- /ext/every.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var callable = require("es5-ext/object/valid-callable") 4 | , forOf = require("es6-iterator/for-of") 5 | , call = Function.prototype.call; 6 | 7 | module.exports = function (cb /*, thisArg*/) { 8 | var thisArg = arguments[1], result = true; 9 | callable(cb); 10 | forOf(this, function (value, doBreak) { 11 | if (!call.call(cb, thisArg, value)) { 12 | result = false; 13 | doBreak(); 14 | } 15 | }); 16 | return result; 17 | }; 18 | -------------------------------------------------------------------------------- /ext/filter.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var callable = require("es5-ext/object/valid-callable") 4 | , forOf = require("es6-iterator/for-of") 5 | , isSet = require("../is-set") 6 | , SetConstructor = require("../") 7 | , call = Function.prototype.call; 8 | 9 | module.exports = function (cb /*, thisArg*/) { 10 | var thisArg = arguments[1], result; 11 | callable(cb); 12 | result = isSet(this) ? new this.constructor() : new SetConstructor(); 13 | forOf(this, function (value) { if (call.call(cb, thisArg, value)) result.add(value); }); 14 | return result; 15 | }; 16 | -------------------------------------------------------------------------------- /ext/get-first.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | module.exports = function () { return this.values().next().value; }; 4 | -------------------------------------------------------------------------------- /ext/get-last.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | module.exports = function () { 4 | var value, iterator = this.values(), item = iterator.next(); 5 | while (!item.done) { 6 | value = item.value; 7 | item = iterator.next(); 8 | } 9 | return value; 10 | }; 11 | -------------------------------------------------------------------------------- /ext/some.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var callable = require("es5-ext/object/valid-callable") 4 | , forOf = require("es6-iterator/for-of") 5 | , call = Function.prototype.call; 6 | 7 | module.exports = function (cb /*, thisArg*/) { 8 | var thisArg = arguments[1], result = false; 9 | callable(cb); 10 | forOf(this, function (value, doBreak) { 11 | if (call.call(cb, thisArg, value)) { 12 | result = true; 13 | doBreak(); 14 | } 15 | }); 16 | return result; 17 | }; 18 | -------------------------------------------------------------------------------- /implement.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | if (!require("./is-implemented")()) { 4 | Object.defineProperty(require("es5-ext/global"), "Set", { 5 | value: require("./polyfill"), 6 | configurable: true, 7 | enumerable: false, 8 | writable: true 9 | }); 10 | } 11 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | module.exports = require("./is-implemented")() ? Set : require("./polyfill"); 4 | -------------------------------------------------------------------------------- /is-implemented.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | module.exports = function () { 4 | var set, iterator, result; 5 | if (typeof Set !== "function") return false; 6 | set = new Set(["raz", "dwa", "trzy"]); 7 | if (String(set) !== "[object Set]") return false; 8 | if (set.size !== 3) return false; 9 | if (typeof set.add !== "function") return false; 10 | if (typeof set.clear !== "function") return false; 11 | if (typeof set.delete !== "function") return false; 12 | if (typeof set.entries !== "function") return false; 13 | if (typeof set.forEach !== "function") return false; 14 | if (typeof set.has !== "function") return false; 15 | if (typeof set.keys !== "function") return false; 16 | if (typeof set.values !== "function") return false; 17 | 18 | iterator = set.values(); 19 | result = iterator.next(); 20 | if (result.done !== false) return false; 21 | if (result.value !== "raz") return false; 22 | 23 | return true; 24 | }; 25 | -------------------------------------------------------------------------------- /is-native-implemented.js: -------------------------------------------------------------------------------- 1 | // Exports true if environment provides native `Set` implementation, 2 | // whatever that is. 3 | 4 | "use strict"; 5 | 6 | module.exports = (function () { 7 | if (typeof Set === "undefined") return false; 8 | return Object.prototype.toString.call(Set.prototype) === "[object Set]"; 9 | })(); 10 | -------------------------------------------------------------------------------- /is-set.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var objToString = Object.prototype.toString 4 | , toStringTagSymbol = require("es6-symbol").toStringTag 5 | , id = "[object Set]" 6 | , Global = typeof Set === "undefined" ? null : Set; 7 | 8 | module.exports = function (value) { 9 | return ( 10 | (value && 11 | ((Global && (value instanceof Global || value === Global.prototype)) || 12 | objToString.call(value) === id || 13 | value[toStringTagSymbol] === "Set")) || 14 | false 15 | ); 16 | }; 17 | -------------------------------------------------------------------------------- /lib/iterator.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var setPrototypeOf = require("es5-ext/object/set-prototype-of") 4 | , contains = require("es5-ext/string/#/contains") 5 | , d = require("d") 6 | , Iterator = require("es6-iterator") 7 | , toStringTagSymbol = require("es6-symbol").toStringTag 8 | , defineProperty = Object.defineProperty 9 | , SetIterator; 10 | 11 | SetIterator = module.exports = function (set, kind) { 12 | if (!(this instanceof SetIterator)) return new SetIterator(set, kind); 13 | Iterator.call(this, set.__setData__, set); 14 | if (!kind) kind = "value"; 15 | else if (contains.call(kind, "key+value")) kind = "key+value"; 16 | else kind = "value"; 17 | return defineProperty(this, "__kind__", d("", kind)); 18 | }; 19 | if (setPrototypeOf) setPrototypeOf(SetIterator, Iterator); 20 | 21 | SetIterator.prototype = Object.create(Iterator.prototype, { 22 | constructor: d(SetIterator), 23 | _resolve: d(function (i) { 24 | if (this.__kind__ === "value") return this.__list__[i]; 25 | return [this.__list__[i], this.__list__[i]]; 26 | }), 27 | toString: d(function () { return "[object Set Iterator]"; }) 28 | }); 29 | defineProperty(SetIterator.prototype, toStringTagSymbol, d("c", "Set Iterator")); 30 | -------------------------------------------------------------------------------- /lib/primitive-iterator.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var clear = require("es5-ext/array/#/clear") 4 | , assign = require("es5-ext/object/assign") 5 | , setPrototypeOf = require("es5-ext/object/set-prototype-of") 6 | , contains = require("es5-ext/string/#/contains") 7 | , d = require("d") 8 | , autoBind = require("d/auto-bind") 9 | , Iterator = require("es6-iterator") 10 | , toStringTagSymbol = require("es6-symbol").toStringTag 11 | , defineProperties = Object.defineProperties 12 | , keys = Object.keys 13 | , unBind = Iterator.prototype._unBind 14 | , PrimitiveSetIterator; 15 | 16 | PrimitiveSetIterator = module.exports = function (set, kind) { 17 | if (!(this instanceof PrimitiveSetIterator)) { 18 | return new PrimitiveSetIterator(set, kind); 19 | } 20 | Iterator.call(this, keys(set.__setData__), set); 21 | kind = !kind || !contains.call(kind, "key+value") ? "value" : "key+value"; 22 | return defineProperties(this, { __kind__: d("", kind), __data__: d("w", set.__setData__) }); 23 | }; 24 | if (setPrototypeOf) setPrototypeOf(PrimitiveSetIterator, Iterator); 25 | 26 | PrimitiveSetIterator.prototype = Object.create( 27 | Iterator.prototype, 28 | assign( 29 | { 30 | constructor: d(PrimitiveSetIterator), 31 | _resolve: d(function (i) { 32 | var value = this.__data__[this.__list__[i]]; 33 | return this.__kind__ === "value" ? value : [value, value]; 34 | }), 35 | _unBind: d(function () { 36 | this.__data__ = null; 37 | unBind.call(this); 38 | }), 39 | toString: d(function () { return "[object Set Iterator]"; }) 40 | }, 41 | autoBind({ 42 | _onAdd: d(function (key) { this.__list__.push(key); }), 43 | _onDelete: d(function (key) { 44 | var index = this.__list__.lastIndexOf(key); 45 | if (index < this.__nextIndex__) return; 46 | this.__list__.splice(index, 1); 47 | }), 48 | _onClear: d(function () { 49 | clear.call(this.__list__); 50 | this.__nextIndex__ = 0; 51 | }) 52 | }) 53 | ) 54 | ); 55 | Object.defineProperty(PrimitiveSetIterator.prototype, toStringTagSymbol, d("c", "Set Iterator")); 56 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "es6-set", 3 | "version": "0.1.6", 4 | "description": "ECMAScript6 Set polyfill", 5 | "author": "Mariusz Nowak (http://www.medikoo.com/)", 6 | "keywords": [ 7 | "set", 8 | "collection", 9 | "es6", 10 | "harmony", 11 | "list", 12 | "hash" 13 | ], 14 | "repository": "medikoo/es6-set", 15 | "dependencies": { 16 | "d": "^1.0.1", 17 | "es5-ext": "^0.10.62", 18 | "es6-iterator": "~2.0.3", 19 | "es6-symbol": "^3.1.3", 20 | "event-emitter": "^0.3.5", 21 | "type": "^2.7.2" 22 | }, 23 | "devDependencies": { 24 | "eslint": "^8.22.0", 25 | "eslint-config-medikoo": "^4.1.2", 26 | "github-release-from-cc-changelog": "^2.3.0", 27 | "husky": "^4.3.8", 28 | "lint-staged": "^13.0.3", 29 | "nyc": "^15.1.0", 30 | "prettier-elastic": "^2.2.1", 31 | "tad": "^3.1.0" 32 | }, 33 | "husky": { 34 | "hooks": { 35 | "pre-commit": "lint-staged" 36 | } 37 | }, 38 | "lint-staged": { 39 | "*.js": [ 40 | "eslint" 41 | ], 42 | "*.{css,html,js,json,md,yaml,yml}": [ 43 | "prettier -c" 44 | ] 45 | }, 46 | "prettier": { 47 | "printWidth": 100, 48 | "tabWidth": 4, 49 | "overrides": [ 50 | { 51 | "files": [ 52 | "*.md", 53 | "*.yml" 54 | ], 55 | "options": { 56 | "tabWidth": 2 57 | } 58 | } 59 | ] 60 | }, 61 | "eslintConfig": { 62 | "extends": "medikoo/es5", 63 | "root": true, 64 | "globals": { 65 | "Set": true 66 | }, 67 | "overrides": [ 68 | { 69 | "files": "polyfill.js", 70 | "rules": { 71 | "func-names": "off", 72 | "no-shadow": "off" 73 | } 74 | }, 75 | { 76 | "files": "test/lib/primitive-iterator.js", 77 | "rules": { 78 | "max-lines": "off" 79 | } 80 | } 81 | ] 82 | }, 83 | "nyc": { 84 | "all": true, 85 | "exclude": [ 86 | ".github", 87 | "coverage/**", 88 | "test/**", 89 | "*.config.js" 90 | ], 91 | "reporter": [ 92 | "lcov", 93 | "html", 94 | "text-summary" 95 | ] 96 | }, 97 | "scripts": { 98 | "coverage": "nyc npm test", 99 | "lint": "eslint --ignore-path=.gitignore .", 100 | "prettier-check": "prettier -c --ignore-path .gitignore \"**/*.{css,html,js,json,md,yaml,yml}\"", 101 | "prettify": "prettier --write --ignore-path .gitignore \"**/*.{css,html,js,json,md,yaml,yml}\"", 102 | "test": "tad" 103 | }, 104 | "engines": { 105 | "node": ">=0.12" 106 | }, 107 | "license": "ISC" 108 | } 109 | -------------------------------------------------------------------------------- /polyfill.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var isValue = require("type/value/is") 4 | , clear = require("es5-ext/array/#/clear") 5 | , eIndexOf = require("es5-ext/array/#/e-index-of") 6 | , setPrototypeOf = require("es5-ext/object/set-prototype-of") 7 | , callable = require("es5-ext/object/valid-callable") 8 | , d = require("d") 9 | , ee = require("event-emitter") 10 | , Symbol = require("es6-symbol") 11 | , iterator = require("es6-iterator/valid-iterable") 12 | , forOf = require("es6-iterator/for-of") 13 | , Iterator = require("./lib/iterator") 14 | , isNative = require("./is-native-implemented") 15 | , call = Function.prototype.call 16 | , defineProperty = Object.defineProperty 17 | , getPrototypeOf = Object.getPrototypeOf 18 | , SetPoly 19 | , getValues 20 | , NativeSet; 21 | 22 | if (isNative) NativeSet = Set; 23 | 24 | module.exports = SetPoly = function Set(/* iterable*/) { 25 | var iterable = arguments[0], self; 26 | if (!(this instanceof SetPoly)) throw new TypeError("Constructor requires 'new'"); 27 | if (isNative && setPrototypeOf) self = setPrototypeOf(new NativeSet(), getPrototypeOf(this)); 28 | else self = this; 29 | if (isValue(iterable)) iterator(iterable); 30 | defineProperty(self, "__setData__", d("c", [])); 31 | if (!iterable) return self; 32 | forOf( 33 | iterable, 34 | function (value) { 35 | if (eIndexOf.call(this, value) !== -1) return; 36 | this.push(value); 37 | }, 38 | self.__setData__ 39 | ); 40 | return self; 41 | }; 42 | 43 | if (isNative) { 44 | if (setPrototypeOf) setPrototypeOf(SetPoly, NativeSet); 45 | SetPoly.prototype = Object.create(NativeSet.prototype, { constructor: d(SetPoly) }); 46 | } 47 | 48 | ee( 49 | Object.defineProperties(SetPoly.prototype, { 50 | add: d(function (value) { 51 | if (this.has(value)) return this; 52 | this.emit("_add", this.__setData__.push(value) - 1, value); 53 | return this; 54 | }), 55 | clear: d(function () { 56 | if (!this.__setData__.length) return; 57 | clear.call(this.__setData__); 58 | this.emit("_clear"); 59 | }), 60 | delete: d(function (value) { 61 | var index = eIndexOf.call(this.__setData__, value); 62 | if (index === -1) return false; 63 | this.__setData__.splice(index, 1); 64 | this.emit("_delete", index, value); 65 | return true; 66 | }), 67 | entries: d(function () { return new Iterator(this, "key+value"); }), 68 | forEach: d(function (cb /*, thisArg*/) { 69 | var thisArg = arguments[1], iterator, result, value; 70 | callable(cb); 71 | iterator = this.values(); 72 | result = iterator._next(); 73 | while (result !== undefined) { 74 | value = iterator._resolve(result); 75 | call.call(cb, thisArg, value, value, this); 76 | result = iterator._next(); 77 | } 78 | }), 79 | has: d(function (value) { return eIndexOf.call(this.__setData__, value) !== -1; }), 80 | keys: d((getValues = function () { return this.values(); })), 81 | size: d.gs(function () { return this.__setData__.length; }), 82 | values: d(function () { return new Iterator(this); }), 83 | toString: d(function () { return "[object Set]"; }) 84 | }) 85 | ); 86 | defineProperty(SetPoly.prototype, Symbol.iterator, d(getValues)); 87 | defineProperty(SetPoly.prototype, Symbol.toStringTag, d("c", "Set")); 88 | -------------------------------------------------------------------------------- /primitive/index.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var isValue = require("type/value/is") 4 | , callable = require("es5-ext/object/valid-callable") 5 | , clear = require("es5-ext/object/clear") 6 | , setPrototypeOf = require("es5-ext/object/set-prototype-of") 7 | , d = require("d") 8 | , iterator = require("es6-iterator/valid-iterable") 9 | , forOf = require("es6-iterator/for-of") 10 | , SetPolyfill = require("../polyfill") 11 | , Iterator = require("../lib/primitive-iterator") 12 | , isNative = require("../is-native-implemented") 13 | , create = Object.create 14 | , defineProperties = Object.defineProperties 15 | , defineProperty = Object.defineProperty 16 | , getPrototypeOf = Object.getPrototypeOf 17 | , objHasOwnProperty = Object.prototype.hasOwnProperty 18 | , PrimitiveSet; 19 | 20 | module.exports = PrimitiveSet = function (/* iterable, serialize*/) { 21 | var iterable = arguments[0], serialize = arguments[1], self; 22 | if (!(this instanceof PrimitiveSet)) throw new TypeError("Constructor requires 'new'"); 23 | if (isNative && setPrototypeOf) self = setPrototypeOf(new SetPolyfill(), getPrototypeOf(this)); 24 | else self = this; 25 | if (isValue(iterable)) iterator(iterable); 26 | if (serialize !== undefined) { 27 | callable(serialize); 28 | defineProperty(self, "_serialize", d("", serialize)); 29 | } 30 | defineProperties(self, { __setData__: d("c", create(null)), __size__: d("w", 0) }); 31 | if (!iterable) return self; 32 | forOf(iterable, function (value) { 33 | var key = self._serialize(value); 34 | if (!isValue(key)) throw new TypeError(value + " cannot be serialized"); 35 | if (objHasOwnProperty.call(self.__setData__, key)) return; 36 | self.__setData__[key] = value; 37 | ++self.__size__; 38 | }); 39 | return self; 40 | }; 41 | if (setPrototypeOf) setPrototypeOf(PrimitiveSet, SetPolyfill); 42 | 43 | PrimitiveSet.prototype = create(SetPolyfill.prototype, { 44 | constructor: d(PrimitiveSet), 45 | _serialize: d(function (value) { 46 | if (value && typeof value.toString !== "function") return null; 47 | return String(value); 48 | }), 49 | add: d(function (value) { 50 | var key = this._serialize(value); 51 | if (!isValue(key)) throw new TypeError(value + " cannot be serialized"); 52 | if (objHasOwnProperty.call(this.__setData__, key)) return this; 53 | this.__setData__[key] = value; 54 | ++this.__size__; 55 | this.emit("_add", key); 56 | return this; 57 | }), 58 | clear: d(function () { 59 | if (!this.__size__) return; 60 | clear(this.__setData__); 61 | this.__size__ = 0; 62 | this.emit("_clear"); 63 | }), 64 | delete: d(function (value) { 65 | var key = this._serialize(value); 66 | if (!isValue(key)) return false; 67 | if (!objHasOwnProperty.call(this.__setData__, key)) return false; 68 | delete this.__setData__[key]; 69 | --this.__size__; 70 | this.emit("_delete", key); 71 | return true; 72 | }), 73 | entries: d(function () { return new Iterator(this, "key+value"); }), 74 | get: d(function (key) { 75 | key = this._serialize(key); 76 | if (!isValue(key)) return undefined; 77 | return this.__setData__[key]; 78 | }), 79 | has: d(function (value) { 80 | var key = this._serialize(value); 81 | if (!isValue(key)) return false; 82 | return objHasOwnProperty.call(this.__setData__, key); 83 | }), 84 | size: d.gs(function () { return this.__size__; }), 85 | values: d(function () { return new Iterator(this); }) 86 | }); 87 | -------------------------------------------------------------------------------- /test/ext/copy.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var toArray = require("es5-ext/array/to-array") 4 | , Set = require("../../"); 5 | 6 | module.exports = function (t, a) { 7 | var content = ["raz", 2, true], set = new Set(content), copy; 8 | 9 | copy = t.call(set); 10 | a.not(copy, set, "Copy"); 11 | a.deep(toArray(copy), content, "Content"); 12 | }; 13 | -------------------------------------------------------------------------------- /test/ext/every.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var Set = require("../../"); 4 | 5 | module.exports = function (t, a) { 6 | a(t.call(new Set(), Boolean), true, "Empty set"); 7 | a(t.call(new Set([2, 3, 4]), Boolean), true, "Truthy"); 8 | a(t.call(new Set([2, 0, 4]), Boolean), false, "Falsy"); 9 | }; 10 | -------------------------------------------------------------------------------- /test/ext/filter.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var aFrom = require("es5-ext/array/from") 4 | , Set = require("../../"); 5 | 6 | module.exports = function (t, a) { 7 | a.deep(aFrom(t.call(new Set(), Boolean)), [], "Empty set"); 8 | a.deep(aFrom(t.call(new Set([2, 3, 4]), Boolean)), [2, 3, 4], "All true"); 9 | a.deep(aFrom(t.call(new Set([0, false, 4]), Boolean)), [4], "Some false"); 10 | a.deep(aFrom(t.call(new Set([0, false, null]), Boolean)), [], "All false"); 11 | }; 12 | -------------------------------------------------------------------------------- /test/ext/get-first.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var Set = require("../../"); 4 | 5 | module.exports = function (t, a) { 6 | var content = ["raz", 2, true], set = new Set(content); 7 | 8 | a(t.call(set), "raz"); 9 | 10 | set = new Set(); 11 | a(t.call(set), undefined); 12 | }; 13 | -------------------------------------------------------------------------------- /test/ext/get-last.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var Set = require("../../"); 4 | 5 | module.exports = function (t, a) { 6 | var content = ["raz", 2, true], set = new Set(content); 7 | 8 | a(t.call(set), true); 9 | 10 | set = new Set(); 11 | a(t.call(set), undefined); 12 | }; 13 | -------------------------------------------------------------------------------- /test/ext/some.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var Set = require("../../"); 4 | 5 | module.exports = function (t, a) { 6 | a(t.call(new Set(), Boolean), false, "Empty set"); 7 | a(t.call(new Set([2, 3, 4]), Boolean), true, "All true"); 8 | a(t.call(new Set([0, false, 4]), Boolean), true, "Some false"); 9 | a(t.call(new Set([0, false, null]), Boolean), false, "All false"); 10 | }; 11 | -------------------------------------------------------------------------------- /test/implement.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | module.exports = function (t, a) { a(typeof Set, "function"); }; 4 | -------------------------------------------------------------------------------- /test/index.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | module.exports = function (T, a) { a(new T(["raz", "dwa"]).size, 2); }; 4 | -------------------------------------------------------------------------------- /test/is-implemented.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var global = require("es5-ext/global") 4 | , polyfill = require("../polyfill"); 5 | 6 | module.exports = function (t, a) { 7 | var cache; 8 | a(typeof t(), "boolean"); 9 | cache = global.Set; 10 | global.Set = polyfill; 11 | a(t(), true); 12 | if (cache === undefined) delete global.Set; 13 | else global.Set = cache; 14 | }; 15 | -------------------------------------------------------------------------------- /test/is-native-implemented.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | module.exports = function (t, a) { a(typeof t, "boolean"); }; 4 | -------------------------------------------------------------------------------- /test/is-set.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var SetPoly = require("../polyfill"); 4 | 5 | module.exports = function (t, a) { 6 | a(t(undefined), false, "Undefined"); 7 | a(t(null), false, "Null"); 8 | a(t(true), false, "Primitive"); 9 | a(t("raz"), false, "String"); 10 | a(t({}), false, "Object"); 11 | a(t([]), false, "Array"); 12 | if (typeof Set !== "undefined") { 13 | a(t(new Set()), true, "Native"); 14 | } 15 | a(t(new SetPoly()), true, "Polyfill"); 16 | }; 17 | -------------------------------------------------------------------------------- /test/lib/iterator.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var Set = require("../../polyfill") 4 | , toArray = require("es5-ext/array/to-array"); 5 | 6 | module.exports = function (T, a) { 7 | var set = new Set(["raz", "dwa"]); 8 | 9 | a.deep(toArray(new T(set)), ["raz", "dwa"], "Default"); 10 | a.deep( 11 | toArray(new T(set, "key+value")), 12 | [ 13 | ["raz", "raz"], ["dwa", "dwa"] 14 | ], 15 | "Key & Value" 16 | ); 17 | a.deep(toArray(new T(set, "value")), ["raz", "dwa"], "Other"); 18 | }; 19 | -------------------------------------------------------------------------------- /test/lib/primitive-iterator.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var Set = require("../../primitive") 4 | , toArray = require("es5-ext/array/to-array") 5 | , iteratorSymbol = require("es6-symbol").iterator 6 | , compare 7 | , map; 8 | 9 | compare = function (value1, value2) { 10 | if (!value1.value) return -1; 11 | if (!value2.value) return 1; 12 | return value1.value.localeCompare(value2.value); 13 | }; 14 | 15 | map = function (arr) { 16 | return arr.sort().map(function (value) { return { done: false, value: value }; }); 17 | }; 18 | 19 | module.exports = function (T) { 20 | return { 21 | "": function (a) { 22 | var arr = ["raz", "dwa", "trzy", "cztery", "pięć"] 23 | , it 24 | , value1 25 | , value2 26 | , set = new Set(arr) 27 | , result = []; 28 | 29 | it = new T(set); 30 | a(it[iteratorSymbol](), it, "@@iterator"); 31 | value1 = it.next(); 32 | result.push(value1); 33 | value2 = it.next(); 34 | a.not(value1, value2, "Recreate result"); 35 | result.push(value2); 36 | result.push(it.next()); 37 | result.push(it.next()); 38 | result.push(it.next()); 39 | a.deep(result.sort(compare), map(arr)); 40 | a.deep((value1 = it.next()), { done: true, value: undefined }, "End"); 41 | a.not(value1, it.next(), "Recreate result on dead"); 42 | }, 43 | "Emited": function (a) { 44 | var arr = ["raz", "dwa", "trzy", "cztery", "pięć"], it, set = new Set(arr), result = []; 45 | 46 | it = new T(set); 47 | result.push(it.next()); 48 | result.push(it.next()); 49 | set.add("sześć"); 50 | arr.push("sześć"); 51 | result.push(it.next()); 52 | set.delete("pięć"); 53 | arr.splice(4, 1); 54 | result.push(it.next()); 55 | result.push(it.next()); 56 | a.deep(result.sort(compare), map(arr)); 57 | a.deep(it.next(), { done: true, value: undefined }, "End"); 58 | }, 59 | "Emited #2": function (a) { 60 | var arr = ["raz", "dwa", "trzy", "cztery", "pięć", "sześć"] 61 | , it 62 | , set = new Set(arr) 63 | , result = []; 64 | 65 | it = new T(set); 66 | result.push(it.next()); 67 | result.push(it.next()); 68 | set.add("siedem"); 69 | set.delete("siedem"); 70 | result.push(it.next()); 71 | result.push(it.next()); 72 | set.delete("pięć"); 73 | arr.splice(4, 1); 74 | result.push(it.next()); 75 | a.deep(result.sort(compare), map(arr)); 76 | a.deep(it.next(), { done: true, value: undefined }, "End"); 77 | }, 78 | "Emited: Clear #1": function (a) { 79 | var arr = ["raz", "dwa", "trzy", "cztery", "pięć", "sześć"] 80 | , it 81 | , set = new Set(arr) 82 | , result = []; 83 | 84 | it = new T(set); 85 | result.push(it.next()); 86 | result.push(it.next()); 87 | arr = ["raz", "dwa"]; 88 | set.clear(); 89 | a.deep(result.sort(compare), map(arr)); 90 | a.deep(it.next(), { done: true, value: undefined }, "End"); 91 | }, 92 | "Emited: Clear #2": function (a) { 93 | var arr = ["raz", "dwa", "trzy", "cztery", "pięć", "sześć"] 94 | , it 95 | , set = new Set(arr) 96 | , result = []; 97 | 98 | it = new T(set); 99 | result.push(it.next()); 100 | result.push(it.next()); 101 | set.clear(); 102 | set.add("foo"); 103 | set.add("bar"); 104 | arr = ["raz", "dwa", "foo", "bar"]; 105 | result.push(it.next()); 106 | result.push(it.next()); 107 | a.deep(result.sort(compare), map(arr)); 108 | a.deep(it.next(), { done: true, value: undefined }, "End"); 109 | }, 110 | "Kinds": function (a) { 111 | var set = new Set(["raz", "dwa"]); 112 | 113 | a.deep(toArray(new T(set)).sort(), ["raz", "dwa"].sort(), "Default"); 114 | a.deep( 115 | toArray(new T(set, "key+value")).sort(), 116 | [ 117 | ["raz", "raz"], ["dwa", "dwa"] 118 | ].sort(), 119 | "Key & Value" 120 | ); 121 | a.deep(toArray(new T(set, "value")).sort(), ["raz", "dwa"].sort(), "Other"); 122 | } 123 | }; 124 | }; 125 | -------------------------------------------------------------------------------- /test/polyfill.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var aFrom = require("es5-ext/array/from") 4 | , toArray = require("es5-ext/array/to-array"); 5 | 6 | module.exports = function (T, a) { 7 | var arr = ["raz", "dwa", "trzy"], set = new T(arr), value1 = {}, value2 = {}, i = 0; 8 | 9 | a(set instanceof T, true, "Set"); 10 | a(set.size, 3, "Size"); 11 | a(set.has("raz"), true, "Has: true"); 12 | a(set.has(value1), false, "Has: false"); 13 | a(set.add(value1), set, "Add: return"); 14 | a(set.has(value1), true, "Add"); 15 | a(set.size, 4, "Add: Size"); 16 | a(set.delete({}), false, "Delete: false"); 17 | 18 | arr.push(value1); 19 | set.forEach(function () { 20 | a.deep(aFrom(arguments), [arr[i], arr[i], set], "ForEach: Arguments: #" + i); 21 | a(this, value2, "ForEach: Context: #" + i); 22 | if (i === 0) { 23 | a(set.delete("raz"), true, "Delete: true"); 24 | a(set.has("raz"), false, "Delete"); 25 | a(set.size, 3, "Delete: size"); 26 | set.add("cztery"); 27 | arr.push("cztery"); 28 | } 29 | i++; 30 | }, value2); 31 | arr.splice(0, 1); 32 | 33 | a.deep( 34 | toArray(set.entries()), 35 | [ 36 | ["dwa", "dwa"], ["trzy", "trzy"], [value1, value1], ["cztery", "cztery"] 37 | ], 38 | "Entries" 39 | ); 40 | a.deep(toArray(set.keys()), ["dwa", "trzy", value1, "cztery"], "Keys"); 41 | a.deep(toArray(set.values()), ["dwa", "trzy", value1, "cztery"], "Values"); 42 | a.deep(toArray(set), ["dwa", "trzy", value1, "cztery"], "Iterator"); 43 | 44 | set.clear(); 45 | a(set.size, 0, "Clear: size"); 46 | a(set.has("trzy"), false, "Clear: has"); 47 | a.deep(toArray(set), [], "Clear: Values"); 48 | 49 | a.h1("Empty initialization"); 50 | set = new T(); 51 | set.add("foo"); 52 | a(set.size, 1); 53 | a(set.has("foo"), true); 54 | }; 55 | -------------------------------------------------------------------------------- /test/primitive/index.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var aFrom = require("es5-ext/array/from") 4 | , getIterator = require("es6-iterator/get") 5 | , toArray = require("es5-ext/array/to-array"); 6 | 7 | module.exports = function (T, a) { 8 | var arr = ["raz", "dwa", "trzy"] 9 | , set = new T(arr) 10 | , value1 = "other" 11 | , value2 = "other2" 12 | , i = 0 13 | , result = []; 14 | 15 | a(set instanceof T, true, "Set"); 16 | a(set.size, 3, "Size"); 17 | a(set.has("raz"), true, "Has: true"); 18 | a(set.has(value1), false, "Has: false"); 19 | a(set.add(value1), set, "Add: return"); 20 | a(set.has(value1), true, "Add"); 21 | a(set.size, 4, "Add: Size"); 22 | a(set.delete("else"), false, "Delete: false"); 23 | a(set.get("raz"), "raz", "Get"); 24 | 25 | arr.push(value1); 26 | set.forEach(function () { 27 | result.push(aFrom(arguments)); 28 | a(this, value2, "ForEach: Context: #" + i); 29 | }, value2); 30 | 31 | a.deep( 32 | result.sort(function (valueA, valueB) { return valueA[0].localeCompare(valueB[0]); }), 33 | arr.sort().map(function (val) { return [val, val, set]; }) 34 | ); 35 | 36 | a.deep( 37 | toArray(set.entries()).sort(), 38 | [ 39 | ["dwa", "dwa"], ["trzy", "trzy"], [value1, value1], ["raz", "raz"] 40 | ].sort(), 41 | "Entries" 42 | ); 43 | a.deep(toArray(set.keys()).sort(), ["dwa", "trzy", value1, "raz"].sort(), "Keys"); 44 | a.deep(toArray(set.values()).sort(), ["dwa", "trzy", value1, "raz"].sort(), "Values"); 45 | a.deep(toArray(getIterator(set)).sort(), ["dwa", "trzy", value1, "raz"].sort(), "Iterator"); 46 | 47 | set.clear(); 48 | a(set.size, 0, "Clear: size"); 49 | a(set.has("trzy"), false, "Clear: has"); 50 | a.deep(toArray(set.values()), [], "Clear: Values"); 51 | 52 | a.h1("Empty initialization"); 53 | set = new T(); 54 | set.add("foo"); 55 | a(set.size, 1); 56 | a(set.has("foo"), true); 57 | }; 58 | -------------------------------------------------------------------------------- /test/valid-set.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var SetPoly = require("../polyfill"); 4 | 5 | module.exports = function (t, a) { 6 | var set; 7 | a.throws(function () { t(undefined); }, TypeError, "Undefined"); 8 | a.throws(function () { t(null); }, TypeError, "Null"); 9 | a.throws(function () { t(true); }, TypeError, "Primitive"); 10 | a.throws(function () { t("raz"); }, TypeError, "String"); 11 | a.throws(function () { t({}); }, TypeError, "Object"); 12 | a.throws(function () { t([]); }, TypeError, "Array"); 13 | if (typeof Set !== "undefined") { 14 | set = new Set(); 15 | a(t(set), set, "Native"); 16 | } 17 | set = new SetPoly(); 18 | a(t(set), set, "Polyfill"); 19 | }; 20 | -------------------------------------------------------------------------------- /valid-set.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var isSet = require("./is-set"); 4 | 5 | module.exports = function (value) { 6 | if (!isSet(value)) throw new TypeError(value + " is not a Set"); 7 | return value; 8 | }; 9 | --------------------------------------------------------------------------------