mirror of https://github.com/n2geoff/testit.git
reworked assertions to use an expect BDD-like
This commit is contained in:
parent
f4bcad2396
commit
8b2daee21f
61
README.md
61
README.md
|
@ -2,17 +2,22 @@
|
||||||
|
|
||||||
> A minimalistic testing library
|
> A minimalistic testing library
|
||||||
|
|
||||||
**Test.it** is a small testing library for people that want to live in code, not tests. No over engineering here. Inspired by the simplicity of libraries like [Tape](https://github.com/substack/tape), but the implementation ideas of [TinyTest](https://github.com/joewalnes/jstinytest)
|
**Test.it** is a small testing library for people that want to live in code, not in tests. No over engineering here. Inspired by the simplicity of libraries like [Tape](https://github.com/substack/tape),but the implementation ideas of things like [Expect](https://github.com/Automattic/expect.js) and [TinyTest](https://github.com/joewalnes/jstinytest)
|
||||||
|
|
||||||
|
This is probally not a *cure-all* testing solution, if you want something more robust checkout [Jasmine](), [Tape]() or [Mocha]() -- this is to...
|
||||||
|
|
||||||
|
**Test small things, with small things**
|
||||||
|
|
||||||
### Features
|
### Features
|
||||||
|
|
||||||
- Works in the Browser
|
- Works in the Browser
|
||||||
- Works with CommonJS (aka NodeJS)
|
- Works with CommonJS (aka NodeJS)
|
||||||
- Less than 100 lines
|
- Barely over a 100 lines
|
||||||
- Single File
|
- Single File
|
||||||
- No Dependicies
|
- No Dependicies
|
||||||
- 2kb footprint (*before gzip*)
|
- 2kb footprint (*before gzip*)
|
||||||
- Extend with custom reporters
|
- Extend with custom reporters
|
||||||
|
- Has an Expect-like style BDD assertions
|
||||||
|
|
||||||
**No Bloat Here!**
|
**No Bloat Here!**
|
||||||
|
|
||||||
|
@ -25,10 +30,10 @@ By default, you can run your tests like
|
||||||
```js
|
```js
|
||||||
test.it({
|
test.it({
|
||||||
'my passing test': function() {
|
'my passing test': function() {
|
||||||
test.pass();
|
test.expects().to.pass();
|
||||||
},
|
},
|
||||||
'my failing test': function() {
|
'my failing test': function() {
|
||||||
test.fail('just wanted to fail fast');
|
test.expects().to.fail('just wanted to fail fast');
|
||||||
}
|
}
|
||||||
}).run();
|
}).run();
|
||||||
```
|
```
|
||||||
|
@ -46,9 +51,11 @@ test.it({
|
||||||
|
|
||||||
A `+` will proceed test lines that pass and a `-` for those that fail, the trace back `file:line` is included after the failing test proceeded by `- -`
|
A `+` will proceed test lines that pass and a `-` for those that fail, the trace back `file:line` is included after the failing test proceeded by `- -`
|
||||||
|
|
||||||
|
> NOTE: API still in flux, and may change to closer match TAP
|
||||||
|
|
||||||
### Optional Next
|
### Optional Next
|
||||||
|
|
||||||
`test.it` `.run()` method provides an optional `next` function parameter that will return the results as an `object` for you to process *however* you like
|
`test.it` `.run()` method provides an optional `next` function parameter that passes the results as an `object` for you to process *however* you like. such as a custom runner
|
||||||
|
|
||||||
For Example...
|
For Example...
|
||||||
|
|
||||||
|
@ -81,21 +88,39 @@ From this object you can easily find the number of tests ran `pass.length`, numb
|
||||||
|
|
||||||
## Methods
|
## Methods
|
||||||
|
|
||||||
To stay minimal, `test.it` only provides 7 methods, 5 for assertion, 1 to capture tests
|
To stay minimal, `test.it` only has 3 core functions:
|
||||||
and 1 to run tests
|
- `it` to capture your tests
|
||||||
|
- `run` to execute yours tests
|
||||||
|
- and `expects` to write your test assertions
|
||||||
|
|
||||||
| Methods | Description |
|
While you can use your own assertion library, the included `expects` provides the following methods for writing your tests:
|
||||||
| ------------------------------- | --------------------------------------- |
|
|
||||||
| `test.it(tests)` | captures test object |
|
| Methods | Description |
|
||||||
| `test.it(tests).run(next)` | runs tests w/ optional processing |
|
| --------------------------------- | --------------------------------------- |
|
||||||
| `test.pass()` | pass test |
|
| `.expects(tests).to.exist()` | truthy evalution if value exists |
|
||||||
| `test.fail(message)` | fails test with message |
|
| `.expects().to.pass()` | pass test |
|
||||||
| `test.exists(value)` | check if value exists |
|
| `.expects().to.fail(message)` | fails test with message |
|
||||||
| `test.assert(expected, actual)` | evaluates results using `==` |
|
| `.expects(this).to.equal(that)` | strictly equal evaluation using `===` |
|
||||||
| `test.equals(expected, actual)` | evaluates results using `===` |
|
| `.expects(this).to.be.like(that)` | loose evaluation using `==` |
|
||||||
|
| `.expects(123).to.be.a('number')` | check typeof value (`.a()` or `.an()`) |
|
||||||
|
|
||||||
> NOTE: wish `eval` was not so evil, `assert(expression, message)` would be ideal
|
> NOTE: wish `eval` was not so evil, `assert(expression, message)` would be ideal
|
||||||
|
|
||||||
|
if you want to shorten test typing try
|
||||||
|
|
||||||
|
let expect = test.expects;
|
||||||
|
|
||||||
|
putting that above your tests will allow you to write like
|
||||||
|
|
||||||
|
```js
|
||||||
|
test.it({
|
||||||
|
"my test should work": function() {
|
||||||
|
expect().to.pass();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
## Support
|
## Support
|
||||||
|
|
||||||
Please open [an issue](https://github.com/n2geoff/testit/issues/new) for support.
|
Please open [an issue](https://github.com/n2geoff/testit/issues/new) for support.
|
||||||
|
@ -106,5 +131,5 @@ Anyone is welcome to contribute, however, if you decide to get involved, please
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
[MIT](LICENSE).
|
[MIT](LICENSE)
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,102 @@
|
||||||
|
/*! Test.it v 0.6.1 | MIT | https://github.com/n2geoff/testit */
|
||||||
|
(function (root, factory) {
|
||||||
|
"use strict";
|
||||||
|
if (typeof module === "object" && module.exports) {
|
||||||
|
module.exports = factory(root.test);
|
||||||
|
} else {
|
||||||
|
root.test = factory(root.test);
|
||||||
|
}
|
||||||
|
}(this, function () {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
const test = {
|
||||||
|
"_tests": {},
|
||||||
|
"run": function (next) {
|
||||||
|
|
||||||
|
let tests = this._tests;
|
||||||
|
let failed = [];
|
||||||
|
let passed = [];
|
||||||
|
|
||||||
|
Object.keys(tests).forEach(function (name) {
|
||||||
|
let test = tests[name];
|
||||||
|
|
||||||
|
try {
|
||||||
|
test();
|
||||||
|
passed.push(`\n+ ${name}`);
|
||||||
|
} catch (err) {
|
||||||
|
failed.push(`\n- ${name}`);
|
||||||
|
console.error(err);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if(typeof next === "function") {
|
||||||
|
return next({
|
||||||
|
pass: passed,
|
||||||
|
fail: failed
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
console.log(...passed, ...failed);
|
||||||
|
console.log(`\n# tests ${failed.length + passed.length} pass ${passed.length} fail ${failed.length}`);
|
||||||
|
|
||||||
|
return failed.length ? false : true;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"it": function (tests) {
|
||||||
|
this._tests = tests;
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
"expects": (val) => {
|
||||||
|
return {
|
||||||
|
"to": {
|
||||||
|
"be": {
|
||||||
|
"a": (type) => {
|
||||||
|
return test.expects(val).to.be.an(type);
|
||||||
|
},
|
||||||
|
"an": (type) => {
|
||||||
|
|
||||||
|
if(['array'].indexOf(type) !== -1) {
|
||||||
|
if(val.constructor.name.toLowerCase() === 'array') {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
throw new Error(`expected ${typeof val} to be an ${type}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(typeof val === type) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
throw new Error(`expected ${typeof val} to be an ${type}`);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"like": (comp) => {
|
||||||
|
if(val == comp) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
throw new Error(`expected ${val} == ${comp}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"equal": (comp) => {
|
||||||
|
|
||||||
|
if(val === comp) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
throw new Error(`expected ${val} === ${comp}`);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"exist": () => {
|
||||||
|
if(val) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
throw new Error(`expected ${val} to be truthy`);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"pass": () => { return true; },
|
||||||
|
"fail": (msg) => { throw new Error(msg); }
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return test;
|
||||||
|
}));
|
|
@ -0,0 +1,2 @@
|
||||||
|
/*! Test.it v 0.6.1 | MIT | https://github.com/n2geoff/testit */
|
||||||
|
!function(t,e){"use strict";"object"==typeof module&&module.exports?module.exports=e(t.test):t.test=e(t.test)}(this,function(){"use strict";const t={_tests:{},run:function(t){let e=this._tests,r=[],o=[];return Object.keys(e).forEach(function(t){let n=e[t];try{n(),o.push(`\n+ ${t}`)}catch(e){r.push(`\n- ${t}`),console.error(e)}}),"function"==typeof t?t({pass:o,fail:r}):(console.log(...o,...r),console.log(`\n# tests ${r.length+o.length} pass ${o.length} fail ${r.length}`),!r.length)},it:function(t){return this._tests=t,this},expects:e=>({to:{be:{a:r=>t.expects(e).to.be.an(r),an:t=>{if(-1!==["array"].indexOf(t)){if("array"===e.constructor.name.toLowerCase())return!0;throw new Error(`expected ${typeof e} to be an ${t}`)}if(typeof e===t)return!0;throw new Error(`expected ${typeof e} to be an ${t}`)},like:t=>{if(e==t)return!0;throw new Error(`expected ${e} == ${t}`)}},equal:t=>{if(e===t)return!0;throw new Error(`expected ${e} === ${t}`)},exist:()=>{if(e)return!0;throw new Error(`expected ${e} to be truthy`)},pass:()=>!0,fail:t=>{throw new Error(t)}}})};return t});
|
|
@ -1,5 +1,5 @@
|
||||||
/* Test.it v 0.5.2 | MIT | https://github.com/n2geoff/testit */
|
/*! Test.it v 0.6.1 | MIT | https://github.com/n2geoff/testit */
|
||||||
;(function (root, factory) {
|
(function (root, factory) {
|
||||||
"use strict";
|
"use strict";
|
||||||
// support browser & commonjs
|
// support browser & commonjs
|
||||||
if (typeof module === "object" && module.exports) {
|
if (typeof module === "object" && module.exports) {
|
||||||
|
@ -18,26 +18,21 @@
|
||||||
// capture results
|
// capture results
|
||||||
let failed = [];
|
let failed = [];
|
||||||
let passed = [];
|
let passed = [];
|
||||||
|
|
||||||
// loop through tests
|
// loop through tests
|
||||||
Object.keys(tests).forEach(function (name) {
|
Object.keys(tests).forEach(function (name) {
|
||||||
let test = tests[name];
|
let test = tests[name];
|
||||||
|
|
||||||
// execute
|
// execute
|
||||||
try {
|
try {
|
||||||
test();
|
test();
|
||||||
passed.push(`\n+ ${name}`);
|
passed.push(`\n+ ${name}`);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
// TODO: include error stack option
|
|
||||||
// let back = err.stack.split('\n')[2];
|
|
||||||
// let re = /(?<=\()(.*?)(?=\))/g;
|
|
||||||
// let trace = re.exec(back)[0];
|
|
||||||
failed.push(`\n- ${name}`);
|
failed.push(`\n- ${name}`);
|
||||||
console.error(err);
|
console.error(err);
|
||||||
// failed.push(`\n- ${name} - - ${trace}`);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// summary
|
// summary
|
||||||
if(typeof next === "function") {
|
if(typeof next === "function") {
|
||||||
return next({
|
return next({
|
||||||
|
@ -47,7 +42,7 @@
|
||||||
} else {
|
} else {
|
||||||
console.log(...passed, ...failed);
|
console.log(...passed, ...failed);
|
||||||
console.log(`\n# tests ${failed.length + passed.length} pass ${passed.length} fail ${failed.length}`);
|
console.log(`\n# tests ${failed.length + passed.length} pass ${passed.length} fail ${failed.length}`);
|
||||||
|
|
||||||
return failed.length ? false : true;
|
return failed.length ? false : true;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -55,11 +50,57 @@
|
||||||
this._tests = tests;
|
this._tests = tests;
|
||||||
return this;
|
return this;
|
||||||
},
|
},
|
||||||
"assert": function (e, a) { if (e != a) throw Error(`expected ${e} == ${a}`); },
|
"expects": (val) => {
|
||||||
"equals": function (e, a) { if (e !== a) throw Error(`expected ${e} === ${a}`); },
|
return {
|
||||||
"exists": function (v) { if (!v) throw Error(`exists value ${v}`); },
|
"to": {
|
||||||
"pass": function () { return true; },
|
"be": {
|
||||||
"fail": function (m) { throw Error(m); }
|
"a": (type) => {
|
||||||
|
return test.expects(val).to.be.an(type);
|
||||||
|
},
|
||||||
|
"an": (type) => {
|
||||||
|
|
||||||
|
if(['array'].indexOf(type) !== -1) {
|
||||||
|
if(val.constructor.name.toLowerCase() === 'array') {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
throw new Error(`expected ${typeof val} to be an ${type}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(typeof val === type) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
throw new Error(`expected ${typeof val} to be an ${type}`);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"like": (comp) => {
|
||||||
|
if(val == comp) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
throw new Error(`expected ${val} == ${comp}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"equal": (comp) => {
|
||||||
|
|
||||||
|
if(val === comp) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
throw new Error(`expected ${val} === ${comp}`);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"exist": () => {
|
||||||
|
if(val) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
throw new Error(`expected ${val} to be truthy`);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"pass": () => { return true; },
|
||||||
|
"fail": (msg) => { throw new Error(msg); }
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return test;
|
return test;
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
/* Test.it v 0.5.2 | MIT | https://github.com/n2geoff/testit */
|
|
||||||
;(function(root,factory){"use strict";if(typeof module==="object"&&module.exports){module.exports=factory(root.test)}else{root.test=factory(root.test)}})(this,function(){"use strict";const test={_tests:{},run:function(next){let tests=this._tests;let failed=[];let passed=[];Object.keys(tests).forEach(function(name){let test=tests[name];try{test();passed.push(`\n+ ${name}`)}catch(err){failed.push(`\n- ${name}`);console.error(err)}});if(typeof next==="function"){return next({pass:passed,fail:failed})}else{console.log(...passed,...failed);console.log(`\n# tests ${failed.length+passed.length} pass ${passed.length} fail ${failed.length}`);return failed.length?false:true}},it:function(tests){this._tests=tests;return this},assert:function(e,a){if(e!=a)throw Error(`expected ${e} == ${a}`)},equals:function(e,a){if(e!==a)throw Error(`expected ${e} === ${a}`)},exists:function(v){if(!v)throw Error(`exists value ${v}`)},pass:function(){return true},fail:function(m){throw Error(m)}};return test});
|
|
|
@ -1,25 +1,31 @@
|
||||||
test.it({
|
test.it({
|
||||||
"'assert' should exist": function() {
|
"'like' should do truthy evaluation via ==": function() {
|
||||||
test.exists(test.assert);
|
test.expects(1).to.be.like('1');
|
||||||
},
|
test.expects("1").to.be.like(1);
|
||||||
"truty assert should work": function() {
|
},
|
||||||
test.assert(1, '1');
|
"'equal' should do === evaluation exist": function() {
|
||||||
test.assert('1', 1);
|
test.expects(1).to.equal(1);
|
||||||
},
|
test.expects('hello').to.equal('hello');
|
||||||
"'equals' should exist": function() {
|
},
|
||||||
test.exists(test.equals);
|
"you should be able to 'pass' a test": function() {
|
||||||
},
|
test.expects().to.pass();
|
||||||
"'equals' should be exact": function() {
|
},
|
||||||
test.equals(1,1);
|
"you should be able to fail' a test too": function() {
|
||||||
test.equals('hello', 'hello');
|
try {
|
||||||
},
|
test.expects().to.fail();
|
||||||
"'pass' should exist": function() {
|
} catch(e) {
|
||||||
test.exists(test.pass);
|
test.expects().to.pass();
|
||||||
},
|
}
|
||||||
"'fail' should exist": function() {
|
},
|
||||||
test.exists(test.fail);
|
"you should be albe to see if something 'exists'": function() {
|
||||||
},
|
test.expects({}).to.exist();
|
||||||
"'exists' should exist": function() {
|
},
|
||||||
test.exists(test.exists);
|
"should be able to check types": function() {
|
||||||
}
|
test.expects(123).to.be.a('number');
|
||||||
|
test.expects([]).to.be.an('array');
|
||||||
|
test.expects({}).to.be.a('object');
|
||||||
|
test.expects(true).to.be.a('boolean');
|
||||||
|
test.expects(false).to.be.a('boolean');
|
||||||
|
test.expects(undefined).to.be.a('undefined');
|
||||||
|
}
|
||||||
});
|
});
|
Loading…
Reference in New Issue