diff --git a/.gitignore b/.gitignore index b07d8ee..dda9df2 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,8 @@ npm-debug.log* # Coverage directory used by tools like istanbul coverage +.nyc_output +.coveralls.yml # Dependency directories node_modules diff --git a/package.json b/package.json index 865f574..f843edf 100644 --- a/package.json +++ b/package.json @@ -9,11 +9,12 @@ "scripts": { "lint": "eslint .", "test": "mocha", - "coverage": "istanbul cover _mocha", - "coveralls": "istanbul cover _mocha && istanbul-coveralls", - "web:install": "npm install --no-save phantomjs-prebuilt mocha-phantomjs", - "web:build": "browserify index.js --standalone copyProps | uglifyjs --compress --mangle -o web/copy-props.js && node test/web/make.js", - "web:test": "mocha-phantomjs -p node_modules/.bin/phantomjs test/web/copy-props.test.html" + "coverage": "nyc --reporter=lcov --reporter=text-summary npm test", + "coveralls": "nyc --reporter=text-lcov npm test | coveralls", + "web:build": "browserify index.js --standalone copyProps -o web/copy-props.js && cd web && uglifyjs copy-props.js --compress --mangle -o copy-props.min.js --source-map url=copy-props.min.js.map", + "chrome:install": "npm i --no-save mocha-chrome", + "chrome:test": "mocha-chrome test/web/browser-test.html", + "build": "npm run lint && npm run coverage && npm run web:build && node test/web/make.js" }, "repository": { "type": "git", @@ -38,12 +39,12 @@ "is-plain-object": "^2.0.1" }, "devDependencies": { - "browserify": "^14.1.0", + "browserify": "^16.2.2", "chai": "^3.5.0", - "eslint": "^3.16.1", - "istanbul": "^0.4.5", - "istanbul-coveralls": "^1.0.3", + "coveralls": "^3.0.1", + "eslint": "^4.19.1", "mocha": "^3.2.0", - "uglify-js": "^2.8.1" + "nyc": "^11.7.2", + "uglify-js": "^3.3.24" } } diff --git a/test/web/copy-props.test.html b/test/web/browser-test.html similarity index 90% rename from test/web/copy-props.test.html rename to test/web/browser-test.html index 5e8f78c..3117c18 100644 --- a/test/web/copy-props.test.html +++ b/test/web/browser-test.html @@ -6,7 +6,7 @@ - +
diff --git a/test/web/copy-props-proc.js b/test/web/copy-props-proc.js index 7bf8c4d..0f06128 100644 --- a/test/web/copy-props-proc.js +++ b/test/web/copy-props-proc.js @@ -166,6 +166,19 @@ describe('Processing', function() { var dst = { a: { b: { c: 1 } } }; expect(copyProps(src, dst)).to.deep.equal({ a: { b: { c: 1 } } }); }); + + it('Should copy normally when src prop is not a plain object but an ' + + 'object', function() { + function O(v) { + this.a = { b: { c: v } }; + } + var o1 = new O(123); + var o2 = new O(456); + var p1 = { o: o1 }; + var p2 = { o: o2 }; + copyProps(p1, p2); + expect(p2.o).to.equal(o1); + }); }); describe('About fromto special cases', function() { diff --git a/web/copy-props.js b/web/copy-props.js index 8cea233..19d7948 100644 --- a/web/copy-props.js +++ b/web/copy-props.js @@ -1 +1,523 @@ -!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var r;r="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,r.copyProps=t()}}(function(){return function(){function t(r,n,e){function o(u,f){if(!n[u]){if(!r[u]){var a="function"==typeof require&&require;if(!f&&a)return a(u,!0);if(i)return i(u,!0);var c=new Error("Cannot find module '"+u+"'");throw c.code="MODULE_NOT_FOUND",c}var s=n[u]={exports:{}};r[u][0].call(s.exports,function(t){return o(r[u][1][t]||t)},s,s.exports,t,r,n,e)}return n[u].exports}for(var i="function"==typeof require&&require,u=0;u + * + * Copyright (c) 2015, 2017, Jon Schlinkert. + * Released under the MIT License. + */ + +'use strict'; + +/** + * Loop over each item in an array and call the given function on every element. + * + * ```js + * each(['a', 'b', 'c'], function(ele) { + * return ele + ele; + * }); + * //=> ['aa', 'bb', 'cc'] + * + * each(['a', 'b', 'c'], function(ele, i) { + * return i + ele; + * }); + * //=> ['0a', '1b', '2c'] + * ``` + * + * @name each + * @alias forEach + * @param {Array} `array` + * @param {Function} `fn` + * @param {Object} `thisArg` (optional) pass a `thisArg` to be used as the context in which to call the function. + * @return {undefined} + * @api public + */ + +module.exports = function each(arr, cb, thisArg) { + if (arr == null) return; + + var len = arr.length; + var idx = -1; + + while (++idx < len) { + var ele = arr[idx]; + if (cb.call(thisArg, ele, idx, arr) === false) { + break; + } + } +}; + +},{}],3:[function(require,module,exports){ +/*! + * array-slice + * + * Copyright (c) 2014-2017, Jon Schlinkert. + * Released under the MIT License. + */ + +'use strict'; + +module.exports = function slice(arr, start, end) { + var len = arr.length; + var range = []; + + start = idx(len, start); + end = idx(len, end, len); + + while (start < end) { + range.push(arr[start++]); + } + return range; +}; + +function idx(len, pos, end) { + if (pos == null) { + pos = end || 0; + } else if (pos < 0) { + pos = Math.max(len + pos, 0); + } else { + pos = Math.min(pos, len); + } + + return pos; +} + +},{}],4:[function(require,module,exports){ +'use strict'; + +var isPlainObject = require('is-plain-object'); +var defaults = require('object.defaults/immutable'); + +module.exports = function(obj, fn, opts) { + if (!isObject(obj)) { + return; + } + + if (typeof fn !== 'function') { + return; + } + + if (!isPlainObject(opts)) { + opts = {}; + } + + forEachChild(obj, '', fn, 0, opts); +}; + +function forEachChild(node, baseKey, fn, depth, opts) { + var keys = Object.keys(node); + if (typeof opts.sort === 'function') { + var sortedKeys = opts.sort(keys); + if (Array.isArray(sortedKeys)) { + keys = sortedKeys; + } + } + + depth += 1; + + for (var i = 0, n = keys.length; i < n; i++) { + var key = keys[i]; + var keyChain = baseKey + '.' + key; + var value = node[key]; + + var nodeInfo = defaults(opts); + nodeInfo.name = key; + nodeInfo.index = i; + nodeInfo.count = n; + nodeInfo.depth = depth; + nodeInfo.parent = node; + + var notDigg = fn(value, keyChain.slice(1), nodeInfo); + if (notDigg || !isPlainObject(value)) { + continue; + } + + forEachChild(value, keyChain, fn, depth, opts); + } +} + +function isObject(v) { + return Object.prototype.toString.call(v) === '[object Object]'; +} + + +},{"is-plain-object":7,"object.defaults/immutable":9}],5:[function(require,module,exports){ +/*! + * for-in + * + * Copyright (c) 2014-2017, Jon Schlinkert. + * Released under the MIT License. + */ + +'use strict'; + +module.exports = function forIn(obj, fn, thisArg) { + for (var key in obj) { + if (fn.call(thisArg, obj[key], key, obj) === false) { + break; + } + } +}; + +},{}],6:[function(require,module,exports){ +/*! + * for-own + * + * Copyright (c) 2014-2017, Jon Schlinkert. + * Released under the MIT License. + */ + +'use strict'; + +var forIn = require('for-in'); +var hasOwn = Object.prototype.hasOwnProperty; + +module.exports = function forOwn(obj, fn, thisArg) { + forIn(obj, function(val, key) { + if (hasOwn.call(obj, key)) { + return fn.call(thisArg, obj[key], key, obj); + } + }); +}; + +},{"for-in":5}],7:[function(require,module,exports){ +/*! + * is-plain-object + * + * Copyright (c) 2014-2017, Jon Schlinkert. + * Released under the MIT License. + */ + +'use strict'; + +var isObject = require('isobject'); + +function isObjectObject(o) { + return isObject(o) === true + && Object.prototype.toString.call(o) === '[object Object]'; +} + +module.exports = function isPlainObject(o) { + var ctor,prot; + + if (isObjectObject(o) === false) return false; + + // If has modified constructor + ctor = o.constructor; + if (typeof ctor !== 'function') return false; + + // If has modified prototype + prot = ctor.prototype; + if (isObjectObject(prot) === false) return false; + + // If constructor does not have an Object-specific method + if (prot.hasOwnProperty('isPrototypeOf') === false) { + return false; + } + + // Most likely a plain Object + return true; +}; + +},{"isobject":8}],8:[function(require,module,exports){ +/*! + * isobject + * + * Copyright (c) 2014-2017, Jon Schlinkert. + * Released under the MIT License. + */ + +'use strict'; + +module.exports = function isObject(val) { + return val != null && typeof val === 'object' && Array.isArray(val) === false; +}; + +},{}],9:[function(require,module,exports){ +'use strict'; + +var slice = require('array-slice'); + +var defaults = require('./mutable'); + +/** + * Extends an empty object with properties of one or + * more additional `objects` + * + * @name .defaults.immutable + * @param {Object} `objects` + * @return {Object} + * @api public + */ + +module.exports = function immutableDefaults() { + var args = slice(arguments); + return defaults.apply(null, [{}].concat(args)); +}; + +},{"./mutable":10,"array-slice":3}],10:[function(require,module,exports){ +'use strict'; + +var each = require('array-each'); +var slice = require('array-slice'); +var forOwn = require('for-own'); +var isObject = require('isobject'); + +/** + * Extends the `target` object with properties of one or + * more additional `objects` + * + * @name .defaults + * @param {Object} `target` The target object. Pass an empty object to shallow clone. + * @param {Object} `objects` + * @return {Object} + * @api public + */ + +module.exports = function defaults(target, objects) { + if (target == null) { + return {}; + } + + each(slice(arguments, 1), function(obj) { + if (isObject(obj)) { + forOwn(obj, function(val, key) { + if (target[key] == null) { + target[key] = val; + } + }); + } + }); + + return target; +}; + +},{"array-each":2,"array-slice":3,"for-own":6,"isobject":8}]},{},[1])(1) +}); diff --git a/web/copy-props.min.js b/web/copy-props.min.js new file mode 100644 index 0000000..ecc3950 --- /dev/null +++ b/web/copy-props.min.js @@ -0,0 +1,2 @@ +!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{("undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this).copyProps=t()}}(function(){return function i(f,u,a){function c(r,t){if(!u[r]){if(!f[r]){var n="function"==typeof require&&require;if(!t&&n)return n(r,!0);if(s)return s(r,!0);var e=new Error("Cannot find module '"+r+"'");throw e.code="MODULE_NOT_FOUND",e}var o=u[r]={exports:{}};f[r][0].call(o.exports,function(t){return c(f[r][1][t]||t)},o,o.exports,i,f,u,a)}return u[r].exports}for(var s="function"==typeof require&&require,t=0;t