Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

2.3.1 #100

Open
wants to merge 22 commits into
base: master
Choose a base branch
from
Open

2.3.1 #100

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
f83c868
Fix security vulnerabilities by updating dependency
ShadSterling Jan 1, 2019
e045360
Add TypeScript type declarations for programmaticRunner exports
ShadSterling Jan 14, 2019
f0f809a
Merge pull request #1 from ShadSterling/patch-1
ShadSterling Nov 17, 2022
fcde646
Merge pull request #2 from ShadSterling/patch-2
ShadSterling Nov 17, 2022
f7f1800
Update dependencies and bump version
ShadSterling Nov 17, 2022
36575ff
Merge pull request #3 from ShadSterling/2.2.X
ShadSterling Nov 17, 2022
607553f
Fix error in handwritten types
ShadSterling Nov 17, 2022
6811f93
Bump version for release
ShadSterling Nov 17, 2022
543a17a
Merge pull request #4 from ShadSterling/2.2.X
ShadSterling Nov 17, 2022
24c0a8b
Replace tshint with TypeScript, replace handwritten type declarations…
ShadSterling Nov 19, 2022
e2f648f
Add testFiles to make the repo a usable dependency independent of pub…
ShadSterling Nov 19, 2022
7f60e75
Merge pull request #5 from ShadSterling/2.2.X
ShadSterling Nov 19, 2022
3832fca
Replace var with let (outside of tests), nil with null
ShadSterling Nov 20, 2022
795b9d6
Fix TypeScript confusion by standardizing capitalization; confirm by …
ShadSterling Nov 20, 2022
9cb7d60
Update metadata for publication
ShadSterling Dec 28, 2022
9f36ea8
Fix broken links in README
ShadSterling Dec 28, 2022
34eb8e3
Merge branch 'master' into 2.3.X
ShadSterling Dec 28, 2022
0e65cf3
Merge pull request #6 from ShadSterling/2.3.X
ShadSterling Dec 28, 2022
940f6c6
Change NPM publication name to publish unscoped
ShadSterling Dec 28, 2022
ff83351
Merge pull request #7 from ShadSterling/rename
ShadSterling Dec 28, 2022
0e48669
Apply new name to instructions in README
ShadSterling Dec 28, 2022
b215210
Merge pull request #9 from ShadSterling/rename
ShadSterling Dec 28, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1 @@
/node_modules/
/npm-debug.log
lib/testFiles.js
25 changes: 12 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
<a href="http://promises-aplus.github.com/promises-spec">
<img src="http://promises-aplus.github.com/promises-spec/assets/logo-small.png"
align="right" alt="Promises/A+ logo" />
</a>
<a href="https://promisesaplus.com/"><img src="https://promisesaplus.com/assets/logo-small.png" align="right" alt="Promises/A+ logo" /></a>

# Promises/A+ Compliance Test Suite
# Promises/A+ Compliance Test Suite (refreshed)

