diff --git a/README.md b/README.md index e5e52be..491bd69 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,44 @@ # test.js -experimental test runner.... +Experimental test runner.... + +## Features + +XXX + +## Contents - [test.js](#testjs) + - [Features](#features) + - [Contents](#contents) - [Architecture](#architecture) - [Combinational testing](#combinational-testing) - [Unit testing](#unit-testing) - [Basic usage](#basic-usage) + - [Components](#components) + - [`DEFAULT_TEST_FILES`](#default_test_files) + - [`IGNORE_TEST_FILES`](#ignore_test_files) + - [`Merged(..)`](#merged) + - [`.members`](#mergedmembers) + - [`.size` / `.usize`](#mergedsize--mergedusize) + - [`.add(..)` / `.remove(..)`](#mergedadd--mergedremove) + - [`.clear()`](#mergedclear) + - [`.keys(..)` / `.values(..)` / `.entries(..)`](#mergedkeys--mergedvalues--mergedentries) + - [`.toObject(..)`](#mergedtoobject) + - [`.checkShadowing(..)`](#mergedcheckshadowing) + - [`.handleShadowing(..)`](#mergedhandleshadowing) + - [`.filename`](#memberfilename) + - [`Setups(..)` / `Setup(..)` (Merged)](#setups--setup-merged) + - [`Modifiers(..)` / `Modifier(..)` (Merged)](#modifiers--modifier-merged) + - [`Tests(..)` / `Test(..)` (Merged)](#tests--test-merged) + - [`Cases(..)` / `Case(..)` (Merged)](#cases--case-merged) + - [`Assert(..)`](#assert) + - [`run(..)`](#run) + - [Advanced components](#advanced-components) + - [`runner(..)`](#runner) + - [`parser(..)`](#parser) + - [Utilities](#utilities) + - [`getCallerFilename()`](#getcallerfilename) + - [License](#license) ## Architecture @@ -17,6 +50,7 @@ This package implements two testing schemes: - Unit testing Simple independent tests. + ### Combinational testing In general the idea here is that you define three things: @@ -52,30 +86,305 @@ This is the traditional self-contained test approach. ## Basic usage +```shell_session +$ touch test.js +$ chmod +x test.js +``` + +The code: ```javascript +#!/usr/bin/env node + var test = require('ig-test') test.Setups({ - basic: function(assert){ + state: function(assert){ return { a: 123, b: 321, } }, }) +test.Modifiers({ + inc: function(assert, state){ + Object.keys(state) + .forEach(function(k){ + state[k] += 1 }) + return state }, +}) + test.Tests({ }) +test.Cases({ + +}) // make the test runnable as a standalone script... __filename == (require.main || {}).filename && tests.run() ``` +Run the tests ```shell_session $ runtests ``` +or +```shell_session +$ node ./test.js +``` + + +## Components + +### `DEFAULT_TEST_FILES` + +[`glob`][glob] pattern(s) used to find test files by default. +``` +DEFAULT_TEST_FILES = + undefined + | + | [ , .. ] +``` + +Default value: `"**/?(*-)test.js"` + + +### `IGNORE_TEST_FILES` + +A list of [`glob`][glob] patterns to ignore while searching for tests. +``` +IGNORE_TEST_FILES = + undefined + | [ , .. ] +``` + +Default value: `['node_modules/**']` + + +### `Merged(..)` + +Implements a _merged_ collection of instances (_members_). +``` +Merged({ : , .. }) + -> + +Merged(, ) + -> +``` + +On construction this will assign the input object / ``-`` into the resulting +``/instance object. + +Each ``/instance created is added to the constructor as a _member_ (i.e. +added into `.members`) + +Provides a set of methods and properties to access/introspect the _merged_ +(hence the name) attributes of the _members_ (i.e. `.keys(..)`, `.values(..)`, +`.entries(..)`, `.size`/`.usize` and `.members`). + + +#### `.members` + +List of _members_ / instances of `Merged` in order of creation. + + +#### `.size` / `.usize` + +Number of _members_ including the `"-"` members and not including respectively. + +#### `.add(..)` / `.remove(..)` + +Add / remove a member. +``` +.add() + -> + +.remove() + -> +``` + +#### `.clear()` + +Remove (_clear_) all the members. + + +#### `.keys(..)` / `.values(..)` / `.entries(..)` + +``` +.keys() +.keys() + -> + +.values() +.values() + -> + +.entries() +.entries() + -> +``` + +These are similar to `Object.keys(..)` / `Object.values(..)` / `Object.entries(..)` +but will also if called without arguments return a list of the callers member +keys/values/entries respectively. + +Note that members' attributes can _shadow_ previous member attributes, only one +value per key will be returned. `` will warn when adding a member of its +attributes will _shadow_ already existing members' attributes (see: +[`.checkShadowing(..)`](#mergedcheckshadowing) and +[`.handleShadowing(..)`](#mergedhandleshadowing)); +Also note that the check for shadowing is performed when the `` is +created and not when new attributes are added manually. + + +#### `.toObject(..)` + +Create an object containing all visible member attributes. +``` +.toObject() + -> +``` + +#### `.checkShadowing(..)` + +Find all shadowed attributes within ``. +``` +.checkShadowing() +``` + +Find all attributes in `` that will be shadowed by `` +``` +.checkShadowing() + -> +``` + + +#### `.handleShadowing(..)` + +Will be called on `` construction when attribute _shadowing_ is detected. +``` +`.handleShadowing()` + -> +``` + +By default this will print a warning and continue, but can be overloaded by the +user to react to _shadowing_ in a different manner. + + +#### `.filename` + +The filename where the `` was defined. + + +### `Setups(..)` / `Setup(..)` (Merged) + +XXX + +A _subclass_ or rather _sub-constructor_ of `Merged`. + +Note that `Setups` and `Setup` are references to the same object, they exists +for better readability in cases when we add a single test or a bunch of tests, +e.g: +```javascript +test.Setup('some-setup', + function(){ + // ... + }) + +test.Setups({ + 'some-other-setup': function(){ + // ... + }, + + // ... +}) +``` + +### `Modifiers(..)` / `Modifier(..)` (Merged) + +XXX + +A _sub-constructor_ of `Merged`. + +### `Tests(..)` / `Test(..)` (Merged) + +XXX + +A _sub-constructor_ of `Merged`. + +### `Cases(..)` / `Case(..)` (Merged) + +XXX + +A _sub-constructor_ of `Merged`. + + +### `Assert(..)` + +XXX this may still change... + + +### `run(..)` + +Run the test system. +``` +run() +run() +run() +run(, ) + -> +``` + +This will: +- parse `process.argv` +- locate and run tests +- report basic stats + +`` format: +``` +{ + setups: , + modifiers: , + tests: , + cases: , +} +``` + + +## Advanced components + +### `runner(..)` + +The default test combinator and runner. + + +### `parser(..)` + +The default [`ig-argv`][ig-argv] parser setup. + + +## Utilities + +### `getCallerFilename()` + +Returns the filename of the module where `getCallerFilename()` is called. + + +## License + +[BSD 3-Clause License](./LICENSE) + +Copyright (c) 2016-2020, Alex A. Naanou, +All rights reserved. + + + +[glob]: https://github.com/isaacs/node-glob +[object.js]: https://github.com/flynx/object.js +[ig-argv]: https://github.com/flynx/argv.js + \ No newline at end of file diff --git a/test.js b/test.js index 3f2d2ed..6cc332e 100644 --- a/test.js +++ b/test.js @@ -232,7 +232,9 @@ object.Constructor('Assert', { //--------------------------------------------------------------------- +// XXX var mergeIter = function(iter){ + // XXX should this get a function as argument??? return function(c){ c = c || this return (c.members || []) @@ -309,7 +311,7 @@ object.Constructor('Merged', { checkShadowing: function(other){ var existing = new Set(this.keys()) - other = other || this.values() + other = other || this.members return (other instanceof Array ? other : [other])