Browse Source

feat: rewrite to Deno/TS

tags/v0.10.0
Muthu Kumar 2 years ago
parent
commit
1623fc7de4
Failed to extract signature
  1. 36
      .circleci/config.yml
  2. 14
      .vscode/launch.json
  3. 4
      .vscode/settings.json
  4. 21
      LICENSE
  5. 12
      build.sh
  6. 142
      es5/index.js
  7. 1
      es5/index.min.js
  8. 1
      es6/index.js
  9. 104
      index.js
  10. 44
      index.ts
  11. 112
      package-lock.json
  12. 37
      package.json
  13. 30
      package.json.old
  14. 76
      spec/PromiseObject.spec.js
  15. 11
      spec/support/jasmine.json
  16. 48
      test.ts

36
.circleci/config.yml

@ -1,36 +0,0 @@
# Javascript Node CircleCI 2.0 configuration file
#
# Check https://circleci.com/docs/2.0/language-javascript/ for more details
#
version: 2
jobs:
build:
docker:
# specify the version you desire here
- image: circleci/node:10.3
working_directory: ~/repo
steps:
- checkout
# Download and cache dependencies
- restore_cache:
keys:
- v1-dependencies-{{ checksum "package.json" }}
# fallback to using the latest cache if no exact match is found
- v1-dependencies-
- run: npm install
- run: npm install --only=dev
- save_cache:
paths:
- node_modules
key: v1-dependencies-{{ checksum "package.json" }}
# run tests!
- run: npm test

14
.vscode/launch.json

@ -1,14 +0,0 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Launch Program",
"program": "${workspaceFolder}/test.js"
}
]
}

4
.vscode/settings.json

@ -0,0 +1,4 @@
{
"deno.enable": true,
"deno.lint": false
}

21
LICENSE

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2023 Feathers Studio
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

12
build.sh

@ -1,12 +0,0 @@
#!/bin/bash
mkdir -p ./es5
echo "Browserifying..."
npx browserify ./es6/index.js -s promiseObject > ./es5/index.temp.js
echo "Babelifying..."
npx babel ./es5/index.temp.js --presets=env --plugins=babel-plugin-transform-object-rest-spread -o ./es5/index.js
echo "Minifying output..."
npx uglifyjs ./es5/index.js > ./es5/index.min.js
echo "Cleaning up..."
rm ./es5/index.temp.js
echo "Done!"

142
es5/index.js

