pax_global_header 0000666 0000000 0000000 00000000064 14132327775 0014525 g ustar 00root root 0000000 0000000 52 comment=67d88df838a329c8d87937e9247b9cba032f1f85
tad-3.1.0/ 0000775 0000000 0000000 00000000000 14132327775 0012276 5 ustar 00root root 0000000 0000000 tad-3.1.0/.editorconfig 0000664 0000000 0000000 00000000446 14132327775 0014757 0 ustar 00root root 0000000 0000000 # EditorConfig is awesome: http://EditorConfig.org
# top-most EditorConfig file
root = true
[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
indent_style = tab
trim_trailing_whitespace = true
[*.{md,yml}]
indent_size = 2
indent_style = space
trim_trailing_whitespace = false
tad-3.1.0/.eslintignore 0000664 0000000 0000000 00000000023 14132327775 0014774 0 ustar 00root root 0000000 0000000 /test/__playground
tad-3.1.0/.github/ 0000775 0000000 0000000 00000000000 14132327775 0013636 5 ustar 00root root 0000000 0000000 tad-3.1.0/.github/FUNDING.yml 0000664 0000000 0000000 00000000020 14132327775 0015443 0 ustar 00root root 0000000 0000000 github: medikoo
tad-3.1.0/.github/workflows/ 0000775 0000000 0000000 00000000000 14132327775 0015673 5 ustar 00root root 0000000 0000000 tad-3.1.0/.github/workflows/integrate.yml 0000664 0000000 0000000 00000002163 14132327775 0020402 0 ustar 00root root 0000000 0000000 # main only
name: Integrate
on:
push:
branches: [main]
env:
FORCE_COLOR: 1
jobs:
tagIfNewVersion:
name: Tag if new version
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v2
with:
# Ensure to have complete history of commits pushed with given push operation
# It's loose and imperfect assumption that no more than 30 commits will be pushed at once
fetch-depth: 30
# Tag needs to be pushed with real user token, otherwise pushed tag won't trigger the actions workflow
# Hence we're passing 'serverless-ci' user authentication token
token: ${{ secrets.USER_GITHUB_TOKEN }}
- name: Tag if new version
if: github.event.before != '0000000000000000000000000000000000000000' # Skip on first commit
run: |
NEW_VERSION=`git diff -U0 ${{ github.event.before }} package.json | grep '"version": "' | tail -n 1 | grep -oE "[0-9]+\.[0-9]+\.[0-9]+"` || :
if [ -n "$NEW_VERSION" ];
then
git tag v$NEW_VERSION
git push --tags
fi
tad-3.1.0/.github/workflows/publish.yml 0000664 0000000 0000000 00000003327 14132327775 0020071 0 ustar 00root root 0000000 0000000 # Version tags only
name: Publish
on:
push:
tags:
- v[0-9]+.[0-9]+.[0-9]+
jobs:
publish:
name: Publish
runs-on: ubuntu-latest
env:
# It'll work with secrets.GITHUB_TOKEN (which is provided by GitHub unconditionally)
# Still then release author would be "github-actions"
GITHUB_TOKEN: ${{ secrets.USER_GITHUB_TOKEN }}
steps:
- name: Checkout repository
uses: actions/checkout@v2
- name: Retrieve dependencies from cache
uses: actions/cache@v2
with:
path: |
~/.npm
node_modules
key: npm-v14-${{ runner.os }}-refs/heads/main-${{ hashFiles('package.json') }}
- name: Install Node.js and npm
uses: actions/setup-node@v1
with:
node-version: 14.x
registry-url: https://registry.npmjs.org
- name: Publish new version
# Note: Setting NODE_AUTH_TOKEN as job|workspace wide env var won't work
# as it appears actions/setup-node sets own value
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
run: npm publish
# Normally we have a guarantee that deps are already there, still it may not be the case when:
# - `main` build for same commit failed (and we still pushed tag manually)
# - We've pushed tag manually before `master` build finalized
- name: Install dependencies
if: steps.cacheNpm.outputs.cache-hit != 'true'
run: |
npm update --no-save
npm update --save-dev --no-save
- name: Publish release notes
run: |
TEMP_ARRAY=($(echo $GITHUB_REF | tr "/" "\n"))
TAG=${TEMP_ARRAY[@]: -1}
npx github-release-from-cc-changelog $TAG
tad-3.1.0/.github/workflows/validate.yml 0000664 0000000 0000000 00000002150 14132327775 0020205 0 ustar 00root root 0000000 0000000 # PR's only
name: Validate
on:
pull_request:
branches: [main]
env:
FORCE_COLOR: 1
jobs:
linuxNode14:
name: "[Linux] Node.js v14: Lint, Formatting"
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v2
- name: Retrieve dependencies from cache
id: cacheNpm
uses: actions/cache@v2
with:
path: |
~/.npm
node_modules
key: npm-v14-${{ runner.os }}-${{ github.ref }}-${{ hashFiles('package.json') }}
restore-keys: |
npm-v14-${{ runner.os }}-${{ github.ref }}-
npm-v14-${{ runner.os }}-refs/heads/main-
- name: Install Node.js and npm
uses: actions/setup-node@v1
with:
node-version: 14.x
- name: Install dependencies
if: steps.cacheNpm.outputs.cache-hit != 'true'
run: |
npm update --no-save
npm update --save-dev --no-save
- name: Validate Prettier formatting
run: npm run prettier-check:updated
- name: Validate ESLint rules
run: npm run lint:updated
tad-3.1.0/.gitignore 0000664 0000000 0000000 00000000057 14132327775 0014270 0 ustar 00root root 0000000 0000000 /node_modules
npm-debug.log
/package-lock.json
tad-3.1.0/.npmignore 0000664 0000000 0000000 00000000064 14132327775 0014275 0 ustar 00root root 0000000 0000000 /.editorconfig
/.github
/commitlint.config.js
/test
tad-3.1.0/CHANGELOG.md 0000664 0000000 0000000 00000005731 14132327775 0014115 0 ustar 00root root 0000000 0000000 # Changelog
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
## [3.1.0](https://github.com/medikoo/tad/compare/v3.0.1...v3.1.0) (2021-10-15)
### Features
- Ignore `*.config.js` files when auto-indexing ([1d9ddf2](https://github.com/medikoo/tad/commit/1d9ddf288e8998dc75235647acf046d9e7ea7650))
### Maintenance Improvements
- Upgrade `cli-color` to v2 ([a087ea0](https://github.com/medikoo/tad/commit/a087ea0e89d47b912d99990e6b7e0b56891f7b0e))
- Upgrade `ncjsm` to v4 ([6beead0](https://github.com/medikoo/tad/commit/6beead03f33f5008d27d7f9a58a16dc92be4d563))
### [3.0.1](https://github.com/medikoo/tad/compare/v3.0.0...v3.0.1) (2019-08-30)
### Bug Fixes
- Catch orphaned assertions and expose them as errors ([987e692](https://github.com/medikoo/tad/commit/987e692))
- Let process to gracefully exit ([aa28832](https://github.com/medikoo/tad/commit/aa28832))
## [3.0.0](https://github.com/medikoo/tad/compare/v2.0.1...v3.0.0) (2019-08-30)
### Bug Fixes
- Recognize signatures of async and arrow functions ([7817b0a](https://github.com/medikoo/tad/commit/7817b0a))
### Features
- Ensure to expose unhandled rejections as crashes ([619dfab](https://github.com/medikoo/tad/commit/619dfab))
- Support thenable test returns ([ad83077](https://github.com/medikoo/tad/commit/ad83077))
### BREAKING CHANGES
- Drop support for Node.js versions lower than v0.11.8
- Due to implied thenable support. Objects which have `then`
method, and are result of test functions, are no longer processed
further as test dictionaries but instead are processed as promises
## [2.0.1](https://github.com/medikoo/tad/compare/v2.0.0...v2.0.1) (2019-04-30)
### Bug Fixes
- ensure ncjsm as normal dependency ([01913b9](https://github.com/medikoo/tad/commit/01913b9))
# [2.0.0](https://github.com/medikoo/tad/compare/v1.0.0...v2.0.0) (2019-04-30)
### Bug Fixes
- Ensure Node.js v12 support ([eabc639](https://github.com/medikoo/tad/commit/eabc639))
### chore
- bump dependencies ([36e44d1](https://github.com/medikoo/tad/commit/36e44d1))
### Features
- remove outdated 'next' dependency ([88da6ff](https://github.com/medikoo/tad/commit/88da6ff))
### BREAKING CHANGES
- Drop support for Node.js v0.10.16 and below
# [1.0.0](https://github.com/medikoo/tad/compare/v0.2.8...v1.0.0) (2019-02-22)
### chore
- rename binary file to tad.js ([5289439](https://github.com/medikoo/tad/commit/5289439))
### Features
- skip js files starting with '.' in automatic testing ([cce5af6](https://github.com/medikoo/tad/commit/cce5af6))
### BREAKING CHANGES
- Binary file direct name was renamed from bin/tad into bin/tad.js
- JS files starting with '.' are not considered as modules to be tested
## [0.2.8](https://github.com/medikoo/tad/compare/v0.2.7...v0.2.8) (2018-09-14)
### Bug Fixes
- support for Node.js version prior v0.12 ([4267dbf](https://github.com/medikoo/tad/commit/4267dbf))
tad-3.1.0/CHANGES 0000664 0000000 0000000 00000007533 14132327775 0013301 0 ustar 00root root 0000000 0000000 v0.2.7 -- 2016.10.19
* Do not crash in case there are no files to test
v0.2.6 -- 2016.09.01
* Ensure to not test files that are ignored by .gitignore rules
v0.2.5 -- 2016.08.30
* Fix process exit handling. Process didn't end gracefully when test reported errors.
It may made some following exceptions hidden
v0.2.4 -- 2015.10.14
* Fix automatic lines resolution (in case no message is provided)
v0.2.3 -- 2015.06.08
* Ignore by default 'examples' folder
* Update up to changes in cli-color
v0.2.2 -- 2015.03.14
* Fix index resolution, so it's not affected by Symbol polyfill workaround
v0.2.1 -- 2015.01.22
* Make assertion messages optional. If message is not provided line and
column number of assertion is provided instead
* Fix issue in assert headings resolution
* Configure lint scripts
* Fix LICENSE spelling
v0.2.0 -- 2014.04.27
* Move lib/suite.js so it's index.js module
* Remove special handling for `lib` module
* Cleanup organization of modules in lib folder
* Update internals to use latest versions of dependencies
* Remove Makefile (it's environment agnostic project)
v0.1.21 -- 2014.02.18
* Support NaN comparision in assert.strictEqual
* Support CONSTANT_NAME convention for index validation
v0.1.20 -- 2013.10.25
* `h1`, `h2`, `h3`, `h4`, `h5`, `h6` methods on assert, which allow inline
customization of message prefixes
v0.1.19 -- 2013.09.02
* Workaround for [test package issue](https://github.com/Gozala/test-commonjs/pull/8)
of no support for Object.create(null) objects
v0.1.18 -- 2013.08.28
* Fix optional context handling in indexTest
* Better error reporting in case of not compliant text configurations
v0.1.17 -- 2013.08.08
* Fix context in smart index tests
* Ignore rules handling (provided via .testignore files)
* Ignore specific (test, node_modules etc.) folders in index resolution
* Fix leading path resolution (minor)
* Internal logic improvements
* Lint cleanup
v0.1.16 -- 2013.05.15
* Smart resolution of testable modules if TAD run on main package folder
v0.1.15 -- 2013.03.14
* Fix path resolution (bug exposed with Node v0.10)
v0.1.14 -- 2013.03.11
* Support error.code in assert.throws
* Add missing licence file
* Fix error stringification for console output
v0.1.13 -- 2013.01.10
* Ignore test folder if tad run on main package folder
v0.1.12 -- 2012.10.11
* Support modules that export `null`
v0.1.11 -- 2012.10.04
* Maintenance:
* Update to latest versions of dependencies
* Convention and lint cleanup
* Print long stack traces on error
* When testing index content do not take into account directories
staring with '_'
v0.1.10 -- 2012.08.06
* Removed descriptor usage from logger, it caused error on Node v0.6
in v0.2 branch of event-emitter package (V8 bug)
v0.1.9 -- 2012.06.13
* Depend on v0.5 release of deferred
v0.1.8 -- 2012.05.28
* Do not allow install on pre v0.6.6 Node.js version
* Configure binary as binary in package.json
v0.1.7 -- 2012.05.28
* Fix name (from path) resolution
* npm friendly package.json
* Exit process at actual process exit (before we forced exit of process right
after tests were completed, that forced exit not finished background
processes)
* Update es5-ext to latest (v0.8) version
v0.1.6 -- 2012.03.22
Fixes:
* Correct input paths handling (should be bulletproof on both *nix and windows)
Improvements:
* JSLint code validation
v0.1.5 -- 2012.01.22
* Better diff on deep asserts error notifications
* Update dependencies to newest version
* Travis CI configuration
v0.1.4 -- 2012.01.05
* Index test now accepts ignores list
v0.1.3 -- 2011.12.22
* Windows support (small fix: use process.cwd() instead of process.env.PWD)
v0.1.2 -- 2011.12.22
* Proper exit codes
* When checking index consistency ignore filenames prefixed with '_'
v0.1.1 -- 2011.12.22
* Custom scopes are now searched up tree
v0.1.0 -- 2011.08.08
* Initial version
tad-3.1.0/LICENSE 0000664 0000000 0000000 00000001405 14132327775 0013303 0 ustar 00root root 0000000 0000000 ISC License
Copyright (c) 2012-2019, Mariusz Nowak, @medikoo, medikoo.com
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
tad-3.1.0/README.md 0000664 0000000 0000000 00000007075 14132327775 0013566 0 ustar 00root root 0000000 0000000 # TAD - JavaScript test suite
Goal of this framework is to allow writing tests with minimal hassle.
TAD will locate your test file, and provide tested module for your test functions.
Example console output:
- [Installation](#installation)
- [Usage](#usage)
_ [File managment](#usage-file-management)
_ [Test files](#usage-test-files)
_ [Test functions](#usage-test-functions)
_ [Assertions](#usage-assertions) \* [Running tests](#usage-running-tests)
- [TODO](#todo)
## Installation
$ npm install tad
## Usage
### File management
Keep your tests in _test_ folder. For each file in in main folder have corresponding test file in
_test_ folder.
### Test files
Tests should be written as set of functions, it can be just one function:
```js
module.exports = function (t, a, d) {
// tests
};
```
or many thematically grouped functions:
```js
exports["Test this"] = function (t, a, d) {
// tests
};
exports["Test that"] = function (t, a, d) {
// tests
};
```
### Test functions
Arguments passed to test functions are:
- **t** - Tested module
- **a** - Assert object
- **d** - _Done_ function, it's for tests that need to be run asynchronously.
You may pass additional block of tests to this
function and they'll be run right after. _d_ argument makes no sense for
synchrounous tests, declare such tests without it.
All arguments are optional, and by the way function is declared suite detect
which arguments should be passed to test function. Examples:
- Asynchronous test:
```js
exports["Some tests"] = funtcion (t, a, d) {
// tests
setTimeout(function () {
// tests
d();
}, 100);
};
```
- Synchronous test:
```js
exports["Some tests"] = function (t, a) {
// tests
};
```
Tests can be nested, and declared various ways (synchronous/asynchronous)
```js
module.exports["Test all"] = function (t, a) {
// Preparation code
// ... tests ...
return {
"Test this": function () {
// We already have module and assert object
// ... tests ...
},
"Test that async way": function (d) {
// This one is asynchronous
// ... tests ....
seTimeout(function () {
// ... tests ...
d({
"Some extra tests": function () {
// ... tests ...
}
});
}, 100);
}
};
};
```
### Assertions
TAD uses assert object from [UncommonJS tests runner](https://github.com/Gozala/test-commonjs/),
It's API is nearly same as of _assert_ that can be found in Node. Full spec is available at
https://github.com/kriskowal/uncommonjs/blob/master/tests/specification.md .
TAD adds some extra sugar to UncommonJS Assert object:
- `a === a.strictEqual`, so you can write your assertions as:
```js
a(shouldBeTrue, true, "It's true");
// it has same effect as:
a.strictEqual(shouldBeTrue, true, "It's true");
```
- `a.not` is an alias for `a.notStrictEqual`
- `a.deep` is an alias for `a.deepEqual`
- `a.notDeep` is an alias for `a.notDeepEqual`
- `assert.never` with that you can check function paths that should never be called.
### Running tests
Test your file with provided binary:
$ bin/tad lib/test-file
or test all files in path:
$ bin/tad lib
## TODO
- Full custom context support
- Code coverage
- TAP support
- jslint, jshint as side validation option
- Port tests to browsers
tad-3.1.0/bin/ 0000775 0000000 0000000 00000000000 14132327775 0013046 5 ustar 00root root 0000000 0000000 tad-3.1.0/bin/tad.js 0000775 0000000 0000000 00000003762 14132327775 0014167 0 ustar 00root root 0000000 0000000 #!/usr/bin/env node
"use strict";
require("essentials");
var compact = require("es5-ext/array/#/compact")
, flatten = require("es5-ext/array/#/flatten")
, endsWith = require("es5-ext/string/#/ends-with")
, deferred = require("deferred")
, path = require("path")
, findRoot = require("next/module/find-package-root")
, readdir = require("fs2/readdir")
, stat = require("fs2/stat")
, argv = require("optimist")
.usage("Usage: $0 [options] [paths]")
.boolean(["a", "m"])
.describe("a", "Display all tests names, including passed")
.describe("m", "Minimise output, verbose only for fails or errors").argv;
var extname = path.extname
, resolve = path.resolve
, initSuite = require("..");
if (!argv._.length) argv._ = ["."];
require("../lib/tad-ignore-mode");
deferred
.map(argv._, function (inputPath) {
if (inputPath !== ".") return inputPath;
inputPath = resolve(".");
return findRoot(resolve(inputPath, "x"))(function (root) {
if (root !== inputPath) return inputPath;
return readdir(inputPath, {
type: { file: true, directory: true },
ignoreRules: ["git", "tad"]
})
.map(function (name) {
var filename = resolve(inputPath, name);
return stat(resolve(inputPath, name))(function (stats) {
if (stats.isDirectory()) {
if (name === "node_modules") return null;
if (name === "bin") return null;
if (name === "test") return null;
if (name === "examples") return null;
return filename;
}
if (extname(name) !== ".js") return null;
if (name[0] === ".") return null;
if (endsWith.call(name, ".config.js")) return null;
return filename;
});
})
.invoke(compact);
});
})(function (paths) {
return initSuite(
flatten.call(paths), argv
)(function (suite) {
var suiteConsole = suite.console;
process.on("exit", function () {
if (suiteConsole.errored) process.exitCode = 2;
else if (suiteConsole.failed) process.exitCode = 1;
});
});
})
.done();
tad-3.1.0/commitlint.config.js 0000664 0000000 0000000 00000001236 14132327775 0016261 0 ustar 00root root 0000000 0000000 "use strict";
module.exports = {
rules: {
"body-leading-blank": [2, "always"],
"body-max-line-length": [2, "always", 72],
"footer-leading-blank": [2, "always"],
"footer-max-line-length": [2, "always", 72],
"header-max-length": [2, "always", 72],
"scope-case": [2, "always", "start-case"],
"scope-enum": [2, "always", [""]],
"subject-case": [2, "always", "sentence-case"],
"subject-empty": [2, "never"],
"subject-full-stop": [2, "never", "."],
"type-case": [2, "always", "lower-case"],
"type-empty": [2, "never"],
"type-enum": [
2, "always",
["build", "chore", "ci", "docs", "feat", "fix", "perf", "refactor", "style", "test"]
]
}
};
tad-3.1.0/index.js 0000775 0000000 0000000 00000007577 14132327775 0013766 0 ustar 00root root 0000000 0000000 /* eslint max-lines: "off" */
"use strict";
var spread = require("es5-ext/function/#/spread")
, deferred = require("deferred")
, path = require("path")
, commonPath = require("path2/common")
, runInContext = require("vm").runInContext
, out = require("./lib/console")
, configure = require("./lib/configure")
, load = require("./lib/load")
, run = require("./lib/run");
var resolve = path.resolve, map = Array.prototype.map, suite, isError;
isError = function (e, context) {
if (e instanceof Error) return true;
if (context !== global) {
return runInContext("(function () { return this instanceof Error; })", context).call(e);
}
return false;
};
suite = {
init: function (paths, options) {
var conf, d, projectRoot;
d = deferred();
paths = map.call(paths, function (testPath) { return resolve(testPath); });
this.resolve = d.resolve;
this.console = out(options);
this.tail = deferred(null);
if (paths.length > 1) {
projectRoot = commonPath.apply(null, paths);
this.rindex = projectRoot ? projectRoot.length + 1 : 0;
} else if (paths.length) {
this.rindex = paths[0].length + 1;
}
conf = configure(paths);
conf("data", this.ondata.bind(this));
conf("end", this.onend.bind(this));
return d.promise;
},
ondata: function () { this.tail = this.tail(spread.call(this.process).bind(this, arguments)); },
process: function (modulePath, fpath, tpath, context) {
var pname = modulePath.slice(this.rindex), fname, logger, testModuleConfig, d;
d = deferred();
this.console.break();
if (fpath instanceof Error) {
// Wrong path
this.console.error(pname, null, fpath);
return d.resolve();
}
fname = fpath.slice(this.rindex);
if (tpath instanceof Error) {
if (tpath.type === "testfile") {
// Input is a test file, ignore
return d.resolve();
}
// Could not assume test file path (not within package)
// or there were problems with obtaining context
this.console.error(pname, fname, tpath);
return d.resolve();
}
// Configured ok, load files
testModuleConfig = load(fpath, tpath, context);
// Any files missing, any evaluation errors ?
if (testModuleConfig.testee === undefined) {
// File not accessible
this.console.error(pname, fname, "Couldn't load module '" + fpath + "'");
return d.resolve();
}
if (isError(testModuleConfig.test, context)) {
this.console.error(pname, fname, testModuleConfig.test);
return d.resolve();
}
if (isError(testModuleConfig.testee, context)) {
this.console.error(pname, fname, testModuleConfig.testee);
return d.resolve();
}
if (!testModuleConfig.test) {
this.console.error(pname, fname, "Tests could not be loaded, tried '" + tpath + "'");
return d.resolve();
}
// Loaded ok, run tests
logger = run(testModuleConfig.testee, testModuleConfig.test);
logger.on(
"data",
function (testResult) {
if (d.resolved) {
var error = new Error(
"Unexpected state: Assertions are issued after suite finalized test run"
);
// Create error in test context (to expose proper stack trace)
// Throw in other context to avoid catch clause
process.nextTick(function () { throw error; });
return;
}
var name = [fname].concat(testResult.msg);
if (testResult.type === "pass") {
name.push(testResult.data);
} else if (testResult.type === "fail" && testResult.data.operator) {
name.push(testResult.data.message);
}
name = name.filter(Boolean).join(": ");
this.console[testResult.type](fname, name, testResult.data);
}.bind(this)
);
logger.on("end", function () { d.resolve(); });
return d.promise;
},
onend: function () {
this.tail(this.end.bind(this)).done();
delete this.tail;
},
end: function () {
this.console.end();
this.resolve(this);
}
};
module.exports = function (paths, options) { return Object.create(suite).init(paths, options); };
tad-3.1.0/lib/ 0000775 0000000 0000000 00000000000 14132327775 0013044 5 ustar 00root root 0000000 0000000 tad-3.1.0/lib/assert.js 0000664 0000000 0000000 00000007676 14132327775 0014723 0 ustar 00root root 0000000 0000000 "use strict";
var isFunction = require("es5-ext/function/is-function")
, assign = require("es5-ext/object/assign")
, isValue = require("es5-ext/object/is-value")
, eq = require("es5-ext/object/eq")
, map = require("es5-ext/object/map")
, isRegExp = require("es5-ext/reg-exp/is-reg-exp")
, Assert = require("test/assert").Assert;
var never
, neverBind
, throws
, resolveMessage
, wrapAssert
, lineRe = /(\d+:\d+)\)?$/
, isErrorCode = RegExp.prototype.test.bind(/^[A-Z_]+$/);
require("./fix-test-utils");
never = function (message) {
message = resolveMessage(message);
this.fail({ message: message, operator: "never" });
};
neverBind = function (message) { return never.bind(this, message); };
resolveMessage = function (message) {
var stack, line, match;
if (isValue(message)) return message;
stack = new Error().stack;
if (!stack) return "";
line = stack.split("\n")[3];
if (!line) return "";
match = line.match(lineRe);
if (!match) return "";
return "@" + match[1];
};
throws = function (block, err, message) {
var threw = false, exception = null, failure;
// If third argument is not provided and second argument is a string it
// means that optional `Error` argument was not passed, so we shift
// arguments.
if (message === undefined) {
if (!isFunction(err) && !isErrorCode(err)) {
message = err;
err = null;
}
}
message = resolveMessage(message);
// Executing given `block`.
try {
block();
} catch (e) {
threw = true;
exception = e;
}
// If exception was thrown and `Error` argument was not passed assert is
// passed.
if (
threw &&
(!isValue(err) ||
// If Error is thrown exception
err === exception ||
// If passed `Error` is RegExp using it's test method to
// assert thrown exception message.
(isRegExp(err) && err.test(exception.message)) ||
// If passed `Error` is a constructor function testing if
// thrown exception is an instance of it.
(isFunction(err) && exception instanceof err) ||
err === exception.code)
) {
this.pass(message);
// Otherwise we report assertion failure.
} else {
failure = { message: message, operator: "throws" };
if (exception) failure.actual = exception;
if (err) failure.expected = err;
this.fail(failure);
}
};
wrapAssert = function (assert, context) {
return function (actual, expected, message) {
return assert.call(context, actual, expected, resolveMessage(message));
};
};
module.exports = function (logger) {
var assert, getHeading;
assert = new Assert({
pass: logger.pass.bind(logger),
fail: logger.fail.bind(logger),
error: logger.error.bind(logger)
});
assert = assign(
function (actual, expected, message) {
message = resolveMessage(message);
if (eq(actual, expected)) {
this.pass(message);
return;
}
this.fail({ actual: actual, expected: expected, message: message, operator: "===" });
}.bind(assert),
map(Assert.prototype, function (method) { return method.bind(assert); })
);
assert.strictEqual = assert;
assert.not = assert.notStrictEqual = function (actual, expected, message) {
message = resolveMessage(message);
if (!eq(actual, expected)) {
this.pass(message);
return;
}
this.fail({ actual: actual, expected: expected, message: message, operator: "!==" });
};
assert.deep = assert.deepEqual = wrapAssert(assert.deepEqual, assert);
assert.notDeep = assert.notDeepEqual = wrapAssert(assert.notDeepEqual, assert);
assert.never = never.bind(assert);
assert.never.bind = neverBind.bind(assert);
assert.throws = throws.bind(assert);
getHeading = function (level) {
return function (msg) {
var index = level - 1 + logger.closure;
if (!hasOwnProperty.call(logger.msg, index)) logger.msg[index] = undefined;
logger.msg.splice(index, Infinity, msg);
};
};
assert.h1 = getHeading(1);
assert.h2 = getHeading(2);
assert.h3 = getHeading(3);
assert.h4 = getHeading(4);
assert.h5 = getHeading(5);
assert.h6 = getHeading(6);
return assert;
};
tad-3.1.0/lib/configure.js 0000775 0000000 0000000 00000003444 14132327775 0015373 0 ustar 00root root 0000000 0000000 "use strict";
var lock = require("es5-ext/function/#/lock")
, partial = require("es5-ext/function/#/partial")
, deferred = require("deferred")
, ee = require("event-emitter")
, fs = require("fs")
, resolve = require("path").resolve
, readdir = require("fs2/readdir")
, findTestPath = require("./find-test-path")
, findContext = require("./find-context");
var stat = deferred.promisify(fs.stat), configure, readdirOpts;
require("./tad-ignore-mode");
readdirOpts = {
depth: Infinity,
type: { file: true },
pattern: /\.js$/,
ignoreRules: ["git", "tad"]
};
configure = ee();
module.exports = function (inputPaths) {
var config, emitdata, emitend;
if (typeof inputPaths === "string") {
inputPaths = arguments;
}
config = Object.create(configure);
emitdata = config.emit.bind(config, "data");
emitend = lock.call(config.emit.bind(config, "end"));
deferred.reduce(
inputPaths,
function (ignore, modulePath) {
var emit;
emit = partial.call(emitdata, modulePath);
return stat(modulePath)(function (stats) {
if (stats.isFile()) return [modulePath];
if (stats.isDirectory()) {
return readdir(modulePath, readdirOpts).map(function (file) {
return resolve(modulePath, file);
});
}
throw new Error("Invalid path");
})(function (paths) {
return deferred.reduce(
paths,
function (ignore2, testee) {
emit = partial.call(emitdata, modulePath, testee);
return findTestPath(testee)(function (test) {
if (!test) return null;
return findContext(
testee, test
)(function (context) { emit(test, context); });
})(null, emit);
},
null
);
}, emit);
},
null
)(function () { process.nextTick(emitend); });
return config.on.bind(config);
};
tad-3.1.0/lib/console.js 0000664 0000000 0000000 00000007031 14132327775 0015045 0 ustar 00root root 0000000 0000000 "use strict";
var call = Function.prototype.call
, partial = require("es5-ext/function/#/partial")
, last = require("es5-ext/array/#/last")
, indent = call.bind(partial.call(require("es5-ext/string/#/indent"), " ", 17))
, format = call.bind(partial.call(require("es5-ext/date/#/format"), "%H:%M:%S.%L "))
, dpad = partial.call(require("es5-ext/string/#/pad"), " ", 12)
, duration = require("duration")
, inspect = require("util").inspect
, clc = require("cli-color")
, ctrim = require("cli-color/strip")
, cthrobber = require("cli-color/throbber");
var write = process.stdout.write.bind(process.stdout)
, lerror = clc.magenta
, lfail = clc.red
, lpass = clc.green
, lsummary = clc.cyan
, handler;
handler = {
init: function (options) {
if (options.a) this.mode = 2;
else this.mode = options.m ? 0 : 1;
this.passed = 0;
this.failed = 0;
this.errored = 0;
this.started = new Date();
this.writeLog = [];
this.write = function (ignored) {
this.writeLog.push(arguments);
return write.apply(this, arguments);
};
this.progress = cthrobber(write, 200);
return this;
},
atNewLine: function () {
return !this.writeLog.length || last.call(ctrim(last.call(this.writeLog)[0])) === "\n";
},
break: function () {
this.progress.restart();
if (!this.atNewLine() && this.mode) {
this.write("\n");
}
},
pass: function (path, name) {
++this.passed;
this.progress.restart();
if (this.mode === 2) {
this.write(lpass(format(new Date()) + " ✓ " + name + "\n"));
} else {
this.write(
lpass(
this.atNewLine()
? format(new Date()) + " ✓ " + (path && this.mode ? path + " " : "") + "."
: "."
)
);
}
},
fail: function (path, name, e) {
var message;
++this.failed;
this.progress.restart();
if (!this.atNewLine()) {
this.write("\n");
}
message = "";
if (e.operator) {
if (hasOwnProperty.call(e, "expected")) {
message += "Expected: " + inspect(e.expected, false, 1) + "\n";
}
if (hasOwnProperty.call(e, "actual")) {
message += "Actual: " + inspect(e.actual, false, 1) + "\n";
}
message += "Operator: " + e.operator + "\n";
} else {
message += (e.stack || e) + "\n";
}
this.write(lfail(format(new Date()) + " ✗ " + name + "\n" + indent(message)));
},
error: function (path, name, e) {
var message, eStr, index;
++this.errored;
this.progress.restart();
if (!this.atNewLine()) {
this.write("\n");
}
name = name || path;
message = format(new Date()) + " - ";
eStr = String(e.stack || e);
if (name) {
message += name + "\n" + indent(eStr);
} else {
index = eStr.indexOf("\n") + 1;
message += index ? eStr.slice(0, index) + indent(eStr.slice(index)) : eStr;
}
this.write(lerror(message + "\n"));
},
end: function () {
var message, all = this.passed + this.failed + this.errored;
this.progress.stop();
if (!this.atNewLine()) {
this.write("\n");
}
this.write("\n");
if (all) {
this.write(
lsummary(dpad.call(duration(this.started, new Date()).toString()) + " ")
);
message = [];
message.push(
clc.green(this.passed + " Ok [" + ((this.passed / all) * 100).toFixed(2) + "%]")
);
if (this.failed) {
message.push(clc.red(this.failed + " Failed"));
}
if (this.errored) {
message.push(clc.magenta(this.errored + " Errors"));
}
this.write(message.join(" ") + "\n\n");
} else {
this.write(lsummary("No tests run\n\n"));
}
}
};
module.exports = function (options) { return Object.create(handler).init(options || {}); };
tad-3.1.0/lib/find-context.js 0000664 0000000 0000000 00000001337 14132327775 0016010 0 ustar 00root root 0000000 0000000 "use strict";
var isFunction = require("es5-ext/function/is-function")
, path = require("path")
, createContext = require("vm").createContext
, findRoot = require("next/module/find-package-root")
, requireFirst = require("./require-first-in-tree");
module.exports = function (lpath, tpath) {
tpath = path.dirname(tpath);
return findRoot(tpath)(function (projectPath) {
var context = requireFirst("__tad", tpath, projectPath);
if (context) {
if (context instanceof Error) throw context;
if (context.context) {
context = context.context;
if (isFunction(context)) context = context(lpath);
context.console = console;
return createContext(context);
}
}
return global;
});
};
tad-3.1.0/lib/find-test-path.js 0000775 0000000 0000000 00000000754 14132327775 0016242 0 ustar 00root root 0000000 0000000 "use strict";
var path = require("path")
, findRoot = require("next/module/find-package-root");
var resolve = path.resolve, sep = path.sep;
module.exports = function (tpath) {
return findRoot(tpath)(function (projectPath) {
var e;
tpath = tpath.slice(projectPath.length + 1).split(sep);
if (tpath[0] === "test") {
e = new Error("Input seems to be a test file");
e.type = "testfile";
throw e;
}
return resolve(projectPath, "test" + sep + tpath.join(sep));
});
};
tad-3.1.0/lib/fix-test-utils.js 0000664 0000000 0000000 00000001712 14132327775 0016304 0 ustar 00root root 0000000 0000000 // Temporary fix for https://github.com/Gozala/test-commonjs/pull/8
"use strict";
var utils = require("test/utils");
var instanceOf;
try {
if (utils.instanceOf) utils.instanceOf(Object.create(null), Date);
} catch (e) {
instanceOf = utils.instanceOf = function (value, Type) {
var valueConstructor
, isConstructorNameSame
, isConstructorSourceSame
, isInstanceOf = value instanceof Type;
if (!isInstanceOf && value) {
valueConstructor = value.constructor;
isConstructorNameSame = valueConstructor && valueConstructor.name === Type.name;
isConstructorSourceSame = String(valueConstructor) === String(Type);
isInstanceOf =
(isConstructorNameSame && isConstructorSourceSame) ||
instanceOf(Object.getPrototypeOf(value), Type);
}
return isInstanceOf;
};
utils.isDate = function (value) { return utils.isObject(value) && instanceOf(value, Date); };
utils.isRegExp = function (value) { return instanceOf(value, RegExp); };
}
tad-3.1.0/lib/load.js 0000775 0000000 0000000 00000003057 14132327775 0014331 0 ustar 00root root 0000000 0000000 // Imports lib and tests from given paths
"use strict";
var assign = require("es5-ext/object/assign")
, endsWith = require("es5-ext/string/#/ends-with")
, path = require("path")
, commonPath = require("path2/common")
, requireInContext = require("./require-in-context")
, requireFirst = require("./require-first-in-tree");
var dirname = path.dirname, sep = path.sep, ptrim;
ptrim = function (testPath) {
return testPath.match(/[\u0000-.0-[\]-\uffff][/\\]$/) ? testPath.slice(0, -1) : testPath;
};
module.exports = function (testeePath, testPath, context) {
var testConfig, scopes;
var testModule, testError, testeeModule, testeeError;
try { testModule = requireInContext(testPath, context, { isSilent: true }); }
catch (error) { testError = error; }
try { testeeModule = requireInContext(testeePath, context, { isSilent: true }); }
catch (error) { testeeError = error; }
if (testError || testeeError) {
return { test: testModule || testError, testee: testeeModule || testeeError };
}
testConfig = { test: testModule, testee: testeeModule };
if (!testConfig.test && endsWith.call(testeePath, sep + "index.js")) {
testConfig.test = require("./utils/index-test")(dirname(testeePath), null, context);
}
if (testConfig.test && testConfig.test.__generic) {
scopes = requireFirst(
"__scopes", dirname(testPath), ptrim(commonPath(testeePath, testPath))
);
assign(testConfig.test, require("./utils/factory")(scopes, testConfig.test.__generic));
delete testConfig.test.__generic;
}
return testConfig;
};
tad-3.1.0/lib/logger.js 0000664 0000000 0000000 00000002060 14132327775 0014657 0 ustar 00root root 0000000 0000000 "use strict";
var aFrom = require("es5-ext/array/from")
, partial = require("es5-ext/function/#/partial")
, mixin = require("es5-ext/object/mixin")
, ee = require("event-emitter");
var logger;
logger = ee(
(exports = {
init: function () {
this.msg = [];
this.closure = 0;
this.passed = [];
this.errored = [];
this.failed = [];
this.started = new Date();
return this;
},
in: function (msg, closure) {
this.msg.push(msg);
if (closure) ++this.closure;
},
out: function (closure) {
this.msg.pop();
if (closure) --this.closure;
},
log: function (type, data) {
var result = { type: type, time: new Date(), data: data, msg: aFrom(this.msg) };
this.push(result);
this[type + "ed"].push(result);
this.emit("data", result);
},
end: function () { this.emit("end"); }
})
);
logger.log.partial = partial;
logger.error = logger.log.partial("error");
logger.pass = logger.log.partial("pass");
logger.fail = logger.log.partial("fail");
module.exports = function () { return mixin([], logger).init(); };
tad-3.1.0/lib/require-first-in-tree.js 0000664 0000000 0000000 00000001023 14132327775 0017540 0 ustar 00root root 0000000 0000000 "use strict";
var path = require("path")
, isModuleNotFoundError = require("ncjsm/is-module-not-found-error");
var dirname = path.dirname, sep = path.sep;
module.exports = function (modulePath, currentPath, topPath) {
while (currentPath !== topPath) {
var currentModulePath = currentPath + sep + modulePath;
try {
return require(currentModulePath);
} catch (error) {
if (!isModuleNotFoundError(error, currentModulePath)) throw error;
}
currentPath = dirname(currentPath);
}
return null;
};
tad-3.1.0/lib/require-in-context.js 0000664 0000000 0000000 00000003700 14132327775 0017144 0 ustar 00root root 0000000 0000000 // Require module in given context
"use strict";
var validValue = require("es5-ext/object/valid-value")
, Module = require("module")
, readFileSync = require("fs").readFileSync
, path = require("path")
, vm = require("vm")
, memoize = require("memoizee")
, isModuleNotFoundError = require("ncjsm/is-module-not-found-error");
var dirname = path.dirname
, extname = path.extname
, objHasOwnProperty = Object.prototype.hasOwnProperty
, natives = process.binding("natives")
, wrap = Module.wrap;
var get = memoize(function (modulePath) { return new Module(modulePath, module); }, { length: 2 });
module.exports = exports = function (modulePath, context /*, options*/) {
var options = arguments[2] || {};
var fmodule, content, dirpath;
validValue(context);
if (context === global) {
try {
return require(modulePath);
} catch (error) {
if (options.isSilent && isModuleNotFoundError(error, modulePath)) return null;
throw error;
}
}
if (objHasOwnProperty.call(natives, modulePath)) return require(modulePath);
fmodule = get(modulePath, context);
if (fmodule.loaded) return fmodule.exports;
fmodule.filename = modulePath;
dirpath = dirname(modulePath);
fmodule.paths = Module._nodeModulePaths(dirpath);
fmodule.require = function (targetPath) {
return exports(Module._resolveFilename(String(targetPath), this), context);
};
try {
content = readFileSync(modulePath, "utf8");
} catch (e) {
if (e.code === "ENOENT") {
if (options.isSilent) return null;
throw new Error("Cannot find module '" + modulePath + "'");
}
throw e;
}
fmodule.loaded = true;
if (extname(modulePath) === ".json") {
fmodule.exports = JSON.parse(content);
} else {
vm.runInContext(wrap(content), context, modulePath).call(
fmodule.exports, fmodule.exports, fmodule.require.bind(fmodule), fmodule, modulePath,
dirpath
);
}
return fmodule.exports;
};
tad-3.1.0/lib/run.js 0000664 0000000 0000000 00000006762 14132327775 0014221 0 ustar 00root root 0000000 0000000 /* eslint max-lines: "off" */
// Runs tests
"use strict";
var isError = require("es5-ext/error/is-error")
, isFunction = require("es5-ext/function/is-function")
, noop = require("es5-ext/function/noop")
, toArray = require("es5-ext/object/to-array")
, hforEach = require("es5-ext/object/for-each")
, isValue = require("es5-ext/object/is-value")
, isThenable = require("es5-ext/object/is-thenable")
, deferred = require("deferred")
, createLogger = require("./logger")
, createAssert = require("./assert");
var nextTick = process.nextTick
, pattern = /^\s*(?:async\s*)?(?:function\s*)?\(\s*([tad])(?:\s*,\s*([tad]))?\s*\)/
, run;
run = function self(testee, tests, assert, logger) {
if (isFunction(tests)) {
tests = { "": tests };
}
hforEach(tests, function (t) {
var conf, match;
if (isFunction(t)) {
conf = t.conf = { t: true, a: true, d: false };
if (t.length > 2) {
conf.d = true;
} else if ((match = t.toString().match(pattern))) {
conf.t = conf.a = false;
conf[match[1]] = true;
if (match[2]) {
conf[match[2]] = true;
}
}
}
});
return deferred.reduce(
toArray(tests),
// eslint-disable-next-line max-statements
function (ignore, data) {
var testResult, d, finish, done, name, testFunction;
name = data[0];
testFunction = data[1];
d = deferred();
finish = function () {
logger.out(true);
d.resolve();
};
logger.in(name, true);
if (isFunction(testFunction)) {
try {
if (testFunction.conf.d) {
done = function (asyncTestResult) {
if (asyncTestResult) {
if (isError(asyncTestResult)) {
assert.fail(asyncTestResult);
finish();
} else {
self(testee, asyncTestResult, assert, logger)(finish).done();
}
} else {
finish();
}
};
if (testFunction.conf.t) {
// eslint-disable-next-line max-depth
if (testFunction.conf.a) {
testFunction(testee, assert, done);
} else {
testFunction(testee, done);
}
} else if (testFunction.conf.a) {
testFunction(assert, done);
} else {
testFunction(done);
}
} else {
if (testFunction.conf.t) {
testResult = testFunction(testee, assert);
} else {
testResult = testFunction(assert);
}
if (isThenable(testResult)) {
testResult.then(
function (thenableTestResult) {
if (thenableTestResult) {
self(
testee, thenableTestResult, assert, logger
)(finish).done();
} else {
finish();
}
},
function (error) {
assert.fail(error);
finish();
}
);
} else if (testResult) {
self(testee, testResult, assert, logger)(finish).done();
} else {
finish();
}
}
} catch (e) {
logger.error(e);
finish();
}
} else if (isValue(testFunction)) {
self(testee, testFunction, assert, logger)(finish).done();
} else {
assert.fail(new Error("No tests found at '" + name + "' property"));
finish();
}
return d.promise;
},
null
)(noop);
};
module.exports = function (testee, test, assert, logger) {
var runResult;
logger = logger || createLogger();
assert = assert || createAssert(logger);
nextTick(function () {
runResult = run(testee, test, assert, logger);
if (logger.end) {
runResult = runResult(logger.end.bind(logger));
}
runResult.done();
});
return logger;
};
tad-3.1.0/lib/tad-ignore-mode.js 0000664 0000000 0000000 00000000726 14132327775 0016362 0 ustar 00root root 0000000 0000000 "use strict";
var findRoot = require("next/module/find-package-root")
, resolve = require("path").resolve;
var isRoot;
require("fs2/lib/ignore-modes").tad = module.exports = {
filename: ".testignore",
isRoot: (isRoot = function (path) {
var promise = findRoot(resolve(path, "_find-that-root_"))(function (projectPath) {
return projectPath === path;
});
promise.path = path;
return promise;
}),
isRootWatcher: isRoot
};
isRoot.returnsPromise = true;
tad-3.1.0/lib/utils/ 0000775 0000000 0000000 00000000000 14132327775 0014204 5 ustar 00root root 0000000 0000000 tad-3.1.0/lib/utils/factory.js 0000664 0000000 0000000 00000000710 14132327775 0016207 0 ustar 00root root 0000000 0000000 "use strict";
var isFunction = require("es5-ext/function/is-function")
, oForEach = require("es5-ext/object/for-each");
module.exports = function (scopes, tests) {
var result = {};
oForEach(scopes, function (scope, typeName) {
if (isFunction(tests)) {
result[typeName] = tests.bind(scope);
} else {
oForEach(tests, function (test, testName) {
result[typeName + ": " + testName] = test.bind(scope);
});
}
});
return result;
};
tad-3.1.0/lib/utils/index-test.js 0000775 0000000 0000000 00000005141 14132327775 0016632 0 ustar 00root root 0000000 0000000 "use strict";
var curry = require("es5-ext/function/#/curry")
, contains = curry.call(require("es5-ext/array/#/contains"))
, noop = require("es5-ext/function/noop")
, not = require("es5-ext/function/#/not")
, oForEach = require("es5-ext/object/for-each")
, isValue = require("es5-ext/object/is-value")
, convert = require("es5-ext/string/#/hyphen-to-camel")
, endsWith = require("es5-ext/string/#/ends-with")
, d = require("d")
, a2p = require("deferred").promisify
, isPromise = require("deferred/is-promise")
, reqInContext = require("../require-in-context")
, fs = require("fs")
, normalize = require("path").normalize;
var defineProperty = Object.defineProperty
, isConstant = RegExp.prototype.test.bind(/^[A-Z0-9_]+$/)
, readDir;
readDir = function (dir) {
var result = {};
if (isPromise(dir)) {
return dir;
}
dir = normalize(dir);
return a2p(fs.readdir)(dir).map(function (filename) {
if (filename[0] === "_") return null;
if (filename[0] === ".") return null;
if (filename === "lib") return null;
if (filename === "node_modules") return null;
if (filename === "test") return null;
if (endsWith.call(filename, ".config.js")) return null;
return a2p(fs.stat)(dir + "/" + filename)(function (stats) {
if (stats.isFile()) {
if (filename.slice(-3) !== ".js" || filename === "index.js") {
return;
}
filename = filename.slice(0, -3);
} else if (!stats.isDirectory()) {
return;
}
defineProperty(
result, convert.call(filename), d("cew", normalize(dir + "/" + filename))
);
}, noop);
})(result);
};
module.exports = function (dir, ignores, context) {
if (!isValue(context)) context = global;
return function (t, a, done) {
readDir(dir)(function (fileList) {
var keys = Object.keys(t), keysLc;
if (ignores) {
keys = keys.filter(not.call(contains), ignores);
}
keysLc = keys.map(function (name) {
if (isConstant(name)) name = name.replace(/_/g, "");
return name.toLowerCase();
});
oForEach(fileList, function (path, value) {
var i = keysLc.indexOf(value.toLowerCase());
if (i === -1) {
a.ok(false, value + " - is present ?");
} else {
a.ok(true, value + " - is present ?");
}
if (i !== -1) {
a(
t[keys[i]], reqInContext(require.resolve(path), context),
value + " - points its module ?"
);
keys.splice(i, 1);
keysLc.splice(i, 1);
}
});
a.ok(keys.length === 0, "[" + keys.toString() + "] - no extras found ?");
done();
}).done();
};
};
module.exports.readDir = readDir;
tad-3.1.0/package.json 0000664 0000000 0000000 00000004700 14132327775 0014565 0 ustar 00root root 0000000 0000000 {
"name": "tad",
"version": "3.1.0",
"description": "JavaScript test suite",
"author": "Mariusz Nowak (http://www.medikoo.com/)",
"keywords": [
"test",
"factory",
"unit",
"unittest",
"runner",
"tests",
"tdd",
"testing"
],
"bin": {
"tad": "./bin/tad.js"
},
"repository": {
"type": "git",
"url": "git://github.com/medikoo/tad.git"
},
"dependencies": {
"cli-color": "^2.0.0",
"d": "^1.0.1",
"deferred": "^0.7.11",
"duration": "^0.2.2",
"es5-ext": "^0.10.51",
"essentials": "^1.0.0",
"event-emitter": "^0.3.5",
"fs2": "^0.2.21",
"memoizee": "^0.4.14",
"ncjsm": "^4.2.0",
"next": "^0.4.1",
"optimist": "^0.6.1",
"path2": "^0.1.0",
"test": "^0.6.0"
},
"devDependencies": {
"@commitlint/cli": "^13.2.1",
"eslint": "^8.0.1",
"eslint-config-medikoo": "^4.1.1",
"git-list-updated": "^1.2.1",
"github-release-from-cc-changelog": "^2.2.0",
"husky": "^4.3.8",
"lint-staged": "^11.2.3",
"prettier-elastic": "^2.2.1",
"standard-version": "^9.3.1"
},
"husky": {
"hooks": {
"commit-msg": "commitlint -E HUSKY_GIT_PARAMS",
"pre-commit": "lint-staged"
}
},
"lint-staged": {
"*.js": [
"eslint"
],
"*.{css,html,js,json,md,yaml,yml}": [
"prettier -c"
]
},
"eslintConfig": {
"extends": "medikoo/node/es5",
"root": true
},
"prettier": {
"printWidth": 100,
"tabWidth": 4,
"overrides": [
{
"files": [
"*.md",
"*.yml"
],
"options": {
"tabWidth": 2
}
}
]
},
"standard-version": {
"skip": {
"commit": true,
"tag": true
},
"types": [
{
"type": "feat",
"section": "Features"
},
{
"type": "fix",
"section": "Bug Fixes"
},
{
"type": "perf",
"section": "Performance Improvements"
},
{
"type": "refactor",
"section": "Maintenance Improvements"
},
{
"type": "chore",
"section": "Maintenance Improvements"
}
]
},
"scripts": {
"commitlint": "commitlint -f HEAD@{15}",
"lint": "eslint .",
"lint-updated": "pipe-git-updated --ext=js -- eslint --ignore-pattern '!*'",
"prepare-release": "standard-version && prettier --write CHANGELOG.md",
"prettier-check-updated": "pipe-git-updated --ext=css --ext=html --ext=js --ext=json --ext=md --ext=yaml --ext=yml -- prettier -c",
"prettify": "prettier --write --ignore-path .gitignore '**/*.{css,html,js,json,md,yaml,yml}'",
"test": "node ./bin/tad"
},
"engines": {
"node": ">=0.12"
},
"license": "ISC"
}
tad-3.1.0/test/ 0000775 0000000 0000000 00000000000 14132327775 0013255 5 ustar 00root root 0000000 0000000 tad-3.1.0/test/.eslintrc.json 0000664 0000000 0000000 00000000070 14132327775 0016046 0 ustar 00root root 0000000 0000000 { "rules": { "id-length": "off", "no-shadow": "off" } }
tad-3.1.0/test/__playground/ 0000775 0000000 0000000 00000000000 14132327775 0015737 5 ustar 00root root 0000000 0000000 tad-3.1.0/test/__playground/lib/ 0000775 0000000 0000000 00000000000 14132327775 0016505 5 ustar 00root root 0000000 0000000 tad-3.1.0/test/__playground/lib/context-error/ 0000775 0000000 0000000 00000000000 14132327775 0021320 5 ustar 00root root 0000000 0000000 tad-3.1.0/test/__playground/lib/context-error/module.js 0000664 0000000 0000000 00000000044 14132327775 0023141 0 ustar 00root root 0000000 0000000 "use strict";
module.exports = {};
tad-3.1.0/test/__playground/lib/dir/ 0000775 0000000 0000000 00000000000 14132327775 0017263 5 ustar 00root root 0000000 0000000 tad-3.1.0/test/__playground/lib/dir/dir/ 0000775 0000000 0000000 00000000000 14132327775 0020041 5 ustar 00root root 0000000 0000000 tad-3.1.0/test/__playground/lib/dir/dir/module.2.js 0000664 0000000 0000000 00000000044 14132327775 0022022 0 ustar 00root root 0000000 0000000 "use strict";
module.exports = {};
tad-3.1.0/test/__playground/lib/dir/dir/module.js 0000664 0000000 0000000 00000000044 14132327775 0021662 0 ustar 00root root 0000000 0000000 "use strict";
module.exports = {};
tad-3.1.0/test/__playground/lib/dir/module.2.js 0000664 0000000 0000000 00000000044 14132327775 0021244 0 ustar 00root root 0000000 0000000 "use strict";
module.exports = {};
tad-3.1.0/test/__playground/lib/dir/module.js 0000664 0000000 0000000 00000000044 14132327775 0021104 0 ustar 00root root 0000000 0000000 "use strict";
module.exports = {};
tad-3.1.0/test/__playground/lib/dir/other 0000664 0000000 0000000 00000000000 14132327775 0020315 0 ustar 00root root 0000000 0000000 tad-3.1.0/test/__playground/lib/evaluation-error.js 0000664 0000000 0000000 00000000041 14132327775 0022334 0 ustar 00root root 0000000 0000000 "use strict";
generate.error();
tad-3.1.0/test/__playground/lib/index-test/ 0000775 0000000 0000000 00000000000 14132327775 0020571 5 ustar 00root root 0000000 0000000 tad-3.1.0/test/__playground/lib/index-test/file-name-1.js 0000664 0000000 0000000 00000000044 14132327775 0023120 0 ustar 00root root 0000000 0000000 "use strict";
module.exports = {};
tad-3.1.0/test/__playground/lib/index-test/file-name-2.js 0000664 0000000 0000000 00000000044 14132327775 0023121 0 ustar 00root root 0000000 0000000 "use strict";
module.exports = {};
tad-3.1.0/test/__playground/lib/index-test/file-name-3.js 0000664 0000000 0000000 00000000044 14132327775 0023122 0 ustar 00root root 0000000 0000000 "use strict";
module.exports = {};
tad-3.1.0/test/__playground/lib/index-test/index.js 0000664 0000000 0000000 00000000256 14132327775 0022241 0 ustar 00root root 0000000 0000000 "use strict";
module.exports = {
fileName1: require("./file-name-1"),
fileName2: require("./file-name-2"),
fileName3: require("./file-name-3"),
sub: require("./sub")
};
tad-3.1.0/test/__playground/lib/index-test/sub/ 0000775 0000000 0000000 00000000000 14132327775 0021362 5 ustar 00root root 0000000 0000000 tad-3.1.0/test/__playground/lib/index-test/sub/index.js 0000664 0000000 0000000 00000000044 14132327775 0023025 0 ustar 00root root 0000000 0000000 "use strict";
module.exports = {};
tad-3.1.0/test/__playground/lib/module.js 0000664 0000000 0000000 00000000044 14132327775 0020326 0 ustar 00root root 0000000 0000000 "use strict";
module.exports = {};
tad-3.1.0/test/__playground/lib/no-tests.js 0000664 0000000 0000000 00000000044 14132327775 0020615 0 ustar 00root root 0000000 0000000 "use strict";
module.exports = {};
tad-3.1.0/test/__playground/lib/test-evaluation-error.js 0000664 0000000 0000000 00000000044 14132327775 0023314 0 ustar 00root root 0000000 0000000 "use strict";
module.exports = {};
tad-3.1.0/test/__playground/module.js 0000664 0000000 0000000 00000000044 14132327775 0017560 0 ustar 00root root 0000000 0000000 "use strict";
module.exports = {};
tad-3.1.0/test/__playground/package.json 0000664 0000000 0000000 00000000047 14132327775 0020226 0 ustar 00root root 0000000 0000000 {
"name": "dummy",
"private": true
}
tad-3.1.0/test/__playground/test/ 0000775 0000000 0000000 00000000000 14132327775 0016716 5 ustar 00root root 0000000 0000000 tad-3.1.0/test/__playground/test/context-error/ 0000775 0000000 0000000 00000000000 14132327775 0021531 5 ustar 00root root 0000000 0000000 tad-3.1.0/test/__playground/test/context-error/__tad.js 0000664 0000000 0000000 00000000041 14132327775 0023130 0 ustar 00root root 0000000 0000000 "use strict";
generate.error();
tad-3.1.0/test/__playground/test/context/ 0000775 0000000 0000000 00000000000 14132327775 0020402 5 ustar 00root root 0000000 0000000 tad-3.1.0/test/__playground/test/context/__tad.js 0000664 0000000 0000000 00000000054 14132327775 0022005 0 ustar 00root root 0000000 0000000 "use strict";
exports.context = { x: {} };
tad-3.1.0/test/__playground/test/context/context/ 0000775 0000000 0000000 00000000000 14132327775 0022066 5 ustar 00root root 0000000 0000000 tad-3.1.0/test/__playground/test/context/context/__tad.js 0000664 0000000 0000000 00000000105 14132327775 0023466 0 ustar 00root root 0000000 0000000 "use strict";
exports.context = function (lpath) { return lpath; };
tad-3.1.0/test/__playground/test/context/context/module.js 0000664 0000000 0000000 00000000016 14132327775 0023706 0 ustar 00root root 0000000 0000000 "use strict";
tad-3.1.0/test/__playground/test/context/dir/ 0000775 0000000 0000000 00000000000 14132327775 0021160 5 ustar 00root root 0000000 0000000 tad-3.1.0/test/__playground/test/context/dir/module.js 0000664 0000000 0000000 00000000016 14132327775 0023000 0 ustar 00root root 0000000 0000000 "use strict";
tad-3.1.0/test/__playground/test/context/module.js 0000664 0000000 0000000 00000000016 14132327775 0022222 0 ustar 00root root 0000000 0000000 "use strict";
tad-3.1.0/test/__playground/test/dir/ 0000775 0000000 0000000 00000000000 14132327775 0017474 5 ustar 00root root 0000000 0000000 tad-3.1.0/test/__playground/test/dir/dir/ 0000775 0000000 0000000 00000000000 14132327775 0020252 5 ustar 00root root 0000000 0000000 tad-3.1.0/test/__playground/test/dir/dir/dummy 0000664 0000000 0000000 00000000000 14132327775 0021316 0 ustar 00root root 0000000 0000000 tad-3.1.0/test/__playground/test/function-test.js 0000664 0000000 0000000 00000000064 14132327775 0022056 0 ustar 00root root 0000000 0000000 "use strict";
module.exports = function (a, d) {};
tad-3.1.0/test/__playground/test/generics-test/ 0000775 0000000 0000000 00000000000 14132327775 0021472 5 ustar 00root root 0000000 0000000 tad-3.1.0/test/__playground/test/generics-test/__scopes.js 0000664 0000000 0000000 00000000127 14132327775 0023622 0 ustar 00root root 0000000 0000000 "use strict";
exports.First = { name: "First" };
exports.Second = { name: "Second" };
tad-3.1.0/test/__playground/test/generics-test/test.js 0000664 0000000 0000000 00000000142 14132327775 0023004 0 ustar 00root root 0000000 0000000 "use strict";
exports.__generic = { "Sample test": function (t, a) { a.ok(true, this.name); } };
tad-3.1.0/test/__playground/test/module.js 0000664 0000000 0000000 00000000200 14132327775 0020531 0 ustar 00root root 0000000 0000000 "use strict";
exports.pass = function (t, a) { a.ok(true, "Pass"); };
exports.fail = function (t, a) { a.ok(false, "Fail"); };
tad-3.1.0/test/__playground/test/test-evaluation-error.js 0000664 0000000 0000000 00000000041 14132327775 0023522 0 ustar 00root root 0000000 0000000 "use strict";
generate.error();
tad-3.1.0/test/index.js 0000664 0000000 0000000 00000001523 14132327775 0014723 0 ustar 00root root 0000000 0000000 "use strict";
var noop = require("es5-ext/function/noop")
, resolve = require("path").resolve;
var pg = resolve(__dirname, "__playground"), n4 = process.version.indexOf("v0.4") === 0;
module.exports = function (t, a, d) {
if (!n4) {
d();
return;
}
var outorg, errorg;
outorg = process.stdout._writeOut;
errorg = process.stderr._writeOut;
process.stdout._writeOut = noop;
process.stderr._writeOut = noop;
t([
"/wrong/path", pg + "/lib/context-error/module.js", pg + "/lib/evaluation-error.js",
pg + "/lib/test-evaluation-error.js", pg + "/lib/no-tests.js", pg + "/lib/module.js"
])(
function () {
process.stdout._writeOut = outorg;
process.stderr._writeOut = errorg;
a.ok(true);
d();
},
function (err) {
process.stdout._writeOut = outorg;
process.stderr._writeOut = errorg;
d(err);
}
).end();
};
tad-3.1.0/test/lib/ 0000775 0000000 0000000 00000000000 14132327775 0014023 5 ustar 00root root 0000000 0000000 tad-3.1.0/test/lib/assert.js 0000664 0000000 0000000 00000001527 14132327775 0015667 0 ustar 00root root 0000000 0000000 "use strict";
var customError = require("es5-ext/error/custom")
, logger = require("../../lib/logger")();
module.exports = function (t, a) {
t = t(logger);
t(true, true, "foo");
t.ok(false, "bar");
t.not(false, true, "not");
t.deep([1, 2], [1, 2], "deep");
t.notDeep([1, 2], [2, 1], "not deep");
t.throws(function () { throw customError("Test", "TEST"); }, "TEST", "throws");
a.deep([logger[0].type, logger[0].data], ["pass", "foo"]);
a.deep([logger[1].type, logger[1].data.message], ["fail", "bar"]);
a.deep([logger[2].type, logger[2].data], ["pass", "not"], "'not' support");
a.deep([logger[3].type, logger[3].data], ["pass", "deep"], "'deep' support");
a.deep([logger[4].type, logger[4].data], ["pass", "not deep"], "'not deep' support");
a.deep([logger[5].type, logger[5].data], ["pass", "throws"], "custom trhows support");
};
tad-3.1.0/test/lib/configure.js 0000775 0000000 0000000 00000002431 14132327775 0016345 0 ustar 00root root 0000000 0000000 "use strict";
var findTestPath = require("../../lib/find-test-path")
, pg = require("path").resolve(__dirname, "../__playground/lib") + "/";
module.exports = function (t, a, d) {
var logger, data, paths = [pg + "module.js", "/wrong/path", pg + "dir"];
logger = t(paths);
data = [];
logger("data", function () { data.push(arguments); });
logger("end", function () {
d({
"File": function (t, a, d) {
var o = data[0];
a(o[0], paths[0], "Path");
a(o[1], paths[0], "File");
a(o[3], global, "Context");
findTestPath(o[1])(function (p) { a(p, o[2], "Test path"); }).done(d);
},
"Wrong path": function () {
var o = data[1];
a(o[0], paths[1], "Path");
a.ok(o[1] instanceof Error, "Error");
},
"Directory": function () {
a(data.length, 6, "Files length");
return {
"File #1": function (t, a, d) {
var o = data[2];
// Console.log(o);
a(o[0], paths[2], "Path");
a(o[3], global, "Context");
findTestPath(o[1])(function (p) { a(p, o[2], "Test path"); }).done(d);
},
"File #2": function (t, a, d) {
var o = data[5];
a(o[0], paths[2], "Path");
a(o[3], global, "Context");
findTestPath(o[1])(function (p) { a(p, o[2], "Test path"); }).done(d);
}
};
}
});
});
};
tad-3.1.0/test/lib/console.js 0000664 0000000 0000000 00000004667 14132327775 0016040 0 ustar 00root root 0000000 0000000 "use strict";
var oForEach = require("es5-ext/object/for-each")
, AssertionError = require("test/assert").AssertionError
, n4 = process.version.indexOf("v0.4") === 0;
module.exports = function (t, a) {
if (!n4) {
return;
}
var outorg, errorg, outl = "", errl = "", console, results = {};
outorg = process.stdout._writeOut;
errorg = process.stderr._writeOut;
process.stdout._writeOut = function (data) { outl += data; };
process.stderr._writeOut = function (data) { errl += data; };
console = t({});
console.pass("foo", "bar");
results["Pass content"] = [outl.length > 0];
results["Pass lines"] = [outl.split("\n").length, 1];
outl = "";
console.pass("foo", "bar");
results["Second Pass content"] = [outl.length > 0];
results["Second Pass lines"] = [outl.split("\n").length, 1];
outl = "";
console.fail(
"foo", "bar",
new AssertionError({ message: "foo", actual: "foo", expected: "foo", operator: "foo" })
);
results["Fail content"] = [outl.length > 0];
results["Fail lines"] = [outl.split("\n").length, 6];
outl = "";
console.error("foo", "bar", new Error("foo"));
results["Error content"] = [outl.length > 0];
results["Error lines"] = [outl.split("\n").length > 4];
outl = "";
console.fail("foo", "bar", new Error("foo"));
results["Fail error content"] = [outl.length > 0];
results["Fail error lines"] = [outl.split("\n").length > 4];
outl = "";
console.fail("foo", "bar", new AssertionError({ message: "foo", operator: "throws" }));
results["Fail throws content"] = [outl.length > 0];
results["Fail throws lines"] = [outl.split("\n").length, 3];
outl = "";
console.end();
results["Summary content"] = [outl.length > 0];
results["Summary length"] = [outl.split("\n").length, 4];
outl = "";
results["No errors stdout"] = [errl.length, 0];
errl = "";
console = t({ a: true });
console.pass("foo", "bar");
results["Show all Pass content"] = [outl.length > 0];
results["Show all Pass lines"] = [outl.split("\n").length, 2];
outl = "";
console.pass("foo", "bar");
results["Show all second Pass content"] = [outl.length > 0];
results["Show all second Pass lines"] = [outl.split("\n").length, 2];
outl = "";
console.end();
results["Show all no errors stdout"] = [errl.length, 0];
errl = "";
process.stdout._writeOut = outorg;
process.stderr._writeOut = errorg;
oForEach(results, function (r, name) {
if (r.length === 1) {
a.ok(r[0], name);
} else {
a(r[0], r[1], name);
}
});
};
tad-3.1.0/test/lib/find-context.js 0000775 0000000 0000000 00000001547 14132327775 0016775 0 ustar 00root root 0000000 0000000 "use strict";
var pg = require("path").resolve(__dirname, "../__playground");
module.exports = {
Default: function (t, a, d) {
t("ignore", pg + "/test/module.js")(function (context) { a(context, global); }).done(d);
},
Custom: {
"": function (t, a, d) {
var path = pg + "/test/context/";
t(
"ignore", path + "module.js"
)(function (context) { a(context.x, require(path + "__tad").context.x); }).done(d);
},
"Nested": function (t, a, d) {
var path = pg + "/test/context/context/", o = { x: {} };
t(
o, path + "module.js"
)(function (context) { a(context.x, require(path + "__tad").context(o).x); }).done(d);
},
"Nested fallback": function (t, a, d) {
var path = pg + "/test/context/";
t(
"ignore", path + "/dir/module.js"
)(function (context) { a(context.x, require(path + "__tad").context.x); }).done(d);
}
}
};
tad-3.1.0/test/lib/find-test-path.js 0000775 0000000 0000000 00000000745 14132327775 0017221 0 ustar 00root root 0000000 0000000 "use strict";
var resolve = require("path").resolve
, playground = resolve(__dirname, "../__playground");
module.exports = {
"In lib": function (t, a, d) {
t(resolve(playground, "lib/dir/module.js"))
.then(function (tpath) { a(tpath, resolve(playground, "test/lib/dir/module.js")); })
.done(d);
},
"In main": function (t, a, d) {
t(resolve(playground, "module.js"))
.then(function (tpath) { a(tpath, resolve(playground, "test/module.js")); })
.done(d);
}
};
tad-3.1.0/test/lib/load.js 0000775 0000000 0000000 00000001124 14132327775 0015301 0 ustar 00root root 0000000 0000000 "use strict";
var resolve = require("path").resolve
, pg = resolve(__dirname, "../__playground");
module.exports = function (t, a) {
var o = t(pg + "/lib/evaluation-error.js", pg + "/not/existing/path", global);
a.ok(o.testee instanceof Error, "Evaluation error");
a(o.test, undefined, "Not found");
o = t(resolve(pg, "lib/index-test/index.js"), resolve(pg, "not/existing/path"), global);
a(typeof o.test, "function", "Automatic index test");
o = t(pg + "/lib/module.js", pg + "/test/generics-test/test.js", global);
a(typeof o.test.__generic, "undefined", "Generics test");
};
tad-3.1.0/test/lib/logger.js 0000664 0000000 0000000 00000001343 14132327775 0015641 0 ustar 00root root 0000000 0000000 "use strict";
module.exports = function (t, a) {
var ondata = [], ended = false;
t = t();
t.on("data", function (o) { ondata.push(o.type, o.data); });
t.on("end", function () { ended = true; });
t.pass("foo");
t.in("ONE");
t.fail("bar");
t.out();
t.error("error");
a.deep(t.msg, [], "Msg");
a(t.length, 3, "Length");
a.deep([t[0].type, t[0].data, t[0].msg.toString()], ["pass", "foo", ""], "#1 pass");
a.deep([t[1].type, t[1].data, t[1].msg.toString()], ["fail", "bar", "ONE"], "#2 fail");
a.deep([t[2].type, t[2].data, t[2].msg.toString()], ["error", "error", ""], "#3 error");
a(ended, false, "Not ended");
t.end();
a(ended, true, "Ended");
a.deep(ondata, ["pass", "foo", "fail", "bar", "error", "error"], "Log");
};
tad-3.1.0/test/lib/run.js 0000664 0000000 0000000 00000005176 14132327775 0015176 0 ustar 00root root 0000000 0000000 "use strict";
var identity = require("es5-ext/function/identity")
, createLogger = require("../../lib/logger")
, createAssert = require("../../lib/assert");
module.exports = function (t, a, d) {
var inProgress = false, logger = createLogger(), assert = createAssert(logger), aa = a;
t(
identity,
{
"Regular": function (x, y) {
var o = {};
a.ok(!inProgress, "Regular: Progress");
a(x, identity, "Regular: Testee");
y(x(o), o, "foo");
a.deep([logger[0].type, logger[0].data], ["pass", "foo"], "Regular: Logger");
a.deep(logger.msg, ["Regular"], "Regular: Name");
},
"Async": function (x, y, z) {
var o = {};
a.ok(!inProgress, "Async: Progress");
inProgress = true;
a(x, identity, "Async: Testee");
y(x(o), o, "bar");
a.deep([logger[1].type, logger[1].data], ["pass", "bar"], "Async: Logger");
a.deep(logger.msg, ["Async"], "Async: Name");
process.nextTick(function () {
inProgress = false;
z();
});
},
"Async nested": function (x, y, z) {
a.ok(!inProgress, "Async nested: Progress");
inProgress = true;
process.nextTick(function () {
z({
"inner test": function (a) {
aa.deep(
logger.msg, ["Async nested", "inner test"], "Async nested: Name"
);
aa(a, assert, "Assert by single arg");
inProgress = false;
}
});
});
},
"Sync nested": function () {
a.ok(!inProgress, "Sync nested: Progress");
inProgress = true;
a.deep(logger.msg, ["Sync nested"], "Sync nested: Name");
return {
"inner other": function (t) {
a.deep(
logger.msg, ["Sync nested", "inner other"], "Sync nested: inner: Name"
);
a(t, identity, "Testee by single arg");
inProgress = false;
}
};
},
"Nested": {
"in nested": function () {
a.ok(!inProgress, "Nested: Progress");
inProgress = true;
a.deep(logger.msg, ["Nested", "in nested"], "Nested: Name");
inProgress = false;
}
},
"Check args": function (a, d) {
aa.ok(!inProgress, "Args: Progress");
inProgress = true;
aa(a, assert, "Assert as first arg when two args");
d(function (d) {
var e, l = logger.length;
aa.deep(logger.msg, ["Check args", ""], "Tests as function");
inProgress = false;
d((e = new Error("Foo")));
aa(logger[l].data, e, "Async error");
});
}
},
assert,
logger
);
logger.on("end", function () {
var l, seen = false;
l = t(identity, function (t, a) { a.ok(true, "Ok"); });
l.on("data", function () { seen = true; });
l.on("end", function () {
a.ok(seen, "Tests are run in nextTick");
d();
});
});
};