mirror of
https://github.com/withastro/astro.git
synced 2024-12-16 21:46:22 -05:00
fix: correctly serialize Infinity as island props (#12121)
This commit is contained in:
parent
f47b347da8
commit
2490cebdb9
7 changed files with 47 additions and 5 deletions
5
.changeset/beige-rice-tap.md
Normal file
5
.changeset/beige-rice-tap.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
'astro': patch
|
||||
---
|
||||
|
||||
Support passing the values `Infinity` and `-Infinity` as island props.
|
|
@ -11,12 +11,14 @@ interface Props {
|
|||
array: any[];
|
||||
map: Map<string, string>;
|
||||
set: Set<string>;
|
||||
infinity: number;
|
||||
negativeInfinity: number;
|
||||
}
|
||||
|
||||
const isNode = typeof process !== 'undefined' && Object.prototype.toString.call(process) === '[object process]';
|
||||
|
||||
/** a counter written in React */
|
||||
export default function Component({ undefined: undefinedProp, null: nullProp, boolean, number, string, bigint, object, array, map, set }: Props) {
|
||||
export default function Component({ undefined: undefinedProp, null: nullProp, boolean, number, string, bigint, object, array, map, set, infinity, negativeInfinity }: Props) {
|
||||
// We are testing hydration, so don't return anything in the server.
|
||||
if(isNode) {
|
||||
return <div></div>
|
||||
|
@ -30,6 +32,10 @@ export default function Component({ undefined: undefinedProp, null: nullProp, bo
|
|||
<span id="boolean-value">{boolean.toString()}</span>
|
||||
<span id="number-type">{Object.prototype.toString.call(number)}</span>
|
||||
<span id="number-value">{number.toString()}</span>
|
||||
<span id="infinity-type">{Object.prototype.toString.call(infinity)}</span>
|
||||
<span id="infinity-value">{infinity.toString()}</span>
|
||||
<span id="negative-infinity-type">{Object.prototype.toString.call(negativeInfinity)}</span>
|
||||
<span id="negative-infinity-value">{negativeInfinity.toString()}</span>
|
||||
<span id="string-type">{Object.prototype.toString.call(string)}</span>
|
||||
<span id="string-value">{string}</span>
|
||||
<span id="bigint-type">{Object.prototype.toString.call(bigint)}</span>
|
||||
|
|
|
@ -42,6 +42,8 @@ set.add('test2');
|
|||
array={[0, "foo"]}
|
||||
map={map}
|
||||
set={set}
|
||||
infinity={Infinity}
|
||||
negativeInfinity={-Infinity}
|
||||
/>
|
||||
</main>
|
||||
</body>
|
||||
|
|
|
@ -47,6 +47,22 @@ test.describe('Passing JS into client components', () => {
|
|||
await expect(numberValue, 'is visible').toBeVisible();
|
||||
await expect(numberValue).toHaveText('16');
|
||||
|
||||
const infinityType = page.locator('#infinity-type');
|
||||
await expect(infinityType, 'is visible').toBeVisible();
|
||||
await expect(infinityType).toHaveText('[object Number]');
|
||||
|
||||
const negativeInfinityType = page.locator('#negative-infinity-type');
|
||||
await expect(negativeInfinityType, 'is visible').toBeVisible();
|
||||
await expect(negativeInfinityType).toHaveText('[object Number]');
|
||||
|
||||
const infinityValue = page.locator('#infinity-value');
|
||||
await expect(infinityValue, 'is visible').toBeVisible();
|
||||
await expect(infinityValue).toHaveText('Infinity');
|
||||
|
||||
const negativeInfinityValue = page.locator('#negative-infinity-value');
|
||||
await expect(negativeInfinityValue, 'is visible').toBeVisible();
|
||||
await expect(negativeInfinityValue).toHaveText('-Infinity');
|
||||
|
||||
// string
|
||||
const stringType = page.locator('#string-type');
|
||||
await expect(stringType, 'is visible').toBeVisible();
|
||||
|
|
|
@ -29,6 +29,7 @@ declare const Astro: {
|
|||
8: (value) => new Uint8Array(value),
|
||||
9: (value) => new Uint16Array(value),
|
||||
10: (value) => new Uint32Array(value),
|
||||
11: (value) => Infinity * value,
|
||||
};
|
||||
|
||||
// Not using JSON.parse reviver because it's bottom-up but we want top-down
|
||||
|
|
|
@ -13,6 +13,7 @@ const PROP_TYPE = {
|
|||
Uint8Array: 8,
|
||||
Uint16Array: 9,
|
||||
Uint32Array: 10,
|
||||
Infinity: 11,
|
||||
};
|
||||
|
||||
function serializeArray(
|
||||
|
@ -93,11 +94,17 @@ function convertToSerializedForm(
|
|||
default: {
|
||||
if (value !== null && typeof value === 'object') {
|
||||
return [PROP_TYPE.Value, serializeObject(value, metadata, parents)];
|
||||
} else if (value === undefined) {
|
||||
return [PROP_TYPE.Value];
|
||||
} else {
|
||||
return [PROP_TYPE.Value, value];
|
||||
}
|
||||
if (value === Infinity) {
|
||||
return [PROP_TYPE.Infinity, 1];
|
||||
}
|
||||
if (value === -Infinity) {
|
||||
return [PROP_TYPE.Infinity, -1];
|
||||
}
|
||||
if (value === undefined) {
|
||||
return [PROP_TYPE.Value];
|
||||
}
|
||||
return [PROP_TYPE.Value, value];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -89,6 +89,11 @@ describe('serialize', () => {
|
|||
const output = `{"a":[10,[1,2,3]]}`;
|
||||
assert.equal(serializeProps(input), output);
|
||||
});
|
||||
it('serializes Infinity and -Infinity', () => {
|
||||
const input = { a: Infinity, b: -Infinity };
|
||||
const output = `{"a":[11,1],"b":[11,-1]}`;
|
||||
assert.equal(serializeProps(input), output);
|
||||
})
|
||||
it('cannot serialize a cyclic reference', () => {
|
||||
const a = {};
|
||||
a.b = a;
|
||||
|
|
Loading…
Reference in a new issue