Skip to content

Commit

Permalink
[FEATURE array-helper] Implement array helper RFC #318
Browse files Browse the repository at this point in the history
  • Loading branch information
josemarluedke committed Oct 8, 2018
1 parent 7116215 commit a86b037
Show file tree
Hide file tree
Showing 3 changed files with 241 additions and 0 deletions.
37 changes: 37 additions & 0 deletions packages/@ember/-internals/glimmer/lib/helpers/array.ts
@@ -0,0 +1,37 @@
import { Arguments, VM } from '@glimmer/runtime';

/**
@module ember
*/

/**
Use the `{{array}}` helper to create an array to pass as an option to your
components.
```handlebars
{{my-component people=(array
'Tom Dade'
'Yehuda Katz'
myOtherPerson)
}}
```
Would result in an object such as:
```js
['Tom Date', 'Yehuda Katz', this.get('myOtherPerson')]
```
Where the 3rd item in the array is bound to updates of the `myOtherPerson` property.
@method array
@for Ember.Templates.helpers
@param {Object} options
@return {Object} Array
@since 2.6.0
@public
*/

export default function(_vm: VM, args: Arguments) {
return args.positional.capture();
}
2 changes: 2 additions & 0 deletions packages/@ember/-internals/glimmer/lib/resolver.ts
Expand Up @@ -23,6 +23,7 @@ import { default as htmlSafeHelper } from './helpers/-html-safe';
import { default as inputTypeHelper } from './helpers/-input-type';
import { default as normalizeClassHelper } from './helpers/-normalize-class';
import { default as action } from './helpers/action';
import { default as array } from './helpers/array';
import { default as concat } from './helpers/concat';
import { default as eachIn } from './helpers/each-in';
import { default as get } from './helpers/get';
Expand Down Expand Up @@ -58,6 +59,7 @@ const BUILTINS_HELPERS = {
concat,
get,
hash,
array,
log,
mut,
'query-params': queryParams,
Expand Down
@@ -0,0 +1,202 @@
import { RenderingTest, moduleFor } from '../../utils/test-case';
import { strip } from '../../utils/abstract-test-case';
import { Component } from '../../utils/helpers';
import { set } from '@ember/-internals/metal';

moduleFor(
'Helpers test: {{array}}',
class extends RenderingTest {
['@test returns an array']() {
this.render(strip`{{#with (array \"Sergio\") as |people|}}
{{#each people as |personName|}}
{{personName}}
{{/each}}
{{/with}}`);

this.assertText('Sergio');

this.runTask(() => this.rerender());

this.assertText('Sergio');
}

['@test can have more than one value']() {
this.render(strip`{{#with (array \"Sergio\" \"Robert\") as |people|}}
{{#each people as |personName|}}
{{personName}},
{{/each}}
{{/with}}`);

this.assertText('Sergio,Robert,');

this.runTask(() => this.rerender());

this.assertText('Sergio,Robert,');
}

['@test binds values when variables are used']() {
this.render(
strip`{{#with (array personOne) as |people|}}
{{#each people as |personName|}}
{{personName}}
{{/each}}
{{/with}}`,
{
personOne: 'Tom',
}
);

this.assertText('Tom');

this.runTask(() => this.rerender());

this.assertText('Tom');

this.runTask(() => set(this.context, 'personOne', 'Yehuda'));

this.assertText('Yehuda');
}

['@test binds multiple values when variables are used']() {
this.render(
strip`{{#with (array personOne personTwo) as |people|}}
{{#each people as |personName|}}
{{personName}},
{{/each}}
{{/with}}`,
{
personOne: 'Tom',
personTwo: 'Yehuda',
}
);

this.assertText('Tom,Yehuda,');

this.runTask(() => this.rerender());

this.assertText('Tom,Yehuda,');

this.runTask(() => set(this.context, 'personOne', 'Sergio'));

this.assertText('Sergio,Yehuda,');

this.runTask(() => set(this.context, 'personTwo', 'Tom'));

this.assertText('Sergio,Tom,');
}

['@test array helpers can be nested']() {
this.render(
strip`{{#with (array (array personOne personTwo)) as |listOfPeople|}}
{{#each listOfPeople as |people|}}
List:
{{#each people as |personName|}}
{{personName}},
{{/each}}
{{/each}}
{{/with}}`,
{
personOne: 'Tom',
personTwo: 'Yehuda',
}
);

this.assertText('List:Tom,Yehuda,');

this.runTask(() => this.rerender());

this.assertText('List:Tom,Yehuda,');

this.runTask(() => set(this.context, 'personOne', 'Chad'));

this.assertText('List:Chad,Yehuda,');

this.runTask(() => set(this.context, 'personTwo', 'Balint'));

this.assertText('List:Chad,Balint,');
}

['@test should yield hash of an array of internal properties']() {
let fooBarInstance;
let FooBarComponent = Component.extend({
init() {
this._super();
fooBarInstance = this;
this.model = { personOne: 'Chad' };
},
});

this.registerComponent('foo-bar', {
ComponentClass: FooBarComponent,
template: `{{yield (hash people=(array model.personOne))}}`,
});

this.render(strip`{{#foo-bar as |values|}}
{{#each values.people as |personName|}}
{{personName}}
{{/each}}
{{/foo-bar}}`);

this.assertText('Chad');

this.runTask(() => this.rerender());

this.assertText('Chad');

this.runTask(() => set(fooBarInstance, 'model.personOne', 'Godfrey'));

this.assertText('Godfrey');

this.runTask(() => set(fooBarInstance, 'model', { personOne: 'Chad' }));

this.assertText('Chad');
}

['@test should yield hash of an array of internal and external properties']() {
let fooBarInstance;
let FooBarComponent = Component.extend({
init() {
this._super();
fooBarInstance = this;
this.model = { personOne: 'Chad' };
},
});

this.registerComponent('foo-bar', {
ComponentClass: FooBarComponent,
template: `{{yield (hash people=(array model.personOne personTwo))}}`,
});

this.render(
strip`{{#foo-bar personTwo=model.personTwo as |values|}}
{{#each values.people as |personName|}}
{{personName}},
{{/each}}
{{/foo-bar}}`,
{
model: { personTwo: 'Tom' },
}
);

this.assertText('Chad,Tom,');

this.runTask(() => this.rerender());

this.assertText('Chad,Tom,');

this.runTask(() => {
set(fooBarInstance, 'model.personOne', 'Godfrey');
set(this.context, 'model.personTwo', 'Yehuda');
});

this.assertText('Godfrey,Yehuda,');

this.runTask(() => {
set(fooBarInstance, 'model', { personOne: 'Chad' });
set(this.context, 'model', { personTwo: 'Tom' });
});

this.assertText('Chad,Tom,');
}
}
);

0 comments on commit a86b037

Please sign in to comment.