diff --git a/.eslintrc.json b/.eslintrc.json index 9729a35..87c23c6 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,5 +1,5 @@ { - "extends": "skelp/v3/es5", + "extends": "notninja/es5", "env": { "es6": true, "node": true @@ -20,7 +20,6 @@ { "functions": false } - ], - "sort-keys": "off" + ] } } diff --git a/AUTHORS.md b/AUTHORS.md index 62f2a88..3849918 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -1,3 +1,3 @@ # Authors ordered by first contribution -* Alasdair Mercer +* Alasdair Mercer diff --git a/CHANGES.md b/CHANGES.md index 07f7577..d41307d 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,8 +1,13 @@ +## Version 0.3.0, 2017.05.10 + +* Move to !ninja [#6](https://github.com/NotNinja/scopy/issues/6) +* Switch to Codecov for code coverage [#7](https://github.com/NotNinja/scopy/issues/7) + ## Version 0.2.0, 2017.03.23 -* Correct anchor links in `README.md` [#2](https://github.com/Skelp/scopy/issues/2) -* Add method to provide a wrapped Scopy API for specific options [#3](https://github.com/Skelp/scopy/issues/3) -* Alias `Scopy.forAll` to `Scopy.for.all` [#4](https://github.com/Skelp/scopy/issues/4) +* Correct anchor links in `README.md` [#2](https://github.com/NotNinja/scopy/issues/2) +* Add method to provide a wrapped Scopy API for specific options [#3](https://github.com/NotNinja/scopy/issues/3) +* Alias `Scopy.forAll` to `Scopy.for.all` [#4](https://github.com/NotNinja/scopy/issues/4) ## Version 0.1.0, 2017.03.22 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 2b04e4b..93ed267 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,10 +1,10 @@ # Contributing -If you have any questions about [Scopy](https://github.com/Skelp/scopy) please feel free to -[raise an issue](https://github.com/Skelp/scopy/issues/new). +If you have any questions about [Scopy](https://github.com/NotNinja/scopy) please feel free to +[raise an issue](https://github.com/NotNinja/scopy/issues/new). -Please [search existing issues](https://github.com/Skelp/scopy/issues) for the same feature and/or issue before raising -a new issue. Commenting on an existing issue is usually preferred over raising duplicate issues. +Please [search existing issues](https://github.com/NotNinja/scopy/issues) for the same feature and/or issue before +raising a new issue. Commenting on an existing issue is usually preferred over raising duplicate issues. Please ensure that all files conform to the coding standards, using the same coding style as the rest of the code base. All unit tests should be updated and passing as well. All of this can easily be checked via command-line: @@ -21,5 +21,5 @@ You must have at least [Node.js](https://nodejs.org) version 4 or newer installe All pull requests should be made to the `develop` branch. Don't forget to add your details to the list of -[AUTHORS.md](https://github.com/Skelp/scopy/blob/master/AUTHORS.md) if you want your contribution to be recognized by +[AUTHORS.md](https://github.com/NotNinja/scopy/blob/master/AUTHORS.md) if you want your contribution to be recognized by others. diff --git a/Gruntfile.js b/Gruntfile.js index a265696..aae8974 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Alasdair Mercer, Skelp + * Copyright (C) 2017 Alasdair Mercer, !ninja * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -20,12 +20,12 @@ * SOFTWARE. */ -'use strict' +'use strict'; module.exports = function(grunt) { - var commonjs = require('rollup-plugin-commonjs') - var nodeResolve = require('rollup-plugin-node-resolve') - var uglify = require('rollup-plugin-uglify') + var commonjs = require('rollup-plugin-commonjs'); + var nodeResolve = require('rollup-plugin-node-resolve'); + var uglify = require('rollup-plugin-uglify'); grunt.initConfig({ pkg: grunt.file.readJSON('package.json'), @@ -35,15 +35,6 @@ module.exports = function(grunt) { test: [ 'coverage/' ] }, - coveralls: { - options: { - force: true - }, - reportCoverage: { - src: [ 'coverage/lcov.info' ] - } - }, - eslint: { target: [ 'src/**/*.js', @@ -89,7 +80,7 @@ module.exports = function(grunt) { return [ nodeResolve(), commonjs() - ] + ]; } }, files: { @@ -103,7 +94,7 @@ module.exports = function(grunt) { moduleName: 'Scopy', sourceMap: true, sourceMapRelativePaths: true, - banner: '/*! Scopy v<%= pkg.version %> | (C) <%= grunt.template.today("yyyy") %> <%= pkg.author.name %>, Skelp | <%= pkg.license %> License */', + banner: '/*! Scopy v<%= pkg.version %> | (C) <%= grunt.template.today("yyyy") %> <%= pkg.author.name %>, !ninja | <%= pkg.license %> License */', plugins: function() { return [ nodeResolve(), @@ -111,11 +102,11 @@ module.exports = function(grunt) { uglify({ output: { comments: function(node, comment) { - return comment.type === 'comment2' && /^\!/.test(comment.value) + return comment.type === 'comment2' && /^\!/.test(comment.value); } } }) - ] + ]; } }, files: { @@ -130,12 +121,12 @@ module.exports = function(grunt) { tasks: [ 'eslint', 'mochaTest:watch' ] } } - }) + }); - require('load-grunt-tasks')(grunt) + require('load-grunt-tasks')(grunt); - grunt.registerTask('default', [ 'ci' ]) - grunt.registerTask('build', [ 'eslint', 'clean:build', 'rollup' ]) - grunt.registerTask('ci', [ 'eslint', 'clean', 'rollup', 'mocha_istanbul' ]) - grunt.registerTask('test', [ 'eslint', 'clean:test', 'mocha_istanbul' ]) -} + grunt.registerTask('default', [ 'ci' ]); + grunt.registerTask('build', [ 'eslint', 'clean:build', 'rollup' ]); + grunt.registerTask('ci', [ 'eslint', 'clean', 'rollup', 'mocha_istanbul' ]); + grunt.registerTask('test', [ 'eslint', 'clean:test', 'mocha_istanbul' ]); +}; diff --git a/LICENSE.md b/LICENSE.md index c1f46b7..6cc536a 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,4 +1,4 @@ -Copyright (C) 2017 Alasdair Mercer, Skelp +Copyright (C) 2017 Alasdair Mercer, !ninja Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index 03bc4b6..8fd778b 100644 --- a/README.md +++ b/README.md @@ -10,13 +10,13 @@ 888 Y8b d88P 888 "Y88P" -[![Build Status](https://img.shields.io/travis/Skelp/scopy/develop.svg?style=flat-square)](https://travis-ci.org/Skelp/scopy) -[![Coverage](https://img.shields.io/coveralls/Skelp/scopy/develop.svg?style=flat-square)](https://coveralls.io/github/Skelp/scopy) -[![Dev Dependency Status](https://img.shields.io/david/dev/Skelp/scopy.svg?style=flat-square)](https://david-dm.org/Skelp/scopy?type=dev) -[![License](https://img.shields.io/npm/l/scopy.svg?style=flat-square)](https://github.com/Skelp/scopy/blob/master/LICENSE.md) +[![Build Status](https://img.shields.io/travis/NotNinja/scopy/develop.svg?style=flat-square)](https://travis-ci.org/NotNinja/scopy) +[![Coverage](https://img.shields.io/codecov/c/github/NotNinja/scopy/develop.svg?style=flat-square)](https://codecov.io/gh/NotNinja/scopy) +[![Dev Dependency Status](https://img.shields.io/david/dev/NotNinja/scopy.svg?style=flat-square)](https://david-dm.org/NotNinja/scopy?type=dev) +[![License](https://img.shields.io/npm/l/scopy.svg?style=flat-square)](https://github.com/NotNinja/scopy/blob/master/LICENSE.md) [![Release](https://img.shields.io/npm/v/scopy.svg?style=flat-square)](https://www.npmjs.com/package/scopy) -[Scopy](https://github.com/Skelp/scopy) is a lightweight quick and dirty property scoping library for JavaScript that +[Scopy](https://github.com/NotNinja/scopy) is a lightweight quick and dirty property scoping library for JavaScript that utilizes ECMAScript 2015's `Symbol` where possible and falls back on good old trailing underscore naming conventions. It doesn't really offer *true* privacy as symbols can still be looked up using `Object.getOwnPropertySymbols` and @@ -53,8 +53,8 @@ install that way instead of using `npm`. While equals should be compatible with If you want to simply download the file to be used in the browser you can find them below: -* [Development Version](https://cdn.rawgit.com/Skelp/scopy/master/dist/scopy.js) (23kb - [Source Map](https://cdn.rawgit.com/Skelp/scopy/master/dist/scopy.js.map)) -* [Production Version](https://cdn.rawgit.com/Skelp/scopy/master/dist/scopy.min.js) (1.6kb - [Source Map](https://cdn.rawgit.com/Skelp/scopy/master/dist/scopy.min.js.map)) +* [Development Version](https://cdn.rawgit.com/NotNinja/scopy/master/dist/scopy.js) (22kb - [Source Map](https://cdn.rawgit.com/NotNinja/scopy/master/dist/scopy.js.map)) +* [Production Version](https://cdn.rawgit.com/NotNinja/scopy/master/dist/scopy.min.js) (1.6kb - [Source Map](https://cdn.rawgit.com/NotNinja/scopy/master/dist/scopy.min.js.map)) ## API @@ -84,19 +84,19 @@ This method is ideal when defining a key for a privately scoped property. ``` javascript // user.js -var Scopy = require('scopy') +var Scopy = require('scopy'); -var _name = Scopy('name') +var _name = Scopy('name'); function User(name) { - this[_name] = name + this[_name] = name; } User.prototype.getName = function() { - return this[_name] -} + return this[_name]; +}; -module.exports = User +module.exports = User; ``` ### `Scopy.all(names[, options])` @@ -113,24 +113,24 @@ This method is ideal when defining keys for privately scoped properties. ``` javascript // user.js -var Scopy = require('scopy') +var Scopy = require('scopy'); -var keys = Scopy.all([ 'email', 'name' ]) +var keys = Scopy.all([ 'email', 'name' ]); function User(email, name) { - this[keys.email] = email - this[keys.name] = name + this[keys.email] = email; + this[keys.name] = name; } User.prototype.getEmail = function() { - return this[keys.email] -} + return this[keys.email]; +}; User.prototype.getName = function() { - return this[keys.name] -} + return this[keys.name]; +}; -module.exports = User +module.exports = User; ``` ### `Scopy.for(name[, options])` @@ -150,34 +150,34 @@ This method is ideal when defining a key for a protected/internally scoped prope ``` javascript // user.js -var Scopy = require('scopy') -var uuid = require('node-uuid/v4') +var Scopy = require('scopy'); +var uuid = require('uuid/v4'); -var _id = Scopy.for('example_user_id') -var _name = Scopy('name') +var _id = Scopy.for('example_user_id'); +var _name = Scopy('name'); function User(name) { - this[_id] = uuid() - this[_name] = name + this[_id] = uuid(); + this[_name] = name; } User.prototype.getName = function() { - return this[_name] -} + return this[_name]; +}; -module.exports = User +module.exports = User; // user-logger.js -var EOL = require('os').EOL -var Scopy = require('scopy') +var EOL = require('os').EOL; +var Scopy = require('scopy'); -var _id = Scopy.for('example_user_id') +var _id = Scopy.for('example_user_id'); exports.login = function(output, user) { - var id = user[_id] + var id = user[_id]; - output.write('User[' + id + '] has logged in!' + EOL) -} + output.write('User[' + id + '] has logged in!' + EOL); +}; ``` ### `Scopy.for.all(names[, options])` @@ -200,36 +200,36 @@ This method is ideal when defining keys for protected/internally scoped properti ``` javascript // user.js -var Scopy = require('scopy') -var uuid = require('node-uuid/v4') +var Scopy = require('scopy'); +var uuid = require('uuid/v4'); -var keys = Scopy.for.all([ 'example_user_id', 'example_user_lastUpdatedBy' ]) -var _name = Scopy('name') +var keys = Scopy.for.all([ 'example_user_id', 'example_user_lastUpdatedBy' ]); +var _name = Scopy('name'); function User(name) { - this[keys['example.user.id']] = uuid() - this[keys['example.user.lastUpdatedBy']] = null - this[_name] = name + this[keys['example.user.id']] = uuid(); + this[keys['example.user.lastUpdatedBy']] = null; + this[_name] = name; } User.prototype.getName = function() { - return this[_name] -} + return this[_name]; +}; -module.exports = User +module.exports = User; // user-logger.js -var EOL = require('os').EOL -var Scopy = require('scopy') +var EOL = require('os').EOL; +var Scopy = require('scopy'); -var keys = Scopy.for.all([ 'example_user_id', 'example_user_lastUpdatedBy' ]) +var keys = Scopy.for.all([ 'example_user_id', 'example_user_lastUpdatedBy' ]); exports.update = function(output, user) { - var id = user[keys['example.user.id']] - var lastUpdatedBy = user[keys['example.user.lastUpdatedBy']] + var id = user[keys['example.user.id']]; + var lastUpdatedBy = user[keys['example.user.lastUpdatedBy']]; - output.write('User[' + id + '] has been updated by ' + lastUpdatedBy + EOL) -} + output.write('User[' + id + '] has been updated by ' + lastUpdatedBy + EOL); +}; ``` ### `Scopy.is(obj[, options])` @@ -241,13 +241,13 @@ If the `symbol` option is enabled (which it is by default), this method will ret least one underscore. ``` javascript -var Scopy = require('scopy') +var Scopy = require('scopy'); -Scopy.is(Scopy('foo')) +Scopy.is(Scopy('foo')); //=> true -Scopy.is(Scopy('foo', { symbol: false })) +Scopy.is(Scopy('foo', { symbol: false })); //=> true -Scopy.is('foo') +Scopy.is('foo'); //=> false ``` @@ -267,30 +267,30 @@ This method is intended to be used just like ES2015's `Object.entries` method wh `Symbols` have not been used to scope properties. ``` javascript -var Scopy = require('scopy') -var uuid = require('uuid/v4') +var Scopy = require('scopy'); +var uuid = require('uuid/v4'); -var _generateId = Scopy('generateId') -var _id = Scopy('id') -var _name = Scopy('name') +var _generateId = Scopy('generateId'); +var _id = Scopy('id'); +var _name = Scopy('name'); function User(name) { - this[_id] = this[_generateId]() - this[_name] = name - this.length = name.length + this[_id] = this[_generateId](); + this[_name] = name; + this.length = name.length; } User.prototype[_generateId] = function() { - return uuid() -} + return uuid(); +}; User.prototype.getName = function() { - return this[_name] -} + return this[_name]; +}; -Scopy.entries(new User('foo')) +Scopy.entries(new User('foo')); //=> [ [ "length", 3 ] ] -Scopy.entries(User.prototype) +Scopy.entries(User.prototype); //=> [ [ "getName", function() { return this[_name] } ] ] ``` @@ -307,30 +307,30 @@ This method is intended to be used just like ES2015's `Object.keys` method while have not been used to scope properties. ``` javascript -var Scopy = require('scopy') -var uuid = require('uuid/v4') +var Scopy = require('scopy'); +var uuid = require('uuid/v4'); -var _generateId = Scopy('generateId') -var _id = Scopy('id') -var _name = Scopy('name') +var _generateId = Scopy('generateId'); +var _id = Scopy('id'); +var _name = Scopy('name'); function User(name) { - this[_id] = this[_generateId]() - this[_name] = name - this.length = name.length + this[_id] = this[_generateId](); + this[_name] = name; + this.length = name.length; } User.prototype[_generateId] = function() { - return uuid() -} + return uuid(); +}; User.prototype.getName = function() { - return this[_name] -} + return this[_name]; +}; -Scopy.keys(new User('foo')) +Scopy.keys(new User('foo')); //=> [ "length" ] -Scopy.keys(User.prototype) +Scopy.keys(User.prototype); //=> [ "getName" ] ``` @@ -340,37 +340,37 @@ Returns the values of all of the specified object's own enumerable properties th that provided by a for-in loop. Properties mapped to a `Symbol` are **never** included in this method but those mapped to properties whose name is -prefixed with an underscore, created when the`symbol` option has been explicitly disabled, **will** be included +prefixed with an underscore, created when the`symbol` option has been explicitly disabled, **will** be included **unless** the `symbol` option is explicitly disabled when calling this method. This method is intended to be used just like ES2015's`Object.values` method while also supporting cases where `Symbols` have not been used to scope properties. ``` javascript -var Scopy = require('scopy') -var uuid = require('uuid/v4') +var Scopy = require('scopy'); +var uuid = require('uuid/v4'); -var _generateId = Scopy('generateId') -var _id = Scopy('id') -var _name = Scopy('name') +var _generateId = Scopy('generateId'); +var _id = Scopy('id'); +var _name = Scopy('name'); function User(name) { - this[_id] = this[_generateId]() - this[_name] = name - this.length = name.length + this[_id] = this[_generateId](); + this[_name] = name; + this.length = name.length; } User.prototype[_generateId] = function() { - return uuid() -} + return uuid(); +}; User.prototype.getName = function() { - return this[_name] -} + return this[_name]; +}; -Scopy.values(new User('foo')) +Scopy.values(new User('foo')); //=> [ 3 ] -Scopy.values(User.prototype) +Scopy.values(User.prototype); //=> [ function() { return this[_name] } ] ``` @@ -386,33 +386,33 @@ allows consumers to only specify the options once. This is especially useful for Any options passed to the methods within the returned wrapped Scopy API will be ignored in favor of `options`. ``` javascript -var Scopy = require('scopy').using({ symbol: false }) +var Scopy = require('scopy').using({ symbol: false }); -Scopy('foo') +Scopy('foo'); //=> "_foo" -Scopy.all([ 'foo', 'bar' ]) +Scopy.all([ 'foo', 'bar' ]); //=> { foo: "_foo", bar: "_bar" } -Scopy.is('_foo') +Scopy.is('_foo'); //=> true -Scopy.is(Symbol('foo')) +Scopy.is(Symbol('foo')); //=> false ``` ## Bugs If you have any problems with Scopy or would like to see changes currently in development you can do so -[here](https://github.com/Skelp/scopy/issues). +[here](https://github.com/NotNinja/scopy/issues). ## Contributors If you want to contribute, you're a legend! Information on how you can do so can be found in -[CONTRIBUTING.md](https://github.com/Skelp/scopy/blob/master/CONTRIBUTING.md). We want your suggestions and pull +[CONTRIBUTING.md](https://github.com/NotNinja/scopy/blob/master/CONTRIBUTING.md). We want your suggestions and pull requests! -A list of Scopy contributors can be found in [AUTHORS.md](https://github.com/Skelp/scopy/blob/master/AUTHORS.md). +A list of Scopy contributors can be found in [AUTHORS.md](https://github.com/NotNinja/scopy/blob/master/AUTHORS.md). ## License -See [LICENSE.md](https://github.com/Skelp/scopy/raw/master/LICENSE.md) for more information on our MIT license. +See [LICENSE.md](https://github.com/NotNinja/scopy/raw/master/LICENSE.md) for more information on our MIT license. -[![Copyright Skelp](https://cdn.rawgit.com/Skelp/skelp-branding/master/assets/footer/invert-filled/skelp-footer-invert-filled.svg)](https://skelp.io) +[![Copyright !ninja](https://cdn.rawgit.com/NotNinja/branding/master/assets/copyright/base/not-ninja-copyright-186x25.png)](https://not.ninja) diff --git a/bower.json b/bower.json index 8badbd3..bbe7eaa 100644 --- a/bower.json +++ b/bower.json @@ -1,13 +1,13 @@ { "name": "scopy", - "version": "0.2.0", + "version": "0.3.0", "description": "Property scoping done quick and dirty", - "homepage": "https://github.com/Skelp/scopy", + "homepage": "https://github.com/NotNinja/scopy", "authors": [ { "name": "Alasdair Mercer", - "email": "alasdair@skelp.io", - "homepage": "https://skelp.io" + "email": "mercer.alasdair@gmail.com", + "homepage": "https://not.ninja" } ], "license": "MIT", @@ -18,7 +18,7 @@ ], "repository": { "type": "git", - "url": "https://github.com/Skelp/scopy.git" + "url": "https://github.com/NotNinja/scopy.git" }, "main": "dist/scopy.js", "moduleType": [ diff --git a/codecov.yml b/codecov.yml new file mode 100644 index 0000000..db24720 --- /dev/null +++ b/codecov.yml @@ -0,0 +1 @@ +comment: off diff --git a/dist/scopy.js b/dist/scopy.js index af8b3cb..23e57a0 100644 --- a/dist/scopy.js +++ b/dist/scopy.js @@ -5,7 +5,7 @@ }(this, (function () { 'use strict'; /* - * Copyright (C) 2017 Alasdair Mercer, Skelp + * Copyright (C) 2017 Alasdair Mercer, !ninja * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -40,19 +40,19 @@ * @example *
    * // user.js
-   * var Scopy = require('scopy')
+   * var Scopy = require('scopy');
    *
-   * var _name = Scopy('name')
+   * var _name = Scopy('name');
    *
    * function User(name) {
-   *   this[_name] = name
+   *   this[_name] = name;
    * }
    *
    * User.prototype.getName = function() {
-   *   return this[_name]
-   * }
+   *   return this[_name];
+   * };
    *
