From 9d0a18ad327c60697e0cc93f305b19ec4961f42f Mon Sep 17 00:00:00 2001 From: Yehuda Katz Date: Tue, 22 Oct 2024 19:09:03 -0700 Subject: [PATCH] Add more shadowing tests --- .../tests/integration/helpers/array-test.js | 23 +++++++++++- .../tests/integration/helpers/fn-test.js | 20 ++++++++++- .../tests/integration/helpers/get-test.js | 13 ++++++- .../tests/integration/helpers/hash-test.js | 17 ++++++++- .../lib/test-cases/rendering.ts | 36 +++++++++++++------ 5 files changed, 94 insertions(+), 15 deletions(-) diff --git a/packages/@ember/-internals/glimmer/tests/integration/helpers/array-test.js b/packages/@ember/-internals/glimmer/tests/integration/helpers/array-test.js index 1b223a10522..6f8df0dfba8 100644 --- a/packages/@ember/-internals/glimmer/tests/integration/helpers/array-test.js +++ b/packages/@ember/-internals/glimmer/tests/integration/helpers/array-test.js @@ -1,4 +1,10 @@ -import { RenderingTestCase, moduleFor, strip, runTask } from 'internal-test-helpers'; +import { + RenderingTestCase, + defineComponent, + moduleFor, + runTask, + strip, +} from 'internal-test-helpers'; import { set } from '@ember/object'; @@ -20,6 +26,21 @@ moduleFor( this.assertStableRerender(); } + ['@test the array helper can be shadowed']() { + function array(...list) { + return list.map((n) => n * 2); + } + + let First = defineComponent({ array }, `{{#each (array 1 2 3) as |n|}}[{{n}}]{{/each}}`); + + let Root = defineComponent( + { shadowArray: array, First }, + `{{#let shadowArray as |array|}}{{#each (array 5 10 15) as |n|}}[{{n}}]{{/each}}{{/let}}` + ); + + this.renderComponent(Root, { expect: '[10][20][30][2][4][6]' }); + } + ['@test can have more than one value']() { this.render(strip` {{#let (array "Sergio" "Robert") as |people|}} diff --git a/packages/@ember/-internals/glimmer/tests/integration/helpers/fn-test.js b/packages/@ember/-internals/glimmer/tests/integration/helpers/fn-test.js index 6b32ac4e715..faec2af6d37 100644 --- a/packages/@ember/-internals/glimmer/tests/integration/helpers/fn-test.js +++ b/packages/@ember/-internals/glimmer/tests/integration/helpers/fn-test.js @@ -1,6 +1,6 @@ import { set } from '@ember/object'; import { DEBUG } from '@glimmer/env'; -import { RenderingTestCase, moduleFor, runTask } from 'internal-test-helpers'; +import { RenderingTestCase, defineComponent, moduleFor, runTask } from 'internal-test-helpers'; import { Component } from '../../utils/helpers'; moduleFor( @@ -22,6 +22,14 @@ moduleFor( }); } + '@test fn can be shadowed'() { + let First = defineComponent( + { fn: boundFn, boundFn, id, invoke }, + `[{{invoke (fn id 1)}}]{{#let boundFn as |fn|}}[{{invoke (fn id 2)}}{{/let}}]` + ); + this.renderComponent(First, { expect: `[bound:1][bound:2]` }); + } + '@test updates when arguments change'() { this.render(`{{invoke (fn this.myFunc this.arg1 this.arg2)}}`, { myFunc(arg1, arg2) { @@ -209,3 +217,13 @@ moduleFor( } } ); + +function invoke(fn) { + return fn(); +} + +function boundFn(fn, ...args) { + return () => fn(...args.map((arg) => `bound:${arg}`)); +} + +let id = (arg) => arg; diff --git a/packages/@ember/-internals/glimmer/tests/integration/helpers/get-test.js b/packages/@ember/-internals/glimmer/tests/integration/helpers/get-test.js index d2946f5ea2e..ed10706ca21 100644 --- a/packages/@ember/-internals/glimmer/tests/integration/helpers/get-test.js +++ b/packages/@ember/-internals/glimmer/tests/integration/helpers/get-test.js @@ -1,4 +1,4 @@ -import { RenderingTestCase, moduleFor, runTask } from 'internal-test-helpers'; +import { RenderingTestCase, defineComponent, moduleFor, runTask } from 'internal-test-helpers'; import { set, get } from '@ember/object'; @@ -32,6 +32,17 @@ moduleFor( this.assertText('[red] [red]'); } + ['@test can be shadowed']() { + let get = (obj, key) => `obj.${key}=${obj[key]}`; + let obj = { apple: 'red', banana: 'yellow' }; + let Root = defineComponent( + { get, outerGet: get, obj }, + `[{{get obj 'apple'}}][{{#let outerGet as |get|}}{{get obj 'banana'}}{{/let}}]` + ); + + this.renderComponent(Root, { expect: '[obj.apple=red][obj.banana=yellow]' }); + } + ['@test should be able to get an object value with nested static key']() { this.render( `[{{get this.colors "apple.gala"}}] [{{if true (get this.colors "apple.gala")}}]`, diff --git a/packages/@ember/-internals/glimmer/tests/integration/helpers/hash-test.js b/packages/@ember/-internals/glimmer/tests/integration/helpers/hash-test.js index 0650980b24a..9db64f7a72e 100644 --- a/packages/@ember/-internals/glimmer/tests/integration/helpers/hash-test.js +++ b/packages/@ember/-internals/glimmer/tests/integration/helpers/hash-test.js @@ -1,4 +1,4 @@ -import { RenderingTestCase, moduleFor, runTask } from 'internal-test-helpers'; +import { RenderingTestCase, defineComponent, moduleFor, runTask } from 'internal-test-helpers'; import { Component } from '../../utils/helpers'; @@ -17,6 +17,21 @@ moduleFor( this.assertText('Sergio'); } + ['@test can be shadowed']() { + let hash = (obj) => + Object.entries(obj) + .map(([key, value]) => `hash:${key}=${value}`) + .join(','); + let Root = defineComponent( + { hash, shadowHash: hash }, + `({{hash apple='red' banana='yellow'}}) ({{#let shadowHash as |hash|}}{{hash apple='green'}}{{/let}})` + ); + + this.renderComponent(Root, { + expect: '(hash:apple=red,hash:banana=yellow) (hash:apple=green)', + }); + } + ['@test can have more than one key-value']() { this.render( `{{#let (hash name="Sergio" lastName="Arbeo") as |person|}}{{person.name}} {{person.lastName}}{{/let}}` diff --git a/packages/internal-test-helpers/lib/test-cases/rendering.ts b/packages/internal-test-helpers/lib/test-cases/rendering.ts index 27de1e8f693..8c8322fa48a 100644 --- a/packages/internal-test-helpers/lib/test-cases/rendering.ts +++ b/packages/internal-test-helpers/lib/test-cases/rendering.ts @@ -1,19 +1,19 @@ -import type { EmberPrecompileOptions } from 'ember-template-compiler'; -import { compile } from 'ember-template-compiler'; -import { EventDispatcher } from '@ember/-internals/views'; import type { Renderer } from '@ember/-internals/glimmer'; +import { _resetRenderers, helper, Helper } from '@ember/-internals/glimmer'; +import { EventDispatcher } from '@ember/-internals/views'; import Component, { setComponentTemplate } from '@ember/component'; -import { helper, Helper, _resetRenderers } from '@ember/-internals/glimmer'; +import type { EmberPrecompileOptions } from 'ember-template-compiler'; +import { compile } from 'ember-template-compiler'; import type Resolver from '../test-resolver'; import { ModuleBasedResolver } from '../test-resolver'; -import AbstractTestCase from './abstract'; -import buildOwner from '../build-owner'; -import { runAppend, runDestroy, runTask } from '../run'; import type { InternalFactory } from '@ember/-internals/owner'; -import type { BootOptions, EngineInstanceOptions } from '@ember/engine/instance'; -import type EngineInstance from '@ember/engine/instance'; import templateOnly from '@ember/component/template-only'; +import type EngineInstance from '@ember/engine/instance'; +import type { BootOptions, EngineInstanceOptions } from '@ember/engine/instance'; +import buildOwner from '../build-owner'; +import { runAppend, runDestroy, runTask } from '../run'; +import AbstractTestCase from './abstract'; const TextNode = window.Text; @@ -172,6 +172,13 @@ export default abstract class RenderingTestCase extends AbstractTestCase { runAppend(this.component); } + renderComponent(component: object, options: { expect: string }) { + this.registerComponent('root', { ComponentClass: component }); + this.render(''); + this.assertHTML(options.expect); + this.assertStableRerender(); + } + rerender() { this.component!.rerender(); } @@ -195,14 +202,21 @@ export default abstract class RenderingTestCase extends AbstractTestCase { registerComponent( name: string, - { ComponentClass = Component, template = null, resolveableTemplate = null } + { + ComponentClass = Component, + template = null, + resolveableTemplate = null, + }: { + ComponentClass?: object | null; + template?: string | null; + resolveableTemplate?: string | null; + } ) { let { owner } = this; if (ComponentClass) { // We cannot set templates multiple times on a class if (ComponentClass === Component) { - // @ts-expect-error - class/instance types in TS are hard ComponentClass = class extends Component {}; }