diff --git a/.eslintrc.js b/.eslintrc.js index 008c09a6..20afbd86 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,3 +1,4 @@ +/* eslint-env node */ module.exports = { root: true, parserOptions: { diff --git a/blueprints/-addon-import.js b/blueprints/-addon-import.js new file mode 100644 index 00000000..27cf4f7f --- /dev/null +++ b/blueprints/-addon-import.js @@ -0,0 +1,48 @@ +'use strict'; + +const stringUtil = require('ember-cli-string-utils'); +const path = require('path'); +const inflector = require('inflection'); + +module.exports = { + description: 'Generates an import wrapper.', + + fileMapTokens: function () { + return { + __name__: function (options) { + return options.dasherizedModuleName; + }, + __path__: function (options) { + return inflector.pluralize(options.locals.blueprintName); + }, + __root__: function (options) { + if (options.inRepoAddon) { + return path.join('lib', options.inRepoAddon, 'app'); + } + return 'app'; + }, + }; + }, + + locals: function (options) { + let addonRawName = options.inRepoAddon ? options.inRepoAddon : options.project.name(); + let addonName = stringUtil.dasherize(addonRawName); + let fileName = stringUtil.dasherize(options.entity.name); + let blueprintName = options.originBlueprintName; + let modulePathSegments = [ + addonName, + inflector.pluralize(options.originBlueprintName), + fileName, + ]; + + if (blueprintName.match(/-addon/)) { + blueprintName = blueprintName.substr(0, blueprintName.indexOf('-addon')); + modulePathSegments = [addonName, inflector.pluralize(blueprintName), fileName]; + } + + return { + modulePath: modulePathSegments.join('/'), + blueprintName: blueprintName, + }; + }, +}; diff --git a/blueprints/component-addon/files/__root__/__path__/__name__.js b/blueprints/component-addon/files/__root__/__path__/__name__.js new file mode 100644 index 00000000..71a8b71c --- /dev/null +++ b/blueprints/component-addon/files/__root__/__path__/__name__.js @@ -0,0 +1 @@ +export { default } from '<%= modulePath %>'; \ No newline at end of file diff --git a/blueprints/component-addon/index.js b/blueprints/component-addon/index.js new file mode 100644 index 00000000..a3f30e40 --- /dev/null +++ b/blueprints/component-addon/index.js @@ -0,0 +1,76 @@ +'use strict'; + +const path = require('path'); +const stringUtil = require('ember-cli-string-utils'); +const getPathOption = require('ember-cli-get-component-path-option'); +const normalizeEntityName = require('ember-cli-normalize-entity-name'); +const useEditionDetector = require('../edition-detector'); + +module.exports = useEditionDetector({ + description: 'Generates a component.', + + fileMapTokens: function () { + return { + __path__: function (options) { + if (options.pod) { + return path.join(options.podPath, options.locals.path, options.dasherizedModuleName); + } + return 'components'; + }, + __name__: function (options) { + if (options.pod) { + return 'component'; + } + return options.dasherizedModuleName; + }, + __root__: function (options) { + if (options.inRepoAddon) { + return path.join('lib', options.inRepoAddon, 'app'); + } + return 'app'; + }, + __templatepath__: function (options) { + if (options.pod) { + return path.join(options.podPath, options.locals.path, options.dasherizedModuleName); + } + return 'templates/components'; + }, + __templatename__: function (options) { + if (options.pod) { + return 'template'; + } + return options.dasherizedModuleName; + }, + }; + }, + + normalizeEntityName: function (entityName) { + return normalizeEntityName(entityName); + }, + + locals: function (options) { + let addonRawName = options.inRepoAddon ? options.inRepoAddon : options.project.name(); + let addonName = stringUtil.dasherize(addonRawName); + let fileName = stringUtil.dasherize(options.entity.name); + let importPathName = [addonName, 'components', fileName].join('/'); + let templatePath = ''; + + if (options.pod) { + importPathName = [addonName, 'components', fileName, 'component'].join('/'); + } + + if (this.project.isEmberCLIAddon() || (options.inRepoAddon && !options.inDummy)) { + if (options.pod) { + templatePath = './template'; + } else { + templatePath = [addonName, 'templates/components', fileName].join('/'); + } + } + + return { + modulePath: importPathName, + templatePath, + path: getPathOption(options), + }; + }, +}); diff --git a/blueprints/component-addon/native-files/__root__/__path__/__name__.js b/blueprints/component-addon/native-files/__root__/__path__/__name__.js new file mode 100644 index 00000000..71a8b71c --- /dev/null +++ b/blueprints/component-addon/native-files/__root__/__path__/__name__.js @@ -0,0 +1 @@ +export { default } from '<%= modulePath %>'; \ No newline at end of file diff --git a/blueprints/component-class-addon/files/__root__/__path__/__name__.js b/blueprints/component-class-addon/files/__root__/__path__/__name__.js new file mode 100644 index 00000000..71a8b71c --- /dev/null +++ b/blueprints/component-class-addon/files/__root__/__path__/__name__.js @@ -0,0 +1 @@ +export { default } from '<%= modulePath %>'; \ No newline at end of file diff --git a/blueprints/component-class-addon/index.js b/blueprints/component-class-addon/index.js new file mode 100644 index 00000000..19272db5 --- /dev/null +++ b/blueprints/component-class-addon/index.js @@ -0,0 +1,54 @@ +'use strict'; + +const path = require('path'); +const stringUtil = require('ember-cli-string-utils'); +const getPathOption = require('ember-cli-get-component-path-option'); +const normalizeEntityName = require('ember-cli-normalize-entity-name'); +const useEditionDetector = require('../edition-detector'); + +module.exports = useEditionDetector({ + description: 'Generates a component class.', + + fileMapTokens: function () { + return { + __path__: function (options) { + if (options.pod) { + return path.join(options.podPath, options.locals.path, options.dasherizedModuleName); + } + return 'components'; + }, + __name__: function (options) { + if (options.pod) { + return 'component'; + } + return options.dasherizedModuleName; + }, + __root__: function (options) { + if (options.inRepoAddon) { + return path.join('lib', options.inRepoAddon, 'app'); + } + return 'app'; + }, + }; + }, + + normalizeEntityName: function (entityName) { + return normalizeEntityName(entityName); + }, + + locals: function (options) { + let addonRawName = options.inRepoAddon ? options.inRepoAddon : options.project.name(); + let addonName = stringUtil.dasherize(addonRawName); + let fileName = stringUtil.dasherize(options.entity.name); + let importPathName = [addonName, 'components', fileName].join('/'); + + if (options.pod) { + importPathName = [addonName, 'components', fileName, 'component'].join('/'); + } + + return { + modulePath: importPathName, + path: getPathOption(options), + }; + }, +}); diff --git a/blueprints/component-class-addon/native-files/__root__/__path__/__name__.js b/blueprints/component-class-addon/native-files/__root__/__path__/__name__.js new file mode 100644 index 00000000..71a8b71c --- /dev/null +++ b/blueprints/component-class-addon/native-files/__root__/__path__/__name__.js @@ -0,0 +1 @@ +export { default } from '<%= modulePath %>'; \ No newline at end of file diff --git a/blueprints/component-class/files/__root__/__path__/__name__.js b/blueprints/component-class/files/__root__/__path__/__name__.js new file mode 100644 index 00000000..777e6155 --- /dev/null +++ b/blueprints/component-class/files/__root__/__path__/__name__.js @@ -0,0 +1,3 @@ +<%= importComponent %> +<%= importTemplate %> +export default <%= defaultExport %> diff --git a/blueprints/component-class/index.js b/blueprints/component-class/index.js new file mode 100644 index 00000000..697d5b0b --- /dev/null +++ b/blueprints/component-class/index.js @@ -0,0 +1,175 @@ +'use strict'; + +const path = require('path'); +const SilentError = require('silent-error'); +const stringUtil = require('ember-cli-string-utils'); +const pathUtil = require('ember-cli-path-utils'); +const getPathOption = require('ember-cli-get-component-path-option'); +const normalizeEntityName = require('ember-cli-normalize-entity-name'); +const { EOL } = require('os'); +const { has } = require('@ember/edition-utils'); + +const OCTANE = has('octane'); + +// TODO: this should be reading from the @ember/canary-features module +// need to refactor broccoli/features.js to be able to work more similarly +// to https://github.com/emberjs/data/pull/6231 +const EMBER_GLIMMER_SET_COMPONENT_TEMPLATE = true; + +// intentionally avoiding use-edition-detector +module.exports = { + description: 'Generates a component class.', + + availableOptions: [ + { + name: 'path', + type: String, + default: 'components', + aliases: [{ 'no-path': '' }], + }, + { + name: 'component-class', + type: ['@ember/component', '@glimmer/component', '@ember/component/template-only'], + default: OCTANE ? '@glimmer/component' : '@ember/component', + aliases: [ + { cc: '@ember/component' }, + { gc: '@glimmer/component' }, + { tc: '@ember/component/template-only' }, + ], + }, + { + name: 'component-structure', + type: OCTANE ? ['flat', 'nested', 'classic'] : ['classic'], + default: OCTANE ? 'flat' : 'classic', + aliases: OCTANE ? [{ fs: 'flat' }, { ns: 'nested' }, { cs: 'classic' }] : [{ cs: 'classic' }], + }, + ], + + init() { + this._super && this._super.init.apply(this, arguments); + let isOctane = has('octane'); + + this.availableOptions.forEach((option) => { + if (option.name === 'component-class') { + if (isOctane) { + option.default = '@glimmer/component'; + } else { + option.default = '@ember/component'; + } + } else if (option.name === 'component-structure') { + if (isOctane) { + option.type = ['flat', 'nested', 'classic']; + option.default = 'flat'; + option.aliases = [{ fs: 'flat' }, { ns: 'nested' }, { cs: 'classic' }]; + } else { + option.type = ['classic']; + option.default = 'classic'; + option.aliases = [{ cs: 'classic' }]; + } + } + }); + + this.EMBER_GLIMMER_SET_COMPONENT_TEMPLATE = EMBER_GLIMMER_SET_COMPONENT_TEMPLATE || isOctane; + }, + + install() { + if (!this.EMBER_GLIMMER_SET_COMPONENT_TEMPLATE) { + throw new SilentError( + 'Usage of `ember generate component-class` is only available on canary' + ); + } + + return this._super.install.apply(this, arguments); + }, + + fileMapTokens(options) { + let commandOptions = this.options; + + if (commandOptions.pod) { + return { + __path__() { + return path.join(options.podPath, options.locals.path, options.dasherizedModuleName); + }, + __name__() { + return 'component'; + }, + }; + } else if ( + commandOptions.componentStructure === 'classic' || + commandOptions.componentStructure === 'flat' + ) { + return { + __path__() { + return 'components'; + }, + }; + } else if (commandOptions.componentStructure === 'nested') { + return { + __path__() { + return `components/${options.dasherizedModuleName}`; + }, + __name__() { + return 'index'; + }, + }; + } + }, + + normalizeEntityName(entityName) { + return normalizeEntityName( + entityName.replace(/\.js$/, '') //Prevent generation of ".js.js" files + ); + }, + + locals(options) { + let sanitizedModuleName = options.entity.name.replace(/\//g, '-'); + let classifiedModuleName = stringUtil.classify(sanitizedModuleName); + + let templatePath = ''; + let importComponent = ''; + let importTemplate = ''; + let defaultExport = ''; + + // if we're in an addon, build import statement + if (options.project.isEmberCLIAddon() || (options.inRepoAddon && !options.inDummy)) { + if (options.pod) { + templatePath = './template'; + } else { + templatePath = + pathUtil.getRelativeParentPath(options.entity.name) + + 'templates/components/' + + stringUtil.dasherize(options.entity.name); + } + } + + let componentClass = options.componentClass; + + switch (componentClass) { + case '@ember/component': + importComponent = `import Component from '@ember/component';`; + if (templatePath) { + importTemplate = `import layout from '${templatePath}';${EOL}`; + defaultExport = `Component.extend({${EOL} layout${EOL}});`; + } else { + defaultExport = `Component.extend({${EOL}});`; + } + break; + case '@glimmer/component': + importComponent = `import Component from '@glimmer/component';`; + defaultExport = `class ${classifiedModuleName}Component extends Component {\n}`; + break; + case '@ember/component/template-only': + importComponent = `import templateOnly from '@ember/component/template-only';`; + defaultExport = `templateOnly();`; + break; + } + + return { + importTemplate, + importComponent, + defaultExport, + path: getPathOption(options), + componentClass, + }; + }, +}; diff --git a/blueprints/component-test/index.js b/blueprints/component-test/index.js new file mode 100644 index 00000000..dbd546ef --- /dev/null +++ b/blueprints/component-test/index.js @@ -0,0 +1,81 @@ +'use strict'; + +const path = require('path'); +const stringUtil = require('ember-cli-string-utils'); +const getPathOption = require('ember-cli-get-component-path-option'); + +const useTestFrameworkDetector = require('../test-framework-detector'); + +function invocationFor(options) { + let parts = options.entity.name.split('/'); + return parts.map((p) => stringUtil.classify(p)).join('::'); +} + +module.exports = useTestFrameworkDetector({ + description: 'Generates a component integration or unit test.', + + availableOptions: [ + { + name: 'test-type', + type: ['integration', 'unit'], + default: 'integration', + aliases: [ + { i: 'integration' }, + { u: 'unit' }, + { integration: 'integration' }, + { unit: 'unit' }, + ], + }, + ], + + fileMapTokens: function () { + return { + __root__() { + return 'tests'; + }, + __testType__(options) { + return options.locals.testType || 'integration'; + }, + __path__(options) { + if (options.pod) { + return path.join(options.podPath, options.locals.path, options.dasherizedModuleName); + } + return 'components'; + }, + }; + }, + + locals: function (options) { + let dasherizedModuleName = stringUtil.dasherize(options.entity.name); + let componentPathName = dasherizedModuleName; + let testType = options.testType || 'integration'; + + let friendlyTestDescription = [ + testType === 'unit' ? 'Unit' : 'Integration', + 'Component', + dasherizedModuleName, + ].join(' | '); + + if (options.pod && options.path !== 'components' && options.path !== '') { + componentPathName = [options.path, dasherizedModuleName].filter(Boolean).join('/'); + } + + let templateInvocation = invocationFor(options); + let componentName = templateInvocation; + let openComponent = (descriptor) => `<${descriptor}>`; + let closeComponent = (descriptor) => ``; + let selfCloseComponent = (descriptor) => `<${descriptor} />`; + + return { + path: getPathOption(options), + testType: testType, + componentName, + componentPathName, + templateInvocation, + openComponent, + closeComponent, + selfCloseComponent, + friendlyTestDescription, + }; + } +}); \ No newline at end of file diff --git a/blueprints/component-test/mocha-files/__root__/__testType__/__path__/__test__.ts b/blueprints/component-test/mocha-files/__root__/__testType__/__path__/__test__.ts new file mode 100644 index 00000000..e2b6cd3f --- /dev/null +++ b/blueprints/component-test/mocha-files/__root__/__testType__/__path__/__test__.ts @@ -0,0 +1,27 @@ +import { expect } from 'chai'; +import { describe, it } from 'mocha'; +import { setupRenderingTest } from 'ember-mocha'; +import { render } from '@ember/test-helpers'; +import { hbs } from 'ember-cli-htmlbars'; + +describe('<%= friendlyTestDescription %>', function() { + setupRenderingTest(); + + it('renders', async function() { + // Set any properties with this.set('myProperty', 'value'); + // Handle any actions with this.set('myAction', function(val) { ... }); + + await render(hbs`<%= selfCloseComponent(componentName) %>`); + + expect(this.element.textContent.trim()).to.equal(''); + + // Template block usage: + await render(hbs` + <%= openComponent(componentName) %> + template block text + <%= closeComponent(componentName) %> + `); + + expect(this.element.textContent.trim()).to.equal('template block text'); + }); +}); \ No newline at end of file diff --git a/blueprints/component-test/qunit-files/__root__/__testType__/__path__/__test__.ts b/blueprints/component-test/qunit-files/__root__/__testType__/__path__/__test__.ts new file mode 100644 index 00000000..6fd18705 --- /dev/null +++ b/blueprints/component-test/qunit-files/__root__/__testType__/__path__/__test__.ts @@ -0,0 +1,26 @@ +import { module, test } from 'qunit'; +import { setupRenderingTest } from 'ember-qunit'; +import { render } from '@ember/test-helpers'; +import { hbs } from 'ember-cli-htmlbars'; + +module('Integration | Component | <%= dasherizedModuleName %>', function(hooks) { + setupRenderingTest(hooks); + + test('it renders', async function(assert) { + // Set any properties with this.set('myProperty', 'value'); + // Handle any actions with this.set('myAction', function(val) { ... }); + + await render(hbs`<<%= templateInvocation %> />`); + + assert.equal(this.element.textContent.trim(), ''); + + // Template block usage: + await render(hbs` + <<%= templateInvocation %>> + template block text + > + `); + + assert.equal(this.element.textContent.trim(), 'template block text'); + }); +}); diff --git a/blueprints/component/files/__root__/__path__/__name__.ts b/blueprints/component/files/__root__/__path__/__name__.ts new file mode 100644 index 00000000..777e6155 --- /dev/null +++ b/blueprints/component/files/__root__/__path__/__name__.ts @@ -0,0 +1,3 @@ +<%= importComponent %> +<%= importTemplate %> +export default <%= defaultExport %> diff --git a/blueprints/component/files/__root__/__templatepath__/__templatename__.hbs b/blueprints/component/files/__root__/__templatepath__/__templatename__.hbs new file mode 100644 index 00000000..fb5c4b15 --- /dev/null +++ b/blueprints/component/files/__root__/__templatepath__/__templatename__.hbs @@ -0,0 +1 @@ +{{yield}} \ No newline at end of file diff --git a/blueprints/component/glimmer-files/__root__/__path__/__name__.hbs b/blueprints/component/glimmer-files/__root__/__path__/__name__.hbs new file mode 100644 index 00000000..fb5c4b15 --- /dev/null +++ b/blueprints/component/glimmer-files/__root__/__path__/__name__.hbs @@ -0,0 +1 @@ +{{yield}} \ No newline at end of file diff --git a/blueprints/component/glimmer-files/__root__/__path__/__name__.ts b/blueprints/component/glimmer-files/__root__/__path__/__name__.ts new file mode 100644 index 00000000..d5b3ea97 --- /dev/null +++ b/blueprints/component/glimmer-files/__root__/__path__/__name__.ts @@ -0,0 +1,7 @@ +import Component from '@glimmer/component'; + +interface <%= componentName %>Args { +} + +export default class <%= componentName %> extends Component<<%= componentName %>Args> { +}; \ No newline at end of file diff --git a/blueprints/component/index.js b/blueprints/component/index.js new file mode 100644 index 00000000..6b81f8d2 --- /dev/null +++ b/blueprints/component/index.js @@ -0,0 +1,97 @@ +'use strict'; + +const path = require('path'); +const stringUtil = require('ember-cli-string-utils'); +const pathUtil = require('ember-cli-path-utils'); +const getPathOption = require('ember-cli-get-component-path-option'); +const normalizeEntityName = require('ember-cli-normalize-entity-name'); +const EOL = require('os').EOL; + +function componentNameFor(options) { + let parts = options.entity.name.split('/'); + return parts.map((p) => stringUtil.classify(p)).join(""); +} + +module.exports = { + description: 'Generates a component.', + + availableOptions: [ + { + name: 'path', + type: String, + default: 'components', + aliases: [{ 'no-path': '' }], + }, + ], + + filesPath: function() { + let filesDirectory = 'files'; + let dependencies = this.project.dependencies(); + + if ('@glimmer/component' in dependencies) { + filesDirectory = 'glimmer-files'; + } + + return path.join(this.path, filesDirectory); + }, + + fileMapTokens: function() { + return { + __path__: function(options) { + if (options.pod) { + return path.join(options.podPath, options.locals.path, options.dasherizedModuleName); + } else { + return 'components'; + } + }, + __templatepath__: function(options) { + if (options.pod) { + return path.join(options.podPath, options.locals.path, options.dasherizedModuleName); + } + return 'templates/components'; + }, + __templatename__: function(options) { + if (options.pod) { + return 'template'; + } + return options.dasherizedModuleName; + }, + }; + }, + + normalizeEntityName: function(entityName) { + return normalizeEntityName(entityName); + }, + + locals: function(options) { + let templatePath = ''; + let importTemplate = ''; + let contents = ''; + + let classifiedModuleName = stringUtil.dasherize(options.entity.name); + + let componentName = componentNameFor(options); + + // if we're in an addon, build import statement + if (options.project.isEmberCLIAddon() || (options.inRepoAddon && !options.inDummy)) { + if (options.pod) { + templatePath = './template'; + } else { + templatePath = + pathUtil.getRelativeParentPath(options.entity.name) + + 'templates/components/' + + classifiedModuleName; + } + importTemplate = '// @ts-ignore: Ignore import of compiled template' + EOL + 'import layout from \'' + templatePath + '\';' + EOL; + contents = EOL + ' layout = layout;'; + } + + return { + importTemplate: importTemplate, + contents: contents, + path: getPathOption(options), + classifiedModuleName, + componentName + }; + }, +}; diff --git a/blueprints/edition-detector.js b/blueprints/edition-detector.js new file mode 100644 index 00000000..4e37fcf1 --- /dev/null +++ b/blueprints/edition-detector.js @@ -0,0 +1,13 @@ +'use strict'; + +const { has } = require('@ember/edition-utils'); +const path = require('path'); + +module.exports = function (blueprint) { + blueprint.filesPath = function () { + let rootPath = has('octane') ? 'native-files' : 'files'; + return path.join(this.path, rootPath); + }; + + return blueprint; +}; diff --git a/blueprints/helper-test/mocha-files/tests/__testType__/helpers/__name__-test.ts b/blueprints/helper-test/mocha-files/tests/__testType__/helpers/__name__-test.ts index 8a36c684..4088a058 100644 --- a/blueprints/helper-test/mocha-files/tests/__testType__/helpers/__name__-test.ts +++ b/blueprints/helper-test/mocha-files/tests/__testType__/helpers/__name__-test.ts @@ -1,7 +1,7 @@ import { expect } from 'chai'; <% if (testType == 'integration') { %>import { describe, it } from 'mocha'; import { setupComponentTest } from 'ember-mocha'; -import hbs from 'htmlbars-inline-precompile'; +import { hbs } from 'ember-cli-htmlbars'; describe('<%= friendlyTestName %>', function() { setupComponentTest('<%= dasherizedModuleName %>', { @@ -21,7 +21,7 @@ describe('<%= friendlyTestName %>', function() { this.render(hbs`{{<%= dasherizedModuleName %> inputValue}}`); - expect(this.$().text().trim()).to.equal('1234'); + expect(this.element.text().trim()).to.equal('1234'); }); }); <% } else if (testType == 'unit') { %>import { describe, it } from 'mocha'; diff --git a/blueprints/helper-test/qunit-files/tests/__testType__/helpers/__name__-test.ts b/blueprints/helper-test/qunit-files/tests/__testType__/helpers/__name__-test.ts index 28a173e3..d894396b 100644 --- a/blueprints/helper-test/qunit-files/tests/__testType__/helpers/__name__-test.ts +++ b/blueprints/helper-test/qunit-files/tests/__testType__/helpers/__name__-test.ts @@ -1,7 +1,7 @@ <% if (testType === 'integration') { %>import { module, test } from 'qunit'; import { setupRenderingTest } from 'ember-qunit'; import { render } from '@ember/test-helpers'; -import hbs from 'htmlbars-inline-precompile'; +import { hbs } from 'ember-cli-htmlbars'; module('<%= friendlyTestName %>', function(hooks) { setupRenderingTest(hooks); diff --git a/jsconfig.json b/jsconfig.json new file mode 100644 index 00000000..f408cac8 --- /dev/null +++ b/jsconfig.json @@ -0,0 +1 @@ +{"compilerOptions":{"target":"es6","experimentalDecorators":true},"exclude":["node_modules","bower_components","tmp","vendor",".git","dist"]} \ No newline at end of file diff --git a/lib/utilities/update-paths-for-addon.js b/lib/utilities/update-paths-for-addon.js index 02ddcb05..8edf7e6d 100644 --- a/lib/utilities/update-paths-for-addon.js +++ b/lib/utilities/update-paths-for-addon.js @@ -14,10 +14,10 @@ module.exports = function(paths, addonName, appName, options) { appStarPaths = paths[appNameStar] = paths[appNameStar] || []; if (options.removePaths) { - if (paths.hasOwnProperty(addonName)) { + if (Object.prototype.hasOwnProperty.call(paths, addonName)) { delete paths[addonName]; } - if (paths.hasOwnProperty(addonNameStar)) { + if (Object.prototype.hasOwnProperty.call(paths, addonNameStar)) { delete paths[addonNameStar] } let addonAppPathIndex = appStarPaths.indexOf([addonAppPath, '*'].join('/')); @@ -26,16 +26,16 @@ module.exports = function(paths, addonName, appName, options) { paths[appNameStar] = appStarPaths; } } else { - if (!paths.hasOwnProperty(addonName)) { + if (!Object.prototype.hasOwnProperty.call(paths, addonName)) { paths[addonName] = [ addonAddonPath ]; } - if (!paths.hasOwnProperty(addonNameStar)) { + if (!Object.prototype.hasOwnProperty.call(paths, addonNameStar)) { paths[addonNameStar] = [ [addonAddonPath, '*'].join('/') ]; } - if (!paths.hasOwnProperty(addonTestSupportPath)) { + if (!Object.prototype.hasOwnProperty.call(paths, addonTestSupportPath)) { paths[addonTestSupportPath] = [ [addonPath, 'addon-test-support'].join('/') ]; } - if (!paths.hasOwnProperty(addonTestSupportStarPath)) { + if (!Object.prototype.hasOwnProperty.call(paths, addonTestSupportStarPath)) { paths[addonTestSupportStarPath] = [ [addonPath, 'addon-test-support', '*'].join('/') ]; } if (appStarPaths.indexOf(addonAppPath) === -1) { diff --git a/node-tests/blueprints/component-addon-test.js b/node-tests/blueprints/component-addon-test.js new file mode 100644 index 00000000..b2f898f3 --- /dev/null +++ b/node-tests/blueprints/component-addon-test.js @@ -0,0 +1,34 @@ +'use strict'; + +const blueprintHelpers = require('ember-cli-blueprint-test-helpers/helpers'); +const setupTestHooks = blueprintHelpers.setupTestHooks; +const emberNew = blueprintHelpers.emberNew; +const emberGenerateDestroy = blueprintHelpers.emberGenerateDestroy; + +const chai = require('ember-cli-blueprint-test-helpers/chai'); +const expect = chai.expect; + +describe('Blueprint: component-addon', function () { + setupTestHooks(this); + + describe('in addon', function () { + beforeEach(function () { + return emberNew({ target: 'addon' }); + }); + + it('component-addon foo', function () { + return emberGenerateDestroy(['component-addon', 'foo'], (_file) => { + expect(_file('app/components/foo.js')).to.contain( + "export { default } from 'my-addon/components/foo';" + ); + }); + }); + it('component-addon foo-bar', function () { + return emberGenerateDestroy(['component-addon', 'foo-bar'], (_file) => { + expect(_file('app/components/foo-bar.js')).to.contain( + "export { default } from 'my-addon/components/foo-bar';" + ); + }); + }); + }); +}); diff --git a/node-tests/blueprints/component-class-addon-test.js b/node-tests/blueprints/component-class-addon-test.js new file mode 100644 index 00000000..1dcdd80c --- /dev/null +++ b/node-tests/blueprints/component-class-addon-test.js @@ -0,0 +1,34 @@ +'use strict'; + +const blueprintHelpers = require('ember-cli-blueprint-test-helpers/helpers'); +const setupTestHooks = blueprintHelpers.setupTestHooks; +const emberNew = blueprintHelpers.emberNew; +const emberGenerateDestroy = blueprintHelpers.emberGenerateDestroy; + +const chai = require('ember-cli-blueprint-test-helpers/chai'); +const expect = chai.expect; + +describe('Blueprint: component-class-addon', function () { + setupTestHooks(this); + + describe('in addon', function () { + beforeEach(function () { + return emberNew({ target: 'addon' }); + }); + + it('component-addon foo', function () { + return emberGenerateDestroy(['component-class-addon', 'foo'], (_file) => { + expect(_file('app/components/foo.js')).to.contain( + "export { default } from 'my-addon/components/foo';" + ); + }); + }); + it('component-addon foo-bar', function () { + return emberGenerateDestroy(['component-class-addon', 'foo-bar'], (_file) => { + expect(_file('app/components/foo-bar.js')).to.contain( + "export { default } from 'my-addon/components/foo-bar';" + ); + }); + }); + }); +}); diff --git a/node-tests/blueprints/component-class-test.js b/node-tests/blueprints/component-class-test.js new file mode 100644 index 00000000..72d588e4 --- /dev/null +++ b/node-tests/blueprints/component-class-test.js @@ -0,0 +1,730 @@ +'use strict'; + +const blueprintHelpers = require('ember-cli-blueprint-test-helpers/helpers'); +const setupTestHooks = blueprintHelpers.setupTestHooks; +const emberNew = blueprintHelpers.emberNew; +const emberGenerateDestroy = blueprintHelpers.emberGenerateDestroy; +const setupPodConfig = blueprintHelpers.setupPodConfig; +const modifyPackages = blueprintHelpers.modifyPackages; + +const chai = require('ember-cli-blueprint-test-helpers/chai'); +const expect = chai.expect; + +const generateFakePackageManifest = require('../helpers/generate-fake-package-manifest'); +const fixture = require('../helpers/fixture'); + +const setupTestEnvironment = require('../helpers/setup-test-environment'); +const enableOctane = setupTestEnvironment.enableOctane; + +const { EMBER_SET_COMPONENT_TEMPLATE } = require('../../blueprints/component'); + +const glimmerComponentContents = `import Component from '@glimmer/component'; + +export default class FooComponent extends Component { +} +`; + +const emberComponentContents = `import Component from '@ember/component'; + +export default Component.extend({ +}); +`; + +const templateOnlyContents = `import templateOnly from '@ember/component/template-only'; + +export default templateOnly(); +`; + +describe('Blueprint: component-class', function () { + setupTestHooks(this); + + describe('in app', function () { + beforeEach(function () { + return emberNew() + .then(() => + modifyPackages([ + { name: 'ember-qunit', delete: true }, + { name: 'ember-cli-qunit', dev: true }, + ]) + ) + .then(() => generateFakePackageManifest('ember-cli-qunit', '4.1.0')); + }); + + it('component-class foo', function () { + return emberGenerateDestroy(['component-class', 'foo'], (_file) => { + expect(_file('app/components/foo.js')).to.equal(emberComponentContents); + }); + }); + + if (EMBER_SET_COMPONENT_TEMPLATE) { + // classic default + it('component-class foo --component-structure=classic --component-class=@ember/component', function () { + return emberGenerateDestroy( + [ + 'component-class', + 'foo', + '--component-structure', + 'classic', + '--component-class', + '@ember/component', + ], + (_file) => { + expect(_file('app/components/foo.js')).to.equal(emberComponentContents); + } + ); + }); + + // Octane default + it('component-class foo --component-structure=flat --component-class=@glimmer/component', function () { + return emberGenerateDestroy( + [ + 'component-class', + '--component-structure', + 'flat', + '--component-class', + '@glimmer/component', + 'foo', + ], + (_file) => { + expect(_file('app/components/foo.js')).to.equal(glimmerComponentContents); + } + ); + }); + + it('component-class foo --component-structure=flat', function () { + return emberGenerateDestroy( + ['component-class', '--component-structure', 'flat', 'foo'], + (_file) => { + expect(_file('app/components/foo.js')).to.equal(emberComponentContents); + } + ); + }); + + it('component-class foo --component-structure=nested', function () { + return emberGenerateDestroy( + ['component-class', '--component-structure', 'nested', 'foo'], + (_file) => { + expect(_file('app/components/foo/index.js')).to.equal(emberComponentContents); + } + ); + }); + + it('component-class foo --component-structure=classic', function () { + return emberGenerateDestroy( + ['component-class', '--component-structure', 'classic', 'foo'], + (_file) => { + expect(_file('app/components/foo.js')).to.equal(emberComponentContents); + } + ); + }); + + it('component-class foo --component-class=@ember/component', function () { + return emberGenerateDestroy( + ['component-class', '--component-class', '@ember/component', 'foo'], + (_file) => { + expect(_file('app/components/foo.js')).to.equal(emberComponentContents); + } + ); + }); + + it('component-class foo --component-class=@glimmer/component', function () { + return emberGenerateDestroy( + ['component-class', '--component-class', '@glimmer/component', 'foo'], + (_file) => { + expect(_file('app/components/foo.js')).to.equal(glimmerComponentContents); + } + ); + }); + + it('component-class foo --component-class=@ember/component/template-only', function () { + return emberGenerateDestroy( + ['component-class', '--component-class', '@ember/component/template-only', 'foo'], + (_file) => { + expect(_file('app/components/foo.js')).to.equal(templateOnlyContents); + } + ); + }); + } + + it('component-class x-foo', function () { + return emberGenerateDestroy(['component-class', 'x-foo'], (_file) => { + expect(_file('app/components/x-foo.js')).to.equal(fixture('component/component-dash.js')); + }); + }); + + it('component-class foo/x-foo', function () { + return emberGenerateDestroy(['component-class', 'foo/x-foo'], (_file) => { + expect(_file('app/components/foo/x-foo.js')).to.equal( + fixture('component/component-nested.js') + ); + }); + }); + + it('component-class x-foo --path foo', function () { + return emberGenerateDestroy(['component-class', 'x-foo', '--path', 'foo'], (_file) => { + expect(_file('app/components/x-foo.js')).to.equal(fixture('component/component-dash.js')); + }); + }); + + it('component-class foo.js', function () { + return emberGenerateDestroy(['component-class', 'foo.js'], (_file) => { + expect(_file('app/components/foo.js.js')).to.not.exist; + expect(_file('app/components/foo.js')).to.equal(fixture('component/component.js')); + }); + }); + + it('component-class x-foo --pod', function () { + return emberGenerateDestroy(['component-class', 'x-foo', '--pod'], (_file) => { + expect(_file('app/components/x-foo/component.js')).to.equal( + fixture('component/component-dash.js') + ); + }); + }); + + it('component-class foo/x-foo --pod', function () { + return emberGenerateDestroy(['component-class', 'foo/x-foo', '--pod'], (_file) => { + expect(_file('app/components/foo/x-foo/component.js')).to.equal( + fixture('component/component-nested.js') + ); + }); + }); + + it('component-class x-foo --pod --path foo', function () { + return emberGenerateDestroy( + ['component-class', 'x-foo', '--pod', '--path', 'foo'], + (_file) => { + expect(_file('app/foo/x-foo/component.js')).to.equal( + fixture('component/component-dash.js') + ); + } + ); + }); + + it('component-class foo/x-foo --pod --path bar', function () { + return emberGenerateDestroy( + ['component-class', 'foo/x-foo', '--pod', '--path', 'bar'], + (_file) => { + expect(_file('app/bar/foo/x-foo/component.js')).to.equal( + fixture('component/component-nested.js') + ); + } + ); + }); + + it('component-class x-foo --pod --path bar/foo', function () { + return emberGenerateDestroy( + ['component-class', 'x-foo', '--pod', '--path', 'bar/foo'], + (_file) => { + expect(_file('app/bar/foo/x-foo/component.js')).to.equal( + fixture('component/component-dash.js') + ); + } + ); + }); + + it('component-class foo/x-foo --pod --path bar/baz', function () { + return emberGenerateDestroy( + ['component-class', 'foo/x-foo', '--pod', '--path', 'bar/baz'], + (_file) => { + expect(_file('app/bar/baz/foo/x-foo/component.js')).to.equal( + fixture('component/component-nested.js') + ); + } + ); + }); + + it('component-class x-foo --pod -no-path', function () { + return emberGenerateDestroy(['component-class', 'x-foo', '--pod', '-no-path'], (_file) => { + expect(_file('app/x-foo/component.js')).to.equal(fixture('component/component-dash.js')); + }); + }); + + it('component-class foo/x-foo --pod -no-path', function () { + return emberGenerateDestroy( + ['component-class', 'foo/x-foo', '--pod', '-no-path'], + (_file) => { + expect(_file('app/foo/x-foo/component.js')).to.equal( + fixture('component/component-nested.js') + ); + } + ); + }); + + it('component-class x-foo.js --pod', function () { + return emberGenerateDestroy(['component-class', 'x-foo.js', '--pod'], (_file) => { + expect(_file('app/components/x-foo.js/component.js')).to.not.exist; + expect(_file('app/components/x-foo/component.js')).to.equal( + fixture('component/component-dash.js') + ); + }); + }); + + describe('with podModulePrefix', function () { + beforeEach(function () { + setupPodConfig({ podModulePrefix: true }); + }); + + it('component-class foo --pod', function () { + return emberGenerateDestroy(['component-class', 'foo', '--pod'], (_file) => { + expect(_file('app/pods/components/foo/component.js')).to.equal( + fixture('component/component.js') + ); + }); + }); + + it('component-class x-foo --pod', function () { + return emberGenerateDestroy(['component-class', 'x-foo', '--pod'], (_file) => { + expect(_file('app/pods/components/x-foo/component.js')).to.equal( + fixture('component/component-dash.js') + ); + }); + }); + + it('component-class foo/x-foo --pod', function () { + return emberGenerateDestroy(['component-class', 'foo/x-foo', '--pod'], (_file) => { + expect(_file('app/pods/components/foo/x-foo/component.js')).to.equal( + fixture('component/component-nested.js') + ); + }); + }); + + it('component-class x-foo --pod --path foo', function () { + return emberGenerateDestroy( + ['component-class', 'x-foo', '--pod', '--path', 'foo'], + (_file) => { + expect(_file('app/pods/foo/x-foo/component.js')).to.equal( + fixture('component/component-dash.js') + ); + } + ); + }); + + it('component-class foo/x-foo --pod --path bar', function () { + return emberGenerateDestroy( + ['component-class', 'foo/x-foo', '--pod', '--path', 'bar'], + (_file) => { + expect(_file('app/pods/bar/foo/x-foo/component.js')).to.equal( + fixture('component/component-nested.js') + ); + } + ); + }); + + it('component-class x-foo --pod --path bar/foo', function () { + return emberGenerateDestroy( + ['component-class', 'x-foo', '--pod', '--path', 'bar/foo'], + (_file) => { + expect(_file('app/pods/bar/foo/x-foo/component.js')).to.equal( + fixture('component/component-dash.js') + ); + } + ); + }); + + it('component-class foo/x-foo --pod --path bar/baz', function () { + return emberGenerateDestroy( + ['component-class', 'foo/x-foo', '--pod', '--path', 'bar/baz'], + (_file) => { + expect(_file('app/pods/bar/baz/foo/x-foo/component.js')).to.equal( + fixture('component/component-nested.js') + ); + } + ); + }); + + it('component-class x-foo --pod -no-path', function () { + return emberGenerateDestroy(['component-class', 'x-foo', '--pod', '-no-path'], (_file) => { + expect(_file('app/pods/x-foo/component.js')).to.equal( + fixture('component/component-dash.js') + ); + }); + }); + + it('component-class foo/x-foo --pod -no-path', function () { + return emberGenerateDestroy( + ['component-class', 'foo/x-foo', '--pod', '-no-path'], + (_file) => { + expect(_file('app/pods/foo/x-foo/component.js')).to.equal( + fixture('component/component-nested.js') + ); + } + ); + }); + }); + }); + + describe('in app - octane', function () { + enableOctane(); + + beforeEach(function () { + return emberNew() + .then(() => + modifyPackages([ + { name: 'ember-qunit', delete: true }, + { name: 'ember-cli-qunit', dev: true }, + ]) + ) + .then(() => generateFakePackageManifest('ember-cli-qunit', '4.1.0')); + }); + + it('component-class foo', function () { + return emberGenerateDestroy(['component-class', 'foo'], (_file) => { + expect(_file('app/components/foo.js')).to.equal(glimmerComponentContents); + }); + }); + + it('component-class x-foo', function () { + return emberGenerateDestroy(['component-class', 'x-foo'], (_file) => { + expect(_file('app/components/x-foo.js')).to.equal( + glimmerComponentContents.replace('FooComponent', 'XFooComponent') + ); + }); + }); + + it('component-class x-foo.js', function () { + return emberGenerateDestroy(['component-class', 'x-foo.js'], (_file) => { + expect(_file('app/components/x-foo.js.js')).to.not.exist; + expect(_file('app/components/x-foo.js')).to.equal( + glimmerComponentContents.replace('FooComponent', 'XFooComponent') + ); + }); + }); + + it('component-class foo/x-foo', function () { + return emberGenerateDestroy(['component-class', 'foo/x-foo'], (_file) => { + expect(_file('app/components/foo/x-foo.js')).to.equal( + glimmerComponentContents.replace('FooComponent', 'FooXFooComponent') + ); + }); + }); + + it('component-class foo/x-foo --component-class="@glimmer/component"', function () { + return emberGenerateDestroy( + ['component-class', 'foo/x-foo', '--component-class', '@glimmer/component'], + (_file) => { + expect(_file('app/components/foo/x-foo.js')).to.equal( + glimmerComponentContents.replace('FooComponent', 'FooXFooComponent') + ); + } + ); + }); + }); + + describe('in addon', function () { + beforeEach(function () { + return emberNew({ target: 'addon' }) + .then(() => + modifyPackages([ + { name: 'ember-qunit', delete: true }, + { name: 'ember-cli-qunit', dev: true }, + ]) + ) + .then(() => generateFakePackageManifest('ember-cli-qunit', '4.1.0')); + }); + + it('component-class foo', function () { + return emberGenerateDestroy(['component-class', 'foo'], (_file) => { + expect(_file('addon/components/foo.js')).to.equal(fixture('component/component-addon.js')); + expect(_file('app/components/foo.js')).to.contain( + "export { default } from 'my-addon/components/foo';" + ); + }); + }); + + it('component-class x-foo', function () { + return emberGenerateDestroy(['component-class', 'x-foo'], (_file) => { + expect(_file('addon/components/x-foo.js')).to.equal( + fixture('component/component-addon-dash.js') + ); + expect(_file('app/components/x-foo.js')).to.contain( + "export { default } from 'my-addon/components/x-foo';" + ); + }); + }); + + it('component-class x-foo.js', function () { + return emberGenerateDestroy(['component-class', 'x-foo.js'], (_file) => { + expect(_file('addon/components/x-foo.js.js')).to.not.exist; + expect(_file('app/components/x-foo.js.js')).to.not.exist; + expect(_file('addon/components/x-foo.js')).to.equal( + fixture('component/component-addon-dash.js') + ); + expect(_file('app/components/x-foo.js')).to.contain( + "export { default } from 'my-addon/components/x-foo';" + ); + }); + }); + + it('component-class foo/x-foo', function () { + return emberGenerateDestroy(['component-class', 'foo/x-foo'], (_file) => { + expect(_file('addon/components/foo/x-foo.js')).to.equal( + fixture('component/component-addon-nested.js') + ); + expect(_file('app/components/foo/x-foo.js')).to.contain( + "export { default } from 'my-addon/components/foo/x-foo';" + ); + }); + }); + + it('component-class x-foo --dummy', function () { + return emberGenerateDestroy(['component-class', 'x-foo', '--dummy'], (_file) => { + expect(_file('tests/dummy/app/components/x-foo.js')).to.equal( + fixture('component/component-addon-dash.js') + ); + expect(_file('app/components/x-foo.js')).to.not.exist; + }); + }); + + it('component-class foo/x-foo --dummy', function () { + return emberGenerateDestroy(['component-class', 'foo/x-foo', '--dummy'], (_file) => { + expect(_file('tests/dummy/app/components/foo/x-foo.js')).to.equal( + fixture('component/component-addon-nested.js') + ); + expect(_file('app/components/foo/x-foo.js')).to.not.exist; + }); + }); + + it('component-class x-foo.js --dummy', function () { + return emberGenerateDestroy(['component-class', 'x-foo.js', '--dummy'], (_file) => { + expect(_file('tests/dummy/app/components/x-foo.js.js')).to.not.exist; + expect(_file('app/components/x-foo.js.js')).to.not.exist; + expect(_file('tests/dummy/app/components/x-foo.js')).to.equal( + fixture('component/component-addon-dash.js') + ); + expect(_file('app/components/x-foo.js')).to.not.exist; + }); + }); + + it('component-class x-foo --pod', function () { + return emberGenerateDestroy(['component-class', 'x-foo', '--pod'], (_file) => { + expect(_file('addon/components/x-foo/component.js')).to.equal( + fixture('component/component-addon-dash-pod.ts') + ); + expect(_file('app/components/x-foo/component.js')).to.contain( + "export { default } from 'my-addon/components/x-foo/component';" + ); + }); + }); + }); + + describe('in addon - octane', function () { + enableOctane(); + + beforeEach(function () { + return emberNew({ target: 'addon' }) + .then(() => + modifyPackages([ + { name: 'ember-qunit', delete: true }, + { name: 'ember-cli-qunit', dev: true }, + ]) + ) + .then(() => generateFakePackageManifest('ember-cli-qunit', '4.1.0')); + }); + + it('component-class foo', function () { + return emberGenerateDestroy(['component-class', 'foo'], (_file) => { + expect(_file('addon/components/foo.js')).to.equal(glimmerComponentContents); + expect(_file('app/components/foo.js')).to.contain( + "export { default } from 'my-addon/components/foo';" + ); + }); + }); + + it('component-class x-foo', function () { + return emberGenerateDestroy(['component-class', 'x-foo'], (_file) => { + expect(_file('addon/components/x-foo.js')).to.equal( + glimmerComponentContents.replace('FooComponent', 'XFooComponent') + ); + expect(_file('app/components/x-foo.js')).to.contain( + "export { default } from 'my-addon/components/x-foo';" + ); + }); + }); + + it('component-class foo/x-foo', function () { + return emberGenerateDestroy(['component-class', 'foo/x-foo'], (_file) => { + expect(_file('addon/components/foo/x-foo.js')).to.equal( + glimmerComponentContents.replace('FooComponent', 'FooXFooComponent') + ); + expect(_file('app/components/foo/x-foo.js')).to.contain( + "export { default } from 'my-addon/components/foo/x-foo';" + ); + }); + }); + + it('component-class x-foo --dummy', function () { + return emberGenerateDestroy(['component-class', 'x-foo', '--dummy'], (_file) => { + expect(_file('tests/dummy/app/components/x-foo.js')).equal( + glimmerComponentContents.replace('FooComponent', 'XFooComponent') + ); + expect(_file('app/components/x-foo.js')).to.not.exist; + }); + }); + + it('component-class foo/x-foo --dummy', function () { + return emberGenerateDestroy(['component-class', 'foo/x-foo', '--dummy'], (_file) => { + expect(_file('tests/dummy/app/components/foo/x-foo.js')).to.equal( + glimmerComponentContents.replace('FooComponent', 'FooXFooComponent') + ); + expect(_file('app/components/foo/x-foo.hbs')).to.not.exist; + }); + }); + }); + + describe('in in-repo-addon', function () { + beforeEach(function () { + return emberNew({ target: 'in-repo-addon' }) + .then(() => + modifyPackages([ + { name: 'ember-qunit', delete: true }, + { name: 'ember-cli-qunit', dev: true }, + ]) + ) + .then(() => generateFakePackageManifest('ember-cli-qunit', '4.1.0')); + }); + + it('component-class foo --in-repo-addon=my-addon', function () { + return emberGenerateDestroy( + ['component-class', 'foo', '--in-repo-addon=my-addon'], + (_file) => { + expect(_file('lib/my-addon/addon/components/foo.js')).to.equal( + fixture('component/component-addon.js') + ); + expect(_file('lib/my-addon/app/components/foo.js')).to.contain( + "export { default } from 'my-addon/components/foo';" + ); + } + ); + }); + + it('component-class x-foo --in-repo-addon=my-addon', function () { + return emberGenerateDestroy( + ['component-class', 'x-foo', '--in-repo-addon=my-addon'], + (_file) => { + expect(_file('lib/my-addon/addon/components/x-foo.js')).to.equal( + fixture('component/component-addon-dash.js') + ); + expect(_file('lib/my-addon/app/components/x-foo.js')).to.contain( + "export { default } from 'my-addon/components/x-foo';" + ); + } + ); + }); + + it('component-class x-foo.js --in-repo-addon=my-addon', function () { + return emberGenerateDestroy( + ['component-class', 'x-foo.js', '--in-repo-addon=my-addon'], + (_file) => { + expect(_file('lib/my-addon/addon/components/x-foo.js.js')).to.not.exist; + expect(_file('lib/my-addon/app/components/x-foo.js.js')).to.not.exist; + + expect(_file('lib/my-addon/addon/components/x-foo.js')).to.equal( + fixture('component/component-addon-dash.js') + ); + expect(_file('lib/my-addon/app/components/x-foo.js')).to.contain( + "export { default } from 'my-addon/components/x-foo';" + ); + } + ); + }); + + it('component-class foo/x-foo --in-repo-addon=my-addon', function () { + return emberGenerateDestroy( + ['component-class', 'foo/x-foo', '--in-repo-addon=my-addon'], + (_file) => { + expect(_file('lib/my-addon/addon/components/foo/x-foo.js')).to.equal( + fixture('component/component-addon-nested.js') + ); + expect(_file('lib/my-addon/app/components/foo/x-foo.js')).to.contain( + "export { default } from 'my-addon/components/foo/x-foo';" + ); + } + ); + }); + + it('component-class x-foo --in-repo-addon=my-addon --pod', function () { + return emberGenerateDestroy( + ['component-class', 'x-foo', '--in-repo-addon=my-addon', '--pod'], + (_file) => { + expect(_file('lib/my-addon/addon/components/x-foo/component.js')).to.equal( + fixture('component/component-addon-dash-pod.ts') + ); + expect(_file('lib/my-addon/app/components/x-foo/component.js')).to.contain( + "export { default } from 'my-addon/components/x-foo/component';" + ); + } + ); + }); + + it('component-class x-foo.js --in-repo-addon=my-addon --pod', function () { + return emberGenerateDestroy( + ['component-class', 'x-foo.js', '--in-repo-addon=my-addon', '--pod'], + (_file) => { + expect(_file('lib/my-addon/addon/components/x-foo/component.js.js')).to.not.exist; + expect(_file('lib/my-addon/app/components/x-foo/component.js.js')).to.not.exist; + expect(_file('lib/my-addon/addon/components/x-foo/component.js')).to.equal( + fixture('component/component-addon-dash-pod.ts') + ); + expect(_file('lib/my-addon/app/components/x-foo/component.js')).to.contain( + "export { default } from 'my-addon/components/x-foo/component';" + ); + } + ); + }); + + it('component-class foo/x-foo --in-repo-addon=my-addon --pod', function () { + return emberGenerateDestroy( + ['component-class', 'foo/x-foo', '--in-repo-addon=my-addon', '--pod'], + (_file) => { + expect(_file('lib/my-addon/addon/components/foo/x-foo/component.js')).to.equal( + fixture('component/component-addon-nested-pod.ts') + ); + expect(_file('lib/my-addon/app/components/foo/x-foo/component.js')).to.contain( + "export { default } from 'my-addon/components/foo/x-foo/component';" + ); + } + ); + }); + }); + + describe('in in-repo-addon - octane', function () { + enableOctane(); + + beforeEach(function () { + return emberNew({ target: 'in-repo-addon' }) + .then(() => + modifyPackages([ + { name: 'ember-qunit', delete: true }, + { name: 'ember-cli-qunit', dev: true }, + ]) + ) + .then(() => generateFakePackageManifest('ember-cli-qunit', '4.1.0')); + }); + + it('component-class foo --in-repo-addon=my-addon', function () { + return emberGenerateDestroy( + ['component-class', 'foo', '--in-repo-addon=my-addon'], + (_file) => { + expect(_file('lib/my-addon/addon/components/foo.js')).to.equal(glimmerComponentContents); + expect(_file('lib/my-addon/app/components/foo.js')).to.contain( + "export { default } from 'my-addon/components/foo';" + ); + } + ); + }); + + it('component-class x-foo --in-repo-addon=my-addon', function () { + return emberGenerateDestroy( + ['component-class', 'x-foo', '--in-repo-addon=my-addon'], + (_file) => { + expect(_file('lib/my-addon/addon/components/x-foo.js')).to.equal( + glimmerComponentContents.replace('FooComponent', 'XFooComponent') + ); + expect(_file('lib/my-addon/app/components/x-foo.js')).to.contain( + "export { default } from 'my-addon/components/x-foo';" + ); + } + ); + }); + }); +}); diff --git a/node-tests/blueprints/component-test-test.js b/node-tests/blueprints/component-test-test.js new file mode 100644 index 00000000..dcfc7fac --- /dev/null +++ b/node-tests/blueprints/component-test-test.js @@ -0,0 +1,103 @@ +'use strict'; + +const blueprintHelpers = require('ember-cli-blueprint-test-helpers/helpers'); +const setupTestHooks = blueprintHelpers.setupTestHooks; +const emberNew = blueprintHelpers.emberNew; +const emberGenerateDestroy = blueprintHelpers.emberGenerateDestroy; +const modifyPackages = blueprintHelpers.modifyPackages; + +const chai = require('ember-cli-blueprint-test-helpers/chai'); +const expect = chai.expect; + +const generateFakePackageManifest = require('../helpers/generate-fake-package-manifest'); +const fixture = require('../helpers/fixture'); + +describe('Blueprint: component-test', function() { + setupTestHooks(this); + + describe('in app', function() { + beforeEach(function() { + return emberNew(); + }); + + describe('with ember-cli-qunit@4.6.0', function() { + beforeEach(function() { + generateFakePackageManifest('ember-cli-qunit', '4.2.0'); + }); + + it('component-test x-foo', function() { + return emberGenerateDestroy(['component-test', 'x-foo'], _file => { + expect(_file('tests/integration/components/x-foo-test.ts')).to.equal( + fixture('component-test/qunit.ts') + ); + }); + }); + + }); + + describe('with ember-mocha@0.16.0', function() { + beforeEach(function() { + modifyPackages([ + { name: 'ember-cli-qunit', delete: true }, + { name: 'ember-mocha', dev: true }, + ]); + generateFakePackageManifest('ember-mocha', '0.16.0'); + }); + + it('component-test x-foo', function() { + return emberGenerateDestroy(['component-test', 'x-foo'], _file => { + expect(_file('tests/integration/components/x-foo-test.ts')).to.equal( + fixture('component-test/mocha.ts') + ); + }); + }); + }); + }); + + describe('in addon', function() { + beforeEach(function() { + return emberNew({ target: 'addon' }).then(() => + generateFakePackageManifest('ember-qunit', '4.6.0') + ); + }); + + it('component-test x-foo', function() { + return emberGenerateDestroy(['component-test', 'x-foo'], _file => { + expect(_file('tests/integration/components/x-foo-test.ts')).to.equal( + fixture('component-test/qunit.ts') + ); + + expect(_file('app/component-test/x-foo.ts')).to.not.exist; + }); + }); + + it('component-test x-foo --dummy', function() { + return emberGenerateDestroy(['component-test', 'x-foo', '--dummy'], _file => { + expect(_file('tests/integration/components/x-foo-test.ts')).to.equal( + fixture('component-test/qunit.ts') + ); + + expect(_file('app/component-test/x-foo.ts')).to.not.exist; + }); + }); + }); + + describe('in in-repo-addon', function() { + beforeEach(function() { + return emberNew({ target: 'in-repo-addon' }).then(() => + generateFakePackageManifest('ember-qunit', '4.6.0') + ); + }); + + it('component-test x-foo --in-repo-addon=my-addon', function() { + return emberGenerateDestroy( + ['component-test', 'x-foo', '--in-repo-addon=my-addon'], + _file => { + expect(_file('tests/integration/components/x-foo-test.ts')).to.equal( + fixture('component-test/qunit.ts') + ); + } + ); + }); + }); +}); diff --git a/node-tests/blueprints/component-test.js b/node-tests/blueprints/component-test.js new file mode 100644 index 00000000..f1da2e5a --- /dev/null +++ b/node-tests/blueprints/component-test.js @@ -0,0 +1,1369 @@ +'use strict'; + +const blueprintHelpers = require('ember-cli-blueprint-test-helpers/helpers'); +const setupTestHooks = blueprintHelpers.setupTestHooks; +const emberNew = blueprintHelpers.emberNew; +const emberGenerateDestroy = blueprintHelpers.emberGenerateDestroy; +const setupPodConfig = blueprintHelpers.setupPodConfig; +const modifyPackages = blueprintHelpers.modifyPackages; + +const chai = require('ember-cli-blueprint-test-helpers/chai'); +const expect = chai.expect; + +const generateFakePackageManifest = require('../helpers/generate-fake-package-manifest'); +const fixture = require('../helpers/fixture'); + +const setupTestEnvironment = require('../helpers/setup-test-environment'); +const enableOctane = setupTestEnvironment.enableOctane; + +const { EMBER_SET_COMPONENT_TEMPLATE } = require('../../blueprints/component'); + +const glimmerComponentContents = `import Component from '@glimmer/component'; + +export default class FooComponent extends Component { +} +`; + +const emberComponentContents = `import Component from '@ember/component'; + +export default Component.extend({ +}); +`; + +const templateOnlyContents = `import templateOnly from '@ember/component/template-only'; + +export default templateOnly(); +`; + +describe('Blueprint: component', function () { + setupTestHooks(this); + + describe('in app', function () { + beforeEach(function () { + return emberNew() + .then(() => + modifyPackages([ + { name: 'ember-qunit', delete: true }, + { name: 'ember-cli-qunit', dev: true }, + ]) + ) + .then(() => generateFakePackageManifest('ember-cli-qunit', '4.1.0')); + }); + + it('component foo', function () { + return emberGenerateDestroy(['component', 'foo'], (_file) => { + expect(_file('app/components/foo.ts')).to.equal(emberComponentContents); + + expect(_file('app/templates/components/foo.hbs')).to.equal('{{yield}}'); + + expect(_file('tests/integration/components/foo-test.ts')).to.equal( + fixture('component-test/default-template.ts', { + replace: { + component: 'foo', + componentInvocation: 'Foo', + }, + }) + ); + }); + }); + + if (EMBER_SET_COMPONENT_TEMPLATE) { + // classic default + it('component foo --component-structure=classic --component-class=@ember/component', function () { + return emberGenerateDestroy( + [ + 'component', + 'foo', + '--component-structure', + 'classic', + '--component-class', + '@ember/component', + ], + (_file) => { + expect(_file('app/components/foo.ts')).to.equal(emberComponentContents); + + expect(_file('app/templates/components/foo.hbs')).to.equal('{{yield}}'); + + expect(_file('tests/integration/components/foo-test.ts')).to.equal( + fixture('component-test/default-template.ts', { + replace: { + component: 'foo', + componentInvocation: 'Foo', + }, + }) + ); + } + ); + }); + + // Octane default + it('component foo --component-structure=flat --component-class=@glimmer/component', function () { + return emberGenerateDestroy( + [ + 'component', + '--component-structure', + 'flat', + '--component-class', + '@glimmer/component', + 'foo', + ], + (_file) => { + expect(_file('app/components/foo.ts')).to.equal(glimmerComponentContents); + + expect(_file('app/components/foo.hbs')).to.equal('{{yield}}'); + + expect(_file('tests/integration/components/foo-test.ts')).to.equal( + fixture('component-test/default-template.ts', { + replace: { + component: 'foo', + componentInvocation: 'Foo', + }, + }) + ); + } + ); + }); + + it('component foo --component-structure=flat', function () { + return emberGenerateDestroy( + ['component', '--component-structure', 'flat', 'foo'], + (_file) => { + expect(_file('app/components/foo.ts')).to.equal(emberComponentContents); + + expect(_file('app/components/foo.hbs')).to.equal('{{yield}}'); + + expect(_file('tests/integration/components/foo-test.ts')).to.equal( + fixture('component-test/default-template.ts', { + replace: { + component: 'foo', + componentInvocation: 'Foo', + }, + }) + ); + } + ); + }); + + it('component foo --component-structure=nested', function () { + return emberGenerateDestroy( + ['component', '--component-structure', 'nested', 'foo'], + (_file) => { + expect(_file('app/components/foo/index.ts')).to.equal(emberComponentContents); + + expect(_file('app/components/foo/index.hbs')).to.equal('{{yield}}'); + + expect(_file('tests/integration/components/foo-test.ts')).to.equal( + fixture('component-test/default-template.ts', { + replace: { + component: 'foo', + componentInvocation: 'Foo', + }, + }) + ); + } + ); + }); + + it('component foo --component-structure=classic', function () { + return emberGenerateDestroy( + ['component', '--component-structure', 'classic', 'foo'], + (_file) => { + expect(_file('app/components/foo.ts')).to.equal(emberComponentContents); + + expect(_file('app/templates/components/foo.hbs')).to.equal('{{yield}}'); + + expect(_file('tests/integration/components/foo-test.ts')).to.equal( + fixture('component-test/default-template.ts', { + replace: { + component: 'foo', + componentInvocation: 'Foo', + }, + }) + ); + } + ); + }); + + it('component foo --component-class=@ember/component', function () { + return emberGenerateDestroy( + ['component', '--component-class', '@ember/component', 'foo'], + (_file) => { + expect(_file('app/components/foo.ts')).to.equal(emberComponentContents); + + expect(_file('app/templates/components/foo.hbs')).to.equal('{{yield}}'); + + expect(_file('tests/integration/components/foo-test.ts')).to.equal( + fixture('component-test/default-template.ts', { + replace: { + component: 'foo', + componentInvocation: 'Foo', + }, + }) + ); + } + ); + }); + + it('component foo --component-class=@glimmer/component', function () { + return emberGenerateDestroy( + ['component', '--component-class', '@glimmer/component', 'foo'], + (_file) => { + expect(_file('app/components/foo.ts')).to.equal(glimmerComponentContents); + + expect(_file('app/templates/components/foo.hbs')).to.equal('{{yield}}'); + + expect(_file('tests/integration/components/foo-test.ts')).to.equal( + fixture('component-test/default-template.ts', { + replace: { + component: 'foo', + componentInvocation: 'Foo', + }, + }) + ); + } + ); + }); + + it('component foo --component-class=@ember/component/template-only', function () { + return emberGenerateDestroy( + ['component', '--component-class', '@ember/component/template-only', 'foo'], + (_file) => { + expect(_file('app/components/foo.ts')).to.equal(templateOnlyContents); + + expect(_file('app/templates/components/foo.hbs')).to.equal('{{yield}}'); + + expect(_file('tests/integration/components/foo-test.ts')).to.equal( + fixture('component-test/default-template.ts', { + replace: { + component: 'foo', + componentInvocation: 'Foo', + }, + }) + ); + } + ); + }); + + it('component foo --no-component-class', function () { + return emberGenerateDestroy(['component', '--no-component-class', 'foo'], (_file) => { + expect(_file('app/components/foo.ts')).to.not.exist; + + expect(_file('app/templates/components/foo.hbs')).to.equal('{{yield}}'); + + expect(_file('tests/integration/components/foo-test.ts')).to.equal( + fixture('component-test/default-template.ts', { + replace: { + component: 'foo', + componentInvocation: 'Foo', + }, + }) + ); + }); + }); + } + it('component x-foo', function () { + return emberGenerateDestroy(['component', 'x-foo'], (_file) => { + expect(_file('app/components/x-foo.ts')).to.equal(fixture('component/component-dash.ts')); + + expect(_file('app/templates/components/x-foo.hbs')).to.equal('{{yield}}'); + + expect(_file('tests/integration/components/x-foo-test.ts')).to.equal( + fixture('component-test/default-template.ts', { + replace: { + component: 'x-foo', + componentInvocation: 'XFoo', + }, + }) + ); + }); + }); + + it('component foo/x-foo', function () { + return emberGenerateDestroy(['component', 'foo/x-foo'], (_file) => { + expect(_file('app/components/foo/x-foo.ts')).to.equal( + fixture('component/component-nested.ts') + ); + + expect(_file('app/templates/components/foo/x-foo.hbs')).to.equal('{{yield}}'); + + expect(_file('tests/integration/components/foo/x-foo-test.ts')).to.equal( + fixture('component-test/default-template.ts', { + replace: { + component: 'foo/x-foo', + componentInvocation: 'Foo::XFoo', + }, + }) + ); + }); + }); + + it('component x-foo --path foo', function () { + return emberGenerateDestroy(['component', 'x-foo', '--path', 'foo'], (_file) => { + expect(_file('app/components/x-foo.ts')).to.equal(fixture('component/component-dash.ts')); + + expect(_file('app/templates/components/x-foo.hbs')).to.equal('{{yield}}'); + + expect(_file('tests/integration/components/x-foo-test.ts')).to.equal( + fixture('component-test/default-template.ts', { + replace: { + component: 'x-foo', + componentInvocation: 'XFoo', + }, + }) + ); + }); + }); + + it('component foo.ts', function () { + return emberGenerateDestroy(['component', 'foo.ts'], (_file) => { + expect(_file('app/components/foo.js.ts')).to.not.exist; + expect(_file('app/templates/components/foo.js.hbs')).to.not.exist; + expect(_file('tests/integration/components/foo.js-test.ts')).to.not.exist; + + expect(_file('app/components/foo.ts')).to.equal(fixture('component/component.ts')); + + expect(_file('app/templates/components/foo.hbs')).to.equal('{{yield}}'); + + expect(_file('tests/integration/components/foo-test.ts')).to.equal( + fixture('component-test/default-template.ts', { + replace: { + component: 'foo', + componentInvocation: 'Foo', + }, + }) + ); + }); + }); + + it('component x-foo --pod', function () { + return emberGenerateDestroy(['component', 'x-foo', '--pod'], (_file) => { + expect(_file('app/components/x-foo/component.ts')).to.equal( + fixture('component/component-dash.ts') + ); + + expect(_file('app/components/x-foo/template.hbs')).to.equal('{{yield}}'); + + expect(_file('tests/integration/components/x-foo/component-test.ts')).to.equal( + fixture('component-test/default-template.ts', { + replace: { + component: 'x-foo', + componentInvocation: 'XFoo', + }, + }) + ); + }); + }); + + it('component foo/x-foo --pod', function () { + return emberGenerateDestroy(['component', 'foo/x-foo', '--pod'], (_file) => { + expect(_file('app/components/foo/x-foo/component.ts')).to.equal( + fixture('component/component-nested.ts') + ); + + expect(_file('app/components/foo/x-foo/template.hbs')).to.equal('{{yield}}'); + + expect(_file('tests/integration/components/foo/x-foo/component-test.ts')).to.equal( + fixture('component-test/default-template.ts', { + replace: { + component: 'foo/x-foo', + componentInvocation: 'Foo::XFoo', + }, + }) + ); + }); + }); + + it('component x-foo --pod --path foo', function () { + return emberGenerateDestroy(['component', 'x-foo', '--pod', '--path', 'foo'], (_file) => { + expect(_file('app/foo/x-foo/component.ts')).to.equal( + fixture('component/component-dash.ts') + ); + + expect(_file('app/foo/x-foo/template.hbs')).to.equal('{{yield}}'); + + expect(_file('tests/integration/foo/x-foo/component-test.ts')).to.equal( + fixture('component-test/default-template.ts', { + replace: { + component: 'x-foo', + componentInvocation: 'XFoo', + path: 'foo/', + }, + }) + ); + }); + }); + + it('component foo/x-foo --pod --path bar', function () { + return emberGenerateDestroy(['component', 'foo/x-foo', '--pod', '--path', 'bar'], (_file) => { + expect(_file('app/bar/foo/x-foo/component.ts')).to.equal( + fixture('component/component-nested.ts') + ); + + expect(_file('app/bar/foo/x-foo/template.hbs')).to.equal('{{yield}}'); + + expect(_file('tests/integration/bar/foo/x-foo/component-test.ts')).to.equal( + fixture('component-test/default-template.ts', { + replace: { + component: 'foo/x-foo', + componentInvocation: 'Foo::XFoo', + path: 'bar/', + }, + }) + ); + }); + }); + + it('component x-foo --pod --path bar/foo', function () { + return emberGenerateDestroy(['component', 'x-foo', '--pod', '--path', 'bar/foo'], (_file) => { + expect(_file('app/bar/foo/x-foo/component.ts')).to.equal( + fixture('component/component-dash.ts') + ); + + expect(_file('app/bar/foo/x-foo/template.hbs')).to.equal('{{yield}}'); + + expect(_file('tests/integration/bar/foo/x-foo/component-test.ts')).to.equal( + fixture('component-test/default-template.ts', { + replace: { + component: 'x-foo', + componentInvocation: 'XFoo', + path: 'bar/foo/', + }, + }) + ); + }); + }); + + it('component foo/x-foo --pod --path bar/baz', function () { + return emberGenerateDestroy( + ['component', 'foo/x-foo', '--pod', '--path', 'bar/baz'], + (_file) => { + expect(_file('app/bar/baz/foo/x-foo/component.ts')).to.equal( + fixture('component/component-nested.ts') + ); + + expect(_file('app/bar/baz/foo/x-foo/template.hbs')).to.equal('{{yield}}'); + + expect(_file('tests/integration/bar/baz/foo/x-foo/component-test.ts')).to.equal( + fixture('component-test/default-template.ts', { + replace: { + component: 'foo/x-foo', + componentInvocation: 'Foo::XFoo', + path: 'bar/baz/', + }, + }) + ); + } + ); + }); + + it('component x-foo --pod -no-path', function () { + return emberGenerateDestroy(['component', 'x-foo', '--pod', '-no-path'], (_file) => { + expect(_file('app/x-foo/component.ts')).to.equal(fixture('component/component-dash.ts')); + + expect(_file('app/x-foo/template.hbs')).to.equal('{{yield}}'); + + expect(_file('tests/integration/x-foo/component-test.ts')).to.equal( + fixture('component-test/default-template.ts', { + replace: { + component: 'x-foo', + componentInvocation: 'XFoo', + }, + }) + ); + }); + }); + + it('component foo/x-foo --pod -no-path', function () { + return emberGenerateDestroy(['component', 'foo/x-foo', '--pod', '-no-path'], (_file) => { + expect(_file('app/foo/x-foo/component.ts')).to.equal( + fixture('component/component-nested.ts') + ); + + expect(_file('app/foo/x-foo/template.hbs')).to.equal('{{yield}}'); + + expect(_file('tests/integration/foo/x-foo/component-test.ts')).to.equal( + fixture('component-test/default-template.ts', { + replace: { + component: 'foo/x-foo', + componentInvocation: 'Foo::XFoo', + }, + }) + ); + }); + }); + + it('component x-foo.js --pod', function () { + return emberGenerateDestroy(['component', 'x-foo.ts', '--pod'], (_file) => { + expect(_file('app/components/x-foo.js/component.ts')).to.not.exist; + expect(_file('app/components/x-foo.js/template.hbs')).to.not.exist; + expect(_file('tests/integration/components/x-foo.js/component-test.ts')).to.not.exist; + + expect(_file('app/components/x-foo/component.ts')).to.equal( + fixture('component/component-dash.ts') + ); + + expect(_file('app/components/x-foo/template.hbs')).to.equal('{{yield}}'); + + expect(_file('tests/integration/components/x-foo/component-test.ts')).to.equal( + fixture('component-test/default-template.ts', { + replace: { + component: 'x-foo', + componentInvocation: 'XFoo', + }, + }) + ); + }); + }); + + describe('with podModulePrefix', function () { + beforeEach(function () { + setupPodConfig({ podModulePrefix: true }); + }); + + it('component foo --pod', function () { + return emberGenerateDestroy(['component', 'foo', '--pod'], (_file) => { + expect(_file('app/pods/components/foo/component.ts')).to.equal( + fixture('component/component.ts') + ); + + expect(_file('app/pods/components/foo/template.hbs')).to.equal('{{yield}}'); + + expect(_file('tests/integration/pods/components/foo/component-test.ts')).to.equal( + fixture('component-test/default-template.ts', { + replace: { + component: 'foo', + componentInvocation: 'Foo', + }, + }) + ); + }); + }); + + it('component x-foo --pod', function () { + return emberGenerateDestroy(['component', 'x-foo', '--pod'], (_file) => { + expect(_file('app/pods/components/x-foo/component.ts')).to.equal( + fixture('component/component-dash.ts') + ); + + expect(_file('app/pods/components/x-foo/template.hbs')).to.equal('{{yield}}'); + + expect(_file('tests/integration/pods/components/x-foo/component-test.ts')).to.equal( + fixture('component-test/default-template.ts', { + replace: { + component: 'x-foo', + componentInvocation: 'XFoo', + }, + }) + ); + }); + }); + + it('component foo/x-foo --pod', function () { + return emberGenerateDestroy(['component', 'foo/x-foo', '--pod'], (_file) => { + expect(_file('app/pods/components/foo/x-foo/component.ts')).to.equal( + fixture('component/component-nested.ts') + ); + + expect(_file('app/pods/components/foo/x-foo/template.hbs')).to.equal('{{yield}}'); + + expect(_file('tests/integration/pods/components/foo/x-foo/component-test.ts')).to.equal( + fixture('component-test/default-template.ts', { + replace: { + component: 'foo/x-foo', + componentInvocation: 'Foo::XFoo', + }, + }) + ); + }); + }); + + it('component x-foo --pod --path foo', function () { + return emberGenerateDestroy(['component', 'x-foo', '--pod', '--path', 'foo'], (_file) => { + expect(_file('app/pods/foo/x-foo/component.ts')).to.equal( + fixture('component/component-dash.ts') + ); + + expect(_file('app/pods/foo/x-foo/template.hbs')).to.equal('{{yield}}'); + + expect(_file('tests/integration/pods/foo/x-foo/component-test.ts')).to.equal( + fixture('component-test/default-template.ts', { + replace: { + component: 'x-foo', + componentInvocation: 'XFoo', + path: 'foo/', + }, + }) + ); + }); + }); + + it('component foo/x-foo --pod --path bar', function () { + return emberGenerateDestroy( + ['component', 'foo/x-foo', '--pod', '--path', 'bar'], + (_file) => { + expect(_file('app/pods/bar/foo/x-foo/component.ts')).to.equal( + fixture('component/component-nested.ts') + ); + + expect(_file('app/pods/bar/foo/x-foo/template.hbs')).to.equal('{{yield}}'); + + expect(_file('tests/integration/pods/bar/foo/x-foo/component-test.ts')).to.equal( + fixture('component-test/default-template.ts', { + replace: { + component: 'foo/x-foo', + componentInvocation: 'Foo::XFoo', + path: 'bar/', + }, + }) + ); + } + ); + }); + + it('component x-foo --pod --path bar/foo', function () { + return emberGenerateDestroy( + ['component', 'x-foo', '--pod', '--path', 'bar/foo'], + (_file) => { + expect(_file('app/pods/bar/foo/x-foo/component.ts')).to.equal( + fixture('component/component-dash.ts') + ); + + expect(_file('app/pods/bar/foo/x-foo/template.hbs')).to.equal('{{yield}}'); + expect(_file('tests/integration/pods/bar/foo/x-foo/component-test.ts')).to.equal( + fixture('component-test/default-template.ts', { + replace: { + component: 'x-foo', + componentInvocation: 'XFoo', + path: 'bar/foo/', + }, + }) + ); + } + ); + }); + + it('component foo/x-foo --pod --path bar/baz', function () { + return emberGenerateDestroy( + ['component', 'foo/x-foo', '--pod', '--path', 'bar/baz'], + (_file) => { + expect(_file('app/pods/bar/baz/foo/x-foo/component.ts')).to.equal( + fixture('component/component-nested.ts') + ); + + expect(_file('app/pods/bar/baz/foo/x-foo/template.hbs')).to.equal('{{yield}}'); + + expect(_file('tests/integration/pods/bar/baz/foo/x-foo/component-test.ts')).to.equal( + fixture('component-test/default-template.ts', { + replace: { + component: 'foo/x-foo', + componentInvocation: 'Foo::XFoo', + path: 'bar/baz/', + }, + }) + ); + } + ); + }); + + it('component x-foo --pod -no-path', function () { + return emberGenerateDestroy(['component', 'x-foo', '--pod', '-no-path'], (_file) => { + expect(_file('app/pods/x-foo/component.ts')).to.equal( + fixture('component/component-dash.ts') + ); + + expect(_file('app/pods/x-foo/template.hbs')).to.equal('{{yield}}'); + + expect(_file('tests/integration/pods/x-foo/component-test.ts')).to.equal( + fixture('component-test/default-template.ts', { + replace: { + component: 'x-foo', + componentInvocation: 'XFoo', + }, + }) + ); + }); + }); + + it('component foo/x-foo --pod -no-path', function () { + return emberGenerateDestroy(['component', 'foo/x-foo', '--pod', '-no-path'], (_file) => { + expect(_file('app/pods/foo/x-foo/component.ts')).to.equal( + fixture('component/component-nested.ts') + ); + + expect(_file('app/pods/foo/x-foo/template.hbs')).to.equal('{{yield}}'); + + expect(_file('tests/integration/pods/foo/x-foo/component-test.ts')).to.equal( + fixture('component-test/default-template.ts', { + replace: { + component: 'foo/x-foo', + componentInvocation: 'Foo::XFoo', + }, + }) + ); + }); + }); + }); + }); + + describe('in app - octane', function () { + enableOctane(); + + beforeEach(function () { + return emberNew() + .then(() => + modifyPackages([ + { name: 'ember-qunit', delete: true }, + { name: 'ember-cli-qunit', dev: true }, + ]) + ) + .then(() => generateFakePackageManifest('ember-cli-qunit', '4.1.0')); + }); + + it('component foo', function () { + return emberGenerateDestroy(['component', 'foo'], (_file) => { + expect(_file('app/components/foo.ts')).to.not.exist; + expect(_file('app/components/foo.hbs')).to.equal('{{yield}}'); + + expect(_file('tests/integration/components/foo-test.ts')).to.equal( + fixture('component-test/default-template.ts', { + replace: { + component: 'foo', + componentInvocation: 'Foo', + }, + }) + ); + }); + }); + + it('component x-foo', function () { + return emberGenerateDestroy(['component', 'x-foo'], (_file) => { + expect(_file('app/components/x-foo.ts')).to.not.exist; + expect(_file('app/components/x-foo.hbs')).to.equal('{{yield}}'); + + expect(_file('tests/integration/components/x-foo-test.ts')).to.equal( + fixture('component-test/default-template.ts', { + replace: { + component: 'x-foo', + componentInvocation: 'XFoo', + }, + }) + ); + }); + }); + + it('component x-foo.ts', function () { + return emberGenerateDestroy(['component', 'x-foo.ts'], (_file) => { + expect(_file('app/components/x-foo.ts')).to.not.exist; + expect(_file('app/components/x-foo.js.ts')).to.not.exist; + expect(_file('app/templates/components/x-foo.js.hbs')).to.not.exist; + expect(_file('tests/integration/components/x-foo-test.ts')).to.not.exist; + + expect(_file('app/components/x-foo.hbs')).to.equal('{{yield}}'); + + expect(_file('tests/integration/components/x-foo-test.ts')).to.equal( + fixture('component-test/default-template.ts', { + replace: { + component: 'x-foo', + componentInvocation: 'XFoo', + }, + }) + ); + }); + }); + + it('component foo/x-foo', function () { + return emberGenerateDestroy(['component', 'foo/x-foo'], (_file) => { + expect(_file('app/components/foo/x-foo.ts')).to.not.exist; + expect(_file('app/components/foo/x-foo.hbs')).to.equal('{{yield}}'); + + expect(_file('tests/integration/components/foo/x-foo-test.ts')).to.equal( + fixture('component-test/default-template.ts', { + replace: { + component: 'foo/x-foo', + componentInvocation: 'Foo::XFoo', + }, + }) + ); + }); + }); + + it('component foo/x-foo --component-class="@glimmer/component"', function () { + return emberGenerateDestroy( + ['component', 'foo/x-foo', '--component-class', '@glimmer/component'], + (_file) => { + expect(_file('app/components/foo/x-foo.ts')).to.equal( + glimmerComponentContents.replace('FooComponent', 'FooXFooComponent') + ); + expect(_file('app/components/foo/x-foo.hbs')).to.equal('{{yield}}'); + + expect(_file('tests/integration/components/foo/x-foo-test.ts')).to.equal( + fixture('component-test/default-template.ts', { + replace: { + component: 'foo/x-foo', + componentInvocation: 'Foo::XFoo', + }, + }) + ); + } + ); + }); + }); + + describe('in addon', function () { + beforeEach(function () { + return emberNew({ target: 'addon' }) + .then(() => + modifyPackages([ + { name: 'ember-qunit', delete: true }, + { name: 'ember-cli-qunit', dev: true }, + ]) + ) + .then(() => generateFakePackageManifest('ember-cli-qunit', '4.1.0')); + }); + + it('component foo', function () { + return emberGenerateDestroy(['component', 'foo'], (_file) => { + expect(_file('addon/components/foo.ts')).to.equal(fixture('component/component-addon.ts')); + + expect(_file('addon/templates/components/foo.hbs')).to.equal('{{yield}}'); + + expect(_file('app/components/foo.ts')).to.contain( + "export { default } from 'my-addon/components/foo';" + ); + + expect(_file('tests/integration/components/foo-test.ts')).to.equal( + fixture('component-test/default-template.ts', { + replace: { + component: 'foo', + componentInvocation: 'Foo', + }, + }) + ); + }); + }); + + it('component x-foo', function () { + return emberGenerateDestroy(['component', 'x-foo'], (_file) => { + expect(_file('addon/components/x-foo.ts')).to.equal( + fixture('component/component-addon-dash.ts') + ); + + expect(_file('addon/templates/components/x-foo.hbs')).to.equal('{{yield}}'); + + expect(_file('app/components/x-foo.ts')).to.contain( + "export { default } from 'my-addon/components/x-foo';" + ); + + expect(_file('tests/integration/components/x-foo-test.ts')).to.equal( + fixture('component-test/default-template.ts', { + replace: { + component: 'x-foo', + componentInvocation: 'XFoo', + }, + }) + ); + }); + }); + + it('component x-foo.ts', function () { + return emberGenerateDestroy(['component', 'x-foo.ts'], (_file) => { + expect(_file('addon/components/x-foo.js.ts')).to.not.exist; + expect(_file('addon/templates/components/x-foo.js.hbs')).to.not.exist; + expect(_file('app/components/x-foo.js.ts')).to.not.exist; + expect(_file('tests/integration/components/x-foo.js-test.ts')).to.not.exist; + + expect(_file('addon/components/x-foo.ts')).to.equal( + fixture('component/component-addon-dash.ts') + ); + + expect(_file('addon/templates/components/x-foo.hbs')).to.equal('{{yield}}'); + + expect(_file('app/components/x-foo.ts')).to.contain( + "export { default } from 'my-addon/components/x-foo';" + ); + + expect(_file('tests/integration/components/x-foo-test.ts')).to.equal( + fixture('component-test/default-template.ts', { + replace: { + component: 'x-foo', + componentInvocation: 'XFoo', + }, + }) + ); + }); + }); + + it('component foo/x-foo', function () { + return emberGenerateDestroy(['component', 'foo/x-foo'], (_file) => { + expect(_file('addon/components/foo/x-foo.ts')).to.equal( + fixture('component/component-addon-nested.ts') + ); + + expect(_file('addon/templates/components/foo/x-foo.hbs')).to.equal('{{yield}}'); + + expect(_file('app/components/foo/x-foo.ts')).to.contain( + "export { default } from 'my-addon/components/foo/x-foo';" + ); + + expect(_file('tests/integration/components/foo/x-foo-test.ts')).to.equal( + fixture('component-test/default-template.ts', { + replace: { + component: 'foo/x-foo', + componentInvocation: 'Foo::XFoo', + }, + }) + ); + }); + }); + + it('component x-foo --dummy', function () { + return emberGenerateDestroy(['component', 'x-foo', '--dummy'], (_file) => { + expect(_file('tests/dummy/app/components/x-foo.ts')).to.equal( + fixture('component/component-addon-dash.ts') + ); + + expect(_file('tests/dummy/app/templates/components/x-foo.hbs')).to.equal('{{yield}}'); + + expect(_file('app/components/x-foo.ts')).to.not.exist; + + expect(_file('tests/unit/components/x-foo-test.ts')).to.not.exist; + }); + }); + + it('component foo/x-foo --dummy', function () { + return emberGenerateDestroy(['component', 'foo/x-foo', '--dummy'], (_file) => { + expect(_file('tests/dummy/app/components/foo/x-foo.ts')).to.equal( + fixture('component/component-addon-nested.ts') + ); + + expect(_file('tests/dummy/app/templates/components/foo/x-foo.hbs')).to.equal('{{yield}}'); + + expect(_file('app/components/foo/x-foo.ts')).to.not.exist; + + expect(_file('tests/unit/components/foo/x-foo-test.ts')).to.not.exist; + }); + }); + + it('component x-foo.js --dummy', function () { + return emberGenerateDestroy(['component', 'x-foo.ts', '--dummy'], (_file) => { + expect(_file('tests/dummy/app/components/x-foo.js.ts')).to.not.exist; + expect(_file('tests/dummy/app/templates/components/x-foo.js.hbs')).to.not.exist; + expect(_file('app/components/x-foo.js.ts')).to.not.exist; + expect(_file('tests/unit/components/x-foo.js-test.ts')).to.not.exist; + + expect(_file('tests/dummy/app/components/x-foo.ts')).to.equal( + fixture('component/component-addon-dash.ts') + ); + + expect(_file('tests/dummy/app/templates/components/x-foo.hbs')).to.equal('{{yield}}'); + + expect(_file('app/components/x-foo.ts')).to.not.exist; + + expect(_file('tests/unit/components/x-foo-test.ts')).to.not.exist; + }); + }); + + it('component x-foo --pod', function () { + return emberGenerateDestroy(['component', 'x-foo', '--pod'], (_file) => { + expect(_file('addon/components/x-foo/component.ts')).to.equal( + fixture('component/component-addon-dash-pod.ts') + ); + + expect(_file('addon/components/x-foo/template.hbs')).to.equal('{{yield}}'); + + expect(_file('app/components/x-foo/component.ts')).to.contain( + "export { default } from 'my-addon/components/x-foo/component';" + ); + + expect(_file('tests/integration/components/x-foo/component-test.ts')).to.equal( + fixture('component-test/default-template.ts', { + replace: { + component: 'x-foo', + componentInvocation: 'XFoo', + }, + }) + ); + }); + }); + }); + + describe('in addon - octane', function () { + enableOctane(); + + beforeEach(function () { + return emberNew({ target: 'addon' }) + .then(() => + modifyPackages([ + { name: 'ember-qunit', delete: true }, + { name: 'ember-cli-qunit', dev: true }, + ]) + ) + .then(() => generateFakePackageManifest('ember-cli-qunit', '4.1.0')); + }); + + it('component foo', function () { + return emberGenerateDestroy(['component', 'foo'], (_file) => { + expect(_file('addon/components/foo.ts')).to.not.exist; + + expect(_file('addon/components/foo.hbs')).to.equal('{{yield}}'); + + expect(_file('app/components/foo.ts')).to.contain( + "export { default } from 'my-addon/components/foo';" + ); + + expect(_file('app/templates/components/foo.ts')).to.not.exist; + + expect(_file('tests/integration/components/foo-test.ts')).to.equal( + fixture('component-test/default-template.ts', { + replace: { + component: 'foo', + componentInvocation: 'Foo', + }, + }) + ); + }); + }); + + it('component x-foo', function () { + return emberGenerateDestroy(['component', 'x-foo'], (_file) => { + expect(_file('addon/components/x-foo.ts')).to.not.exist; + + expect(_file('addon/components/x-foo.hbs')).to.equal('{{yield}}'); + + expect(_file('app/components/x-foo.ts')).to.contain( + "export { default } from 'my-addon/components/x-foo';" + ); + + expect(_file('app/templates/components/x-foo.ts')).to.not.exist; + expect(_file('app/components/x-foo.hbs')).to.not.exist; + + expect(_file('tests/integration/components/x-foo-test.ts')).to.equal( + fixture('component-test/default-template.ts', { + replace: { + component: 'x-foo', + componentInvocation: 'XFoo', + }, + }) + ); + }); + }); + + it('component foo/x-foo', function () { + return emberGenerateDestroy(['component', 'foo/x-foo'], (_file) => { + expect(_file('addon/components/foo/x-foo.ts')).to.not.exist; + + expect(_file('addon/components/foo/x-foo.hbs')).to.equal('{{yield}}'); + + expect(_file('app/components/foo/x-foo.ts')).to.contain( + "export { default } from 'my-addon/components/foo/x-foo';" + ); + + expect(_file('app/templates/components/foo/x-foo.ts')).to.not.exist; + + expect(_file('tests/integration/components/foo/x-foo-test.ts')).to.equal( + fixture('component-test/default-template.ts', { + replace: { + component: 'foo/x-foo', + componentInvocation: 'Foo::XFoo', + }, + }) + ); + }); + }); + + it('component x-foo --dummy', function () { + return emberGenerateDestroy(['component', 'x-foo', '--dummy'], (_file) => { + expect(_file('tests/dummy/app/components/x-foo.ts')).to.not.exist; + + expect(_file('tests/dummy/app/components/x-foo.hbs')).to.equal('{{yield}}'); + + expect(_file('app/components/x-foo.ts')).to.not.exist; + expect(_file('app/components/x-foo.hbs')).to.not.exist; + expect(_file('app/templates/components/x-foo.ts')).to.not.exist; + + expect(_file('tests/integration/components/x-foo-test.ts')).to.not.exist; + }); + }); + + it('component foo/x-foo --dummy', function () { + return emberGenerateDestroy(['component', 'foo/x-foo', '--dummy'], (_file) => { + expect(_file('tests/dummy/app/components/foo/x-foo.ts')).to.not.exist; + + expect(_file('tests/dummy/app/components/foo/x-foo.hbs')).to.equal('{{yield}}'); + expect(_file('tests/dummy/app/templates/components/foo/x-foo.hbs')).to.not.exist; + + expect(_file('app/components/foo/x-foo.ts')).to.not.exist; + expect(_file('app/components/foo/x-foo.hbs')).to.not.exist; + expect(_file('app/templates/components/foo/x-foo.ts')).to.not.exist; + + expect(_file('tests/integration/components/foo/x-foo-test.ts')).to.not.exist; + }); + }); + }); + + describe('in in-repo-addon', function () { + beforeEach(function () { + return emberNew({ target: 'in-repo-addon' }) + .then(() => + modifyPackages([ + { name: 'ember-qunit', delete: true }, + { name: 'ember-cli-qunit', dev: true }, + ]) + ) + .then(() => generateFakePackageManifest('ember-cli-qunit', '4.1.0')); + }); + + it('component foo --in-repo-addon=my-addon', function () { + return emberGenerateDestroy(['component', 'foo', '--in-repo-addon=my-addon'], (_file) => { + expect(_file('lib/my-addon/addon/components/foo.ts')).to.equal( + fixture('component/component-addon.ts') + ); + + expect(_file('lib/my-addon/addon/templates/components/foo.hbs')).to.equal('{{yield}}'); + + expect(_file('lib/my-addon/app/components/foo.ts')).to.contain( + "export { default } from 'my-addon/components/foo';" + ); + + expect(_file('tests/integration/components/foo-test.ts')).to.equal( + fixture('component-test/default-template.ts', { + replace: { + component: 'foo', + componentInvocation: 'Foo', + }, + }) + ); + }); + }); + + it('component x-foo --in-repo-addon=my-addon', function () { + return emberGenerateDestroy(['component', 'x-foo', '--in-repo-addon=my-addon'], (_file) => { + expect(_file('lib/my-addon/addon/components/x-foo.ts')).to.equal( + fixture('component/component-addon-dash.ts') + ); + + expect(_file('lib/my-addon/addon/templates/components/x-foo.hbs')).to.equal('{{yield}}'); + + expect(_file('lib/my-addon/app/components/x-foo.ts')).to.contain( + "export { default } from 'my-addon/components/x-foo';" + ); + + expect(_file('tests/integration/components/x-foo-test.ts')).to.equal( + fixture('component-test/default-template.ts', { + replace: { + component: 'x-foo', + componentInvocation: 'XFoo', + }, + }) + ); + }); + }); + + it('component x-foo.js --in-repo-addon=my-addon', function () { + return emberGenerateDestroy( + ['component', 'x-foo.ts', '--in-repo-addon=my-addon'], + (_file) => { + expect(_file('lib/my-addon/addon/components/x-foo.js.ts')).to.not.exist; + expect(_file('lib/my-addon/addon/templates/components/x-foo.js.hbs')).to.not.exist; + expect(_file('lib/my-addon/app/components/x-foo.js.ts')).to.not.exist; + expect(_file('tests/integration/components/x-foo-test.ts')).to.not.exist; + + expect(_file('lib/my-addon/addon/components/x-foo.ts')).to.equal( + fixture('component/component-addon-dash.ts') + ); + + expect(_file('lib/my-addon/addon/templates/components/x-foo.hbs')).to.equal('{{yield}}'); + + expect(_file('lib/my-addon/app/components/x-foo.ts')).to.contain( + "export { default } from 'my-addon/components/x-foo';" + ); + + expect(_file('tests/integration/components/x-foo-test.ts')).to.equal( + fixture('component-test/default-template.ts', { + replace: { + component: 'x-foo', + componentInvocation: 'XFoo', + }, + }) + ); + } + ); + }); + + it('component foo/x-foo --in-repo-addon=my-addon', function () { + return emberGenerateDestroy( + ['component', 'foo/x-foo', '--in-repo-addon=my-addon'], + (_file) => { + expect(_file('lib/my-addon/addon/components/foo/x-foo.ts')).to.equal( + fixture('component/component-addon-nested.ts') + ); + + expect(_file('lib/my-addon/addon/templates/components/foo/x-foo.hbs')).to.equal( + '{{yield}}' + ); + + expect(_file('lib/my-addon/app/components/foo/x-foo.ts')).to.contain( + "export { default } from 'my-addon/components/foo/x-foo';" + ); + + expect(_file('tests/integration/components/foo/x-foo-test.ts')).to.equal( + fixture('component-test/default-template.ts', { + replace: { + component: 'foo/x-foo', + componentInvocation: 'Foo::XFoo', + }, + }) + ); + } + ); + }); + + it('component x-foo --in-repo-addon=my-addon --pod', function () { + return emberGenerateDestroy( + ['component', 'x-foo', '--in-repo-addon=my-addon', '--pod'], + (_file) => { + expect(_file('lib/my-addon/addon/components/x-foo/component.ts')).to.equal( + fixture('component/component-addon-dash-pod.ts') + ); + + expect(_file('lib/my-addon/addon/components/x-foo/template.hbs')).to.equal('{{yield}}'); + + expect(_file('lib/my-addon/app/components/x-foo/component.ts')).to.contain( + "export { default } from 'my-addon/components/x-foo/component';" + ); + + expect(_file('tests/integration/components/x-foo/component-test.ts')).to.equal( + fixture('component-test/default-template.ts', { + replace: { + component: 'x-foo', + componentInvocation: 'XFoo', + }, + }) + ); + } + ); + }); + + it('component x-foo.js --in-repo-addon=my-addon --pod', function () { + return emberGenerateDestroy( + ['component', 'x-foo.ts', '--in-repo-addon=my-addon', '--pod'], + (_file) => { + expect(_file('lib/my-addon/addon/components/x-foo/component.js.ts')).to.not.exist; + expect(_file('lib/my-addon/addon/components/x-foo/template.js.hbs')).to.not.exist; + expect(_file('lib/my-addon/app/components/x-foo/component.js.ts')).to.not.exist; + expect(_file('tests/integration/components/x-foo/component-test.ts')).to.not.exist; + + expect(_file('lib/my-addon/addon/components/x-foo/component.ts')).to.equal( + fixture('component/component-addon-dash-pod.ts') + ); + + expect(_file('lib/my-addon/addon/components/x-foo/template.hbs')).to.equal('{{yield}}'); + + expect(_file('lib/my-addon/app/components/x-foo/component.ts')).to.contain( + "export { default } from 'my-addon/components/x-foo/component';" + ); + + expect(_file('tests/integration/components/x-foo/component-test.ts')).to.equal( + fixture('component-test/default-template.ts', { + replace: { + component: 'x-foo', + componentInvocation: 'XFoo', + }, + }) + ); + } + ); + }); + + it('component foo/x-foo --in-repo-addon=my-addon --pod', function () { + return emberGenerateDestroy( + ['component', 'foo/x-foo', '--in-repo-addon=my-addon', '--pod'], + (_file) => { + expect(_file('lib/my-addon/addon/components/foo/x-foo/component.ts')).to.equal( + fixture('component/component-addon-nested-pod.ts') + ); + + expect(_file('lib/my-addon/addon/components/foo/x-foo/template.hbs')).to.equal( + '{{yield}}' + ); + + expect(_file('lib/my-addon/app/components/foo/x-foo/component.ts')).to.contain( + "export { default } from 'my-addon/components/foo/x-foo/component';" + ); + + expect(_file('tests/integration/components/foo/x-foo/component-test.ts')).to.equal( + fixture('component-test/default-template.ts', { + replace: { + component: 'foo/x-foo', + componentInvocation: 'Foo::XFoo', + }, + }) + ); + } + ); + }); + }); + + describe('in in-repo-addon - octane', function () { + enableOctane(); + + beforeEach(function () { + return emberNew({ target: 'in-repo-addon' }) + .then(() => + modifyPackages([ + { name: 'ember-qunit', delete: true }, + { name: 'ember-cli-qunit', dev: true }, + ]) + ) + .then(() => generateFakePackageManifest('ember-cli-qunit', '4.1.0')); + }); + + it('component foo --in-repo-addon=my-addon', function () { + return emberGenerateDestroy(['component', 'foo', '--in-repo-addon=my-addon'], (_file) => { + expect(_file('lib/my-addon/addon/components/foo.ts')).to.not.exist; + expect(_file('lib/my-addon/addon/components/foo.hbs')).to.equal('{{yield}}'); + expect(_file('lib/my-addon/addon/templates/components/foo.hbs')).to.not.exist; + + expect(_file('lib/my-addon/app/components/foo.ts')).to.contain( + "export { default } from 'my-addon/components/foo';" + ); + + expect(_file('lib/my-addon/app/templates/components/foo.ts')).to.not.exist; + expect(_file('lib/my-addon/app/components/foo.hbs')).to.not.exist; + + expect(_file('tests/integration/components/foo-test.ts')).to.equal( + fixture('component-test/default-template.ts', { + replace: { + component: 'foo', + componentInvocation: 'Foo', + }, + }) + ); + }); + }); + + it('component x-foo --in-repo-addon=my-addon', function () { + return emberGenerateDestroy(['component', 'x-foo', '--in-repo-addon=my-addon'], (_file) => { + expect(_file('lib/my-addon/addon/components/x-foo.ts')).to.not.exist; + expect(_file('lib/my-addon/addon/components/x-foo.hbs')).to.equal('{{yield}}'); + expect(_file('lib/my-addon/addon/templates/components/x-foo.hbs')).to.not.exist; + + expect(_file('lib/my-addon/app/components/x-foo.ts')).to.contain( + "export { default } from 'my-addon/components/x-foo';" + ); + + expect(_file('lib/my-addon/app/templates/components/x-foo.ts')).to.not.exist; + expect(_file('lib/my-addon/app/components/x-foo.hbs')).to.not.exist; + + expect(_file('tests/integration/components/x-foo-test.ts')).to.equal( + fixture('component-test/default-template.ts', { + replace: { + component: 'x-foo', + componentInvocation: 'XFoo', + }, + }) + ); + }); + }); + }); +}); diff --git a/node-tests/fixtures/component-test/default-template.ts b/node-tests/fixtures/component-test/default-template.ts new file mode 100644 index 00000000..72df2c7f --- /dev/null +++ b/node-tests/fixtures/component-test/default-template.ts @@ -0,0 +1,24 @@ +import { moduleForComponent, test } from 'ember-qunit'; +import hbs from 'htmlbars-inline-precompile'; + +moduleForComponent('<%= path =%><%= component =%>', 'Integration | Component | <%= component =%>', { + integration: true +}); + +test('it renders', function(assert) { + // Set any properties with this.set('myProperty', 'value'); + // Handle any actions with this.on('myAction', function(val) { ... }); + + this.render(hbs`<<%= componentInvocation =%> />`); + + assert.equal(this.$().text().trim(), ''); + + // Template block usage: + this.render(hbs` + <<%= componentInvocation =%>> + template block text + > + `); + + assert.equal(this.$().text().trim(), 'template block text'); +}); diff --git a/node-tests/fixtures/component-test/default.ts b/node-tests/fixtures/component-test/default.ts new file mode 100644 index 00000000..fc4c11ce --- /dev/null +++ b/node-tests/fixtures/component-test/default.ts @@ -0,0 +1,24 @@ +import { moduleForComponent, test } from 'ember-qunit'; +import hbs from 'htmlbars-inline-precompile'; + +moduleForComponent('x-foo', 'Integration | Component | x-foo', { + integration: true +}); + +test('it renders', function(assert) { + // Set any properties with this.set('myProperty', 'value'); + // Handle any actions with this.on('myAction', function(val) { ... }); + + this.render(hbs``); + + assert.equal(this.$().text().trim(), ''); + + // Template block usage: + this.render(hbs` + + template block text + + `); + + assert.equal(this.$().text().trim(), 'template block text'); +}); diff --git a/node-tests/fixtures/component-test/mocha.ts b/node-tests/fixtures/component-test/mocha.ts new file mode 100644 index 00000000..87c62720 --- /dev/null +++ b/node-tests/fixtures/component-test/mocha.ts @@ -0,0 +1,27 @@ +import { expect } from 'chai'; +import { describe, it } from 'mocha'; +import { setupRenderingTest } from 'ember-mocha'; +import { render } from '@ember/test-helpers'; +import { hbs } from 'ember-cli-htmlbars'; + +describe('x-foo', 'Integration | Component | x-foo', function() { + setupRenderingTest(); + + it('renders', async function() { + // Set any properties with this.set('myProperty', 'value'); + // Handle any actions with this.set('myAction', function(val) { ... }); + + await render(hbs``); + + expect(this.element.textContent.trim()).to.equal(''); + + // Template block usage: + await render(hbs` + + template block text + + `); + + expect(this.element.textContent.trim()).to.equal('template block text'); + }); +}); diff --git a/node-tests/fixtures/component-test/qunit.ts b/node-tests/fixtures/component-test/qunit.ts new file mode 100644 index 00000000..dbebc793 --- /dev/null +++ b/node-tests/fixtures/component-test/qunit.ts @@ -0,0 +1,26 @@ +import { module, test } from 'qunit'; +import { setupRenderingTest } from 'ember-qunit'; +import { render } from '@ember/test-helpers'; +import { hbs } from 'ember-cli-htmlbars'; + +module('Integration | Component | x-foo', function(hooks) { + setupRenderingTest(hooks); + + test('it renders', async function(assert) { + // Set any properties with this.set('myProperty', 'value'); + // Handle any actions with this.set('myAction', function(val) { ... }); + + await render(hbs``); + + assert.equal(this.element.textContent.trim(), ''); + + // Template block usage: + await render(hbs` + + template block text + + `); + + assert.equal(this.element.textContent.trim(), 'template block text'); + }); +}); diff --git a/node-tests/fixtures/component/component-addon-dash-pod.ts b/node-tests/fixtures/component/component-addon-dash-pod.ts new file mode 100644 index 00000000..6dfbdd55 --- /dev/null +++ b/node-tests/fixtures/component/component-addon-dash-pod.ts @@ -0,0 +1,7 @@ +import Component from '@ember/component'; +// @ts-ignore: Ignore import of compiled template +import layout from './template'; + +export default class XFoo extends Component { + layout = layout; +}; diff --git a/node-tests/fixtures/component/component-addon-dash.ts b/node-tests/fixtures/component/component-addon-dash.ts new file mode 100644 index 00000000..7fd9a3b5 --- /dev/null +++ b/node-tests/fixtures/component/component-addon-dash.ts @@ -0,0 +1,7 @@ +import Component from '@ember/component'; +// @ts-ignore: Ignore import of compiled template +import layout from '../templates/components/x-foo'; + +export default class XFoo extends Component { + layout = layout; +}; diff --git a/node-tests/fixtures/component/component-addon-nested-pod.ts b/node-tests/fixtures/component/component-addon-nested-pod.ts new file mode 100644 index 00000000..b84869b7 --- /dev/null +++ b/node-tests/fixtures/component/component-addon-nested-pod.ts @@ -0,0 +1,10 @@ +import Component from '@ember/component'; +// @ts-ignore: Ignore import of compiled template +import layout from './template'; + +export default class FooXFoo extends Component.extend({ + // anything which *must* be merged to prototype here +}) { + layout = layout; + // normal class body definition here +}; diff --git a/node-tests/fixtures/component/component-addon-nested.ts b/node-tests/fixtures/component/component-addon-nested.ts new file mode 100644 index 00000000..b8d2c8a9 --- /dev/null +++ b/node-tests/fixtures/component/component-addon-nested.ts @@ -0,0 +1,7 @@ +import Component from '@ember/component'; +// @ts-ignore: Ignore import of compiled template +import layout from '../../templates/components/foo/x-foo'; + +export default class FooXFoo extends Component { + layout = layout; +} diff --git a/node-tests/fixtures/component/component-addon.ts b/node-tests/fixtures/component/component-addon.ts new file mode 100644 index 00000000..8cc7412f --- /dev/null +++ b/node-tests/fixtures/component/component-addon.ts @@ -0,0 +1,7 @@ +import Component from '@ember/component'; +// @ts-ignore: Ignore import of compiled template +import layout from '../templates/components/foo'; + +export default class Foo extends Component { + layout = layout; +} diff --git a/node-tests/fixtures/component/component-dash.ts b/node-tests/fixtures/component/component-dash.ts new file mode 100644 index 00000000..c978f988 --- /dev/null +++ b/node-tests/fixtures/component/component-dash.ts @@ -0,0 +1,4 @@ +import Component from '@ember/component'; + +export default class XFoo extends Component { +} diff --git a/node-tests/fixtures/component/component-nested.ts b/node-tests/fixtures/component/component-nested.ts new file mode 100644 index 00000000..760840ce --- /dev/null +++ b/node-tests/fixtures/component/component-nested.ts @@ -0,0 +1,4 @@ +import Component from '@ember/component'; + +export default class FooXFoo extends Component { +} diff --git a/node-tests/fixtures/component/component.ts b/node-tests/fixtures/component/component.ts new file mode 100644 index 00000000..9ffdf650 --- /dev/null +++ b/node-tests/fixtures/component/component.ts @@ -0,0 +1,4 @@ +import Component from '@ember/component'; + +export default class Foo extends Component { +}; diff --git a/node-tests/fixtures/component/glimmer-component-dash.ts b/node-tests/fixtures/component/glimmer-component-dash.ts new file mode 100644 index 00000000..312a6b5f --- /dev/null +++ b/node-tests/fixtures/component/glimmer-component-dash.ts @@ -0,0 +1,7 @@ +import Component from '@glimmer/component'; + +interface XFooArgs {} + +export default class XFoo extends Component { + +} diff --git a/node-tests/fixtures/component/glimmer-component-nested.ts b/node-tests/fixtures/component/glimmer-component-nested.ts new file mode 100644 index 00000000..1bd26c76 --- /dev/null +++ b/node-tests/fixtures/component/glimmer-component-nested.ts @@ -0,0 +1,5 @@ +import Component from '@glimmer/component'; + +interface FooXFooArgs {} + +export default class FooXFoo extends Component {} diff --git a/node-tests/fixtures/component/glimmer-component.ts b/node-tests/fixtures/component/glimmer-component.ts new file mode 100644 index 00000000..b77f74d9 --- /dev/null +++ b/node-tests/fixtures/component/glimmer-component.ts @@ -0,0 +1,5 @@ +import Component from '@glimmer/component'; + +interface FooArgs {} + +export default class Foo extends Component {} diff --git a/node-tests/fixtures/helper-test/integration.ts b/node-tests/fixtures/helper-test/integration.ts index 8ce8201b..f9b2db03 100644 --- a/node-tests/fixtures/helper-test/integration.ts +++ b/node-tests/fixtures/helper-test/integration.ts @@ -1,7 +1,7 @@ import { module, test } from 'qunit'; import { setupRenderingTest } from 'ember-qunit'; import { render } from '@ember/test-helpers'; -import hbs from 'htmlbars-inline-precompile'; +import { hbs } from 'ember-cli-htmlbars'; module('Integration | Helper | foo/bar-baz', function(hooks) { setupRenderingTest(hooks); diff --git a/node-tests/fixtures/helper-test/mocha.ts b/node-tests/fixtures/helper-test/mocha.ts index feca3336..ec2202a1 100644 --- a/node-tests/fixtures/helper-test/mocha.ts +++ b/node-tests/fixtures/helper-test/mocha.ts @@ -1,7 +1,7 @@ import { expect } from 'chai'; import { describe, it } from 'mocha'; import { setupComponentTest } from 'ember-mocha'; -import hbs from 'htmlbars-inline-precompile'; +import { hbs } from 'ember-cli-htmlbars'; describe('Integration | Helper | foo/bar-baz', function() { setupComponentTest('foo/bar-baz', { @@ -21,6 +21,6 @@ describe('Integration | Helper | foo/bar-baz', function() { this.render(hbs`{{foo/bar-baz inputValue}}`); - expect(this.$().text().trim()).to.equal('1234'); + expect(this.element.text().trim()).to.equal('1234'); }); }); diff --git a/node-tests/helpers/expect-error.js b/node-tests/helpers/expect-error.js index c96aab1e..e9eda641 100644 --- a/node-tests/helpers/expect-error.js +++ b/node-tests/helpers/expect-error.js @@ -8,7 +8,7 @@ module.exports = function expectError(promise, expectedErrorText) { .then(() => { throw new Error('the command should raise an exception'); }) - .catch(error => { - expect(error.message || error).to.equal(expectedErrorText); + .catch((error) => { + expect(error.message).to.equal(expectedErrorText); }); }; diff --git a/node-tests/helpers/fixture.js b/node-tests/helpers/fixture.js index 4b9c83b1..b55cde25 100644 --- a/node-tests/helpers/fixture.js +++ b/node-tests/helpers/fixture.js @@ -4,12 +4,14 @@ const path = require('path'); const file = require('ember-cli-blueprint-test-helpers/chai').file; const fs = require('fs'); -module.exports = function(filePath, options) { +module.exports = function (filePath, options) { if (!options) { return file(path.join(__dirname, '../fixtures', filePath)); } - let content = fs.readFileSync(path.join(__dirname, '../fixtures', filePath), { encoding: 'utf-8' }); + let content = fs.readFileSync(path.join(__dirname, '../fixtures', filePath), { + encoding: 'utf-8', + }); if (options.replace) { content = content.replace(/<%= (\w+) =%>/g, (_match, key) => options.replace[key] || ''); } diff --git a/node-tests/helpers/generate-fake-package-manifest.js b/node-tests/helpers/generate-fake-package-manifest.js index 50a3c664..ad521a48 100644 --- a/node-tests/helpers/generate-fake-package-manifest.js +++ b/node-tests/helpers/generate-fake-package-manifest.js @@ -1,22 +1,16 @@ -// @ts-check -const { writeFileSync } = require('fs'); -const { ensureDirSync } = require('fs-extra'); -const path = require('path'); +const fs = require('fs'); -/** - * Create fake package manifests on the file system to use in ensuring that the - * blueprint generator is well-behaved with different test environments (e.g. - * qunit and mocha). - * - * @param {string} name - * @param {string} version - */ -function generateFakePackageManifest(name, version) { - const targetDir = path.join('node_modules', name); - ensureDirSync(targetDir); - - const pkgFilePath = path.join(targetDir, 'package.json'); - writeFileSync(pkgFilePath, JSON.stringify({ version })); -} - -module.exports = generateFakePackageManifest; +module.exports = function generateFakePackageManifest(name, version) { + if (!fs.existsSync('node_modules')) { + fs.mkdirSync('node_modules'); + } + if (!fs.existsSync('node_modules/' + name)) { + fs.mkdirSync('node_modules/' + name); + } + fs.writeFileSync( + 'node_modules/' + name + '/package.json', + JSON.stringify({ + version: version, + }) + ); +}; diff --git a/node-tests/helpers/setup-test-environment.js b/node-tests/helpers/setup-test-environment.js new file mode 100644 index 00000000..25d9a60d --- /dev/null +++ b/node-tests/helpers/setup-test-environment.js @@ -0,0 +1,15 @@ +const { setEdition, clearEdition } = require('@ember/edition-utils'); + +function enableOctane() { + beforeEach(function () { + setEdition('octane'); + }); + + afterEach(function () { + clearEdition(); + }); +} + +module.exports = { + enableOctane, +}; diff --git a/package.json b/package.json index 4cbd1d5c..c30a8f5c 100644 --- a/package.json +++ b/package.json @@ -35,6 +35,7 @@ "silent-error": "^1.1.0" }, "devDependencies": { + "@babel/core": "^7.12.3", "@typed-ember/renovate-config": "1.2.1", "broccoli-asset-rev": "3.0.0", "ember-ajax": "5.0.0", @@ -44,7 +45,6 @@ "ember-cli-eslint": "5.1.0", "ember-cli-htmlbars": "5.3.1", "ember-cli-inject-live-reload": "2.0.2", - "ember-qunit": "4.6.0", "ember-cli-shims": "1.2.0", "ember-cli-sri": "2.1.1", "ember-cli-uglify": "3.0.0", @@ -52,10 +52,12 @@ "ember-export-application-global": "2.0.1", "ember-load-initializers": "2.1.2", "ember-maybe-import-regenerator": "0.1.6", + "ember-qunit": "4.6.0", "ember-resolver": "8.0.2", "ember-source": "3.23.0", "ember-source-channel-url": "3.0.0", "ember-try": "1.4.0", + "eslint": "^7.13.0", "eslint-plugin-ember": "9.6.0", "eslint-plugin-node": "11.1.0", "loader.js": "4.7.0", diff --git a/yarn.lock b/yarn.lock index 65c5c3fa..b3e5a9c6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -23,7 +23,7 @@ invariant "^2.2.4" semver "^5.5.0" -"@babel/core@^7.11.6", "@babel/core@^7.12.0", "@babel/core@^7.3.4", "@babel/core@^7.8.4": +"@babel/core@^7.11.6", "@babel/core@^7.12.0", "@babel/core@^7.12.3", "@babel/core@^7.3.4", "@babel/core@^7.8.4": version "7.12.3" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.12.3.tgz#1b436884e1e3bff6fb1328dc02b208759de92ad8" integrity sha512-0qXcZYKZp3/6N2jKYVxZv0aNCsxTSVCiK72DTiTYZAu7sjg73W0/aynWjMbiGd87EQL4WyA8reiJVh92AVla9g== @@ -1472,6 +1472,22 @@ ember-cli-htmlbars-inline-precompile "^2.1.0" ember-test-waiters "^1.1.1" +"@eslint/eslintrc@^0.2.1": + version "0.2.1" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.2.1.tgz#f72069c330461a06684d119384435e12a5d76e3c" + integrity sha512-XRUeBZ5zBWLYgSANMpThFddrZZkEbGHgUdt5UJjZfnlN9BGCiUBrf+nvbRupSjMvqzwnQN0qwCmOxITt1cfywA== + dependencies: + ajv "^6.12.4" + debug "^4.1.1" + espree "^7.3.0" + globals "^12.1.0" + ignore "^4.0.6" + import-fresh "^3.2.1" + js-yaml "^3.13.1" + lodash "^4.17.19" + minimatch "^3.0.4" + strip-json-comments "^3.1.1" + "@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" @@ -1640,16 +1656,36 @@ acorn-jsx@^5.0.0: resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.0.0.tgz#958584ddb60990c02c97c1bd9d521fce433bb101" integrity sha512-XkB50fn0MURDyww9+UYL3c1yLbOBz0ZFvrdYlGB8l+Ije1oSC75qAqrzSPjYQbdnQUzhlUGNKuesryAv0gxZOg== +acorn-jsx@^5.2.0: + version "5.3.1" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.1.tgz#fc8661e11b7ac1539c47dbfea2e72b3af34d267b" + integrity sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng== + acorn@^6.0.2: version "6.4.2" resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.2.tgz#35866fd710528e92de10cf06016498e47e39e1e6" integrity sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ== +acorn@^7.4.0: + version "7.4.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" + integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== + after@0.8.2: version "0.8.2" resolved "https://registry.yarnpkg.com/after/-/after-0.8.2.tgz#fedb394f9f0e02aa9768e702bda23b505fae7e1f" integrity sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8= +ajv@^6.10.0, ajv@^6.10.2, ajv@^6.12.4: + version "6.12.6" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" + integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== + dependencies: + fast-deep-equal "^3.1.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + ajv@^6.5.3: version "6.5.5" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.5.5.tgz#cf97cdade71c6399a92c6d6c4177381291b781a1" @@ -1680,7 +1716,7 @@ amdefine@>=0.0.4: resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" integrity sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU= -ansi-colors@4.1.1: +ansi-colors@4.1.1, ansi-colors@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== @@ -1710,6 +1746,11 @@ 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@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" @@ -1868,6 +1909,11 @@ ast-types@0.13.1: resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.13.1.tgz#9461428a270c5a27fda44b738dd3bab2e9353003" integrity sha512-b+EeK0WlzrSmpMw5jktWvQGxblpWnvMrV+vOp69RLjzGiHwWV0vgq75DPKtUjppKni3yWwSW8WLGV3Ch/XIWcQ== +astral-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9" + integrity sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg== + async-disk-cache@^1.2.1: version "1.3.3" resolved "https://registry.yarnpkg.com/async-disk-cache/-/async-disk-cache-1.3.3.tgz#6040486660b370e4051cd9fa9fee275e1fae3728" @@ -3372,7 +3418,7 @@ callsites@^0.2.0: resolved "https://registry.yarnpkg.com/callsites/-/callsites-0.2.0.tgz#afab96262910a7f33c19a5775825c69f34e350ca" integrity sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo= -callsites@^3.1.0: +callsites@^3.0.0, callsites@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== @@ -3894,7 +3940,7 @@ cross-spawn@^6.0.0, cross-spawn@^6.0.5: shebang-command "^1.2.0" which "^1.2.9" -cross-spawn@^7.0.0: +cross-spawn@^7.0.0, cross-spawn@^7.0.2: version "7.0.3" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== @@ -3997,7 +4043,7 @@ deep-extend@^0.6.0: resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== -deep-is@~0.1.3: +deep-is@^0.1.3, deep-is@~0.1.3: version "0.1.3" resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= @@ -4112,6 +4158,13 @@ doctrine@^2.1.0: dependencies: esutils "^2.0.2" +doctrine@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" + integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== + dependencies: + esutils "^2.0.2" + dot-case@^3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/dot-case/-/dot-case-3.0.3.tgz#21d3b52efaaba2ea5fda875bb1aa8124521cf4aa" @@ -4829,6 +4882,13 @@ engine.io@~3.2.0: engine.io-parser "~2.1.0" ws "~3.3.1" +enquirer@^2.3.5: + version "2.3.6" + resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.6.tgz#2a7fe5dd634a1e4125a975ec994ff5456dc3734d" + integrity sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg== + dependencies: + ansi-colors "^4.1.1" + ensure-posix-path@^1.0.0, ensure-posix-path@^1.0.1, ensure-posix-path@^1.0.2, ensure-posix-path@^1.1.0, ensure-posix-path@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/ensure-posix-path/-/ensure-posix-path-1.1.1.tgz#3c62bdb19fa4681544289edb2b382adc029179ce" @@ -4916,6 +4976,14 @@ eslint-scope@^4.0.0: esrecurse "^4.1.0" estraverse "^4.1.1" +eslint-scope@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" + integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== + dependencies: + esrecurse "^4.3.0" + estraverse "^4.1.1" + eslint-utils@^1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.3.1.tgz#9a851ba89ee7c460346f97cf8939c7298827e512" @@ -4928,11 +4996,28 @@ eslint-utils@^2.0.0: dependencies: eslint-visitor-keys "^1.1.0" +eslint-utils@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-2.1.0.tgz#d2de5e03424e707dc10c74068ddedae708741b27" + integrity sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg== + dependencies: + eslint-visitor-keys "^1.1.0" + eslint-visitor-keys@^1.0.0, eslint-visitor-keys@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz#e2a82cea84ff246ad6fb57f9bde5b46621459ec2" integrity sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A== +eslint-visitor-keys@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz#30ebd1ef7c2fdff01c3a4f151044af25fab0523e" + integrity sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ== + +eslint-visitor-keys@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz#21fdc8fbcd9c795cc0321f0563702095751511a8" + integrity sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ== + eslint@^5.6.0: version "5.9.0" resolved "https://registry.yarnpkg.com/eslint/-/eslint-5.9.0.tgz#b234b6d15ef84b5849c6de2af43195a2d59d408e" @@ -4977,6 +5062,49 @@ eslint@^5.6.0: table "^5.0.2" text-table "^0.2.0" +eslint@^7.13.0: + version "7.13.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.13.0.tgz#7f180126c0dcdef327bfb54b211d7802decc08da" + integrity sha512-uCORMuOO8tUzJmsdRtrvcGq5qposf7Rw0LwkTJkoDbOycVQtQjmnhZSuLQnozLE4TmAzlMVV45eCHmQ1OpDKUQ== + dependencies: + "@babel/code-frame" "^7.0.0" + "@eslint/eslintrc" "^0.2.1" + ajv "^6.10.0" + chalk "^4.0.0" + cross-spawn "^7.0.2" + debug "^4.0.1" + doctrine "^3.0.0" + enquirer "^2.3.5" + eslint-scope "^5.1.1" + eslint-utils "^2.1.0" + eslint-visitor-keys "^2.0.0" + espree "^7.3.0" + esquery "^1.2.0" + esutils "^2.0.2" + file-entry-cache "^5.0.1" + functional-red-black-tree "^1.0.1" + glob-parent "^5.0.0" + globals "^12.1.0" + ignore "^4.0.6" + import-fresh "^3.0.0" + imurmurhash "^0.1.4" + is-glob "^4.0.0" + js-yaml "^3.13.1" + json-stable-stringify-without-jsonify "^1.0.1" + levn "^0.4.1" + lodash "^4.17.19" + minimatch "^3.0.4" + natural-compare "^1.4.0" + optionator "^0.9.1" + progress "^2.0.0" + regexpp "^3.1.0" + semver "^7.2.1" + strip-ansi "^6.0.0" + strip-json-comments "^3.1.0" + table "^5.2.3" + text-table "^0.2.0" + v8-compile-cache "^2.0.3" + esm@^3.2.4: version "3.2.25" resolved "https://registry.yarnpkg.com/esm/-/esm-3.2.25.tgz#342c18c29d56157688ba5ce31f8431fbb795cc10" @@ -4991,6 +5119,15 @@ espree@^4.0.0: acorn-jsx "^5.0.0" eslint-visitor-keys "^1.0.0" +espree@^7.3.0: + version "7.3.0" + resolved "https://registry.yarnpkg.com/espree/-/espree-7.3.0.tgz#dc30437cf67947cf576121ebd780f15eeac72348" + integrity sha512-dksIWsvKCixn1yrEXO8UosNSxaDoSYpq9reEjZSbHLpT5hpaCAKTLBwq0RHtLrIr+c0ByiYzWT8KTMRzoRCNlw== + dependencies: + acorn "^7.4.0" + acorn-jsx "^5.2.0" + eslint-visitor-keys "^1.3.0" + esprima@^4.0.0, esprima@~4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" @@ -5008,6 +5145,13 @@ esquery@^1.0.1: dependencies: estraverse "^4.0.0" +esquery@^1.2.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.3.1.tgz#b78b5828aa8e214e29fb74c4d5b752e1c033da57" + integrity sha512-olpvt9QG0vniUBZspVRN6lwB7hOZoTRtT+jzR+tS4ffYx2mzbw+z0XCOk44aaLYKApNX5nMm+E+P6o25ip/DHQ== + dependencies: + estraverse "^5.1.0" + esrecurse@^4.1.0: version "4.2.1" resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.2.1.tgz#007a3b9fdbc2b3bb87e4879ea19c92fdbd3942cf" @@ -5015,11 +5159,23 @@ esrecurse@^4.1.0: dependencies: estraverse "^4.1.0" +esrecurse@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" + integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== + dependencies: + estraverse "^5.2.0" + estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1: version "4.2.0" resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13" integrity sha1-De4/7TH81GlhjOc0IJn8GvoL2xM= +estraverse@^5.1.0, estraverse@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.2.0.tgz#307df42547e6cc7324d3cf03c155d5cdb8c53880" + integrity sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ== + esutils@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" @@ -5202,6 +5358,11 @@ fast-deep-equal@^2.0.1: resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49" integrity sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk= +fast-deep-equal@^3.1.1: + version "3.1.3" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" + integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== + fast-glob@^3.0.3: version "3.2.4" resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.4.tgz#d20aefbf99579383e7f3cc66529158c9b98554d3" @@ -5219,7 +5380,7 @@ fast-json-stable-stringify@^2.0.0: resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2" integrity sha1-1RQsDK7msRifh9OnYREGT4bIu/I= -fast-levenshtein@~2.0.4: +fast-levenshtein@^2.0.6, fast-levenshtein@~2.0.4: version "2.0.6" resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= @@ -5295,6 +5456,13 @@ file-entry-cache@^2.0.0: flat-cache "^1.2.1" object-assign "^4.0.1" +file-entry-cache@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-5.0.1.tgz#ca0f6efa6dd3d561333fb14515065c2fafdf439c" + integrity sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g== + dependencies: + flat-cache "^2.0.1" + filesize@^6.1.0: version "6.1.0" resolved "https://registry.yarnpkg.com/filesize/-/filesize-6.1.0.tgz#e81bdaa780e2451d714d71c0d7a4f3238d37ad00" @@ -5451,11 +5619,25 @@ flat-cache@^1.2.1: graceful-fs "^4.1.2" write "^0.2.1" +flat-cache@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-2.0.1.tgz#5d296d6f04bda44a4630a301413bdbc2ec085ec0" + integrity sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA== + dependencies: + flatted "^2.0.0" + rimraf "2.6.3" + write "1.0.3" + flat@^5.0.2: version "5.0.2" resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241" integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== +flatted@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-2.0.2.tgz#4575b21e2bcee7434aa9be662f4b7b5f9c2b5138" + integrity sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA== + follow-redirects@^1.0.0: version "1.5.6" resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.5.6.tgz#44eb4fe1981dff25e2bd86b7d4033abcdb81e965" @@ -5748,7 +5930,7 @@ git-write-pkt-line@0.1.0: bops "0.0.3" through "~2.2.7" -glob-parent@^5.1.0, glob-parent@~5.1.0: +glob-parent@^5.0.0, glob-parent@^5.1.0, 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== @@ -5803,6 +5985,13 @@ globals@^11.1.0, globals@^11.7.0: resolved "https://registry.yarnpkg.com/globals/-/globals-11.9.0.tgz#bde236808e987f290768a93d065060d78e6ab249" integrity sha512-5cJVtyXWH8PiJPVLZzzoIizXx944O4OmRro5MWKx5fT4MgcN7OfaMutPeaTdJCCURwbWdhhcCWcKIffPnmTzBg== +globals@^12.1.0: + version "12.4.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-12.4.0.tgz#a18813576a41b00a24a97e7f815918c2e19925f8" + integrity sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg== + dependencies: + type-fest "^0.8.1" + globals@^9.18.0: version "9.18.0" resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a" @@ -6160,6 +6349,14 @@ ignore@^5.1.1: resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.1.tgz#2fc6b8f518aff48fef65a7f348ed85632448e4a5" integrity sha512-DWjnQIFLenVrwyRCKZT+7a7/U4Cqgar4WG8V++K3hw+lrW1hc/SIwdiGmtxKCVACmHULTuGeBbHJmbwW7/sAvA== +import-fresh@^3.0.0, import-fresh@^3.2.1: + version "3.2.2" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.2.2.tgz#fc129c160c5d68235507f4331a6baad186bdbc3e" + integrity sha512-cTPNrlvJT6twpYy+YmKUKrTSjWFs3bjYjAhCwm+z4EOCubZxAuO+hHpRN64TqjEaYSHs7tJAE0w1CKMGmsG/lw== + dependencies: + parent-module "^1.0.0" + resolve-from "^4.0.0" + imurmurhash@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" @@ -6721,6 +6918,14 @@ levn@^0.3.0, levn@~0.3.0: prelude-ls "~1.1.2" type-check "~0.3.2" +levn@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" + integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== + dependencies: + prelude-ls "^1.2.1" + type-check "~0.4.0" + line-stream@0.0.0: version "0.0.0" resolved "https://registry.yarnpkg.com/line-stream/-/line-stream-0.0.0.tgz#888b7cc7951c6a05ce4d696dd1e6b8262371bb45" @@ -7798,6 +8003,18 @@ optionator@^0.8.2: type-check "~0.3.2" wordwrap "~1.0.0" +optionator@^0.9.1: + version "0.9.1" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.1.tgz#4f236a6373dae0566a6d43e1326674f50c291499" + integrity sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw== + dependencies: + deep-is "^0.1.3" + fast-levenshtein "^2.0.6" + levn "^0.4.1" + prelude-ls "^1.2.1" + type-check "^0.4.0" + word-wrap "^1.2.3" + ora@^3.4.0: version "3.4.0" resolved "https://registry.yarnpkg.com/ora/-/ora-3.4.0.tgz#bf0752491059a3ef3ed4c85097531de9fdbcd318" @@ -7917,6 +8134,13 @@ package-json@^4.0.1: registry-url "^3.0.3" semver "^5.1.0" +parent-module@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" + integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== + dependencies: + callsites "^3.0.0" + parse-passwd@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6" @@ -8073,6 +8297,11 @@ posix-character-classes@^0.1.0: resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs= +prelude-ls@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" + integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== + prelude-ls@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" @@ -8375,6 +8604,11 @@ regexpp@^3.0.0: resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.0.0.tgz#dd63982ee3300e67b41c1956f850aa680d9d330e" integrity sha512-Z+hNr7RAVWxznLPuA7DIh8UNX1j9CDrUQxskw9IrBE1Dxue2lyXT+shqEIeLUjrokxIP8CMy1WkjgG3rTsd5/g== +regexpp@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.1.0.tgz#206d0ad0a5648cffbdb8ae46438f3dc51c9f78e2" + integrity sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q== + regexpu-core@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-2.0.0.tgz#49d038837b8dcf8bfa5b9a42139938e6ea2ae240" @@ -8523,6 +8757,11 @@ resolve-from@^1.0.0: resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-1.0.1.tgz#26cbfe935d1aeeeabb29bc3fe5aeb01e93d44226" integrity sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY= +resolve-from@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" + integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== + resolve-package-path@^1.0.11, resolve-package-path@^1.2.6: version "1.2.7" resolved "https://registry.yarnpkg.com/resolve-package-path/-/resolve-package-path-1.2.7.tgz#2a7bc37ad96865e239330e3102c31322847e652e" @@ -8585,6 +8824,13 @@ reusify@^1.0.4: resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== +rimraf@2.6.3, rimraf@~2.6.2: + version "2.6.3" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" + integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA== + dependencies: + glob "^7.1.3" + rimraf@^2.1.4, rimraf@^2.2.8, rimraf@^2.3.4, rimraf@^2.4.3, rimraf@^2.4.4, rimraf@^2.5.3, rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.2, rimraf@^2.6.3: version "2.7.1" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" @@ -8599,13 +8845,6 @@ rimraf@^3.0.0, rimraf@^3.0.1, rimraf@^3.0.2: dependencies: glob "^7.1.3" -rimraf@~2.6.2: - version "2.6.3" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" - integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA== - dependencies: - glob "^7.1.3" - rsvp@^3.0.14, rsvp@^3.0.17, rsvp@^3.0.18, rsvp@^3.0.21, rsvp@^3.0.6, rsvp@^3.1.0: version "3.6.2" resolved "https://registry.yarnpkg.com/rsvp/-/rsvp-3.6.2.tgz#2e96491599a96cde1b515d5674a8f7a91452926a" @@ -8697,7 +8936,7 @@ semver@^6.0.0, semver@^6.1.0, semver@^6.1.1, semver@^6.3.0: resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== -semver@^7.0.0, semver@^7.3.2: +semver@^7.0.0, semver@^7.2.1, semver@^7.3.2: version "7.3.2" resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.2.tgz#604962b052b81ed0786aae84389ffba70ffd3938" integrity sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ== @@ -8831,6 +9070,15 @@ slice-ansi@1.0.0: dependencies: is-fullwidth-code-point "^2.0.0" +slice-ansi@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-2.1.0.tgz#cacd7693461a637a5788d92a7dd4fba068e81636" + integrity sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ== + dependencies: + ansi-styles "^3.2.0" + astral-regex "^1.0.0" + is-fullwidth-code-point "^2.0.0" + snake-case@^3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/snake-case/-/snake-case-3.0.3.tgz#c598b822ab443fcbb145ae8a82c5e43526d5bbee" @@ -9140,6 +9388,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@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-4.0.0.tgz#9c3505c1db45bcedca3d9cf7a16f5c5aa3901878" @@ -9155,7 +9410,7 @@ strip-final-newline@^2.0.0: resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== -strip-json-comments@3.1.1: +strip-json-comments@3.1.1, strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== @@ -9240,6 +9495,16 @@ table@^5.0.2: slice-ansi "1.0.0" string-width "^2.1.1" +table@^5.2.3: + version "5.4.6" + resolved "https://registry.yarnpkg.com/table/-/table-5.4.6.tgz#1292d19500ce3f86053b05f0e8e7e4a3bb21079e" + integrity sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug== + dependencies: + ajv "^6.10.2" + lodash "^4.17.14" + slice-ansi "^2.1.0" + string-width "^3.0.0" + tap-parser@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/tap-parser/-/tap-parser-7.0.0.tgz#54db35302fda2c2ccc21954ad3be22b2cba42721" @@ -9506,6 +9771,13 @@ tslib@^1.10.0, tslib@^1.9.0: resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.10.0.tgz#c3c19f95973fb0a62973fb09d90d961ee43e5c8a" integrity sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ== +type-check@^0.4.0, type-check@~0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" + integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== + dependencies: + prelude-ls "^1.2.1" + type-check@~0.3.2: version "0.3.2" resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" @@ -9533,6 +9805,11 @@ type-fest@^0.11.0: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.11.0.tgz#97abf0872310fed88a5c466b25681576145e33f1" integrity sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ== +type-fest@^0.8.1: + version "0.8.1" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d" + integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== + type-is@~1.6.17, type-is@~1.6.18: version "1.6.18" resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" @@ -9720,6 +9997,11 @@ uuid@^8.3.0: resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.1.tgz#2ba2e6ca000da60fce5a196954ab241131e05a31" integrity sha512-FOmRr+FmWEIG8uhZv6C2bTgEVXsHk08kE7mPlrBbEe+c3r9pjceVPgupIfNIhc4yx55H69OXANrUaSuu9eInKg== +v8-compile-cache@^2.0.3: + version "2.2.0" + resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.2.0.tgz#9471efa3ef9128d2f7c6a7ca39c4dd6b5055b132" + integrity sha512-gTpR5XQNKFwOd4clxfnhaqvfqMpqEwr4tOtCyz4MtYZX2JYhfr1JvBFKdS+7K/9rfpZR3VLX+YWBbKoxCgS43Q== + validate-npm-package-name@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/validate-npm-package-name/-/validate-npm-package-name-3.0.0.tgz#5fa912d81eb7d0c74afc140de7317f0ca7df437e" @@ -9830,6 +10112,11 @@ wide-align@1.1.3, wide-align@^1.1.0: dependencies: string-width "^1.0.2 || 2" +word-wrap@^1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" + integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== + wordwrap@^0.0.3: version "0.0.3" resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107" @@ -9890,6 +10177,13 @@ write-file-atomic@^3.0.0: signal-exit "^3.0.2" typedarray-to-buffer "^3.1.5" +write@1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/write/-/write-1.0.3.tgz#0800e14523b923a387e415123c865616aae0f5c3" + integrity sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig== + dependencies: + mkdirp "^0.5.1" + write@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/write/-/write-0.2.1.tgz#5fc03828e264cea3fe91455476f7a3c566cb0757"