Skip to content

Commit

Permalink
Implement gt helper
Browse files Browse the repository at this point in the history
It has lazy evaluation of the second argument, so it doesn't even get
read if the first argument is already undefined.
For now without an option to coerce strings to numbers.
  • Loading branch information
cibernox committed Nov 4, 2018
1 parent 95925ab commit 4fecacb
Show file tree
Hide file tree
Showing 3 changed files with 177 additions and 0 deletions.
38 changes: 38 additions & 0 deletions packages/@ember/-internals/glimmer/lib/helpers/gt.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { Arguments, CapturedArguments, VM } from '@glimmer/runtime';
import { InternalHelperReference } from '../utils/references';

/**
@module ember
*/

/**
Compares the two given values with >
Example:
```handlebars
{{gt age 17}}
{{! be true if `age` is > 17}}
```
@public
@method gt
@for Ember.Templates.helpers
@since 2.7.0
*/
function gt({ positional: { references } }: CapturedArguments) {
let left = references[0].value();
if (left === undefined || left === null) {
return false;
}
let right = references[1].value();
if (right === undefined || right === null) {
return false;
}
return left > right;
}

export default function(_vm: VM, args: Arguments) {
return new InternalHelperReference(gt, args.capture());
}
2 changes: 2 additions & 0 deletions packages/@ember/-internals/glimmer/lib/resolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import { default as array } from './helpers/array';
import { default as concat } from './helpers/concat';
import { default as eq } from './helpers/eq';
import { default as not } from './helpers/not';
import { default as gt } from './helpers/gt';
import { default as eachIn } from './helpers/each-in';
import { default as get } from './helpers/get';
import { default as hash } from './helpers/hash';
Expand Down Expand Up @@ -69,6 +70,7 @@ const BUILTINS_HELPERS = {
concat,
eq,
get,
gt,
hash,
array,
log,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
import { RenderingTest, moduleFor } from '../../utils/test-case';
import { set } from '@ember/-internals/metal';
import { Component } from '../../utils/helpers';
import { computed } from '@ember/-internals/metal';

moduleFor(
'Helpers test: {{gt}}',
class extends RenderingTest {
['@test returns true when the first static argument is bigger than the second one']() {
this.render(`{{gt 2 1}}`);
this.assertText('true');
}

['@test returns false when the first static argument is not bigger than the second one']() {
this.render(`{{gt 0 1}}`);
this.assertText('false');
}

['@test returns false when both arguments are the same']() {
this.render(`{{gt 1 1}}`);
this.assertText('false');
}

['@test it updates for bound arguments']() {
this.render(`{{gt left right}}`, { left: 1, right: 2 });

this.assertText('false');

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

this.assertText('false');

this.runTask(() => set(this.context, 'left', 3));

this.assertText('true');

this.runTask(() => set(this.context, 'right', 4));

this.assertText('false');

this.runTask(() => set(this.context, 'left', 5));

this.assertText('true');

this.runTask(() => set(this.context, 'right', 5));

this.assertText('false');
}

['@test it can be used as a sub-expression']() {
this.render(`{{if (gt left right) "yes" "no"}}`, { left: 1, right: 2 });

this.assertText('no');

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

this.assertText('no');

this.runTask(() => set(this.context, 'left', 3));

this.assertText('yes');

this.runTask(() => set(this.context, 'right', 4));

this.assertText('no');

this.runTask(() => {
set(this.context, 'left', 5);
set(this.context, 'right', 0);
});

this.assertText('yes');
}

['@test of the first argument is undefined, it never pulls the second argument']() {
let didInvokeLeft = false;
let didInvokeRight = false;
let FooBarComponent = Component.extend({
left: computed(function() {
didInvokeLeft = true;
return undefined;
}),
right: computed(function() {
didInvokeRight = true;
return 5;
}),
});

this.registerComponent('foo-bar', {
ComponentClass: FooBarComponent,
template: `{{gt left right}}`,
});

this.render(`{{foo-bar}}`, {});

this.assertText('false');

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

this.assertText('false');

this.assert.ok(didInvokeLeft, 'the `left` property was accessed');
this.assert.notOk(didInvokeRight, "the `right` property wasn't accessed");
}

['@test of the first argument is null, it never pulls the second argument']() {
let didInvokeLeft = false;
let didInvokeRight = false;
let FooBarComponent = Component.extend({
left: computed(function() {
didInvokeLeft = true;
return null;
}),
right: computed(function() {
didInvokeRight = true;
return 5;
}),
});

this.registerComponent('foo-bar', {
ComponentClass: FooBarComponent,
template: `{{gt left right}}`,
});

this.render(`{{foo-bar}}`, {});

this.assertText('false');

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

this.assertText('false');

this.assert.ok(didInvokeLeft, 'the `left` property was accessed');
this.assert.notOk(didInvokeRight, "the `right` property wasn't accessed");
}
}
);

0 comments on commit 4fecacb

Please sign in to comment.