pax_global_header00006660000000000000000000000064144717422770014531gustar00rootroot0000000000000052 comment=b92f3f0ed3777adf3b68cb6f780b89cd1627ef2c tad-3.1.1/000077500000000000000000000000001447174227700123035ustar00rootroot00000000000000tad-3.1.1/.editorconfig000066400000000000000000000004561447174227700147650ustar00rootroot00000000000000# 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 [*.md] trim_trailing_whitespace = false tad-3.1.1/.eslintignore000066400000000000000000000000231447174227700150010ustar00rootroot00000000000000/test/__playground tad-3.1.1/.github/000077500000000000000000000000001447174227700136435ustar00rootroot00000000000000tad-3.1.1/.github/FUNDING.yml000066400000000000000000000000201447174227700154500ustar00rootroot00000000000000github: medikoo tad-3.1.1/.github/workflows/000077500000000000000000000000001447174227700157005ustar00rootroot00000000000000tad-3.1.1/.github/workflows/integrate.yml000066400000000000000000000004021447174227700204010ustar00rootroot00000000000000# main only name: Integrate on: push: branches: [main] env: FORCE_COLOR: 1 jobs: _: uses: medikoo/github-actions-workflows/.github/workflows/no-tests-integrate.yml@main secrets: USER_GITHUB_TOKEN: ${{ secrets.USER_GITHUB_TOKEN }} tad-3.1.1/.github/workflows/publish.yml000066400000000000000000000004721447174227700200740ustar00rootroot00000000000000# Version tags only name: Publish on: push: tags: - v[0-9]+.[0-9]+.[0-9]+ env: FORCE_COLOR: 1 jobs: _: uses: medikoo/github-actions-workflows/.github/workflows/publish.yml@main secrets: USER_GITHUB_TOKEN: ${{ secrets.USER_GITHUB_TOKEN }} NPM_TOKEN: ${{ secrets.NPM_TOKEN }} tad-3.1.1/.github/workflows/validate.yml000066400000000000000000000003011447174227700202060ustar00rootroot00000000000000# PR's only name: Validate on: pull_request: branches: [main] env: FORCE_COLOR: 1 jobs: _: uses: medikoo/github-actions-workflows/.github/workflows/no-tests-validate.yml@main tad-3.1.1/.gitignore000066400000000000000000000000571447174227700142750ustar00rootroot00000000000000/node_modules npm-debug.log /package-lock.json tad-3.1.1/.npmignore000066400000000000000000000000641447174227700143020ustar00rootroot00000000000000/.editorconfig /.github /commitlint.config.js /test tad-3.1.1/CHANGELOG.md000066400000000000000000000063271447174227700141240ustar00rootroot00000000000000# 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.1](https://github.com/medikoo/tad/compare/v3.1.0...v3.1.1) (2023-08-24) ### Bug Fixes - Ensure to support test functions configured as object methods ([4972a8b](https://github.com/medikoo/tad/commit/4972a8bde8b5022be0888f847bebda3301ea23a5)) ## [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.1/CHANGES000066400000000000000000000075331447174227700133060ustar00rootroot00000000000000v0.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.1/LICENSE000066400000000000000000000014051447174227700133100ustar00rootroot00000000000000ISC License Copyright (c) 2012-2023, 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.1/README.md000066400000000000000000000070751447174227700135730ustar00rootroot00000000000000# 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.1/bin/000077500000000000000000000000001447174227700130535ustar00rootroot00000000000000tad-3.1.1/bin/tad.js000077500000000000000000000037621447174227700141740ustar00rootroot00000000000000#!/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.1/commitlint.config.js000066400000000000000000000012361447174227700162660ustar00rootroot00000000000000"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.1/index.js000077500000000000000000000075771447174227700137730ustar00rootroot00000000000000/* 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.1/lib/000077500000000000000000000000001447174227700130515ustar00rootroot00000000000000tad-3.1.1/lib/assert.js000066400000000000000000000076761447174227700147300ustar00rootroot00000000000000"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.1/lib/configure.js000077500000000000000000000034441447174227700154000ustar00rootroot00000000000000"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.1/lib/console.js000066400000000000000000000070311447174227700150520ustar00rootroot00000000000000"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.1/lib/find-context.js000066400000000000000000000013371447174227700160150ustar00rootroot00000000000000"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.1/lib/find-test-path.js000077500000000000000000000007541447174227700162470ustar00rootroot00000000000000"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.1/lib/fix-test-utils.js000066400000000000000000000017121447174227700163110ustar00rootroot00000000000000// 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.1/lib/load.js000077500000000000000000000030571447174227700143360ustar00rootroot00000000000000// 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.1/lib/logger.js000066400000000000000000000020601447174227700146640ustar00rootroot00000000000000"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.1/lib/require-first-in-tree.js000066400000000000000000000010231447174227700175450ustar00rootroot00000000000000"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.1/lib/require-in-context.js000066400000000000000000000037001447174227700171510ustar00rootroot00000000000000// 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.1/lib/run.js000066400000000000000000000067621447174227700142260ustar00rootroot00000000000000/* 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*)?(?:[^\s()]+\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.1/lib/tad-ignore-mode.js000066400000000000000000000007261447174227700163670ustar00rootroot00000000000000"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.1/lib/utils/000077500000000000000000000000001447174227700142115ustar00rootroot00000000000000tad-3.1.1/lib/utils/factory.js000066400000000000000000000007101447174227700162140ustar00rootroot00000000000000"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.1/lib/utils/index-test.js000077500000000000000000000051411447174227700166370ustar00rootroot00000000000000"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.1/package.json000066400000000000000000000042731447174227700145770ustar00rootroot00000000000000{ "name": "tad", "version": "3.1.1", "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": "medikoo/tad", "dependencies": { "cli-color": "^2.0.3", "d": "^1.0.1", "deferred": "^0.7.11", "duration": "^0.2.2", "es5-ext": "^0.10.62", "essentials": "^1.2.0", "event-emitter": "^0.3.5", "fs2": "^0.2.21", "memoizee": "^0.4.15", "ncjsm": "^4.3.2", "next": "^0.4.1", "optimist": "^0.6.1", "path2": "^0.1.0", "test": "^0.6.0" }, "devDependencies": { "@commitlint/cli": "^13.2.1", "eslint": "^8.47.0", "eslint-config-medikoo": "^4.2.0", "git-list-updated": "^1.2.1", "github-release-from-cc-changelog": "^2.3.0", "husky": "^4.3.8", "lint-staged": "^11.2.6", "prettier-elastic": "^2.2.1", "standard-version": "^9.5.0" }, "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 } } ] }, "scripts": { "commitlint": "commitlint -f HEAD@{15}", "lint": "eslint --ignore-path=.gitignore .", "lint:updated": "pipe-git-updated --base=main --ext=js -- eslint --ignore-pattern '!*'", "prettier-check": "prettier -c --ignore-path .gitignore \"**/*.{css,html,js,json,md,yaml,yml}\"", "prettier-check:updated": "pipe-git-updated --base=main --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}\"", "prettify:updated": "pipe-git-updated ---base=main -ext=css --ext=html --ext=js --ext=json --ext=md --ext=yaml --ext=yml -- prettier --write", "test": "node ./bin/tad" }, "engines": { "node": ">=0.12" }, "license": "ISC" } tad-3.1.1/test/000077500000000000000000000000001447174227700132625ustar00rootroot00000000000000tad-3.1.1/test/.eslintrc.json000066400000000000000000000000701447174227700160530ustar00rootroot00000000000000{ "rules": { "id-length": "off", "no-shadow": "off" } } tad-3.1.1/test/__playground/000077500000000000000000000000001447174227700157445ustar00rootroot00000000000000tad-3.1.1/test/__playground/lib/000077500000000000000000000000001447174227700165125ustar00rootroot00000000000000tad-3.1.1/test/__playground/lib/context-error/000077500000000000000000000000001447174227700213255ustar00rootroot00000000000000tad-3.1.1/test/__playground/lib/context-error/module.js000066400000000000000000000000441447174227700231460ustar00rootroot00000000000000"use strict"; module.exports = {}; tad-3.1.1/test/__playground/lib/dir/000077500000000000000000000000001447174227700172705ustar00rootroot00000000000000tad-3.1.1/test/__playground/lib/dir/dir/000077500000000000000000000000001447174227700200465ustar00rootroot00000000000000tad-3.1.1/test/__playground/lib/dir/dir/module.2.js000066400000000000000000000000441447174227700220270ustar00rootroot00000000000000"use strict"; module.exports = {}; tad-3.1.1/test/__playground/lib/dir/dir/module.js000066400000000000000000000000441447174227700216670ustar00rootroot00000000000000"use strict"; module.exports = {}; tad-3.1.1/test/__playground/lib/dir/module.2.js000066400000000000000000000000441447174227700212510ustar00rootroot00000000000000"use strict"; module.exports = {}; tad-3.1.1/test/__playground/lib/dir/module.js000066400000000000000000000000441447174227700211110ustar00rootroot00000000000000"use strict"; module.exports = {}; tad-3.1.1/test/__playground/lib/dir/other000066400000000000000000000000001447174227700203220ustar00rootroot00000000000000tad-3.1.1/test/__playground/lib/evaluation-error.js000066400000000000000000000000411447174227700223410ustar00rootroot00000000000000"use strict"; generate.error(); tad-3.1.1/test/__playground/lib/index-test/000077500000000000000000000000001447174227700205765ustar00rootroot00000000000000tad-3.1.1/test/__playground/lib/index-test/file-name-1.js000066400000000000000000000000441447174227700231250ustar00rootroot00000000000000"use strict"; module.exports = {}; tad-3.1.1/test/__playground/lib/index-test/file-name-2.js000066400000000000000000000000441447174227700231260ustar00rootroot00000000000000"use strict"; module.exports = {}; tad-3.1.1/test/__playground/lib/index-test/file-name-3.js000066400000000000000000000000441447174227700231270ustar00rootroot00000000000000"use strict"; module.exports = {}; tad-3.1.1/test/__playground/lib/index-test/index.js000066400000000000000000000002561447174227700222460ustar00rootroot00000000000000"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.1/test/__playground/lib/index-test/sub/000077500000000000000000000000001447174227700213675ustar00rootroot00000000000000tad-3.1.1/test/__playground/lib/index-test/sub/index.js000066400000000000000000000000441447174227700230320ustar00rootroot00000000000000"use strict"; module.exports = {}; tad-3.1.1/test/__playground/lib/module.js000066400000000000000000000000441447174227700203330ustar00rootroot00000000000000"use strict"; module.exports = {}; tad-3.1.1/test/__playground/lib/no-tests.js000066400000000000000000000000441447174227700206220ustar00rootroot00000000000000"use strict"; module.exports = {}; tad-3.1.1/test/__playground/lib/test-evaluation-error.js000066400000000000000000000000441447174227700233210ustar00rootroot00000000000000"use strict"; module.exports = {}; tad-3.1.1/test/__playground/module.js000066400000000000000000000000441447174227700175650ustar00rootroot00000000000000"use strict"; module.exports = {}; tad-3.1.1/test/__playground/package.json000066400000000000000000000000471447174227700202330ustar00rootroot00000000000000{ "name": "dummy", "private": true } tad-3.1.1/test/__playground/test/000077500000000000000000000000001447174227700167235ustar00rootroot00000000000000tad-3.1.1/test/__playground/test/context-error/000077500000000000000000000000001447174227700215365ustar00rootroot00000000000000tad-3.1.1/test/__playground/test/context-error/__tad.js000066400000000000000000000000411447174227700231350ustar00rootroot00000000000000"use strict"; generate.error(); tad-3.1.1/test/__playground/test/context/000077500000000000000000000000001447174227700204075ustar00rootroot00000000000000tad-3.1.1/test/__playground/test/context/__tad.js000066400000000000000000000000541447174227700220120ustar00rootroot00000000000000"use strict"; exports.context = { x: {} }; tad-3.1.1/test/__playground/test/context/context/000077500000000000000000000000001447174227700220735ustar00rootroot00000000000000tad-3.1.1/test/__playground/test/context/context/__tad.js000066400000000000000000000001051447174227700234730ustar00rootroot00000000000000"use strict"; exports.context = function (lpath) { return lpath; }; tad-3.1.1/test/__playground/test/context/context/module.js000066400000000000000000000000161447174227700237130ustar00rootroot00000000000000"use strict"; tad-3.1.1/test/__playground/test/context/dir/000077500000000000000000000000001447174227700211655ustar00rootroot00000000000000tad-3.1.1/test/__playground/test/context/dir/module.js000066400000000000000000000000161447174227700230050ustar00rootroot00000000000000"use strict"; tad-3.1.1/test/__playground/test/context/module.js000066400000000000000000000000161447174227700222270ustar00rootroot00000000000000"use strict"; tad-3.1.1/test/__playground/test/dir/000077500000000000000000000000001447174227700175015ustar00rootroot00000000000000tad-3.1.1/test/__playground/test/dir/dir/000077500000000000000000000000001447174227700202575ustar00rootroot00000000000000tad-3.1.1/test/__playground/test/dir/dir/dummy000066400000000000000000000000001447174227700213230ustar00rootroot00000000000000tad-3.1.1/test/__playground/test/function-test.js000066400000000000000000000000641447174227700220630ustar00rootroot00000000000000"use strict"; module.exports = function (a, d) {}; tad-3.1.1/test/__playground/test/generics-test/000077500000000000000000000000001447174227700214775ustar00rootroot00000000000000tad-3.1.1/test/__playground/test/generics-test/__scopes.js000066400000000000000000000001271447174227700236270ustar00rootroot00000000000000"use strict"; exports.First = { name: "First" }; exports.Second = { name: "Second" }; tad-3.1.1/test/__playground/test/generics-test/test.js000066400000000000000000000001421447174227700230110ustar00rootroot00000000000000"use strict"; exports.__generic = { "Sample test": function (t, a) { a.ok(true, this.name); } }; tad-3.1.1/test/__playground/test/module.js000066400000000000000000000002001447174227700205360ustar00rootroot00000000000000"use strict"; exports.pass = function (t, a) { a.ok(true, "Pass"); }; exports.fail = function (t, a) { a.ok(false, "Fail"); }; tad-3.1.1/test/__playground/test/test-evaluation-error.js000066400000000000000000000000411447174227700235270ustar00rootroot00000000000000"use strict"; generate.error(); tad-3.1.1/test/index.js000066400000000000000000000015231447174227700147300ustar00rootroot00000000000000"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.1/test/lib/000077500000000000000000000000001447174227700140305ustar00rootroot00000000000000tad-3.1.1/test/lib/assert.js000066400000000000000000000015271447174227700156740ustar00rootroot00000000000000"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.1/test/lib/configure.js000077500000000000000000000024311447174227700163520ustar00rootroot00000000000000"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.1/test/lib/console.js000066400000000000000000000046671447174227700160450ustar00rootroot00000000000000"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.1/test/lib/find-context.js000077500000000000000000000015471447174227700170020ustar00rootroot00000000000000"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.1/test/lib/find-test-path.js000077500000000000000000000007451447174227700172260ustar00rootroot00000000000000"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.1/test/lib/load.js000077500000000000000000000011241447174227700153060ustar00rootroot00000000000000"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.1/test/lib/logger.js000066400000000000000000000013431447174227700156460ustar00rootroot00000000000000"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.1/test/lib/run.js000066400000000000000000000051761447174227700152030ustar00rootroot00000000000000"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(); }); }); };