@ -1,142 +0,0 @@
"use strict";
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
(function (f) {
if ((typeof exports === "undefined" ? "undefined" : _typeof(exports)) === "object" && typeof module !== "undefined") {
module.exports = f();
} else if (typeof define === "function" && define.amd) {
define([], f);
} else {
var g;if (typeof window !== "undefined") {
g = window;
} else if (typeof global !== "undefined") {
g = global;
} else if (typeof self !== "undefined") {
g = self;
} else {
g = this;
}g.promiseObject = f();
}
})(function () {
var define, module, exports;return function () {
function r(e, n, t) {
function o(i, f) {
if (!n[i]) {
if (!e[i]) {
var c = "function" == typeof require && require;if (!f && c) return c(i, !0);if (u) return u(i, !0);var a = new Error("Cannot find module '" + i + "'");throw a.code = "MODULE_NOT_FOUND", a;
}var p = n[i] = { exports: {} };e[i][0].call(p.exports, function (r) {
var n = e[i][1][r];return o(n || r);
}, p, p.exports, r, e, n, t);
}return n[i].exports;
}for (var u = "function" == typeof require && require, i = 0; i < t.length; i++) {
o(t[i]);
}return o;
}return r;
}()({ 1: [function (require, module, exports) {
module.exports = require('../index.js');
}, { "../index.js": 2 }], 2: [function (require, module, exports) {
"use strict";
/**
* Returns true if x is an object, false otherwise.
* @param {any} x
* @returns {Boolean}
*/
var isObject = function isObject(x) {
return x && (typeof x === "undefined" ? "undefined" : _typeof(x)) === 'object' && x.constructor === Object;
};
/* A well known Symbol. */
var $SELF = typeof Symbol !== 'undefined' ? Symbol('SELF') : '[~~//-- SELF --//~~]';
/**
* Replaces values that match the query parameter
* with a reference to the parent parameter.
* @param {Object} object Object to make cyclic.
* @param {any} query Query to match against.
* @returns {Object}
*/
var makeCyclic = function makeCyclic(object, query) {
var start = function start(obj) {
return Object.keys(obj).reduce(function (acc, key) {
var value = obj[key];
if (value === query) {
obj[key] = object;
return [].concat(_toConsumableArray(acc), [key]);
};
if (isObject(value)) return [].concat(_toConsumableArray(acc), _toConsumableArray(start(value, query)));else return acc;
}, []);
};
return start(object);
};
/**
* Promise.map polyfill.
* @param {Array.<any>} arr Array of Promises.
* @param {Function} functor Function to call resolved values.
*/
var PromiseMap = function PromiseMap(arr, functor) {
return Promise.all(arr.map(function (x) {
return Promise.resolve(x).then(functor);
}));
};
/**
* Resolve a flat object's promises.
* @param {Object}
* @returns {Object}
*/
var ResolveObject = function ResolveObject(obj) {
return Promise.all(Object.keys(obj).map(function (key) {
return Promise.resolve(obj[key]).then(function (val) {
return obj[key] = val;
});
})).then(function (_) {
return obj;
});
};
/**
* Recursively resolves deep objects with nested promises.
* @param {Object} object Object or value to resolve.
* @returns {Object} Resolved object.
*/
var PromiseObject = function PromiseObject(object) {
var shouldReplaceSelf = false;
var ResolveDeepObject = function ResolveDeepObject(obj) {
return Promise.resolve(obj).then(function (resolvedObject) {
if (Array.isArray(resolvedObject)) {
// Promise and map every item to recursively deep resolve.
return PromiseMap(resolvedObject, function (obj) {
return ResolveDeepObject(obj);
});
} else if (isObject(resolvedObject)) {
return ResolveObject(Object.keys(resolvedObject).reduce(function (acc, key) {
if (resolvedObject[key] === object) {
shouldReplaceSelf = true;
return _extends({}, acc, _defineProperty({}, key, $SELF));
}
return _extends({}, acc, _defineProperty({}, key, ResolveDeepObject(resolvedObject[key])));
}, {}));
}
return resolvedObject;
});
};
return ResolveDeepObject(object).then(function (obj) {
// Replace $SELF with reference to obj
if (shouldReplaceSelf) makeCyclic(obj, $SELF);
return obj;
});
};
module.exports = PromiseObject;
}, {}] }, {}, [1])(1);
});

1
es5/index.min.js

@ -1 +0,0 @@
"use strict";var _extends=Object.assign||function(target){for(var i=1;i<arguments.length;i++){var source=arguments[i];for(var key in source){if(Object.prototype.hasOwnProperty.call(source,key)){target[key]=source[key]}}}return target};var _typeof=typeof Symbol==="function"&&typeof Symbol.iterator==="symbol"?function(obj){return typeof obj}:function(obj){return obj&&typeof Symbol==="function"&&obj.constructor===Symbol&&obj!==Symbol.prototype?"symbol":typeof obj};function _defineProperty(obj,key,value){if(key in obj){Object.defineProperty(obj,key,{value:value,enumerable:true,configurable:true,writable:true})}else{obj[key]=value}return obj}function _toConsumableArray(arr){if(Array.isArray(arr)){for(var i=0,arr2=Array(arr.length);i<arr.length;i++){arr2[i]=arr[i]}return arr2}else{return Array.from(arr)}}(function(f){if((typeof exports==="undefined"?"undefined":_typeof(exports))==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.promiseObject=f()}})(function(){var define,module,exports;return function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++){o(t[i])}return o}return r}()({1:[function(require,module,exports){module.exports=require("../index.js")},{"../index.js":2}],2:[function(require,module,exports){"use strict";var isObject=function isObject(x){return x&&(typeof x==="undefined"?"undefined":_typeof(x))==="object"&&x.constructor===Object};var $SELF=typeof Symbol!=="undefined"?Symbol("SELF"):"[~~//-- SELF --//~~]";var makeCyclic=function makeCyclic(object,query){var start=function start(obj){return Object.keys(obj).reduce(function(acc,key){var value=obj[key];if(value===query){obj[key]=object;return[].concat(_toConsumableArray(acc),[key])}if(isObject(value))return[].concat(_toConsumableArray(acc),_toConsumableArray(start(value,query)));else return acc},[])};return start(object)};var PromiseMap=function PromiseMap(arr,functor){return Promise.all(arr.map(function(x){return Promise.resolve(x).then(functor)}))};var ResolveObject=function ResolveObject(obj){return Promise.all(Object.keys(obj).map(function(key){return Promise.resolve(obj[key]).then(function(val){return obj[key]=val})})).then(function(_){return obj})};var PromiseObject=function PromiseObject(object){var shouldReplaceSelf=false;var ResolveDeepObject=function ResolveDeepObject(obj){return Promise.resolve(obj).then(function(resolvedObject){if(Array.isArray(resolvedObject)){return PromiseMap(resolvedObject,function(obj){return ResolveDeepObject(obj)})}else if(isObject(resolvedObject)){return ResolveObject(Object.keys(resolvedObject).reduce(function(acc,key){if(resolvedObject[key]===object){shouldReplaceSelf=true;return _extends({},acc,_defineProperty({},key,$SELF))}return _extends({},acc,_defineProperty({},key,ResolveDeepObject(resolvedObject[key])))},{}))}return resolvedObject})};return ResolveDeepObject(object).then(function(obj){if(shouldReplaceSelf)makeCyclic(obj,$SELF);return obj})};module.exports=PromiseObject},{}]},{},[1])(1)});

