Skip to content

Commit

Permalink
Implement supportsDataTestProperties to disable tagless component ass…
Browse files Browse the repository at this point in the history
…ertion
  • Loading branch information
Ben Demboski committed Dec 12, 2018
1 parent 4753fbb commit 160814c
Show file tree
Hide file tree
Showing 9 changed files with 88 additions and 9 deletions.
43 changes: 43 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,49 @@ export default Ember.Component({
As with `data-test-*` attributes in the templates, these properties, whether
computed or not, will be removed automatically in production builds.

### Usage with tagless components

Since tagless components do not have a root element, `data-test-*` attributes
passed to them cannot be bound to the DOM. If you try to pass a `data-test-*`
attribute to a tagless component, or define one in its Javascript class,
`ember-test-selectors` will throw an assertion error.

However, there are some cases where you might want to pass a `data-test-*`
attribute to a tagless component, for example a tagless wrapper component:

```js
// comment-wrapper.js
export default Ember.Component({
tagName: ''
})
```

```hbs
{{!-- comment-wrapper.hbs --}}
Comment:
{{comment-list-item comment=comment data-test-comment-id=data-test-comment-id}}
```

```handlebars
{{!-- comment-list.hbs --}}
{{#each comments as |comment|}}
{{comment-wrapper comment=comment data-test-comment-id=comment.id}}
{{/each}}
```

In this case, to prevent the assertion on the specific `comment-wrapper`
component, you can specify `supportsDataTestProperties` on the class:

```js
// comment-wrapper.js
export default Ember.Component({
tagName: '',
supportsDataTestProperties: true
})
```

`supportsDataTestProperties`, like `data-test-*` properties, will be stripped
from the build.

Configuration
------------------------------------------------------------------------------
Expand Down
14 changes: 8 additions & 6 deletions addon/utils/bind-data-test-attributes.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,16 @@ export default function bindDataTestAttributes(component) {
return;
}

let tagName = component.get('tagName');
if (!component.get('supportsDataTestProperties')) {
let tagName = component.get('tagName');

let message = `ember-test-selectors could not bind data-test-* properties on ${component} ` +
`automatically because tagName is empty.`;
let message = `ember-test-selectors could not bind data-test-* properties on ${component} ` +
`automatically because tagName is empty.`;

assert(message, tagName !== '', {
id: 'ember-test-selectors.empty-tag-name',
});
assert(message, tagName !== '', {
id: 'ember-test-selectors.empty-tag-name',
});
}

let attributeBindings = component.getWithDefault('attributeBindings', []);
if (!isArray(attributeBindings)) {
Expand Down
5 changes: 4 additions & 1 deletion node-tests/fixtures/default/expected.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,7 @@ exports['default'] = _ember2['default'].Component.extend({
foo: 'foo',
'data-test': 'test'
});
module.exports = exports['default'];
var c2 = _ember2['default'].Component.extend({
foo: 'foo'
});
exports.c2 = c2;
4 changes: 4 additions & 0 deletions node-tests/fixtures/default/expected6.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,7 @@ export default Ember.Component.extend({
foo: 'foo',
'data-test': 'test'
});

export let c2 = Ember.Component.extend({
foo: 'foo'
});
3 changes: 3 additions & 0 deletions node-tests/fixtures/default/expected7.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,6 @@ export default Ember.Component.extend({
foo: 'foo',
'data-test': 'test'
});
export let c2 = Ember.Component.extend({
foo: 'foo'
});
6 changes: 6 additions & 0 deletions node-tests/fixtures/default/fixture.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,10 @@ export default Ember.Component.extend({
'data-test-foobar': Ember.computed('data-test-foo', function() {
return `${this.get('data-test-foo')}bar`
}),
supportsDataTestProperties: true
});

export let c2 = Ember.Component.extend({
foo: 'foo',
'supportsDataTestProperties': true
});
4 changes: 3 additions & 1 deletion strip-data-test-properties-plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@
/* eslint-env node */

let TEST_SELECTOR_PREFIX = /data-test-.*/;
let SUPPORTS_DATA_TEST_PROP = 'supportsDataTestProperties';

function StripDataTestPropertiesPlugin(babel) {
return new babel.Plugin('ember-test-selectors', {
visitor: {
Property(node) {
if (TEST_SELECTOR_PREFIX.test(node.key.value)) {
let nodeName = node.key.name || node.key.value;
if (TEST_SELECTOR_PREFIX.test(nodeName) || nodeName === SUPPORTS_DATA_TEST_PROP) {
this.dangerouslyRemove();
}
},
Expand Down
4 changes: 3 additions & 1 deletion strip-data-test-properties-plugin6.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@
/* eslint-env node */

let TEST_SELECTOR_PREFIX = /data-test-.*/;
let SUPPORTS_DATA_TEST_PROP = 'supportsDataTestProperties';

function StripDataTestPropertiesPlugin() {
return {
visitor: {
Property(path) {
if (TEST_SELECTOR_PREFIX.test(path.node.key.value)) {
let nodeName = path.node.key.name || path.node.key.value;
if (TEST_SELECTOR_PREFIX.test(nodeName) || nodeName === SUPPORTS_DATA_TEST_PROP) {
path.remove();
}
},
Expand Down
14 changes: 14 additions & 0 deletions tests/unit/utils/bind-data-test-attributes-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,20 @@ test('it breaks if tagName is empty', function(assert) {
assert.throws(() => bindDataTestAttributes(instance));
});

test('it does not breaks if tagName is empty and supportsDataTestProperties is set', function(assert) {
let Fixture = EmberObject.extend({
tagName: '',
supportsDataTestProperties: true,
'data-test-from-factory': 'foo',
});
let instance = Fixture.create({
'data-test-from-invocation': 'bar',
});

bindDataTestAttributes(instance);
assert.ok(true, 'did not throw');
});

test('issue #106', function(assert) {
let Component = EmberObject.extend({});

Expand Down

0 comments on commit 160814c

Please sign in to comment.