fix: types in renderers tests

paoloricciuti 1 month ago
parent 6ce5481b4e
commit 3bf1037afe

@ -8,7 +8,7 @@
import { createRenderer } from '../../src/renderer/index.js';
type ObjElement = {
export type ObjElement = {
type: 'element';
name: string;
attributes: Record<string, string>;
@ -29,7 +29,7 @@ export type ObjFragment = {
parent: ObjNode | null;
elements_children: Array<HTMLElement | DocumentFragment | Text | Comment>;
};
type ObjNode = ObjElement | ObjText | ObjComment | ObjFragment;
export type ObjNode = ObjElement | ObjText | ObjComment | ObjFragment;
function insert_node(
parent: ObjNode & { children?: ObjNode[] },

@ -1,8 +1,8 @@
import { test } from '../../test';
export default test({
test({ assert, target }) {
const elements = target.children.filter((/** @type {any} */ n) => n.type === 'element');
test({ assert, target, utils }) {
const elements = target.children.filter(utils.filter_elements());
assert.equal(elements.length, 4);

@ -1,7 +1,7 @@
import { test } from '../../test';
export default test({
test({ assert, target, serialize }) {
test({ assert, target, serialize, utils }) {
const html = serialize(target);
assert.equal(
html,
@ -9,17 +9,13 @@ export default test({
);
// Verify individual attribute access on the object node
const div = target.children.find(
(/** @type {any} */ n) => n.type === 'element' && n.name === 'div'
);
const div = target.children.find(utils.filter_elements((n) => n.name === 'div'));
assert.ok(div);
assert.equal(div.attributes['class'], 'container');
assert.equal(div.attributes['data-color'], 'red');
assert.equal(div?.attributes['class'], 'container');
assert.equal(div?.attributes['data-color'], 'red');
const span = div.children.find(
(/** @type {any} */ n) => n.type === 'element' && n.name === 'span'
);
const span = div?.children.find(utils.filter_elements((n) => n.name === 'span'));
assert.ok(span);
assert.equal(span.attributes['id'], 'label');
assert.equal(span?.attributes['id'], 'label');
}
});

@ -2,13 +2,9 @@ import { flushSync } from 'svelte';
import { test } from '../../test';
export default test({
test({ assert, target, dispatch_event }) {
const inputs = target.children.filter(
(/** @type {any} */ n) => n.type === 'element' && n.name === 'input'
);
const button = target.children.find(
(/** @type {any} */ n) => n.type === 'element' && n.name === 'button'
);
test({ assert, target, dispatch_event, utils }) {
const inputs = target.children.filter(utils.filter_elements((n) => n.name === 'input'));
const button = target.children.find(utils.filter_elements((n) => n.name === 'button'));
assert.equal(inputs.length, 4);
assert.ok(button);

@ -2,19 +2,17 @@ import { flushSync } from 'svelte';
import { test } from '../../test';
export default test({
test({ assert, target, serialize, logs }) {
const button = target.children.find(
(/** @type {any} */ n) => n.type === 'element' && n.name === 'button'
);
test({ assert, target, utils, logs }) {
const button = target.children.find(utils.filter_elements((n) => n.name === 'button'));
assert.ok(button);
const listeners = button.listeners?.click;
const listeners = button?.listeners?.click;
assert.ok(listeners, 'button should have click listeners');
// Call the handler with multiple arguments.
// Custom renderers may pass multiple arguments to event handlers,
// so we need to make sure all arguments are forwarded.
for (const { handler } of listeners) {
for (const { handler } of listeners ?? []) {
handler.call(button, { type: 'click' }, 'extra', 42);
}
flushSync();

@ -3,19 +3,17 @@ import { test } from '../../test';
export default test({
html: '<button>click me</button> <p>0</p>',
test({ assert, target, serialize, logs }) {
const button = target.children.find(
(/** @type {any} */ n) => n.type === 'element' && n.name === 'button'
);
test({ assert, target, serialize, logs, utils }) {
const button = target.children.find(utils.filter_elements((n) => n.name === 'button'));
assert.ok(button);
const listeners = button.listeners?.click;
const listeners = button?.listeners?.click;
assert.ok(listeners, 'button should have click listeners');
// Call the handler with multiple arguments.
// Custom renderers may pass multiple arguments to event handlers,
// so we need to make sure all arguments are forwarded through spreads too.
for (const { handler } of listeners) {
for (const { handler } of listeners ?? []) {
handler.call(button, { type: 'click' }, 'extra', 42);
}
flushSync();

@ -2,23 +2,19 @@ import { test } from '../../test';
export default test({
html: '<select value="b"><option value="a">A</option><option value="b">B</option><option value="c">C</option></select> <p>b</p>',
test({ assert, target, serialize }) {
const select = target.children.find(
(/** @type {any} */ n) => n.type === 'element' && n.name === 'select'
);
test({ assert, target, serialize, utils }) {
const select = target.children.find(utils.filter_elements((n) => n.name === 'select'));
assert.ok(select);
// The select element should have a value attribute set via the normal attribute path
assert.equal(select.attributes['value'], 'b');
assert.equal(select?.attributes['value'], 'b');
// Each option should have its value as a regular attribute
const options = select.children.filter(
(/** @type {any} */ n) => n.type === 'element' && n.name === 'option'
);
assert.equal(options.length, 3);
assert.equal(options[0].attributes['value'], 'a');
assert.equal(options[1].attributes['value'], 'b');
assert.equal(options[2].attributes['value'], 'c');
const options = select?.children.filter(utils.filter_elements((n) => n.name === 'option'));
assert.equal(options?.length, 3);
assert.equal(options?.[0]?.attributes['value'], 'a');
assert.equal(options?.[1]?.attributes['value'], 'b');
assert.equal(options?.[2]?.attributes['value'], 'c');
const html = serialize(target);
assert.equal(

@ -2,14 +2,10 @@ import { flushSync } from 'svelte';
import { test } from '../../test';
export default test({
test({ assert, target, dispatch_event }) {
test({ assert, utils, target, dispatch_event }) {
// Find all inputs and the button
const inputs = target.children.filter(
(/** @type {any} */ n) => n.type === 'element' && n.name === 'input'
);
const button = target.children.find(
(/** @type {any} */ n) => n.type === 'element' && n.name === 'button'
);
const inputs = target.children.filter(utils.filter_elements((n) => n.name === 'input'));
const button = target.children.find(utils.filter_elements((n) => n.name === 'button'));
assert.equal(inputs.length, 5);
assert.ok(button);

@ -1,18 +1,16 @@
import { test } from '../../test';
export default test({
test({ assert, target }) {
test({ assert, target, utils }) {
// If we got here, the component mounted without crashing on document.body access.
// Verify autofocus is set as a regular attribute.
const input = target.children.find(
(/** @type {any} */ n) => n.type === 'element' && n.name === 'input'
);
const input = target.children.find(utils.filter_elements((n) => n.name === 'input'));
assert.ok(input, 'input element should exist');
assert.equal(
input.attributes['autofocus'],
input?.attributes['autofocus'],
'true',
'autofocus should be set as a regular attribute'
);
assert.equal(input.attributes['value'], 'test', 'value should be set as a regular attribute');
assert.equal(input?.attributes['value'], 'test', 'value should be set as a regular attribute');
}
});

@ -5,7 +5,14 @@ import { assert } from 'vitest';
import { compile_directory } from '../helpers.js';
import { suite_with_variants, type BaseTest } from '../suite.js';
import type { CompileOptions } from '#compiler';
import renderer, { create_root, serialize, dispatch_event, type ObjFragment } from './renderer.js';
import renderer, {
create_root,
serialize,
dispatch_event,
type ObjFragment,
type ObjElement,
type ObjNode
} from './renderer.js';
import { writeFile } from 'node:fs/promises';
import { globSync } from 'tinyglobby';
import { hydrate, unmount } from 'svelte';
@ -52,6 +59,15 @@ interface CustomRendererHydrateTest extends BaseTest {
}) => void | Promise<void>;
}
function filter_elements(extra_filter?: (node: ObjElement) => boolean) {
return (node: ObjNode): node is ObjElement =>
node.type === 'element' && (extra_filter?.(node) ?? true);
}
const utils = {
filter_elements
};
interface CustomRendererNonHydrateTest extends BaseTest {
html?: string;
compileOptions?: Partial<CompileOptions>;
@ -65,6 +81,9 @@ interface CustomRendererNonHydrateTest extends BaseTest {
runtime_error?: string;
warnings?: string[];
test?: (args: {
utils: {
filter_elements: typeof filter_elements;
};
assert: Assert;
target: ObjFragment;
component: Record<string, any>;
@ -249,6 +268,7 @@ async function run_test(cwd: string, config: CustomRendererTest, compile_options
try {
if (config.test) {
await config.test({
utils,
assert,
target: target as never,
component: component ?? {},
@ -317,6 +337,7 @@ async function run_hydration_test(
try {
if (config.test) {
await config.test({
utils,
assert,
target: target as never,
component,

Loading…
Cancel
Save