• Stars
    star
    105
  • Rank 321,166 (Top 7 %)
  • Language
    JavaScript
  • License
    BSD 3-Clause "New...
  • Created over 10 years ago
  • Updated almost 10 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Your current coverage tool is lying to you. This one will hurt your feelings.

SteamShovel

JS code coverage done right. Why?

See an example report

Get Started

# install
npm install -g steamshovel

# instrument
shovel mySourceDirectory myInstrumentedDirectory

# introspect
mocha -R steamshovel

For a more detailed guide to the SteamShovel internals, see the API section.

Why Should You Use SteamShovel

"But I like Blanket/Istanbul/JScover!" I hear you say. "Why should I move?"

That's a great question. It comes down to this:

Your existing instrumentor is lying to you.

That's right. When you run your tests, and the coverage data is collected, the instrumentor only pays attention to whether a code branch was run... or wasn't. Unfortunately this is a gross oversimplification of how code is invoked by a test suite, and it will leave you with a false sense of security.

The hypothesis behind SteamShovel is this:

Your unit tests should run your code directly. Indirect invocation is probably unintentional, and that code shouldn't be considered tested.

In order to support this hypothesis, SteamShovel records the stack depth of the instrumentor at every invocation, and calculates the 'testedness' of a given branch by applying a weighted inverse logarithm to this depth.

This gives you a much more accurate code coverage value. The variance in 'coverage' as defined by SteamShovel and a conventional instrumentor like Istanbul can be as much as 50% β€” that's how much Istanbul is over-reporting.

What else?