1
es6/index.js

@ -1 +0,0 @@
module.exports = require('../index.js');

104
index.js

@ -1,104 +0,0 @@
"use strict";
/**
* Returns true if x is an object, false otherwise.
* @param {any} x
* @returns {Boolean}
*/
const isObject = x => x &&
typeof x === 'object' &&
x.constructor === Object;
/* A well known Symbol. */
const $SELF = typeof Symbol !== 'undefined' ?
Symbol('SELF') :
'[~~//-- SELF --//~~]';
/**
* Replaces values that match the query parameter
* with a reference to the parent parameter.
* @param {Object} object Object to make cyclic.
* @param {any} query Query to match against.
* @returns {Object}
*/
const makeCyclic = (object, query) => {
const start = obj => Object.keys(obj).reduce((acc, key) => {
const value = obj[key];
if (value === query) {
obj[key] = object;
return [...acc, key]
};
if (isObject(value)) return [...acc, ...start(value, query)];
else return acc;
}, []);
return start(object);
};
/**
* Promise.map polyfill.
* @param {Array.<any>} arr Array of Promises.
* @param {Function} functor Function to call resolved values.
*/
const PromiseMap = (arr, functor) =>
Promise.all(arr.map(x => Promise.resolve(x).then(functor)));
/**
* Resolve a flat object's promises.
* @param {Object}
* @returns {Object}
*/
const ResolveObject = obj =>
Promise.all(
Object
.keys(obj)
.map(key =>
Promise
.resolve(obj[key])
.then(val => obj[key] = val))
)
.then(_ => obj);
/**
* Recursively resolves deep objects with nested promises.
* @param {Object} object Object or value to resolve.
* @returns {Object} Resolved object.
*/
const PromiseObject = object => {
let shouldReplaceSelf = false;
const ResolveDeepObject = obj =>
Promise
.resolve(obj)
.then(resolvedObject => {
if (Array.isArray(resolvedObject)) {
// Promise and map every item to recursively deep resolve.
return PromiseMap(resolvedObject, obj => ResolveDeepObject(obj));
} else if (isObject(resolvedObject)) {
return ResolveObject(
Object
.keys(resolvedObject)
.reduce((acc, key) => {
if (resolvedObject[key] === object) {
shouldReplaceSelf = true;
return {
...acc,
[key]: $SELF, // Replace with resolved object.
}
}
return {
...acc,
[key]: ResolveDeepObject(resolvedObject[key]),
}
}, {}));
}
return resolvedObject;
});
return ResolveDeepObject(object)
.then(obj => {
// Replace $SELF with reference to obj
if(shouldReplaceSelf) makeCyclic(obj, $SELF);
return obj;
});
};
module.exports = PromiseObject;

44
index.ts

@ -0,0 +1,44 @@
type ResolveObject<T> = T extends object
? T extends Promise<infer U>
? ResolveObject<U>
: { [k in keyof T]: ResolveObject<T[k]> }
: T;
/** Recursively resolves deep objects with nested promises. */
export async function promiseObject<T>(obj: T): Promise<ResolveObject<T>> {
const seen = new Map<any, unknown>();
async function resolver<T>(obj: T): Promise<ResolveObject<T>> {
// null / undefined
if (obj == null) return obj as ResolveObject<T>;
// other primitive
if (typeof obj !== "object") return obj as ResolveObject<T>;
if (seen.has(obj)) return seen.get(obj) as ResolveObject<T>;
// PromiseLike
if ("then" in obj && typeof obj.then === "function") {
const resolved = resolver(await obj);
seen.set(obj, resolved);
return resolved as ResolveObject<T>;
}
// Array
if (Array.isArray(obj)) {
const resolved = await Promise.all(obj.map(each => Promise.resolve(each).then(resolver)));
seen.set(obj, resolved);
return resolved as ResolveObject<T>;
}
// object
const ret = {} as ResolveObject<T>;
seen.set(obj, ret);
// @ts-ignore
for (const [key, value] of Object.entries(obj)) ret[key] = await resolver(value);
seen.set(obj, ret);
return ret;
}
return resolver(obj);
}

