// 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" ) {
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 ];
-
- // Prevent never-ending loop
- if ( target === copy )
- continue;
-
- // Recurse if we're merging object values
- if ( deep && copy && typeof copy === "object" ) {
- target[ name ] = process.mixin( deep,
- // Never move original objects, clone them
- src || ( copy.length != null ? [ ] : { } )
- , copy );
-
- // Don't bring in undefined values
- } else {
- target[ name ] = copy;
+ 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 === d.value)
+ continue;
+
+ if (deep && d.value && typeof d.value === "object") {
+ target[k] = process.mixin(deep,
+ // Never move original objects, clone them
+ source || (d.value.length != null ? [] : {})
+ , d.value);
+ }
+ else {
+ target[k] = d.value;
+ }
+ }
+ });
}
}
// Return the modified object
target = {};
process.mixin(target, objectWithUndefinedValue);
-assert.ok(target.hasOwnProperty('foo'));
\ No newline at end of file
+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');