From c616cb542283f60039a0fc1faf192b5fa3dc4414 Mon Sep 17 00:00:00 2001 From: Brett Zamir Date: Thu, 30 Apr 2020 08:04:12 +0800 Subject: [PATCH 01/13] - Breaking change: Update estraverse dep. - License: Add separate copy of BSD-2-Clause (as per other estools project) - Travis: Change from stable to 10, 12, 14 - Linting: Apply config used in other estools projects (disabling in main file until Babel routine to be added to build) - Docs (README): Use more current syntax in examples - Refactoring: Remove gulp in favor of npm scripts - Babel: Use "json" extension - npm: Add npmrc as per other estools projects - npm: Use `files` in package.json in place of `.npmignore` (as per other estools projects) - npm (package.json): Add recommended bugs and keywords fields and use author/contributors in place of maintainers - npm: Update to Babel 7/preset-env; update other devDeps. (chai, esprima) - npm: Remove unneeded babel-eslint and unused jsdoc - Testing: Use chai/register-expect and babel/register - Testing: Add coverage with nyc --- .babelrc | 3 - .babelrc.json | 3 + .editorconfig | 18 ++++++ .eslintignore | 5 ++ .eslintrc.js | 48 +++++++++++++++ .npmignore | 16 ----- .npmrc | 1 + .travis.yml | 6 +- LICENSE.BSD | 19 ++++++ README.md | 21 ++++--- esrecurse.js | 2 + gulpfile.babel.js | 92 ----------------------------- package.json | 56 +++++++++--------- test/traverse.js | 146 ++++++++++++++++++++++------------------------ 14 files changed, 207 insertions(+), 229 deletions(-) delete mode 100644 .babelrc create mode 100644 .babelrc.json create mode 100644 .editorconfig create mode 100644 .eslintignore create mode 100644 .eslintrc.js delete mode 100644 .npmignore create mode 100644 .npmrc create mode 100644 LICENSE.BSD delete mode 100644 gulpfile.babel.js diff --git a/.babelrc b/.babelrc deleted file mode 100644 index a0765e1..0000000 --- a/.babelrc +++ /dev/null @@ -1,3 +0,0 @@ -{ - "presets": ["es2015"] -} diff --git a/.babelrc.json b/.babelrc.json new file mode 100644 index 0000000..69fe715 --- /dev/null +++ b/.babelrc.json @@ -0,0 +1,3 @@ +{ + "presets": ["@babel/preset-env"] +} diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..d83d722 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,18 @@ +# This file is for unifying the coding style for different editors and IDEs +# editorconfig.org + +root = true + +[*] +end_of_line = lf +charset = utf-8 +insert_final_newline = true +trim_trailing_whitespace = true +indent_style = space +indent_size = 4 + +[*.json] +indent_size = 2 + +[*.yml] +indent_size = 2 diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000..42b0b2a --- /dev/null +++ b/.eslintignore @@ -0,0 +1,5 @@ +node_modules +dist + +!.eslintrc.js +coverage diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 0000000..1507be3 --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,48 @@ +'use strict'; +module.exports = { + env: { + browser: true, + commonjs: true, + es6: true, + node: true + }, + extends: 'eslint:recommended', + globals: { + Atomics: 'readonly', + SharedArrayBuffer: 'readonly' + }, + overrides: [{ + files: '.eslintrc.js', + parserOptions: { + sourceType: 'script' + }, + rules: { + strict: 'error' + } + }, { + files: 'test/**', + globals: { + expect: true + }, + env: { + mocha: true + } + }], + parserOptions: { + sourceType: 'module', + ecmaVersion: 2018 + }, + rules: { + semi: ['error'], + indent: ['error', 4, { SwitchCase: 1 }], + 'prefer-const': ['error'], + 'no-var': ['error'], + 'prefer-destructuring': ['error'], + 'object-shorthand': ['error'], + 'object-curly-spacing': ['error', 'always'], + quotes: ['error', 'single'], + 'quote-props': ['error', 'as-needed'], + 'brace-style': ['error', '1tbs', { allowSingleLine: true }], + 'prefer-template': ['error'] + } +}; diff --git a/.npmignore b/.npmignore deleted file mode 100644 index 2711a8f..0000000 --- a/.npmignore +++ /dev/null @@ -1,16 +0,0 @@ -npm-debug.log -.DS_Store -.vimrc.local -t.js -.travis.yml -.npmignore -/tmp/ -/.git/ -/node_modules/ -/tools/ -/test/ -/build/ -/cover_html/ -/coverage/ -/.coverage_data/ -package-lock.json diff --git a/.npmrc b/.npmrc new file mode 100644 index 0000000..c1ca392 --- /dev/null +++ b/.npmrc @@ -0,0 +1 @@ +package-lock = false diff --git a/.travis.yml b/.travis.yml index c60f507..6a408a8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,6 @@ sudo: false language: node_js node_js: - - "6" - - "8" - - "10" + - 10 + - 12 + - 14 diff --git a/LICENSE.BSD b/LICENSE.BSD new file mode 100644 index 0000000..3e580c3 --- /dev/null +++ b/LICENSE.BSD @@ -0,0 +1,19 @@ +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/README.md b/README.md index ffea6b4..56d5e85 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ The following code will output all variables declared at the root of a file. ```javascript esrecurse.visit(ast, { - XXXStatement: function (node) { + XXXStatement (node) { this.visit(node.left); // do something... this.visit(node.right); @@ -21,8 +21,8 @@ esrecurse.visit(ast, { We can use `Visitor` instance. ```javascript -var visitor = new esrecurse.Visitor({ - XXXStatement: function (node) { +const visitor = new esrecurse.Visitor({ + XXXStatement (node) { this.visit(node.left); // do something... this.visit(node.right); @@ -36,8 +36,7 @@ We can inherit `Visitor` instance easily. ```javascript class Derived extends esrecurse.Visitor { - constructor() - { + constructor() { super(null); } @@ -76,7 +75,7 @@ We can use user-defined node types. ```javascript // This tree contains a user-defined `TestExpression` node. -var tree = { +const tree = { type: 'TestExpression', // This 'argument' is the property containing the other **node**. @@ -91,7 +90,7 @@ var tree = { esrecurse.visit( ast, { - Literal: function (node) { + Literal (node) { // do something... } }, @@ -113,7 +112,7 @@ Please note circular references cause the stack overflow. AST might have circula esrecurse.visit( ast, { - Literal: function (node) { + Literal (node) { // do something... } }, @@ -130,13 +129,13 @@ Please note circular references cause the stack overflow. AST might have circula esrecurse.visit( ast, { - Literal: function (node) { + Literal (node) { // do something... } }, { - fallback: function (node) { - return Object.keys(node).filter(function(key) { + fallback (node) { + return Object.keys(node).filter((key) => { return key !== 'argument' }); } diff --git a/esrecurse.js b/esrecurse.js index 15d57df..9858556 100644 --- a/esrecurse.js +++ b/esrecurse.js @@ -1,3 +1,5 @@ +// Todo: Remove eslint disable directive once have a Babel routine +/* eslint-disable no-var, prefer-template */ /* Copyright (C) 2014 Yusuke Suzuki diff --git a/gulpfile.babel.js b/gulpfile.babel.js deleted file mode 100644 index aa881c9..0000000 --- a/gulpfile.babel.js +++ /dev/null @@ -1,92 +0,0 @@ -// Copyright (C) 2014 Yusuke Suzuki -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -import gulp from 'gulp'; -import mocha from 'gulp-mocha'; -import eslint from 'gulp-eslint'; -import minimist from 'minimist'; -import git from 'gulp-git'; -import bump from 'gulp-bump'; -import filter from 'gulp-filter'; -import tagVersion from 'gulp-tag-version'; -import 'babel-register'; - -const SOURCE = [ - '*.js' -]; - -let ESLINT_OPTION = { - parser: 'babel-eslint', - parserOptions: { - 'sourceType': 'module' - }, - rules: { - 'quotes': 0, - 'eqeqeq': 0, - 'no-use-before-define': 0, - 'no-shadow': 0, - 'no-new': 0, - 'no-underscore-dangle': 0, - 'no-multi-spaces': 0, - 'no-native-reassign': 0, - 'no-loop-func': 0 - }, - env: { - 'node': true - } -}; - -gulp.task('test', function() { - let options = minimist(process.argv.slice(2), { - string: 'test', - default: { - test: 'test/*.js' - } - } - ); - return gulp.src(options.test).pipe(mocha({reporter: 'spec'})); -}); - -gulp.task('lint', () => - gulp.src(SOURCE) - .pipe(eslint(ESLINT_OPTION)) - .pipe(eslint.formatEach('stylish', process.stderr)) - .pipe(eslint.failOnError()) -); - -let inc = importance => - gulp.src(['./package.json']) - .pipe(bump({type: importance})) - .pipe(gulp.dest('./')) - .pipe(git.commit('Bumps package version')) - .pipe(filter('package.json')) - .pipe(tagVersion({ - prefix: '' - })) -; - -gulp.task('travis', [ 'lint', 'test' ]); -gulp.task('default', [ 'travis' ]); - -gulp.task('patch', [ ], () => inc('patch')); -gulp.task('minor', [ ], () => inc('minor')); -gulp.task('major', [ ], () => inc('major')); diff --git a/package.json b/package.json index dec5b1b..53bdbe5 100755 --- a/package.json +++ b/package.json @@ -2,51 +2,49 @@ "name": "esrecurse", "description": "ECMAScript AST recursive visitor", "homepage": "https://github.com/estools/esrecurse", + "bugs": "https://github.com/estools/esrecurse/issues", "main": "esrecurse.js", "version": "4.3.0", "engines": { "node": ">=4.0" }, - "maintainers": [ - { - "name": "Yusuke Suzuki", - "email": "utatane.tea@gmail.com", - "web": "https://github.com/Constellation" - } + "files": [ + "esrecurse.js", + "LICENSE.BSD", + "README.md" + ], + "author": { + "name": "Yusuke Suzuki", + "email": "utatane.tea@gmail.com", + "web": "https://github.com/Constellation" + }, + "contributors": [ + "Brett Zamir" ], "repository": { "type": "git", "url": "https://github.com/estools/esrecurse.git" }, + "keywords": [ + "recursion" + ], "dependencies": { "estraverse": "^5.2.0" }, "devDependencies": { - "babel-cli": "^6.24.1", - "babel-eslint": "^7.2.3", - "babel-preset-es2015": "^6.24.1", - "babel-register": "^6.24.1", - "chai": "^4.0.2", - "esprima": "^4.0.0", - "gulp": "^3.9.0", - "gulp-bump": "^2.7.0", - "gulp-eslint": "^4.0.0", - "gulp-filter": "^5.0.0", - "gulp-git": "^2.4.1", - "gulp-mocha": "^4.3.1", - "gulp-tag-version": "^1.2.1", - "jsdoc": "^3.3.0-alpha10", - "minimist": "^1.1.0" + "@babel/core": "^7.9.6", + "@babel/preset-env": "^7.9.6", + "@babel/register": "^7.9.0", + "chai": "^4.2.0", + "eslint": "^6.8.0", + "esprima": "^4.0.1", + "mocha": "^7.1.2", + "nyc": "^15.0.1" }, "license": "BSD-2-Clause", "scripts": { - "test": "gulp travis", - "unit-test": "gulp test", - "lint": "gulp lint" - }, - "babel": { - "presets": [ - "es2015" - ] + "test": "npm run lint && npm run unit-test", + "unit-test": "nyc mocha --require chai/register-expect --require @babel/register test", + "lint": "eslint ." } } diff --git a/test/traverse.js b/test/traverse.js index 285edaa..02a9697 100644 --- a/test/traverse.js +++ b/test/traverse.js @@ -1,31 +1,32 @@ -// Copyright (C) 2013 Yusuke Suzuki -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -var expect = require('chai').expect; -var esrecurse = require('..'); - -describe('object expression', () => +/* +Copyright (C) 2013 Yusuke Suzuki + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +import esrecurse from '../'; + +describe('object expression', () => { it('properties', function() { - let tree = { + const tree = { type: 'ObjectExpression', properties: [{ type: 'Property', @@ -40,7 +41,7 @@ describe('object expression', () => }] }; - let log = []; + const log = []; esrecurse.visit(tree, { Identifier(node) { return log.push(node.name); @@ -48,10 +49,9 @@ describe('object expression', () => } ); - - return expect(log).to.deep.equal(['a', 'b']); - }) -); + expect(log).to.deep.equal(['a', 'b']); + }); +}); describe('chain expression', () => it('expressions', function() { @@ -85,9 +85,9 @@ describe('chain expression', () => }) ); -describe('non listed keys throw an error', () => +describe('non listed keys throw an error', () => { it('traverse', function() { - let tree = { + const tree = { type: 'TestStatement', id: { type: 'Identifier', @@ -111,8 +111,8 @@ describe('non listed keys throw an error', () => } }; - return expect(function() { - let log = []; + expect(function() { + const log = []; return esrecurse.visit( tree, { @@ -122,14 +122,13 @@ describe('non listed keys throw an error', () => } ); }).to.throw('Unknown node type TestStatement.'); - }) -); - + }); +}); -describe('no listed keys fallback if "fallback" option was given', () => +describe('no listed keys fallback if "fallback" option was given', () => { it('traverse', function() { - let tree = { + const tree = { type: 'TestStatement', id: { type: 'Identifier', @@ -153,7 +152,7 @@ describe('no listed keys fallback if "fallback" option was given', () => } }; - let log = []; + const log = []; esrecurse.visit( tree, { @@ -166,13 +165,13 @@ describe('no listed keys fallback if "fallback" option was given', () => } ); - return expect(log).to.deep.equal([ 20 ]); -}) -); + expect(log).to.deep.equal([ 20 ]); + }); +}); -describe('no listed keys fallback if "fallback" option is a function', () => +describe('no listed keys fallback if "fallback" option is a function', () => { it('traverse', function() { - let tree = { + const tree = { type: 'TestStatement', id: { type: 'Identifier', @@ -211,14 +210,14 @@ describe('no listed keys fallback if "fallback" option is a function', () => } ); - return expect(result).to.equal(2); - }) -); + expect(result).to.equal(2); + }); +}); describe('inherit Visitor', function() { it('log names', function() { - let tree = { + const tree = { type: 'TestStatement', id: { type: 'Identifier', @@ -244,7 +243,7 @@ describe('inherit Visitor', function() { class Derived extends esrecurse.Visitor { constructor() { - super(null, {fallback: 'iteration'}); + super(null, { fallback: 'iteration' }); this.log = []; } @@ -253,14 +252,14 @@ describe('inherit Visitor', function() { } } - let visitor = new Derived; + const visitor = new Derived(); visitor.visit(tree); - return expect(visitor.log).to.deep.equal([ 'decl', 'a', 'rest' ]); -}); + expect(visitor.log).to.deep.equal([ 'decl', 'a', 'rest' ]); + }); - return it('customize behavior', function() { - let tree = { + it('customize behavior', function() { + const tree = { type: 'TestStatement', id: { type: 'Identifier', @@ -289,27 +288,27 @@ describe('inherit Visitor', function() { class Derived extends esrecurse.Visitor { constructor() { - super(null, {fallback: 'iteration'}); + super(null, { fallback: 'iteration' }); this.log = []; } - BlockStatement(node) {} + BlockStatement(/* node */) {} Identifier(node) { return this.log.push(node.name); } } - let visitor = new Derived; + const visitor = new Derived(); visitor.visit(tree); - return expect(visitor.log).to.deep.equal([ 'decl', 'a', 'rest' ]); -}); + expect(visitor.log).to.deep.equal([ 'decl', 'a', 'rest' ]); + }); }); describe('bidirectional relationship at non visitor keys.', function() { it('ExpressionStatement <-> Identifier', function() { - let tree = { + const tree = { type: 'ExpressionStatement', expression: { type: 'Identifier', @@ -318,20 +317,18 @@ describe('bidirectional relationship at non visitor keys.', function() { }; tree.expression.parent = tree; - let log = []; + const log = []; esrecurse.visit(tree, { Identifier(node) { return log.push(node.name); } - } - ); + }); + expect(log).to.deep.equal(['foo']); + }); - return expect(log).to.deep.equal(['foo']); -}); - - return it('ExpressionStatement <-> UnknownNode with the childVisitorKeys option', function() { - let tree = { + it('ExpressionStatement <-> UnknownNode with the childVisitorKeys option', function() { + const tree = { type: 'ExpressionStatement', expression: { type: 'UnknownNode', @@ -344,7 +341,7 @@ describe('bidirectional relationship at non visitor keys.', function() { tree.expression.parent = tree; tree.expression.argument.parent = tree.expression; - let log = []; + const log = []; esrecurse.visit( tree, { @@ -359,7 +356,6 @@ describe('bidirectional relationship at non visitor keys.', function() { } ); - - return expect(log).to.deep.equal(['foo']); -}); + expect(log).to.deep.equal(['foo']); + }); }); From 91e8e395d083c90b6002f9ecd153e32b57813ed6 Mon Sep 17 00:00:00 2001 From: Brett Zamir Date: Thu, 30 Apr 2020 08:38:14 +0800 Subject: [PATCH 02/13] - Testing: Improve coverage (handle `null`) --- package.json | 13 +++++++++++++ test/traverse.js | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/package.json b/package.json index 53bdbe5..0bee96c 100755 --- a/package.json +++ b/package.json @@ -42,6 +42,19 @@ "nyc": "^15.0.1" }, "license": "BSD-2-Clause", + "nyc": { + "branches": 100, + "lines": 100, + "functions": 100, + "statements": 100, + "reporter": [ + "html", + "text" + ], + "exclude": [ + "test" + ] + }, "scripts": { "test": "npm run lint && npm run unit-test", "unit-test": "nyc mocha --require chai/register-expect --require @babel/register test", diff --git a/test/traverse.js b/test/traverse.js index 02a9697..a3793d1 100644 --- a/test/traverse.js +++ b/test/traverse.js @@ -258,6 +258,43 @@ describe('inherit Visitor', function() { expect(visitor.log).to.deep.equal([ 'decl', 'a', 'rest' ]); }); + it('`visit` handles `null`', function () { + class Derived extends esrecurse.Visitor { + constructor() { + super(null, { fallback: 'iteration' }); + this.log = []; + } + + Identifier(node) { + return this.log.push(node.name); + } + } + + const visitor = new Derived(); + visitor.visit(null); + + expect(visitor.log).to.be.empty; + }); + + // `null` should not get to `visitChildren` through `visit` + it('`visitChildren` handles `null`', function () { + class Derived extends esrecurse.Visitor { + constructor() { + super(null, { fallback: 'iteration' }); + this.log = []; + } + + Identifier(node) { + return this.log.push(node.name); + } + } + + const visitor = new Derived(); + visitor.visitChildren(null); + + expect(visitor.log).to.be.empty; + }); + it('customize behavior', function() { const tree = { type: 'TestStatement', From 88503759e31669cb23f5d75c7cd0dd81e251610e Mon Sep 17 00:00:00 2001 From: Brett Zamir Date: Thu, 30 Apr 2020 08:38:44 +0800 Subject: [PATCH 03/13] - Testing: Improve coverage (silently recover with missing visitor keys) --- test/traverse.js | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/test/traverse.js b/test/traverse.js index a3793d1..e187255 100644 --- a/test/traverse.js +++ b/test/traverse.js @@ -51,6 +51,29 @@ describe('object expression', () => { expect(log).to.deep.equal(['a', 'b']); }); + + it('silently recover when AST missing visitor keys', function() { + const tree = { + type: 'ObjectExpression', + properties: [{ + type: 'Property', + key: { + type: 'Identifier', + name: 'a' + } + }] + }; + + const log = []; + esrecurse.visit(tree, { + Identifier(node) { + return log.push(node.name); + } + } + ); + + expect(log).to.deep.equal(['a']); + }); }); describe('chain expression', () => From ff81c28d730700b75ec849f7b9f16951b463b1c8 Mon Sep 17 00:00:00 2001 From: Brett Zamir Date: Thu, 30 Apr 2020 08:44:05 +0800 Subject: [PATCH 04/13] - Temporarily set nyc thresholds below current coverage to get passing baseline --- package.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 0bee96c..ad38930 100755 --- a/package.json +++ b/package.json @@ -43,10 +43,10 @@ }, "license": "BSD-2-Clause", "nyc": { - "branches": 100, - "lines": 100, - "functions": 100, - "statements": 100, + "branches": 79, + "lines": 95, + "functions": 85, + "statements": 95, "reporter": [ "html", "text" From 57d8b9cf47b2a9275b23516d3d395255544b32a2 Mon Sep 17 00:00:00 2001 From: Brett Zamir Date: Fri, 24 Jul 2020 19:43:53 +0800 Subject: [PATCH 05/13] - npm: Update devDeps. --- package.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index ad38930..f043706 100755 --- a/package.json +++ b/package.json @@ -32,14 +32,14 @@ "estraverse": "^5.2.0" }, "devDependencies": { - "@babel/core": "^7.9.6", - "@babel/preset-env": "^7.9.6", - "@babel/register": "^7.9.0", + "@babel/core": "^7.10.5", + "@babel/preset-env": "^7.10.4", + "@babel/register": "^7.10.5", "chai": "^4.2.0", - "eslint": "^6.8.0", + "eslint": "^7.5.0", "esprima": "^4.0.1", - "mocha": "^7.1.2", - "nyc": "^15.0.1" + "mocha": "^8.0.1", + "nyc": "^15.1.0" }, "license": "BSD-2-Clause", "nyc": { From 68ae1a40eaf4dbc54980218c171ad5c5e52c2530 Mon Sep 17 00:00:00 2001 From: Brett Zamir Date: Fri, 24 Jul 2020 19:51:57 +0800 Subject: [PATCH 06/13] - Testing: Add ignore comment for unreachable code; bump coverage thresholds --- esrecurse.js | 1 + package.json | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/esrecurse.js b/esrecurse.js index 9858556..6e36262 100644 --- a/esrecurse.js +++ b/esrecurse.js @@ -29,6 +29,7 @@ var estraverse = require('estraverse'); function isNode(node) { + // istanbul ignore if -- Is currently always truthy if (node == null) { return false; } diff --git a/package.json b/package.json index f043706..c97fe9e 100755 --- a/package.json +++ b/package.json @@ -43,10 +43,10 @@ }, "license": "BSD-2-Clause", "nyc": { - "branches": 79, - "lines": 95, - "functions": 85, - "statements": 95, + "branches": 80.95, + "lines": 95.56, + "functions": 85.71, + "statements": 95.56, "reporter": [ "html", "text" From 8ddf53495ab79394405f75300aafb57b7330531e Mon Sep 17 00:00:00 2001 From: Brett Zamir Date: Fri, 24 Jul 2020 22:26:59 +0800 Subject: [PATCH 07/13] - Testing: Inogre non-Node children --- test/traverse.js | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/test/traverse.js b/test/traverse.js index e187255..d68c192 100644 --- a/test/traverse.js +++ b/test/traverse.js @@ -318,6 +318,27 @@ describe('inherit Visitor', function() { expect(visitor.log).to.be.empty; }); + it('`visitChildren` ignores non-Node children', function () { + class Derived extends esrecurse.Visitor { + constructor() { + super(null, { fallback: 'iteration' }); + this.log = []; + } + + Identifier(node) { + return this.log.push(node.name); + } + } + + const visitor = new Derived(); + visitor.visitChildren({ + type: 'FunctionDeclaration', + params: [null, {}] + }); + + expect(visitor.log).to.be.empty; + }); + it('customize behavior', function() { const tree = { type: 'TestStatement', From 26f20ea154a35946b64f3847a5309f8eccf4c0b1 Mon Sep 17 00:00:00 2001 From: Brett Zamir Date: Fri, 24 Jul 2020 22:35:06 +0800 Subject: [PATCH 08/13] - Testing: `visitChildren` defaulting to Property type --- test/traverse.js | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/test/traverse.js b/test/traverse.js index d68c192..820a41d 100644 --- a/test/traverse.js +++ b/test/traverse.js @@ -339,6 +339,36 @@ describe('inherit Visitor', function() { expect(visitor.log).to.be.empty; }); + it('`visitChildren` defaults to Property type', function () { + class Derived extends esrecurse.Visitor { + constructor() { + super(null, { fallback: 'iteration' }); + this.log = []; + } + + key(node) { + return this.log.push(node.name); + } + value(node) { + return this.log.push(node.name); + } + } + + const visitor = new Derived(); + visitor.visitChildren({ + key: { + name: 'myKey', + type: 'key' + }, + value: { + name: 'myValue', + type: 'value' + } + }); + + expect(visitor.log).to.deep.equal(['myKey', 'myValue']); + }); + it('customize behavior', function() { const tree = { type: 'TestStatement', From 9fd349236a9670e1201d8c5122f8d75ae4fa8434 Mon Sep 17 00:00:00 2001 From: Brett Zamir Date: Fri, 24 Jul 2020 22:36:54 +0800 Subject: [PATCH 09/13] - Testing: `visit` default to Property type --- test/traverse.js | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/test/traverse.js b/test/traverse.js index 820a41d..e42e7da 100644 --- a/test/traverse.js +++ b/test/traverse.js @@ -299,6 +299,36 @@ describe('inherit Visitor', function() { expect(visitor.log).to.be.empty; }); + it('`visit` defaults to Property type', function () { + class Derived extends esrecurse.Visitor { + constructor() { + super(null, { fallback: 'iteration' }); + this.log = []; + } + + key(node) { + return this.log.push(node.name); + } + value(node) { + return this.log.push(node.name); + } + } + + const visitor = new Derived(); + visitor.visit({ + key: { + name: 'myKey', + type: 'key' + }, + value: { + name: 'myValue', + type: 'value' + } + }); + + expect(visitor.log).to.deep.equal(['myKey', 'myValue']); + }); + // `null` should not get to `visitChildren` through `visit` it('`visitChildren` handles `null`', function () { class Derived extends esrecurse.Visitor { From c70b4fa68a8d728002dfc425c64140073e84aef5 Mon Sep 17 00:00:00 2001 From: Brett Zamir Date: Fri, 24 Jul 2020 22:50:35 +0800 Subject: [PATCH 10/13] - Testing: non-Node property keys --- test/traverse.js | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/test/traverse.js b/test/traverse.js index e42e7da..4b4dac8 100644 --- a/test/traverse.js +++ b/test/traverse.js @@ -355,6 +355,10 @@ describe('inherit Visitor', function() { this.log = []; } + FunctionDeclaration(node) { + return this.log.push(node.name); + } + Identifier(node) { return this.log.push(node.name); } @@ -399,6 +403,35 @@ describe('inherit Visitor', function() { expect(visitor.log).to.deep.equal(['myKey', 'myValue']); }); + it('`visitChildren` visits non-Node `ObjectExpression`/`ObjectPattern` property keys', function () { + class Derived extends esrecurse.Visitor { + constructor() { + super(null, { fallback: 'iteration' }); + this.log = []; + } + + Property(node) { + return this.log.push(node.name); + } + } + + const visitor = new Derived(); + visitor.visitChildren({ + type: 'ObjectExpression', + properties: [{ + name: 'myExpression' + }] + }); + visitor.visitChildren({ + type: 'ObjectPattern', + properties: [{ + name: 'myPattern' + }] + }); + + expect(visitor.log).to.deep.equal(['myExpression', 'myPattern']); + }); + it('customize behavior', function() { const tree = { type: 'TestStatement', From 4f8409b166d83c13319d40be1bfdd219ca6acc03 Mon Sep 17 00:00:00 2001 From: Brett Zamir Date: Fri, 24 Jul 2020 22:50:46 +0800 Subject: [PATCH 11/13] - Testing: Bump thresholds to 100 --- package.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index c97fe9e..81c8412 100755 --- a/package.json +++ b/package.json @@ -43,10 +43,10 @@ }, "license": "BSD-2-Clause", "nyc": { - "branches": 80.95, - "lines": 95.56, - "functions": 85.71, - "statements": 95.56, + "branches": 100, + "lines": 100, + "functions": 100, + "statements": 100, "reporter": [ "html", "text" From e07935354f330f86e217ad5666568dcf59c14820 Mon Sep 17 00:00:00 2001 From: Brett Zamir Date: Sun, 13 Mar 2022 22:53:21 +0800 Subject: [PATCH 12/13] chore: linting of recent additions --- test/traverse.js | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/test/traverse.js b/test/traverse.js index 4b4dac8..24f7d64 100644 --- a/test/traverse.js +++ b/test/traverse.js @@ -78,7 +78,7 @@ describe('object expression', () => { describe('chain expression', () => it('expressions', function() { - let tree = { + const tree = { type: 'ChainExpression', expression: [{ type: 'MemberExpression', @@ -95,14 +95,12 @@ describe('chain expression', () => }] }; - let log = []; + const log = []; esrecurse.visit(tree, { - Identifier(node) { - return log.push(node.name); - } + Identifier(node) { + return log.push(node.name); } - ); - + }); return expect(log).to.deep.equal(['a', 'b']); }) From 079383c3fcd9a58ac549c7d89ae6d7137a4bd1f5 Mon Sep 17 00:00:00 2001 From: Brett Zamir Date: Sun, 13 Mar 2022 23:06:22 +0800 Subject: [PATCH 13/13] chore: update estraverse and devDeps. --- package.json | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/package.json b/package.json index 81c8412..a0e7717 100755 --- a/package.json +++ b/package.json @@ -29,16 +29,16 @@ "recursion" ], "dependencies": { - "estraverse": "^5.2.0" + "estraverse": "^5.3.0" }, "devDependencies": { - "@babel/core": "^7.10.5", - "@babel/preset-env": "^7.10.4", - "@babel/register": "^7.10.5", - "chai": "^4.2.0", - "eslint": "^7.5.0", + "@babel/core": "^7.17.5", + "@babel/preset-env": "^7.16.11", + "@babel/register": "^7.17.0", + "chai": "^4.3.6", + "eslint": "^8.11.0", "esprima": "^4.0.1", - "mocha": "^8.0.1", + "mocha": "^9.2.2", "nyc": "^15.1.0" }, "license": "BSD-2-Clause", @@ -57,7 +57,7 @@ }, "scripts": { "test": "npm run lint && npm run unit-test", - "unit-test": "nyc mocha --require chai/register-expect --require @babel/register test", + "unit-test": "nyc mocha --require chai/register-expect.js --require @babel/register test", "lint": "eslint ." } }