Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

unassert - encourage reliable programming by writing assertions in production

15,734 views

Published on

unassert - Encourage Design by Contract (DbC) by writing assertions in production code, and compiling them away from release.

Takuto Wada
2015/11/07 @nodefest Tokkyo 2015

Published in: Technology
  • Be the first to comment

unassert - encourage reliable programming by writing assertions in production

  1. 1. 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
  2. 2. Takuto Wada Twitter: @t_wada github: @twada
  3. 3. Do you write tests?
  4. 4. 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
  5. 5. Wrestling with Babel6 recently…
  6. 6. unassertEncourage Design by Contract (DbC) by writing assertions in production code, and compiling them away from release
  7. 7. •unassert •unassertify •babel-plugin-unassert •webpack-unassert-loader unassert family
  8. 8. '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
  9. 9. babel --plugins babel-plugin-unassert src.js > dest.js browserify -t unassertify src.js > dest.js
  10. 10. '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
  11. 11. User s voice
  12. 12. https://www.mapbox.com/
  13. 13. 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
  14. 14. 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
  15. 15. 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
  16. 16. preconditions? postconditions? invariants?
  17. 17. {P} A {Q}
  18. 18. Design by Contract by Bertrand Meyer
  19. 19. 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)
  20. 20. •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)
  21. 21. switch (name) { case 'foo': doSomething(); break; case 'bar': doAnother(); break; default: assert(false, 'Cannot be here'); } Not only preconditions
  22. 22. 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
  23. 23. Not only preconditions
  24. 24. What if… we use power-assert instead of assert?
  25. 25. 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
  26. 26. { "env": { "development": { "plugins": [ "babel-plugin-espower" ], }, "production": { "plugins": [ "babel-plugin-unassert" ] } } } .babelrc unassert in prod, power-assert in dev
  27. 27. $ $(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!
  28. 28. user s voice
  29. 29. One more thing…
  30. 30. unassert is now babel6 ready!
  31. 31. power-assert is not babel6 ready yet update: 2015/11/13 power-assert now supports babel6!!
  32. 32. power-assert now works with async/await
  33. 33. # 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
  34. 34. Encourage reliable programming by writing assertions in production code, and compiling them away from release (if you want). to recap
  35. 35. power-assert https://github.com/power-assert-js/power-assert unassert https://github.com/twada/unassert Thank you!

×