From b293927066673840e6df2865575b1d36178f5d97 Mon Sep 17 00:00:00 2001 From: simonihmig Date: Fri, 29 May 2020 11:59:12 +0200 Subject: [PATCH 1/7] Add template test support --- package.json | 1 + src/test-support.js | 73 ++------------------------------- src/test-support/jscodeshift.js | 61 +++++++++++++++++++++++++++ src/test-support/template.js | 65 +++++++++++++++++++++++++++++ src/test-support/utils.js | 16 ++++++++ 5 files changed, 147 insertions(+), 69 deletions(-) create mode 100644 src/test-support/jscodeshift.js create mode 100644 src/test-support/template.js create mode 100644 src/test-support/utils.js diff --git a/package.json b/package.json index 99b57e4..ab7cf55 100644 --- a/package.json +++ b/package.json @@ -38,6 +38,7 @@ "@babel/parser": "^7.6.0", "chalk": "^2.4.2", "common-tags": "^1.8.0", + "ember-template-recast": "^4.1.4", "execa": "^2.0.4", "fs-extra": "^8.1.0", "globby": "^10.0.1", diff --git a/src/test-support.js b/src/test-support.js index db252a2..e11fdd0 100644 --- a/src/test-support.js +++ b/src/test-support.js @@ -1,79 +1,14 @@ 'use strict'; -/* global it, describe, beforeEach, afterEach */ - -const { runInlineTest } = require('jscodeshift/dist/testUtils'); -const fs = require('fs-extra'); -const path = require('path'); -const globby = require('globby'); - -function transformDetails(options) { - let root = process.cwd() + `/transforms/${options.name}/`; - - return { - name: options.name, - root, - transformPath: root + 'index', - fixtureDir: root + '__testfixtures__/', - }; -} - -function jscodeshiftTest(options) { - let details = transformDetails(options); - - let transform = require(details.transformPath); - - describe(details.name, function() { - globby - .sync('**/*.input.*', { - cwd: details.fixtureDir, - absolute: true, - }) - .map(entry => entry.slice(entry.indexOf('__testfixtures__') + '__testfixtures__'.length + 1)) - .forEach(filename => { - let extension = path.extname(filename); - let testName = filename.replace(`.input${extension}`, ''); - let testInputPath = path.join(details.fixtureDir, `${testName}${extension}`); - let inputPath = path.join(details.fixtureDir, `${testName}.input${extension}`); - let outputPath = path.join(details.fixtureDir, `${testName}.output${extension}`); - let optionsPath = path.join(details.fixtureDir, `${testName}.options.json`); - let options = fs.pathExistsSync(optionsPath) ? fs.readFileSync(optionsPath) : '{}'; - - describe(testName, function() { - beforeEach(function() { - process.env.CODEMOD_CLI_ARGS = options; - }); - - afterEach(function() { - process.env.CODEMOD_CLI_ARGS = ''; - }); - - it('transforms correctly', function() { - runInlineTest( - transform, - {}, - { path: testInputPath, source: fs.readFileSync(inputPath, 'utf8') }, - fs.readFileSync(outputPath, 'utf8') - ); - }); - - it('is idempotent', function() { - runInlineTest( - transform, - {}, - { path: testInputPath, source: fs.readFileSync(outputPath, 'utf8') }, - fs.readFileSync(outputPath, 'utf8') - ); - }); - }); - }); - }); -} +const jscodeshiftTest = require('./test-support/jscodeshift'); +const templateTest = require('./test-support/template'); function runTransformTest(options) { switch (options.type) { case 'jscodeshift': return jscodeshiftTest(options); + case 'template': + return templateTest(options); } } diff --git a/src/test-support/jscodeshift.js b/src/test-support/jscodeshift.js new file mode 100644 index 0000000..5926573 --- /dev/null +++ b/src/test-support/jscodeshift.js @@ -0,0 +1,61 @@ +'use strict'; + +/* global it, describe, beforeEach, afterEach */ + +const { runInlineTest } = require('jscodeshift/dist/testUtils'); +const fs = require('fs-extra'); +const path = require('path'); +const globby = require('globby'); +const { transformDetails } = require('./utils'); + +module.exports = function jscodeshiftTest(options) { + let details = transformDetails(options); + + let transform = require(details.transformPath); + + describe(details.name, function() { + globby + .sync('**/*.input.*', { + cwd: details.fixtureDir, + absolute: true, + }) + .map(entry => entry.slice(entry.indexOf('__testfixtures__') + '__testfixtures__'.length + 1)) + .forEach(filename => { + let extension = path.extname(filename); + let testName = filename.replace(`.input${extension}`, ''); + let testInputPath = path.join(details.fixtureDir, `${testName}${extension}`); + let inputPath = path.join(details.fixtureDir, `${testName}.input${extension}`); + let outputPath = path.join(details.fixtureDir, `${testName}.output${extension}`); + let optionsPath = path.join(details.fixtureDir, `${testName}.options.json`); + let options = fs.pathExistsSync(optionsPath) ? fs.readFileSync(optionsPath) : '{}'; + + describe(testName, function() { + beforeEach(function() { + process.env.CODEMOD_CLI_ARGS = options; + }); + + afterEach(function() { + process.env.CODEMOD_CLI_ARGS = ''; + }); + + it('transforms correctly', function() { + runInlineTest( + transform, + {}, + { path: testInputPath, source: fs.readFileSync(inputPath, 'utf8') }, + fs.readFileSync(outputPath, 'utf8') + ); + }); + + it('is idempotent', function() { + runInlineTest( + transform, + {}, + { path: testInputPath, source: fs.readFileSync(outputPath, 'utf8') }, + fs.readFileSync(outputPath, 'utf8') + ); + }); + }); + }); + }); +}; diff --git a/src/test-support/template.js b/src/test-support/template.js new file mode 100644 index 0000000..68b86e7 --- /dev/null +++ b/src/test-support/template.js @@ -0,0 +1,65 @@ +'use strict'; + +/* global expect, it, describe, beforeEach, afterEach */ + +const fs = require('fs-extra'); +const path = require('path'); +const globby = require('globby'); +const { transformDetails } = require('./utils'); + +function runTemplateTest(transformFn, input, expectedOutput) { + const { transform } = require('ember-template-recast'); + + let { code } = transform(input, transformFn); + + expect((code || '').trim()).toEqual(expectedOutput.trim()); +} + +module.exports = function templateTest(options) { + let details = transformDetails(options); + + let transform = require(details.transformPath); + + describe(details.name, function() { + globby + .sync('**/*.input.*', { + cwd: details.fixtureDir, + absolute: true, + }) + .map(entry => entry.slice(entry.indexOf('__testfixtures__') + '__testfixtures__'.length + 1)) + .forEach(filename => { + let extension = path.extname(filename); + let testName = filename.replace(`.input${extension}`, ''); + let inputPath = path.join(details.fixtureDir, `${testName}.input${extension}`); + let outputPath = path.join(details.fixtureDir, `${testName}.output${extension}`); + let optionsPath = path.join(details.fixtureDir, `${testName}.options.json`); + let options = fs.pathExistsSync(optionsPath) ? fs.readFileSync(optionsPath) : '{}'; + + describe(testName, function() { + beforeEach(function() { + process.env.CODEMOD_CLI_ARGS = options; + }); + + afterEach(function() { + process.env.CODEMOD_CLI_ARGS = ''; + }); + + it('transforms correctly', function() { + runTemplateTest( + transform, + fs.readFileSync(inputPath, 'utf8'), + fs.readFileSync(outputPath, 'utf8') + ); + }); + + it('is idempotent', function() { + runTemplateTest( + transform, + fs.readFileSync(outputPath, 'utf8'), + fs.readFileSync(outputPath, 'utf8') + ); + }); + }); + }); + }); +}; diff --git a/src/test-support/utils.js b/src/test-support/utils.js new file mode 100644 index 0000000..a4b8876 --- /dev/null +++ b/src/test-support/utils.js @@ -0,0 +1,16 @@ +'use strict'; + +function transformDetails(options) { + let root = process.cwd() + `/transforms/${options.name}/`; + + return { + name: options.name, + root, + transformPath: root + 'index', + fixtureDir: root + '__testfixtures__/', + }; +} + +module.exports = { + transformDetails, +}; From c809c5d17bf701da0f54ab7631066076c04a657c Mon Sep 17 00:00:00 2001 From: simonihmig Date: Fri, 29 May 2020 13:35:33 +0200 Subject: [PATCH 2/7] Add bin-support for templates, updated test-support for full plugin rather than visitor fn --- src/bin-support.js | 54 ++++++++++++++++++++++++++++++++++-- src/test-support/template.js | 42 +++++++++++++++------------- 2 files changed, 74 insertions(+), 22 deletions(-) diff --git a/src/bin-support.js b/src/bin-support.js index e0c8be3..97cec19 100644 --- a/src/bin-support.js +++ b/src/bin-support.js @@ -1,8 +1,9 @@ 'use strict'; -const DEFAULT_EXTENSIONS = 'js,ts'; +const DEFAULT_JS_EXTENSIONS = 'js,ts'; +const DEFAULT_TEMPLATE_EXTENSIONS = 'hbs'; -async function runTransform(binRoot, transformName, args, extensions = DEFAULT_EXTENSIONS) { +async function runJsTransform(binRoot, transformName, args, extensions = DEFAULT_JS_EXTENSIONS) { const globby = require('globby'); const execa = require('execa'); const chalk = require('chalk'); @@ -37,6 +38,55 @@ async function runTransform(binRoot, transformName, args, extensions = DEFAULT_E } } +async function runTemplateTransform( + binRoot, + transformName, + args, + extensions = DEFAULT_TEMPLATE_EXTENSIONS +) { + const globby = require('globby'); + const execa = require('execa'); + const chalk = require('chalk'); + const path = require('path'); + const { parseTransformArgs } = require('./options-support'); + + let { paths, options } = parseTransformArgs(args); + + try { + let foundPaths = await globby(paths, { + expandDirectories: { extensions: extensions.split(',') }, + }); + let transformPath = path.join(binRoot, '..', 'transforms', transformName, 'index.js'); + + let templateRecastPkg = require('ember-template-recast/package'); + let templateRecastPath = path.dirname(require.resolve('ember-template-recast/package')); + let binPath = path.join(templateRecastPath, templateRecastPkg.bin); + + let binOptions = ['-t', transformPath, ...foundPaths]; + + return execa(binPath, binOptions, { + stdio: 'inherit', + env: { + CODEMOD_CLI_ARGS: JSON.stringify(options), + }, + }); + } catch (error) { + console.error(chalk.red(error.stack)); // eslint-disable-line no-console + process.exitCode = 1; + + throw error; + } +} + +async function runTransform(binRoot, transformName, args, extensions, type = 'jscodeshift') { + switch (type) { + case 'jscodeshift': + return runJsTransform(binRoot, transformName, args, extensions); + case 'template': + return runTemplateTransform(binRoot, transformName, args, extensions); + } +} + module.exports = { runTransform, }; diff --git a/src/test-support/template.js b/src/test-support/template.js index 68b86e7..2a79f25 100644 --- a/src/test-support/template.js +++ b/src/test-support/template.js @@ -1,16 +1,27 @@ 'use strict'; -/* global expect, it, describe, beforeEach, afterEach */ +/* global expect, it, describe */ const fs = require('fs-extra'); const path = require('path'); const globby = require('globby'); const { transformDetails } = require('./utils'); +const { transform, parse } = require('ember-template-recast'); -function runTemplateTest(transformFn, input, expectedOutput) { - const { transform } = require('ember-template-recast'); - - let { code } = transform(input, transformFn); +function runTemplateTest(plugin, { path, source }, expectedOutput) { + const code = plugin( + { + path, + source, + }, + { + parse, + visit(ast, callback) { + const results = transform(ast, callback); + return results && results.code; + }, + } + ); expect((code || '').trim()).toEqual(expectedOutput.trim()); } @@ -18,7 +29,7 @@ function runTemplateTest(transformFn, input, expectedOutput) { module.exports = function templateTest(options) { let details = transformDetails(options); - let transform = require(details.transformPath); + let plugin = require(details.transformPath); describe(details.name, function() { globby @@ -30,32 +41,23 @@ module.exports = function templateTest(options) { .forEach(filename => { let extension = path.extname(filename); let testName = filename.replace(`.input${extension}`, ''); + let testInputPath = path.join(details.fixtureDir, `${testName}${extension}`); let inputPath = path.join(details.fixtureDir, `${testName}.input${extension}`); let outputPath = path.join(details.fixtureDir, `${testName}.output${extension}`); - let optionsPath = path.join(details.fixtureDir, `${testName}.options.json`); - let options = fs.pathExistsSync(optionsPath) ? fs.readFileSync(optionsPath) : '{}'; describe(testName, function() { - beforeEach(function() { - process.env.CODEMOD_CLI_ARGS = options; - }); - - afterEach(function() { - process.env.CODEMOD_CLI_ARGS = ''; - }); - it('transforms correctly', function() { runTemplateTest( - transform, - fs.readFileSync(inputPath, 'utf8'), + plugin, + { path: testInputPath, source: fs.readFileSync(inputPath, 'utf8') }, fs.readFileSync(outputPath, 'utf8') ); }); it('is idempotent', function() { runTemplateTest( - transform, - fs.readFileSync(outputPath, 'utf8'), + plugin, + { path: testInputPath, source: fs.readFileSync(inputPath, 'utf8') }, fs.readFileSync(outputPath, 'utf8') ); }); From 7995cbf0cf45abb90aaaf4bddc9a8dc31fab4cda Mon Sep 17 00:00:00 2001 From: simonihmig Date: Fri, 29 May 2020 15:54:01 +0200 Subject: [PATCH 3/7] Add generator for template transforms and tests --- commands/local/generate/codemod.js | 104 +++++++++++++++++++++-- commands/local/generate/fixture.js | 10 ++- tests/cli-test.js | 130 ++++++++++++++++++++++++++++- 3 files changed, 235 insertions(+), 9 deletions(-) diff --git a/commands/local/generate/codemod.js b/commands/local/generate/codemod.js index d3052fb..e346ad4 100644 --- a/commands/local/generate/codemod.js +++ b/commands/local/generate/codemod.js @@ -2,12 +2,19 @@ module.exports.command = 'codemod '; module.exports.desc = 'Generate a new codemod file'; module.exports.builder = function builder(yargs) { - yargs.positional('codemod-name', { - describe: 'the name of the codemod to generate', - }); + yargs + .positional('codemod-name', { + describe: 'the name of the codemod to generate', + }) + .option('type', { + alias: 't', + describe: 'choose the transform type', + choices: ['js', 'hbs'], + default: 'js', + }); }; -module.exports.handler = function handler(options) { +function jsHandler(options) { const fs = require('fs-extra'); const { stripIndent } = require('common-tags'); const importCwd = require('import-cwd'); @@ -86,5 +93,92 @@ module.exports.handler = function handler(options) { 'utf8' ); - generateFixture({ codemodName, fixtureName: 'basic' }); + generateFixture({ codemodName, fixtureName: 'basic', type: options.type }); +} + +function hbsHandler(options) { + const fs = require('fs-extra'); + const { stripIndent } = require('common-tags'); + const importCwd = require('import-cwd'); + const generateFixture = require('./fixture').handler; + + let { codemodName } = options; + let projectName = importCwd('./package.json').name; + let codemodDir = `${process.cwd()}/transforms/${codemodName}`; + + fs.outputFileSync( + `${codemodDir}/index.js`, + stripIndent` + module.exports = function ({ source /*, path*/ }, { parse, visit }) { + const ast = parse(source); + + return visit(ast, (env) => { + let { builders: b } = env.syntax; + + return { + MustacheStatement() { + return b.mustache(b.path('wat-wat')); + }, + }; + }); + }; + `, + 'utf8' + ); + fs.outputFileSync( + `${codemodDir}/test.js`, + stripIndent` + 'use strict'; + + const { runTransformTest } = require('codemod-cli'); + + runTransformTest({ + type: 'template', + name: '${codemodName}', + }); + `, + 'utf8' + ); + fs.outputFileSync( + `${codemodDir}/README.md`, + stripIndent` + # ${codemodName}\n + + ## Usage + + \`\`\` + npx ${projectName} ${codemodName} path/of/files/ or/some**/*glob.hbs + + # or + + yarn global add ${projectName} + ${projectName} ${codemodName} path/of/files/ or/some**/*glob.hbs + \`\`\` + + ## Local Usage + \`\`\` + node ./bin/cli.js ${codemodName} path/of/files/ or/some**/*glob.hbs + \`\`\` + + ## Input / Output + + + + + + + `, + 'utf8' + ); + + generateFixture({ codemodName, fixtureName: 'basic', type: options.type }); +} + +module.exports.handler = function handler(options) { + switch (options.type) { + case 'js': + return jsHandler(options); + case 'hbs': + return hbsHandler(options); + } }; diff --git a/commands/local/generate/fixture.js b/commands/local/generate/fixture.js index 8449028..666a775 100644 --- a/commands/local/generate/fixture.js +++ b/commands/local/generate/fixture.js @@ -8,6 +8,12 @@ module.exports.builder = function builder(yargs) { }) .positional('fixture-name', { describe: 'the name of the fixture to generate', + }) + .option('type', { + alias: 't', + describe: 'choose the fixture type', + choices: ['js', 'hbs'], + default: 'js', }); }; @@ -18,6 +24,6 @@ module.exports.handler = function handler(options) { let codemodDir = `${process.cwd()}/transforms/${codemodName}`; let fixturePath = `${codemodDir}/__testfixtures__/${fixtureName}`; - fs.outputFileSync(`${fixturePath}.input.js`, ''); - fs.outputFileSync(`${fixturePath}.output.js`, ''); + fs.outputFileSync(`${fixturePath}.input.${options.type}`, ''); + fs.outputFileSync(`${fixturePath}.output.${options.type}`, ''); }; diff --git a/tests/cli-test.js b/tests/cli-test.js index 34d77bc..cc4c584 100644 --- a/tests/cli-test.js +++ b/tests/cli-test.js @@ -112,7 +112,7 @@ QUnit.module('codemod-cli', function(hooks) { setupProject(hooks); QUnit.module('codemod', function() { - QUnit.test('should generate a codemod', async function(assert) { + QUnit.test('should generate a js codemod', async function(assert) { let result = await execa(EXECUTABLE_PATH, ['generate', 'codemod', 'main']); assert.equal(result.exitCode, 0, 'exited with zero'); @@ -127,10 +127,26 @@ QUnit.module('codemod-cli', function(hooks) { 'main/test.js', ]); }); + + QUnit.test('should generate a hbs codemod', async function(assert) { + let result = await execa(EXECUTABLE_PATH, ['generate', 'codemod', 'main', '--type', 'hbs']); + + assert.equal(result.exitCode, 0, 'exited with zero'); + assert.deepEqual(walkSync(codemodProject.path('transforms')), [ + '.gitkeep', + 'main/', + 'main/README.md', + 'main/__testfixtures__/', + 'main/__testfixtures__/basic.input.hbs', + 'main/__testfixtures__/basic.output.hbs', + 'main/index.js', + 'main/test.js', + ]); + }); }); QUnit.module('fixture', function() { - QUnit.test('should generate a fixture for the specified codemod', async function(assert) { + QUnit.test('should generate a fixture for the specified js codemod', async function(assert) { await execa(EXECUTABLE_PATH, ['generate', 'codemod', 'main']); let result = await execa(EXECUTABLE_PATH, [ 'generate', @@ -153,6 +169,32 @@ QUnit.module('codemod-cli', function(hooks) { 'main/test.js', ]); }); + + QUnit.test('should generate a fixture for the specified hbs codemod', async function(assert) { + await execa(EXECUTABLE_PATH, ['generate', 'codemod', 'main', '--type', 'hbs']); + let result = await execa(EXECUTABLE_PATH, [ + 'generate', + 'fixture', + 'main', + 'this-dot-owner', + '--type', + 'hbs', + ]); + + assert.equal(result.exitCode, 0, 'exited with zero'); + assert.deepEqual(walkSync(codemodProject.path('transforms')), [ + '.gitkeep', + 'main/', + 'main/README.md', + 'main/__testfixtures__/', + 'main/__testfixtures__/basic.input.hbs', + 'main/__testfixtures__/basic.output.hbs', + 'main/__testfixtures__/this-dot-owner.input.hbs', + 'main/__testfixtures__/this-dot-owner.output.hbs', + 'main/index.js', + 'main/test.js', + ]); + }); }); QUnit.module('test', function() { @@ -539,5 +581,89 @@ QUnit.module('codemod-cli', function(hooks) { }); }); }); + + QUnit.module('runTransform type=template', function(hooks) { + let userProject; + + hooks.beforeEach(async function() { + // includes simple mustache transform + await execa(EXECUTABLE_PATH, ['generate', 'codemod', 'main', '--type', 'hbs']); + + userProject = await createTempDir(); + process.chdir(userProject.path()); + }); + + hooks.afterEach(function() { + process.chdir(ROOT); + + return userProject.dispose(); + }); + + QUnit.test('runs transform', async function(assert) { + userProject.write({ + foo: { + 'something.hbs': '{{what}}', + 'other.hbs': '{{what}}', + }, + }); + + await CodemodCLI.runTransform( + codemodProject.path('bin'), + 'main', + 'foo/*thing.hbs', + undefined, + 'template' + ); + + assert.deepEqual(userProject.read(), { + foo: { + 'something.hbs': '{{wat-wat}}', + 'other.hbs': '{{what}}', + }, + }); + }); + + QUnit.test('runs transform with options', async function(assert) { + codemodProject.write({ + transforms: { + main: { + 'index.js': ` + const { getOptions } = require('codemod-cli'); + module.exports = function ({ source /*, path*/ }, { parse, visit }) { + const ast = parse(source); + const options = getOptions(); + + return visit(ast, (env) => { + let { builders: b } = env.syntax; + + return { + MustacheStatement() { + return b.mustache(b.path(options.biz + options.baz)); + }, + }; + }); + }; + `, + }, + }, + }); + + userProject.write({ + foo: { 'something.hbs': `{{foo}}` }, + }); + + await CodemodCLI.runTransform( + codemodProject.path('bin'), + 'main', + ['--biz', 'A', '--baz', 'B', 'foo/*ing.hbs'], + undefined, + 'template' + ); + + assert.deepEqual(userProject.read(), { + foo: { 'something.hbs': `{{AB}}` }, + }); + }); + }); }); }); From 9dba17c9022088600acced17fbb3f8a47f3b242a Mon Sep 17 00:00:00 2001 From: simonihmig Date: Thu, 25 Jun 2020 22:50:36 +0200 Subject: [PATCH 4/7] Address PR feedback --- commands/local/generate/codemod.js | 2 ++ src/bin-support.js | 10 ++++------ src/test-support.js | 2 ++ src/test-support/template.js | 8 ++++---- 4 files changed, 12 insertions(+), 10 deletions(-) diff --git a/commands/local/generate/codemod.js b/commands/local/generate/codemod.js index e346ad4..4e70353 100644 --- a/commands/local/generate/codemod.js +++ b/commands/local/generate/codemod.js @@ -180,5 +180,7 @@ module.exports.handler = function handler(options) { return jsHandler(options); case 'hbs': return hbsHandler(options); + default: + throw new Error(`Unknown type: "${options.type}"`); } }; diff --git a/src/bin-support.js b/src/bin-support.js index 97cec19..3dd60c8 100644 --- a/src/bin-support.js +++ b/src/bin-support.js @@ -57,15 +57,11 @@ async function runTemplateTransform( expandDirectories: { extensions: extensions.split(',') }, }); let transformPath = path.join(binRoot, '..', 'transforms', transformName, 'index.js'); - - let templateRecastPkg = require('ember-template-recast/package'); - let templateRecastPath = path.dirname(require.resolve('ember-template-recast/package')); - let binPath = path.join(templateRecastPath, templateRecastPkg.bin); - let binOptions = ['-t', transformPath, ...foundPaths]; - return execa(binPath, binOptions, { + return execa('ember-template-recast', binOptions, { stdio: 'inherit', + preferLocal: true, env: { CODEMOD_CLI_ARGS: JSON.stringify(options), }, @@ -84,6 +80,8 @@ async function runTransform(binRoot, transformName, args, extensions, type = 'js return runJsTransform(binRoot, transformName, args, extensions); case 'template': return runTemplateTransform(binRoot, transformName, args, extensions); + default: + throw new Error(`Unknown type passed to runTransform: "${type}"`); } } diff --git a/src/test-support.js b/src/test-support.js index e11fdd0..9a1cec8 100644 --- a/src/test-support.js +++ b/src/test-support.js @@ -9,6 +9,8 @@ function runTransformTest(options) { return jscodeshiftTest(options); case 'template': return templateTest(options); + default: + throw new Error(`Unknown type passed to runTransformTest: "${options.type}"`); } } diff --git a/src/test-support/template.js b/src/test-support/template.js index 2a79f25..6284e95 100644 --- a/src/test-support/template.js +++ b/src/test-support/template.js @@ -8,10 +8,10 @@ const globby = require('globby'); const { transformDetails } = require('./utils'); const { transform, parse } = require('ember-template-recast'); -function runTemplateTest(plugin, { path, source }, expectedOutput) { +function runTemplateTest(plugin, { path: pluginPath, source }, expectedOutput) { const code = plugin( { - path, + path: pluginPath, source, }, { @@ -23,7 +23,7 @@ function runTemplateTest(plugin, { path, source }, expectedOutput) { } ); - expect((code || '').trim()).toEqual(expectedOutput.trim()); + expect(code || '').toEqual(expectedOutput); } module.exports = function templateTest(options) { @@ -57,7 +57,7 @@ module.exports = function templateTest(options) { it('is idempotent', function() { runTemplateTest( plugin, - { path: testInputPath, source: fs.readFileSync(inputPath, 'utf8') }, + { path: testInputPath, source: fs.readFileSync(outputPath, 'utf8') }, fs.readFileSync(outputPath, 'utf8') ); }); From 6bf475ab432ccfc531993e4fa4b7d0d9a57efcb9 Mon Sep 17 00:00:00 2001 From: simonihmig Date: Fri, 10 Jul 2020 17:19:13 +0200 Subject: [PATCH 5/7] Remove extra globby call in bin-support/runTemplateTransform As ember-template-recast handles that, https://github.com/rwjblue/codemod-cli/pull/81#discussion_r445161914 --- src/bin-support.js | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/src/bin-support.js b/src/bin-support.js index 3dd60c8..5db4d72 100644 --- a/src/bin-support.js +++ b/src/bin-support.js @@ -1,7 +1,6 @@ 'use strict'; const DEFAULT_JS_EXTENSIONS = 'js,ts'; -const DEFAULT_TEMPLATE_EXTENSIONS = 'hbs'; async function runJsTransform(binRoot, transformName, args, extensions = DEFAULT_JS_EXTENSIONS) { const globby = require('globby'); @@ -38,13 +37,7 @@ async function runJsTransform(binRoot, transformName, args, extensions = DEFAULT } } -async function runTemplateTransform( - binRoot, - transformName, - args, - extensions = DEFAULT_TEMPLATE_EXTENSIONS -) { - const globby = require('globby'); +async function runTemplateTransform(binRoot, transformName, args) { const execa = require('execa'); const chalk = require('chalk'); const path = require('path'); @@ -53,11 +46,8 @@ async function runTemplateTransform( let { paths, options } = parseTransformArgs(args); try { - let foundPaths = await globby(paths, { - expandDirectories: { extensions: extensions.split(',') }, - }); let transformPath = path.join(binRoot, '..', 'transforms', transformName, 'index.js'); - let binOptions = ['-t', transformPath, ...foundPaths]; + let binOptions = ['-t', transformPath, ...paths]; return execa('ember-template-recast', binOptions, { stdio: 'inherit', @@ -79,7 +69,7 @@ async function runTransform(binRoot, transformName, args, extensions, type = 'js case 'jscodeshift': return runJsTransform(binRoot, transformName, args, extensions); case 'template': - return runTemplateTransform(binRoot, transformName, args, extensions); + return runTemplateTransform(binRoot, transformName, args); default: throw new Error(`Unknown type passed to runTransform: "${type}"`); } From 1902c2810818c9e0ccf9a969566f1fed45c0bb91 Mon Sep 17 00:00:00 2001 From: simonihmig Date: Fri, 10 Jul 2020 19:59:22 +0200 Subject: [PATCH 6/7] Refactor transform type detection A generated transform now exports its own type. This allows us to * remove the `type` arguments from `runTransform()`, which was problematic anyway as that type would have to passed in the project's `cli.js`, so would not have allowed to have different transform types per project. Instead the type is taken from the transform's exported type itself. * same for `runTransformTest()`: `options.type` is not needed anymore, as the type is also taken from the transform itself * instead of failing when a user tries to generate a fixture for a transform with non-matching types, the generate fixture command now implicitly determines the fixture type from its transform type --- commands/local/generate/codemod.js | 10 +- commands/local/generate/fixture.js | 14 +- src/bin-support.js | 22 ++- src/test-support.js | 11 +- src/test-support/utils.js | 7 +- src/transform-support.js | 11 ++ tests/cli-test.js | 28 ++-- yarn.lock | 247 ++++++++++++++++++++++++++++- 8 files changed, 308 insertions(+), 42 deletions(-) diff --git a/commands/local/generate/codemod.js b/commands/local/generate/codemod.js index 4e70353..a9781a5 100644 --- a/commands/local/generate/codemod.js +++ b/commands/local/generate/codemod.js @@ -43,7 +43,9 @@ function jsHandler(options) { .join(''); }) .toSource(); - } + }; + + module.exports.type = 'js'; `, 'utf8' ); @@ -54,8 +56,7 @@ function jsHandler(options) { const { runTransformTest } = require('codemod-cli'); - runTransformTest({ - type: 'jscodeshift', + runTransformTest({ name: '${codemodName}', }); `, @@ -122,6 +123,8 @@ function hbsHandler(options) { }; }); }; + + module.exports.type = 'hbs'; `, 'utf8' ); @@ -133,7 +136,6 @@ function hbsHandler(options) { const { runTransformTest } = require('codemod-cli'); runTransformTest({ - type: 'template', name: '${codemodName}', }); `, diff --git a/commands/local/generate/fixture.js b/commands/local/generate/fixture.js index 666a775..f89414c 100644 --- a/commands/local/generate/fixture.js +++ b/commands/local/generate/fixture.js @@ -8,22 +8,20 @@ module.exports.builder = function builder(yargs) { }) .positional('fixture-name', { describe: 'the name of the fixture to generate', - }) - .option('type', { - alias: 't', - describe: 'choose the fixture type', - choices: ['js', 'hbs'], - default: 'js', }); }; module.exports.handler = function handler(options) { const fs = require('fs-extra'); + const { getTransformType } = require('../../../src/transform-support'); let { codemodName, fixtureName } = options; let codemodDir = `${process.cwd()}/transforms/${codemodName}`; + let codemodTransform = `${codemodDir}/index.js`; let fixturePath = `${codemodDir}/__testfixtures__/${fixtureName}`; - fs.outputFileSync(`${fixturePath}.input.${options.type}`, ''); - fs.outputFileSync(`${fixturePath}.output.${options.type}`, ''); + let transformType = getTransformType(codemodTransform); + + fs.outputFileSync(`${fixturePath}.input.${transformType}`, ''); + fs.outputFileSync(`${fixturePath}.output.${transformType}`, ''); }; diff --git a/src/bin-support.js b/src/bin-support.js index 5db4d72..b8c3cdf 100644 --- a/src/bin-support.js +++ b/src/bin-support.js @@ -2,6 +2,12 @@ const DEFAULT_JS_EXTENSIONS = 'js,ts'; +function getTransformPath(binRoot, transformName) { + const path = require('path'); + + return path.join(binRoot, '..', 'transforms', transformName, 'index.js'); +} + async function runJsTransform(binRoot, transformName, args, extensions = DEFAULT_JS_EXTENSIONS) { const globby = require('globby'); const execa = require('execa'); @@ -15,7 +21,7 @@ async function runJsTransform(binRoot, transformName, args, extensions = DEFAULT let foundPaths = await globby(paths, { expandDirectories: { extensions: extensions.split(',') }, }); - let transformPath = path.join(binRoot, '..', 'transforms', transformName, 'index.js'); + let transformPath = getTransformPath(binRoot, transformName); let jscodeshiftPkg = require('jscodeshift/package'); let jscodeshiftPath = path.dirname(require.resolve('jscodeshift/package')); @@ -40,13 +46,12 @@ async function runJsTransform(binRoot, transformName, args, extensions = DEFAULT async function runTemplateTransform(binRoot, transformName, args) { const execa = require('execa'); const chalk = require('chalk'); - const path = require('path'); const { parseTransformArgs } = require('./options-support'); let { paths, options } = parseTransformArgs(args); try { - let transformPath = path.join(binRoot, '..', 'transforms', transformName, 'index.js'); + let transformPath = getTransformPath(binRoot, transformName); let binOptions = ['-t', transformPath, ...paths]; return execa('ember-template-recast', binOptions, { @@ -64,11 +69,16 @@ async function runTemplateTransform(binRoot, transformName, args) { } } -async function runTransform(binRoot, transformName, args, extensions, type = 'jscodeshift') { +async function runTransform(binRoot, transformName, args, extensions) { + const { getTransformType } = require('./transform-support'); + + let transformPath = getTransformPath(binRoot, transformName); + let type = getTransformType(transformPath); + switch (type) { - case 'jscodeshift': + case 'js': return runJsTransform(binRoot, transformName, args, extensions); - case 'template': + case 'hbs': return runTemplateTransform(binRoot, transformName, args); default: throw new Error(`Unknown type passed to runTransform: "${type}"`); diff --git a/src/test-support.js b/src/test-support.js index 9a1cec8..f5b3c4c 100644 --- a/src/test-support.js +++ b/src/test-support.js @@ -2,15 +2,18 @@ const jscodeshiftTest = require('./test-support/jscodeshift'); const templateTest = require('./test-support/template'); +const { transformDetails } = require('./test-support/utils'); function runTransformTest(options) { - switch (options.type) { - case 'jscodeshift': + let details = transformDetails(options); + + switch (details.transformType) { + case 'js': return jscodeshiftTest(options); - case 'template': + case 'hbs': return templateTest(options); default: - throw new Error(`Unknown type passed to runTransformTest: "${options.type}"`); + throw new Error(`Unknown type of transform: "${details.transformType}"`); } } diff --git a/src/test-support/utils.js b/src/test-support/utils.js index a4b8876..9fa0aa6 100644 --- a/src/test-support/utils.js +++ b/src/test-support/utils.js @@ -1,12 +1,17 @@ 'use strict'; function transformDetails(options) { + const { getTransformType } = require('../transform-support'); + let root = process.cwd() + `/transforms/${options.name}/`; + let transformPath = root + 'index.js'; + let transformType = getTransformType(transformPath); return { name: options.name, root, - transformPath: root + 'index', + transformPath, + transformType, fixtureDir: root + '__testfixtures__/', }; } diff --git a/src/transform-support.js b/src/transform-support.js index 32649ea..315e38e 100644 --- a/src/transform-support.js +++ b/src/transform-support.js @@ -1,5 +1,15 @@ 'use strict'; +function getTransformType(transformPath) { + const fs = require('fs-extra'); + + if (!fs.existsSync(transformPath)) { + throw new Error(`Transform ${transformPath} not found.`); + } + + return require(transformPath).type || 'js'; // fallback to 'js' if `type` export does not exist +} + function getJSCodeshiftParser(api) { try { let parser = require('recast/parsers/typescript'); @@ -19,4 +29,5 @@ module.exports = { jscodeshift: { getParser: getJSCodeshiftParser, }, + getTransformType, }; diff --git a/tests/cli-test.js b/tests/cli-test.js index cc4c584..9acae98 100644 --- a/tests/cli-test.js +++ b/tests/cli-test.js @@ -177,8 +177,6 @@ QUnit.module('codemod-cli', function(hooks) { 'fixture', 'main', 'this-dot-owner', - '--type', - 'hbs', ]); assert.equal(result.exitCode, 0, 'exited with zero'); @@ -582,7 +580,7 @@ QUnit.module('codemod-cli', function(hooks) { }); }); - QUnit.module('runTransform type=template', function(hooks) { + QUnit.module('runTransform type=hbs', function(hooks) { let userProject; hooks.beforeEach(async function() { @@ -607,13 +605,7 @@ QUnit.module('codemod-cli', function(hooks) { }, }); - await CodemodCLI.runTransform( - codemodProject.path('bin'), - 'main', - 'foo/*thing.hbs', - undefined, - 'template' - ); + await CodemodCLI.runTransform(codemodProject.path('bin'), 'main', 'foo/*thing.hbs'); assert.deepEqual(userProject.read(), { foo: { @@ -643,6 +635,8 @@ QUnit.module('codemod-cli', function(hooks) { }; }); }; + + module.exports.type = 'hbs'; `, }, }, @@ -652,13 +646,13 @@ QUnit.module('codemod-cli', function(hooks) { foo: { 'something.hbs': `{{foo}}` }, }); - await CodemodCLI.runTransform( - codemodProject.path('bin'), - 'main', - ['--biz', 'A', '--baz', 'B', 'foo/*ing.hbs'], - undefined, - 'template' - ); + await CodemodCLI.runTransform(codemodProject.path('bin'), 'main', [ + '--biz', + 'A', + '--baz', + 'B', + 'foo/*ing.hbs', + ]); assert.deepEqual(userProject.read(), { foo: { 'something.hbs': `{{AB}}` }, diff --git a/yarn.lock b/yarn.lock index 7b7a3d1..85fdf7f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -724,6 +724,37 @@ exec-sh "^0.3.2" minimist "^1.2.0" +"@glimmer/env@0.1.7": + version "0.1.7" + resolved "https://registry.yarnpkg.com/@glimmer/env/-/env-0.1.7.tgz#fd2d2b55a9029c6b37a6c935e8c8871ae70dfa07" + integrity sha1-/S0rVakCnGs3psk16MiHGucN+gc= + +"@glimmer/interfaces@^0.51.1": + version "0.51.1" + resolved "https://registry.yarnpkg.com/@glimmer/interfaces/-/interfaces-0.51.1.tgz#c5637669ff83c630d91c700598b9963225d656f2" + integrity sha512-ImwkFNj92RaeANQPlnSQ5kTtK18JzkY2FPE7N7Ktn3AvdXgM4P3puQzPuXhTn4UCBl6NZtN8YqCAy7kQ6eRC0w== + dependencies: + "@simple-dom/interface" "^1.4.0" + +"@glimmer/syntax@^0.51.1": + version "0.51.1" + resolved "https://registry.yarnpkg.com/@glimmer/syntax/-/syntax-0.51.1.tgz#24cb4f01693bd934075d03087bdc76ab6bff0524" + integrity sha512-z5XSbLgMKGU8tgSm9Ju4mimSAJ6/SZrY2Xw2znEAmUJOIPte+tmkdpggpgj7lAjD5u2YVBVHDbz6RaZDhYASsw== + dependencies: + "@glimmer/interfaces" "^0.51.1" + "@glimmer/util" "^0.51.1" + handlebars "^4.7.4" + simple-html-tokenizer "^0.5.9" + +"@glimmer/util@^0.51.1": + version "0.51.1" + resolved "https://registry.yarnpkg.com/@glimmer/util/-/util-0.51.1.tgz#db27afd2ee7191e8e399c272b9f7fbe05cc26691" + integrity sha512-MCwUvV3z4pqLpeXcv5Mbchdgw0GeEPH8jUEkUTG837b5XlC2M/NO893E5A8AZbGNSP7CDsYibDExz7mjaLqq/A== + dependencies: + "@glimmer/env" "0.1.7" + "@glimmer/interfaces" "^0.51.1" + "@simple-dom/interface" "^1.4.0" + "@iarna/toml@2.2.3": version "2.2.3" resolved "https://registry.yarnpkg.com/@iarna/toml/-/toml-2.2.3.tgz#f060bf6eaafae4d56a7dac618980838b0696e2ab" @@ -885,11 +916,24 @@ "@nodelib/fs.stat" "2.0.2" run-parallel "^1.1.9" +"@nodelib/fs.scandir@2.1.3": + version "2.1.3" + resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz#3a582bdb53804c6ba6d146579c46e52130cf4a3b" + integrity sha512-eGmwYQn3gxo4r7jdQnkrrN6bY478C3P+a/y72IJukF8LjB6ZHeB3c+Ehacj3sYeSmUXGlnA67/PmbM9CVwL7Dw== + dependencies: + "@nodelib/fs.stat" "2.0.3" + run-parallel "^1.1.9" + "@nodelib/fs.stat@2.0.2", "@nodelib/fs.stat@^2.0.1": version "2.0.2" resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.2.tgz#2762aea8fe78ea256860182dcb52d61ee4b8fda6" integrity sha512-z8+wGWV2dgUhLqrtRYa03yDx4HWMvXKi1z8g3m2JyxAx8F7xk74asqPk5LAETjqDSGLFML/6CDl0+yFunSYicw== +"@nodelib/fs.stat@2.0.3", "@nodelib/fs.stat@^2.0.2": + version "2.0.3" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz#34dc5f4cabbc720f4e60f75a747e7ecd6c175bd3" + integrity sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA== + "@nodelib/fs.walk@^1.2.1": version "1.2.3" resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.3.tgz#a555dc256acaf00c62b0db29529028dd4d4cb141" @@ -898,6 +942,14 @@ "@nodelib/fs.scandir" "2.1.2" fastq "^1.6.0" +"@nodelib/fs.walk@^1.2.3": + version "1.2.4" + resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.4.tgz#011b9202a70a6366e436ca5c065844528ab04976" + integrity sha512-1V9XOY4rDW0rehzbrcqAmHnz8e7SKvX27gh8Gt2WgB0+pdzdiLV83p72kZPU+jvMbS1qU5mauP2iOvO8rhmurQ== + dependencies: + "@nodelib/fs.scandir" "2.1.3" + fastq "^1.6.0" + "@octokit/endpoint@^5.1.0": version "5.3.5" resolved "https://registry.yarnpkg.com/@octokit/endpoint/-/endpoint-5.3.5.tgz#2822c3b01107806dbdce3863b6205e3eff4289ed" @@ -945,6 +997,11 @@ once "^1.4.0" universal-user-agent "^4.0.0" +"@simple-dom/interface@^1.4.0": + version "1.4.0" + resolved "https://registry.yarnpkg.com/@simple-dom/interface/-/interface-1.4.0.tgz#e8feea579232017f89b0138e2726facda6fbb71f" + integrity sha512-l5qumKFWU0S+4ZzMaLXFU8tQZsicHEMEyAxI5kDFGhJsRqDwe0a7/iPA/GdxlGyDKseQQAgIz5kzU7eXTrlSpA== + "@sindresorhus/is@^0.14.0": version "0.14.0" resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.14.0.tgz#9fb3a3cf3132328151f353de4632e01e52102bea" @@ -990,6 +1047,11 @@ dependencies: "@babel/types" "^7.3.0" +"@types/color-name@^1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0" + integrity sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ== + "@types/events@*": version "3.0.0" resolved "https://registry.yarnpkg.com/@types/events/-/events-3.0.0.tgz#2862f3f58a9a7f7c3e78d79f130dd4d71c25c2a7" @@ -1171,6 +1233,11 @@ ansi-regex@^4.0.0, ansi-regex@^4.1.0: resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg== +ansi-regex@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75" + integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg== + ansi-styles@^3.2.0, ansi-styles@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" @@ -1178,6 +1245,14 @@ ansi-styles@^3.2.0, ansi-styles@^3.2.1: dependencies: color-convert "^1.9.0" +ansi-styles@^4.1.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.2.1.tgz#90ae75c424d008d2624c5bf29ead3177ebfcf359" + integrity sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA== + dependencies: + "@types/color-name" "^1.1.1" + color-convert "^2.0.1" + any-promise@^1.0.0: version "1.3.0" resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f" @@ -1288,6 +1363,14 @@ async-limiter@~1.0.0: resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd" integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ== +async-promise-queue@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/async-promise-queue/-/async-promise-queue-1.0.5.tgz#cb23bce9fce903a133946a700cc85f27f09ea49d" + integrity sha512-xi0aQ1rrjPWYmqbwr18rrSKbSaXIeIwSd1J4KAgVfkq8utNbdZoht7GfvfY6swFUAMJ9obkc4WPJmtGwl+B8dw== + dependencies: + async "^2.4.1" + debug "^2.6.8" + async-retry@1.2.3: version "1.2.3" resolved "https://registry.yarnpkg.com/async-retry/-/async-retry-1.2.3.tgz#a6521f338358d322b1a0012b79030c6f411d1ce0" @@ -1295,6 +1378,13 @@ async-retry@1.2.3: dependencies: retry "0.12.0" +async@^2.4.1: + version "2.6.3" + resolved "https://registry.yarnpkg.com/async/-/async-2.6.3.tgz#d72625e2344a3656e3a3ad4fa749fa83299d82ff" + integrity sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg== + dependencies: + lodash "^4.17.14" + asynckit@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" @@ -1682,6 +1772,14 @@ chalk@2.4.2, chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.0, chalk@^2.4. escape-string-regexp "^1.0.5" supports-color "^5.3.0" +chalk@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-3.0.0.tgz#3f73c2bf526591f574cc492c51e2456349f844e4" + integrity sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + changelog-filename-regex@^1.1.0: version "1.1.2" resolved "https://registry.yarnpkg.com/changelog-filename-regex/-/changelog-filename-regex-1.1.2.tgz#19e98e38248cff0c1cf3ae3bf51bfb22c48592d6" @@ -1757,6 +1855,11 @@ cli-spinners@^2.0.0: resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.2.0.tgz#e8b988d9206c692302d8ee834e7a85c0144d8f77" integrity sha512-tgU3fKwzYjiLEQgPMD9Jt+JjHVL9kW93FiIMX/l7rivvOD4/LL0Mf7gda3+4U2KJBloybwgj5KEoQgGRioMiKQ== +cli-spinners@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.3.0.tgz#0632239a4b5aa4c958610142c34bb7a651fc8df5" + integrity sha512-Xs2Hf2nzrvJMFKimOR7YR0QwZ8fc0u98kdtwN1eNAZzNQgH3vK2pXzff6GJtKh7S5hoJ87ECiAiZFS2fb5Ii2w== + cli-width@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639" @@ -1817,16 +1920,33 @@ color-convert@^1.9.0: dependencies: color-name "1.1.3" +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + color-name@1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= +color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + colors@^1.1.2: version "1.3.3" resolved "https://registry.yarnpkg.com/colors/-/colors-1.3.3.tgz#39e005d546afe01e01f9c4ca8fa50f686a01205d" integrity sha512-mmGt/1pZqYRjMxB1axhTo16/snVZ5krrKkcmMeVKxzECMMXoCgnvTPp10QgHfcbQZw8Dq2jMNG6je4JlWU0gWg== +colors@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78" + integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA== + combined-stream@^1.0.6, combined-stream@~1.0.6: version "1.0.8" resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" @@ -1844,6 +1964,11 @@ commander@^2.15.1: resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.0.tgz#d58bb2b5c1ee8f87b0d340027e9e94e222c5a422" integrity sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ== +commander@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-5.1.0.tgz#46abbd1652f8e059bddaef99bbdcb2ad9cf179ae" + integrity sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg== + common-tags@^1.8.0: version "1.8.0" resolved "https://registry.yarnpkg.com/common-tags/-/common-tags-1.8.0.tgz#8e3153e542d4a39e9b10554434afaaf98956a937" @@ -2044,7 +2169,7 @@ data-urls@^1.0.0: whatwg-mimetype "^2.2.0" whatwg-url "^7.0.0" -debug@2.6.9, debug@^2.2.0, debug@^2.3.3: +debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.8: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== @@ -2267,6 +2392,21 @@ electron-to-chromium@^1.3.247: resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.264.tgz#ed837f44524d0601a7b2b7b6efd86e35753d0e27" integrity sha512-z8E7WkrrquCuGYv+kKyybuZIbdms+4PeHp7Zm2uIgEhAigP0bOwqXILItwj0YO73o+QyHY/7XtEfP5DsHOWQgQ== +ember-template-recast@^4.1.4: + version "4.1.4" + resolved "https://registry.yarnpkg.com/ember-template-recast/-/ember-template-recast-4.1.4.tgz#0552f4f27d33b17ac05a48107f369032eb45fb97" + integrity sha512-jw38ncM5uJu7INVWYCmm4GNIEdGVLkjABWbj451A83Ag4lBfXIbIHq+5IM7rFzUlw/Ho39WxeKhKZ5KTvIVljQ== + dependencies: + "@glimmer/syntax" "^0.51.1" + async-promise-queue "^1.0.5" + colors "^1.4.0" + commander "^5.1.0" + globby "^11.0.0" + ora "^4.0.4" + slash "^3.0.0" + tmp "^0.1.0" + workerpool "^5.0.4" + emoji-regex@^7.0.1: version "7.0.3" resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" @@ -2688,6 +2828,18 @@ fast-glob@^3.0.3: merge2 "^1.2.3" micromatch "^4.0.2" +fast-glob@^3.1.1: + version "3.2.4" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.4.tgz#d20aefbf99579383e7f3cc66529158c9b98554d3" + integrity sha512-kr/Oo6PX51265qeuCYsyGypiO5uJFgBS0jksyG7FUeCyQzNwYnzrNIMR1NXfkZXsMYXYLRAHgISHBz8gQcxKHQ== + dependencies: + "@nodelib/fs.stat" "^2.0.2" + "@nodelib/fs.walk" "^1.2.3" + glob-parent "^5.1.0" + merge2 "^1.3.0" + micromatch "^4.0.2" + picomatch "^2.2.1" + fast-json-stable-stringify@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2" @@ -3046,6 +3198,13 @@ glob-parent@^5.0.0: dependencies: is-glob "^4.0.1" +glob-parent@^5.1.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.1.tgz#b6c1ef417c4e5663ea498f1c45afac6916bbc229" + integrity sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ== + dependencies: + is-glob "^4.0.1" + glob@^7.0.0, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4: version "7.1.4" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.4.tgz#aa608a2f6c577ad357e1ae5a5c26d9a8d1969255" @@ -3104,6 +3263,18 @@ globby@10.0.1, globby@^10.0.1: merge2 "^1.2.3" slash "^3.0.0" +globby@^11.0.0: + version "11.0.1" + resolved "https://registry.yarnpkg.com/globby/-/globby-11.0.1.tgz#9a2bf107a068f3ffeabc49ad702c79ede8cfd357" + integrity sha512-iH9RmgwCmUJHi2z5o2l3eTtGBtXek1OYlHrbcxOYugyHLmAsZrPj43OtHThd62Buh/Vv6VyCBD2bdyWcGNQqoQ== + dependencies: + array-union "^2.1.0" + dir-glob "^3.0.1" + fast-glob "^3.1.1" + ignore "^5.1.4" + merge2 "^1.3.0" + slash "^3.0.0" + got@9.6.0, got@^9.6.0: version "9.6.0" resolved "https://registry.yarnpkg.com/got/-/got-9.6.0.tgz#edf45e7d67f99545705de1f7bbeeeb121765ed85" @@ -3153,7 +3324,7 @@ growly@^1.3.0: resolved "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081" integrity sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE= -handlebars@^4.0.11, handlebars@^4.1.2: +handlebars@^4.0.11, handlebars@^4.1.2, handlebars@^4.7.4: version "4.7.6" resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.7.6.tgz#d4c05c1baf90e9945f77aa68a7a219aa4a7df74e" integrity sha512-1f2BACcBfiwAfStCKZNrUCgqNZkGsAT7UM3kkYtXuLo0KnaVfjKOyf7PRzB6++aK9STyT1Pd2ZCPe3EGOXleXA== @@ -3361,6 +3532,11 @@ ignore@^5.1.1: resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.4.tgz#84b7b3dbe64552b6ef0eca99f6743dbec6d97adf" integrity sha512-MzbUSahkTW1u7JpKKjY7LCARd1fU5W2rLdxlM4kdkayuCwZImjkpluF9CM1aLewYJguPDqewLam18Y6AU69A8A== +ignore@^5.1.4: + version "5.1.8" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.8.tgz#f150a8b50a34289b33e22f5889abd4d8016f0e57" + integrity sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw== + import-cwd@3.0.0, import-cwd@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/import-cwd/-/import-cwd-3.0.0.tgz#20845547718015126ea9b3676b7592fb8bd4cf92" @@ -3656,6 +3832,11 @@ is-installed-globally@^0.1.0: global-dirs "^0.1.0" is-path-inside "^1.0.0" +is-interactive@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-interactive/-/is-interactive-1.0.0.tgz#cea6e6ae5c870a7b0a0004070b7b587e0252912e" + integrity sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w== + is-npm@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-1.0.0.tgz#f2fb63a65e4905b406c86072765a1a4dc793b9f4" @@ -4543,6 +4724,13 @@ log-symbols@^2.2.0: dependencies: chalk "^2.0.1" +log-symbols@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-3.0.0.tgz#f3a08516a5dea893336a7dee14d18a1cfdab77c4" + integrity sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ== + dependencies: + chalk "^2.4.2" + loose-envify@^1.0.0: version "1.4.0" resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" @@ -4696,6 +4884,11 @@ merge2@^1.2.3: resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.3.0.tgz#5b366ee83b2f1582c48f87e47cf1a9352103ca81" integrity sha512-2j4DAdlBOkiSZIsaXk4mTE3sRS02yBHAtfy127xRV3bQUFqXkjHCHLW6Scv7DwNRbIWNHH8zpnz9zMaKXIdvYw== +merge2@^1.3.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" + integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== + micromatch@^3.0.4, micromatch@^3.1.10, micromatch@^3.1.4: version "3.1.10" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" @@ -5198,6 +5391,20 @@ ora@3.4.0: strip-ansi "^5.2.0" wcwidth "^1.0.1" +ora@^4.0.4: + version "4.0.4" + resolved "https://registry.yarnpkg.com/ora/-/ora-4.0.4.tgz#e8da697cc5b6a47266655bf68e0fb588d29a545d" + integrity sha512-77iGeVU1cIdRhgFzCK8aw1fbtT1B/iZAvWjS+l/o1x0RShMgxHUZaD2yDpWsNCPwXg9z1ZA78Kbdvr8kBmG/Ww== + dependencies: + chalk "^3.0.0" + cli-cursor "^3.1.0" + cli-spinners "^2.2.0" + is-interactive "^1.0.0" + log-symbols "^3.0.0" + mute-stream "0.0.8" + strip-ansi "^6.0.0" + wcwidth "^1.0.1" + os-homedir@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" @@ -5461,6 +5668,11 @@ picomatch@^2.0.5: resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.0.7.tgz#514169d8c7cd0bdbeecc8a2609e34a7163de69f6" integrity sha512-oLHIdio3tZ0qH76NybpeneBhYVj0QFTfXEFTc/B3zKQspYfYYkWYgFsmzo+4kvId/bQRcNkVeguI3y+CD22BtA== +picomatch@^2.2.1: + version "2.2.2" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad" + integrity sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg== + pify@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" @@ -6275,6 +6487,11 @@ silent-error@^1.1.0: dependencies: debug "^2.2.0" +simple-html-tokenizer@^0.5.9: + version "0.5.9" + resolved "https://registry.yarnpkg.com/simple-html-tokenizer/-/simple-html-tokenizer-0.5.9.tgz#1a83fe97f5a3e39b335fddf71cfe9b0263b581c2" + integrity sha512-w/3FEDN94r4JQ9WoYrIr8RqDIPZdyNkdpbK9glFady1CAEyD97XWCv8HFetQO21w81e7h7Nh59iYTyG1mUJftg== + sisteransi@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.3.tgz#98168d62b79e3a5e758e27ae63c4a053d748f4eb" @@ -6581,6 +6798,13 @@ strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0: dependencies: ansi-regex "^4.1.0" +strip-ansi@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.0.tgz#0b1571dd7669ccd4f3e06e14ef1eed26225ae532" + integrity sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w== + dependencies: + ansi-regex "^5.0.0" + strip-bom@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" @@ -6632,6 +6856,13 @@ supports-color@^6.1.0: dependencies: has-flag "^3.0.0" +supports-color@^7.1.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.1.0.tgz#68e32591df73e25ad1c4b49108a2ec507962bfd1" + integrity sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g== + dependencies: + has-flag "^4.0.0" + symbol-tree@^3.2.2: version "3.2.4" resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" @@ -6739,6 +6970,13 @@ tmp@0.0.33, tmp@^0.0.33: dependencies: os-tmpdir "~1.0.2" +tmp@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.1.0.tgz#ee434a4e22543082e294ba6201dcc6eafefa2877" + integrity sha512-J7Z2K08jbGcdA1kkQpJSqLF6T0tdQqpR2pnSUXsIchbPdTI9v3e85cLW0d6WDhwuAleOV71j2xWs8qMPfK7nKw== + dependencies: + rimraf "^2.6.3" + tmpl@1.0.x: version "1.0.4" resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.4.tgz#23640dd7b42d00433911140820e5cf440e521dd1" @@ -7218,6 +7456,11 @@ wordwrap@^1.0.0, wordwrap@~1.0.0: resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" integrity sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus= +workerpool@^5.0.4: + version "5.0.4" + resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-5.0.4.tgz#4f67cb70ff7550a27ab94de25b0b843cd92059a2" + integrity sha512-Sywova24Ow2NQ24JPB68bI89EdqMDjUXo4OpofK/QMD7C2ZVMloYBgQ5J3PChcBJHj2vspsmGx1/3nBKXtUkXQ== + wrap-ansi@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" From a21d5ca6e8ee59cb2fc6b75c5ed9ed9743d7cdb1 Mon Sep 17 00:00:00 2001 From: simonihmig Date: Wed, 15 Jul 2020 02:22:19 +0200 Subject: [PATCH 7/7] Cleanup after PR feedback --- commands/local/generate/fixture.js | 3 +- src/bin-support.js | 26 ++++++------- src/test-support.js | 61 ++++++++++++++++++++++++++++-- src/test-support/jscodeshift.js | 58 +--------------------------- src/test-support/template.js | 48 +---------------------- src/test-support/utils.js | 9 +++-- src/transform-support.js | 11 +++--- 7 files changed, 85 insertions(+), 131 deletions(-) diff --git a/commands/local/generate/fixture.js b/commands/local/generate/fixture.js index f89414c..565ca3b 100644 --- a/commands/local/generate/fixture.js +++ b/commands/local/generate/fixture.js @@ -17,10 +17,9 @@ module.exports.handler = function handler(options) { let { codemodName, fixtureName } = options; let codemodDir = `${process.cwd()}/transforms/${codemodName}`; - let codemodTransform = `${codemodDir}/index.js`; let fixturePath = `${codemodDir}/__testfixtures__/${fixtureName}`; - let transformType = getTransformType(codemodTransform); + let transformType = getTransformType(codemodDir); fs.outputFileSync(`${fixturePath}.input.${transformType}`, ''); fs.outputFileSync(`${fixturePath}.output.${transformType}`, ''); diff --git a/src/bin-support.js b/src/bin-support.js index b8c3cdf..1f2021d 100644 --- a/src/bin-support.js +++ b/src/bin-support.js @@ -2,18 +2,13 @@ const DEFAULT_JS_EXTENSIONS = 'js,ts'; -function getTransformPath(binRoot, transformName) { - const path = require('path'); - - return path.join(binRoot, '..', 'transforms', transformName, 'index.js'); -} - -async function runJsTransform(binRoot, transformName, args, extensions = DEFAULT_JS_EXTENSIONS) { +async function runJsTransform(root, transformName, args, extensions = DEFAULT_JS_EXTENSIONS) { const globby = require('globby'); const execa = require('execa'); const chalk = require('chalk'); const path = require('path'); const { parseTransformArgs } = require('./options-support'); + const { getTransformPath } = require('./transform-support'); let { paths, options } = parseTransformArgs(args); @@ -21,7 +16,7 @@ async function runJsTransform(binRoot, transformName, args, extensions = DEFAULT let foundPaths = await globby(paths, { expandDirectories: { extensions: extensions.split(',') }, }); - let transformPath = getTransformPath(binRoot, transformName); + let transformPath = getTransformPath(root, transformName); let jscodeshiftPkg = require('jscodeshift/package'); let jscodeshiftPath = path.dirname(require.resolve('jscodeshift/package')); @@ -43,15 +38,16 @@ async function runJsTransform(binRoot, transformName, args, extensions = DEFAULT } } -async function runTemplateTransform(binRoot, transformName, args) { +async function runTemplateTransform(root, transformName, args) { const execa = require('execa'); const chalk = require('chalk'); const { parseTransformArgs } = require('./options-support'); + const { getTransformPath } = require('./transform-support'); let { paths, options } = parseTransformArgs(args); try { - let transformPath = getTransformPath(binRoot, transformName); + let transformPath = getTransformPath(root, transformName); let binOptions = ['-t', transformPath, ...paths]; return execa('ember-template-recast', binOptions, { @@ -70,16 +66,18 @@ async function runTemplateTransform(binRoot, transformName, args) { } async function runTransform(binRoot, transformName, args, extensions) { - const { getTransformType } = require('./transform-support'); + const { getTransformType, getTransformPath } = require('./transform-support'); + const path = require('path'); - let transformPath = getTransformPath(binRoot, transformName); + let root = path.join(binRoot, '..'); + let transformPath = getTransformPath(root, transformName); let type = getTransformType(transformPath); switch (type) { case 'js': - return runJsTransform(binRoot, transformName, args, extensions); + return runJsTransform(root, transformName, args, extensions); case 'hbs': - return runTemplateTransform(binRoot, transformName, args); + return runTemplateTransform(root, transformName, args); default: throw new Error(`Unknown type passed to runTransform: "${type}"`); } diff --git a/src/test-support.js b/src/test-support.js index f5b3c4c..4ccd930 100644 --- a/src/test-support.js +++ b/src/test-support.js @@ -1,17 +1,70 @@ 'use strict'; -const jscodeshiftTest = require('./test-support/jscodeshift'); -const templateTest = require('./test-support/template'); +/* global it, describe, beforeEach, afterEach */ + +const fs = require('fs-extra'); +const path = require('path'); +const globby = require('globby'); const { transformDetails } = require('./test-support/utils'); +function testRunner(options, runTest) { + let details = transformDetails(options); + + let transform = require(details.transformPath); + + describe(details.name, function() { + globby + .sync('**/*.input.*', { + cwd: details.fixtureDir, + absolute: true, + }) + .map(entry => entry.slice(entry.indexOf('__testfixtures__') + '__testfixtures__'.length + 1)) + .forEach(filename => { + let extension = path.extname(filename); + let testName = filename.replace(`.input${extension}`, ''); + let testInputPath = path.join(details.fixtureDir, `${testName}${extension}`); + let inputPath = path.join(details.fixtureDir, `${testName}.input${extension}`); + let outputPath = path.join(details.fixtureDir, `${testName}.output${extension}`); + let optionsPath = path.join(details.fixtureDir, `${testName}.options.json`); + let options = fs.pathExistsSync(optionsPath) ? fs.readFileSync(optionsPath) : '{}'; + + describe(testName, function() { + beforeEach(function() { + process.env.CODEMOD_CLI_ARGS = options; + }); + + afterEach(function() { + process.env.CODEMOD_CLI_ARGS = ''; + }); + + it('transforms correctly', function() { + runTest( + transform, + { path: testInputPath, source: fs.readFileSync(inputPath, 'utf8') }, + fs.readFileSync(outputPath, 'utf8') + ); + }); + + it('is idempotent', function() { + runTest( + transform, + { path: testInputPath, source: fs.readFileSync(outputPath, 'utf8') }, + fs.readFileSync(outputPath, 'utf8') + ); + }); + }); + }); + }); +} + function runTransformTest(options) { let details = transformDetails(options); switch (details.transformType) { case 'js': - return jscodeshiftTest(options); + return testRunner(options, require('./test-support/jscodeshift')); case 'hbs': - return templateTest(options); + return testRunner(options, require('./test-support/template')); default: throw new Error(`Unknown type of transform: "${details.transformType}"`); } diff --git a/src/test-support/jscodeshift.js b/src/test-support/jscodeshift.js index 5926573..fdf0fb8 100644 --- a/src/test-support/jscodeshift.js +++ b/src/test-support/jscodeshift.js @@ -1,61 +1,7 @@ 'use strict'; -/* global it, describe, beforeEach, afterEach */ - const { runInlineTest } = require('jscodeshift/dist/testUtils'); -const fs = require('fs-extra'); -const path = require('path'); -const globby = require('globby'); -const { transformDetails } = require('./utils'); - -module.exports = function jscodeshiftTest(options) { - let details = transformDetails(options); - - let transform = require(details.transformPath); - - describe(details.name, function() { - globby - .sync('**/*.input.*', { - cwd: details.fixtureDir, - absolute: true, - }) - .map(entry => entry.slice(entry.indexOf('__testfixtures__') + '__testfixtures__'.length + 1)) - .forEach(filename => { - let extension = path.extname(filename); - let testName = filename.replace(`.input${extension}`, ''); - let testInputPath = path.join(details.fixtureDir, `${testName}${extension}`); - let inputPath = path.join(details.fixtureDir, `${testName}.input${extension}`); - let outputPath = path.join(details.fixtureDir, `${testName}.output${extension}`); - let optionsPath = path.join(details.fixtureDir, `${testName}.options.json`); - let options = fs.pathExistsSync(optionsPath) ? fs.readFileSync(optionsPath) : '{}'; - - describe(testName, function() { - beforeEach(function() { - process.env.CODEMOD_CLI_ARGS = options; - }); - - afterEach(function() { - process.env.CODEMOD_CLI_ARGS = ''; - }); - - it('transforms correctly', function() { - runInlineTest( - transform, - {}, - { path: testInputPath, source: fs.readFileSync(inputPath, 'utf8') }, - fs.readFileSync(outputPath, 'utf8') - ); - }); - it('is idempotent', function() { - runInlineTest( - transform, - {}, - { path: testInputPath, source: fs.readFileSync(outputPath, 'utf8') }, - fs.readFileSync(outputPath, 'utf8') - ); - }); - }); - }); - }); +module.exports = function runJsTest(transform, input, expectedOutput) { + return runInlineTest(transform, {}, input, expectedOutput); }; diff --git a/src/test-support/template.js b/src/test-support/template.js index 6284e95..aa683d3 100644 --- a/src/test-support/template.js +++ b/src/test-support/template.js @@ -1,14 +1,10 @@ 'use strict'; -/* global expect, it, describe */ +/* global expect */ -const fs = require('fs-extra'); -const path = require('path'); -const globby = require('globby'); -const { transformDetails } = require('./utils'); const { transform, parse } = require('ember-template-recast'); -function runTemplateTest(plugin, { path: pluginPath, source }, expectedOutput) { +module.exports = function runTemplateTest(plugin, { path: pluginPath, source }, expectedOutput) { const code = plugin( { path: pluginPath, @@ -24,44 +20,4 @@ function runTemplateTest(plugin, { path: pluginPath, source }, expectedOutput) { ); expect(code || '').toEqual(expectedOutput); -} - -module.exports = function templateTest(options) { - let details = transformDetails(options); - - let plugin = require(details.transformPath); - - describe(details.name, function() { - globby - .sync('**/*.input.*', { - cwd: details.fixtureDir, - absolute: true, - }) - .map(entry => entry.slice(entry.indexOf('__testfixtures__') + '__testfixtures__'.length + 1)) - .forEach(filename => { - let extension = path.extname(filename); - let testName = filename.replace(`.input${extension}`, ''); - let testInputPath = path.join(details.fixtureDir, `${testName}${extension}`); - let inputPath = path.join(details.fixtureDir, `${testName}.input${extension}`); - let outputPath = path.join(details.fixtureDir, `${testName}.output${extension}`); - - describe(testName, function() { - it('transforms correctly', function() { - runTemplateTest( - plugin, - { path: testInputPath, source: fs.readFileSync(inputPath, 'utf8') }, - fs.readFileSync(outputPath, 'utf8') - ); - }); - - it('is idempotent', function() { - runTemplateTest( - plugin, - { path: testInputPath, source: fs.readFileSync(outputPath, 'utf8') }, - fs.readFileSync(outputPath, 'utf8') - ); - }); - }); - }); - }); }; diff --git a/src/test-support/utils.js b/src/test-support/utils.js index 9fa0aa6..ee19624 100644 --- a/src/test-support/utils.js +++ b/src/test-support/utils.js @@ -1,10 +1,11 @@ 'use strict'; function transformDetails(options) { - const { getTransformType } = require('../transform-support'); + const { getTransformType, getTransformPath } = require('../transform-support'); + const path = require('path'); - let root = process.cwd() + `/transforms/${options.name}/`; - let transformPath = root + 'index.js'; + let transformPath = getTransformPath(process.cwd(), options.name); + let root = path.dirname(transformPath); let transformType = getTransformType(transformPath); return { @@ -12,7 +13,7 @@ function transformDetails(options) { root, transformPath, transformType, - fixtureDir: root + '__testfixtures__/', + fixtureDir: path.join(root, '__testfixtures__/'), }; } diff --git a/src/transform-support.js b/src/transform-support.js index 315e38e..4afbb84 100644 --- a/src/transform-support.js +++ b/src/transform-support.js @@ -1,12 +1,12 @@ 'use strict'; -function getTransformType(transformPath) { - const fs = require('fs-extra'); +function getTransformPath(root, transformName) { + const path = require('path'); - if (!fs.existsSync(transformPath)) { - throw new Error(`Transform ${transformPath} not found.`); - } + return require.resolve(path.join(root, 'transforms', transformName)); +} +function getTransformType(transformPath) { return require(transformPath).type || 'js'; // fallback to 'js' if `type` export does not exist } @@ -30,4 +30,5 @@ module.exports = { getParser: getJSCodeshiftParser, }, getTransformType, + getTransformPath, };