Skip to content

Commit 9cef7d0

Browse files
Separate incremental render test fixtures from base fixtures to fix test failures
Commit 7605907 added async/stream helper functions to bundle.js and secondary-bundle.js to support new incremental render tests. However, these changes broke existing tests in vm.test.ts, handleRenderRequest.test.ts, and worker.test.ts that expected the original minimal bundle fixtures. Create separate bundle-incremental.js and secondary-bundle-incremental.js fixtures specifically for the 6 new incremental render tests, allowing the original fixtures to be restored to their simple 3-line versions. This isolates incremental render functionality while maintaining backward compatibility with existing tests. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
1 parent eadea2b commit 9cef7d0

File tree

7 files changed

+153
-113
lines changed

7 files changed

+153
-113
lines changed
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
const { PassThrough } = require('stream');
2+
3+
global.ReactOnRails = {
4+
dummy: { html: 'Dummy Object' },
5+
6+
// Get or create async value promise
7+
getAsyncValue: function () {
8+
debugger;
9+
if (!sharedExecutionContext.has('asyncPromise')) {
10+
const promiseData = {};
11+
const promise = new Promise((resolve, reject) => {
12+
promiseData.resolve = resolve;
13+
promiseData.reject = reject;
14+
});
15+
promiseData.promise = promise;
16+
sharedExecutionContext.set('asyncPromise', promiseData);
17+
}
18+
return sharedExecutionContext.get('asyncPromise').promise;
19+
},
20+
21+
// Resolve the async value promise
22+
setAsyncValue: function (value) {
23+
debugger;
24+
if (!sharedExecutionContext.has('asyncPromise')) {
25+
ReactOnRails.getAsyncValue();
26+
}
27+
const promiseData = sharedExecutionContext.get('asyncPromise');
28+
promiseData.resolve(value);
29+
},
30+
31+
// Get or create stream
32+
getStreamValues: function () {
33+
if (!sharedExecutionContext.has('stream')) {
34+
const stream = new PassThrough();
35+
sharedExecutionContext.set('stream', { stream });
36+
}
37+
return sharedExecutionContext.get('stream').stream;
38+
},
39+
40+
// Add value to stream
41+
addStreamValue: function (value) {
42+
if (!sharedExecutionContext.has('stream')) {
43+
// Create the stream first if it doesn't exist
44+
ReactOnRails.getStreamValues();
45+
}
46+
const { stream } = sharedExecutionContext.get('stream');
47+
stream.write(value);
48+
return value;
49+
},
50+
51+
endStream: function () {
52+
if (sharedExecutionContext.has('stream')) {
53+
const { stream } = sharedExecutionContext.get('stream');
54+
stream.end();
55+
}
56+
},
57+
};
Lines changed: 0 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,57 +1,3 @@
1-
const { PassThrough } = require('stream');
2-
31
global.ReactOnRails = {
42
dummy: { html: 'Dummy Object' },
5-
6-
// Get or create async value promise
7-
getAsyncValue: function () {
8-
debugger;
9-
if (!sharedExecutionContext.has('asyncPromise')) {
10-
const promiseData = {};
11-
const promise = new Promise((resolve, reject) => {
12-
promiseData.resolve = resolve;
13-
promiseData.reject = reject;
14-
});
15-
promiseData.promise = promise;
16-
sharedExecutionContext.set('asyncPromise', promiseData);
17-
}
18-
return sharedExecutionContext.get('asyncPromise').promise;
19-
},
20-
21-
// Resolve the async value promise
22-
setAsyncValue: function (value) {
23-
debugger;
24-
if (!sharedExecutionContext.has('asyncPromise')) {
25-
ReactOnRails.getAsyncValue();
26-
}
27-
const promiseData = sharedExecutionContext.get('asyncPromise');
28-
promiseData.resolve(value);
29-
},
30-
31-
// Get or create stream
32-
getStreamValues: function () {
33-
if (!sharedExecutionContext.has('stream')) {
34-
const stream = new PassThrough();
35-
sharedExecutionContext.set('stream', { stream });
36-
}
37-
return sharedExecutionContext.get('stream').stream;
38-
},
39-
40-
// Add value to stream
41-
addStreamValue: function (value) {
42-
if (!sharedExecutionContext.has('stream')) {
43-
// Create the stream first if it doesn't exist
44-
ReactOnRails.getStreamValues();
45-
}
46-
const { stream } = sharedExecutionContext.get('stream');
47-
stream.write(value);
48-
return value;
49-
},
50-
51-
endStream: function () {
52-
if (sharedExecutionContext.has('stream')) {
53-
const { stream } = sharedExecutionContext.get('stream');
54-
stream.end();
55-
}
56-
},
573
};
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
const { PassThrough } = require('stream');
2+
3+
global.ReactOnRails = {
4+
dummy: { html: 'Dummy Object from secondary bundle' },
5+
6+
// Get or create async value promise
7+
getAsyncValue: function () {
8+
if (!sharedExecutionContext.has('secondaryAsyncPromise')) {
9+
const promiseData = {};
10+
const promise = new Promise((resolve, reject) => {
11+
promiseData.resolve = resolve;
12+
promiseData.reject = reject;
13+
});
14+
promiseData.promise = promise;
15+
sharedExecutionContext.set('secondaryAsyncPromise', promiseData);
16+
}
17+
return sharedExecutionContext.get('secondaryAsyncPromise').promise;
18+
},
19+
20+
// Resolve the async value promise
21+
setAsyncValue: function (value) {
22+
if (!sharedExecutionContext.has('secondaryAsyncPromise')) {
23+
ReactOnRails.getAsyncValue();
24+
}
25+
const promiseData = sharedExecutionContext.get('secondaryAsyncPromise');
26+
promiseData.resolve(value);
27+
},
28+
29+
// Get or create stream
30+
getStreamValues: function () {
31+
if (!sharedExecutionContext.has('secondaryStream')) {
32+
const stream = new PassThrough();
33+
sharedExecutionContext.set('secondaryStream', { stream });
34+
}
35+
return sharedExecutionContext.get('secondaryStream').stream;
36+
},
37+
38+
// Add value to stream
39+
addStreamValue: function (value) {
40+
if (!sharedExecutionContext.has('secondaryStream')) {
41+
// Create the stream first if it doesn't exist
42+
ReactOnRails.getStreamValues();
43+
}
44+
const { stream } = sharedExecutionContext.get('secondaryStream');
45+
stream.write(value);
46+
},
47+
48+
endStream: function () {
49+
if (sharedExecutionContext.has('secondaryStream')) {
50+
const { stream } = sharedExecutionContext.get('secondaryStream');
51+
stream.end();
52+
}
53+
},
54+
};
Lines changed: 0 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,3 @@
11
global.ReactOnRails = {
22
dummy: { html: 'Dummy Object from secondary bundle' },
3-
4-
// Get or create async value promise
5-
getAsyncValue: function () {
6-
if (!sharedExecutionContext.has('secondaryAsyncPromise')) {
7-
const promiseData = {};
8-
const promise = new Promise((resolve, reject) => {
9-
promiseData.resolve = resolve;
10-
promiseData.reject = reject;
11-
});
12-
promiseData.promise = promise;
13-
sharedExecutionContext.set('secondaryAsyncPromise', promiseData);
14-
}
15-
return sharedExecutionContext.get('secondaryAsyncPromise').promise;
16-
},
17-
18-
// Resolve the async value promise
19-
setAsyncValue: function (value) {
20-
if (!sharedExecutionContext.has('secondaryAsyncPromise')) {
21-
ReactOnRails.getAsyncValue();
22-
}
23-
const promiseData = sharedExecutionContext.get('secondaryAsyncPromise');
24-
promiseData.resolve(value);
25-
},
26-
27-
// Get or create stream
28-
getStreamValues: function () {
29-
if (!sharedExecutionContext.has('secondaryStream')) {
30-
const stream = new PassThrough();
31-
sharedExecutionContext.set('secondaryStream', { stream });
32-
}
33-
return sharedExecutionContext.get('secondaryStream').stream;
34-
},
35-
36-
// Add value to stream
37-
addStreamValue: function (value) {
38-
if (!sharedExecutionContext.has('secondaryStream')) {
39-
// Create the stream first if it doesn't exist
40-
ReactOnRails.getStreamValues();
41-
}
42-
const { stream } = sharedExecutionContext.get('secondaryStream');
43-
stream.write(value);
44-
},
45-
46-
endStream: function () {
47-
if (sharedExecutionContext.has('secondaryStream')) {
48-
const { stream } = sharedExecutionContext.get('secondaryStream');
49-
stream.end();
50-
}
51-
},
523
};