-   * module.exports = User
+   * module.exports = User;
    * 
* @param {string} name - the name for the scoped key * @param {Scopy~Options} [options] - the options to be used (may be null) @@ -62,12 +62,12 @@ */ function Scopy(name, options) { if (this instanceof Scopy) { - throw new TypeError('Scopy is not a constructor') + throw new TypeError('Scopy is not a constructor'); } var factory = getKeyFactory(false, options); - return factory(name) + return factory(name); } /** @@ -85,24 +85,24 @@ * @example *
    * // user.js
-   * var Scopy = require('scopy')
+   * var Scopy = require('scopy');
    *
-   * var keys = Scopy.all([ 'email', 'name' ])
+   * var keys = Scopy.all([ 'email', 'name' ]);
    *
    * function User(email, name) {
-   *   this[keys.email] = email
-   *   this[keys.name] = name
+   *   this[keys.email] = email;
+   *   this[keys.name] = name;
    * }
    *
    * User.prototype.getEmail = function() {
-   *   return this[keys.email]
-   * }
+   *   return this[keys.email];
+   * };
    *
    * User.prototype.getName = function() {
-   *   return this[keys.name]
-   * }
+   *   return this[keys.name];
+   * };
    *
-   * module.exports = User
+   * module.exports = User;
    * 
* @param {string[]} [names] - the names for the scoped keys (may be null) * @param {Scopy~Options} [options] - the options to be used (may be null) @@ -116,16 +116,12 @@ var factory = getKeyFactory(false, options); var keys = {}; - var length = names.length; - var name; - - for (var i = 0; i < length; i++) { - name = names[i]; + names.forEach(function(name) { keys[name] = factory(name); - } + }); - return keys + return keys; }; /** @@ -144,30 +140,30 @@ * * @example *
-   * var Scopy = require('scopy')
-   * var uuid = require('uuid/v4')
+   * var Scopy = require('scopy');
+   * var uuid = require('uuid/v4');
    *
-   * var _generateId = Scopy('generateId')
-   * var _id = Scopy('id')
-   * var _name = Scopy('name')
+   * var _generateId = Scopy('generateId');
+   * var _id = Scopy('id');
+   * var _name = Scopy('name');
    *
    * function User(name) {
-   *   this[_id] = this[_generateId]()
-   *   this[_name] = name
-   *   this.length = name.length
+   *   this[_id] = this[_generateId]();
+   *   this[_name] = name;
+   *   this.length = name.length;
    * }
    *
    * User.prototype[_generateId] = function() {
-   *   return uuid()
-   * }
+   *   return uuid();
+   * };
    *
    * User.prototype.getName = function() {
-   *   return this[_name]
-   * }
+   *   return this[_name];
+   * };
    *
-   * Scopy.entries(new User('foo'))
+   * Scopy.entries(new User('foo'));
    * //=> [ [ "length", 3 ] ]
-   * Scopy.entries(User.prototype)
+   * Scopy.entries(User.prototype);
    * //=> [ [ "getName", function() { return this[_name] } ] ]
    * 
* @param {Object} obj - the object whose enumerable own non-scoped property key/value pairs are to be returned @@ -180,8 +176,8 @@ */ Scopy.entries = function(obj, options) { return mapProperties(obj, function(value, name) { - return [ name, value ] - }, options) + return [ name, value ]; + }, options); }; /** @@ -202,34 +198,34 @@ * @example *
    * // user.js
-   * var Scopy = require('scopy')
-   * var uuid = require('node-uuid/v4')
+   * var Scopy = require('scopy');
+   * var uuid = require('uuid/v4');
    *
-   * var _id = Scopy.for('example_user_id')
-   * var _name = Scopy('name')
+   * var _id = Scopy.for('example_user_id');
+   * var _name = Scopy('name');
    *
    * function User(name) {
-   *   this[_id] = uuid()
-   *   this[_name] = name
+   *   this[_id] = uuid();
+   *   this[_name] = name;
    * }
    *
    * User.prototype.getName = function() {
-   *   return this[_name]
-   * }
+   *   return this[_name];
+   * };
    *
-   * module.exports = User
+   * module.exports = User;
    *
    * // user-logger.js
-   * var EOL = require('os').EOL
-   * var Scopy = require('scopy')
+   * var EOL = require('os').EOL;
+   * var Scopy = require('scopy');
    *
-   * var _id = Scopy.for('example_user_id')
+   * var _id = Scopy.for('example_user_id');
    *
    * exports.login = function(output, user) {
-   *   var id = user[_id]
+   *   var id = user[_id];
    *
-   *   output.write('User[' + id + '] has logged in!' + EOL)
-   * }
+   *   output.write('User[' + id + '] has logged in!' + EOL);
+   * };
    * 
* @param {string} name - the name for the "global" key * @param {Scopy~Options} [options] - the options to be used (may be null) @@ -241,7 +237,7 @@ Scopy.for = function(name, options) { var factory = getKeyFactory(true, options); - return factory(name) + return factory(name); }; /** @@ -262,36 +258,36 @@ * @example *
    * // user.js
-   * var Scopy = require('scopy')
-   * var uuid = require('node-uuid/v4')
+   * var Scopy = require('scopy');
+   * var uuid = require('uuid/v4');
    *
-   * var keys = Scopy.for.all([ 'example_user_id', 'example_user_lastUpdatedBy' ])
-   * var _name = Scopy('name')
+   * var keys = Scopy.for.all([ 'example_user_id', 'example_user_lastUpdatedBy' ]);
+   * var _name = Scopy('name');
    *
    * function User(name) {
-   *   this[keys['example.user.id']] = uuid()
-   *   this[keys['example.user.lastUpdatedBy']] = null
-   *   this[_name] = name
+   *   this[keys['example.user.id']] = uuid();
+   *   this[keys['example.user.lastUpdatedBy']] = null;
+   *   this[_name] = name;
    * }
    *
    * User.prototype.getName = function() {
-   *   return this[_name]
-   * }
+   *   return this[_name];
+   * };
    *
-   * module.exports = User
+   * module.exports = User;
    *
    * // user-logger.js
-   * var EOL = require('os').EOL
-   * var Scopy = require('scopy')
+   * var EOL = require('os').EOL;
+   * var Scopy = require('scopy');
    *
-   * var keys = Scopy.for.all([ 'example_user_id', 'example_user_lastUpdatedBy' ])
+   * var keys = Scopy.for.all([ 'example_user_id', 'example_user_lastUpdatedBy' ]);
    *
    * exports.update = function(output, user) {
-   *   var id = user[keys['example.user.id']]
-   *   var lastUpdatedBy = user[keys['example.user.lastUpdatedBy']]
+   *   var id = user[keys['example.user.id']];
+   *   var lastUpdatedBy = user[keys['example.user.lastUpdatedBy']];
    *
-   *   output.write('User[' + id + '] has been updated by ' + lastUpdatedBy + EOL)
-   * }
+   *   output.write('User[' + id + '] has been updated by ' + lastUpdatedBy + EOL);
+   * };
    * 
* @param {string[]} [names] - the names for the "global" keys (may be null) * @param {Scopy~Options} [options] - the options to be used (may be null) @@ -306,16 +302,12 @@ var factory = getKeyFactory(true, options); var keys = {}; - var length = names.length; - var name; - - for (var i = 0; i < length; i++) { - name = names[i]; + names.forEach(function(name) { keys[name] = factory(name); - } + }); - return keys + return keys; }; /** @@ -341,13 +333,13 @@ * * @example *
-   * var Scopy = require('scopy')
+   * var Scopy = require('scopy');
    *
-   * Scopy.is(Scopy('foo'))
+   * Scopy.is(Scopy('foo'));
    * //=> true
-   * Scopy.is(Scopy('foo', { symbol: false }))
+   * Scopy.is(Scopy('foo', { symbol: false }));
    * //=> true
-   * Scopy.is('foo')
+   * Scopy.is('foo');
    * //=> false
    * 
* @param {*} obj - the object to be checked (may be null) @@ -359,12 +351,12 @@ */ Scopy.is = function(obj, options) { if (obj == null) { - return false + return false; } options = parseOptions(options); - return options.symbol ? typeof obj === 'symbol' : typeof obj === 'string' && obj[0] === '_' + return options.symbol ? typeof obj === 'symbol' : typeof obj === 'string' && obj[0] === '_'; }; /** @@ -380,30 +372,30 @@ * * @example *
-   * var Scopy = require('scopy')
-   * var uuid = require('uuid/v4')
+   * var Scopy = require('scopy');
+   * var uuid = require('uuid/v4');
    *
-   * var _generateId = Scopy('generateId')
-   * var _id = Scopy('id')
-   * var _name = Scopy('name')
+   * var _generateId = Scopy('generateId');
+   * var _id = Scopy('id');
+   * var _name = Scopy('name');
    *
    * function User(name) {
-   *   this[_id] = this[_generateId]()
-   *   this[_name] = name
-   *   this.length = name.length
+   *   this[_id] = this[_generateId]();
+   *   this[_name] = name;
+   *   this.length = name.length;
    * }
    *
    * User.prototype[_generateId] = function() {
-   *   return uuid()
-   * }
+   *   return uuid();
+   * };
    *
    * User.prototype.getName = function() {
-   *   return this[_name]
-   * }
+   *   return this[_name];
+   * };
    *
-   * Scopy.keys(new User('foo'))
+   * Scopy.keys(new User('foo'));
    * //=> [ "length" ]
-   * Scopy.keys(User.prototype)
+   * Scopy.keys(User.prototype);
    * //=> [ "getName" ]
    * 
* @param {Object} obj - the object whose enumerable own non-scoped property names are to be returned @@ -416,8 +408,8 @@ */ Scopy.keys = function(obj, options) { return mapProperties(obj, function(value, name) { - return name - }, options) + return name; + }, options); }; /** @@ -433,15 +425,15 @@ * * @example *
-   * var Scopy = require('scopy').using({ symbol: false })
+   * var Scopy = require('scopy').using({ symbol: false });
    *
-   * Scopy('foo')
+   * Scopy('foo');
    * //=> "_foo"
-   * Scopy.all([ 'foo', 'bar' ])
+   * Scopy.all([ 'foo', 'bar' ]);
    * //=> { foo: "_foo", bar: "_bar" }
-   * Scopy.is('_foo')
+   * Scopy.is('_foo');
    * //=> true
-   * Scopy.is(Symbol('foo'))
+   * Scopy.is(Symbol('foo'));
    * //=> false
    * 
* @param {Scopy~Options} [options] - the options to be used (may be null) @@ -467,7 +459,7 @@ BoundScopy.for.all = BoundScopy.forAll; BoundScopy.using = Scopy.using; - return BoundScopy + return BoundScopy; }; /** @@ -483,30 +475,30 @@ * * @example *
-   * var Scopy = require('scopy')
-   * var uuid = require('uuid/v4')
+   * var Scopy = require('scopy');
+   * var uuid = require('uuid/v4');
    *
-   * var _generateId = Scopy('generateId')
-   * var _id = Scopy('id')
-   * var _name = Scopy('name')
+   * var _generateId = Scopy('generateId');
+   * var _id = Scopy('id');
+   * var _name = Scopy('name');
    *
    * function User(name) {
-   *   this[_id] = this[_generateId]()
-   *   this[_name] = name
-   *   this.length = name.length
+   *   this[_id] = this[_generateId]();
+   *   this[_name] = name;
+   *   this.length = name.length;
    * }
    *
    * User.prototype[_generateId] = function() {
-   *   return uuid()
-   * }
+   *   return uuid();
+   * };
    *
    * User.prototype.getName = function() {
-   *   return this[_name]
-   * }
+   *   return this[_name];
+   * };
    *
-   * Scopy.values(new User('foo'))
+   * Scopy.values(new User('foo'));
    * //=> [ 3 ]
-   * Scopy.values(User.prototype)
+   * Scopy.values(User.prototype);
    * //=> [ function() { return this[_name] } ]
    * 
* @param {Object} obj - the object whose enumerable own non-scoped property values are to be returned @@ -518,8 +510,8 @@ */ Scopy.values = function(obj, options) { return mapProperties(obj, function(value) { - return value - }, options) + return value; + }, options); }; /** @@ -537,8 +529,8 @@ return function() { var args = Array.prototype.slice.call(arguments, 0, 1); - return func.apply(null, args.concat(options)) - } + return func.apply(null, args.concat(options)); + }; } /** @@ -556,14 +548,9 @@ * @private */ function applyOptionsToAll(source, target, names, options) { - var length = names.length; - var name; - - for (var i = 0; i < length; i++) { - name = names[i]; - + names.forEach(function(name) { target[name] = applyOptions(source[name], options); - } + }); } /** @@ -580,12 +567,12 @@ options = parseOptions(options); if (options.symbol) { - return global ? Symbol.for : Symbol + return global ? Symbol.for : Symbol; } return function(name) { - return '_' + name - } + return '_' + name; + }; } /** @@ -612,7 +599,7 @@ } } - return result + return result; } /** @@ -630,7 +617,7 @@ var symbol = options.symbol !== false && typeof Symbol === 'function'; - return { symbol: symbol } + return { symbol: symbol }; } var scopy = Scopy; diff --git a/dist/scopy.js.map b/dist/scopy.js.map index 6fc2a51..5c6b96d 100644 --- a/dist/scopy.js.map +++ b/dist/scopy.js.map @@ -1 +1 @@ -{"version":3,"file":"scopy.js","sources":["../src/scopy.js"],"sourcesContent":["/*\n * Copyright (C) 2017 Alasdair Mercer, Skelp\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\n'use strict'\n\n/**\n * Returns a scoped key based on the specified name and using the options provided.\n *\n * If the symbol option is enabled (which it is by default), an ES2015 Symbol will be\n * returned (where supported), otherwise this method will simply return name prefixed with an underscore.\n *\n * Symbols returned by this method will always be unique when called multiple times with the same\n * name, however, string keys will always be exactly the same.\n *\n * This method is ideal when defining a key for a privately scoped property.\n *\n * @example\n *
\n * // user.js\n * var Scopy = require('scopy')\n *\n * var _name = Scopy('name')\n *\n * function User(name) {\n *   this[_name] = name\n * }\n *\n * User.prototype.getName = function() {\n *   return this[_name]\n * }\n *\n * module.exports = User\n * 
\n * @param {string} name - the name for the scoped key\n * @param {Scopy~Options} [options] - the options to be used (may be null)\n * @return {string|symbol} The scoped key for name.\n * @throws {TypeError} If an attempt is made to instantiate Scopy (e.g. via new).\n * @public\n */\nfunction Scopy(name, options) {\n if (this instanceof Scopy) {\n throw new TypeError('Scopy is not a constructor')\n }\n\n var factory = getKeyFactory(false, options)\n\n return factory(name)\n}\n\n/**\n * Returns scoped keys based on the specified names and using the options provided.\n *\n * If the symbol option is enabled (which it is by default), this method will return names\n * mapped to ES2015 Symbols (where supported), otherwise names will simply be mapped to\n * themselves prefixed with an underscore.\n *\n * Symbols included in the mapping returned by this method will always be unique when called multiple times\n * with the same name, however, string keys will always be exactly the same.\n *\n * This method is ideal when defining keys for privately scoped properties.\n *\n * @example\n *
\n * // user.js\n * var Scopy = require('scopy')\n *\n * var keys = Scopy.all([ 'email', 'name' ])\n *\n * function User(email, name) {\n *   this[keys.email] = email\n *   this[keys.name] = name\n * }\n *\n * User.prototype.getEmail = function() {\n *   return this[keys.email]\n * }\n *\n * User.prototype.getName = function() {\n *   return this[keys.name]\n * }\n *\n * module.exports = User\n * 
\n * @param {string[]} [names] - the names for the scoped keys (may be null)\n * @param {Scopy~Options} [options] - the options to be used (may be null)\n * @return {Object.} A mapping containing names and their corresponding scoped keys.\n * @public\n * @static\n * @memberof Scopy\n */\nScopy.all = function(names, options) {\n names = names || []\n\n var factory = getKeyFactory(false, options)\n var keys = {}\n var length = names.length\n var name\n\n for (var i = 0; i < length; i++) {\n name = names[i]\n\n keys[name] = factory(name)\n }\n\n return keys\n}\n\n/**\n * Returns the key/value pairs for all of the specified object's own enumerable properties that are not scoped, in the\n * same order as that provided by a for-in loop.\n *\n * This method returns a multi-dimensional array where each item is an array containing the name and value\n * ([name, value]) of a non-scoped enumerable property.\n *\n * Properties mapped to a Symbol are never included in this method but those mapped to properties\n * whose name is prefixed with an underscore, created when the symbol option has been explicitly disabled,\n * will be included unless the symbol option is explicitly disabled when calling this method.\n *\n * This method is intended to be used just like ES2015's Object.entries method while also supporting cases\n * where Symbols have not been used to scope properties.\n *\n * @example\n *
\n * var Scopy = require('scopy')\n * var uuid = require('uuid/v4')\n *\n * var _generateId = Scopy('generateId')\n * var _id = Scopy('id')\n * var _name = Scopy('name')\n *\n * function User(name) {\n *   this[_id] = this[_generateId]()\n *   this[_name] = name\n *   this.length = name.length\n * }\n *\n * User.prototype[_generateId] = function() {\n *   return uuid()\n * }\n *\n * User.prototype.getName = function() {\n *   return this[_name]\n * }\n *\n * Scopy.entries(new User('foo'))\n * //=> [ [ \"length\", 3 ] ]\n * Scopy.entries(User.prototype)\n * //=> [ [ \"getName\", function() { return this[_name] } ] ]\n * 
\n * @param {Object} obj - the object whose enumerable own non-scoped property key/value pairs are to be returned\n * @param {Scopy~Options} [options] - the options to be used (may be null)\n * @return {Array} An array containing the key/value pairs for all of the enumerable non-scoped properties of\n * obj.\n * @public\n * @static\n * @memberof Scopy\n */\nScopy.entries = function(obj, options) {\n return mapProperties(obj, function(value, name) {\n return [ name, value ]\n }, options)\n}\n\n/**\n * Returns a \"global\" key based on the specified name and using the options provided.\n *\n * If the symbol option is enabled (which it is by default), an ES2015 Symbol will be returned\n * from the runtime-wide symbol registry (where supported), otherwise this method will simply return name\n * prefixed with an underscore.\n *\n * Unlike {@link Scopy}, Symbols returned by this method will always be the same when called multiple times\n * with the same name, just like string keys.\n *\n * It is recommended that name be prefixed in order to avoid conflicts with other libraries that may also\n * have a \"global\" key of the same name.\n *\n * This method is ideal when defining a key for a protected/internally scoped property.\n *\n * @example\n *
\n * // user.js\n * var Scopy = require('scopy')\n * var uuid = require('node-uuid/v4')\n *\n * var _id = Scopy.for('example_user_id')\n * var _name = Scopy('name')\n *\n * function User(name) {\n *   this[_id] = uuid()\n *   this[_name] = name\n * }\n *\n * User.prototype.getName = function() {\n *   return this[_name]\n * }\n *\n * module.exports = User\n *\n * // user-logger.js\n * var EOL = require('os').EOL\n * var Scopy = require('scopy')\n *\n * var _id = Scopy.for('example_user_id')\n *\n * exports.login = function(output, user) {\n *   var id = user[_id]\n *\n *   output.write('User[' + id + '] has logged in!' + EOL)\n * }\n * 
\n * @param {string} name - the name for the \"global\" key\n * @param {Scopy~Options} [options] - the options to be used (may be null)\n * @return {string|symbol} The \"global\" key for name.\n * @public\n * @static\n * @memberof Scopy\n */\nScopy.for = function(name, options) {\n var factory = getKeyFactory(true, options)\n\n return factory(name)\n}\n\n/**\n * Returns \"global\" keys based on the specified names and using the options provided.\n *\n * If the symbol option is enabled (which it is by default), this method will return names\n * mapped to ES2015 Symbols from the runtime-wide symbol registry (where supported), otherwise\n * names will simply be mapped to themselves prefixed with an underscore.\n *\n * Unlike {@link Scopy.all}, Symbols included in the mapping returned by this method will always be the\n * same when called multiple times with the same name, just like string keys.\n *\n * It is recommended that each name within names be prefixed in order to avoid conflicts with other\n * libraries that may also have a \"global\" key of the same name.\n *\n * This method is ideal when defining keys for protected/internally scoped properties.\n *\n * @example\n *
\n * // user.js\n * var Scopy = require('scopy')\n * var uuid = require('node-uuid/v4')\n *\n * var keys = Scopy.for.all([ 'example_user_id', 'example_user_lastUpdatedBy' ])\n * var _name = Scopy('name')\n *\n * function User(name) {\n *   this[keys['example.user.id']] = uuid()\n *   this[keys['example.user.lastUpdatedBy']] = null\n *   this[_name] = name\n * }\n *\n * User.prototype.getName = function() {\n *   return this[_name]\n * }\n *\n * module.exports = User\n *\n * // user-logger.js\n * var EOL = require('os').EOL\n * var Scopy = require('scopy')\n *\n * var keys = Scopy.for.all([ 'example_user_id', 'example_user_lastUpdatedBy' ])\n *\n * exports.update = function(output, user) {\n *   var id = user[keys['example.user.id']]\n *   var lastUpdatedBy = user[keys['example.user.lastUpdatedBy']]\n *\n *   output.write('User[' + id + '] has been updated by ' + lastUpdatedBy + EOL)\n * }\n * 
\n * @param {string[]} [names] - the names for the \"global\" keys (may be null)\n * @param {Scopy~Options} [options] - the options to be used (may be null)\n * @return {Object.} A mapping containing names and their corresponding \"global\"\n * keys.\n * @public\n * @static\n * @memberof Scopy.for\n */\nScopy.for.all = function(names, options) {\n names = names || []\n\n var factory = getKeyFactory(true, options)\n var keys = {}\n var length = names.length\n var name\n\n for (var i = 0; i < length; i++) {\n name = names[i]\n\n keys[name] = factory(name)\n }\n\n return keys\n}\n\n/**\n * An alias for the {@link Scopy.for.all} method.\n *\n * @param {string[]} [names] - the names for the \"global\" keys (may be null)\n * @param {Scopy~Options} [options] - the options to be used (may be null)\n * @return {Object.} A mapping containing names and their corresponding \"global\"\n * keys.\n * @public\n * @static\n * @memberof Scopy\n */\nScopy.forAll = Scopy.for.all\n\n/**\n * Returns whether the specified obj represents a scoped or \"global\" key based on the options\n * provided.\n *\n * If the symbol option is enabled (which it is by default), this method will return true if\n * obj is an ES2015 Symbol (where supported), otherwise it will only return true\n * if and only if obj is a string that starts with at least one underscore.\n *\n * @example\n *
\n * var Scopy = require('scopy')\n *\n * Scopy.is(Scopy('foo'))\n * //=> true\n * Scopy.is(Scopy('foo', { symbol: false }))\n * //=> true\n * Scopy.is('foo')\n * //=> false\n * 
\n * @param {*} obj - the object to be checked (may be null)\n * @param {Scopy~Options} [options] - the options to be used (may be null)\n * @return {boolean} true if obj is a scoped or \"global\" key; otherwise false.\n * @public\n * @static\n * @memberof Scopy\n */\nScopy.is = function(obj, options) {\n if (obj == null) {\n return false\n }\n\n options = parseOptions(options)\n\n return options.symbol ? typeof obj === 'symbol' : typeof obj === 'string' && obj[0] === '_'\n}\n\n/**\n * Returns the names of all of the specified object's own enumerable properties that are not scoped, in the same order\n * as that provided by a for-in loop.\n *\n * Properties mapped to a Symbol are never included in this method but those mapped to properties\n * whose name is prefixed with an underscore, created when the symbol option has been explicitly disabled,\n * will be included unless the symbol option is explicitly disabled when calling this method.\n *\n * This method is intended to be used just like ES2015's Object.keys method while also supporting cases\n * where Symbols have not been used to scope properties.\n *\n * @example\n *
\n * var Scopy = require('scopy')\n * var uuid = require('uuid/v4')\n *\n * var _generateId = Scopy('generateId')\n * var _id = Scopy('id')\n * var _name = Scopy('name')\n *\n * function User(name) {\n *   this[_id] = this[_generateId]()\n *   this[_name] = name\n *   this.length = name.length\n * }\n *\n * User.prototype[_generateId] = function() {\n *   return uuid()\n * }\n *\n * User.prototype.getName = function() {\n *   return this[_name]\n * }\n *\n * Scopy.keys(new User('foo'))\n * //=> [ \"length\" ]\n * Scopy.keys(User.prototype)\n * //=> [ \"getName\" ]\n * 
\n * @param {Object} obj - the object whose enumerable own non-scoped property names are to be returned\n * @param {Scopy~Options} [options] - the options to be used (may be null)\n * @return {string[]} An array of strings that represent all of the enumerable non-scoped properties of\n * obj.\n * @public\n * @static\n * @memberof Scopy\n */\nScopy.keys = function(obj, options) {\n return mapProperties(obj, function(value, name) {\n return name\n }, options)\n}\n\n/**\n * Returns a version of {@link Scopy} that is bound (along with all of its methods) to the specified\n * options.\n *\n * Since it's recommended that consumers use the same options, when specified, this method can be really useful as it\n * allows consumers to only specify the options once. This is especially useful for those wishing to explictly disable\n * the symbol option.\n *\n * Any options passed to the methods within the returned wrapped Scopy API will be ignored in favor of\n * options.\n *\n * @example\n *
\n * var Scopy = require('scopy').using({ symbol: false })\n *\n * Scopy('foo')\n * //=> \"_foo\"\n * Scopy.all([ 'foo', 'bar' ])\n * //=> { foo: \"_foo\", bar: \"_bar\" }\n * Scopy.is('_foo')\n * //=> true\n * Scopy.is(Symbol('foo'))\n * //=> false\n * 
\n * @param {Scopy~Options} [options] - the options to be used (may be null)\n * @return {Function} A version of {@link Scopy} that will, along with its methods, always use options.\n * @public\n * @static\n * @memberof Scopy\n */\nScopy.using = function(options) {\n options = parseOptions(options)\n\n var BoundScopy = applyOptions(Scopy, options)\n applyOptionsToAll(Scopy, BoundScopy, [\n 'all',\n 'entries',\n 'for',\n 'forAll',\n 'is',\n 'keys',\n 'values'\n ], options)\n\n BoundScopy.for.all = BoundScopy.forAll\n BoundScopy.using = Scopy.using\n\n return BoundScopy\n}\n\n/**\n * Returns the values of all of the specified object's own enumerable properties that are not scoped, in the same order\n * as that provided by a for-in loop.\n *\n * Properties mapped to a Symbol are never included in this method but those mapped to properties\n * whose name is prefixed with an underscore, created when the symbol option has been explicitly disabled,\n * will be included unless the symbol option is explicitly disabled when calling this method.\n *\n * This method is intended to be used just like ES2015's Object.values method while also supporting cases\n * where Symbols have not been used to scope properties.\n *\n * @example\n *
\n * var Scopy = require('scopy')\n * var uuid = require('uuid/v4')\n *\n * var _generateId = Scopy('generateId')\n * var _id = Scopy('id')\n * var _name = Scopy('name')\n *\n * function User(name) {\n *   this[_id] = this[_generateId]()\n *   this[_name] = name\n *   this.length = name.length\n * }\n *\n * User.prototype[_generateId] = function() {\n *   return uuid()\n * }\n *\n * User.prototype.getName = function() {\n *   return this[_name]\n * }\n *\n * Scopy.values(new User('foo'))\n * //=> [ 3 ]\n * Scopy.values(User.prototype)\n * //=> [ function() { return this[_name] } ]\n * 
\n * @param {Object} obj - the object whose enumerable own non-scoped property values are to be returned\n * @param {Scopy~Options} [options] - the options to be used (may be null)\n * @return {Array} An array containing the values of all of the enumerable non-scoped properties of obj.\n * @public\n * @static\n * @memberof Scopy\n */\nScopy.values = function(obj, options) {\n return mapProperties(obj, function(value) {\n return value\n }, options)\n}\n\n/**\n * Returns a function that delegates the call to the specified func so that the options\n * provided are always passed to it.\n *\n * The returned function will always return the return value of calling func.\n *\n * @param {Function} func - the function to which options are to be applied\n * @param {Scopy~Options} options - the options to be applied\n * @return {Function} A function which will always pass options as the last argument to func.\n * @private\n */\nfunction applyOptions(func, options) {\n return function() {\n var args = Array.prototype.slice.call(arguments, 0, 1)\n\n return func.apply(null, args.concat(options))\n }\n}\n\n/**\n * Assigns functions to the specified target for all of the names provided that delegate their\n * calls to the function of the same name on the given source so that the options provided are\n * always passed to them.\n *\n * Each proxy function will always return the return value of calling the original function.\n *\n * @param {Object} source - the object on which the original functions belong\n * @param {Object} target - the object to which the proxy functions are to be assigned\n * @param {string[]} names - the names of each function to be proxied\n * @param {Scopy~Options} options - the options to be used\n * @return {void}\n * @private\n */\nfunction applyOptionsToAll(source, target, names, options) {\n var length = names.length\n var name\n\n for (var i = 0; i < length; i++) {\n name = names[i]\n\n target[name] = applyOptions(source[name], options)\n }\n}\n\n/**\n * Returns a function which can be used to create scoped/\"global\" keys based on the options provided and a\n * name which is passed to it.\n *\n * @param {boolean} global - true if the keys created by the factory are to be \"global\"; otherwise\n * false\n * @param {?Scopy~Options} options - the options to be used (may be null)\n * @return {Scopy~KeyFactory} The key factory.\n * @private\n */\nfunction getKeyFactory(global, options) {\n options = parseOptions(options)\n\n if (options.symbol) {\n return global ? Symbol.for : Symbol\n }\n\n return function(name) {\n return '_' + name\n }\n}\n\n/**\n * Iterates over all non-scoped properties on the specified object using the options provided\n * and creates a new array containing values derived from the key/value pairs for each property using the given\n * mapper.\n *\n * @param {Object} obj - the object whose non-scoped properties are to be mapped\n * @param {Scopy~PropertyMapper} mapper - the function to be called with the value and name of each non-scoped property\n * and to return a value to be mapped to the result\n * @param {?Scopy~Options} options - the options to be used (may be null/code>)\n * @return {Array} An array containing values derived from the non-scoped properties of obj using\n * mapper.\n * @private\n */\nfunction mapProperties(obj, mapper, options) {\n options = parseOptions(options)\n\n var result = []\n\n for (var name in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, name) && (options.symbol || name[0] !== '_')) {\n result.push(mapper(obj[name], name))\n }\n }\n\n return result\n}\n\n/**\n * Parses the optional input options provided, normalizing options and applying default values, where\n * needed.\n *\n * @param {?Scopy~Options} options - the input options to be parsed (may be null if none were provided)\n * @return {Scopy~Options} A new options object parsed from options.\n * @private\n */\nfunction parseOptions(options) {\n if (options == null) {\n options = {}\n }\n\n var symbol = options.symbol !== false && typeof Symbol === 'function'\n\n return { symbol: symbol }\n}\n\nmodule.exports = Scopy\n\n/**\n * Returns a scoped or \"global\" key based on the specified name.\n *\n * @callback Scopy~KeyFactory\n * @param {string} name - the name on which to base the key\n * @return {string|symbol} The key created for name.\n */\n\n/**\n * The options to be used to create property keys with Scopy.\n *\n * @typedef {Object} Scopy~Options\n * @property {boolean} [symbol=true] - true if ES2015's Symbol should be used, where possible;\n * otherwise false.\n */\n/**\n * Returns a single value derived from the non-scoped property name and value provided.\n *\n * @callback Scopy~PropertyMapper\n * @param {*} value - the value of the non-scoped property\n * @param {string} name - the name of the non-scoped property\n * @return {*} The value to mapped for the non-scoped property.\n */\n"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"scopy.js","sources":["../src/scopy.js"],"sourcesContent":["/*\n * Copyright (C) 2017 Alasdair Mercer, !ninja\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\n'use strict';\n\n/**\n * Returns a scoped key based on the specified name and using the options provided.\n *\n * If the symbol option is enabled (which it is by default), an ES2015 Symbol will be\n * returned (where supported), otherwise this method will simply return name prefixed with an underscore.\n *\n * Symbols returned by this method will always be unique when called multiple times with the same\n * name, however, string keys will always be exactly the same.\n *\n * This method is ideal when defining a key for a privately scoped property.\n *\n * @example\n *
\n * // user.js\n * var Scopy = require('scopy');\n *\n * var _name = Scopy('name');\n *\n * function User(name) {\n *   this[_name] = name;\n * }\n *\n * User.prototype.getName = function() {\n *   return this[_name];\n * };\n *\n * module.exports = User;\n * 
\n * @param {string} name - the name for the scoped key\n * @param {Scopy~Options} [options] - the options to be used (may be null)\n * @return {string|symbol} The scoped key for name.\n * @throws {TypeError} If an attempt is made to instantiate Scopy (e.g. via new).\n * @public\n */\nfunction Scopy(name, options) {\n if (this instanceof Scopy) {\n throw new TypeError('Scopy is not a constructor');\n }\n\n var factory = getKeyFactory(false, options);\n\n return factory(name);\n}\n\n/**\n * Returns scoped keys based on the specified names and using the options provided.\n *\n * If the symbol option is enabled (which it is by default), this method will return names\n * mapped to ES2015 Symbols (where supported), otherwise names will simply be mapped to\n * themselves prefixed with an underscore.\n *\n * Symbols included in the mapping returned by this method will always be unique when called multiple times\n * with the same name, however, string keys will always be exactly the same.\n *\n * This method is ideal when defining keys for privately scoped properties.\n *\n * @example\n *
\n * // user.js\n * var Scopy = require('scopy');\n *\n * var keys = Scopy.all([ 'email', 'name' ]);\n *\n * function User(email, name) {\n *   this[keys.email] = email;\n *   this[keys.name] = name;\n * }\n *\n * User.prototype.getEmail = function() {\n *   return this[keys.email];\n * };\n *\n * User.prototype.getName = function() {\n *   return this[keys.name];\n * };\n *\n * module.exports = User;\n * 
\n * @param {string[]} [names] - the names for the scoped keys (may be null)\n * @param {Scopy~Options} [options] - the options to be used (may be null)\n * @return {Object.} A mapping containing names and their corresponding scoped keys.\n * @public\n * @static\n * @memberof Scopy\n */\nScopy.all = function(names, options) {\n names = names || [];\n\n var factory = getKeyFactory(false, options);\n var keys = {};\n\n names.forEach(function(name) {\n keys[name] = factory(name);\n });\n\n return keys;\n};\n\n/**\n * Returns the key/value pairs for all of the specified object's own enumerable properties that are not scoped, in the\n * same order as that provided by a for-in loop.\n *\n * This method returns a multi-dimensional array where each item is an array containing the name and value\n * ([name, value]) of a non-scoped enumerable property.\n *\n * Properties mapped to a Symbol are never included in this method but those mapped to properties\n * whose name is prefixed with an underscore, created when the symbol option has been explicitly disabled,\n * will be included unless the symbol option is explicitly disabled when calling this method.\n *\n * This method is intended to be used just like ES2015's Object.entries method while also supporting cases\n * where Symbols have not been used to scope properties.\n *\n * @example\n *
\n * var Scopy = require('scopy');\n * var uuid = require('uuid/v4');\n *\n * var _generateId = Scopy('generateId');\n * var _id = Scopy('id');\n * var _name = Scopy('name');\n *\n * function User(name) {\n *   this[_id] = this[_generateId]();\n *   this[_name] = name;\n *   this.length = name.length;\n * }\n *\n * User.prototype[_generateId] = function() {\n *   return uuid();\n * };\n *\n * User.prototype.getName = function() {\n *   return this[_name];\n * };\n *\n * Scopy.entries(new User('foo'));\n * //=> [ [ \"length\", 3 ] ]\n * Scopy.entries(User.prototype);\n * //=> [ [ \"getName\", function() { return this[_name] } ] ]\n * 
\n * @param {Object} obj - the object whose enumerable own non-scoped property key/value pairs are to be returned\n * @param {Scopy~Options} [options] - the options to be used (may be null)\n * @return {Array} An array containing the key/value pairs for all of the enumerable non-scoped properties of\n * obj.\n * @public\n * @static\n * @memberof Scopy\n */\nScopy.entries = function(obj, options) {\n return mapProperties(obj, function(value, name) {\n return [ name, value ];\n }, options);\n};\n\n/**\n * Returns a \"global\" key based on the specified name and using the options provided.\n *\n * If the symbol option is enabled (which it is by default), an ES2015 Symbol will be returned\n * from the runtime-wide symbol registry (where supported), otherwise this method will simply return name\n * prefixed with an underscore.\n *\n * Unlike {@link Scopy}, Symbols returned by this method will always be the same when called multiple times\n * with the same name, just like string keys.\n *\n * It is recommended that name be prefixed in order to avoid conflicts with other libraries that may also\n * have a \"global\" key of the same name.\n *\n * This method is ideal when defining a key for a protected/internally scoped property.\n *\n * @example\n *
\n * // user.js\n * var Scopy = require('scopy');\n * var uuid = require('uuid/v4');\n *\n * var _id = Scopy.for('example_user_id');\n * var _name = Scopy('name');\n *\n * function User(name) {\n *   this[_id] = uuid();\n *   this[_name] = name;\n * }\n *\n * User.prototype.getName = function() {\n *   return this[_name];\n * };\n *\n * module.exports = User;\n *\n * // user-logger.js\n * var EOL = require('os').EOL;\n * var Scopy = require('scopy');\n *\n * var _id = Scopy.for('example_user_id');\n *\n * exports.login = function(output, user) {\n *   var id = user[_id];\n *\n *   output.write('User[' + id + '] has logged in!' + EOL);\n * };\n * 
\n * @param {string} name - the name for the \"global\" key\n * @param {Scopy~Options} [options] - the options to be used (may be null)\n * @return {string|symbol} The \"global\" key for name.\n * @public\n * @static\n * @memberof Scopy\n */\nScopy.for = function(name, options) {\n var factory = getKeyFactory(true, options);\n\n return factory(name);\n};\n\n/**\n * Returns \"global\" keys based on the specified names and using the options provided.\n *\n * If the symbol option is enabled (which it is by default), this method will return names\n * mapped to ES2015 Symbols from the runtime-wide symbol registry (where supported), otherwise\n * names will simply be mapped to themselves prefixed with an underscore.\n *\n * Unlike {@link Scopy.all}, Symbols included in the mapping returned by this method will always be the\n * same when called multiple times with the same name, just like string keys.\n *\n * It is recommended that each name within names be prefixed in order to avoid conflicts with other\n * libraries that may also have a \"global\" key of the same name.\n *\n * This method is ideal when defining keys for protected/internally scoped properties.\n *\n * @example\n *
\n * // user.js\n * var Scopy = require('scopy');\n * var uuid = require('uuid/v4');\n *\n * var keys = Scopy.for.all([ 'example_user_id', 'example_user_lastUpdatedBy' ]);\n * var _name = Scopy('name');\n *\n * function User(name) {\n *   this[keys['example.user.id']] = uuid();\n *   this[keys['example.user.lastUpdatedBy']] = null;\n *   this[_name] = name;\n * }\n *\n * User.prototype.getName = function() {\n *   return this[_name];\n * };\n *\n * module.exports = User;\n *\n * // user-logger.js\n * var EOL = require('os').EOL;\n * var Scopy = require('scopy');\n *\n * var keys = Scopy.for.all([ 'example_user_id', 'example_user_lastUpdatedBy' ]);\n *\n * exports.update = function(output, user) {\n *   var id = user[keys['example.user.id']];\n *   var lastUpdatedBy = user[keys['example.user.lastUpdatedBy']];\n *\n *   output.write('User[' + id + '] has been updated by ' + lastUpdatedBy + EOL);\n * };\n * 
\n * @param {string[]} [names] - the names for the \"global\" keys (may be null)\n * @param {Scopy~Options} [options] - the options to be used (may be null)\n * @return {Object.} A mapping containing names and their corresponding \"global\"\n * keys.\n * @public\n * @static\n * @memberof Scopy.for\n */\nScopy.for.all = function(names, options) {\n names = names || [];\n\n var factory = getKeyFactory(true, options);\n var keys = {};\n\n names.forEach(function(name) {\n keys[name] = factory(name);\n });\n\n return keys;\n};\n\n/**\n * An alias for the {@link Scopy.for.all} method.\n *\n * @param {string[]} [names] - the names for the \"global\" keys (may be null)\n * @param {Scopy~Options} [options] - the options to be used (may be null)\n * @return {Object.} A mapping containing names and their corresponding \"global\"\n * keys.\n * @public\n * @static\n * @memberof Scopy\n */\nScopy.forAll = Scopy.for.all;\n\n/**\n * Returns whether the specified obj represents a scoped or \"global\" key based on the options\n * provided.\n *\n * If the symbol option is enabled (which it is by default), this method will return true if\n * obj is an ES2015 Symbol (where supported), otherwise it will only return true\n * if and only if obj is a string that starts with at least one underscore.\n *\n * @example\n *
\n * var Scopy = require('scopy');\n *\n * Scopy.is(Scopy('foo'));\n * //=> true\n * Scopy.is(Scopy('foo', { symbol: false }));\n * //=> true\n * Scopy.is('foo');\n * //=> false\n * 
\n * @param {*} obj - the object to be checked (may be null)\n * @param {Scopy~Options} [options] - the options to be used (may be null)\n * @return {boolean} true if obj is a scoped or \"global\" key; otherwise false.\n * @public\n * @static\n * @memberof Scopy\n */\nScopy.is = function(obj, options) {\n if (obj == null) {\n return false;\n }\n\n options = parseOptions(options);\n\n return options.symbol ? typeof obj === 'symbol' : typeof obj === 'string' && obj[0] === '_';\n};\n\n/**\n * Returns the names of all of the specified object's own enumerable properties that are not scoped, in the same order\n * as that provided by a for-in loop.\n *\n * Properties mapped to a Symbol are never included in this method but those mapped to properties\n * whose name is prefixed with an underscore, created when the symbol option has been explicitly disabled,\n * will be included unless the symbol option is explicitly disabled when calling this method.\n *\n * This method is intended to be used just like ES2015's Object.keys method while also supporting cases\n * where Symbols have not been used to scope properties.\n *\n * @example\n *
\n * var Scopy = require('scopy');\n * var uuid = require('uuid/v4');\n *\n * var _generateId = Scopy('generateId');\n * var _id = Scopy('id');\n * var _name = Scopy('name');\n *\n * function User(name) {\n *   this[_id] = this[_generateId]();\n *   this[_name] = name;\n *   this.length = name.length;\n * }\n *\n * User.prototype[_generateId] = function() {\n *   return uuid();\n * };\n *\n * User.prototype.getName = function() {\n *   return this[_name];\n * };\n *\n * Scopy.keys(new User('foo'));\n * //=> [ \"length\" ]\n * Scopy.keys(User.prototype);\n * //=> [ \"getName\" ]\n * 
\n * @param {Object} obj - the object whose enumerable own non-scoped property names are to be returned\n * @param {Scopy~Options} [options] - the options to be used (may be null)\n * @return {string[]} An array of strings that represent all of the enumerable non-scoped properties of\n * obj.\n * @public\n * @static\n * @memberof Scopy\n */\nScopy.keys = function(obj, options) {\n return mapProperties(obj, function(value, name) {\n return name;\n }, options);\n};\n\n/**\n * Returns a version of {@link Scopy} that is bound (along with all of its methods) to the specified\n * options.\n *\n * Since it's recommended that consumers use the same options, when specified, this method can be really useful as it\n * allows consumers to only specify the options once. This is especially useful for those wishing to explictly disable\n * the symbol option.\n *\n * Any options passed to the methods within the returned wrapped Scopy API will be ignored in favor of\n * options.\n *\n * @example\n *
\n * var Scopy = require('scopy').using({ symbol: false });\n *\n * Scopy('foo');\n * //=> \"_foo\"\n * Scopy.all([ 'foo', 'bar' ]);\n * //=> { foo: \"_foo\", bar: \"_bar\" }\n * Scopy.is('_foo');\n * //=> true\n * Scopy.is(Symbol('foo'));\n * //=> false\n * 
\n * @param {Scopy~Options} [options] - the options to be used (may be null)\n * @return {Function} A version of {@link Scopy} that will, along with its methods, always use options.\n * @public\n * @static\n * @memberof Scopy\n */\nScopy.using = function(options) {\n options = parseOptions(options);\n\n var BoundScopy = applyOptions(Scopy, options);\n applyOptionsToAll(Scopy, BoundScopy, [\n 'all',\n 'entries',\n 'for',\n 'forAll',\n 'is',\n 'keys',\n 'values'\n ], options);\n\n BoundScopy.for.all = BoundScopy.forAll;\n BoundScopy.using = Scopy.using;\n\n return BoundScopy;\n};\n\n/**\n * Returns the values of all of the specified object's own enumerable properties that are not scoped, in the same order\n * as that provided by a for-in loop.\n *\n * Properties mapped to a Symbol are never included in this method but those mapped to properties\n * whose name is prefixed with an underscore, created when the symbol option has been explicitly disabled,\n * will be included unless the symbol option is explicitly disabled when calling this method.\n *\n * This method is intended to be used just like ES2015's Object.values method while also supporting cases\n * where Symbols have not been used to scope properties.\n *\n * @example\n *
\n * var Scopy = require('scopy');\n * var uuid = require('uuid/v4');\n *\n * var _generateId = Scopy('generateId');\n * var _id = Scopy('id');\n * var _name = Scopy('name');\n *\n * function User(name) {\n *   this[_id] = this[_generateId]();\n *   this[_name] = name;\n *   this.length = name.length;\n * }\n *\n * User.prototype[_generateId] = function() {\n *   return uuid();\n * };\n *\n * User.prototype.getName = function() {\n *   return this[_name];\n * };\n *\n * Scopy.values(new User('foo'));\n * //=> [ 3 ]\n * Scopy.values(User.prototype);\n * //=> [ function() { return this[_name] } ]\n * 
\n * @param {Object} obj - the object whose enumerable own non-scoped property values are to be returned\n * @param {Scopy~Options} [options] - the options to be used (may be null)\n * @return {Array} An array containing the values of all of the enumerable non-scoped properties of obj.\n * @public\n * @static\n * @memberof Scopy\n */\nScopy.values = function(obj, options) {\n return mapProperties(obj, function(value) {\n return value;\n }, options);\n};\n\n/**\n * Returns a function that delegates the call to the specified func so that the options\n * provided are always passed to it.\n *\n * The returned function will always return the return value of calling func.\n *\n * @param {Function} func - the function to which options are to be applied\n * @param {Scopy~Options} options - the options to be applied\n * @return {Function} A function which will always pass options as the last argument to func.\n * @private\n */\nfunction applyOptions(func, options) {\n return function() {\n var args = Array.prototype.slice.call(arguments, 0, 1);\n\n return func.apply(null, args.concat(options));\n };\n}\n\n/**\n * Assigns functions to the specified target for all of the names provided that delegate their\n * calls to the function of the same name on the given source so that the options provided are\n * always passed to them.\n *\n * Each proxy function will always return the return value of calling the original function.\n *\n * @param {Object} source - the object on which the original functions belong\n * @param {Object} target - the object to which the proxy functions are to be assigned\n * @param {string[]} names - the names of each function to be proxied\n * @param {Scopy~Options} options - the options to be used\n * @return {void}\n * @private\n */\nfunction applyOptionsToAll(source, target, names, options) {\n names.forEach(function(name) {\n target[name] = applyOptions(source[name], options);\n });\n}\n\n/**\n * Returns a function which can be used to create scoped/\"global\" keys based on the options provided and a\n * name which is passed to it.\n *\n * @param {boolean} global - true if the keys created by the factory are to be \"global\"; otherwise\n * false\n * @param {?Scopy~Options} options - the options to be used (may be null)\n * @return {Scopy~KeyFactory} The key factory.\n * @private\n */\nfunction getKeyFactory(global, options) {\n options = parseOptions(options);\n\n if (options.symbol) {\n return global ? Symbol.for : Symbol;\n }\n\n return function(name) {\n return '_' + name;\n };\n}\n\n/**\n * Iterates over all non-scoped properties on the specified object using the options provided\n * and creates a new array containing values derived from the key/value pairs for each property using the given\n * mapper.\n *\n * @param {Object} obj - the object whose non-scoped properties are to be mapped\n * @param {Scopy~PropertyMapper} mapper - the function to be called with the value and name of each non-scoped property\n * and to return a value to be mapped to the result\n * @param {?Scopy~Options} options - the options to be used (may be null/code>)\n * @return {Array} An array containing values derived from the non-scoped properties of obj using\n * mapper.\n * @private\n */\nfunction mapProperties(obj, mapper, options) {\n options = parseOptions(options);\n\n var result = [];\n\n for (var name in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, name) && (options.symbol || name[0] !== '_')) {\n result.push(mapper(obj[name], name));\n }\n }\n\n return result;\n}\n\n/**\n * Parses the optional input options provided, normalizing options and applying default values, where\n * needed.\n *\n * @param {?Scopy~Options} options - the input options to be parsed (may be null if none were provided)\n * @return {Scopy~Options} A new options object parsed from options.\n * @private\n */\nfunction parseOptions(options) {\n if (options == null) {\n options = {};\n }\n\n var symbol = options.symbol !== false && typeof Symbol === 'function';\n\n return { symbol: symbol };\n}\n\nmodule.exports = Scopy;\n\n/**\n * Returns a scoped or \"global\" key based on the specified name.\n *\n * @callback Scopy~KeyFactory\n * @param {string} name - the name on which to base the key\n * @return {string|symbol} The key created for name.\n */\n\n/**\n * The options to be used to create property keys with Scopy.\n *\n * @typedef {Object} Scopy~Options\n * @property {boolean} [symbol=true] - true if ES2015's Symbol should be used, where possible;\n * otherwise false.\n */\n\n/**\n * Returns a single value derived from the non-scoped property name and value provided.\n *\n * @callback Scopy~PropertyMapper\n * @param {*} value - the value of the non-scoped property\n * @param {string} name - the name of the non-scoped property\n * @return {*} The value to mapped for the non-scoped property.\n */\n"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/scopy.min.js b/dist/scopy.min.js index 75dc1fb..7b26843 100644 --- a/dist/scopy.min.js +++ b/dist/scopy.min.js @@ -1,4 +1,4 @@ -/*! Scopy v0.2.0 | (C) 2017 Alasdair Mercer, Skelp | MIT License */ -!function(n,r){"object"==typeof exports&&"undefined"!=typeof module?module.exports=r():"function"==typeof define&&define.amd?define("scopy",r):n.Scopy=r()}(this,function(){"use strict";function n(r,t){if(this instanceof n)throw new TypeError("Scopy is not a constructor");return o(!1,t)(r)}function r(n,r){return function(){var t=Array.prototype.slice.call(arguments,0,1);return n.apply(null,t.concat(r))}}function t(n,t,o,e){for(var u,f=o.length,l=0;lname and using the options provided.\n *\n * If the symbol option is enabled (which it is by default), an ES2015 Symbol will be\n * returned (where supported), otherwise this method will simply return name prefixed with an underscore.\n *\n * Symbols returned by this method will always be unique when called multiple times with the same\n * name, however, string keys will always be exactly the same.\n *\n * This method is ideal when defining a key for a privately scoped property.\n *\n * @example\n *
\n * // user.js\n * var Scopy = require('scopy')\n *\n * var _name = Scopy('name')\n *\n * function User(name) {\n *   this[_name] = name\n * }\n *\n * User.prototype.getName = function() {\n *   return this[_name]\n * }\n *\n * module.exports = User\n * 
\n * @param {string} name - the name for the scoped key\n * @param {Scopy~Options} [options] - the options to be used (may be null)\n * @return {string|symbol} The scoped key for name.\n * @throws {TypeError} If an attempt is made to instantiate Scopy (e.g. via new).\n * @public\n */\nfunction Scopy(name, options) {\n if (this instanceof Scopy) {\n throw new TypeError('Scopy is not a constructor')\n }\n\n var factory = getKeyFactory(false, options)\n\n return factory(name)\n}\n\n/**\n * Returns scoped keys based on the specified names and using the options provided.\n *\n * If the symbol option is enabled (which it is by default), this method will return names\n * mapped to ES2015 Symbols (where supported), otherwise names will simply be mapped to\n * themselves prefixed with an underscore.\n *\n * Symbols included in the mapping returned by this method will always be unique when called multiple times\n * with the same name, however, string keys will always be exactly the same.\n *\n * This method is ideal when defining keys for privately scoped properties.\n *\n * @example\n *
\n * // user.js\n * var Scopy = require('scopy')\n *\n * var keys = Scopy.all([ 'email', 'name' ])\n *\n * function User(email, name) {\n *   this[keys.email] = email\n *   this[keys.name] = name\n * }\n *\n * User.prototype.getEmail = function() {\n *   return this[keys.email]\n * }\n *\n * User.prototype.getName = function() {\n *   return this[keys.name]\n * }\n *\n * module.exports = User\n * 
\n * @param {string[]} [names] - the names for the scoped keys (may be null)\n * @param {Scopy~Options} [options] - the options to be used (may be null)\n * @return {Object.} A mapping containing names and their corresponding scoped keys.\n * @public\n * @static\n * @memberof Scopy\n */\nScopy.all = function(names, options) {\n names = names || []\n\n var factory = getKeyFactory(false, options)\n var keys = {}\n var length = names.length\n var name\n\n for (var i = 0; i < length; i++) {\n name = names[i]\n\n keys[name] = factory(name)\n }\n\n return keys\n}\n\n/**\n * Returns the key/value pairs for all of the specified object's own enumerable properties that are not scoped, in the\n * same order as that provided by a for-in loop.\n *\n * This method returns a multi-dimensional array where each item is an array containing the name and value\n * ([name, value]) of a non-scoped enumerable property.\n *\n * Properties mapped to a Symbol are never included in this method but those mapped to properties\n * whose name is prefixed with an underscore, created when the symbol option has been explicitly disabled,\n * will be included unless the symbol option is explicitly disabled when calling this method.\n *\n * This method is intended to be used just like ES2015's Object.entries method while also supporting cases\n * where Symbols have not been used to scope properties.\n *\n * @example\n *
\n * var Scopy = require('scopy')\n * var uuid = require('uuid/v4')\n *\n * var _generateId = Scopy('generateId')\n * var _id = Scopy('id')\n * var _name = Scopy('name')\n *\n * function User(name) {\n *   this[_id] = this[_generateId]()\n *   this[_name] = name\n *   this.length = name.length\n * }\n *\n * User.prototype[_generateId] = function() {\n *   return uuid()\n * }\n *\n * User.prototype.getName = function() {\n *   return this[_name]\n * }\n *\n * Scopy.entries(new User('foo'))\n * //=> [ [ \"length\", 3 ] ]\n * Scopy.entries(User.prototype)\n * //=> [ [ \"getName\", function() { return this[_name] } ] ]\n * 
\n * @param {Object} obj - the object whose enumerable own non-scoped property key/value pairs are to be returned\n * @param {Scopy~Options} [options] - the options to be used (may be null)\n * @return {Array} An array containing the key/value pairs for all of the enumerable non-scoped properties of\n * obj.\n * @public\n * @static\n * @memberof Scopy\n */\nScopy.entries = function(obj, options) {\n return mapProperties(obj, function(value, name) {\n return [ name, value ]\n }, options)\n}\n\n/**\n * Returns a \"global\" key based on the specified name and using the options provided.\n *\n * If the symbol option is enabled (which it is by default), an ES2015 Symbol will be returned\n * from the runtime-wide symbol registry (where supported), otherwise this method will simply return name\n * prefixed with an underscore.\n *\n * Unlike {@link Scopy}, Symbols returned by this method will always be the same when called multiple times\n * with the same name, just like string keys.\n *\n * It is recommended that name be prefixed in order to avoid conflicts with other libraries that may also\n * have a \"global\" key of the same name.\n *\n * This method is ideal when defining a key for a protected/internally scoped property.\n *\n * @example\n *
\n * // user.js\n * var Scopy = require('scopy')\n * var uuid = require('node-uuid/v4')\n *\n * var _id = Scopy.for('example_user_id')\n * var _name = Scopy('name')\n *\n * function User(name) {\n *   this[_id] = uuid()\n *   this[_name] = name\n * }\n *\n * User.prototype.getName = function() {\n *   return this[_name]\n * }\n *\n * module.exports = User\n *\n * // user-logger.js\n * var EOL = require('os').EOL\n * var Scopy = require('scopy')\n *\n * var _id = Scopy.for('example_user_id')\n *\n * exports.login = function(output, user) {\n *   var id = user[_id]\n *\n *   output.write('User[' + id + '] has logged in!' + EOL)\n * }\n * 
\n * @param {string} name - the name for the \"global\" key\n * @param {Scopy~Options} [options] - the options to be used (may be null)\n * @return {string|symbol} The \"global\" key for name.\n * @public\n * @static\n * @memberof Scopy\n */\nScopy.for = function(name, options) {\n var factory = getKeyFactory(true, options)\n\n return factory(name)\n}\n\n/**\n * Returns \"global\" keys based on the specified names and using the options provided.\n *\n * If the symbol option is enabled (which it is by default), this method will return names\n * mapped to ES2015 Symbols from the runtime-wide symbol registry (where supported), otherwise\n * names will simply be mapped to themselves prefixed with an underscore.\n *\n * Unlike {@link Scopy.all}, Symbols included in the mapping returned by this method will always be the\n * same when called multiple times with the same name, just like string keys.\n *\n * It is recommended that each name within names be prefixed in order to avoid conflicts with other\n * libraries that may also have a \"global\" key of the same name.\n *\n * This method is ideal when defining keys for protected/internally scoped properties.\n *\n * @example\n *
\n * // user.js\n * var Scopy = require('scopy')\n * var uuid = require('node-uuid/v4')\n *\n * var keys = Scopy.for.all([ 'example_user_id', 'example_user_lastUpdatedBy' ])\n * var _name = Scopy('name')\n *\n * function User(name) {\n *   this[keys['example.user.id']] = uuid()\n *   this[keys['example.user.lastUpdatedBy']] = null\n *   this[_name] = name\n * }\n *\n * User.prototype.getName = function() {\n *   return this[_name]\n * }\n *\n * module.exports = User\n *\n * // user-logger.js\n * var EOL = require('os').EOL\n * var Scopy = require('scopy')\n *\n * var keys = Scopy.for.all([ 'example_user_id', 'example_user_lastUpdatedBy' ])\n *\n * exports.update = function(output, user) {\n *   var id = user[keys['example.user.id']]\n *   var lastUpdatedBy = user[keys['example.user.lastUpdatedBy']]\n *\n *   output.write('User[' + id + '] has been updated by ' + lastUpdatedBy + EOL)\n * }\n * 
\n * @param {string[]} [names] - the names for the \"global\" keys (may be null)\n * @param {Scopy~Options} [options] - the options to be used (may be null)\n * @return {Object.} A mapping containing names and their corresponding \"global\"\n * keys.\n * @public\n * @static\n * @memberof Scopy.for\n */\nScopy.for.all = function(names, options) {\n names = names || []\n\n var factory = getKeyFactory(true, options)\n var keys = {}\n var length = names.length\n var name\n\n for (var i = 0; i < length; i++) {\n name = names[i]\n\n keys[name] = factory(name)\n }\n\n return keys\n}\n\n/**\n * An alias for the {@link Scopy.for.all} method.\n *\n * @param {string[]} [names] - the names for the \"global\" keys (may be null)\n * @param {Scopy~Options} [options] - the options to be used (may be null)\n * @return {Object.} A mapping containing names and their corresponding \"global\"\n * keys.\n * @public\n * @static\n * @memberof Scopy\n */\nScopy.forAll = Scopy.for.all\n\n/**\n * Returns whether the specified obj represents a scoped or \"global\" key based on the options\n * provided.\n *\n * If the symbol option is enabled (which it is by default), this method will return true if\n * obj is an ES2015 Symbol (where supported), otherwise it will only return true\n * if and only if obj is a string that starts with at least one underscore.\n *\n * @example\n *
\n * var Scopy = require('scopy')\n *\n * Scopy.is(Scopy('foo'))\n * //=> true\n * Scopy.is(Scopy('foo', { symbol: false }))\n * //=> true\n * Scopy.is('foo')\n * //=> false\n * 
\n * @param {*} obj - the object to be checked (may be null)\n * @param {Scopy~Options} [options] - the options to be used (may be null)\n * @return {boolean} true if obj is a scoped or \"global\" key; otherwise false.\n * @public\n * @static\n * @memberof Scopy\n */\nScopy.is = function(obj, options) {\n if (obj == null) {\n return false\n }\n\n options = parseOptions(options)\n\n return options.symbol ? typeof obj === 'symbol' : typeof obj === 'string' && obj[0] === '_'\n}\n\n/**\n * Returns the names of all of the specified object's own enumerable properties that are not scoped, in the same order\n * as that provided by a for-in loop.\n *\n * Properties mapped to a Symbol are never included in this method but those mapped to properties\n * whose name is prefixed with an underscore, created when the symbol option has been explicitly disabled,\n * will be included unless the symbol option is explicitly disabled when calling this method.\n *\n * This method is intended to be used just like ES2015's Object.keys method while also supporting cases\n * where Symbols have not been used to scope properties.\n *\n * @example\n *
\n * var Scopy = require('scopy')\n * var uuid = require('uuid/v4')\n *\n * var _generateId = Scopy('generateId')\n * var _id = Scopy('id')\n * var _name = Scopy('name')\n *\n * function User(name) {\n *   this[_id] = this[_generateId]()\n *   this[_name] = name\n *   this.length = name.length\n * }\n *\n * User.prototype[_generateId] = function() {\n *   return uuid()\n * }\n *\n * User.prototype.getName = function() {\n *   return this[_name]\n * }\n *\n * Scopy.keys(new User('foo'))\n * //=> [ \"length\" ]\n * Scopy.keys(User.prototype)\n * //=> [ \"getName\" ]\n * 
\n * @param {Object} obj - the object whose enumerable own non-scoped property names are to be returned\n * @param {Scopy~Options} [options] - the options to be used (may be null)\n * @return {string[]} An array of strings that represent all of the enumerable non-scoped properties of\n * obj.\n * @public\n * @static\n * @memberof Scopy\n */\nScopy.keys = function(obj, options) {\n return mapProperties(obj, function(value, name) {\n return name\n }, options)\n}\n\n/**\n * Returns a version of {@link Scopy} that is bound (along with all of its methods) to the specified\n * options.\n *\n * Since it's recommended that consumers use the same options, when specified, this method can be really useful as it\n * allows consumers to only specify the options once. This is especially useful for those wishing to explictly disable\n * the symbol option.\n *\n * Any options passed to the methods within the returned wrapped Scopy API will be ignored in favor of\n * options.\n *\n * @example\n *
\n * var Scopy = require('scopy').using({ symbol: false })\n *\n * Scopy('foo')\n * //=> \"_foo\"\n * Scopy.all([ 'foo', 'bar' ])\n * //=> { foo: \"_foo\", bar: \"_bar\" }\n * Scopy.is('_foo')\n * //=> true\n * Scopy.is(Symbol('foo'))\n * //=> false\n * 
\n * @param {Scopy~Options} [options] - the options to be used (may be null)\n * @return {Function} A version of {@link Scopy} that will, along with its methods, always use options.\n * @public\n * @static\n * @memberof Scopy\n */\nScopy.using = function(options) {\n options = parseOptions(options)\n\n var BoundScopy = applyOptions(Scopy, options)\n applyOptionsToAll(Scopy, BoundScopy, [\n 'all',\n 'entries',\n 'for',\n 'forAll',\n 'is',\n 'keys',\n 'values'\n ], options)\n\n BoundScopy.for.all = BoundScopy.forAll\n BoundScopy.using = Scopy.using\n\n return BoundScopy\n}\n\n/**\n * Returns the values of all of the specified object's own enumerable properties that are not scoped, in the same order\n * as that provided by a for-in loop.\n *\n * Properties mapped to a Symbol are never included in this method but those mapped to properties\n * whose name is prefixed with an underscore, created when the symbol option has been explicitly disabled,\n * will be included unless the symbol option is explicitly disabled when calling this method.\n *\n * This method is intended to be used just like ES2015's Object.values method while also supporting cases\n * where Symbols have not been used to scope properties.\n *\n * @example\n *
\n * var Scopy = require('scopy')\n * var uuid = require('uuid/v4')\n *\n * var _generateId = Scopy('generateId')\n * var _id = Scopy('id')\n * var _name = Scopy('name')\n *\n * function User(name) {\n *   this[_id] = this[_generateId]()\n *   this[_name] = name\n *   this.length = name.length\n * }\n *\n * User.prototype[_generateId] = function() {\n *   return uuid()\n * }\n *\n * User.prototype.getName = function() {\n *   return this[_name]\n * }\n *\n * Scopy.values(new User('foo'))\n * //=> [ 3 ]\n * Scopy.values(User.prototype)\n * //=> [ function() { return this[_name] } ]\n * 
\n * @param {Object} obj - the object whose enumerable own non-scoped property values are to be returned\n * @param {Scopy~Options} [options] - the options to be used (may be null)\n * @return {Array} An array containing the values of all of the enumerable non-scoped properties of obj.\n * @public\n * @static\n * @memberof Scopy\n */\nScopy.values = function(obj, options) {\n return mapProperties(obj, function(value) {\n return value\n }, options)\n}\n\n/**\n * Returns a function that delegates the call to the specified func so that the options\n * provided are always passed to it.\n *\n * The returned function will always return the return value of calling func.\n *\n * @param {Function} func - the function to which options are to be applied\n * @param {Scopy~Options} options - the options to be applied\n * @return {Function} A function which will always pass options as the last argument to func.\n * @private\n */\nfunction applyOptions(func, options) {\n return function() {\n var args = Array.prototype.slice.call(arguments, 0, 1)\n\n return func.apply(null, args.concat(options))\n }\n}\n\n/**\n * Assigns functions to the specified target for all of the names provided that delegate their\n * calls to the function of the same name on the given source so that the options provided are\n * always passed to them.\n *\n * Each proxy function will always return the return value of calling the original function.\n *\n * @param {Object} source - the object on which the original functions belong\n * @param {Object} target - the object to which the proxy functions are to be assigned\n * @param {string[]} names - the names of each function to be proxied\n * @param {Scopy~Options} options - the options to be used\n * @return {void}\n * @private\n */\nfunction applyOptionsToAll(source, target, names, options) {\n var length = names.length\n var name\n\n for (var i = 0; i < length; i++) {\n name = names[i]\n\n target[name] = applyOptions(source[name], options)\n }\n}\n\n/**\n * Returns a function which can be used to create scoped/\"global\" keys based on the options provided and a\n * name which is passed to it.\n *\n * @param {boolean} global - true if the keys created by the factory are to be \"global\"; otherwise\n * false\n * @param {?Scopy~Options} options - the options to be used (may be null)\n * @return {Scopy~KeyFactory} The key factory.\n * @private\n */\nfunction getKeyFactory(global, options) {\n options = parseOptions(options)\n\n if (options.symbol) {\n return global ? Symbol.for : Symbol\n }\n\n return function(name) {\n return '_' + name\n }\n}\n\n/**\n * Iterates over all non-scoped properties on the specified object using the options provided\n * and creates a new array containing values derived from the key/value pairs for each property using the given\n * mapper.\n *\n * @param {Object} obj - the object whose non-scoped properties are to be mapped\n * @param {Scopy~PropertyMapper} mapper - the function to be called with the value and name of each non-scoped property\n * and to return a value to be mapped to the result\n * @param {?Scopy~Options} options - the options to be used (may be null/code>)\n * @return {Array} An array containing values derived from the non-scoped properties of obj using\n * mapper.\n * @private\n */\nfunction mapProperties(obj, mapper, options) {\n options = parseOptions(options)\n\n var result = []\n\n for (var name in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, name) && (options.symbol || name[0] !== '_')) {\n result.push(mapper(obj[name], name))\n }\n }\n\n return result\n}\n\n/**\n * Parses the optional input options provided, normalizing options and applying default values, where\n * needed.\n *\n * @param {?Scopy~Options} options - the input options to be parsed (may be null if none were provided)\n * @return {Scopy~Options} A new options object parsed from options.\n * @private\n */\nfunction parseOptions(options) {\n if (options == null) {\n options = {}\n }\n\n var symbol = options.symbol !== false && typeof Symbol === 'function'\n\n return { symbol: symbol }\n}\n\nmodule.exports = Scopy\n\n/**\n * Returns a scoped or \"global\" key based on the specified name.\n *\n * @callback Scopy~KeyFactory\n * @param {string} name - the name on which to base the key\n * @return {string|symbol} The key created for name.\n */\n\n/**\n * The options to be used to create property keys with Scopy.\n *\n * @typedef {Object} Scopy~Options\n * @property {boolean} [symbol=true] - true if ES2015's Symbol should be used, where possible;\n * otherwise false.\n */\n/**\n * Returns a single value derived from the non-scoped property name and value provided.\n *\n * @callback Scopy~PropertyMapper\n * @param {*} value - the value of the non-scoped property\n * @param {string} name - the name of the non-scoped property\n * @return {*} The value to mapped for the non-scoped property.\n */\n"],"names":["Scopy","name","options","this","TypeError","getKeyFactory","applyOptions","func","args","Array","prototype","slice","call","arguments","apply","concat","applyOptionsToAll","source","target","names","length","i","global","parseOptions","symbol","Symbol","for","mapProperties","obj","mapper","result","Object","hasOwnProperty","push","all","factory","keys","entries","value","forAll","is","using","BoundScopy","values"],"mappings":";wLA0DA,SAASA,GAAMC,EAAMC,GACnB,GAAIC,eAAgBH,GAClB,KAAM,IAAII,WAAU,6BAKtB,OAFcC,IAAc,EAAOH,GAEpBD,GAkdjB,QAASK,GAAaC,EAAML,GAC1B,MAAO,YACL,GAAIM,GAAOC,MAAMC,UAAUC,MAAMC,KAAKC,UAAW,EAAG,EAEpD,OAAON,GAAKO,MAAM,KAAMN,EAAKO,OAAOb,KAkBxC,QAASc,GAAkBC,EAAQC,EAAQC,EAAOjB,GAIhD,IAAK,GAFDD,GADAmB,EAASD,EAAMC,OAGVC,EAAI,EAAGA,EAAID,EAAQC,IAC1BpB,EAAOkB,EAAME,GAEbH,EAAOjB,GAAQK,EAAaW,EAAOhB,GAAOC,GAc9C,QAASG,GAAciB,EAAQpB,GAG7B,MAFAA,GAAUqB,EAAarB,GAEnBA,EAAQsB,OACHF,EAASG,OAAOC,IAAMD,OAGxB,SAASxB,GACd,MAAO,IAAMA,GAiBjB,QAAS0B,GAAcC,EAAKC,EAAQ3B,GAClCA,EAAUqB,EAAarB,EAEvB,IAAI4B,KAEJ,KAAK,GAAI7B,KAAQ2B,GACXG,OAAOrB,UAAUsB,eAAepB,KAAKgB,EAAK3B,KAAUC,EAAQsB,QAAsB,MAAZvB,EAAK,KAC7E6B,EAAOG,KAAKJ,EAAOD,EAAI3B,GAAOA,GAIlC,OAAO6B,GAWT,QAASP,GAAarB,GAOpB,MANe,OAAXA,IACFA,OAKOsB,OAFItB,EAAQsB,UAAW,GAA2B,kBAAXC,eArgBlDzB,GAAMkC,IAAM,SAASf,EAAOjB,GAC1BiB,EAAQA,KAOR,KAAK,GAFDlB,GAHAkC,EAAU9B,GAAc,EAAOH,GAC/BkC,KACAhB,EAASD,EAAMC,OAGVC,EAAI,EAAGA,EAAID,EAAQC,IAC1BpB,EAAOkB,EAAME,GAEbe,EAAKnC,GAAQkC,EAAQlC,EAGvB,OAAOmC,IAqDTpC,EAAMqC,QAAU,SAAST,EAAK1B,GAC5B,MAAOyB,GAAcC,EAAK,SAASU,EAAOrC,GACxC,OAASA,EAAMqC,IACdpC,IAyDLF,EAAM0B,IAAM,SAASzB,EAAMC,GAGzB,MAFcG,IAAc,EAAMH,GAEnBD,IA4DjBD,EAAM0B,IAAIQ,IAAM,SAASf,EAAOjB,GAC9BiB,EAAQA,KAOR,KAAK,GAFDlB,GAHAkC,EAAU9B,GAAc,EAAMH,GAC9BkC,KACAhB,EAASD,EAAMC,OAGVC,EAAI,EAAGA,EAAID,EAAQC,IAC1BpB,EAAOkB,EAAME,GAEbe,EAAKnC,GAAQkC,EAAQlC,EAGvB,OAAOmC,IAcTpC,EAAMuC,OAASvC,EAAM0B,IAAIQ,IA4BzBlC,EAAMwC,GAAK,SAASZ,EAAK1B,GACvB,MAAW,OAAP0B,IAIJ1B,EAAUqB,EAAarB,GAEhBA,EAAQsB,OAAwB,gBAARI,GAAkC,gBAARA,IAA+B,MAAXA,EAAI,KAkDnF5B,EAAMoC,KAAO,SAASR,EAAK1B,GACzB,MAAOyB,GAAcC,EAAK,SAASU,EAAOrC,GACxC,MAAOA,IACNC,IAiCLF,EAAMyC,MAAQ,SAASvC,GACrBA,EAAUqB,EAAarB,EAEvB,IAAIwC,GAAapC,EAAaN,EAAOE,EAcrC,OAbAc,GAAkBhB,EAAO0C,GACvB,MACA,UACA,MACA,SACA,KACA,OACA,UACCxC,GAEHwC,EAAWhB,IAAIQ,IAAMQ,EAAWH,OAChCG,EAAWD,MAAQzC,EAAMyC,MAElBC,GAiDT1C,EAAM2C,OAAS,SAASf,EAAK1B,GAC3B,MAAOyB,GAAcC,EAAK,SAASU,GACjC,MAAOA,IACNpC,IAkHYF"} \ No newline at end of file +{"version":3,"file":"scopy.min.js","sources":["../src/scopy.js"],"sourcesContent":["/*\n * Copyright (C) 2017 Alasdair Mercer, !ninja\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\n'use strict';\n\n/**\n * Returns a scoped key based on the specified name and using the options provided.\n *\n * If the symbol option is enabled (which it is by default), an ES2015 Symbol will be\n * returned (where supported), otherwise this method will simply return name prefixed with an underscore.\n *\n * Symbols returned by this method will always be unique when called multiple times with the same\n * name, however, string keys will always be exactly the same.\n *\n * This method is ideal when defining a key for a privately scoped property.\n *\n * @example\n *
\n * // user.js\n * var Scopy = require('scopy');\n *\n * var _name = Scopy('name');\n *\n * function User(name) {\n *   this[_name] = name;\n * }\n *\n * User.prototype.getName = function() {\n *   return this[_name];\n * };\n *\n * module.exports = User;\n * 
\n * @param {string} name - the name for the scoped key\n * @param {Scopy~Options} [options] - the options to be used (may be null)\n * @return {string|symbol} The scoped key for name.\n * @throws {TypeError} If an attempt is made to instantiate Scopy (e.g. via new).\n * @public\n */\nfunction Scopy(name, options) {\n if (this instanceof Scopy) {\n throw new TypeError('Scopy is not a constructor');\n }\n\n var factory = getKeyFactory(false, options);\n\n return factory(name);\n}\n\n/**\n * Returns scoped keys based on the specified names and using the options provided.\n *\n * If the symbol option is enabled (which it is by default), this method will return names\n * mapped to ES2015 Symbols (where supported), otherwise names will simply be mapped to\n * themselves prefixed with an underscore.\n *\n * Symbols included in the mapping returned by this method will always be unique when called multiple times\n * with the same name, however, string keys will always be exactly the same.\n *\n * This method is ideal when defining keys for privately scoped properties.\n *\n * @example\n *
\n * // user.js\n * var Scopy = require('scopy');\n *\n * var keys = Scopy.all([ 'email', 'name' ]);\n *\n * function User(email, name) {\n *   this[keys.email] = email;\n *   this[keys.name] = name;\n * }\n *\n * User.prototype.getEmail = function() {\n *   return this[keys.email];\n * };\n *\n * User.prototype.getName = function() {\n *   return this[keys.name];\n * };\n *\n * module.exports = User;\n * 
\n * @param {string[]} [names] - the names for the scoped keys (may be null)\n * @param {Scopy~Options} [options] - the options to be used (may be null)\n * @return {Object.} A mapping containing names and their corresponding scoped keys.\n * @public\n * @static\n * @memberof Scopy\n */\nScopy.all = function(names, options) {\n names = names || [];\n\n var factory = getKeyFactory(false, options);\n var keys = {};\n\n names.forEach(function(name) {\n keys[name] = factory(name);\n });\n\n return keys;\n};\n\n/**\n * Returns the key/value pairs for all of the specified object's own enumerable properties that are not scoped, in the\n * same order as that provided by a for-in loop.\n *\n * This method returns a multi-dimensional array where each item is an array containing the name and value\n * ([name, value]) of a non-scoped enumerable property.\n *\n * Properties mapped to a Symbol are never included in this method but those mapped to properties\n * whose name is prefixed with an underscore, created when the symbol option has been explicitly disabled,\n * will be included unless the symbol option is explicitly disabled when calling this method.\n *\n * This method is intended to be used just like ES2015's Object.entries method while also supporting cases\n * where Symbols have not been used to scope properties.\n *\n * @example\n *
\n * var Scopy = require('scopy');\n * var uuid = require('uuid/v4');\n *\n * var _generateId = Scopy('generateId');\n * var _id = Scopy('id');\n * var _name = Scopy('name');\n *\n * function User(name) {\n *   this[_id] = this[_generateId]();\n *   this[_name] = name;\n *   this.length = name.length;\n * }\n *\n * User.prototype[_generateId] = function() {\n *   return uuid();\n * };\n *\n * User.prototype.getName = function() {\n *   return this[_name];\n * };\n *\n * Scopy.entries(new User('foo'));\n * //=> [ [ \"length\", 3 ] ]\n * Scopy.entries(User.prototype);\n * //=> [ [ \"getName\", function() { return this[_name] } ] ]\n * 
\n * @param {Object} obj - the object whose enumerable own non-scoped property key/value pairs are to be returned\n * @param {Scopy~Options} [options] - the options to be used (may be null)\n * @return {Array} An array containing the key/value pairs for all of the enumerable non-scoped properties of\n * obj.\n * @public\n * @static\n * @memberof Scopy\n */\nScopy.entries = function(obj, options) {\n return mapProperties(obj, function(value, name) {\n return [ name, value ];\n }, options);\n};\n\n/**\n * Returns a \"global\" key based on the specified name and using the options provided.\n *\n * If the symbol option is enabled (which it is by default), an ES2015 Symbol will be returned\n * from the runtime-wide symbol registry (where supported), otherwise this method will simply return name\n * prefixed with an underscore.\n *\n * Unlike {@link Scopy}, Symbols returned by this method will always be the same when called multiple times\n * with the same name, just like string keys.\n *\n * It is recommended that name be prefixed in order to avoid conflicts with other libraries that may also\n * have a \"global\" key of the same name.\n *\n * This method is ideal when defining a key for a protected/internally scoped property.\n *\n * @example\n *
\n * // user.js\n * var Scopy = require('scopy');\n * var uuid = require('uuid/v4');\n *\n * var _id = Scopy.for('example_user_id');\n * var _name = Scopy('name');\n *\n * function User(name) {\n *   this[_id] = uuid();\n *   this[_name] = name;\n * }\n *\n * User.prototype.getName = function() {\n *   return this[_name];\n * };\n *\n * module.exports = User;\n *\n * // user-logger.js\n * var EOL = require('os').EOL;\n * var Scopy = require('scopy');\n *\n * var _id = Scopy.for('example_user_id');\n *\n * exports.login = function(output, user) {\n *   var id = user[_id];\n *\n *   output.write('User[' + id + '] has logged in!' + EOL);\n * };\n * 
\n * @param {string} name - the name for the \"global\" key\n * @param {Scopy~Options} [options] - the options to be used (may be null)\n * @return {string|symbol} The \"global\" key for name.\n * @public\n * @static\n * @memberof Scopy\n */\nScopy.for = function(name, options) {\n var factory = getKeyFactory(true, options);\n\n return factory(name);\n};\n\n/**\n * Returns \"global\" keys based on the specified names and using the options provided.\n *\n * If the symbol option is enabled (which it is by default), this method will return names\n * mapped to ES2015 Symbols from the runtime-wide symbol registry (where supported), otherwise\n * names will simply be mapped to themselves prefixed with an underscore.\n *\n * Unlike {@link Scopy.all}, Symbols included in the mapping returned by this method will always be the\n * same when called multiple times with the same name, just like string keys.\n *\n * It is recommended that each name within names be prefixed in order to avoid conflicts with other\n * libraries that may also have a \"global\" key of the same name.\n *\n * This method is ideal when defining keys for protected/internally scoped properties.\n *\n * @example\n *
\n * // user.js\n * var Scopy = require('scopy');\n * var uuid = require('uuid/v4');\n *\n * var keys = Scopy.for.all([ 'example_user_id', 'example_user_lastUpdatedBy' ]);\n * var _name = Scopy('name');\n *\n * function User(name) {\n *   this[keys['example.user.id']] = uuid();\n *   this[keys['example.user.lastUpdatedBy']] = null;\n *   this[_name] = name;\n * }\n *\n * User.prototype.getName = function() {\n *   return this[_name];\n * };\n *\n * module.exports = User;\n *\n * // user-logger.js\n * var EOL = require('os').EOL;\n * var Scopy = require('scopy');\n *\n * var keys = Scopy.for.all([ 'example_user_id', 'example_user_lastUpdatedBy' ]);\n *\n * exports.update = function(output, user) {\n *   var id = user[keys['example.user.id']];\n *   var lastUpdatedBy = user[keys['example.user.lastUpdatedBy']];\n *\n *   output.write('User[' + id + '] has been updated by ' + lastUpdatedBy + EOL);\n * };\n * 
\n * @param {string[]} [names] - the names for the \"global\" keys (may be null)\n * @param {Scopy~Options} [options] - the options to be used (may be null)\n * @return {Object.} A mapping containing names and their corresponding \"global\"\n * keys.\n * @public\n * @static\n * @memberof Scopy.for\n */\nScopy.for.all = function(names, options) {\n names = names || [];\n\n var factory = getKeyFactory(true, options);\n var keys = {};\n\n names.forEach(function(name) {\n keys[name] = factory(name);\n });\n\n return keys;\n};\n\n/**\n * An alias for the {@link Scopy.for.all} method.\n *\n * @param {string[]} [names] - the names for the \"global\" keys (may be null)\n * @param {Scopy~Options} [options] - the options to be used (may be null)\n * @return {Object.} A mapping containing names and their corresponding \"global\"\n * keys.\n * @public\n * @static\n * @memberof Scopy\n */\nScopy.forAll = Scopy.for.all;\n\n/**\n * Returns whether the specified obj represents a scoped or \"global\" key based on the options\n * provided.\n *\n * If the symbol option is enabled (which it is by default), this method will return true if\n * obj is an ES2015 Symbol (where supported), otherwise it will only return true\n * if and only if obj is a string that starts with at least one underscore.\n *\n * @example\n *
\n * var Scopy = require('scopy');\n *\n * Scopy.is(Scopy('foo'));\n * //=> true\n * Scopy.is(Scopy('foo', { symbol: false }));\n * //=> true\n * Scopy.is('foo');\n * //=> false\n * 
\n * @param {*} obj - the object to be checked (may be null)\n * @param {Scopy~Options} [options] - the options to be used (may be null)\n * @return {boolean} true if obj is a scoped or \"global\" key; otherwise false.\n * @public\n * @static\n * @memberof Scopy\n */\nScopy.is = function(obj, options) {\n if (obj == null) {\n return false;\n }\n\n options = parseOptions(options);\n\n return options.symbol ? typeof obj === 'symbol' : typeof obj === 'string' && obj[0] === '_';\n};\n\n/**\n * Returns the names of all of the specified object's own enumerable properties that are not scoped, in the same order\n * as that provided by a for-in loop.\n *\n * Properties mapped to a Symbol are never included in this method but those mapped to properties\n * whose name is prefixed with an underscore, created when the symbol option has been explicitly disabled,\n * will be included unless the symbol option is explicitly disabled when calling this method.\n *\n * This method is intended to be used just like ES2015's Object.keys method while also supporting cases\n * where Symbols have not been used to scope properties.\n *\n * @example\n *
\n * var Scopy = require('scopy');\n * var uuid = require('uuid/v4');\n *\n * var _generateId = Scopy('generateId');\n * var _id = Scopy('id');\n * var _name = Scopy('name');\n *\n * function User(name) {\n *   this[_id] = this[_generateId]();\n *   this[_name] = name;\n *   this.length = name.length;\n * }\n *\n * User.prototype[_generateId] = function() {\n *   return uuid();\n * };\n *\n * User.prototype.getName = function() {\n *   return this[_name];\n * };\n *\n * Scopy.keys(new User('foo'));\n * //=> [ \"length\" ]\n * Scopy.keys(User.prototype);\n * //=> [ \"getName\" ]\n * 
\n * @param {Object} obj - the object whose enumerable own non-scoped property names are to be returned\n * @param {Scopy~Options} [options] - the options to be used (may be null)\n * @return {string[]} An array of strings that represent all of the enumerable non-scoped properties of\n * obj.\n * @public\n * @static\n * @memberof Scopy\n */\nScopy.keys = function(obj, options) {\n return mapProperties(obj, function(value, name) {\n return name;\n }, options);\n};\n\n/**\n * Returns a version of {@link Scopy} that is bound (along with all of its methods) to the specified\n * options.\n *\n * Since it's recommended that consumers use the same options, when specified, this method can be really useful as it\n * allows consumers to only specify the options once. This is especially useful for those wishing to explictly disable\n * the symbol option.\n *\n * Any options passed to the methods within the returned wrapped Scopy API will be ignored in favor of\n * options.\n *\n * @example\n *
\n * var Scopy = require('scopy').using({ symbol: false });\n *\n * Scopy('foo');\n * //=> \"_foo\"\n * Scopy.all([ 'foo', 'bar' ]);\n * //=> { foo: \"_foo\", bar: \"_bar\" }\n * Scopy.is('_foo');\n * //=> true\n * Scopy.is(Symbol('foo'));\n * //=> false\n * 
\n * @param {Scopy~Options} [options] - the options to be used (may be null)\n * @return {Function} A version of {@link Scopy} that will, along with its methods, always use options.\n * @public\n * @static\n * @memberof Scopy\n */\nScopy.using = function(options) {\n options = parseOptions(options);\n\n var BoundScopy = applyOptions(Scopy, options);\n applyOptionsToAll(Scopy, BoundScopy, [\n 'all',\n 'entries',\n 'for',\n 'forAll',\n 'is',\n 'keys',\n 'values'\n ], options);\n\n BoundScopy.for.all = BoundScopy.forAll;\n BoundScopy.using = Scopy.using;\n\n return BoundScopy;\n};\n\n/**\n * Returns the values of all of the specified object's own enumerable properties that are not scoped, in the same order\n * as that provided by a for-in loop.\n *\n * Properties mapped to a Symbol are never included in this method but those mapped to properties\n * whose name is prefixed with an underscore, created when the symbol option has been explicitly disabled,\n * will be included unless the symbol option is explicitly disabled when calling this method.\n *\n * This method is intended to be used just like ES2015's Object.values method while also supporting cases\n * where Symbols have not been used to scope properties.\n *\n * @example\n *
\n * var Scopy = require('scopy');\n * var uuid = require('uuid/v4');\n *\n * var _generateId = Scopy('generateId');\n * var _id = Scopy('id');\n * var _name = Scopy('name');\n *\n * function User(name) {\n *   this[_id] = this[_generateId]();\n *   this[_name] = name;\n *   this.length = name.length;\n * }\n *\n * User.prototype[_generateId] = function() {\n *   return uuid();\n * };\n *\n * User.prototype.getName = function() {\n *   return this[_name];\n * };\n *\n * Scopy.values(new User('foo'));\n * //=> [ 3 ]\n * Scopy.values(User.prototype);\n * //=> [ function() { return this[_name] } ]\n * 
\n * @param {Object} obj - the object whose enumerable own non-scoped property values are to be returned\n * @param {Scopy~Options} [options] - the options to be used (may be null)\n * @return {Array} An array containing the values of all of the enumerable non-scoped properties of obj.\n * @public\n * @static\n * @memberof Scopy\n */\nScopy.values = function(obj, options) {\n return mapProperties(obj, function(value) {\n return value;\n }, options);\n};\n\n/**\n * Returns a function that delegates the call to the specified func so that the options\n * provided are always passed to it.\n *\n * The returned function will always return the return value of calling func.\n *\n * @param {Function} func - the function to which options are to be applied\n * @param {Scopy~Options} options - the options to be applied\n * @return {Function} A function which will always pass options as the last argument to func.\n * @private\n */\nfunction applyOptions(func, options) {\n return function() {\n var args = Array.prototype.slice.call(arguments, 0, 1);\n\n return func.apply(null, args.concat(options));\n };\n}\n\n/**\n * Assigns functions to the specified target for all of the names provided that delegate their\n * calls to the function of the same name on the given source so that the options provided are\n * always passed to them.\n *\n * Each proxy function will always return the return value of calling the original function.\n *\n * @param {Object} source - the object on which the original functions belong\n * @param {Object} target - the object to which the proxy functions are to be assigned\n * @param {string[]} names - the names of each function to be proxied\n * @param {Scopy~Options} options - the options to be used\n * @return {void}\n * @private\n */\nfunction applyOptionsToAll(source, target, names, options) {\n names.forEach(function(name) {\n target[name] = applyOptions(source[name], options);\n });\n}\n\n/**\n * Returns a function which can be used to create scoped/\"global\" keys based on the options provided and a\n * name which is passed to it.\n *\n * @param {boolean} global - true if the keys created by the factory are to be \"global\"; otherwise\n * false\n * @param {?Scopy~Options} options - the options to be used (may be null)\n * @return {Scopy~KeyFactory} The key factory.\n * @private\n */\nfunction getKeyFactory(global, options) {\n options = parseOptions(options);\n\n if (options.symbol) {\n return global ? Symbol.for : Symbol;\n }\n\n return function(name) {\n return '_' + name;\n };\n}\n\n/**\n * Iterates over all non-scoped properties on the specified object using the options provided\n * and creates a new array containing values derived from the key/value pairs for each property using the given\n * mapper.\n *\n * @param {Object} obj - the object whose non-scoped properties are to be mapped\n * @param {Scopy~PropertyMapper} mapper - the function to be called with the value and name of each non-scoped property\n * and to return a value to be mapped to the result\n * @param {?Scopy~Options} options - the options to be used (may be null/code>)\n * @return {Array} An array containing values derived from the non-scoped properties of obj using\n * mapper.\n * @private\n */\nfunction mapProperties(obj, mapper, options) {\n options = parseOptions(options);\n\n var result = [];\n\n for (var name in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, name) && (options.symbol || name[0] !== '_')) {\n result.push(mapper(obj[name], name));\n }\n }\n\n return result;\n}\n\n/**\n * Parses the optional input options provided, normalizing options and applying default values, where\n * needed.\n *\n * @param {?Scopy~Options} options - the input options to be parsed (may be null if none were provided)\n * @return {Scopy~Options} A new options object parsed from options.\n * @private\n */\nfunction parseOptions(options) {\n if (options == null) {\n options = {};\n }\n\n var symbol = options.symbol !== false && typeof Symbol === 'function';\n\n return { symbol: symbol };\n}\n\nmodule.exports = Scopy;\n\n/**\n * Returns a scoped or \"global\" key based on the specified name.\n *\n * @callback Scopy~KeyFactory\n * @param {string} name - the name on which to base the key\n * @return {string|symbol} The key created for name.\n */\n\n/**\n * The options to be used to create property keys with Scopy.\n *\n * @typedef {Object} Scopy~Options\n * @property {boolean} [symbol=true] - true if ES2015's Symbol should be used, where possible;\n * otherwise false.\n */\n\n/**\n * Returns a single value derived from the non-scoped property name and value provided.\n *\n * @callback Scopy~PropertyMapper\n * @param {*} value - the value of the non-scoped property\n * @param {string} name - the name of the non-scoped property\n * @return {*} The value to mapped for the non-scoped property.\n */\n"],"names":["Scopy","name","options","this","TypeError","getKeyFactory","applyOptions","func","args","Array","prototype","slice","call","arguments","apply","concat","applyOptionsToAll","source","target","names","forEach","global","parseOptions","symbol","Symbol","for","mapProperties","obj","mapper","result","Object","hasOwnProperty","push","all","factory","keys","entries","value","forAll","is","using","BoundScopy","values"],"mappings":";wLA0DA,SAASA,GAAMC,EAAMC,GACnB,GAAIC,eAAgBH,GAClB,KAAM,IAAII,WAAU,6BAKtB,OAFcC,IAAc,EAAOH,GAEpBD,GA0cjB,QAASK,GAAaC,EAAML,GAC1B,MAAO,YACL,GAAIM,GAAOC,MAAMC,UAAUC,MAAMC,KAAKC,UAAW,EAAG,EAEpD,OAAON,GAAKO,MAAM,KAAMN,EAAKO,OAAOb,KAkBxC,QAASc,GAAkBC,EAAQC,EAAQC,EAAOjB,GAChDiB,EAAMC,QAAQ,SAASnB,GACrBiB,EAAOjB,GAAQK,EAAaW,EAAOhB,GAAOC,KAc9C,QAASG,GAAcgB,EAAQnB,GAG7B,MAFAA,GAAUoB,EAAapB,GAEnBA,EAAQqB,OACHF,EAASG,OAAOC,IAAMD,OAGxB,SAASvB,GACd,MAAO,IAAMA,GAiBjB,QAASyB,GAAcC,EAAKC,EAAQ1B,GAClCA,EAAUoB,EAAapB,EAEvB,IAAI2B,KAEJ,KAAK,GAAI5B,KAAQ0B,GACXG,OAAOpB,UAAUqB,eAAenB,KAAKe,EAAK1B,KAAUC,EAAQqB,QAAsB,MAAZtB,EAAK,KAC7E4B,EAAOG,KAAKJ,EAAOD,EAAI1B,GAAOA,GAIlC,OAAO4B,GAWT,QAASP,GAAapB,GAOpB,MANe,OAAXA,IACFA,OAKOqB,OAFIrB,EAAQqB,UAAW,GAA2B,kBAAXC,eAxflDxB,GAAMiC,IAAM,SAASd,EAAOjB,GAC1BiB,EAAQA,KAER,IAAIe,GAAU7B,GAAc,EAAOH,GAC/BiC,IAMJ,OAJAhB,GAAMC,QAAQ,SAASnB,GACrBkC,EAAKlC,GAAQiC,EAAQjC,KAGhBkC,GAqDTnC,EAAMoC,QAAU,SAAST,EAAKzB,GAC5B,MAAOwB,GAAcC,EAAK,SAASU,EAAOpC,GACxC,OAASA,EAAMoC,IACdnC,IAyDLF,EAAMyB,IAAM,SAASxB,EAAMC,GAGzB,MAFcG,IAAc,EAAMH,GAEnBD,IA4DjBD,EAAMyB,IAAIQ,IAAM,SAASd,EAAOjB,GAC9BiB,EAAQA,KAER,IAAIe,GAAU7B,GAAc,EAAMH,GAC9BiC,IAMJ,OAJAhB,GAAMC,QAAQ,SAASnB,GACrBkC,EAAKlC,GAAQiC,EAAQjC,KAGhBkC,GAcTnC,EAAMsC,OAAStC,EAAMyB,IAAIQ,IA4BzBjC,EAAMuC,GAAK,SAASZ,EAAKzB,GACvB,MAAW,OAAPyB,IAIJzB,EAAUoB,EAAapB,GAEhBA,EAAQqB,OAAwB,gBAARI,GAAkC,gBAARA,IAA+B,MAAXA,EAAI,KAkDnF3B,EAAMmC,KAAO,SAASR,EAAKzB,GACzB,MAAOwB,GAAcC,EAAK,SAASU,EAAOpC,GACxC,MAAOA,IACNC,IAiCLF,EAAMwC,MAAQ,SAAStC,GACrBA,EAAUoB,EAAapB,EAEvB,IAAIuC,GAAanC,EAAaN,EAAOE,EAcrC,OAbAc,GAAkBhB,EAAOyC,GACvB,MACA,UACA,MACA,SACA,KACA,OACA,UACCvC,GAEHuC,EAAWhB,IAAIQ,IAAMQ,EAAWH,OAChCG,EAAWD,MAAQxC,EAAMwC,MAElBC,GAiDTzC,EAAM0C,OAAS,SAASf,EAAKzB,GAC3B,MAAOwB,GAAcC,EAAK,SAASU,GACjC,MAAOA,IACNnC,IA6GYF"} \ No newline at end of file diff --git a/package.json b/package.json index e7ec021..2118a8e 100644 --- a/package.json +++ b/package.json @@ -1,15 +1,15 @@ { "name": "scopy", - "version": "0.2.0", + "version": "0.3.0", "description": "Property scoping done quick and dirty", - "homepage": "https://github.com/Skelp/scopy", + "homepage": "https://github.com/NotNinja/scopy", "bugs": { - "url": "https://github.com/Skelp/scopy/issues" + "url": "https://github.com/NotNinja/scopy/issues" }, "author": { "name": "Alasdair Mercer", - "email": "alasdair@skelp.io", - "url": "https://skelp.io" + "email": "mercer.alasdair@gmail.com", + "url": "https://not.ninja" }, "license": "MIT", "keywords": [ @@ -19,16 +19,16 @@ ], "repository": { "type": "git", - "url": "https://github.com/Skelp/scopy.git" + "url": "https://github.com/NotNinja/scopy.git" }, "devDependencies": { "chai": "^3.5.0", - "eslint-config-skelp": "^0.1.5", + "codecov": "^2.1.0", + "eslint-config-notninja": "^0.1.1", "grunt": "^1.0.1", "grunt-cli": "^1.2.0", "grunt-contrib-clean": "^1.0.0", "grunt-contrib-watch": "^1.0.0", - "grunt-coveralls": "^1.0.1", "grunt-eslint": "^19.0.0", "grunt-mocha-istanbul": "^5.0.2", "grunt-mocha-test": "^0.13.2", @@ -45,7 +45,7 @@ "scripts": { "build": "grunt build", "ci": "grunt ci", - "report-coverage": "grunt coveralls", + "report-coverage": "codecov", "test": "grunt test" } } diff --git a/src/scopy.js b/src/scopy.js index dbab190..6599aac 100644 --- a/src/scopy.js +++ b/src/scopy.js @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Alasdair Mercer, Skelp + * Copyright (C) 2017 Alasdair Mercer, !ninja * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -20,7 +20,7 @@ * SOFTWARE. */ -'use strict' +'use strict'; /** * Returns a scoped key based on the specified name and using the options provided. @@ -36,19 +36,19 @@ * @example *
  * // user.js
