[Pkg-javascript-commits] [node-class-utils] 01/07: Import Upstream version 0.3.4
Sruthi Chandran
srud-guest at moszumanska.debian.org
Fri Oct 28 07:45:21 UTC 2016
This is an automated email from the git hooks/post-receive script.
srud-guest pushed a commit to branch master
in repository node-class-utils.
commit 5c354fde2e4527b8f4cfd6079253ae6b7441449b
Author: Sruthi <srud at disroot.org>
Date: Fri Oct 28 12:52:50 2016 +0530
Import Upstream version 0.3.4
---
.editorconfig | 22 +++
.eslintrc | 125 +++++++++++++++
.gitattributes | 10 ++
.gitignore | 15 ++
.travis.yml | 10 ++
.verb.md | 8 +
LICENSE | 21 +++
README.md | 285 ++++++++++++++++++++++++++++++++++
example.js | 9 ++
examples/a.js | 34 ++++
examples/app.js | 33 ++++
examples/b.js | 39 +++++
examples/c.js | 34 ++++
examples/meta.js | 6 +
fixtures/app.js | 22 +++
gulpfile.js | 63 ++++++++
index.js | 365 +++++++++++++++++++++++++++++++++++++++++++
package.json | 87 +++++++++++
test.js | 465 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
utils.js | 21 +++
20 files changed, 1674 insertions(+)
diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000..991900b
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,22 @@
+# http://editorconfig.org
+root = true
+
+[*]
+indent_style = space
+end_of_line = lf
+charset = utf-8
+indent_size = 2
+trim_trailing_whitespace = true
+insert_final_newline = true
+
+[*.md]
+trim_trailing_whitespace = false
+insert_final_newline = false
+
+[test/**]
+trim_trailing_whitespace = false
+insert_final_newline = false
+
+[templates/**]
+trim_trailing_whitespace = false
+insert_final_newline = false
diff --git a/.eslintrc b/.eslintrc
new file mode 100644
index 0000000..7b5d047
--- /dev/null
+++ b/.eslintrc
@@ -0,0 +1,125 @@
+{
+ "ecmaFeatures": {
+ "modules": true,
+ "experimentalObjectRestSpread": true
+ },
+
+ "env": {
+ "browser": false,
+ "es6": true,
+ "node": true,
+ "mocha": true
+ },
+
+ "globals": {
+ "document": false,
+ "navigator": false,
+ "window": false
+ },
+
+ "rules": {
+ "accessor-pairs": 2,
+ "arrow-spacing": [2, { "before": true, "after": true }],
+ "block-spacing": [2, "always"],
+ "brace-style": [2, "1tbs", { "allowSingleLine": true }],
+ "comma-dangle": [2, "never"],
+ "comma-spacing": [2, { "before": false, "after": true }],
+ "comma-style": [2, "last"],
+ "constructor-super": 2,
+ "curly": [2, "multi-line"],
+ "dot-location": [2, "property"],
+ "eol-last": 2,
+ "eqeqeq": [2, "allow-null"],
+ "generator-star-spacing": [2, { "before": true, "after": true }],
+ "handle-callback-err": [2, "^(err|error)$" ],
+ "indent": [2, 2, { "SwitchCase": 1 }],
+ "key-spacing": [2, { "beforeColon": false, "afterColon": true }],
+ "new-cap": [2, { "newIsCap": true, "capIsNew": false }],
+ "new-parens": 2,
+ "no-array-constructor": 2,
+ "no-caller": 2,
+ "no-class-assign": 2,
+ "no-cond-assign": 2,
+ "no-const-assign": 2,
+ "no-control-regex": 2,
+ "no-debugger": 2,
+ "no-delete-var": 2,
+ "no-dupe-args": 2,
+ "no-dupe-class-members": 2,
+ "no-dupe-keys": 2,
+ "no-duplicate-case": 2,
+ "no-empty-character-class": 2,
+ "no-empty-label": 2,
+ "no-eval": 2,
+ "no-ex-assign": 2,
+ "no-extend-native": 2,
+ "no-extra-bind": 2,
+ "no-extra-boolean-cast": 2,
+ "no-extra-parens": [2, "functions"],
+ "no-fallthrough": 2,
+ "no-floating-decimal": 2,
+ "no-func-assign": 2,
+ "no-implied-eval": 2,
+ "no-inner-declarations": [2, "functions"],
+ "no-invalid-regexp": 2,
+ "no-irregular-whitespace": 2,
+ "no-iterator": 2,
+ "no-label-var": 2,
+ "no-labels": 2,
+ "no-lone-blocks": 2,
+ "no-mixed-spaces-and-tabs": 2,
+ "no-multi-spaces": 2,
+ "no-multi-str": 2,
+ "no-multiple-empty-lines": [2, { "max": 1 }],
+ "no-native-reassign": 2,
+ "no-negated-in-lhs": 2,
+ "no-new": 2,
+ "no-new-func": 2,
+ "no-new-object": 2,
+ "no-new-require": 2,
+ "no-new-wrappers": 2,
+ "no-obj-calls": 2,
+ "no-octal": 2,
+ "no-octal-escape": 2,
+ "no-proto": 0,
+ "no-redeclare": 2,
+ "no-regex-spaces": 2,
+ "no-return-assign": 2,
+ "no-self-compare": 2,
+ "no-sequences": 2,
+ "no-shadow-restricted-names": 2,
+ "no-spaced-func": 2,
+ "no-sparse-arrays": 2,
+ "no-this-before-super": 2,
+ "no-throw-literal": 2,
+ "no-trailing-spaces": 0,
+ "no-undef": 2,
+ "no-undef-init": 2,
+ "no-unexpected-multiline": 2,
+ "no-unneeded-ternary": [2, { "defaultAssignment": false }],
+ "no-unreachable": 2,
+ "no-unused-vars": [2, { "vars": "all", "args": "none" }],
+ "no-useless-call": 0,
+ "no-with": 2,
+ "one-var": [0, { "initialized": "never" }],
+ "operator-linebreak": [0, "after", { "overrides": { "?": "before", ":": "before" } }],
+ "padded-blocks": [0, "never"],
+ "quotes": [2, "single", "avoid-escape"],
+ "radix": 2,
+ "semi": [2, "always"],
+ "semi-spacing": [2, { "before": false, "after": true }],
+ "space-after-keywords": [2, "always"],
+ "space-before-blocks": [2, "always"],
+ "space-before-function-paren": [2, "never"],
+ "space-before-keywords": [2, "always"],
+ "space-in-parens": [2, "never"],
+ "space-infix-ops": 2,
+ "space-return-throw-case": 2,
+ "space-unary-ops": [2, { "words": true, "nonwords": false }],
+ "spaced-comment": [0, "always", { "markers": ["global", "globals", "eslint", "eslint-disable", "*package", "!", ","] }],
+ "use-isnan": 2,
+ "valid-typeof": 2,
+ "wrap-iife": [2, "any"],
+ "yoda": [2, "never"]
+ }
+}
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..660957e
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,10 @@
+# Enforce Unix newlines
+* text eol=lf
+
+# binaries
+*.ai binary
+*.psd binary
+*.jpg binary
+*.gif binary
+*.png binary
+*.jpeg binary
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..80a228c
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,15 @@
+*.DS_Store
+*.sublime-*
+_gh_pages
+bower_components
+node_modules
+npm-debug.log
+actual
+test/actual
+temp
+tmp
+TODO.md
+vendor
+.idea
+benchmark
+coverage
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..d6e658e
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,10 @@
+sudo: false
+language: node_js
+node_js:
+ - "stable"
+ - "0.12"
+ - "0.10"
+matrix:
+ fast_finish: true
+ allow_failures:
+ - node_js: "0.10"
diff --git a/.verb.md b/.verb.md
new file mode 100644
index 0000000..0018001
--- /dev/null
+++ b/.verb.md
@@ -0,0 +1,8 @@
+## Usage
+
+```js
+var cu = require('{%= name %}');
+```
+
+## API
+{%= apidocs('index.js') %}
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..65f90ac
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2015, Jon Schlinkert.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..41b72f6
--- /dev/null
+++ b/README.md
@@ -0,0 +1,285 @@
+# class-utils [![NPM version](https://img.shields.io/npm/v/class-utils.svg?style=flat)](https://www.npmjs.com/package/class-utils) [![NPM downloads](https://img.shields.io/npm/dm/class-utils.svg?style=flat)](https://npmjs.org/package/class-utils) [![Build Status](https://img.shields.io/travis/jonschlinkert/class-utils.svg?style=flat)](https://travis-ci.org/jonschlinkert/class-utils)
+
+> Utils for working with JavaScript classes and prototype methods.
+
+## Install
+
+Install with [npm](https://www.npmjs.com/):
+
+```sh
+$ npm install class-utils --save
+```
+
+## Usage
+
+```js
+var cu = require('class-utils');
+```
+
+## API
+
+### [.has](index.js#L40)
+
+Returns true if an array has any of the given elements, or an object has any of the give keys.
+
+**Params**
+
+* `obj` **{Object}**
+* `val` **{String|Array}**
+* `returns` **{Boolean}**
+
+**Example**
+
+```js
+cu.has(['a', 'b', 'c'], 'c');
+//=> true
+
+cu.has(['a', 'b', 'c'], ['c', 'z']);
+//=> true
+
+cu.has({a: 'b', c: 'd'}, ['c', 'z']);
+//=> true
+```
+
+### [.hasAll](index.js#L87)
+
+Returns true if an array or object has all of the given values.
+
+**Params**
+
+* `val` **{Object|Array}**
+* `values` **{String|Array}**
+* `returns` **{Boolean}**
+
+**Example**
+
+```js
+cu.hasAll(['a', 'b', 'c'], 'c');
+//=> true
+
+cu.hasAll(['a', 'b', 'c'], ['c', 'z']);
+//=> false
+
+cu.hasAll({a: 'b', c: 'd'}, ['c', 'z']);
+//=> false
+```
+
+### [.arrayify](index.js#L114)
+
+Cast the given value to an array.
+
+**Params**
+
+* `val` **{String|Array}**
+* `returns` **{Array}**
+
+**Example**
+
+```js
+cu.arrayify('foo');
+//=> ['foo']
+
+cu.arrayify(['foo']);
+//=> ['foo']
+```
+
+### [.hasConstructor](index.js#L149)
+
+Returns true if a value has a `contructor`
+
+**Params**
+
+* `value` **{Object}**
+* `returns` **{Boolean}**
+
+**Example**
+
+```js
+cu.hasConstructor({});
+//=> true
+
+cu.hasConstructor(Object.create(null));
+//=> false
+```
+
+### [.nativeKeys](index.js#L171)
+
+Get the native `ownPropertyNames` from the constructor of the given `object`. An empty array is returned if the object does not have a constructor.
+
+**Params**
+
+* `obj` **{Object}**: Object that has a `constructor`.
+* `returns` **{Array}**: Array of keys.
+
+**Example**
+
+```js
+cu.nativeKeys({a: 'b', b: 'c', c: 'd'})
+//=> ['a', 'b', 'c']
+
+cu.nativeKeys(function(){})
+//=> ['length', 'caller']
+```
+
+### [.getDescriptor](index.js#L203)
+
+Returns property descriptor `key` if it's an "own" property of the given object.
+
+**Params**
+
+* `obj` **{Object}**
+* `key` **{String}**
+* `returns` **{Object}**: Returns descriptor `key`
+
+**Example**
+
+```js
+function App() {}
+Object.defineProperty(App.prototype, 'count', {
+ get: function() {
+ return Object.keys(this).length;
+ }
+});
+cu.getDescriptor(App.prototype, 'count');
+// returns:
+// {
+// get: [Function],
+// set: undefined,
+// enumerable: false,
+// configurable: false
+// }
+```
+
+### [.copyDescriptor](index.js#L233)
+
+Copy a descriptor from one object to another.
+
+**Params**
+
+* `receiver` **{Object}**
+* `provider` **{Object}**
+* `name` **{String}**
+* `returns` **{Object}**
+
+**Example**
+
+```js
+function App() {}
+Object.defineProperty(App.prototype, 'count', {
+ get: function() {
+ return Object.keys(this).length;
+ }
+});
+var obj = {};
+cu.copyDescriptor(obj, App.prototype, 'count');
+```
+
+### [.copy](index.js#L259)
+
+Copy static properties, prototype properties, and descriptors
+from one object to another.
+
+**Params**
+
+* `receiver` **{Object}**
+* `provider` **{Object}**
+* `omit` **{String|Array}**: One or more properties to omit
+* `returns` **{Object}**
+
+### [.inherit](index.js#L294)
+
+Inherit the static properties, prototype properties, and descriptors
+from of an object.
+
+**Params**
+
+* `receiver` **{Object}**
+* `provider` **{Object}**
+* `omit` **{String|Array}**: One or more properties to omit
+* `returns` **{Object}**
+
+### [.extend](index.js#L338)
+
+Returns a function for extending the static properties, prototype properties, and descriptors from the `Parent` constructor onto `Child` constructors.
+
+**Params**
+
+* `Parent` **{Function}**: Parent ctor
+* `extend` **{Function}**: Optional extend function to handle custom extensions. Useful when updating methods that require a specific prototype.
+* `Child` **{Function}**: Child ctor
+* `proto` **{Object}**: Optionally pass additional prototype properties to inherit.
+* `returns` **{Object}**
+
+**Example**
+
+```js
+var extend = cu.extend(Parent);
+Parent.extend(Child);
+
+// optional methods
+Parent.extend(Child, {
+ foo: function() {},
+ bar: function() {}
+});
+```
+
+### [.bubble](index.js#L351)
+
+Bubble up events emitted from static methods on the Parent ctor.
+
+**Params**
+
+* `Parent` **{Object}**
+* `events` **{Array}**: Event names to bubble up
+
+## Related projects
+
+You might also be interested in these projects:
+
+* [define-property](https://www.npmjs.com/package/define-property): Define a non-enumerable property on an object. | [homepage](https://github.com/jonschlinkert/define-property)
+* [delegate-properties](https://www.npmjs.com/package/delegate-properties): Deep-clone properties from one object to another and make them non-enumerable, or make existing properties… [more](https://www.npmjs.com/package/delegate-properties) | [homepage](https://github.com/jonschlinkert/delegate-properties)
+* [is-descriptor](https://www.npmjs.com/package/is-descriptor): Returns true if a value has the characteristics of a valid JavaScript descriptor. Works for… [more](https://www.npmjs.com/package/is-descriptor) | [homepage](https://github.com/jonschlinkert/is-descriptor)
+
+## Contributing
+
+Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](https://github.com/jonschlinkert/class-utils/issues/new).
+
+## Building docs
+
+Generate readme and API documentation with [verb](https://github.com/verbose/verb):
+
+```sh
+$ npm install verb && npm run docs
+```
+
+Or, if [verb](https://github.com/verbose/verb) is installed globally:
+
+```sh
+$ verb
+```
+
+## Running tests
+
+Install dev dependencies:
+
+```sh
+$ npm install -d && npm test
+```
+
+## Author
+
+**Jon Schlinkert**
+
+Follow me on GitHub or Twitter for updates about class-utils and my other libraries:
+
+* [github/jonschlinkert](https://github.com/jonschlinkert)
+* [twitter/jonschlinkert](http://twitter.com/jonschlinkert)
+
+## License
+
+Copyright © 2016, [Jon Schlinkert](https://github.com/jonschlinkert).
+Released under the [MIT license](https://github.com/jonschlinkert/class-utils/blob/master/LICENSE).
+
+***
+
+_This file was generated by [verb](https://github.com/verbose/verb), v, on April 05, 2016._
\ No newline at end of file
diff --git a/example.js b/example.js
new file mode 100644
index 0000000..654dd00
--- /dev/null
+++ b/example.js
@@ -0,0 +1,9 @@
+var cu = require('./');
+
+function App() {}
+Object.defineProperty(App.prototype, 'count', {
+ get: function () {
+ return Object.keys(this).length;
+ }
+});
+console.log(cu.getDescriptor(App.prototype, 'count'));
diff --git a/examples/a.js b/examples/a.js
new file mode 100644
index 0000000..67d3c58
--- /dev/null
+++ b/examples/a.js
@@ -0,0 +1,34 @@
+'use strict';
+
+var App = require('./app');
+var define = require('define-property');
+
+function A(options) {
+ App.call(this);
+ this.options = options || {};
+}
+
+define(A, 'metadata', {
+ name: 'A',
+ repository: 'foo/a'
+});
+App.extend(A);
+
+A.prototype.set = function(key, value) {
+ this[key] = value;
+ return this;
+};
+A.prototype.get = function(key) {
+ return this[key];
+};
+A.prototype.del = function(key) {
+ delete this[key];
+};
+Object.defineProperty(A.prototype, 'count', {
+ get: function () {
+ return Object.keys(this).length;
+ },
+ set: function () {
+ }
+});
+module.exports = A;
diff --git a/examples/app.js b/examples/app.js
new file mode 100644
index 0000000..5eeb45c
--- /dev/null
+++ b/examples/app.js
@@ -0,0 +1,33 @@
+var define = require('define-property');
+var cu = require('..');
+
+function App(options) {
+ this.options = options || {};
+}
+App.prototype.set = function(key, value) {
+ this[key] = value;
+ return this;
+};
+App.prototype.get = function(key) {
+ return this[key];
+};
+App.prototype.del = function(key) {
+ delete this[key];
+};
+Object.defineProperty(App.prototype, 'count', {
+ get: function () {
+ return Object.keys(this).length;
+ },
+ set: function () {
+ }
+});
+
+define(App, 'metadata', {
+ name: 'App',
+ repository: 'app/app'
+});
+
+App.extend = cu.extend(App);
+App.inherit = cu.inherit;
+
+module.exports = App;
diff --git a/examples/b.js b/examples/b.js
new file mode 100644
index 0000000..26f5842
--- /dev/null
+++ b/examples/b.js
@@ -0,0 +1,39 @@
+'use strict';
+
+var A = require('./a');
+var define = require('define-property');
+
+function B(options) {
+ A.call(this);
+ this.options = options || {};
+}
+
+define(B, 'metadata', {
+ name: 'B',
+ repository: 'foo/b'
+});
+A.extend(B);
+
+B.prototype.set = function(key, value) {
+ this[key] = value;
+ return this;
+};
+B.prototype.get = function(key) {
+ return this[key];
+};
+B.prototype.del = function(key) {
+ delete this[key];
+};
+Object.defineProperty(B.prototype, 'count', {
+ get: function () {
+ return Object.keys(this).length;
+ },
+ set: function () {
+ }
+});
+
+define(B, 'metadata', {
+ name: 'B',
+ repository: 'foo/b'
+});
+module.exports = B;
diff --git a/examples/c.js b/examples/c.js
new file mode 100644
index 0000000..6219ad6
--- /dev/null
+++ b/examples/c.js
@@ -0,0 +1,34 @@
+'use strict';
+
+var B = require('./b');
+var define = require('define-property');
+
+function C(options) {
+ B.call(this);
+ this.options = options || {};
+}
+B.extend(C);
+define(C, 'metadata', {
+ name: 'C',
+ repository: 'foo/c'
+});
+
+C.prototype.set = function(key, value) {
+ this[key] = value;
+ return this;
+};
+C.prototype.get = function(key) {
+ return this[key];
+};
+C.prototype.del = function(key) {
+ delete this[key];
+};
+Object.defineProperty(C.prototype, 'count', {
+ get: function () {
+ return Object.keys(this).length;
+ },
+ set: function () {
+ }
+});
+
+module.exports = C;
diff --git a/examples/meta.js b/examples/meta.js
new file mode 100644
index 0000000..3c793bc
--- /dev/null
+++ b/examples/meta.js
@@ -0,0 +1,6 @@
+
+var B = require('./b');
+var App = require('./c');
+
+// console.log(App.metadata)
+var app = new App();
diff --git a/fixtures/app.js b/fixtures/app.js
new file mode 100644
index 0000000..4f9c66b
--- /dev/null
+++ b/fixtures/app.js
@@ -0,0 +1,22 @@
+function App(options) {
+ this.options = options || {};
+}
+App.prototype.set = function(key, value) {
+ this[key] = value;
+ return this;
+};
+App.prototype.get = function(key) {
+ return this[key];
+};
+App.prototype.del = function(key) {
+ delete this[key];
+};
+Object.defineProperty(App.prototype, 'count', {
+ get: function () {
+ return Object.keys(this).length;
+ },
+ set: function () {
+ }
+});
+
+module.exports = App;
\ No newline at end of file
diff --git a/gulpfile.js b/gulpfile.js
new file mode 100644
index 0000000..cd32374
--- /dev/null
+++ b/gulpfile.js
@@ -0,0 +1,63 @@
+'use strict';
+
+var gulp = require('gulp');
+var mocha = require('gulp-mocha');
+var istanbul = require('gulp-istanbul');
+var eslint = require('gulp-eslint');
+var through = require('through2');
+
+gulp.task('coverage', function() {
+ return gulp.src(['index.js', 'utils.js'])
+ .pipe(istanbul({includeUntested: true}))
+ .pipe(istanbul.hookRequire());
+});
+
+gulp.task('mocha', ['coverage'], function() {
+ return gulp.src('test.js')
+ .pipe(mocha())
+ .pipe(istanbul.writeReports());
+});
+
+gulp.task('eslint', function() {
+ return gulp.src('*.js')
+ .pipe(eslint())
+ .pipe(eslint.format());
+});
+
+gulp.task('vars', function() {
+ var utils = require('./utils');
+ var keys = Object.keys(utils);
+ var report = {};
+ var cache = {};
+
+ return gulp.src(['index.js', 'utils.js'])
+ .pipe(through.obj(function(file, enc, next) {
+ var str = file.contents.toString();
+ keys.forEach(function(key) {
+ report[key] = report[key] || 0;
+ var re = cache[key] || (cache[key] = new RegExp('\\.' + key, 'g'));
+ var m = str.match(re);
+ if (!m) return;
+ report[key]++;
+ });
+
+ next(null, file);
+ }, function(next) {
+ var keys = Object.keys(report);
+ var res = {};
+
+ keys.sort(function(a, b) {
+ return report[a] > report[b] ? -1 : 1;
+ });
+
+ keys.forEach(function(key) {
+ res[key] = report[key];
+ });
+
+ console.log(res);
+ console.log(keys.length, 'modules');
+ next();
+ }))
+});
+
+gulp.task('default', ['mocha', 'eslint']);
diff --git a/index.js b/index.js
new file mode 100644
index 0000000..f14ea04
--- /dev/null
+++ b/index.js
@@ -0,0 +1,365 @@
+'use strict';
+
+var util = require('util');
+var utils = require('./utils');
+
+/**
+ * Expose class utils
+ */
+
+var cu = module.exports;
+
+/**
+ * Expose class utils: `cu`
+ */
+
+cu.isObject = function isObject(val) {
+ return utils.isObj(val) || typeof val === 'function';
+};
+
+/**
+ * Returns true if an array has any of the given elements, or an
+ * object has any of the give keys.
+ *
+ * ```js
+ * cu.has(['a', 'b', 'c'], 'c');
+ * //=> true
+ *
+ * cu.has(['a', 'b', 'c'], ['c', 'z']);
+ * //=> true
+ *
+ * cu.has({a: 'b', c: 'd'}, ['c', 'z']);
+ * //=> true
+ * ```
+ * @param {Object} `obj`
+ * @param {String|Array} `val`
+ * @return {Boolean}
+ * @api public
+ */
+
+cu.has = function has(obj, val) {
+ val = cu.arrayify(val);
+ var len = val.length;
+
+ if (cu.isObject(obj)) {
+ for (var key in obj) {
+ if (val.indexOf(key) > -1) {
+ return true;
+ }
+ }
+
+ var keys = cu.nativeKeys(obj);
+ return cu.has(keys, val);
+ }
+
+ if (Array.isArray(obj)) {
+ var arr = obj;
+ while (len--) {
+ if (arr.indexOf(val[len]) > -1) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ throw new TypeError('expected an array or object.');
+};
+
+/**
+ * Returns true if an array or object has all of the given values.
+ *
+ * ```js
+ * cu.hasAll(['a', 'b', 'c'], 'c');
+ * //=> true
+ *
+ * cu.hasAll(['a', 'b', 'c'], ['c', 'z']);
+ * //=> false
+ *
+ * cu.hasAll({a: 'b', c: 'd'}, ['c', 'z']);
+ * //=> false
+ * ```
+ * @param {Object|Array} `val`
+ * @param {String|Array} `values`
+ * @return {Boolean}
+ * @api public
+ */
+
+cu.hasAll = function hasAll(val, values) {
+ values = cu.arrayify(values);
+ var len = values.length;
+ while (len--) {
+ if (!cu.has(val, values[len])) {
+ return false;
+ }
+ }
+ return true;
+};
+
+/**
+ * Cast the given value to an array.
+ *
+ * ```js
+ * cu.arrayify('foo');
+ * //=> ['foo']
+ *
+ * cu.arrayify(['foo']);
+ * //=> ['foo']
+ * ```
+ *
+ * @param {String|Array} `val`
+ * @return {Array}
+ * @api public
+ */
+
+cu.arrayify = function arrayify(val) {
+ return val ? (Array.isArray(val) ? val : [val]) : [];
+};
+
+/**
+ * Noop
+ */
+
+cu.noop = function noop() {
+ return;
+};
+
+/**
+ * Returns the first argument passed to the function.
+ */
+
+cu.identity = function identity(val) {
+ return val;
+};
+
+/**
+ * Returns true if a value has a `contructor`
+ *
+ * ```js
+ * cu.hasConstructor({});
+ * //=> true
+ *
+ * cu.hasConstructor(Object.create(null));
+ * //=> false
+ * ```
+ * @param {Object} `value`
+ * @return {Boolean}
+ * @api public
+ */
+
+cu.hasConstructor = function hasConstructor(val) {
+ return cu.isObject(val) && typeof val.constructor !== 'undefined';
+};
+
+/**
+ * Get the native `ownPropertyNames` from the constructor of the
+ * given `object`. An empty array is returned if the object does
+ * not have a constructor.
+ *
+ * ```js
+ * cu.nativeKeys({a: 'b', b: 'c', c: 'd'})
+ * //=> ['a', 'b', 'c']
+ *
+ * cu.nativeKeys(function(){})
+ * //=> ['length', 'caller']
+ * ```
+ *
+ * @param {Object} `obj` Object that has a `constructor`.
+ * @return {Array} Array of keys.
+ * @api public
+ */
+
+cu.nativeKeys = function nativeKeys(val) {
+ if (!cu.hasConstructor(val)) return [];
+ return Object.getOwnPropertyNames(val);
+};
+
+/**
+ * Returns property descriptor `key` if it's an "own" property
+ * of the given object.
+ *
+ * ```js
+ * function App() {}
+ * Object.defineProperty(App.prototype, 'count', {
+ * get: function() {
+ * return Object.keys(this).length;
+ * }
+ * });
+ * cu.getDescriptor(App.prototype, 'count');
+ * // returns:
+ * // {
+ * // get: [Function],
+ * // set: undefined,
+ * // enumerable: false,
+ * // configurable: false
+ * // }
+ * ```
+ *
+ * @param {Object} `obj`
+ * @param {String} `key`
+ * @return {Object} Returns descriptor `key`
+ * @api public
+ */
+
+cu.getDescriptor = function getDescriptor(obj, key) {
+ if (!cu.isObject(obj)) {
+ throw new TypeError('expected an object.');
+ }
+ if (typeof key !== 'string') {
+ throw new TypeError('expected key to be a string.');
+ }
+ return Object.getOwnPropertyDescriptor(obj, key);
+};
+
+/**
+ * Copy a descriptor from one object to another.
+ *
+ * ```js
+ * function App() {}
+ * Object.defineProperty(App.prototype, 'count', {
+ * get: function() {
+ * return Object.keys(this).length;
+ * }
+ * });
+ * var obj = {};
+ * cu.copyDescriptor(obj, App.prototype, 'count');
+ * ```
+ * @param {Object} `receiver`
+ * @param {Object} `provider`
+ * @param {String} `name`
+ * @return {Object}
+ * @api public
+ */
+
+cu.copyDescriptor = function copyDescriptor(receiver, provider, name) {
+ if (!cu.isObject(receiver)) {
+ throw new TypeError('expected receiving object to be an object.');
+ }
+ if (!cu.isObject(provider)) {
+ throw new TypeError('expected providing object to be an object.');
+ }
+ if (typeof name !== 'string') {
+ throw new TypeError('expected name to be a string.');
+ }
+
+ var val = cu.getDescriptor(provider, name);
+ if (val) Object.defineProperty(receiver, name, val);
+};
+
+/**
+ * Copy static properties, prototype properties, and descriptors
+ * from one object to another.
+ *
+ * @param {Object} `receiver`
+ * @param {Object} `provider`
+ * @param {String|Array} `omit` One or more properties to omit
+ * @return {Object}
+ * @api public
+ */
+
+cu.copy = function copy(receiver, provider, omit) {
+ if (!cu.isObject(receiver)) {
+ throw new TypeError('expected receiving object to be an object.');
+ }
+ if (!cu.isObject(provider)) {
+ throw new TypeError('expected providing object to be an object.');
+ }
+ var props = Object.getOwnPropertyNames(provider);
+ var keys = Object.keys(provider);
+ var len = props.length,
+ key;
+ omit = cu.arrayify(omit);
+
+ while (len--) {
+ key = props[len];
+
+ if (cu.has(keys, key)) {
+ utils.define(receiver, key, provider[key]);
+ } else if (!(key in receiver) && !cu.has(omit, key)) {
+ cu.copyDescriptor(receiver, provider, key);
+ }
+ }
+};
+
+/**
+ * Inherit the static properties, prototype properties, and descriptors
+ * from of an object.
+ *
+ * @param {Object} `receiver`
+ * @param {Object} `provider`
+ * @param {String|Array} `omit` One or more properties to omit
+ * @return {Object}
+ * @api public
+ */
+
+cu.inherit = function inherit(receiver, provider, omit) {
+ if (!cu.isObject(receiver)) {
+ throw new TypeError('expected receiving object to be an object.');
+ }
+ if (!cu.isObject(provider)) {
+ throw new TypeError('expected providing object to be an object.');
+ }
+
+ var keys = [];
+ for (var key in provider) {
+ keys.push(key);
+ receiver[key] = provider[key];
+ }
+
+ keys = keys.concat(cu.arrayify(omit));
+
+ var a = provider.prototype || provider;
+ var b = receiver.prototype || receiver;
+ cu.copy(b, a, keys);
+};
+
+/**
+ * Returns a function for extending the static properties,
+ * prototype properties, and descriptors from the `Parent`
+ * constructor onto `Child` constructors.
+ *
+ * ```js
+ * var extend = cu.extend(Parent);
+ * Parent.extend(Child);
+ *
+ * // optional methods
+ * Parent.extend(Child, {
+ * foo: function() {},
+ * bar: function() {}
+ * });
+ * ```
+ * @param {Function} `Parent` Parent ctor
+ * @param {Function} `extend` Optional extend function to handle custom extensions. Useful when updating methods that require a specific prototype.
+ * @param {Function} `Child` Child ctor
+ * @param {Object} `proto` Optionally pass additional prototype properties to inherit.
+ * @return {Object}
+ * @api public
+ */
+
+cu.extend = function() {
+ // keep it lazy, instead of assigning to `cu.extend`
+ return utils.staticExtend.apply(null, arguments);
+};
+
+/**
+ * Bubble up events emitted from static methods on the Parent ctor.
+ *
+ * @param {Object} `Parent`
+ * @param {Array} `events` Event names to bubble up
+ * @api public
+ */
+
+cu.bubble = function(Parent, events) {
+ events = events || [];
+ Parent.bubble = function(Child, arr) {
+ if (Array.isArray(arr)) {
+ events = utils.union([], events, arr);
+ }
+ var len = events.length;
+ var idx = -1;
+ while (++idx < len) {
+ var name = events[idx];
+ Parent.on(name, Child.emit.bind(Child, name));
+ }
+ cu.bubble(Child, events);
+ };
+};
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..4dd995f
--- /dev/null
+++ b/package.json
@@ -0,0 +1,87 @@
+{
+ "name": "class-utils",
+ "description": "Utils for working with JavaScript classes and prototype methods.",
+ "version": "0.3.4",
+ "homepage": "https://github.com/jonschlinkert/class-utils",
+ "author": "Jon Schlinkert (https://github.com/jonschlinkert)",
+ "repository": "jonschlinkert/class-utils",
+ "bugs": {
+ "url": "https://github.com/jonschlinkert/class-utils/issues"
+ },
+ "license": "MIT",
+ "files": [
+ "index.js",
+ "utils.js"
+ ],
+ "main": "index.js",
+ "engines": {
+ "node": ">=0.10.0"
+ },
+ "scripts": {
+ "test": "mocha"
+ },
+ "dependencies": {
+ "arr-union": "^3.1.0",
+ "define-property": "^0.2.5",
+ "isobject": "^2.0.0",
+ "lazy-cache": "^1.0.3",
+ "static-extend": "^0.1.1"
+ },
+ "devDependencies": {
+ "gulp": "^3.9.1",
+ "gulp-eslint": "^2.0.0",
+ "gulp-format-md": "^0.1.7",
+ "gulp-istanbul": "^0.10.3",
+ "gulp-mocha": "^2.2.0",
+ "mocha": "^2.4.5",
+ "should": "^8.2.2",
+ "through2": "^2.0.1"
+ },
+ "keywords": [
+ "array",
+ "assign",
+ "class",
+ "copy",
+ "ctor",
+ "define",
+ "delegate",
+ "descriptor",
+ "extend",
+ "extends",
+ "inherit",
+ "inheritance",
+ "merge",
+ "method",
+ "object",
+ "prop",
+ "properties",
+ "property",
+ "prototype",
+ "util",
+ "utils"
+ ],
+ "verb": {
+ "run": true,
+ "toc": false,
+ "layout": "default",
+ "tasks": [
+ "readme"
+ ],
+ "plugins": [
+ "gulp-format-md"
+ ],
+ "related": {
+ "list": [
+ "define-property",
+ "delegate-properties",
+ "is-descriptor"
+ ]
+ },
+ "reflinks": [
+ "verb"
+ ],
+ "lint": {
+ "reflinks": true
+ }
+ }
+}
diff --git a/test.js b/test.js
new file mode 100644
index 0000000..4c4e7a4
--- /dev/null
+++ b/test.js
@@ -0,0 +1,465 @@
+'use strict';
+require('mocha');
+require('should');
+var assert = require('assert');
+var App = require('./fixtures/app');
+var cu = require('./');
+
+assert.hasAll = function(a, b) {
+ assert(cu.hasAll(a, b));
+};
+assert.contains = function(a, b) {
+ assert(cu.has(a, b));
+};
+
+
+describe('noop', function() {
+ it('should return undefined:', function() {
+ assert(typeof cu.noop({}) === 'undefined');
+ assert(typeof cu.noop('foo') === 'undefined');
+ });
+});
+
+describe('isObject', function() {
+ it('should be true if the value is an object:', function() {
+ assert(cu.isObject({}));
+ });
+ it('should be true if the value is a function:', function() {
+ assert(cu.isObject(function() {}));
+ });
+ it('should be false if the value is an object:', function() {
+ assert(!cu.isObject('foo'));
+ });
+});
+
+describe('identity', function() {
+ it('should return the given value:', function() {
+ assert.deepEqual(cu.identity({}), {});
+ assert.deepEqual(cu.identity('foo'), 'foo');
+ assert.deepEqual(cu.identity(['foo']), ['foo']);
+ assert.deepEqual(cu.identity([]), []);
+ });
+});
+
+describe('hasAll', function() {
+ describe('object', function() {
+ it('should be true if an object has all given value:', function() {
+ assert(cu.hasAll({
+ a: 'b',
+ b: 'c',
+ c: 'd'
+ }, 'c'));
+ assert(cu.hasAll({
+ a: 'b',
+ b: 'c',
+ c: 'd'
+ }, ['c', 'b']));
+ assert(cu.hasAll({
+ a: 'b',
+ b: 'c',
+ c: 'd'
+ }, ['a', 'b', 'c']));
+ });
+
+ it('should be false if an object does not have all given value:', function() {
+ assert(!cu.hasAll({
+ a: 'b',
+ b: 'c',
+ c: 'd'
+ }, 'd'));
+ assert(!cu.hasAll({
+ a: 'b',
+ b: 'c',
+ c: 'd'
+ }, ['c', 'b', 'z']));
+ });
+ });
+
+ describe('arrays', function() {
+ it('should be true if an array has all given value:', function() {
+ assert(cu.hasAll(['a', 'b', 'c'], 'c'));
+ assert(cu.hasAll(['a', 'b', 'c'], ['c', 'b']));
+ assert(cu.hasAll(['a', 'b', 'c'], ['a', 'b', 'c']));
+ });
+
+ it('should be false if an array does not have all given value:', function() {
+ assert(!cu.hasAll(['a', 'b', 'c'], 'd'));
+ assert(!cu.hasAll(['a', 'b', 'c'], ['c', 'b', 'z']));
+ });
+ });
+});
+
+describe('has', function() {
+ describe('objects', function() {
+ it('should return true if an array has the given value:', function() {
+ assert(cu.has({
+ a: 'b',
+ b: 'c',
+ c: 'd'
+ }, 'c'));
+ assert(cu.has({
+ a: 'b',
+ b: 'c',
+ c: 'd'
+ }, 'b'));
+ });
+ it('should return false if an array does not have the given value:', function() {
+ assert(!cu.has({
+ a: 'b',
+ b: 'c',
+ c: 'd'
+ }, 'd'));
+ assert(!cu.has({
+ a: 'b',
+ b: 'c',
+ c: 'd'
+ }, 'e'));
+ });
+ it('should return true if an array has any given values:', function() {
+ assert(cu.has({
+ a: 'b',
+ b: 'c',
+ c: 'd'
+ }, ['c', 'z']));
+ assert(cu.has({
+ a: 'b',
+ b: 'c',
+ c: 'd'
+ }, ['a', 'z']));
+ });
+ it('should return false if an array does not have any given values:', function() {
+ assert(!cu.has({
+ a: 'b',
+ b: 'c',
+ c: 'd'
+ }, ['x', 'z']));
+ assert(!cu.has({
+ a: 'b',
+ b: 'c',
+ c: 'd'
+ }, ['y', 'z']));
+ });
+ });
+
+ describe('arrays', function() {
+ it('should return true if an array has the given value:', function() {
+ assert(cu.has(['a', 'b', 'c'], 'c'));
+ assert(cu.has(['a', 'b', 'c'], 'b'));
+ });
+ it('should return false if an array does not have the given value:', function() {
+ assert(!cu.has(['a', 'b', 'c'], 'd'));
+ assert(!cu.has(['a', 'b', 'c'], 'e'));
+ });
+ it('should return true if an array has any given values:', function() {
+ assert(cu.has(['a', 'b', 'c'], ['c', 'z']));
+ assert(cu.has(['a', 'b', 'c'], ['a', 'z']));
+ });
+ it('should return false if an array does not have any given values:', function() {
+ assert(!cu.has(['a', 'b', 'c'], ['x', 'z']));
+ assert(!cu.has(['a', 'b', 'c'], ['y', 'z']));
+ });
+ });
+
+ it('should throw an error when the value is not an array or object:', function() {
+ (function() {
+ cu.has('foo');
+ }).should.throw('expected an array or object.');
+ });
+});
+
+describe('hasConstructor', function() {
+ it('should return true if a value is an object and has a constructor:', function() {
+ assert(cu.hasConstructor({
+ a: 'b',
+ b: 'c',
+ c: 'd'
+ }));
+ assert(cu.hasConstructor(function() {}));
+ assert(cu.hasConstructor(App));
+ assert(cu.hasConstructor(new App()));
+ assert(cu.hasConstructor(Object.create(new App())));
+ });
+
+ it('should return false if a value is not object:', function() {
+ assert(!cu.hasConstructor('foo'));
+ assert(!cu.hasConstructor(5));
+ });
+
+ it('should return false if an object does not have a constructor:', function() {
+ assert(!cu.hasConstructor(Object.create(null)));
+ assert(!cu.hasConstructor(null));
+ });
+});
+
+describe('nativeKeys', function() {
+ it('should get the native keys of an object:', function() {
+ assert.hasAll(cu.nativeKeys({
+ a: 'b',
+ b: 'c',
+ c: 'd'
+ }), ['a', 'b', 'c']);
+ assert.hasAll(cu.nativeKeys(function() {}), ['length', 'name', 'prototype']);
+ assert.hasAll(cu.nativeKeys(App), ['length', 'name', 'prototype']);
+ assert.hasAll(cu.nativeKeys(App.prototype), ['constructor', 'set', 'get', 'del']);
+ assert.hasAll(cu.nativeKeys(App.constructor), ['length', 'name', 'caller']);
+ assert.hasAll(cu.nativeKeys(App.prototype.constructor), ['length', 'caller']);
+ assert.hasAll(cu.nativeKeys(new App()), ['options']);
+ assert.hasAll(cu.nativeKeys(Object.create(new App())), []);
+ });
+
+ it('should return empty array if a value does not have native keys:', function() {
+ assert.deepEqual(cu.nativeKeys(Object.create(null)), []);
+ assert.deepEqual(cu.nativeKeys(null), []);
+ });
+});
+
+describe('getDescriptor', function() {
+ it('should get the native keys of an object:', function() {
+ assert.contains(cu.getDescriptor(App.prototype, 'count'), ['get',
+ 'set'
+ ]);
+ assert(typeof cu.getDescriptor(App.prototype, 'foo') ===
+ 'undefined');
+ });
+
+ it('should throw an error when key is not a string:', function() {
+ (function() {
+ cu.getDescriptor({}, {}, null);
+ }).should.throw('expected key to be a string.');
+ });
+
+ it('should throw an error when receiver is not an object:', function() {
+ (function() {
+ cu.getDescriptor('foo');
+ }).should.throw('expected an object.');
+ });
+});
+
+describe('copyDescriptor', function() {
+ it('should copy a descriptor from the provider to receiver:', function() {
+ var proto = App.prototype;
+ var obj = {};
+ cu.copyDescriptor(obj, proto, 'count');
+ assert.contains(cu.getDescriptor(obj, 'count'), ['get', 'set']);
+ });
+
+ it('should do nothing when the descriptor does not exist:', function() {
+ var proto = App.prototype;
+ var obj = {};
+ cu.copyDescriptor(obj, proto, 'foo');
+ assert.deepEqual(obj, {});
+ });
+
+ it('should throw an error when name is not a string:', function() {
+ (function() {
+ cu.copyDescriptor({}, {}, null);
+ }).should.throw('expected name to be a string.');
+ });
+
+ it('should throw an error when receiver is not an object:', function() {
+ (function() {
+ cu.copyDescriptor('foo');
+ }).should.throw('expected receiving object to be an object.');
+ });
+
+ it('should throw an error when provider is not an object:', function() {
+ (function() {
+ cu.copyDescriptor({}, 'foo');
+ }).should.throw('expected providing object to be an object.');
+ });
+});
+
+describe('copy', function() {
+ it('should copy descriptors from the provider to receiver:', function() {
+ var proto = App.prototype;
+ var obj = {};
+ cu.copy(obj, proto);
+ assert.contains(cu.getDescriptor(obj, 'count'), ['get', 'set']);
+ });
+
+ it('should copy properties from the provider to receiver:', function() {
+ var proto = App.prototype;
+ var obj = {};
+ cu.copy(obj, proto);
+ obj.set('a', 'b');
+ assert(obj.a === 'b');
+ assert.contains(obj, ['get', 'set']);
+ });
+
+ it('should do nothing when the property does not exist:', function() {
+ var proto = App.prototype;
+ var obj = {};
+ cu.copy(obj, proto, 'foo');
+ assert.deepEqual(obj, {});
+ });
+
+ it('should throw an error when receiver is not an object:', function() {
+ (function() {
+ cu.copy('foo');
+ }).should.throw('expected receiving object to be an object.');
+ });
+
+ it('should throw an error when provider is not an object:', function() {
+ (function() {
+ cu.copy({}, 'foo');
+ }).should.throw('expected providing object to be an object.');
+ });
+});
+
+describe('inherit', function() {
+ it('should inherit descriptors from provider:', function() {
+ var proto = App.prototype;
+ var obj = {};
+ cu.inherit(obj, proto);
+ assert.contains(cu.getDescriptor(obj, 'count'), ['get', 'set']);
+ });
+
+ it('should inherit properties from provider:', function() {
+ var proto = App.prototype;
+ var obj = {};
+ cu.inherit(obj, proto);
+ obj.set('a', 'b');
+ assert(obj.a === 'b');
+ assert.contains(obj, ['get', 'set', 'del']);
+ });
+
+ it('should do nothing when the property does not exist:', function() {
+ var proto = App.prototype;
+ var obj = {};
+ cu.inherit(obj, proto, 'foo');
+ assert.deepEqual(obj, {});
+ });
+
+ it('should throw an error when receiver is not an object:', function() {
+ (function() {
+ cu.inherit('foo');
+ }).should.throw('expected receiving object to be an object.');
+ });
+
+ it('should throw an error when provider is not an object:', function() {
+ (function() {
+ cu.inherit({}, 'foo');
+ }).should.throw('expected providing object to be an object.');
+ });
+});
+
+describe('extend', function() {
+ var Parent;
+ var Ctor;
+ var proto;
+
+ beforeEach(function() {
+ Parent = function() {}
+ Parent.foo = 'bar';
+ Parent.prototype.a = function() {};
+ Parent.prototype.b = function() {};
+ Parent.prototype.c = function() {};
+ Object.defineProperty(Parent.prototype, 'count', {
+ get: function() {
+ return Object.keys(this).length;
+ },
+ set: function() {}
+ });
+ Ctor = function() {
+ Parent.call(this);
+ };
+ proto = App.prototype;
+ });
+
+ it('should add `Parent.prototype` to `Ctor` instances as `_parent_`', function() {
+ var extend = cu.extend(Parent);
+ var instance1 = new Ctor();
+ assert.equal(typeof instance1._parent_, 'undefined');
+ extend(Ctor);
+ var instance2 = new Ctor();
+ assert.equal(typeof instance2._parent_, 'object');
+ assert.deepEqual(instance2._parent_, Parent.prototype);
+ });
+
+ it('should access `Parent` methods through `_parent_`', function() {
+ Parent.prototype.upper = function(str) {
+ return str.toUpperCase();
+ };
+
+ var extend = cu.extend(Parent);
+ extend(Ctor);
+
+ var instance = new Ctor();
+ assert.equal(instance.upper('foo'), 'FOO');
+
+ instance.upper = function(str) {
+ return str;
+ };
+ assert.equal(instance.upper('foo'), 'foo');
+
+ instance.upper = function(str) {
+ return this._parent_.upper(str) + ' ' + str;
+ };
+ assert.equal(instance.upper('foo'), 'FOO foo');
+ });
+
+ it('should add static methods to Ctor:', function() {
+ var extend = cu.extend(Parent);
+ extend(Ctor);
+ assert(typeof Ctor.extend === 'function');
+ assert(Ctor.foo === 'bar');
+ });
+
+ it('should add prototype methods to Ctor:', function() {
+ var extend = cu.extend(Parent);
+ extend(Ctor);
+ assert(typeof Ctor.prototype.a === 'function');
+ assert(typeof Ctor.prototype.b === 'function');
+ assert(typeof Ctor.prototype.c === 'function');
+ });
+
+ it('should add descriptors to Ctor:', function() {
+ var extend = cu.extend(Parent);
+ extend(Ctor);
+ });
+
+ it('should copy prototype properties to Ctor:', function() {
+ var extend = cu.extend(Parent);
+ extend(Ctor, App.prototype);
+ assert(typeof Ctor.prototype.get === 'function');
+ assert(typeof Ctor.prototype.set === 'function');
+ assert(typeof Ctor.prototype.del === 'function');
+ });
+
+ it('should add a mixin method to the prototype of Ctor using `extend` function:', function() {
+ var extend = cu.extend(Parent, function(Child) {
+ Child.prototype.mixin = function(key, val) {
+ Child.prototype[key] = val;
+ };
+ });
+ extend(Ctor, App.prototype);
+ assert(typeof Ctor.prototype.mixin === 'function');
+ assert(typeof Ctor.prototype.get === 'function');
+ assert(typeof Ctor.prototype.set === 'function');
+ assert(typeof Ctor.prototype.del === 'function');
+ });
+
+ it('should mixin methods to the Ctor.prototype using `extend` function:', function() {
+ var extend = cu.extend(Parent, function(Child) {
+ Child.prototype.mixin = function(key, val) {
+ Child.prototype[key] = val;
+ };
+ });
+ extend(Ctor, App.prototype);
+ var app = new Ctor();
+ app.mixin('foo', function() {});
+ assert.equal(typeof Ctor.prototype.foo, 'function');
+ });
+
+ it('should throw an error when Parent is not a function:', function() {
+ (function() {
+ cu.extend('foo');
+ }).should.throw('expected Parent to be a function.');
+ });
+
+ it('should throw an error when Ctor is not a function:', function() {
+ (function() {
+ cu.extend(function Foo() {})('bar')
+ }).should.throw('expected Ctor to be a function.');
+ });
+});
diff --git a/utils.js b/utils.js
new file mode 100644
index 0000000..0cf143e
--- /dev/null
+++ b/utils.js
@@ -0,0 +1,21 @@
+'use strict';
+
+var utils = require('lazy-cache')(require);
+var fn = require;
+require = utils;
+
+/**
+ * Lazily required module dependencies
+ */
+
+require('arr-union', 'union');
+require('define-property', 'define');
+require('isobject', 'isObj');
+require('static-extend');
+require = fn;
+
+/**
+ * Expose `utils`
+ */
+
+module.exports = utils;
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/node-class-utils.git
More information about the Pkg-javascript-commits
mailing list