react_on_rails_pro/packages/node-renderer/tests/helper.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,14 @@ export function getFixtureSecondaryBundle() {
2727
return path.resolve(__dirname, './fixtures/secondary-bundle.js');
2828
}
2929

30+
export function getFixtureIncrementalBundle() {
31+
return path.resolve(__dirname, './fixtures/bundle-incremental.js');
32+
}
33+
34+
export function getFixtureIncrementalSecondaryBundle() {
35+
return path.resolve(__dirname, './fixtures/secondary-bundle-incremental.js');
36+
}
37+
3038
export function getFixtureAsset() {
3139
return path.resolve(__dirname, `./fixtures/${ASSET_UPLOAD_FILE}`);
3240
}
@@ -79,6 +87,28 @@ export async function createSecondaryVmBundle(testName: string) {
7987
await buildExecutionContext([vmSecondaryBundlePath(testName)], /* buildVmsIfNeeded */ true);
8088
}
8189

90+
export async function createIncrementalVmBundle(testName: string) {
91+
// Build config with module support before creating VM bundle
92+
buildConfig({
93+
serverBundleCachePath: serverBundleCachePath(testName),
94+
supportModules: true,
95+
stubTimers: false,
96+
});
97+
await safeCopyFileAsync(getFixtureIncrementalBundle(), vmBundlePath(testName));
98+
await buildExecutionContext([vmBundlePath(testName)], /* buildVmsIfNeeded */ true);
99+
}
100+
101+
export async function createIncrementalSecondaryVmBundle(testName: string) {
102+
// Build config with module support before creating VM bundle
103+
buildConfig({
104+
serverBundleCachePath: serverBundleCachePath(testName),
105+
supportModules: true,
106+
stubTimers: false,
107+
});
108+
await safeCopyFileAsync(getFixtureIncrementalSecondaryBundle(), vmSecondaryBundlePath(testName));
109+
await buildExecutionContext([vmSecondaryBundlePath(testName)], /* buildVmsIfNeeded */ true);
110+
}
111+
82112
export function lockfilePath(testName: string) {
83113
return `${vmBundlePath(testName)}.lock`;
84114
}

