Browse Source

fixed process.mixin to properly copy getters/setters

v0.7.4-release
Rasmus Andersson 15 years ago
committed by Ryan Dahl
parent
commit
3bb7ad6fea
  1. 35
      src/node.js
  2. 15
      test/mjsunit/test-process-mixin.js

35
src/node.js

@ -105,9 +105,10 @@ process.assert = function (x, msg) {
// Copyright (c) 2009 John Resig
// Dual licensed under the MIT and GPL licenses.
// http://docs.jquery.com/License
// Modified for node.js (formely for copying properties correctly)
process.mixin = function() {
// copy reference to target object
var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options;
var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, source;
// Handle a deep copy situation
if ( typeof target === "boolean" ) {
@ -129,28 +130,32 @@ process.mixin = function() {
for ( ; i < length; i++ ) {
// Only deal with non-null/undefined values
if ( (options = arguments[ i ]) != null ) {
if ( (source = arguments[i]) != null ) {
// Extend the base object
for ( var name in options ) {
var src = target[ name ], copy = options[ name ];
Object.getOwnPropertyNames(source).forEach(function(k){
var d = Object.getOwnPropertyDescriptor(source, k);
if (d.get) {
target.__defineGetter__(k, d.get);
if (d.set)
target.__defineSetter__(k, d.set);
}
else {
// Prevent never-ending loop
if ( target === copy )
if (target === d.value)
continue;
// Recurse if we're merging object values
if ( deep && copy && typeof copy === "object" ) {
target[ name ] = process.mixin( deep,
if (deep && d.value && typeof d.value === "object") {
target[k] = process.mixin(deep,
// Never move original objects, clone them
src || ( copy.length != null ? [ ] : { } )
, copy );
// Don't bring in undefined values
} else {
target[ name ] = copy;
source || (d.value.length != null ? [] : {})
, d.value);
}
else {
target[k] = d.value;
}
}
});
}
}
// Return the modified object
return target;

15
test/mjsunit/test-process-mixin.js

@ -20,3 +20,18 @@ target = {};
process.mixin(target, objectWithUndefinedValue);
assert.ok(target.hasOwnProperty('foo'));
// This test verifies getters and setters being copied correctly
var source = {
_foo:'a',
get foo(){ return this._foo; },
set foo(value){ this._foo = "did set to "+value; }
};
var target = {};
process.mixin(target, source);
target._foo = 'b';
assert.equal(source.foo, 'a');
assert.equal('b', target.foo, 'target.foo != "b" -- value/result was copied instead of getter function');
source.foo = 'c';
assert.equal('did set to c', source.foo, 'source.foo != "c" -- value was set instead of calling setter function');

Loading…
Cancel
Save