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

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

@ -20,3 +20,18 @@ target = {};
process.mixin(target, objectWithUndefinedValue); process.mixin(target, objectWithUndefinedValue);
assert.ok(target.hasOwnProperty('foo')); 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