Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
62 changes: 62 additions & 0 deletions packages/react/runtime/__test__/core/lynx-page-data.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import { afterEach, beforeEach, describe, expect, it } from 'vitest';

import { applyUpdatePageData } from '../../src/core/lynx-page-data.js';

describe('applyUpdatePageData', () => {
let originalInitData: typeof lynx.__initData;

beforeEach(() => {
originalInitData = lynx.__initData;
});

afterEach(() => {
lynx.__initData = originalInitData;
});

it('merges non-empty object data into the existing initData object', () => {
const previousInitData = { msg: 'init', stable: true };
lynx.__initData = previousInitData;

applyUpdatePageData({ msg: 'update', next: 1 });

expect(lynx.__initData).toBe(previousInitData);
expect(lynx.__initData).toEqual({ msg: 'update', stable: true, next: 1 });
});

it('creates initData when merging into an empty main-thread state', () => {
lynx.__initData = undefined;

applyUpdatePageData({ msg: 'update' });

expect(lynx.__initData).toEqual({ msg: 'update' });
});

it('clears existing initData before resetPageData merge', () => {
lynx.__initData = { stale: true, msg: 'init' };

applyUpdatePageData({ msg: 'reset' }, { resetPageData: true });

expect(lynx.__initData).toEqual({ msg: 'reset' });
});

it('supports resetPageData without update data', () => {
lynx.__initData = { stale: true };

applyUpdatePageData(undefined, { resetPageData: true });

expect(lynx.__initData).toEqual({});
});

it('does not change initData for empty or non-object data', () => {
const previousInitData = { msg: 'init' };
lynx.__initData = previousInitData;

applyUpdatePageData({});
applyUpdatePageData(null);
applyUpdatePageData(undefined);
applyUpdatePageData('ignored');

expect(lynx.__initData).toBe(previousInitData);
expect(lynx.__initData).toEqual({ msg: 'init' });
});
});
14 changes: 14 additions & 0 deletions packages/react/runtime/__test__/core/reload-version.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { describe, expect, it } from 'vitest';

import { getReloadVersion, increaseReloadVersion } from '../../src/core/reload-version.js';

