From f4e66fe56f7bdeb8dfe6e2c5ebb5a1886aa96089 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Wed, 6 May 2026 23:15:11 +0000
Subject: [PATCH 1/3] Initial plan
From 0743417797da59fe91030bf82316b1b575ad674f Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Thu, 7 May 2026 00:06:28 +0000
Subject: [PATCH 2/3] Add tests for inline if/unless with arg as condition [GH
#21042]
Agent-Logs-Url: https://github.com/emberjs/ember.js/sessions/eeaec1fb-7e92-497a-9eae-adcc5fbc23b9
Co-authored-by: NullVoxPopuli <199018+NullVoxPopuli@users.noreply.github.com>
---
.../integration-tests/test/updating-test.ts | 92 +++++++++++++++++++
1 file changed, 92 insertions(+)
diff --git a/packages/@glimmer-workspace/integration-tests/test/updating-test.ts b/packages/@glimmer-workspace/integration-tests/test/updating-test.ts
index 46f2c627834..2f4eda48a1e 100644
--- a/packages/@glimmer-workspace/integration-tests/test/updating-test.ts
+++ b/packages/@glimmer-workspace/integration-tests/test/updating-test.ts
@@ -792,6 +792,98 @@ class UpdatingTest extends RenderTest {
this.assertHTML('truthy', 'If the condition is true, the truthy value renders');
}
+ @test
+ 'if keyword in append position with arg as condition [GH emberjs/ember.js#21042]'() {
+ this.registerComponent('TemplateOnly', 'Foo', '{{if @condition "truthy"}}');
+ this.render('', {
+ condition: true,
+ });
+
+ this.assertHTML('truthy', 'Initial render');
+
+ this.rerender({ condition: false });
+ this.assertHTML('', 'If the condition is false nothing renders');
+
+ this.rerender({ condition: true });
+ this.assertHTML('truthy', 'If the condition is true, the truthy value renders');
+ }
+
+ @test
+ 'if keyword in append position with arg as condition with falsy [GH emberjs/ember.js#21042]'() {
+ this.registerComponent('TemplateOnly', 'Foo', '{{if @condition "truthy" "falsy"}}');
+ this.render('', {
+ condition: true,
+ });
+
+ this.assertHTML('truthy', 'Initial render');
+
+ this.rerender({ condition: false });
+ this.assertHTML('falsy', 'If the condition is false, the falsy value renders');
+
+ this.rerender({ condition: true });
+ this.assertHTML('truthy', 'If the condition is true, the truthy value renders');
+ }
+
+ @test
+ 'unless keyword in append position with arg as condition [GH emberjs/ember.js#21042]'() {
+ this.registerComponent('TemplateOnly', 'Foo', '{{unless @condition "falsy"}}');
+ this.render('', {
+ condition: false,
+ });
+
+ this.assertHTML('falsy', 'Initial render');
+
+ this.rerender({ condition: true });
+ this.assertHTML('', 'If the condition is true nothing renders');
+
+ this.rerender({ condition: false });
+ this.assertHTML('falsy', 'If the condition is false, the falsy value renders');
+ }
+
+ @test
+ 'unless keyword in append position with arg as condition with truthy [GH emberjs/ember.js#21042]'() {
+ this.registerComponent('TemplateOnly', 'Foo', '{{unless @condition "falsy" "truthy"}}');
+ this.render('', {
+ condition: false,
+ });
+
+ this.assertHTML('falsy', 'Initial render');
+
+ this.rerender({ condition: true });
+ this.assertHTML('truthy', 'If the condition is true, the truthy value renders');
+
+ this.rerender({ condition: false });
+ this.assertHTML('falsy', 'If the condition is false, the falsy value renders');
+ }
+
+ @test
+ 'if keyword in append position with @tracked arg as condition [GH emberjs/ember.js#21042]'() {
+ let parentInstance!: ParentComponent;
+
+ class ParentComponent extends GlimmerishComponent {
+ @tracked condition = true;
+
+ constructor(owner: object, args: Record) {
+ super(owner, args);
+ parentInstance = this;
+ }
+ }
+
+ this.registerComponent('TemplateOnly', 'Foo', '{{if @condition "truthy" "falsy"}}');
+ this.registerComponent('Glimmer', 'Parent', '', ParentComponent);
+ this.render('');
+
+ this.assertHTML('truthy', 'Initial render');
+
+ parentInstance.condition = false;
+ this.rerender();
+ this.assertHTML('falsy', 'If the condition is false, the falsy value renders');
+
+ parentInstance.condition = true;
+ this.rerender();
+ this.assertHTML('truthy', 'If the condition is true, the truthy value renders');
+ }
+
@test
'unless keyword in call position'() {
this.registerComponent('TemplateOnly', 'Foo', '{{@value}}');
From 13ad9c6ed61a4f1a459f1095e32cf2a8b0f0b2ee Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Thu, 7 May 2026 07:14:36 +0000
Subject: [PATCH 3/3] Fix inline if/unless with component args: add
VM_ASSERT_SAME_OP for component branch
Agent-Logs-Url: https://github.com/emberjs/ember.js/sessions/c9384514-8a79-4fd1-997c-859207137897
Co-authored-by: NullVoxPopuli <199018+NullVoxPopuli@users.noreply.github.com>
---
.../integration-tests/test/updating-test.ts | 109 ++++++++----------
.../lib/opcode-builder/helpers/stdlib.ts | 1 +
2 files changed, 46 insertions(+), 64 deletions(-)
diff --git a/packages/@glimmer-workspace/integration-tests/test/updating-test.ts b/packages/@glimmer-workspace/integration-tests/test/updating-test.ts
index 2f4eda48a1e..3f6eeff4b83 100644
--- a/packages/@glimmer-workspace/integration-tests/test/updating-test.ts
+++ b/packages/@glimmer-workspace/integration-tests/test/updating-test.ts
@@ -7,6 +7,7 @@ import { createComputeRef, createConstRef, createPrimitiveRef } from '@glimmer/r
import { consumeTag, createTag, dirtyTag } from '@glimmer/validator';
import {
assertNodeTagName,
+ defineComponent,
getElementByClassName,
getElementsByTagName,
GlimmerishComponent,
@@ -15,6 +16,7 @@ import {
stripTight,
test,
tracked,
+ trackedObj,
trimLines,
} from '@glimmer-workspace/integration-tests';
@@ -794,94 +796,73 @@ class UpdatingTest extends RenderTest {
@test
'if keyword in append position with arg as condition [GH emberjs/ember.js#21042]'() {
- this.registerComponent('TemplateOnly', 'Foo', '{{if @condition "truthy"}}');
- this.render('', {
- condition: true,
- });
+ const Ok = defineComponent({}, 'ok');
+ const Ko = defineComponent({}, 'ko');
+ const Flipper = defineComponent({ Ok, Ko }, '{{if @isOk Ok Ko}}');
- this.assertHTML('truthy', 'Initial render');
+ let args = trackedObj({ isOk: true });
- this.rerender({ condition: false });
- this.assertHTML('', 'If the condition is false nothing renders');
-
- this.rerender({ condition: true });
- this.assertHTML('truthy', 'If the condition is true, the truthy value renders');
- }
-
- @test
- 'if keyword in append position with arg as condition with falsy [GH emberjs/ember.js#21042]'() {
- this.registerComponent('TemplateOnly', 'Foo', '{{if @condition "truthy" "falsy"}}');
- this.render('', {
- condition: true,
- });
+ this.renderComponent(Flipper, args);
+ this.assertHTML('ok', 'Initial render');
- this.assertHTML('truthy', 'Initial render');
-
- this.rerender({ condition: false });
- this.assertHTML('falsy', 'If the condition is false, the falsy value renders');
+ args['isOk'] = false;
+ this.rerender();
+ this.assertHTML('ko', 'If the condition is false, the falsy component renders');
- this.rerender({ condition: true });
- this.assertHTML('truthy', 'If the condition is true, the truthy value renders');
+ args['isOk'] = true;
+ this.rerender();
+ this.assertHTML('ok', 'If the condition is true, the truthy component renders');
}
@test
'unless keyword in append position with arg as condition [GH emberjs/ember.js#21042]'() {
- this.registerComponent('TemplateOnly', 'Foo', '{{unless @condition "falsy"}}');
- this.render('', {
- condition: false,
- });
-
- this.assertHTML('falsy', 'Initial render');
+ const Ok = defineComponent({}, 'ok');
+ const Ko = defineComponent({}, 'ko');
+ const Flipper = defineComponent({ Ok, Ko }, '{{unless @isOk Ko Ok}}');
- this.rerender({ condition: true });
- this.assertHTML('', 'If the condition is true nothing renders');
+ let args = trackedObj({ isOk: false });
- this.rerender({ condition: false });
- this.assertHTML('falsy', 'If the condition is false, the falsy value renders');
- }
+ this.renderComponent(Flipper, args);
+ this.assertHTML('ko', 'Initial render');
- @test
- 'unless keyword in append position with arg as condition with truthy [GH emberjs/ember.js#21042]'() {
- this.registerComponent('TemplateOnly', 'Foo', '{{unless @condition "falsy" "truthy"}}');
- this.render('', {
- condition: false,
- });
-
- this.assertHTML('falsy', 'Initial render');
-
- this.rerender({ condition: true });
- this.assertHTML('truthy', 'If the condition is true, the truthy value renders');
+ args['isOk'] = true;
+ this.rerender();
+ this.assertHTML('ok', 'If the condition is true, the truthy component renders');
- this.rerender({ condition: false });
- this.assertHTML('falsy', 'If the condition is false, the falsy value renders');
+ args['isOk'] = false;
+ this.rerender();
+ this.assertHTML('ko', 'If the condition is false, the falsy component renders');
}
@test
'if keyword in append position with @tracked arg as condition [GH emberjs/ember.js#21042]'() {
- let parentInstance!: ParentComponent;
+ const Ok = defineComponent({}, 'ok');
+ const Ko = defineComponent({}, 'ko');
+ const Flipper = defineComponent({ Ok, Ko }, '{{if @isOk Ok Ko}}');
- class ParentComponent extends GlimmerishComponent {
- @tracked condition = true;
+ let instance!: { isOk: boolean };
- constructor(owner: object, args: Record) {
- super(owner, args);
- parentInstance = this;
- }
- }
+ const Demo = defineComponent({ Flipper }, '', {
+ definition: class extends GlimmerishComponent {
+ @tracked isOk = true;
- this.registerComponent('TemplateOnly', 'Foo', '{{if @condition "truthy" "falsy"}}');
- this.registerComponent('Glimmer', 'Parent', '', ParentComponent);
- this.render('');
+ constructor(owner: object, args: Record) {
+ super(owner, args);
+ instance = this;
+ }
+ },
+ });
- this.assertHTML('truthy', 'Initial render');
+ this.renderComponent(Demo);
+ this.assertHTML('ok', 'Initial render');
- parentInstance.condition = false;
+ instance.isOk = false;
this.rerender();
- this.assertHTML('falsy', 'If the condition is false, the falsy value renders');
+ this.assertHTML('ko', 'If the condition is false, the falsy component renders');
- parentInstance.condition = true;
+ instance.isOk = true;
this.rerender();
- this.assertHTML('truthy', 'If the condition is true, the truthy value renders');
+ this.assertHTML('ok', 'If the condition is true, the truthy component renders');
}
@test
diff --git a/packages/@glimmer/opcode-compiler/lib/opcode-builder/helpers/stdlib.ts b/packages/@glimmer/opcode-compiler/lib/opcode-builder/helpers/stdlib.ts
index 466add49cc9..4f4b29746ea 100644
--- a/packages/@glimmer/opcode-compiler/lib/opcode-builder/helpers/stdlib.ts
+++ b/packages/@glimmer/opcode-compiler/lib/opcode-builder/helpers/stdlib.ts
@@ -56,6 +56,7 @@ export function StdAppend(
if (typeof nonDynamicAppend === 'number') {
when(ContentType.Component, () => {
+ op(VM_ASSERT_SAME_OP);
op(VM_RESOLVE_CURRIED_COMPONENT_OP);
op(VM_PUSH_DYNAMIC_COMPONENT_INSTANCE_OP);
InvokeBareComponent(op);