This suite tests compliance of a promise implementation with the [Promises/A+ specification][].
This suite tests compliance of a promise implementation with the [Promises/A+ specification](https://github.com/promises-aplus/promises-spec).

[Promises/A+ specification]: https://github.com/promises-aplus/promises-spec
Passing the tests in this repo means that you have a Promises/A+ compliant implementation of the `then()` method, and you can display the [Promises/A+ logo](https://promisesaplus.com/assets/logo-small.png) in your README.

Passing the tests in this repo means that you have a Promises/A+ compliant implementation of the `then()` method, and you can display the Promises/A+ logo in your README. You can also [send a pull request](https://github.com/promises-aplus/promises-spec) to have your implementation listed on the [implementations page](https://promisesaplus.com/implementations).
The [original suite](https://github.com/promises-aplus/promises-tests) seems to have been abandoned; this fork passes [`npm audit`](https://docs.npmjs.com/auditing-package-dependencies-for-security-vulnerabilities) and adds [TypeScript](https://typescriptlang.org/) types, without changing any of the tests.

Before it was abandoned, you could also [send a pull request](https://github.com/promises-aplus/promises-spec) to have your implementation listed on the [implementations page](https://promisesaplus.com/implementations).

## How To Run

Expand Down Expand Up @@ -44,16 +43,16 @@ your implementation in `try`/`catch` when writing the adapter.
### From the CLI

This package comes with a command-line interface that can be used either by installing it globally with
`npm install promises-aplus-tests -g` or by including it in your `package.json`'s `devDependencies` and using npm's
`npm install promises-aplus-tests-refreshed -g` or by including it in your `package.json`'s `devDependencies` and using npm's
`scripts` feature. In the latter case, your setup might look something like

```json
{
"devDependencies": {
"promises-aplus-tests": "*"
"promises-aplus-tests-refreshed": "*"
},
"scripts": {
"test": "run-my-own-tests && promises-aplus-tests test/my-adapter"
"test": "run-my-own-tests && promises-aplus-tests-refreshed test/my-adapter"
}
}
```
Expand All @@ -66,7 +65,7 @@ tries to pass through any subsequent options to Mocha, so you can use e.g. `--re
The main export of this package is a function that allows you to run the tests against an adapter:

```js
var promisesAplusTests = require("promises-aplus-tests");
let promisesAplusTests = require("promises-aplus-tests-refreshed");

promisesAplusTests(adapter, function (err) {
// All done; output is in the console. Or check `err` for number of failures.
Expand All @@ -87,7 +86,7 @@ If you already have a Mocha test suite and want to include these tests in it, yo

```js
describe("Promises/A+ Tests", function () {
require("promises-aplus-tests").mocha(adapter);
require("promises-aplus-tests-refreshed").mocha(adapter);
});
```

Expand Down
2 changes: 2 additions & 0 deletions lib/cli.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#!/usr/bin/env node
export {};
18 changes: 9 additions & 9 deletions lib/cli.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
#!/usr/bin/env node
"use strict";

var path = require("path");
var getMochaOpts = require("./getMochaOpts");
var programmaticRunner = require("./programmaticRunner");
let path = require("path");
let getMochaOpts = require("./getMochaOpts");
let ProgrammaticRunner = require("./programmaticRunner");

var filePath = getAdapterFilePath();
var adapter = adapterObjectFromFilePath(filePath);
var mochaOpts = getMochaOpts(process.argv.slice(3));
programmaticRunner(adapter, mochaOpts, function (err) {
let filePath = getAdapterFilePath();
let adapter = adapterObjectFromFilePath(filePath);
let mochaOpts = getMochaOpts(process.argv.slice(3));
ProgrammaticRunner(adapter, mochaOpts, function (err) {
if (err) {
process.exit(err.failures || -1);
process.exit(err.failure_count || -1);
}
});

Expand All @@ -26,7 +26,7 @@ function adapterObjectFromFilePath(filePath) {
try {
return require(filePath);
} catch (e) {
var error = new Error("Error `require`ing adapter file " + filePath + "\n\n" + e);
let error = new Error("Error `require`ing adapter file " + filePath + "\n\n" + e);
error.cause = e;

throw error;
Expand Down
2 changes: 2 additions & 0 deletions lib/getMochaOpts.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
declare function _exports(args: any): {};
export = _exports;
10 changes: 5 additions & 5 deletions lib/getMochaOpts.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
"use strict";

module.exports = function getMochaOpts(args) {
var rawOpts = args;
var opts = {};
let rawOpts = args;
let opts = {};

rawOpts.join(" ").split("--").forEach(function (opt) {
var optSplit = opt.split(" ");
let optSplit = opt.split(" ");

var key = optSplit[0];
var value = optSplit[1] || true;
let key = optSplit[0];
let value = optSplit[1] || true;

if (key) {
opts[key] = value;
Expand Down
29 changes: 29 additions & 0 deletions lib/programmaticRunner.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
export = PromisesAPlusTests;
/** @type { PromisesAPlusTests.Export } */
declare function PromisesAPlusTests(adapter: PromisesAPlusTests.Adapter<any>, mocha_options_or_callback: any | PromisesAPlusTests.Callback, callback_or_omitted: PromisesAPlusTests.Callback | void): void;
declare namespace PromisesAPlusTests {
function mocha(implementation: Adapter<any>): void;
type Adapter<T> = {
resolved?: (value: T) => Promise<T>;
rejected?: (reason: any) => Promise<never>;
deferred: <U = T>() => PromisesAPlusTests.Deferred<U>;
};
type Callback = (error?: PromisesAPlusTests.TestError) => void;
type Deferred<T> = {
promise: Promise<T>;
resolve: (value: T) => void;
reject: (reason: any) => void;
};
type Export = (PromisesAPlusTests.TesterWithOptions | PromisesAPlusTests.TesterWithoutOptions) & PromisesAPlusTests.MochaTester;
type MaybeFailureCount = {
failure_count?: number;
};
type MochaTester = {
mocha: PromisesAPlusTests.MochaTestMethod;
};
type MochaTestMethod = (implementation: PromisesAPlusTests.Adapter<any>) => void;
type Tester = PromisesAPlusTests.TesterWithOptions & PromisesAPlusTests.TesterWithoutOptions;
type TestError = Error & PromisesAPlusTests.MaybeFailureCount;
type TesterWithOptions = (implementation: PromisesAPlusTests.Adapter<any>, mochaOptions: any, callback?: PromisesAPlusTests.Callback) => void;
type TesterWithoutOptions = (implementation: PromisesAPlusTests.Adapter<any>, callback?: PromisesAPlusTests.Callback) => void;
}
151 changes: 89 additions & 62 deletions lib/programmaticRunner.js
Original file line number Diff line number Diff line change
@@ -1,76 +1,103 @@
"use strict";

var Mocha = require("mocha");
var path = require("path");
var fs = require("fs");
var _ = require("underscore");
/** @typedef { { resolved?: ( value: T ) => Promise<T>, rejected?: ( reason: any ) => Promise<never>, deferred: <U=T>() => PromisesAPlusTests.Deferred<U> } } PromisesAPlusTests.Adapter @template T */
/** @typedef { ( error?: PromisesAPlusTests.TestError ) => void } PromisesAPlusTests.Callback */
/** @typedef { { promise: Promise<T>, resolve: ( value: T ) => void, reject: ( reason: any ) => void, } } PromisesAPlusTests.Deferred @template T */
/** @typedef { ( PromisesAPlusTests.TesterWithOptions | PromisesAPlusTests.TesterWithoutOptions ) & PromisesAPlusTests.MochaTester } PromisesAPlusTests.Export */
/** @typedef { { failure_count?: number } } PromisesAPlusTests.MaybeFailureCount */
/** @typedef { { mocha: PromisesAPlusTests.MochaTestMethod } } PromisesAPlusTests.MochaTester */
/** @typedef { ( implementation: PromisesAPlusTests.Adapter<any> ) => void } PromisesAPlusTests.MochaTestMethod */
/** @typedef { PromisesAPlusTests.TesterWithOptions & PromisesAPlusTests.TesterWithoutOptions } PromisesAPlusTests.Tester */
/** @typedef { Error & PromisesAPlusTests.MaybeFailureCount } PromisesAPlusTests.TestError */
/** @typedef { ( implementation: PromisesAPlusTests.Adapter<any>, mochaOptions: any, callback?: PromisesAPlusTests.Callback ) => void } PromisesAPlusTests.TesterWithOptions */
/** @typedef { ( implementation: PromisesAPlusTests.Adapter<any>, callback?: PromisesAPlusTests.Callback ) => void } PromisesAPlusTests.TesterWithoutOptions */

var testsDir = path.resolve(__dirname, "tests");
let Mocha = require("mocha");
let path = require("path");
let fs = require("fs");
let _ = require("underscore");

function normalizeAdapter(adapter) {
if (!adapter.resolved) {
adapter.resolved = function (value) {
var d = adapter.deferred();
d.resolve(value);
return d.promise;
};
}
let testsDir = path.resolve(__dirname, "tests");

if (!adapter.rejected) {
adapter.rejected = function (reason) {
var d = adapter.deferred();
d.reject(reason);
return d.promise;
};
}
/** @type { (adapter: PromisesAPlusTests.Adapter<any>) => void } */
function normalizeAdapter(adapter) {
if (!adapter.resolved) {
adapter.resolved = function (value) {
let d = adapter.deferred();
d.resolve(value);
return d.promise;
};
}
if (!adapter.rejected) {
adapter.rejected = function (reason) {
/** @type { PromisesAPlusTests.Deferred<never> } */
let d = adapter.deferred();
d.reject(reason);
return d.promise;
};
}
}

module.exports = function (adapter, mochaOpts, cb) {
if (typeof mochaOpts === "function") {
cb = mochaOpts;
mochaOpts = {};
}
if (typeof cb !== "function") {
cb = function () { };
}
/** @type { PromisesAPlusTests.Export } */
function PromisesAPlusTests (
/** @type { PromisesAPlusTests.Adapter<any> } */
adapter,
/** @type { any | PromisesAPlusTests.Callback } */
mocha_options_or_callback,
/** @type { PromisesAPlusTests.Callback | void } */
callback_or_omitted,
) {
let mochaOpts = {}
/** @type { PromisesAPlusTests.Callback } */
let cb = function () { };
if( mocha_options_or_callback && typeof mocha_options_or_callback !== "function" ) {
mochaOpts = mocha_options_or_callback;
if( typeof callback_or_omitted === "function" ) {
cb = callback_or_omitted;
}
} else if ( typeof mocha_options_or_callback === "function" ) {
cb = mocha_options_or_callback
}

normalizeAdapter(adapter);
mochaOpts = _.defaults(mochaOpts, { timeout: 200, slow: Infinity });
normalizeAdapter(adapter);
mochaOpts = _.defaults(mochaOpts, { timeout: 200, slow: Infinity });

fs.readdir(testsDir, function (err, testFileNames) {
if (err) {
cb(err);
return;
}
fs.readdir( testsDir, (err, testFileNames) => {
if (err) {
cb(err);
return;
}

var mocha = new Mocha(mochaOpts);
testFileNames.forEach(function (testFileName) {
if (path.extname(testFileName) === ".js") {
var testFilePath = path.resolve(testsDir, testFileName);
mocha.addFile(testFilePath);
}
});
let mocha = new Mocha(mochaOpts);
testFileNames.forEach( (testFileName) => {
if( path.extname(testFileName) === ".js" ) {
let testFilePath = path.resolve( testsDir, testFileName );
mocha.addFile(testFilePath);
}
});

global.adapter = adapter;
mocha.run(function (failures) {
delete global.adapter;
if (failures > 0) {
var err = new Error("Test suite failed with " + failures + " failures.");
err.failures = failures;
cb(err);
} else {
cb(null);
}
});
});
global.adapter = adapter;
mocha.run( (failures) => {
delete global.adapter;
if (failures > 0) {
/** @type { PromisesAPlusTests.TestError } */
let err = new Error("Test suite failed with " + failures + " failures.");
err.failure_count = failures;
cb(err);
} else {
cb();
}
} );
} );
};

module.exports.mocha = function (adapter) {
normalizeAdapter(adapter);

global.adapter = adapter;

require("./testFiles");

delete global.adapter;
/** @type { PromisesAPlusTests.MochaTestMethod } */
PromisesAPlusTests.mocha = function mocha(adapter) {
normalizeAdapter(adapter);
global.adapter = adapter;
require("./testFiles");
delete global.adapter;
};

/** @type { PromisesAPlusTests.Export } */
module.exports = PromisesAPlusTests
1 change: 1 addition & 0 deletions lib/testFiles.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export {};
14 changes: 14 additions & 0 deletions lib/testFiles.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
"use strict";
require("./tests/2.1.2");
require("./tests/2.1.3");
require("./tests/2.2.1");
require("./tests/2.2.2");
require("./tests/2.2.3");
require("./tests/2.2.4");
require("./tests/2.2.5");
require("./tests/2.2.6");
require("./tests/2.2.7");
require("./tests/2.3.1");
require("./tests/2.3.2");
require("./tests/2.3.3");
require("./tests/2.3.4");
1 change: 1 addition & 0 deletions lib/tests/2.1.2.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export {};
1 change: 1 addition & 0 deletions lib/tests/2.1.3.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export {};
1 change: 1 addition & 0 deletions lib/tests/2.2.1.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export {};
2 changes: 2 additions & 0 deletions lib/tests/2.2.1.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
"use strict";

require("./2.2.1"); // Using an "import form" tells TypeScript that this is a module that can be required by other scripts

var adapter = global.adapter;
var resolved = adapter.resolved;
var rejected = adapter.rejected;
Expand Down
1 change: 1 addition & 0 deletions lib/tests/2.2.2.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export {};
1 change: 1 addition & 0 deletions lib/tests/2.2.3.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export {};
1 change: 1 addition & 0 deletions lib/tests/2.2.4.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export {};
1 change: 1 addition & 0 deletions lib/tests/2.2.5.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export {};
Loading