SteamShovel can do a whole lot more, too:

  • Profile timing, order, and stack depth
  • Record environment data like memory or load on a per-expression level (set the environment variable REPORTER_OUTPUT to csv and you'll get an expression level dump of timing and memory data!
  • Save the result of every evaluation of every expression in your codebase, and let you step through the results of your test run, interactively. (Coming soon!)
  • SteamShovel can now auto-instrument your code as you require it! Simply set the AUTO_INSTRUMENT environment variable to true before running the SteamShovel reporter. Remember that this won't instrument code that isn't required, so the manual instrumentor may be more accurate in some cases.

You can override the SteamShovel instrumentor with your own, and record anything you might want to record! The sky is the limit.

SteamShovel's exported memory data from a test run

Seen here: SteamShovel's recorded memory data from a test run, visualised in, uh... Numbers.app

See also: Stack depth of calls over time, Call latency over run-time of test suite β€” you're only limited by your imagination here.

Caveat

Because SteamShovel records so much more from your code, it does have a considerable performance impact. However, the accuracy of your test coverage data should be more important than how quickly it runs.

Also, (if you couldn't tell already!) SteamShovel is early in its development. Be careful: there will be an excruciating number of bugs.

I am most of the way through an important refactor which will make steamshovel ready for use by anyone!

Todo

  • Stats generation needs to be a lot more abstract, and a lot faster. Look forward to a huge amount of progress in this area!
  • Stats should also allow arbitrary queries to be developed against the data which could be defined by a model and included in the template.
  • Gotta make things even easier to use!
  • More info in the default HTML output.
  • Memory usage and timing output as CSV & JSON!

API

Processing Files

You can recursively instrument one or more directories or files by using the SteamShovel instrument processor. This is the same system the CLI tool uses to instrument your code.

var steamshovel = require("steamshovel");

steamshovel.process("./lib", "./lib-instrumented")
	.on("complete", function(inFile) {
		console.log("The instrumentation of %s is complete!", inFile);
	});

steamshovel.process ( <string | array> inFile, outFile <string | array> , EventEmitter emitter )

This function takes a string describing an input file or directory, or an array of strings of files/directories. If the first parameter is an array, the second must also be an array, and their lengths must be the same.

The function returns an event emitter, to which it emits the following events:

  • complete (file) β€” the processing for one of the directly specified files or directories is complete.
  • dircomplete (dir) β€” the processing for a given directory is complete (this is emitted for directories that SteamShovel discovers, too β€” not just for directly specified trees.)
  • error (error, path/file) β€” an error was emitted from a filesystem operation.
  • ignore (file) β€” this file was explicitly ignored (the directive steamShovel:ignore was found in the file.)
  • instrumenterror (err, file) β€” an error occurred while attempting to instrument a given file (most likely a syntax error.)
  • mkdir (path) β€” emitted when SteamShovel creates a new directory
  • nojs (file) β€” SteamShovel discovered a file, but it is not a JavaScript file and will be ignored. (It will be written into the new tree, but not instrumented.)
  • processdir (dir, out) β€” Emitted when SteamShovel begins processing a new directory
  • readdir (dir) β€” Emitted after SteamShovel reads the contents of a directory.
  • readfile (file) β€” Emitted after SteamShovel completes reading a file.
  • writefile (file) β€” Emitted after SteamShovel completes writing a file.

Instrumenting Code

You can instrument code on a file by file basis by using the steamshovel.instrument method.

steamshovel.instrument ( data, [ filename, incorporateMap ] )

This function takes a string containing the JavaScript source code and returns the transformed code with instrumentation added.

Presently, the code is instrumented by replacing all applicable expressions with SequenceExpressions (you'll probably know these as lists of expressions delimited by way of the comma operator.) These make a function call with a unique ID to the individual expression (incorporating a hash of the filename and an expression index.)

The filename is required if you want to instrument more than one file. Otherwise you could end up with ID conflicts. (This won't ever be a problem if you let SteamShovel instrument for you.)

The third boolean parameter enables you to turn off the 'map', basically a non-human-readable object definition for the expression instrumentation in the code. It is advisable that you leave this alone, as the code won't run without it, but switching it off can be useful for testing the output of the instrument function.

More Repositories

1

Captionator

HTML5 polyfill for closed captioning with the <track> element, and implements the WHATWG Timed Text Track specification.
JavaScript
300
star
2

TextStatistics.js

Generate information about text including syllable counts and Flesch-Kincaid, Gunning-Fog, Coleman-Liau, SMOG and Automated Readability scores.
JavaScript
190
star
3

Behaviour-Assertion-Sheets

CSS-like declarative DSL for web integration testing.
JavaScript
138
star
4

Downsize

Tag safe text truncation for HTML and XML!
JavaScript
41
star
5

Perspex

Helper for perspective projection calculations - set up a camera and start projecting 3D points to 2D!
JavaScript
12
star
6

140ByteShow

A JS slideshow framework in 140 bytes. To prove a point.
CSS
11
star
7

Wrker

Runner for wrk tests
JavaScript
10
star
8

Stegosaw

A proof of concept steganographic encoder for storing encrypted secrets in HTML whitespace
JavaScript
8
star
9

Bivouac

BVH Motion Capture parser for Javascript
JavaScript
7
star
10

Injecto

Test your code in production!
JavaScript
7
star
11

TableEditor

Simple JS UI for editing tables.
JavaScript
7
star
12

Vixen

Ultra-lean HTML5 media player/framework.
JavaScript
7
star
13

DiamondSquare

Implementation of the diamond-square algorithm in JS.
JavaScript
6
star
14

Duckdown

Ultra-simple Markdown-inspired markup language.
JavaScript
6
star
15

Progress

Tiny JS/CSS progress bar.
JavaScript
6
star
16

Psychic

Discovers and extracts content and semantic data from raw HTML.
JavaScript
6
star
17

Illuminite

Simple Javascript wrapper for calculating Blinn-Phong illumination.
JavaScript
6
star
18

Synonyms

CLI tool for retrieving english synonyms
JavaScript
6
star
19

Yoyaku

Really, really simple wrapper to easily create promise-like APIs.
JavaScript
5
star
20

50Lines

Slideshow in < 50 SLOC
JavaScript
5
star
21

PixelWave

Simple pixellating image effect using Canvas
JavaScript
5
star
22

LiveStep-Server-Layer

Server Layer part of step sequencer made at Sydney Amped Hackday 2010
JavaScript
4
star
23

GAAD-Talk-2013

Repo for my Global Accessibility Awareness Day (2013) talk.
JavaScript
4
star
24

CSVtoJSON.js

Little utility to convert a CSV to JSON. Written for node.
JavaScript
4
star
25

isograph

A collection of sprites for drawing diagrams of your cloud infrastructure.
3
star
26

Minideck.js

A very minimal slide deck system with no dependencies except ES5.
JavaScript
3
star
27

NCoder

Little node wrapper for ffmpeg.
JavaScript
3
star
28

YAYAML

Yet Another Yet Another Markup Language
JavaScript
3
star
29

Castor

Ultra-simple HTML/XML parser. Generates a DOM-like (but extremely simplified and not at all compliant) tree.
JavaScript
3
star
30

tcog-filters

A nifty little component discarded from an application.
JavaScript
3
star
31

SmartClone

Cleverly clone objects including their immediate prototypes, without fear!
JavaScript
2
star
32

node-koku

Koku bindings for Node.js
JavaScript
2
star
33

Re-Serve

Node utility for archiving and serving cached websites
JavaScript
2
star
34

Jade-Fixture-Test

Statically test Jade templates.
JavaScript
2
star
35

HotFuzz

Fuzzer for Jade Templates
JavaScript
2
star
36

yasuko-site

ζˆΈη”°ζ³°ε­
HTML
2
star
37

Video-Player

Basic HTML UI for Video
JavaScript
2
star
38

webgl-charts-hack

Output of a hack day, validating how easy it was to render a line chart quickly with WebGL.
HTML
1
star
39

graytest

Mucking around with gray codes
JavaScript
1
star
40

recruitment

1
star
41

Rotifera

Perl tool to extract and validate metadata from RTF files
Perl
1
star
42

ADN-Getter

The worst code ever. Ignore
JavaScript
1
star
43

nchain

A DSL for compiling chained transformations
JavaScript
1
star
44

Ghost

Just a blogging platform
JavaScript
1
star
45

node-simplecrawler-mongo-cache

Mongo backend for the simplecrawler cache mechanism
1
star
46

FamiliesInMind.com.au

Website for Families In Mind Psychology
HTML
1
star