Indiana Jones - Exploring JS Code

Authors:  Mathieu Rene & Steve Venzerul

The inspiration

A great talk by Alan Shreve 

The concept (read: Hack)

Parse input

Instrument AST

Run instrumented code

Output coverage report

Reparse input into AST, use report to remove nodes that weren't executed

Output modified AST back to disk. 

function someFunction(someValue) {
    if (someValue % 2 === 0) console.log('foo'); 
    else console.log('bar');

    switch(someValue) {
        case 0:
        case 20:
        console.log('nope');
        break;

        case 11:
        try {
            console.log('maybe', 1234 / 0);

            throw new Error(':)');
        } catch(e) {
            void 0;
            console.log('e', e);
        }
        break;

        case 42:
        fs.readFile('./nonexistant', (err, data) => {
            if (err) {
                return 10;
            }

            console.log('Data:', data);
        });
    }
}

someFunction(42);

var __coverage__ = { /* ... */ };
​
__coverage__ = __coverage__['fixtures/test.js'];
__coverage__.s['1']++;
var fs = require('fs');
function someFunction(someValue) {
  __coverage__.f['1']++;__coverage__.s['3']++;
  if (someValue % 2 === 0) {
    __coverage__.b['1'][0]++;__coverage__.s['4']++;console.log('foo');
  } else {
    __coverage__.b['1'][1]++;__coverage__.s['5']++;console.log('bar');
  }
  __coverage__.s['6']++;switch (someValue) {
    case 0:
      __coverage__.b['2'][0]++;case 20:
      __coverage__.b['2'][1]++;__coverage__.s['7']++;console.log('nope');__coverage__.s['8']++;
      break;case 11:
      __coverage__.b['2'][2]++;__coverage__.s['9']++;try {
        __coverage__.s['10']++;console.log('maybe', 1234 / 0);__coverage__.s['11']++;
        throw new Error(':)');
      } catch ( e ) {
        __coverage__.s['12']++;void 0;__coverage__.s['13']++;console.log('e', e);
      } __coverage__.s['14']++;
      break;case 42:
      __coverage__.b['2'][3]++;__coverage__.s['15']++;fs.readFile('./nonexistant', (err, data) => {
        __coverage__.s['16']++;
        if (err) {
          __coverage__.b['3'][0]++;__coverage__.s['17']++;return 10;
        } else {
          __coverage__.b['3'][1]++;
        }
        __coverage__.s['18']++;console.log('Data:', data);
      });
  }
}
__coverage__.s['19']++;someFunction(42);
​
process.on('beforeExit', () => {
  require('fs').writeFileSync('coverage-fixtures_test.js.json', JSON.stringify(__coverage__), 'utf8');
});
{
  "fixtures/test.js": {
    "path": "fixtures/test.js",
    ....
    "s": {
      "1": 1,
      "2": 1,
      "3": 1,
	  ....
    },
    ....
    "statementMap": {
      "1": {
        "start": {
          "line": 1,
          "column": 0
        },
        "end": {
          "line": 1,
          "column": 23
        }
      },
      "2": {
        "start": {
          "line": 3,
          "column": 0
        },
        "end": {
          "line": 37,
          "column": 1
        }
      }
    }
  }
}
var fs = require('fs');
​
function someFunction(someValue) {
    if (someValue % 2 === 0) {
        console.log('foo');
    } else {}
​
​
    switch(someValue) {
        case 0:
        case 20:
            break;
​
        case 11:
            break;
​
        case 42:
        fs.readFile('./nonexistant', (err, data) => {
            if (err) {
                return 10;
            }
        });
    }
}
​
someFunction(42);

Final Output

Dreaming big

var fs = require('fs');
​
function someFunction(someValue) {
    if (someValue % 2 === 0) {
        console.log('foo');
    }
​
    fs.readFile('./nonexistant', (err, data) => {
        if (err) {
            return 10;
        }
    });
}
​
someFunction(42);

If you want to play with the code, head over to: https://github.com/mrene/indiana-jones

Questions?

Made with Slides.com