describe('reload version', () => {
it('increments monotonically and exposes the current version', () => {
const initial = getReloadVersion();

expect(increaseReloadVersion()).toBe(initial + 1);
expect(getReloadVersion()).toBe(initial + 1);
expect(increaseReloadVersion()).toBe(initial + 2);
expect(getReloadVersion()).toBe(initial + 2);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,16 @@ describe('ElementTemplate alog helpers', () => {
11,
0,
'updated',
ElementTemplateUpdateOps.createTypedElement,
13,
'list',
{ id: 'typed-list' },
[[12]],
{ listChildren: [{ __etHandleRef: 12 }] },
ElementTemplateUpdateOps.setAttribute,
13,
0,
{ insertAction: [] },
ElementTemplateUpdateOps.insertNode,
11,
1,
Expand All @@ -51,6 +61,20 @@ describe('ElementTemplate alog helpers', () => {
attrSlotIndex: 0,
value: 'updated',
},
{
op: 'createTypedElement',
handleId: 13,
type: 'list',
attributes: { id: 'typed-list' },
elementSlots: [[12]],
options: { listChildren: [{ __etHandleRef: 12 }] },
},
{
op: 'setAttribute',
targetId: 13,
attrSlotIndex: 0,
value: { insertAction: [] },
},
{
op: 'insertNode',
targetId: 11,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ describe('ElementTemplate PAPI alog wrapper', () => {
it('wraps ET PAPI calls and formats native refs', () => {
const templateRef = { id: 1 };
const childRef = { id: 2 };
const typedRef = { id: 'page' };
const circular: Record<string, unknown> = {};
circular['self'] = circular;
const jsonUndefined = { toJSON: () => undefined };
Expand All @@ -30,6 +31,7 @@ describe('ElementTemplate PAPI alog wrapper', () => {

const target = {
__CreateElementTemplate: vi.fn(() => templateRef),
__CreateTypedElementTemplate: vi.fn(() => typedRef),
__SetAttributeOfElementTemplate: vi.fn(),
__InsertNodeToElementTemplate: vi.fn(() => childRef),
__RemoveNodeFromElementTemplate: vi.fn(() => null),
Expand All @@ -45,6 +47,13 @@ describe('ElementTemplate PAPI alog wrapper', () => {
[],
17,
)).toBe(templateRef);
expect((target.__CreateTypedElementTemplate as (...args: unknown[]) => unknown)(
'page',
null,
null,
'0',
null,
)).toBe(typedRef);
(target.__SetAttributeOfElementTemplate as (...args: unknown[]) => unknown)(
templateRef,
0,
Expand Down Expand Up @@ -81,6 +90,7 @@ describe('ElementTemplate PAPI alog wrapper', () => {
expect(logs).toContain(
'__CreateElementTemplate("_et_card", null, ["title"], [], 17) => _et_card#17',
);
expect(logs).toContain('__CreateTypedElementTemplate("page", null, null, "0", null) => page#0');
expect(logs).toContain(
'__SetAttributeOfElementTemplate(_et_card#17, 0, [_et_card#17, undefined, null, [Function namedHandler], [Function], Symbol(slot), [object Object], [object Object]], null)',
);
Expand All @@ -89,8 +99,8 @@ describe('ElementTemplate PAPI alog wrapper', () => {
);
expect(logs).toContain('__RemoveNodeFromElementTemplate(_et_card#17, 1, {"id":2})');
expect(logs).toContain('__SerializeElementTemplate(_et_card#17) => Symbol(serialized)');
expect(globalThis.lynx.performance.profileStart).toHaveBeenCalledTimes(5);
expect(globalThis.lynx.performance.profileEnd).toHaveBeenCalledTimes(5);
expect(globalThis.lynx.performance.profileStart).toHaveBeenCalledTimes(6);
expect(globalThis.lynx.performance.profileEnd).toHaveBeenCalledTimes(6);
});

it('skips missing APIs and keeps logging optional', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import type { SerializedElementTemplate } from '../../../../../src/element-templ
import { __page } from '../../../../../src/element-template/runtime/page/page.js';
import { __root } from '../../../../../src/element-template/runtime/page/root-instance.js';
import { ElementTemplateEnvManager } from '../../../test-utils/debug/envManager.js';
import { extractSerializedHydrateInstances } from '../../../test-utils/debug/hydratePayload.js';
import { installMockNativePapi } from '../../../test-utils/mock/mockNativePapi.js';
import { serializeToJSX } from '../../../test-utils/debug/serializer.js';

Expand Down Expand Up @@ -100,12 +101,7 @@ function setup(): CaseContext {
envManager.setUseElementTemplate(true);

const onHydrate = vi.fn().mockImplementation((event: { data: unknown }) => {
const data = event.data;
if (Array.isArray(data)) {
for (const item of data) {
hydrationData.push(item as SerializedElementTemplate);
}
}
hydrationData.push(...extractSerializedHydrateInstances(event.data));
});
lynx.getCoreContext().addEventListener(ElementTemplateLifecycleConstant.hydrate, onHydrate);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { resetTemplateId } from '../../../../../src/element-template/runtime/tem
import { elementTemplateRegistry } from '../../../../../src/element-template/runtime/template/registry.js';
import { loadCompiledFixtureApp } from '../../../test-utils/debug/compiledFixtureApp.js';
import { ElementTemplateEnvManager } from '../../../test-utils/debug/envManager.js';
import { extractSerializedHydrateInstances } from '../../../test-utils/debug/hydratePayload.js';
import { installMockNativePapi } from '../../../test-utils/mock/mockNativePapi.js';

declare const renderPage: () => void;
Expand All @@ -32,12 +33,7 @@ function setup(): HydrationContext {

const hydrationData: unknown[] = [];
const onHydrate = vi.fn().mockImplementation((event: { data: unknown }) => {
const data = event.data;
if (Array.isArray(data)) {
for (const item of data) {
hydrationData.push(item);
}
}
hydrationData.push(...extractSerializedHydrateInstances(event.data));
});
lynx.getCoreContext().addEventListener(ElementTemplateLifecycleConstant.hydrate, onHydrate);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
Array [
Array [
"__CreatePage",
"__CreateTypedElementTemplate",
"page",
null,
null,
"0",
0,
null,
],
Array [
"__CreateElementTemplate",
Expand All @@ -13,8 +16,10 @@ Array [
-1,
],
Array [
"__AppendElement",
"0",
"__InsertNodeToElementTemplate",
"<page />",
0,
"<_et_a94a8_test_1 />",
null,
],
]
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import { resetTemplateId } from '../../../../src/element-template/runtime/templa
import { elementTemplateRegistry } from '../../../../src/element-template/runtime/template/registry.js';
import { registerBuiltinRawTextTemplate } from '../../test-utils/debug/registry.js';
import { ElementTemplateEnvManager } from '../../test-utils/debug/envManager.js';
import { extractSerializedHydrateInstances } from '../../test-utils/debug/hydratePayload.js';
import { compileFixtureSource } from '../../test-utils/debug/compiledFixtureCompiler.js';
import {
loadCompiledFixtureModule,
Expand Down Expand Up @@ -87,12 +88,7 @@ export function setupPatchContext(): PatchContext {
envManager.switchToBackground();

const onHydrate = vi.fn().mockImplementation((event: { data: unknown }) => {
const data = event.data;
if (Array.isArray(data)) {
for (const item of data) {
hydrationData.push(item as SerializedElementTemplate);
}
}
hydrationData.push(...extractSerializedHydrateInstances(event.data));
});
lynx.getCoreContext().addEventListener(ElementTemplateLifecycleConstant.hydrate, onHydrate);

Expand Down Expand Up @@ -124,12 +120,7 @@ export function setupUpdateFixtureContext(): UpdateFixtureContext {
installElementTemplateHydrationListener();
installElementTemplateCommitHook();
const onHydrate = (event: { data: unknown }) => {
const data = event.data;
if (Array.isArray(data)) {
for (const item of data) {
hydrationData.push(item as SerializedElementTemplate);
}
}
hydrationData.push(...extractSerializedHydrateInstances(event.data));
};
lynx.getCoreContext().addEventListener(ElementTemplateLifecycleConstant.hydrate, onHydrate);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
[
[
"__CreateTypedElementTemplate",
"page",
null,
null,
"0",
null
],
[
"__CreateElementTemplate",
"_et_7a8c6_test_2",
Expand Down Expand Up @@ -111,8 +119,10 @@
-5
],
[
"__AppendElement",
"0",
"<_et_7a8c6_test_1 />"
"__InsertNodeToElementTemplate",
"<page />",
0,
"<_et_7a8c6_test_1 />",
null
]
]
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
[
[
"__CreateTypedElementTemplate",
"page",
null,
null,
"0",
null
],
[
"__CreateElementTemplate",
"_et_7a8c6_test_3",
Expand Down Expand Up @@ -68,8 +76,10 @@
-3
],
[
"__AppendElement",
"0",
"<_et_7a8c6_test_2 />"
"__InsertNodeToElementTemplate",
"<page />",
0,
"<_et_7a8c6_test_2 />",
null
]
]
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
[
[
"__CreateTypedElementTemplate",
"page",
null,
null,
"0",
null
],
[
"__CreateElementTemplate",
"_et_builtin_raw_text",
Expand Down Expand Up @@ -50,8 +58,10 @@
-3
],
[
"__AppendElement",
"0",
"<_et_7a8c6_test_1 />"
"__InsertNodeToElementTemplate",
"<page />",
0,
"<_et_7a8c6_test_1 />",
null
]
]
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
[
[
"__CreateTypedElementTemplate",
"page",
null,
null,
"0",
null
],
[
"__CreateElementTemplate",
"_et_builtin_raw_text",
Expand Down Expand Up @@ -197,8 +205,10 @@
-7
],
[
"__AppendElement",
"0",
"<_et_7a8c6_test_1 />"
"__InsertNodeToElementTemplate",
"<page />",
0,
"<_et_7a8c6_test_1 />",
null
]
]
Loading
Loading