unassertEncourage Design by Contract (DbC) by writing assertions
in production code, and compiling them away from release
Takuto Wada
Nov 7, 2015 @nodefest Tokyo 2015
Takuto Wada
Twitter: @t_wada
github: @twada
Do you write tests?
assert(typeof item.id === 'strong')
| | | |
| | | false
| | "foo"
| Item{id:"foo",name:"bar"}
"string"
--- [string] 'strong'
+++ [string] typeof item.id
@@ -1,6 +1,6 @@
str
-o
+i
ng
I m the author of power-assert-js!
power-assert
Wrestling with Babel6 recently…
unassertEncourage Design by Contract (DbC) by writing assertions
in production code, and compiling them away from release
•unassert
•unassertify
•babel-plugin-unassert
•webpack-unassert-loader
unassert family
'use strict';
var assert = require('assert');
function add (a, b) {
console.assert(typeof a === 'number');
assert(!isNaN(a));
assert.equal(typeof b, 'number');
assert.ok(!isNaN(b));
return a + b;
}
before
src.js
babel --plugins babel-plugin-unassert src.js > dest.js
browserify -t unassertify src.js > dest.js
'use strict';
var assert = require('assert');
function add (a, b) {
console.assert(typeof a === 'number');
assert(!isNaN(a));
assert.equal(typeof b, 'number');
assert.ok(!isNaN(b));
return a + b;
}
after
dest.js
User s voice
https://www.mapbox.com/
In internal / private methods, we
check preconditions with assert,
helping us catch mistakes within the
library.
For performance, these checks are
removed from the production build
with unassertify.
CONTRIBUTING.md
where / when unassert
I don't think we should use this
primarily for type checking, but for
preconditions -- parts of API
contracts that cannot be statically
checked.
@jfirebaugh
why unassert
Flow & TypeScript are compile-time,
and preconditions could be runtime.
Mapbox GL JS is pretty minimal in
terms of transforms - envify, brfs, glify
- such that all JS is vanilla.
@tmcw
why not flow / typescript
preconditions?
postconditions?
invariants?
{P} A {Q}
Design by Contract by Bertrand Meyer
If you promise to call routine with
precondition satisfied then I, in
return, promise to deliver a final
state in which postcondition is
satisfied.
Design by Contract (DbC)
•redundant checks can and indeed will hurt
•simplicity becomes a crucial criterion
•complexity is the major enemy of quality
•whose responsibility it is to enforce it: the
client's, or the supplier's.
Design by Contract (DbC)
switch (name) {
case 'foo':
doSomething();
break;
case 'bar':
doAnother();
break;
default:
assert(false, 'Cannot be here');
}
Not only preconditions
add(path) {
assert(path instanceof PathElement,
`path should be PathElement but was: ${ typeName(path) }`);
this.paths.push(path);
assert.deepEqual(this.paths, sortedPathElements(this.paths),
'this.paths should always be sorted');
}
Not only preconditions
Not only preconditions
What if…
we use power-assert instead of assert?
import assert from 'power-assert';
class Calc {
add (a, b) {
assert(!(isNaN(a) || isNaN(b)));
assert(typeof a === 'number');
assert(typeof b === 'number');
return a + b;
}
}
const calc = new Calc();
console.log(calc.add(3, NaN));
calc.js
write assertions with power-assert
{
"env": {
"development": {
"plugins": [
"babel-plugin-espower"
],
},
"production": {
"plugins": [
"babel-plugin-unassert"
]
}
}
} .babelrc
unassert in prod, power-assert in dev
$ $(npm bin)/babel-node calc.js
AssertionError: # calc.js:5
assert(!(isNaN(a) || isNaN(b)))
| | | | | |
| | | | true NaN
| false 3 true
false
power-assert output appears!
user s voice
One more thing…
unassert is now babel6 ready!
power-assert is not babel6 ready yet
update: 2015/11/13
power-assert now
supports babel6!!
power-assert now works with async/await
# test/some_test.js:6
assert((await bigOrSmall(input)) === big)
| | | |
| | | "big"
"small" 3 false
--- [string] big
+++ [string] await bigOrSmall(input)
@@ -1,3 +1,5 @@
-big
+small
power-assert now works with async/await
by @jamestalmage
Encourage reliable programming
by writing assertions in
production code,
and compiling them away from
release (if you want).
to recap
power-assert
https://github.com/power-assert-js/power-assert
unassert
https://github.com/twada/unassert
Thank you!

unassert - encourage reliable programming by writing assertions in production