112
package-lock.json

@ -1,112 +0,0 @@
{
"name": "@codefeathers/promise.object",
"version": "0.9.1",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"balanced-match": {
"version": "1.0.0",
"resolved": "http://localhost:4873/balanced-match/-/balanced-match-1.0.0.tgz",
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
"dev": true
},
"brace-expansion": {
"version": "1.1.11",
"resolved": "http://localhost:4873/brace-expansion/-/brace-expansion-1.1.11.tgz",
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
"dev": true,
"requires": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
}
},
"concat-map": {
"version": "0.0.1",
"resolved": "http://localhost:4873/concat-map/-/concat-map-0.0.1.tgz",
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
"dev": true
},
"fs.realpath": {
"version": "1.0.0",
"resolved": "http://localhost:4873/fs.realpath/-/fs.realpath-1.0.0.tgz",
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
"dev": true
},
"glob": {
"version": "7.1.2",
"resolved": "http://localhost:4873/glob/-/glob-7.1.2.tgz",
"integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
"dev": true,
"requires": {
"fs.realpath": "^1.0.0",
"inflight": "^1.0.4",
"inherits": "2",
"minimatch": "^3.0.4",
"once": "^1.3.0",
"path-is-absolute": "^1.0.0"
}
},
"inflight": {
"version": "1.0.6",
"resolved": "http://localhost:4873/inflight/-/inflight-1.0.6.tgz",
"integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
"dev": true,
"requires": {
"once": "^1.3.0",
"wrappy": "1"
}
},
"inherits": {
"version": "2.0.3",
"resolved": "http://localhost:4873/inherits/-/inherits-2.0.3.tgz",
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
"dev": true
},
"jasmine": {
"version": "3.1.0",
"resolved": "http://localhost:4873/jasmine/-/jasmine-3.1.0.tgz",
"integrity": "sha1-K9Wf1+xuwOistk4J9Fpo7SrRlSo=",
"dev": true,
"requires": {
"glob": "^7.0.6",
"jasmine-core": "~3.1.0"
}
},
"jasmine-core": {
"version": "3.1.0",
"resolved": "http://localhost:4873/jasmine-core/-/jasmine-core-3.1.0.tgz",
"integrity": "sha1-pHheE11d9lAk38kiSVPfWFvSdmw=",
"dev": true
},
"minimatch": {
"version": "3.0.4",
"resolved": "http://localhost:4873/minimatch/-/minimatch-3.0.4.tgz",
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
"dev": true,
"requires": {
"brace-expansion": "^1.1.7"
}
},
"once": {
"version": "1.4.0",
"resolved": "http://localhost:4873/once/-/once-1.4.0.tgz",
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
"dev": true,
"requires": {
"wrappy": "1"
}
},
"path-is-absolute": {
"version": "1.0.1",
"resolved": "http://localhost:4873/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
"dev": true
},
"wrappy": {
"version": "1.0.2",
"resolved": "http://localhost:4873/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
"dev": true
}
}
}

37
package.json

@ -1,37 +0,0 @@
{
"name": "@codefeathers/promise.object",
"version": "0.9.5",
"description": "Deep resolve promises in objects.",
"main": "es5/index.min.js",
"scripts": {
"test": "jasmine",
"build": "./build.sh"
},
"keywords": [
"Promise",
"A+",
"objects",
"deep resolve"
],
"author": "Muthu Kumar <@MKRhere> (https://mkr.pw)",
"contributors": [
"Thomas Rory Gummerson <@TRGWII> (https://rory.no)"
],
"repository": {
"type": "git",
"url": "git+https://github.com/codefeathers/Promise.object.git"
},
"bugs": {
"url": "https://github.com/codefeathers/Promise.object/issues"
},
"homepage": "https://github.com/codefeathers/Promise.object#readme",
"license": "MIT",
"devDependencies": {
"babel-cli": "^6.26.0",
"babel-plugin-transform-object-rest-spread": "^6.26.0",
"babel-preset-env": "^1.7.0",
"browserify": "^16.2.2",
"jasmine": "^3.1.0",
"uglify-js": "^3.4.0"
}
}