react_on_rails_pro/packages/node-renderer/tests/incrementalRender.test.ts

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ import * as incremental from '../src/worker/handleIncrementalRenderRequest';
77
import {
88
createVmBundle,
99
createSecondaryVmBundle,
10+
createIncrementalVmBundle,
11+
createIncrementalSecondaryVmBundle,
1012
BUNDLE_TIMESTAMP,
1113
SECONDARY_BUNDLE_TIMESTAMP,
1214
waitFor,
@@ -675,7 +677,7 @@ describe('incremental render NDJSON endpoint', () => {
675677

676678
describe('incremental render update chunk functionality', () => {
677679
test('basic incremental update - initial request gets value, update chunks set value', async () => {
678-
await createVmBundle(TEST_NAME);
680+
await createIncrementalVmBundle(TEST_NAME);
679681
const SERVER_BUNDLE_TIMESTAMP = String(BUNDLE_TIMESTAMP);
680682

681683
// Create the HTTP request
@@ -710,8 +712,8 @@ describe('incremental render NDJSON endpoint', () => {
710712
});
711713

712714
test('incremental updates work with multiple bundles using runOnOtherBundle', async () => {
713-
await createVmBundle(TEST_NAME);
714-
await createSecondaryVmBundle(TEST_NAME);
715+
await createIncrementalVmBundle(TEST_NAME);
716+
await createIncrementalSecondaryVmBundle(TEST_NAME);
715717
const SERVER_BUNDLE_TIMESTAMP = String(BUNDLE_TIMESTAMP);
716718
const SECONDARY_BUNDLE_TIMESTAMP_STR = String(SECONDARY_BUNDLE_TIMESTAMP);
717719

@@ -764,7 +766,7 @@ describe('incremental render NDJSON endpoint', () => {
764766
});
765767

766768
test('streaming functionality with incremental updates', async () => {
767-
await createVmBundle(TEST_NAME);
769+
await createIncrementalVmBundle(TEST_NAME);
768770
const SERVER_BUNDLE_TIMESTAMP = String(BUNDLE_TIMESTAMP);
769771

770772
// Create the HTTP request
@@ -817,7 +819,7 @@ describe('incremental render NDJSON endpoint', () => {
817819
});
818820

819821
test('error handling in incremental render updates', async () => {
820-
await createVmBundle(TEST_NAME);
822+
await createIncrementalVmBundle(TEST_NAME);
821823
const SERVER_BUNDLE_TIMESTAMP = String(BUNDLE_TIMESTAMP);
822824

823825
// Create the HTTP request
@@ -865,7 +867,7 @@ describe('incremental render NDJSON endpoint', () => {
865867
});
866868

867869
test('update chunks with non-existent bundle timestamp', async () => {
868-
await createVmBundle(TEST_NAME);
870+
await createIncrementalVmBundle(TEST_NAME);
869871
const SERVER_BUNDLE_TIMESTAMP = String(BUNDLE_TIMESTAMP);
870872
const NON_EXISTENT_TIMESTAMP = '9999999999999';
871873

@@ -908,8 +910,8 @@ describe('incremental render NDJSON endpoint', () => {
908910
});
909911

910912
test('complex multi-bundle streaming scenario', async () => {
911-
await createVmBundle(TEST_NAME);
912-
await createSecondaryVmBundle(TEST_NAME);
913+
await createIncrementalVmBundle(TEST_NAME);
914+
await createIncrementalSecondaryVmBundle(TEST_NAME);
913915
const SERVER_BUNDLE_TIMESTAMP = String(BUNDLE_TIMESTAMP);
914916
const SECONDARY_BUNDLE_TIMESTAMP_STR = String(SECONDARY_BUNDLE_TIMESTAMP);
915917

react_on_rails_pro/packages/node-renderer/tests/worker.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -652,8 +652,8 @@ describe('worker', () => {
652652
expect(files).toHaveLength(1);
653653
expect(files[0]).toBe(`${bundleHash}.js`);
654654

655-
// Verify the original content is preserved (1646 bytes from bundle.js, not 1689 from secondary-bundle.js)
656-
expect(secondBundleSize).toBe(1646); // Size of getFixtureBundle(), not getFixtureSecondaryBundle()
655+
// Verify the original content is preserved (62 bytes from bundle.js, not 84 from secondary-bundle.js)
656+
expect(secondBundleSize).toBe(62); // Size of getFixtureBundle(), not getFixtureSecondaryBundle()
657657
});
658658

659659
test('post /upload-assets with bundles placed in their own hash directories, not targetBundles directories', async () => {

0 commit comments

Comments
 (0)