diff --git a/Promise.js b/Promise.js index b28e78d..ad8279f 100644 --- a/Promise.js +++ b/Promise.js @@ -95,16 +95,31 @@ object.Constructor('IterablePromise', Promise, { // .some(..) / .every(..) // .sort(..) // + // XXX sould these support returning a promise??? // XXX should these support STOP??? map: function(func){ return this.constructor(this, function(e){ - return [func(e)] }) }, + //return [func(e)] }) }, + var res = func(e) + return res instanceof Promise ? + res.then(function(e){ + return [e] }) + : [res] }) }, filter: function(func){ return this.constructor(this, function(e){ - return func(e) ? - [e] + //return func(e) ? + // [e] + // : [] }) }, + var res = func(e) + return res instanceof Promise ? + res.then(function(res){ + return res ? + [e] + : [] }) + : res ? + [e] : [] }) }, // NOTE: this does not return an iterable promise as we can't know // what the user reduces to... @@ -114,6 +129,7 @@ object.Constructor('IterablePromise', Promise, { // XXX write how to go around this... // NOTE: since order of execution can not be guaranteed there is no // point in implementing .reduceRight(..) + // XXX should func be able to return a promise??? reduce: function(func, res){ return this.constructor(this, function(e){ @@ -268,6 +284,14 @@ object.Constructor('IterablePromise', Promise, { // manually handle the stop... // - another issue here is that the stop would happen in order of // execution and not order of elements... + // + // XXX BUG: + // await Promise.iter([1,Promise.resolve(2),[3]]) + // is not the same as: + // await Promise.iter([1,Promise.resolve(2),[3]]) + // .map(e => Promise.resolve(e)) + // ...again the problem is in the normalized input... + // XXX BUG: .map(..) returning a promise broken again... __new__: function(_, list, handler){ // instance... var promise @@ -287,17 +311,43 @@ object.Constructor('IterablePromise', Promise, { if(handler != 'raw'){ handler = handler - ?? function(e){ - return [e] } + ?? function(e){ return [e] } - // NOTE: this is recursive to handle expanding nested promises... var handle = function(elem){ - // call the handler... return (elem && elem.then) ? - //elem.then(function(elem){ - // return handler(elem) }) elem.then(handler) : handler(elem) } + // NOTE: these are nor exactly the same, but it would be + // nice to figure out a way to merge thess (XXX) + // XXX BUG: this seems to for some reason cack promises returned + // by .map(..) / .. into arrays... + // await Promise.iter([1, Promise.resolve(2), [3]]) + // .map(e => Promise.resolve(e)) + // ...will return a list with three promises... + // the odd thing is that printing the items shows + // that this gets the resolved results so it might + // seem that the problem is a tad bigger... + // ...also, the promises in the list are correct, + // seems that we need to .flat(..) the list... + var handleNormList = function(list){ + return list.map(function(sub){ + // XXX this get's the already resolved values... + //console.log('---', sub) + return sub instanceof Promise ? + sub.then(function(sub){ + return sub + .map(handle) + .flat() }) + : sub + .map(handle) + .flat() }) } + var handleList = function(list){ + return list instanceof Promise ? + list.then(function(list){ + return [list].flat() + .map(handle) }) + : [list].flat() + .map(handle) } // handle the list... // NOTE: we can't .flat() the results here as we need to @@ -307,24 +357,8 @@ object.Constructor('IterablePromise', Promise, { && !(list.__list instanceof Promise)) ? // NOTE: this is essentially the same as below but // with a normalized list as input... - // XXX can we merge the two??? - list.__list - .map(function(elems){ - return elems instanceof Promise ? - elems.then(function(elems){ - return elems - .map(handle) - .flat() }) - : elems - .map(handle) - .flat() }) - : list instanceof Promise ? - // special case: promised list... - list.then(function(list){ - return [list].flat() - .map(handle) }) - : [list].flat() - .map(handle) } + handleNormList(list.__list) + : handleList(list) } Object.defineProperty(obj, '__list', { value: list, @@ -337,9 +371,7 @@ object.Constructor('IterablePromise', Promise, { list : Promise.all([list].flat())) .then(function(res){ - promise.resolve(handler ? - res.flat() - : res) }) + promise.resolve(res.flat()) }) .catch(promise.reject) } return obj }, diff --git a/package-lock.json b/package-lock.json index bf6b1cc..8bd43d4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "ig-types", - "version": "6.11.0", + "version": "6.13.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "ig-types", - "version": "6.11.0", + "version": "6.13.0", "license": "BSD-3-Clause", "dependencies": { "ig-object": "^5.4.16", @@ -341,15 +341,15 @@ "integrity": "sha512-5MAUWSwfHKQNrgLroXxBHjlhrhVbhzlVqvUcfMDjUeK/ufWQ9THE0HDcvhfu+YrPfRjTR2QpD2Ygp+2H4O0C6g==" }, "node_modules/ig-test": { - "version": "1.4.8", - "resolved": "https://registry.npmjs.org/ig-test/-/ig-test-1.4.8.tgz", - "integrity": "sha512-TwSVA/874sHTc05RE+HtMW1BEbgws868CTQzpBwnVMYTKj6Th0mrNSls9SsTM/Ias2giPRZfusg+U/vc/JIcQQ==", + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/ig-test/-/ig-test-1.5.4.tgz", + "integrity": "sha512-1N2U3v6tSPGUeBNnCuFWem09ngNkuMT1NGEEyVtA73VR5nz8GMbroifiPX0+j/GLqBJ/u39bsMCdZSMaIMTRdg==", "dev": true, "dependencies": { - "colors": "^1.4.0", + "colors": "1.4.0", "glob": "^7.1.6", - "ig-argv": "^2.13.2", - "ig-object": "^5.2.6" + "ig-argv": "^2.16.3", + "ig-object": "^5.4.16" }, "bin": { "runtests": "test.js" @@ -478,7 +478,7 @@ "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "dev": true, "dependencies": { "wrappy": "1" @@ -526,7 +526,7 @@ "node_modules/path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", "dev": true, "engines": { "node": ">=0.10.0" @@ -1041,15 +1041,15 @@ "integrity": "sha512-5MAUWSwfHKQNrgLroXxBHjlhrhVbhzlVqvUcfMDjUeK/ufWQ9THE0HDcvhfu+YrPfRjTR2QpD2Ygp+2H4O0C6g==" }, "ig-test": { - "version": "1.4.8", - "resolved": "https://registry.npmjs.org/ig-test/-/ig-test-1.4.8.tgz", - "integrity": "sha512-TwSVA/874sHTc05RE+HtMW1BEbgws868CTQzpBwnVMYTKj6Th0mrNSls9SsTM/Ias2giPRZfusg+U/vc/JIcQQ==", + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/ig-test/-/ig-test-1.5.4.tgz", + "integrity": "sha512-1N2U3v6tSPGUeBNnCuFWem09ngNkuMT1NGEEyVtA73VR5nz8GMbroifiPX0+j/GLqBJ/u39bsMCdZSMaIMTRdg==", "dev": true, "requires": { - "colors": "^1.4.0", + "colors": "1.4.0", "glob": "^7.1.6", - "ig-argv": "^2.13.2", - "ig-object": "^5.2.6" + "ig-argv": "^2.16.3", + "ig-object": "^5.4.16" } }, "inflight": { @@ -1148,7 +1148,7 @@ "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "dev": true, "requires": { "wrappy": "1" @@ -1181,7 +1181,7 @@ "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", "dev": true }, "path-key": { diff --git a/package.json b/package.json index e1284e7..105f1cc 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ig-types", - "version": "6.12.1", + "version": "6.13.1", "description": "Generic JavaScript types and type extensions...", "main": "main.js", "scripts": { diff --git a/test.js b/test.js index bbe1acc..4f5b0e5 100755 --- a/test.js +++ b/test.js @@ -111,45 +111,142 @@ var cases = test.Cases({ RegExp: function(assert){ }, - Promise: function(assert){ + IterablePromise: test.TestSet(function(){ + var create = function(assert, value){ + return { + input: value, + output: assert(Promise.iter(value), 'Promise.iter(', value, ')'), + } } + + this.Setup({ + empty: function(assert){ + return create(assert, []) }, + value: function(assert){ + return create(assert, 123) }, + array: function(assert){ + return create(assert, [1, 2, 3]) }, + nested_array: function(assert){ + return create(assert, [1, 2, [3]]) }, + promise_value: function(assert){ + return create(assert, Promise.resolve(123)) }, + promise_array: function(assert){ + return create(assert, Promise.resolve([1, 2, 3])) }, + promise_nested_array: function(assert){ + return create(assert, Promise.resolve([1, 2, [3]])) }, + array_mixed: function(assert){ + return create(assert, [1, Promise.resolve(2), 3]) }, + nested_array_mixed: function(assert){ + return create(assert, [ + 1, + Promise.resolve(2), + [3], + Promise.resolve([4]), + ]) }, + promise_array_mixed: function(assert){ + return create(assert, Promise.resolve([1, Promise.resolve(2), 3])) }, + promise_nested_array_mixed: function(assert){ + return create(assert, Promise.resolve([ + 1, + Promise.resolve(2), + [3], + Promise.resolve([4]), + ])) }, + }) + this.Modifier({ + nest: function(assert, setup){ + setup.output = Promise.iter(setup.output) + return setup }, + iter: function(assert, setup){ + setup.output = setup.output.iter() + return setup }, + + map_asis: function(assert, setup){ + setup.output = setup.output + .map(function(e){ + return e }) + return setup }, + map_promise: function(assert, setup){ + setup.output = setup.output + .map(function(e){ + return Promise.resolve(e) }) + return setup }, + + filter_all: function(assert, setup){ + setup.output = setup.output + .filter(function(e){ return true }) + return setup }, + // XXX either the test is worng or something is broken... + filter_none: function(assert, setup){ + return { + input: [], + output: setup.output + .filter(function(e){ return false }), + } }, + + }) + this.Test({ + value: async function(assert, {input, output}){ + + var res = await output + + assert(res instanceof Array, 'result is array') + + input instanceof Array ? + assert.array(res, + await Promise.all(input), + 'array -> array') + : (input instanceof Promise && await input instanceof Array) ? + assert.array(res, + await input, + 'promise array -> array') + : input instanceof Promise ? + assert.array(res, + [await input], + 'promise value -> array') + : assert.array(res, + [input], + 'value -> array') }, + }) + }), + Promise: async function(assert){ var p = assert(Promise.cooperative(), '.cooperative()') - //var p = assert(promise._CooperativePromise()) - assert(!p.isSet, '.isSet is false') - + assert(!p.isSet, 'promise unset') + var RESOLVE = 123 + var then = false + var done = false - var then p.then(function(v){ - // XXX this does not get printed for some reason... - console.log('!!!!!!!!!!! then') - // XXX this seems not to work/print/count a fail... - assert(false, 'test fail') + then = assert(v == RESOLVE, '.then(..) handled') }) - then = v }) - - assert(!p.isSet, '.isSet is false') - - var fin p.finally(function(){ - fin = true }) + done = assert(true, '.finally(..) handled') }) - assert(!p.isSet, '.isSet is false') + assert(!p.isSet, 'promise unset') p.set(RESOLVE) - assert(p.isSet, '.isSet') + assert(p.isSet, 'promise set') - // XXX without setTimeout(..) these are run before the - // .then(..) / .finally(..) have a chance to run... - // ...not yet sure how I feel about this... - // XXX with setTimeout(..) these appear not to have ANY effect, - // as if setTimeout(..) did not run... - setTimeout(function(){ - assert(false, 'test fail') - assert(then == RESOLVE, '.then(..)') - assert(fin, '.finally(..)') - }, 0) + // allow the promise to finalize... + await p + + assert(then, '.then(..): confirmed') + assert(done, '.done(..): confirmed') + + // XXX + + assert(await Promise.iter([1, Promise.resolve(2), [3]]), '.iter(..)') + + assert.array( + await Promise.iter([1, 2, 3]), + [1, 2, 3], + 'basic array') + assert.array( + await Promise.iter([1, Promise.resolve(2), 3]), + [1, 2, 3], + 'promises as elements') }, // Date.js