From c09dc38f0dc0e39725961570348e1a9b0a3bcc54 Mon Sep 17 00:00:00 2001 From: Corey Farrell Date: Wed, 24 Apr 2019 15:47:55 -0400 Subject: [PATCH] feat: Enable classProperties and classPrivateProperties parsers and coverage. (#379) --- .../src/instrumenter.js | 7 +-- .../src/read-coverage.js | 10 +--- .../istanbul-lib-instrument/src/visitor.js | 6 +++ .../test/specs/class-properties.yaml | 49 +++++++++++++++++++ .../test/util/guards.js | 8 +++ 5 files changed, 67 insertions(+), 13 deletions(-) create mode 100644 packages/istanbul-lib-instrument/test/specs/class-properties.yaml diff --git a/packages/istanbul-lib-instrument/src/instrumenter.js b/packages/istanbul-lib-instrument/src/instrumenter.js index 628e702c..5df1e728 100644 --- a/packages/istanbul-lib-instrument/src/instrumenter.js +++ b/packages/istanbul-lib-instrument/src/instrumenter.js @@ -26,11 +26,8 @@ export function defaultOpts() { plugins: [ 'asyncGenerators', 'bigInt', - /* Verify and add upon release of node.js 12: - * classProperties - * classPrivateProperties - * classPrivateMethods - */ + 'classProperties', + 'classPrivateProperties', 'dynamicImport', 'importMeta', 'objectRestSpread', diff --git a/packages/istanbul-lib-instrument/src/read-coverage.js b/packages/istanbul-lib-instrument/src/read-coverage.js index 64a1b1a7..c0cd554f 100644 --- a/packages/istanbul-lib-instrument/src/read-coverage.js +++ b/packages/istanbul-lib-instrument/src/read-coverage.js @@ -2,6 +2,7 @@ import { parse } from '@babel/parser'; import traverse from '@babel/traverse'; import * as t from '@babel/types'; import { MAGIC_KEY, MAGIC_VALUE } from './constants'; +import { defaultOpts } from './instrumenter'; export default function readInitialCoverage(code) { if (typeof code !== 'string') { @@ -14,14 +15,7 @@ export default function readInitialCoverage(code) { allowReturnOutsideFunction: true, allowSuperOutsideMethod: true, sourceType: 'script', - plugins: [ - 'asyncGenerators', - 'dynamicImport', - 'objectRestSpread', - 'optionalCatchBinding', - 'flow', - 'jsx' - ] + plugins: defaultOpts().plugins }); let covScope; diff --git a/packages/istanbul-lib-instrument/src/visitor.js b/packages/istanbul-lib-instrument/src/visitor.js index 8868d45b..4b8b513d 100644 --- a/packages/istanbul-lib-instrument/src/visitor.js +++ b/packages/istanbul-lib-instrument/src/visitor.js @@ -356,6 +356,10 @@ function coverVariableDeclarator(path) { this.insertStatementCounter(path.get('init')); } +function coverClassPropDeclarator(path) { + this.insertStatementCounter(path.get('value')); +} + function makeBlock(path) { const T = this.types; if (!path.node) { @@ -485,6 +489,8 @@ const codeVisitor = { ExportNamedDeclaration: entries(), // ignore processing only ClassMethod: entries(coverFunction), ClassDeclaration: entries(parenthesizedExpressionProp('superClass')), + ClassProperty: entries(coverClassPropDeclarator), + ClassPrivateProperty: entries(coverClassPropDeclarator), ObjectMethod: entries(coverFunction), ExpressionStatement: entries(coverStatement), BreakStatement: entries(coverStatement), diff --git a/packages/istanbul-lib-instrument/test/specs/class-properties.yaml b/packages/istanbul-lib-instrument/test/specs/class-properties.yaml new file mode 100644 index 00000000..2b109585 --- /dev/null +++ b/packages/istanbul-lib-instrument/test/specs/class-properties.yaml @@ -0,0 +1,49 @@ +--- +name: class property declaration +guard: isClassPropAvailable +code: | + class Foo { + bar = 1; + uninitialized; + } + output = args === 1 ? new Foo().bar : args +tests: + - name: covered + args: 1 + out: 1 + lines: {'2': 1, '5': 1} + statements: {'0': 1, '1': 1} + branches: {'0': [1, 0]} + functions: {} + - name: not covered + args: 2 + out: 2 + lines: {'2': 0, '5': 1} + statements: {'0': 0, '1': 1} + branches: {'0': [0, 1]} + functions: {} +--- +name: class private property declaration +guard: isClassPrivatePropAvailable +code: | + class Foo { + #bar = 1; + get bar() { return this.#bar; } + #uninitialized; + } + output = args === 1 ? new Foo().bar : args +tests: + - name: covered + args: 1 + out: 1 + lines: {'2': 1, '3': 1, '6': 1} + statements: {'0': 1, '1': 1, '2': 1} + branches: {'0': [1, 0]} + functions: {'0': 1} + - name: not covered + args: 2 + out: 2 + lines: {'2': 0, '3': 0, '6': 1} + statements: {'0': 0, '1': 0, '2': 1} + branches: {'0': [0, 1]} + functions: {'0': 0} diff --git a/packages/istanbul-lib-instrument/test/util/guards.js b/packages/istanbul-lib-instrument/test/util/guards.js index cb2026a0..4b891e19 100644 --- a/packages/istanbul-lib-instrument/test/util/guards.js +++ b/packages/istanbul-lib-instrument/test/util/guards.js @@ -18,6 +18,14 @@ export function isYieldAvailable() { return tryThis('function *foo() { yield 1; }', 'yield'); } +export function isClassPropAvailable() { + return tryThis('class Foo { a = 1; }', 'class property'); +} + +export function isClassPrivatePropAvailable() { + return tryThis('class Foo { #a = 1; }', 'class private property'); +} + export function isForOfAvailable() { return tryThis( 'function *foo() { yield 1; }\n' + 'for (var k of foo()) {}',