{"id":16255301,"url":"https://github.com/qubyte/es2015-deferred","last_synced_at":"2025-09-22T18:22:00.382Z","repository":{"id":44778584,"uuid":"54579821","full_name":"qubyte/es2015-deferred","owner":"qubyte","description":"A tiny constructor for deferred objects. Useful for stubbing promises in tests.","archived":false,"fork":false,"pushed_at":"2023-11-24T13:47:35.000Z","size":384,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2024-04-25T06:43:27.803Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/qubyte.png","metadata":{"files":{"readme":"README.md","changelog":"HISTORY.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-03-23T17:29:26.000Z","updated_at":"2022-01-25T11:38:34.000Z","dependencies_parsed_at":"2023-11-24T14:49:02.912Z","dependency_job_id":null,"html_url":"https://github.com/qubyte/es2015-deferred","commit_stats":{"total_commits":124,"total_committers":5,"mean_commits":24.8,"dds":0.5161290322580645,"last_synced_commit":"f43ab7726c8cca1c4de323fb0aa87952946c0871"},"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/qubyte%2Fes2015-deferred","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/qubyte%2Fes2015-deferred/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/qubyte%2Fes2015-deferred/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/qubyte%2Fes2015-deferred/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/qubyte","download_url":"https://codeload.github.com/qubyte/es2015-deferred/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247847614,"owners_count":21006100,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-10T15:29:22.500Z","updated_at":"2025-09-22T18:22:00.363Z","avatar_url":"https://github.com/qubyte.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"This project has [moved to codeberg](https://codeberg.org/qubyte/es2015-deferred).\n\n# ES2015 Deferred\n\nThis library contains a small constructor which produces deferred objects. These\nare useful for testing purposes, and their use in production JS is discouraged\n(it's usually better to use the promise constructor directly).\n\nThis module has no production dependencies.\n\n\u003e [!Note]\n\u003e JavaScript now has a built-in to achieve most of what this module does, and you\n\u003e should use it when possible.\n\u003e\n\u003e ```javascript\n\u003e // Before:\n\u003e const { promise, resolve, reject } = Deferred();\n\u003e\n\u003e // After:\n\u003e const { promise, resolve, reject } = Promise.withResolvers();\n\u003e ```\n\u003e\n\u003e The one nuance to be aware of is that `resolve` and `reject` from this library\n\u003e return `promise`, whereas `resolve` and `reject` from `withResolvers` return\n\u003e `undefined`.\n\n## installation\n\n```\nnpm i es2015-deferred\n```\n\n### ES2015\n\nES2015 module loaders can directly consume `index.js`. If you're using\n[rollup](http://rollupjs.org) or another ES2015 compatible module loader\nconfigured to look for the [`module`](./package.json#L6) field and in a\n`package.json` file, then you can import with:\n\n```javascript\nimport Deferred from 'es2015-deferred';\n```\n\nThe\n[@rollup/plugin-node-resolve](https://github.com/rollup/plugins/tree/master/packages/node-resolve)\npackage may be useful to you.\n\nIf you want to try this module out directly without installation, it can be used\nvia unpkg:\n\n```javascript\nimport Deferred from 'https://unpkg.com/es2015-deferred';\n```\n\n## API\n\nWith `Deferred` in your environment you can create `deferred` objects.\n\n```javascript\nvar deferred = new Deferred();\n\n// new is optional...\n\nvar deferred = Deferred();\n```\n\nA promise is managed by the deferred object.\n\n```javascript\nvar promise = deferred.promise;\n```\n\nResolve `deferred.promise` with a given value.\n\n```javascript\ndeferred.resolve('a-resolution');\n```\n\nReject `deferred.promise` with an error.\n\n```javascript\ndeferred.reject(new Error('Oh noes!'));\n```\n\nResolve and reject return the promise for easy chaining, e.g.\n\n```javascript\ndeferred.resolve('a-resolution').then(/* ... */);\n```\n\n## example\n\nThis module is intended for use with unit test runners like\n[mocha](http://mochajs.org/). Let's say you want to test a module which makes a\nrequest using\n[fetch](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch)\nand parses the response as JSON:\n\n```javascript\nexport default function fetchAndParse(url) {\n  return self.fetch(url).then(response =\u003e {\n    if (!response.ok) {\n      throw new Error(`Unexpected response: ${response.status}`);\n    }\n\n    return response.json();\n  });\n}\n```\n\nFetch uses promises, so testing it can be tricky! Here's a set of tests for this\nmodule written in mocha and sinon. What follows is bulky, but exhaustive. It can\nbe surprising how much branching promises hide!\n\n```javascript\nimport assert from 'assert';\nimport sinon from 'sinon';\nimport fetchAndParse from './fetchAndParse';\n\n// For failing tests on promises which should reject but do not.\nfunction failResolve() {\n  throw new Error('Promise should reject.');\n}\n\ndescribe('fetchAndParse', () =\u003e {\n  const sandbox = sinon.sandbox.create();\n\n  let fetchDeferred;\n  let promise;\n\n  beforeEach(() =\u003e {\n    fetchDeferred = new Deferred();\n\n    // Stub fetch with a function which returns a promise we control.\n    sandbox.stub(self, 'fetch').returns(fetchDeferred.promise);\n\n    // Using a deferred above means we can use this promise throughout\n    // the tests, resolve or rejecting steps as we go along. A deferred\n    // allows test cases to be built progressively as describe nest.\n    promise = fetchAndParse('some-url');\n  });\n\n  afterEach(() =\u003e {\n    sandbox.reset();\n  });\n\n  it('calls fetch with the given url', () =\u003e {\n    assert.equal(self.fetch.callCount, 1);\n    assert.ok(self.fetch.calledWithExactly('some-url'));\n  });\n\n  describe('when the call to fetch rejects', () =\u003e {\n    let error;\n\n    beforeEach(() =\u003e {\n      error = new Error();\n\n      // By rejecting here, the promise set up above gets is rejected.\n      fetchDeferred.reject(error);\n    });\n\n    it('rejects the promise returned from fetchAndParse with the same error', () =\u003e {\n      // Mocha treats a resolved promise as a success. This line\n      // converts and checks rejected promises to resolved, and turns\n      // resolve promises to rejections before returning for mocha.\n      return promise.then(\n        failResolve,\n        err =\u003e assert.equal(err, error)\n      );\n    });\n  });\n\n  describe('when the call to fetch resolves with an unsuccessful status', () =\u003e {\n    beforeEach(() =\u003e {\n      // Fetch resolves to a response object. Instruct the deferred\n      // object to follow that behaviour.\n      fetchDeferred.resolve({\n        ok: false,\n        status: 404\n      });\n    });\n\n    it('rejects with an unexpected response error', () =\u003e {\n      return promise.then(failResolve, err =\u003e {\n        assert.ok(err instanceof Error);\n        assert.equal(err.message, 'Unexpected response: 404');\n      });\n    });\n  });\n\n  describe('when the call to fetch resolves with a successful status', () =\u003e {\n    let jsonDeferred;\n    let response;\n\n    beforeEach(() =\u003e {\n      // The json method of the response returns a promise. Use a deferred\n      // object to manage that.\n      jsonDeferred = new Deferred();\n\n      response = {\n        ok: true,\n        json: sansbox.stub().returns(jsonDeferred.promise);\n      };\n\n      fetchDeferred.resolve(response);\n    });\n\n    it('calls the json method of the response object', () =\u003e {\n      return fetchDeferred.promise.then(() =\u003e assert.equal(response.json.callCount, 1));\n    });\n\n    describe('when response.json rejects', () =\u003e {\n      let error;\n\n      beforeEach(() =\u003e {\n        error = new Error();\n\n        jsonDeferred.reject(error);\n      });\n\n      it('rejects the promise returned from fetchAndParse with the same error', () =\u003e {\n        return promise.then(\n          failResolve,\n          err =\u003e assert.equal(err, error)\n        );\n      });\n    });\n\n    describe('when response.json resolves', () =\u003e {\n      beforeEach(() =\u003e {\n        jsonDeferred.resolve('parsed-response-body')\n      });\n\n      it('resolves the promise returned from fetchAndParse with the result', () =\u003e {\n        return promise.then(result =\u003e assert.equal(result, 'parsed-response-body'));\n      });\n    });\n  });\n});\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fqubyte%2Fes2015-deferred","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fqubyte%2Fes2015-deferred","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fqubyte%2Fes2015-deferred/lists"}