Upgrade to Pro — share decks privately, control downloads, hide ads and more …

finite-state-monster: An exploration of Javascript Tools

finite-state-monster: An exploration of Javascript Tools

Danielle Brook-Roberge

January 14, 2016
Tweet

More Decks by Danielle Brook-Roberge

Other Decks in Programming

Transcript

  1. Overview • Over winter cleaning, I worked on a small

    side project library to test out some new tooling without the overhead of converting an existing project like Pusheen. • https://github.com/DanielBrookRoberge/finite-state-monster • The finite-state-monster library is a small library for building and using finite state machines in Javascript.
  2. What Boring Stuff I Used • The build setup was

    based on the Pusheen build system, using a Makefile to control the build and packaging Javascript using Browserify. • The linting setup was also (mostly) identical to Pusheen, using eslint and the Mobify standard .eslintrc. • Everything was wrapped in a Vagrant to ensure clean, repeatable environments.
  3. Babel • The first tool I tried was Babel for

    transpiling of ES6 to browser-standard ES5. • A Browserify transform called Babelify allows simple integration of Babel into a Browserify build system. • Setting up and using Babel was easy, but had some awkward interactions with some of the non-ES6-aware testing tools I used.
  4. Flow Type • The next step was to try using

    the Flow type checker. • I found Flow difficult to get working and very heavyweight and slow. • It also did not track changes to the files correctly in the Vagrant. • I also found it difficult to annotate ad-hoc data structures in a way that would produce meaningful type errors.
  5. Flow Typing • In Flow, the type annotation for the

    (input) machine definition I was using is: Array<string | Array<Array<string | Array<string>>> | {[key: string]: {[key:string]: string}} • This compares poorly with my C++ benchmark Std::vector<ND::THandle<ND::THitSelection> >::const_iterator
  6. Removal of Flow • While the type example on the

    last page could be simplified with typedefs, it is more work than would be justified for a single-use type like this. • Given the difficulty of using Flow in this situation, I have removed it from the current master of finite-state-monster.
  7. Karma • Karma is a Javascript test runner, initially developed

    by the Angular team. • It is plugin-based and plugins are available to integrate with most test systems and browsers. • The Karma setup I have for finite-state-monster automatically builds the test bundle with browserify, runs the test suite in PhantomJS and Chrome, and produces test coverage reports using Istanbul.
  8. Extensibility • Karma is very extensible. • Adding additional browsers

    is straightforward (Firefox support would be trivial, for example). • There is a plugin for using Karma to coordinate tests on SauceLabs using the same configuration interface as local browsers. • If it is configured correctly, it can also rerun the test suite (or a limited version thereof) on every file save.
  9. Istanbul • Istanbul is a code coverage tool that has

    good integration with Karma. • It can run as part of a standard Karma run, and will generate an HTML coverage report with per-file and global statistics, plus annotated version of the source. • Unfortunately, I was not able to get it to work with heavily Babel-transformed source, such as the ES6 classes I wrote to manage the FSM
  10. Summary • Babel: simple to set up, integrates with browserify,

    not boring enough. • Flow: Slow, poor interface, unsuitable for functional JS. • Karma: Easy to configure and extend, requires much less manual maintenance than mocha- phantomjs • Istanbul: Gives good coverage reports for Karma tests of ES5, awkward with Babel.