Skip to content
This repository was archived by the owner on Dec 31, 2022. It is now read-only.

improve component blueprint for octane #213

Closed
wants to merge 14 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint-env node */
module.exports = {
root: true,
parserOptions: {
Expand Down
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ language: node_js
node_js:
# we recommend testing addons with the same minimum supported node version as Ember CLI
# so that your addon works for all apps
- "8"
- "12"

sudo: false
dist: trusty
Expand Down
58 changes: 52 additions & 6 deletions blueprints/component-test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,17 @@

const path = require('path');
const stringUtil = require('ember-cli-string-utils');
const isPackageMissing = require('ember-cli-is-package-missing');
const getPathOption = require('ember-cli-get-component-path-option');
const semver = require('semver');

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.',

Expand All @@ -23,7 +30,7 @@ module.exports = useTestFrameworkDetector({
},
],

fileMapTokens: function() {
fileMapTokens: function () {
return {
__root__() {
return 'tests';
Expand All @@ -40,7 +47,7 @@ module.exports = useTestFrameworkDetector({
};
},

locals: function(options) {
locals: function (options) {
let dasherizedModuleName = stringUtil.dasherize(options.entity.name);
let componentPathName = dasherizedModuleName;
let testType = options.testType || 'integration';
Expand All @@ -55,11 +62,50 @@ module.exports = useTestFrameworkDetector({
componentPathName = [options.path, dasherizedModuleName].filter(Boolean).join('/');
}

let hbsImportStatement = this._useNamedHbsImport()
? "import { hbs } from 'ember-cli-htmlbars';"
: "import hbs from 'htmlbars-inline-precompile';";

let templateInvocation = invocationFor(options);
let componentName = templateInvocation;
let openComponent = (descriptor) => `<${descriptor}>`;
let closeComponent = (descriptor) => `</${descriptor}>`;
let selfCloseComponent = (descriptor) => `<${descriptor} />`;

return {
path: getPathOption(options),
testType: testType,
componentPathName: componentPathName,
friendlyTestDescription: friendlyTestDescription,
componentName,
componentPathName,
templateInvocation,
openComponent,
closeComponent,
selfCloseComponent,
friendlyTestDescription,
hbsImportStatement,
};
}
});
},

_useNamedHbsImport() {
let htmlbarsAddon = this.project.addons.find((a) => a.name === 'ember-cli-htmlbars');

if (htmlbarsAddon && semver.gte(htmlbarsAddon.pkg.version, '4.0.0-alpha.1')) {
return true;
}

return false;
},

afterInstall: function (options) {
if (
!options.dryRun &&
options.testType === 'integration' &&
!this._useNamedHbsImport() &&
isPackageMissing(this, 'ember-cli-htmlbars-inline-precompile')
) {
return this.addPackagesToProject([
{ name: 'ember-cli-htmlbars-inline-precompile', target: '^0.3.1' },
]);
}
},
});
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,22 @@ describe('<%= friendlyTestDescription %>', function() {
it('renders', function() {
<% if (testType === 'integration' ) { %>// Set any properties with this.set('myProperty', 'value');
// Handle any actions with this.on('myAction', function(val) { ... });

this.render(hbs`<%= selfCloseComponent(componentName) %>`);
expect(this.$()).to.have.length(1);

// Template block usage:
// this.render(hbs`
// {{#<%= dasherizedModuleName %>}}
// template content
// {{/<%= dasherizedModuleName %>}}
// `);
this.render(hbs`
<%= openComponent(componentName) %>
template block text
<%= closeComponent(componentName) %>
`);

this.render(hbs`{{<%= dasherizedModuleName %>}}`);
expect(this.$()).to.have.length(1);<% } else if(testType === 'unit') { %>// creates the component instance
expect(this.$().text().trim()).to.equal('template block text');<% } else if(testType === 'unit') { %>// creates the component instance
let component = this.subject();
// renders the component on the page
this.render();
expect(component).to.be.ok;
expect(this.$()).to.have.length(1);<% } %>
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,23 @@ describeComponent('<%= componentPathName %>', '<%= friendlyTestDescription %>',
it('renders', function() {
<% if (testType === 'integration' ) { %>// Set any properties with this.set('myProperty', 'value');
// Handle any actions with this.on('myAction', function(val) { ... });

this.render(hbs`<%= selfCloseComponent(componentName) %>`);
expect(this.$()).to.have.length(1);

// Template block usage:
// this.render(hbs`
// {{#<%= dasherizedModuleName %>}}
// template content
// {{/<%= dasherizedModuleName %>}}
// `);
this.render(hbs`
<%= openComponent(componentName) %>
template block text
<%= closeComponent(componentName) %>
`);

this.render(hbs`{{<%= dasherizedModuleName %>}}`);
expect(this.$()).to.have.length(1);<% } else if(testType === 'unit') { %>// creates the component instance
expect(this.$().text().trim()).to.equal('template block text');<% } else if(testType === 'unit') { %>// creates the component instance
let component = this.subject();
// renders the component on the page
this.render();
expect(component).to.be.ok;
expect(this.$()).to.have.length(1);<% } %>
});
}
);
);
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import { describe, it } from 'mocha';
import { setupRenderingTest } from 'ember-mocha';
import { render } from '@ember/test-helpers';
import hbs from 'htmlbars-inline-precompile';
<%= hbsImportStatement %>

describe('<%= friendlyTestDescription %>', function() {
setupRenderingTest();
Expand All @@ -11,15 +11,15 @@ describe('<%= friendlyTestDescription %>', function() {
// Set any properties with this.set('myProperty', 'value');
// Handle any actions with this.set('myAction', function(val) { ... });

await render(hbs`{{<%= componentPathName %>}}`);
await render(hbs`<%= selfCloseComponent(componentName) %>`);

expect(this.element.textContent.trim()).to.equal('');

// Template block usage:
await render(hbs`
{{#<%= componentPathName %>}}
<%= openComponent(componentName) %>
template block text
{{/<%= componentPathName %>}}
<%= closeComponent(componentName) %>
`);

expect(this.element.textContent.trim()).to.equal('template block text');
Expand All @@ -35,4 +35,4 @@ describe('<%= friendlyTestDescription %>', function() {
let component = this.owner.factoryFor('component:<%= componentPathName %>').create();
expect(component).to.be.ok;
});
});<% } %>
});<% } %>
Original file line number Diff line number Diff line change
@@ -1,31 +1,36 @@
import { moduleForComponent, test } from 'ember-qunit';<% if (testType === 'integration') { %>
import hbs from 'htmlbars-inline-precompile';<% } %>

moduleForComponent('<%= componentPathName %>', '<%= friendlyTestDescription %>', {
<% if (testType === 'integration' ) { %>integration: true<% } else if(testType === 'unit') { %>// Specify the other units that are required for this test
// needs: ['component:foo', 'helper:bar'],
unit: true<% } %>
});

test('it renders', function(assert) {
<% if (testType === 'integration' ) { %>// Set any properties with this.set('myProperty', 'value');
// Handle any actions with this.on('myAction', function(val) { ... });

this.render(hbs`{{<%= componentPathName %>}}`);

assert.equal(this.$().text().trim(), '');

// Template block usage:
this.render(hbs`
{{#<%= componentPathName %>}}
template block text
{{/<%= componentPathName %>}}
`);

assert.equal(this.$().text().trim(), 'template block text');<% } else if(testType === 'unit') { %>
// Creates the component instance
/*let component =*/ this.subject();
// Renders the component to the page
this.render();
assert.equal(this.$().text().trim(), '');<% } %>
});
import hbs from 'htmlbars-inline-precompile';<% } %>
import { TestContext } from 'ember-test-helpers';

type Context = TestContext & {
// add your test properties here
}

moduleForComponent('<%= componentPathName %>', '<%= friendlyTestDescription %>', {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One thought: while we’re at it, we should, uhh, just get rid of the old-style moduleFor* blueprints. YIKES. I’d forgotten just how out of date our blueprints are. (Doesn’t have to be this PR.)

<% if (testType === 'integration' ) { %>integration: true<% } else if(testType === 'unit') { %>// Specify the other units that are required for this test
// needs: ['component:foo', 'helper:bar'],
unit: true<% } %>
});

test('it renders', function(this: Context, assert: Assert) {
<% if (testType === 'integration' ) { %>// Set any properties with this.set('myProperty', 'value');
// Handle any actions with this.on('myAction', function(val) { ... });

this.render(hbs`<%= selfCloseComponent(componentName) %>`);

assert.equal(this.$().text().trim(), '');

// Template block usage:
this.render(hbs`
<%= openComponent(componentName) %>
template block text
<%= closeComponent(componentName) %>
`);

assert.equal(this.$().text().trim(), 'template block text');<% } else if(testType === 'unit') { %>
// Creates the component instance
/*let component =*/ this.subject();
// Renders the component to the page
this.render();
assert.equal(this.$().text().trim(), '');<% } %>
});
Original file line number Diff line number Diff line change
@@ -1,36 +1,46 @@
<% if (testType === 'integration') { %>import { module, test } from 'qunit';
import { setupRenderingTest } from 'ember-qunit';
import { TestContext } from 'ember-test-helpers';
import { render } from '@ember/test-helpers';
import hbs from 'htmlbars-inline-precompile';
<%= hbsImportStatement %>

type Context = TestContext & {
// add your test properties here
}

module('<%= friendlyTestDescription %>', function(hooks) {
setupRenderingTest(hooks);

test('it renders', async function(assert) {
test('it renders', async function(this: Context, assert: Assert) {
// Set any properties with this.set('myProperty', 'value');
// Handle any actions with this.set('myAction', function(val) { ... });

await render(hbs`{{<%= componentPathName %>}}`);
await render(hbs`<%= selfCloseComponent(componentName) %>`);

assert.equal(this.element.textContent.trim(), '');

// Template block usage:
await render(hbs`
{{#<%= componentPathName %>}}
<%= openComponent(componentName) %>
template block text
{{/<%= componentPathName %>}}
<%= closeComponent(componentName) %>
`);

assert.equal(this.element.textContent.trim(), 'template block text');
});
});<% } else if (testType === 'unit') { %>import { module, test } from 'qunit';
import { setupTest } from 'ember-qunit';
import { TestContext } from 'ember-test-helpers';

type Context = TestContext & {
// add your test properties here
}

module('<%= friendlyTestDescription %>', function(hooks) {
setupTest(hooks);

test('it exists', function(assert) {
test('it exists', function(this: Context, assert: Assert) {
let component = this.owner.factoryFor('component:<%= componentPathName %>').create();
assert.ok(component);
});
});<% } %>
});<% } %>
5 changes: 1 addition & 4 deletions blueprints/component/files/__root__/__path__/__name__.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
import Component from '@ember/component';
<%= importTemplate %>
export default class <%= classifiedModuleName %> extends Component.extend({
// anything which *must* be merged to prototype here
}) {<%= contents %>
// normal class body definition here
export default class <%= classifiedModuleName %> extends Component {
};
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import Component from '@glimmer/component';

interface <%= classifiedModuleName %>Args {}
interface <%= classifiedModuleName %>Args {
// define component arguments here
}

export default class <%= classifiedModuleName %> extends Component<<%= classifiedModuleName %>Args> {}
export default class <%= classifiedModuleName %> extends Component<<%= classifiedModuleName %>Args> {
// class body definition here
};

This file was deleted.

This file was deleted.

1 change: 1 addition & 0 deletions jsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"compilerOptions":{"target":"es6","experimentalDecorators":true},"exclude":["node_modules","bower_components","tmp","vendor",".git","dist"]}
12 changes: 6 additions & 6 deletions lib/utilities/update-paths-for-addon.js
Original file line number Diff line number Diff line change
Expand Up @@ -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('/'));
Expand All @@ -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) {
Expand Down
Loading