30
package.json.old

@ -0,0 +1,30 @@
{
"name": "@codefeathers/promise.object",
"version": "0.9.5",
"description": "Deep resolve promises in objects.",
"main": "es5/index.min.js",
"scripts": {
"test": "jasmine",
"build": "./build.sh"
},
"keywords": [
"Promise",
"A+",
"objects",
"deep resolve"
],
"author": "Muthu Kumar <@MKRhere> (https://mkr.pw)",
"contributors": [
"Thomas Rory Gummerson <@TRGWII> (https://rory.no)"
],
"repository": {
"type": "git",
"url": "git+https://github.com/codefeathers/Promise.object.git"
},
"bugs": {
"url": "https://github.com/codefeathers/Promise.object/issues"
},
"homepage": "https://github.com/codefeathers/Promise.object#readme",
"license": "MIT",
"devDependencies": {}
}

76
spec/PromiseObject.spec.js

@ -1,76 +0,0 @@
'use strict';
Promise.object = require('../es5/index.min.js');
// Simple object
const testObject1 = {
foo: Promise.resolve(1),
bar: {
foobar: Promise.resolve(2),
},
};
const resolvedObject1 = {
foo: 1,
bar: {
foobar: 2
},
};
// Nested promises with circular reference
const testObject2 = {
foo: Promise.resolve(1),
bar: {
foobar: Promise.resolve(2)
},
baz: [ 1, "two", Promise.resolve(3) ],
};
testObject2.link1 = testObject2;
testObject2.link2 = { link3: testObject2 };
const resolvedObject2 = {
foo: 1,
bar: {
foobar: 2,
},
baz: [ 1, "two", 3 ],
};
resolvedObject2.link1 = resolvedObject2;
resolvedObject2.link2 = { link3: resolvedObject2 };
// Deeply nested promises
const testObject3 = Promise.resolve({
foo: Promise.resolve({
bar: Promise.resolve(
Promise.resolve(5)
),
}),
});
const resolvedObject3 = {
foo: {
bar: 5,
},
};
/* global describe it expect */
describe("Promise.object", () => {
it("Should return resolvedObject1", () => {
return Promise.object(testObject1)
.then(obj => expect(obj).toEqual(resolvedObject1));
})
it("Should return resolvedObject2", () => {
return Promise.object(testObject2)
.then(obj => expect(obj).toEqual(resolvedObject2));
})
it("Should return resolvedObject3", () => {
return Promise.object(testObject3)
.then(obj => expect(obj).toEqual(resolvedObject3));
})
})

11
spec/support/jasmine.json

@ -1,11 +0,0 @@
{
"spec_dir": "spec",
"spec_files": [
"**/*[sS]pec.js"
],
"helpers": [
"helpers/**/*.js"
],
"stopSpecOnExpectationFailure": false,
"random": true
}

48
test.ts

@ -0,0 +1,48 @@
import { assertEquals } from "https://deno.land/std@0.178.0/testing/asserts.ts";
import { promiseObject } from "./index.ts";
// Simple object
const simple = {
test: { foo: Promise.resolve(1), bar: { foobar: Promise.resolve(2) } },
resolved: { foo: 1, bar: { foobar: 2 } },
};
// Nested promises with circular reference
const nested = {
test: (() => {
let o = {
foo: Promise.resolve(1),
bar: { foobar: Promise.resolve(2) },
baz: [1, "two", Promise.resolve(3)],
};
return Object.assign(o, { link1: o, link2: { link3: o } });
})(),
resolved: (() => {
const o = {
foo: 1,
bar: { foobar: 2 },
baz: [1, "two", 3],
};
return Object.assign(o, { link1: o, link2: { link3: o } });
})(),
};
// Deeply nested promises
const deeplyNested = {
test: Promise.resolve({ foo: Promise.resolve({ bar: Promise.resolve(Promise.resolve(5)) }) }),
resolved: { foo: { bar: 5 } },
};
Deno.test("Should resolve simple object", async () => {
assertEquals(await promiseObject(simple.test), simple.resolved);
});
Deno.test("Should resolve cyclic objects", async () => {
assertEquals(await promiseObject(nested.test), nested.resolved);
});
Deno.test("Should resolve deeply cyclic objects", async () => {
assertEquals(await promiseObject(deeplyNested.test), deeplyNested.resolved);
});
Loading…
Cancel
Save