- * var Scopy = require('scopy')
+ * var Scopy = require('scopy');
  *
- * var _name = Scopy('name')
+ * var _name = Scopy('name');
  *
  * function User(name) {
- *   this[_name] = name
+ *   this[_name] = name;
  * }
  *
  * User.prototype.getName = function() {
- *   return this[_name]
- * }
+ *   return this[_name];
+ * };
  *
- * module.exports = User
+ * module.exports = User;
  * 
* @param {string} name - the name for the scoped key * @param {Scopy~Options} [options] - the options to be used (may be null) @@ -58,12 +58,12 @@ */ function Scopy(name, options) { if (this instanceof Scopy) { - throw new TypeError('Scopy is not a constructor') + throw new TypeError('Scopy is not a constructor'); } - var factory = getKeyFactory(false, options) + var factory = getKeyFactory(false, options); - return factory(name) + return factory(name); } /** @@ -81,24 +81,24 @@ function Scopy(name, options) { * @example *
  * // user.js
- * var Scopy = require('scopy')
+ * var Scopy = require('scopy');
  *
- * var keys = Scopy.all([ 'email', 'name' ])
+ * var keys = Scopy.all([ 'email', 'name' ]);
  *
  * function User(email, name) {
- *   this[keys.email] = email
- *   this[keys.name] = name
+ *   this[keys.email] = email;
+ *   this[keys.name] = name;
  * }
  *
  * User.prototype.getEmail = function() {
- *   return this[keys.email]
- * }
+ *   return this[keys.email];
+ * };
  *
  * User.prototype.getName = function() {
- *   return this[keys.name]
- * }
+ *   return this[keys.name];
+ * };
  *
- * module.exports = User
+ * module.exports = User;
  * 
* @param {string[]} [names] - the names for the scoped keys (may be null) * @param {Scopy~Options} [options] - the options to be used (may be null) @@ -108,21 +108,17 @@ function Scopy(name, options) { * @memberof Scopy */ Scopy.all = function(names, options) { - names = names || [] - - var factory = getKeyFactory(false, options) - var keys = {} - var length = names.length - var name + names = names || []; - for (var i = 0; i < length; i++) { - name = names[i] + var factory = getKeyFactory(false, options); + var keys = {}; - keys[name] = factory(name) - } + names.forEach(function(name) { + keys[name] = factory(name); + }); - return keys -} + return keys; +}; /** * Returns the key/value pairs for all of the specified object's own enumerable properties that are not scoped, in the @@ -140,30 +136,30 @@ Scopy.all = function(names, options) { * * @example *
- * var Scopy = require('scopy')
- * var uuid = require('uuid/v4')
+ * var Scopy = require('scopy');
+ * var uuid = require('uuid/v4');
  *
- * var _generateId = Scopy('generateId')
- * var _id = Scopy('id')
- * var _name = Scopy('name')
+ * var _generateId = Scopy('generateId');
+ * var _id = Scopy('id');
+ * var _name = Scopy('name');
  *
  * function User(name) {
- *   this[_id] = this[_generateId]()
- *   this[_name] = name
- *   this.length = name.length
+ *   this[_id] = this[_generateId]();
+ *   this[_name] = name;
+ *   this.length = name.length;
  * }
  *
  * User.prototype[_generateId] = function() {
- *   return uuid()
- * }
+ *   return uuid();
+ * };
  *
  * User.prototype.getName = function() {
- *   return this[_name]
- * }
+ *   return this[_name];
+ * };
  *
- * Scopy.entries(new User('foo'))
+ * Scopy.entries(new User('foo'));
  * //=> [ [ "length", 3 ] ]
- * Scopy.entries(User.prototype)
+ * Scopy.entries(User.prototype);
  * //=> [ [ "getName", function() { return this[_name] } ] ]
  * 
* @param {Object} obj - the object whose enumerable own non-scoped property key/value pairs are to be returned @@ -176,9 +172,9 @@ Scopy.all = function(names, options) { */ Scopy.entries = function(obj, options) { return mapProperties(obj, function(value, name) { - return [ name, value ] - }, options) -} + return [ name, value ]; + }, options); +}; /** * Returns a "global" key based on the specified name and using the options provided. @@ -198,34 +194,34 @@ Scopy.entries = function(obj, options) { * @example *
  * // user.js
- * var Scopy = require('scopy')
- * var uuid = require('node-uuid/v4')
+ * var Scopy = require('scopy');
+ * var uuid = require('uuid/v4');
  *
- * var _id = Scopy.for('example_user_id')
- * var _name = Scopy('name')
+ * var _id = Scopy.for('example_user_id');
+ * var _name = Scopy('name');
  *
  * function User(name) {
- *   this[_id] = uuid()
- *   this[_name] = name
+ *   this[_id] = uuid();
+ *   this[_name] = name;
  * }
  *
  * User.prototype.getName = function() {
- *   return this[_name]
- * }
+ *   return this[_name];
+ * };
  *
- * module.exports = User
+ * module.exports = User;
  *
  * // user-logger.js
- * var EOL = require('os').EOL
- * var Scopy = require('scopy')
+ * var EOL = require('os').EOL;
+ * var Scopy = require('scopy');
  *
- * var _id = Scopy.for('example_user_id')
+ * var _id = Scopy.for('example_user_id');
  *
  * exports.login = function(output, user) {
- *   var id = user[_id]
+ *   var id = user[_id];
  *
- *   output.write('User[' + id + '] has logged in!' + EOL)
- * }
+ *   output.write('User[' + id + '] has logged in!' + EOL);
+ * };
  * 
* @param {string} name - the name for the "global" key * @param {Scopy~Options} [options] - the options to be used (may be null) @@ -235,10 +231,10 @@ Scopy.entries = function(obj, options) { * @memberof Scopy */ Scopy.for = function(name, options) { - var factory = getKeyFactory(true, options) + var factory = getKeyFactory(true, options); - return factory(name) -} + return factory(name); +}; /** * Returns "global" keys based on the specified names and using the options provided. @@ -258,36 +254,36 @@ Scopy.for = function(name, options) { * @example *
  * // user.js
- * var Scopy = require('scopy')
- * var uuid = require('node-uuid/v4')
+ * var Scopy = require('scopy');
+ * var uuid = require('uuid/v4');
  *
- * var keys = Scopy.for.all([ 'example_user_id', 'example_user_lastUpdatedBy' ])
- * var _name = Scopy('name')
+ * var keys = Scopy.for.all([ 'example_user_id', 'example_user_lastUpdatedBy' ]);
+ * var _name = Scopy('name');
  *
  * function User(name) {
- *   this[keys['example.user.id']] = uuid()
- *   this[keys['example.user.lastUpdatedBy']] = null
- *   this[_name] = name
+ *   this[keys['example.user.id']] = uuid();
+ *   this[keys['example.user.lastUpdatedBy']] = null;
+ *   this[_name] = name;
  * }
  *
  * User.prototype.getName = function() {
- *   return this[_name]
- * }
+ *   return this[_name];
+ * };
  *
- * module.exports = User
+ * module.exports = User;
  *
  * // user-logger.js
- * var EOL = require('os').EOL
- * var Scopy = require('scopy')
+ * var EOL = require('os').EOL;
+ * var Scopy = require('scopy');
  *
- * var keys = Scopy.for.all([ 'example_user_id', 'example_user_lastUpdatedBy' ])
+ * var keys = Scopy.for.all([ 'example_user_id', 'example_user_lastUpdatedBy' ]);
  *
  * exports.update = function(output, user) {
- *   var id = user[keys['example.user.id']]
- *   var lastUpdatedBy = user[keys['example.user.lastUpdatedBy']]
+ *   var id = user[keys['example.user.id']];
+ *   var lastUpdatedBy = user[keys['example.user.lastUpdatedBy']];
  *
- *   output.write('User[' + id + '] has been updated by ' + lastUpdatedBy + EOL)
- * }
+ *   output.write('User[' + id + '] has been updated by ' + lastUpdatedBy + EOL);
+ * };
  * 
* @param {string[]} [names] - the names for the "global" keys (may be null) * @param {Scopy~Options} [options] - the options to be used (may be null) @@ -298,21 +294,17 @@ Scopy.for = function(name, options) { * @memberof Scopy.for */ Scopy.for.all = function(names, options) { - names = names || [] + names = names || []; - var factory = getKeyFactory(true, options) - var keys = {} - var length = names.length - var name + var factory = getKeyFactory(true, options); + var keys = {}; - for (var i = 0; i < length; i++) { - name = names[i] + names.forEach(function(name) { + keys[name] = factory(name); + }); - keys[name] = factory(name) - } - - return keys -} + return keys; +}; /** * An alias for the {@link Scopy.for.all} method. @@ -325,7 +317,7 @@ Scopy.for.all = function(names, options) { * @static * @memberof Scopy */ -Scopy.forAll = Scopy.for.all +Scopy.forAll = Scopy.for.all; /** * Returns whether the specified obj represents a scoped or "global" key based on the options @@ -337,13 +329,13 @@ Scopy.forAll = Scopy.for.all * * @example *
- * var Scopy = require('scopy')
+ * var Scopy = require('scopy');
  *
- * Scopy.is(Scopy('foo'))
+ * Scopy.is(Scopy('foo'));
  * //=> true
- * Scopy.is(Scopy('foo', { symbol: false }))
+ * Scopy.is(Scopy('foo', { symbol: false }));
  * //=> true
- * Scopy.is('foo')
+ * Scopy.is('foo');
  * //=> false
  * 
* @param {*} obj - the object to be checked (may be null) @@ -355,13 +347,13 @@ Scopy.forAll = Scopy.for.all */ Scopy.is = function(obj, options) { if (obj == null) { - return false + return false; } - options = parseOptions(options) + options = parseOptions(options); - return options.symbol ? typeof obj === 'symbol' : typeof obj === 'string' && obj[0] === '_' -} + return options.symbol ? typeof obj === 'symbol' : typeof obj === 'string' && obj[0] === '_'; +}; /** * Returns the names of all of the specified object's own enumerable properties that are not scoped, in the same order @@ -376,30 +368,30 @@ Scopy.is = function(obj, options) { * * @example *
- * var Scopy = require('scopy')
- * var uuid = require('uuid/v4')
+ * var Scopy = require('scopy');
+ * var uuid = require('uuid/v4');
  *
- * var _generateId = Scopy('generateId')
- * var _id = Scopy('id')
- * var _name = Scopy('name')
+ * var _generateId = Scopy('generateId');
+ * var _id = Scopy('id');
+ * var _name = Scopy('name');
  *
  * function User(name) {
- *   this[_id] = this[_generateId]()
- *   this[_name] = name
- *   this.length = name.length
+ *   this[_id] = this[_generateId]();
+ *   this[_name] = name;
+ *   this.length = name.length;
  * }
  *
  * User.prototype[_generateId] = function() {
- *   return uuid()
- * }
+ *   return uuid();
+ * };
  *
  * User.prototype.getName = function() {
- *   return this[_name]
- * }
+ *   return this[_name];
+ * };
  *
- * Scopy.keys(new User('foo'))
+ * Scopy.keys(new User('foo'));
  * //=> [ "length" ]
- * Scopy.keys(User.prototype)
+ * Scopy.keys(User.prototype);
  * //=> [ "getName" ]
  * 
* @param {Object} obj - the object whose enumerable own non-scoped property names are to be returned @@ -412,9 +404,9 @@ Scopy.is = function(obj, options) { */ Scopy.keys = function(obj, options) { return mapProperties(obj, function(value, name) { - return name - }, options) -} + return name; + }, options); +}; /** * Returns a version of {@link Scopy} that is bound (along with all of its methods) to the specified @@ -429,15 +421,15 @@ Scopy.keys = function(obj, options) { * * @example *
- * var Scopy = require('scopy').using({ symbol: false })
+ * var Scopy = require('scopy').using({ symbol: false });
  *
- * Scopy('foo')
+ * Scopy('foo');
  * //=> "_foo"
- * Scopy.all([ 'foo', 'bar' ])
+ * Scopy.all([ 'foo', 'bar' ]);
  * //=> { foo: "_foo", bar: "_bar" }
- * Scopy.is('_foo')
+ * Scopy.is('_foo');
  * //=> true
- * Scopy.is(Symbol('foo'))
+ * Scopy.is(Symbol('foo'));
  * //=> false
  * 
* @param {Scopy~Options} [options] - the options to be used (may be null) @@ -447,9 +439,9 @@ Scopy.keys = function(obj, options) { * @memberof Scopy */ Scopy.using = function(options) { - options = parseOptions(options) + options = parseOptions(options); - var BoundScopy = applyOptions(Scopy, options) + var BoundScopy = applyOptions(Scopy, options); applyOptionsToAll(Scopy, BoundScopy, [ 'all', 'entries', @@ -458,13 +450,13 @@ Scopy.using = function(options) { 'is', 'keys', 'values' - ], options) + ], options); - BoundScopy.for.all = BoundScopy.forAll - BoundScopy.using = Scopy.using + BoundScopy.for.all = BoundScopy.forAll; + BoundScopy.using = Scopy.using; - return BoundScopy -} + return BoundScopy; +}; /** * Returns the values of all of the specified object's own enumerable properties that are not scoped, in the same order @@ -479,30 +471,30 @@ Scopy.using = function(options) { * * @example *
- * var Scopy = require('scopy')
- * var uuid = require('uuid/v4')
+ * var Scopy = require('scopy');
+ * var uuid = require('uuid/v4');
  *
- * var _generateId = Scopy('generateId')
- * var _id = Scopy('id')
- * var _name = Scopy('name')
+ * var _generateId = Scopy('generateId');
+ * var _id = Scopy('id');
+ * var _name = Scopy('name');
  *
  * function User(name) {
- *   this[_id] = this[_generateId]()
- *   this[_name] = name
- *   this.length = name.length
+ *   this[_id] = this[_generateId]();
+ *   this[_name] = name;
+ *   this.length = name.length;
  * }
  *
  * User.prototype[_generateId] = function() {
- *   return uuid()
- * }
+ *   return uuid();
+ * };
  *
  * User.prototype.getName = function() {
- *   return this[_name]
- * }
+ *   return this[_name];
+ * };
  *
- * Scopy.values(new User('foo'))
+ * Scopy.values(new User('foo'));
  * //=> [ 3 ]
- * Scopy.values(User.prototype)
+ * Scopy.values(User.prototype);
  * //=> [ function() { return this[_name] } ]
  * 
* @param {Object} obj - the object whose enumerable own non-scoped property values are to be returned @@ -514,9 +506,9 @@ Scopy.using = function(options) { */ Scopy.values = function(obj, options) { return mapProperties(obj, function(value) { - return value - }, options) -} + return value; + }, options); +}; /** * Returns a function that delegates the call to the specified func so that the options @@ -531,10 +523,10 @@ Scopy.values = function(obj, options) { */ function applyOptions(func, options) { return function() { - var args = Array.prototype.slice.call(arguments, 0, 1) + var args = Array.prototype.slice.call(arguments, 0, 1); - return func.apply(null, args.concat(options)) - } + return func.apply(null, args.concat(options)); + }; } /** @@ -552,14 +544,9 @@ function applyOptions(func, options) { * @private */ function applyOptionsToAll(source, target, names, options) { - var length = names.length - var name - - for (var i = 0; i < length; i++) { - name = names[i] - - target[name] = applyOptions(source[name], options) - } + names.forEach(function(name) { + target[name] = applyOptions(source[name], options); + }); } /** @@ -573,15 +560,15 @@ function applyOptionsToAll(source, target, names, options) { * @private */ function getKeyFactory(global, options) { - options = parseOptions(options) + options = parseOptions(options); if (options.symbol) { - return global ? Symbol.for : Symbol + return global ? Symbol.for : Symbol; } return function(name) { - return '_' + name - } + return '_' + name; + }; } /** @@ -598,17 +585,17 @@ function getKeyFactory(global, options) { * @private */ function mapProperties(obj, mapper, options) { - options = parseOptions(options) + options = parseOptions(options); - var result = [] + var result = []; for (var name in obj) { if (Object.prototype.hasOwnProperty.call(obj, name) && (options.symbol || name[0] !== '_')) { - result.push(mapper(obj[name], name)) + result.push(mapper(obj[name], name)); } } - return result + return result; } /** @@ -621,15 +608,15 @@ function mapProperties(obj, mapper, options) { */ function parseOptions(options) { if (options == null) { - options = {} + options = {}; } - var symbol = options.symbol !== false && typeof Symbol === 'function' + var symbol = options.symbol !== false && typeof Symbol === 'function'; - return { symbol: symbol } + return { symbol: symbol }; } -module.exports = Scopy +module.exports = Scopy; /** * Returns a scoped or "global" key based on the specified name. @@ -646,6 +633,7 @@ module.exports = Scopy * @property {boolean} [symbol=true] - true if ES2015's Symbol should be used, where possible; * otherwise false. */ + /** * Returns a single value derived from the non-scoped property name and value provided. * diff --git a/test/scopy.spec.js b/test/scopy.spec.js index 0779158..5f191cd 100644 --- a/test/scopy.spec.js +++ b/test/scopy.spec.js @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Alasdair Mercer, Skelp + * Copyright (C) 2017 Alasdair Mercer, !ninja * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -20,124 +20,124 @@ * SOFTWARE. */ -'use strict' +'use strict'; -var expect = require('chai').expect +var expect = require('chai').expect; -var Scopy = require('../src/scopy') +var Scopy = require('../src/scopy'); describe('Scopy', function() { - var Test + var Test; before(function() { Test = function() { - this.foo = true - this.bar = 123 - this._fu = 'Hello' - this[Symbol('baz')] = 'World' - } + this.foo = true; + this.bar = 123; + this._fu = 'Hello'; + this[Symbol('baz')] = 'World'; + }; Test.prototype.fizz = function() { - return 'buzz' - } - }) + return 'buzz'; + }; + }); it('should be a function', function() { - expect(Scopy).to.be.a('function') - }) + expect(Scopy).to.be.a('function'); + }); context('when instantiated', function() { it('should throw an error', function() { expect(function() { - return new Scopy('foo') - }).to.throw(TypeError, 'Scopy is not a constructor') - }) - }) + return new Scopy('foo'); + }).to.throw(TypeError, 'Scopy is not a constructor'); + }); + }); context('when no options are provided', function() { it('should use symbols', function() { - expect(Scopy('foo')).to.be.a('symbol') - }) - }) + expect(Scopy('foo')).to.be.a('symbol'); + }); + }); context('when "symbol" option is enabled', function() { it('should return symbol for specified name', function() { - var key1 = Scopy('foo', { symbol: true }) - var key2 = Scopy('bar', { symbol: true }) + var key1 = Scopy('foo', { symbol: true }); + var key2 = Scopy('bar', { symbol: true }); - expect(key1).to.be.a('symbol') - expect(getSymbolDescription(key1)).to.equal('foo') - expect(key2).to.be.a('symbol') - expect(getSymbolDescription(key2)).to.equal('bar') - expect(key1).to.not.equal(key2) - }) + expect(key1).to.be.a('symbol'); + expect(getSymbolDescription(key1)).to.equal('foo'); + expect(key2).to.be.a('symbol'); + expect(getSymbolDescription(key2)).to.equal('bar'); + expect(key1).to.not.equal(key2); + }); it('should return unique symbol for same name', function() { - var key1 = Scopy('foo', { symbol: true }) - var key2 = Scopy('foo', { symbol: true }) + var key1 = Scopy('foo', { symbol: true }); + var key2 = Scopy('foo', { symbol: true }); - expect(key1).to.not.equal(key2) - }) - }) + expect(key1).to.not.equal(key2); + }); + }); context('when "symbol" option is disabled', function() { it('should return specified name with underscore prefix', function() { - var key1 = Scopy('foo', { symbol: false }) - var key2 = Scopy('bar', { symbol: false }) + var key1 = Scopy('foo', { symbol: false }); + var key2 = Scopy('bar', { symbol: false }); - expect(key1).to.equal('_foo') - expect(key2).to.equal('_bar') - }) - }) + expect(key1).to.equal('_foo'); + expect(key2).to.equal('_bar'); + }); + }); describe('.all', function() { context('when no names are provided', function() { it('should return an empty array', function() { - expect(Scopy.all()).to.be.empty - }) - }) + expect(Scopy.all()).to.be.empty; + }); + }); context('when no options are provided', function() { it('should use symbols (where possible)', function() { - var keys = Scopy.all([ 'foo', 'bar' ]) + var keys = Scopy.all([ 'foo', 'bar' ]); - expect(keys).to.have.all.keys([ 'foo', 'bar' ]) - expect(keys.foo).to.be.a('symbol') - expect(keys.bar).to.be.a('symbol') - }) - }) + expect(keys).to.have.all.keys([ 'foo', 'bar' ]); + expect(keys.foo).to.be.a('symbol'); + expect(keys.bar).to.be.a('symbol'); + }); + }); context('when "symbol" option is enabled', function() { it('should return object containing symbols mapped to each of specified names', function() { - var keys = Scopy.all([ 'foo', 'bar', 'foo' ], { symbol: true }) + var keys = Scopy.all([ 'foo', 'bar', 'foo' ], { symbol: true }); - expect(keys).to.have.all.keys([ 'foo', 'bar' ]) - expect(keys.foo).to.be.a('symbol') - expect(getSymbolDescription(keys.foo)).to.equal('foo') - expect(keys.bar).to.be.a('symbol') - expect(getSymbolDescription(keys.bar)).to.equal('bar') - expect(keys.foo).to.not.equal(keys.bar) - }) + expect(keys).to.have.all.keys([ 'foo', 'bar' ]); + expect(keys.foo).to.be.a('symbol'); + expect(getSymbolDescription(keys.foo)).to.equal('foo'); + expect(keys.bar).to.be.a('symbol'); + expect(getSymbolDescription(keys.bar)).to.equal('bar'); + expect(keys.foo).to.not.equal(keys.bar); + }); it('should return object containing unique symbols mapped to same names', function() { - var keys1 = Scopy.all([ 'foo', 'bar' ], { symbol: true }) - var keys2 = Scopy.all([ 'foo', 'bar' ], { symbol: true }) + var keys1 = Scopy.all([ 'foo', 'bar' ], { symbol: true }); + var keys2 = Scopy.all([ 'foo', 'bar' ], { symbol: true }); - expect(keys1.foo).to.not.equal(keys2.foo) - expect(keys1.bar).to.not.equal(keys2.bar) - }) - }) + expect(keys1.foo).to.not.equal(keys2.foo); + expect(keys1.bar).to.not.equal(keys2.bar); + }); + }); context('when "symbol" option is disabled', function() { it('should return object containing names with underscore prefixes mapped to specified names', function() { - var keys = Scopy.all([ 'foo', 'bar', 'foo' ], { symbol: false }) + var keys = Scopy.all([ 'foo', 'bar', 'foo' ], { symbol: false }); - expect(keys).to.have.all.keys([ 'foo', 'bar' ]) - expect(keys.foo).to.equal('_foo') - expect(keys.bar).to.equal('_bar') - }) - }) - }) + expect(keys).to.have.all.keys([ 'foo', 'bar' ]); + expect(keys.foo).to.equal('_foo'); + expect(keys.bar).to.equal('_bar'); + }); + }); + }); describe('.entries', function() { context('when no options are provided', function() { @@ -146,19 +146,19 @@ describe('Scopy', function() { foo: true, bar: 123, _fu: 'Hello' - } + }; - var entries = Scopy.entries(new Test()) + var entries = Scopy.entries(new Test()); - expect(entries).to.have.lengthOf(3) - expect(expectedValues).to.have.ownProperty(entries[0][0]) - expect(expectedValues[entries[0][0]]).to.equal(entries[0][1]) - expect(expectedValues).to.have.ownProperty(entries[1][0]) - expect(expectedValues[entries[1][0]]).to.equal(entries[1][1]) - expect(expectedValues).to.have.ownProperty(entries[2][0]) - expect(expectedValues[entries[2][0]]).to.equal(entries[2][1]) - }) - }) + expect(entries).to.have.lengthOf(3); + expect(expectedValues).to.have.ownProperty(entries[0][0]); + expect(expectedValues[entries[0][0]]).to.equal(entries[0][1]); + expect(expectedValues).to.have.ownProperty(entries[1][0]); + expect(expectedValues[entries[1][0]]).to.equal(entries[1][1]); + expect(expectedValues).to.have.ownProperty(entries[2][0]); + expect(expectedValues[entries[2][0]]).to.equal(entries[2][1]); + }); + }); context('when "symbol" option is enabled', function() { it('should return entries for all of specified object\'s properties', function() { @@ -166,432 +166,432 @@ describe('Scopy', function() { foo: true, bar: 123, _fu: 'Hello' - } + }; - var entries = Scopy.entries(new Test(), { symbol: true }) + var entries = Scopy.entries(new Test(), { symbol: true }); - expect(entries).to.have.lengthOf(3) - expect(expectedValues).to.have.ownProperty(entries[0][0]) - expect(expectedValues[entries[0][0]]).to.equal(entries[0][1]) - expect(expectedValues).to.have.ownProperty(entries[1][0]) - expect(expectedValues[entries[1][0]]).to.equal(entries[1][1]) - expect(expectedValues).to.have.ownProperty(entries[2][0]) - expect(expectedValues[entries[2][0]]).to.equal(entries[2][1]) - }) - }) + expect(entries).to.have.lengthOf(3); + expect(expectedValues).to.have.ownProperty(entries[0][0]); + expect(expectedValues[entries[0][0]]).to.equal(entries[0][1]); + expect(expectedValues).to.have.ownProperty(entries[1][0]); + expect(expectedValues[entries[1][0]]).to.equal(entries[1][1]); + expect(expectedValues).to.have.ownProperty(entries[2][0]); + expect(expectedValues[entries[2][0]]).to.equal(entries[2][1]); + }); + }); context('when "symbol" option is disabled', function() { it('should only return entries for specified object\'s properties without underscore prefix', function() { var expectedValues = { foo: true, bar: 123 - } + }; - var entries = Scopy.entries(new Test(), { symbol: false }) + var entries = Scopy.entries(new Test(), { symbol: false }); - expect(entries).to.have.lengthOf(2) - expect(expectedValues).to.have.ownProperty(entries[0][0]) - expect(expectedValues[entries[0][0]]).to.equal(entries[0][1]) - expect(expectedValues).to.have.ownProperty(entries[1][0]) - expect(expectedValues[entries[1][0]]).to.equal(entries[1][1]) - }) - }) - }) + expect(entries).to.have.lengthOf(2); + expect(expectedValues).to.have.ownProperty(entries[0][0]); + expect(expectedValues[entries[0][0]]).to.equal(entries[0][1]); + expect(expectedValues).to.have.ownProperty(entries[1][0]); + expect(expectedValues[entries[1][0]]).to.equal(entries[1][1]); + }); + }); + }); describe('.for', function() { - var counter = 0 - var namePrefix + var counter = 0; + var namePrefix; beforeEach(function() { - counter++ - namePrefix = 'for.t' + counter + '.' - }) + counter++; + namePrefix = 'for.t' + counter + '.'; + }); context('when no options are provided', function() { it('should use symbols', function() { - var foo = namePrefix + 'foo' + var foo = namePrefix + 'foo'; - expect(Scopy.for(foo)).to.be.a('symbol') - }) - }) + expect(Scopy.for(foo)).to.be.a('symbol'); + }); + }); context('when "symbol" option is enabled', function() { it('should return symbol for specified name', function() { - var foo = namePrefix + 'foo' - var bar = namePrefix + 'bar' + var foo = namePrefix + 'foo'; + var bar = namePrefix + 'bar'; - var key1 = Scopy.for(foo, { symbol: true }) - var key2 = Scopy.for(bar, { symbol: true }) + var key1 = Scopy.for(foo, { symbol: true }); + var key2 = Scopy.for(bar, { symbol: true }); - expect(key1).to.be.a('symbol') - expect(getSymbolDescription(key1)).to.equal(foo) - expect(key2).to.be.a('symbol') - expect(getSymbolDescription(key2)).to.equal(bar) - expect(key1).to.not.equal(key2) - }) + expect(key1).to.be.a('symbol'); + expect(getSymbolDescription(key1)).to.equal(foo); + expect(key2).to.be.a('symbol'); + expect(getSymbolDescription(key2)).to.equal(bar); + expect(key1).to.not.equal(key2); + }); it('should return same symbol for same name', function() { - var foo = namePrefix + 'foo' + var foo = namePrefix + 'foo'; - var key1 = Scopy.for(foo, { symbol: true }) - var key2 = Scopy.for(foo, { symbol: true }) + var key1 = Scopy.for(foo, { symbol: true }); + var key2 = Scopy.for(foo, { symbol: true }); - expect(key1).to.equal(key2) - }) - }) + expect(key1).to.equal(key2); + }); + }); context('when "symbol" option is disabled', function() { it('should return specified name with underscore prefix', function() { - var foo = namePrefix + 'foo' - var bar = namePrefix + 'bar' + var foo = namePrefix + 'foo'; + var bar = namePrefix + 'bar'; - var key1 = Scopy.for(foo, { symbol: false }) - var key2 = Scopy.for(bar, { symbol: false }) + var key1 = Scopy.for(foo, { symbol: false }); + var key2 = Scopy.for(bar, { symbol: false }); - expect(key1).to.equal('_' + foo) - expect(key2).to.equal('_' + bar) - }) - }) - }) + expect(key1).to.equal('_' + foo); + expect(key2).to.equal('_' + bar); + }); + }); + }); describe('.for.all', function() { - var counter = 0 - var namePrefix + var counter = 0; + var namePrefix; beforeEach(function() { - counter++ - namePrefix = 'for.all.t' + counter + '.' - }) + counter++; + namePrefix = 'for.all.t' + counter + '.'; + }); context('when no names are provided', function() { it('should return an empty array', function() { - expect(Scopy.for.all()).to.be.empty - }) - }) + expect(Scopy.for.all()).to.be.empty; + }); + }); context('when no options are provided', function() { it('should use symbols (where possible)', function() { - var foo = namePrefix + 'foo' - var bar = namePrefix + 'bar' + var foo = namePrefix + 'foo'; + var bar = namePrefix + 'bar'; - var keys = Scopy.for.all([ foo, bar, foo ]) + var keys = Scopy.for.all([ foo, bar, foo ]); - expect(keys).to.have.all.keys([ foo, bar ]) - expect(keys[foo]).to.be.a('symbol') - expect(keys[bar]).to.be.a('symbol') - }) - }) + expect(keys).to.have.all.keys([ foo, bar ]); + expect(keys[foo]).to.be.a('symbol'); + expect(keys[bar]).to.be.a('symbol'); + }); + }); context('when "symbol" option is enabled', function() { it('should return object containing symbols mapped to each of specified names', function() { - var foo = namePrefix + 'foo' - var bar = namePrefix + 'bar' + var foo = namePrefix + 'foo'; + var bar = namePrefix + 'bar'; - var keys = Scopy.for.all([ foo, bar, foo ], { symbol: true }) + var keys = Scopy.for.all([ foo, bar, foo ], { symbol: true }); - expect(keys).to.have.all.keys([ foo, bar ]) - expect(keys[foo]).to.be.a('symbol') - expect(getSymbolDescription(keys[foo])).to.equal(foo) - expect(keys[bar]).to.be.a('symbol') - expect(getSymbolDescription(keys[bar])).to.equal(bar) - expect(keys[foo]).to.not.equal(keys[bar]) - }) + expect(keys).to.have.all.keys([ foo, bar ]); + expect(keys[foo]).to.be.a('symbol'); + expect(getSymbolDescription(keys[foo])).to.equal(foo); + expect(keys[bar]).to.be.a('symbol'); + expect(getSymbolDescription(keys[bar])).to.equal(bar); + expect(keys[foo]).to.not.equal(keys[bar]); + }); it('should return object containing same symbols mapped to same names', function() { - var foo = namePrefix + 'foo' - var bar = namePrefix + 'bar' + var foo = namePrefix + 'foo'; + var bar = namePrefix + 'bar'; - var keys1 = Scopy.for.all([ foo, bar ], { symbol: true }) - var keys2 = Scopy.for.all([ foo, bar ], { symbol: true }) + var keys1 = Scopy.for.all([ foo, bar ], { symbol: true }); + var keys2 = Scopy.for.all([ foo, bar ], { symbol: true }); - expect(keys1[foo]).to.equal(keys2[foo]) - expect(keys1[bar]).to.equal(keys2[bar]) - }) - }) + expect(keys1[foo]).to.equal(keys2[foo]); + expect(keys1[bar]).to.equal(keys2[bar]); + }); + }); context('when "symbol" option is disabled', function() { it('should return object containing names with underscore prefixes mapped to specified names', function() { - var foo = namePrefix + 'foo' - var bar = namePrefix + 'bar' + var foo = namePrefix + 'foo'; + var bar = namePrefix + 'bar'; - var keys = Scopy.for.all([ foo, bar, foo ], { symbol: false }) + var keys = Scopy.for.all([ foo, bar, foo ], { symbol: false }); - expect(keys).to.have.all.keys([ foo, bar ]) - expect(keys[foo]).to.equal('_' + foo) - expect(keys[bar]).to.equal('_' + bar) - }) - }) - }) + expect(keys).to.have.all.keys([ foo, bar ]); + expect(keys[foo]).to.equal('_' + foo); + expect(keys[bar]).to.equal('_' + bar); + }); + }); + }); describe('.forAll', function() { it('should be an alias for Scopy.for.all', function() { - expect(Scopy.forAll).to.equal(Scopy.for.all) - }) - }) + expect(Scopy.forAll).to.equal(Scopy.for.all); + }); + }); describe('.is', function() { context('when no options are provided', function() { it('should use symbols', function() { - expect(Scopy.is(Symbol())).to.be.true - }) - }) + expect(Scopy.is(Symbol())).to.be.true; + }); + }); context('when no specified object is null', function() { it('should return false', function() { - expect(Scopy.is(null)).to.be.false - }) - }) + expect(Scopy.is(null)).to.be.false; + }); + }); context('when "symbol" option is enabled', function() { context('and specified object is a symbol', function() { it('should return true', function() { - expect(Scopy.is(Symbol('foo'), { symbol: true })).to.be.true - }) - }) + expect(Scopy.is(Symbol('foo'), { symbol: true })).to.be.true; + }); + }); context('and specified object is not a symbol', function() { it('should return false', function() { - expect(Scopy.is('', { symbol: true })).to.be.false - expect(Scopy.is('foo', { symbol: true })).to.be.false - expect(Scopy.is('_foo', { symbol: true })).to.be.false - expect(Scopy.is('__foo', { symbol: true })).to.be.false - expect(Scopy.is('_foo_', { symbol: true })).to.be.false - expect(Scopy.is('foo_', { symbol: true })).to.be.false - }) - }) - }) + expect(Scopy.is('', { symbol: true })).to.be.false; + expect(Scopy.is('foo', { symbol: true })).to.be.false; + expect(Scopy.is('_foo', { symbol: true })).to.be.false; + expect(Scopy.is('__foo', { symbol: true })).to.be.false; + expect(Scopy.is('_foo_', { symbol: true })).to.be.false; + expect(Scopy.is('foo_', { symbol: true })).to.be.false; + }); + }); + }); context('when "symbol" option is disabled', function() { context('and specified object is a string with an underscore prefix', function() { it('should return true', function() { - expect(Scopy.is('_foo', { symbol: false })).to.be.true - expect(Scopy.is('__foo', { symbol: false })).to.be.true - expect(Scopy.is('_foo_', { symbol: false })).to.be.true - }) - }) + expect(Scopy.is('_foo', { symbol: false })).to.be.true; + expect(Scopy.is('__foo', { symbol: false })).to.be.true; + expect(Scopy.is('_foo_', { symbol: false })).to.be.true; + }); + }); context('and specified object is a string without an underscore prefix', function() { it('should return false', function() { - expect(Scopy.is('', { symbol: false })).to.be.false - expect(Scopy.is('foo', { symbol: false })).to.be.false - expect(Scopy.is('foo_', { symbol: false })).to.be.false - expect(Scopy.is(' _foo', { symbol: false })).to.be.false - }) - }) + expect(Scopy.is('', { symbol: false })).to.be.false; + expect(Scopy.is('foo', { symbol: false })).to.be.false; + expect(Scopy.is('foo_', { symbol: false })).to.be.false; + expect(Scopy.is(' _foo', { symbol: false })).to.be.false; + }); + }); context('and specified object is not a string', function() { it('should return false', function() { - expect(Scopy.is(Symbol('foo'), { symbol: false })).to.be.false - }) - }) - }) - }) + expect(Scopy.is(Symbol('foo'), { symbol: false })).to.be.false; + }); + }); + }); + }); describe('.keys', function() { context('when no options are provided', function() { it('should use symbols (where possible)', function() { - var keys = Scopy.keys(new Test()) + var keys = Scopy.keys(new Test()); - expect(keys).to.have.lengthOf(3) - expect(keys).to.include('foo') - expect(keys).to.include('bar') - expect(keys).to.include('_fu') - }) - }) + expect(keys).to.have.lengthOf(3); + expect(keys).to.include('foo'); + expect(keys).to.include('bar'); + expect(keys).to.include('_fu'); + }); + }); context('when "symbol" option is enabled', function() { it('should return names of all of specified object\'s properties', function() { - var keys = Scopy.keys(new Test(), { symbol: true }) + var keys = Scopy.keys(new Test(), { symbol: true }); - expect(keys).to.have.lengthOf(3) - expect(keys).to.include('foo') - expect(keys).to.include('bar') - expect(keys).to.include('_fu') - }) - }) + expect(keys).to.have.lengthOf(3); + expect(keys).to.include('foo'); + expect(keys).to.include('bar'); + expect(keys).to.include('_fu'); + }); + }); context('when "symbol" option is disabled', function() { it('should only return names of specified object\'s properties without underscore prefix', function() { - var keys = Scopy.keys(new Test(), { symbol: false }) + var keys = Scopy.keys(new Test(), { symbol: false }); - expect(keys).to.have.lengthOf(2) - expect(keys).to.include('foo') - expect(keys).to.include('bar') - }) - }) - }) + expect(keys).to.have.lengthOf(2); + expect(keys).to.include('foo'); + expect(keys).to.include('bar'); + }); + }); + }); describe('.using', function() { - var BoundScopy - var counter = 0 - var namePrefix + var BoundScopy; + var counter = 0; + var namePrefix; beforeEach(function() { - counter++ - namePrefix = 'using.t' + counter + '.' - }) + counter++; + namePrefix = 'using.t' + counter + '.'; + }); context('when no options are provided', function() { before(function() { - BoundScopy = Scopy.using() - }) + BoundScopy = Scopy.using(); + }); it('should use symbols (where possible)', function() { - var foo = namePrefix + 'foo' - var bar = namePrefix + 'bar' + var foo = namePrefix + 'foo'; + var bar = namePrefix + 'bar'; var expectedValues = { foo: true, bar: 123, _fu: 'Hello' - } + }; - expect(BoundScopy('foo')).to.be.a('symbol') + expect(BoundScopy('foo')).to.be.a('symbol'); - var scopedKeys = BoundScopy.all([ 'foo', 'bar' ]) + var scopedKeys = BoundScopy.all([ 'foo', 'bar' ]); - expect(scopedKeys).to.have.all.keys([ 'foo', 'bar' ]) - expect(scopedKeys.foo).to.be.a('symbol') - expect(scopedKeys.bar).to.be.a('symbol') + expect(scopedKeys).to.have.all.keys([ 'foo', 'bar' ]); + expect(scopedKeys.foo).to.be.a('symbol'); + expect(scopedKeys.bar).to.be.a('symbol'); - expect(BoundScopy.for(foo)).to.be.a('symbol') + expect(BoundScopy.for(foo)).to.be.a('symbol'); - var globalKeys = BoundScopy.for.all([ foo, bar ]) + var globalKeys = BoundScopy.for.all([ foo, bar ]); - expect(globalKeys).to.have.all.keys([ foo, bar ]) - expect(globalKeys[foo]).to.be.a('symbol') - expect(globalKeys[bar]).to.be.a('symbol') + expect(globalKeys).to.have.all.keys([ foo, bar ]); + expect(globalKeys[foo]).to.be.a('symbol'); + expect(globalKeys[bar]).to.be.a('symbol'); - expect(globalKeys).to.deep.equal(BoundScopy.forAll([ foo, bar ])) + expect(globalKeys).to.deep.equal(BoundScopy.forAll([ foo, bar ])); - expect(BoundScopy.is(Symbol('foo'))).to.be.true - expect(BoundScopy.is('_foo')).to.be.false + expect(BoundScopy.is(Symbol('foo'))).to.be.true; + expect(BoundScopy.is('_foo')).to.be.false; - var entries = BoundScopy.entries(new Test()) + var entries = BoundScopy.entries(new Test()); - expect(entries).to.have.lengthOf(3) - expect(expectedValues).to.have.ownProperty(entries[0][0]) - expect(expectedValues[entries[0][0]]).to.equal(entries[0][1]) - expect(expectedValues).to.have.ownProperty(entries[1][0]) - expect(expectedValues[entries[1][0]]).to.equal(entries[1][1]) - expect(expectedValues).to.have.ownProperty(entries[2][0]) - expect(expectedValues[entries[2][0]]).to.equal(entries[2][1]) + expect(entries).to.have.lengthOf(3); + expect(expectedValues).to.have.ownProperty(entries[0][0]); + expect(expectedValues[entries[0][0]]).to.equal(entries[0][1]); + expect(expectedValues).to.have.ownProperty(entries[1][0]); + expect(expectedValues[entries[1][0]]).to.equal(entries[1][1]); + expect(expectedValues).to.have.ownProperty(entries[2][0]); + expect(expectedValues[entries[2][0]]).to.equal(entries[2][1]); - var keys = BoundScopy.keys(new Test()) + var keys = BoundScopy.keys(new Test()); - expect(keys).to.have.lengthOf(3) - expect(keys).to.include('foo') - expect(keys).to.include('bar') - expect(keys).to.include('_fu') + expect(keys).to.have.lengthOf(3); + expect(keys).to.include('foo'); + expect(keys).to.include('bar'); + expect(keys).to.include('_fu'); - var values = BoundScopy.values(new Test()) + var values = BoundScopy.values(new Test()); - expect(values).to.have.lengthOf(3) - expect(values).to.include(true) - expect(values).to.include(123) - expect(values).to.include('Hello') + expect(values).to.have.lengthOf(3); + expect(values).to.include(true); + expect(values).to.include(123); + expect(values).to.include('Hello'); - expect(BoundScopy.using({ symbol: false })('foo')).to.equal('_foo') - }) + expect(BoundScopy.using({ symbol: false })('foo')).to.equal('_foo'); + }); it('should ignore any options passed to methods', function() { - expect(BoundScopy('foo', { symbol: false })).to.be.a('symbol') - }) - }) + expect(BoundScopy('foo', { symbol: false })).to.be.a('symbol'); + }); + }); context('when options are provided', function() { before(function() { - BoundScopy = Scopy.using({ symbol: false }) - }) + BoundScopy = Scopy.using({ symbol: false }); + }); it('should apply options to all methods', function() { - var foo = namePrefix + 'foo' - var bar = namePrefix + 'bar' + var foo = namePrefix + 'foo'; + var bar = namePrefix + 'bar'; var expectedValues = { foo: true, bar: 123 - } + }; - expect(BoundScopy('foo')).to.equal('_foo') + expect(BoundScopy('foo')).to.equal('_foo'); expect(BoundScopy.all([ 'foo', 'bar' ])).to.deep.equal({ foo: '_foo', bar: '_bar' - }) - expect(BoundScopy.for(foo)).to.equal('_' + foo) + }); + expect(BoundScopy.for(foo)).to.equal('_' + foo); - var globalKeys = BoundScopy.for.all([ foo, bar ]) + var globalKeys = BoundScopy.for.all([ foo, bar ]); - expect(globalKeys[foo]).to.equal('_' + foo) - expect(globalKeys[bar]).to.equal('_' + bar) + expect(globalKeys[foo]).to.equal('_' + foo); + expect(globalKeys[bar]).to.equal('_' + bar); - expect(globalKeys).to.deep.equal(BoundScopy.forAll([ foo, bar ])) + expect(globalKeys).to.deep.equal(BoundScopy.forAll([ foo, bar ])); - expect(BoundScopy.is('_foo')).to.be.true - expect(BoundScopy.is(Symbol('foo'))).to.be.false + expect(BoundScopy.is('_foo')).to.be.true; + expect(BoundScopy.is(Symbol('foo'))).to.be.false; - var entries = BoundScopy.entries(new Test()) + var entries = BoundScopy.entries(new Test()); - expect(entries).to.have.lengthOf(2) - expect(expectedValues).to.have.ownProperty(entries[0][0]) - expect(expectedValues[entries[0][0]]).to.equal(entries[0][1]) - expect(expectedValues).to.have.ownProperty(entries[1][0]) - expect(expectedValues[entries[1][0]]).to.equal(entries[1][1]) + expect(entries).to.have.lengthOf(2); + expect(expectedValues).to.have.ownProperty(entries[0][0]); + expect(expectedValues[entries[0][0]]).to.equal(entries[0][1]); + expect(expectedValues).to.have.ownProperty(entries[1][0]); + expect(expectedValues[entries[1][0]]).to.equal(entries[1][1]); - var keys = BoundScopy.keys(new Test()) + var keys = BoundScopy.keys(new Test()); - expect(keys).to.have.lengthOf(2) - expect(keys).to.include('foo') - expect(keys).to.include('bar') + expect(keys).to.have.lengthOf(2); + expect(keys).to.include('foo'); + expect(keys).to.include('bar'); - var values = BoundScopy.values(new Test()) + var values = BoundScopy.values(new Test()); - expect(values).to.have.lengthOf(2) - expect(values).to.include(true) - expect(values).to.include(123) + expect(values).to.have.lengthOf(2); + expect(values).to.include(true); + expect(values).to.include(123); - expect(BoundScopy.using({ symbol: true })('foo')).to.be.a('symbol') - }) + expect(BoundScopy.using({ symbol: true })('foo')).to.be.a('symbol'); + }); it('should ignore any options passed to methods', function() { - expect(BoundScopy('foo', { symbol: true })).to.equal('_foo') - }) - }) - }) + expect(BoundScopy('foo', { symbol: true })).to.equal('_foo'); + }); + }); + }); describe('.values', function() { context('when no options are provided', function() { it('should use symbols (where possible)', function() { - var values = Scopy.values(new Test()) + var values = Scopy.values(new Test()); - expect(values).to.have.lengthOf(3) - expect(values).to.include(true) - expect(values).to.include(123) - expect(values).to.include('Hello') - }) - }) + expect(values).to.have.lengthOf(3); + expect(values).to.include(true); + expect(values).to.include(123); + expect(values).to.include('Hello'); + }); + }); context('when "symbol" option is enabled', function() { it('should return values of all of specified object\'s properties', function() { - var values = Scopy.values(new Test(), { symbol: true }) + var values = Scopy.values(new Test(), { symbol: true }); - expect(values).to.have.lengthOf(3) - expect(values).to.include(true) - expect(values).to.include(123) - expect(values).to.include('Hello') - }) - }) + expect(values).to.have.lengthOf(3); + expect(values).to.include(true); + expect(values).to.include(123); + expect(values).to.include('Hello'); + }); + }); context('when "symbol" option is disabled', function() { it('should only return values of specified object\'s properties without underscore prefix', function() { - var values = Scopy.values(new Test(), { symbol: false }) + var values = Scopy.values(new Test(), { symbol: false }); - expect(values).to.have.lengthOf(2) - expect(values).to.include(true) - expect(values).to.include(123) - }) - }) - }) + expect(values).to.have.lengthOf(2); + expect(values).to.include(true); + expect(values).to.include(123); + }); + }); + }); /** * Returns the description that was used for the specified symbol. @@ -601,8 +601,8 @@ describe('Scopy', function() { * @private */ function getSymbolDescription(symbol) { - var match = symbol.toString().match(/^Symbol\((.+)\)$/) + var match = symbol.toString().match(/^Symbol\((.+)\)$/); - return match && match[1] + return match && match[1]; } -}) +});