From 1f44e00c5069e965b85fd4147cebd977d3324a55 Mon Sep 17 00:00:00 2001 From: Peter Burns Date: Sun, 25 Sep 2016 14:01:30 -0700 Subject: [PATCH] Add support for cloning Promises --- clone.js | 17 +++++++++++++++-- test.js | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+), 2 deletions(-) diff --git a/clone.js b/clone.js index aa97478..2c8f65a 100644 --- a/clone.js +++ b/clone.js @@ -14,11 +14,16 @@ var nativeSet; try { nativeSet = Set; } catch(_) { - // maybe a reference error because no `Set`. Give it a dummy value that no - // value will ever be an instanceof. nativeSet = function() {}; } +var nativePromise; +try { + nativePromise = Promise; +} catch(_) { + nativePromise = function() {}; +} + /** * Clones (copies) an Object using deep copying. * @@ -77,6 +82,14 @@ function clone(parent, circular, depth, prototype) { child = new nativeMap(); } else if (parent instanceof nativeSet) { child = new nativeSet(); + } else if (parent instanceof nativePromise) { + child = new nativePromise(function (resolve, reject) { + parent.then(function(value) { + resolve(_clone(value, depth - 1)); + }, function(err) { + reject(_clone(err, depth - 1)); + }); + }); } else if (clone.__isArray(parent)) { child = []; } else if (clone.__isRegExp(parent)) { diff --git a/test.js b/test.js index 5de1923..984ea72 100644 --- a/test.js +++ b/test.js @@ -427,3 +427,61 @@ if (nativeSet) { test.done(); } } + +var nativePromise; +try { + nativePromise = Promise; +} catch(_) {} +if (nativePromise) { + exports["clone a native Promise"] = function (test) { + test.expect(9); + + var allDonePromises = []; + + // Resolving to a value + allDonePromises.push( + clone(Promise.resolve('foo')).then(function (value) { + test.equal(value, 'foo'); + }) + ); + + // Rejecting to a value + allDonePromises.push( + clone(Promise.reject('bar')).catch(function (value) { + test.equal(value, 'bar'); + }) + ); + + // Resolving to a promise + allDonePromises.push( + clone(Promise.resolve(Promise.resolve('baz'))).then(function (value) { + test.equal(value, 'baz'); + }) + ); + + // Resolving to a circular value + var circle = {}; + circle.circle = circle; + allDonePromises.push( + clone(Promise.resolve(circle)).then(function (value) { + test.notEqual(circle, value); + test.equal(value.circle, value); + }) + ); + + var expandoPromise = Promise.resolve('ok'); + expandoPromise.circle = expandoPromise; + expandoPromise.prop = 'val'; + var clonedPromise = clone(expandoPromise); + test.notEqual(expandoPromise, clonedPromise); + test.equal(clonedPromise.prop, 'val'); + test.equal(clonedPromise.circle, clonedPromise); + allDonePromises.push(clonedPromise.then(function(value) { + test.equal(value, 'ok'); + })); + + Promise.all(allDonePromises).then(function() { + test.done(); + }); + } +} \ No newline at end of file