mirror of
https://github.com/withastro/astro.git
synced 2024-12-30 22:03:56 -05:00
Fix: plain string children bug (#138)
* fix: string children bug * test: add string children test * test: add other child test scenarios
This commit is contained in:
parent
6bc51facce
commit
633bb46dc4
9 changed files with 172 additions and 4 deletions
|
@ -16,7 +16,10 @@ function childrenToTree(children: string[]) {
|
||||||
*/
|
*/
|
||||||
export const childrenToVnodes = moize.deep(function childrenToVnodes(h: any, children: string[]) {
|
export const childrenToVnodes = moize.deep(function childrenToVnodes(h: any, children: string[]) {
|
||||||
const tree = childrenToTree(children);
|
const tree = childrenToTree(children);
|
||||||
const vnodes = tree.map((subtree) => toH(h, subtree));
|
const vnodes = tree.map((subtree) => {
|
||||||
|
if (subtree.type === 'text') return subtree.value;
|
||||||
|
return toH(h, subtree);
|
||||||
|
});
|
||||||
return vnodes;
|
return vnodes;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -37,11 +40,13 @@ export const childrenToH = moize.deep(function childrenToH(renderer: ComponentRe
|
||||||
return { ...vnode, __SERIALIZED };
|
return { ...vnode, __SERIALIZED };
|
||||||
};
|
};
|
||||||
const serializeChild = (child: unknown) => {
|
const serializeChild = (child: unknown) => {
|
||||||
if (typeof child === 'string') return `\`${child}\``;
|
if (['string', 'number', 'boolean'].includes(typeof child)) return JSON.stringify(child);
|
||||||
if (typeof child === 'number' || typeof child === 'boolean') return `${child}`;
|
|
||||||
if (child === null) return `null`;
|
if (child === null) return `null`;
|
||||||
if ((child as any).__SERIALIZED) return (child as any).__SERIALIZED;
|
if ((child as any).__SERIALIZED) return (child as any).__SERIALIZED;
|
||||||
return innerH(child).__SERIALIZED;
|
return innerH(child).__SERIALIZED;
|
||||||
};
|
};
|
||||||
return tree.map((subtree) => toH(innerH, subtree).__SERIALIZED);
|
return tree.map((subtree) => {
|
||||||
|
if (subtree.type === 'text') return JSON.stringify(subtree.value);
|
||||||
|
return toH(innerH, subtree).__SERIALIZED
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
75
test/astro-children.test.js
Normal file
75
test/astro-children.test.js
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
import { suite } from 'uvu';
|
||||||
|
import * as assert from 'uvu/assert';
|
||||||
|
import { doc } from './test-utils.js';
|
||||||
|
import { setup, setupBuild } from './helpers.js';
|
||||||
|
|
||||||
|
const ComponentChildren = suite('Component children tests');
|
||||||
|
|
||||||
|
setup(ComponentChildren, './fixtures/astro-children');
|
||||||
|
setupBuild(ComponentChildren, './fixtures/astro-children');
|
||||||
|
|
||||||
|
ComponentChildren('Passes string children to framework components', async ({ runtime }) => {
|
||||||
|
let result = await runtime.load('/strings');
|
||||||
|
|
||||||
|
assert.equal(result.statusCode, 200);
|
||||||
|
const $ = doc(result.contents);
|
||||||
|
|
||||||
|
const $preact = $('#preact');
|
||||||
|
assert.equal($preact.text().trim(), 'Hello world', 'Can pass text to Preact components');
|
||||||
|
|
||||||
|
const $vue = $('#vue');
|
||||||
|
assert.equal($vue.text().trim(), 'Hello world', 'Can pass text to Vue components');
|
||||||
|
|
||||||
|
const $svelte = $('#svelte');
|
||||||
|
assert.equal($svelte.text().trim(), 'Hello world', 'Can pass text to Svelte components');
|
||||||
|
});
|
||||||
|
|
||||||
|
ComponentChildren('Passes markup children to framework components', async ({ runtime }) => {
|
||||||
|
let result = await runtime.load('/markup');
|
||||||
|
|
||||||
|
assert.equal(result.statusCode, 200);
|
||||||
|
const $ = doc(result.contents);
|
||||||
|
|
||||||
|
const $preact = $('#preact > h1');
|
||||||
|
assert.equal($preact.text().trim(), 'Hello world', 'Can pass markup to Preact components');
|
||||||
|
|
||||||
|
const $vue = $('#vue > h1');
|
||||||
|
assert.equal($vue.text().trim(), 'Hello world', 'Can pass markup to Vue components');
|
||||||
|
|
||||||
|
const $svelte = $('#svelte > h1');
|
||||||
|
assert.equal($svelte.text().trim(), 'Hello world', 'Can pass markup to Svelte components');
|
||||||
|
});
|
||||||
|
|
||||||
|
ComponentChildren('Passes multiple children to framework components', async ({ runtime }) => {
|
||||||
|
let result = await runtime.load('/multiple');
|
||||||
|
|
||||||
|
assert.equal(result.statusCode, 200);
|
||||||
|
const $ = doc(result.contents);
|
||||||
|
|
||||||
|
const $preact = $('#preact');
|
||||||
|
assert.equal($preact.children().length, 2, 'Can pass multiple children to Preact components');
|
||||||
|
assert.equal($preact.children(':first-child').text().trim(), 'Hello world');
|
||||||
|
assert.equal($preact.children(':last-child').text().trim(), 'Goodbye world');
|
||||||
|
|
||||||
|
const $vue = $('#vue');
|
||||||
|
assert.equal($vue.children().length, 2, 'Can pass multiple children to Vue components');
|
||||||
|
assert.equal($vue.children(':first-child').text().trim(), 'Hello world');
|
||||||
|
assert.equal($vue.children(':last-child').text().trim(), 'Goodbye world');
|
||||||
|
|
||||||
|
const $svelte = $('#svelte');
|
||||||
|
assert.equal($svelte.children().length, 2, 'Can pass multiple children to Svelte components');
|
||||||
|
assert.equal($svelte.children(':first-child').text().trim(), 'Hello world');
|
||||||
|
assert.equal($svelte.children(':last-child').text().trim(), 'Goodbye world');
|
||||||
|
});
|
||||||
|
|
||||||
|
ComponentChildren('Can be built', async ({ build }) => {
|
||||||
|
try {
|
||||||
|
await build();
|
||||||
|
assert.ok(true, 'Can build a project with component children');
|
||||||
|
} catch (err) {
|
||||||
|
console.log(err);
|
||||||
|
assert.ok(false, 'build threw');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
ComponentChildren.run();
|
5
test/fixtures/astro-children/astro.config.mjs
vendored
Normal file
5
test/fixtures/astro-children/astro.config.mjs
vendored
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
export default {
|
||||||
|
extensions: {
|
||||||
|
'.jsx': 'preact'
|
||||||
|
},
|
||||||
|
};
|
5
test/fixtures/astro-children/src/components/Component.jsx
vendored
Normal file
5
test/fixtures/astro-children/src/components/Component.jsx
vendored
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
import { h } from 'preact';
|
||||||
|
|
||||||
|
export default function PreactComponent({ children }) {
|
||||||
|
return <div id="preact">{children}</div>
|
||||||
|
}
|
3
test/fixtures/astro-children/src/components/Component.svelte
vendored
Normal file
3
test/fixtures/astro-children/src/components/Component.svelte
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
<div id="svelte">
|
||||||
|
<slot />
|
||||||
|
</div>
|
9
test/fixtures/astro-children/src/components/Component.vue
vendored
Normal file
9
test/fixtures/astro-children/src/components/Component.vue
vendored
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
<template>
|
||||||
|
<div id="vue">
|
||||||
|
<slot />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {}
|
||||||
|
</script>
|
21
test/fixtures/astro-children/src/pages/markup.astro
vendored
Normal file
21
test/fixtures/astro-children/src/pages/markup.astro
vendored
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
---
|
||||||
|
import PreactComponent from '../components/Component.jsx';
|
||||||
|
import VueComponent from '../components/Component.vue';
|
||||||
|
import SvelteComponent from '../components/Component.svelte';
|
||||||
|
---
|
||||||
|
<html>
|
||||||
|
<head><title>Children</title></head>
|
||||||
|
<body>
|
||||||
|
<PreactComponent>
|
||||||
|
<h1>Hello world</h1>
|
||||||
|
</PreactComponent>
|
||||||
|
|
||||||
|
<VueComponent>
|
||||||
|
<h1>Hello world</h1>
|
||||||
|
</VueComponent>
|
||||||
|
|
||||||
|
<SvelteComponent>
|
||||||
|
<h1>Hello world</h1>
|
||||||
|
</SvelteComponent>
|
||||||
|
</body>
|
||||||
|
</html>
|
24
test/fixtures/astro-children/src/pages/multiple.astro
vendored
Normal file
24
test/fixtures/astro-children/src/pages/multiple.astro
vendored
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
---
|
||||||
|
import PreactComponent from '../components/Component.jsx';
|
||||||
|
import VueComponent from '../components/Component.vue';
|
||||||
|
import SvelteComponent from '../components/Component.svelte';
|
||||||
|
---
|
||||||
|
<html>
|
||||||
|
<head><title>Children</title></head>
|
||||||
|
<body>
|
||||||
|
<PreactComponent>
|
||||||
|
<h1>Hello world</h1>
|
||||||
|
<h1>Goodbye world</h1>
|
||||||
|
</PreactComponent>
|
||||||
|
|
||||||
|
<VueComponent>
|
||||||
|
<h1>Hello world</h1>
|
||||||
|
<h1>Goodbye world</h1>
|
||||||
|
</VueComponent>
|
||||||
|
|
||||||
|
<SvelteComponent>
|
||||||
|
<h1>Hello world</h1>
|
||||||
|
<h1>Goodbye world</h1>
|
||||||
|
</SvelteComponent>
|
||||||
|
</body>
|
||||||
|
</html>
|
21
test/fixtures/astro-children/src/pages/strings.astro
vendored
Normal file
21
test/fixtures/astro-children/src/pages/strings.astro
vendored
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
---
|
||||||
|
import PreactComponent from '../components/Component.jsx';
|
||||||
|
import VueComponent from '../components/Component.vue';
|
||||||
|
import SvelteComponent from '../components/Component.svelte';
|
||||||
|
---
|
||||||
|
<html>
|
||||||
|
<head><title>Children</title></head>
|
||||||
|
<body>
|
||||||
|
<PreactComponent>
|
||||||
|
Hello world
|
||||||
|
</PreactComponent>
|
||||||
|
|
||||||
|
<VueComponent>
|
||||||
|
Hello world
|
||||||
|
</VueComponent>
|
||||||
|
|
||||||
|
<SvelteComponent>
|
||||||
|
Hello world
|
||||||
|
</SvelteComponent>
|
||||||
|
</body>
|
||||||
|
</html>
|
Loading…
Reference in a new issue