gotwarlost / istanbul

Yet another JS code coverage tool that computes statement, line, function and branch coverage with module loader hooks to transparently add coverage when running tests. Supports all JS coverage use cases including unit tests, server side functional tests and browser tests. Built for scale.
Other
8.7k stars 786 forks source link

SyntaxError: Unexpected token : when using destructoids with default values #842

Open guymguym opened 6 years ago

guymguym commented 6 years ago

This code:

$ cat a.js 
'use strict';

const object = { field: 1 };
const { field: value = 0 } = object;
console.log(value);

Works on node v6:

$ node -v 
v6.11.2

$ node a.js 
1

Fails on istanbul 0.4.5:

$ istanbul help
...
istanbul version:0.4.5

$ istanbul cover a.js 
No coverage information was collected, exit without writing coverage information a.js:9
__cov_txVrA0tc0SvRcxzSCmLkhg.s['1']++;const object={field:1};__cov_txVrA0tc0SvRcxzSCmLkhg.s['2']++;const {value=0:value=0}=object;__cov_txVrA0tc0SvRcxzSCmLkhg.s['3']++;console.log(value);
                                                                                                                 ^

SyntaxError: Unexpected token :
    at createScript (vm.js:56:10)
    at Object.runInThisContext (vm.js:97:10)
    at Module._compile (module.js:542:28)
    at Object.Module._extensions.(anonymous function) [as .js] (node_modules/istanbul/lib/hook.js:107:24)
    at Module.load (module.js:487:32)
    at tryModuleLoad (module.js:446:12)
    at Function.Module._load (module.js:438:3)
    at Function.Module.runMain (module.js:604:10)
    at runFn (node_modules/istanbul/lib/command/common/run-with-cover.js:122:16)
    at node_modules/istanbul/lib/command/common/run-with-cover.js:251:17

Here is the instrumented code:

$ istanbul instrument a.js 
"use strict";
var __cov_txVrA0tc0SvRcxzSCmLkhg = (Function('return this'))();
if (!__cov_txVrA0tc0SvRcxzSCmLkhg.__coverage__) { __cov_txVrA0tc0SvRcxzSCmLkhg.__coverage__ = {}; }
__cov_txVrA0tc0SvRcxzSCmLkhg = __cov_txVrA0tc0SvRcxzSCmLkhg.__coverage__;
if (!(__cov_txVrA0tc0SvRcxzSCmLkhg['a.js'])) {
   __cov_txVrA0tc0SvRcxzSCmLkhg['a.js'] = {"path":"a.js","s":{"1":0,"2":0,"3":0},"b":{},"f":{},"fnMap":{},"statementMap":{"1":{"start":{"line":3,"column":0},"end":{"line":3,"column":28}},"2":{"start":{"line":4,"column":0},"end":{"line":4,"column":36}},"3":{"start":{"line":5,"column":0},"end":{"line":5,"column":19}}},"branchMap":{}};
}
__cov_txVrA0tc0SvRcxzSCmLkhg = __cov_txVrA0tc0SvRcxzSCmLkhg[a.js'];
__cov_txVrA0tc0SvRcxzSCmLkhg.s['1']++;const object={field:1};__cov_txVrA0tc0SvRcxzSCmLkhg.s['2']++;const {value=0:value=0}=object;__cov_txVrA0tc0SvRcxzSCmLkhg.s['3']++;console.log(value);

This statement was malformed:

const {value=0:value=0}=object;
AngryPidgeon commented 6 years ago

+1, just ran into this issue while updating our code coverage tool.

The syntax where you assign a default value inside destructuring of an object seems to trigger this. Not great, but to work around you'd have to instead of const { field: value = 0 } = object; do const {field : value} = object; value = value || 0;

guymguym commented 6 years ago

@AngryPidgeon You best upgrade to use https://github.com/istanbuljs/nyc instead of this deprecated repo. It has not been active for 2 years now (see comment in readme)

AngryPidgeon commented 6 years ago

@guymguym thanks, I'll look into that. (I did get Istanbul working fine, but better to be update)