Skip to content
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
15 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions packages/@glimmer-workspace/integration-tests/lib/suites.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,11 @@ export * from './suites/entry-point';
export * from './suites/has-block';
export * from './suites/has-block-params';
export * from './suites/in-element';
export * from './suites/in-element-document-fragment';
export * from './suites/in-element-shadow-root';
export * from './suites/initial-render';
export * from './suites/scope';
export * from './suites/shadow-dom';
export * from './suites/shadowing';
export * from './suites/ssr';
export * from './suites/with-dynamic-vars';
Expand Down
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think these tests are all good

Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
import { RenderTest } from '../render-test';
import { test } from '../test-decorator';

export class InElementDocumentFragmentSuite extends RenderTest {
static suiteName = '#in-element (DocumentFragment)';

@test
'Renders curlies into a detached DocumentFragment'() {
const fragment = document.createDocumentFragment();

this.render('{{#in-element this.fragment}}[{{this.foo}}]{{/in-element}}', {
fragment,
foo: 'Hello Fragment!',
});

this.assert.strictEqual(
fragment.textContent,
'[Hello Fragment!]',
'content rendered in document fragment'
);
this.assertHTML('<!---->');
this.assertStableRerender();

this.rerender({ foo: 'Updated!' });
this.assert.strictEqual(
fragment.textContent,
'[Updated!]',
'content updated in document fragment'
);
this.assertHTML('<!---->');

this.rerender({ foo: 'Hello Fragment!' });
this.assert.strictEqual(
fragment.textContent,
'[Hello Fragment!]',
'content reverted in document fragment'
);
this.assertHTML('<!---->');
}

@test
'Renders curlies into a template.content fragment'() {
const templateEl = document.createElement('template');
const fragment = templateEl.content;

this.render('{{#in-element this.fragment}}[{{this.foo}}]{{/in-element}}', {
fragment,
foo: 'Hello Template Content!',
});

this.assert.strictEqual(
fragment.textContent,
'[Hello Template Content!]',
'content rendered in template.content fragment'
);
this.assertHTML('<!---->');
this.assertStableRerender();

this.rerender({ foo: 'Updated!' });
this.assert.strictEqual(
fragment.textContent,
'[Updated!]',
'content updated in template.content fragment'
);
this.assertHTML('<!---->');

this.rerender({ foo: 'Hello Template Content!' });
this.assert.strictEqual(
fragment.textContent,
'[Hello Template Content!]',
'content reverted in template.content fragment'
);
this.assertHTML('<!---->');
}

@test
'Renders elements into a fragment that is later attached to the DOM'() {
const fragment = document.createDocumentFragment();
const container = document.createElement('div');

this.render('{{#in-element this.fragment}}<p id="frag-p">{{this.message}}</p>{{/in-element}}', {
fragment,
message: 'in fragment',
});

this.assert.strictEqual(
fragment.querySelector('#frag-p')?.textContent,
'in fragment',
'content rendered in detached fragment'
);
this.assertHTML('<!---->');

// Attach fragment's children to the DOM
container.appendChild(fragment);
this.assert.strictEqual(
container.querySelector('#frag-p')?.textContent,
'in fragment',
'content is in the DOM after fragment is appended'
);
// Fragment itself is now empty (children moved to container)
this.assert.strictEqual(fragment.childNodes.length, 0, 'fragment is empty after append');
}

@test
'Multiple in-element calls to the same DocumentFragment'() {
const fragment = document.createDocumentFragment();

this.render(
'{{#in-element this.fragment}}[{{this.foo}}]{{/in-element}}' +
'{{#in-element this.fragment insertBefore=null}}[{{this.bar}}]{{/in-element}}',
{
fragment,
foo: 'first',
bar: 'second',
}
);

this.assert.ok(fragment.textContent?.includes('[first]'), 'first block present in fragment');
this.assert.ok(fragment.textContent?.includes('[second]'), 'second block present in fragment');
this.assertHTML('<!----><!---->');
this.assertStableRerender();

this.rerender({ foo: 'updated-first', bar: 'updated-second' });
this.assert.ok(
fragment.textContent?.includes('[updated-first]'),
'first block updated in fragment'
);
this.assert.ok(
fragment.textContent?.includes('[updated-second]'),
'second block updated in fragment'
);
this.assertHTML('<!----><!---->');
}

@test
'Multiple in-element calls to the same DocumentFragment with insertBefore=null'() {
const fragment = document.createDocumentFragment();

this.render(
'{{#in-element this.fragment insertBefore=null}}<p id="a">{{this.foo}}</p>{{/in-element}}' +
'{{#in-element this.fragment insertBefore=null}}<p id="b">{{this.bar}}</p>{{/in-element}}',
{
fragment,
foo: 'first',
bar: 'second',
}
);

// Use childNodes to query into the fragment since querySelector doesn't work on detached fragment nodes in all browsers
const nodes = Array.from(fragment.childNodes);
const pA = nodes.find((n) => (n as Element).id === 'a') as HTMLElement | undefined;
const pB = nodes.find((n) => (n as Element).id === 'b') as HTMLElement | undefined;

this.assert.strictEqual(pA?.textContent, 'first', 'first block appended to fragment');
this.assert.strictEqual(pB?.textContent, 'second', 'second block appended to fragment');
this.assertHTML('<!----><!---->');
this.assertStableRerender();

this.rerender({ foo: 'updated-first', bar: 'updated-second' });
this.assert.strictEqual(pA?.textContent, 'updated-first', 'first block updated in fragment');
this.assert.strictEqual(pB?.textContent, 'updated-second', 'second block updated in fragment');
this.assertHTML('<!----><!---->');
}
}
Loading
Loading