Skip to content

Commit b8b5a92

Browse files
justin808claude
andcommitted
Fix RSC test infrastructure: Convert jest.setup.js to ESM and re-enable tests (#2124)
Fixes #2122 - Convert `jest.setup.js` from CommonJS `require()` to ESM imports for compatibility with ESM mode - Re-enable RSC tests with automatic React version detection - Remove unnecessary `script/convert` override since `package.json` now handles version checking automatically Moved `require()` statements to top-level ESM imports: - `import { TextEncoder, TextDecoder } from 'util'` - `import { Readable } from 'stream'` - `import { ReadableStream, ReadableStreamDefaultReader } from 'stream/web'` - `import { jest } from '@jest/globals'` Re-enabled `test:rsc` script with React version detection: - Tests run normally on React 19+ where RSC features are available - Tests skip gracefully on React 18 with informative message: `RSC tests skipped (requires React 19+, found 18.0.0)` Removed the override that disabled RSC tests since the version check is now built into `package.json`. - [x] Run `yarn test` in `packages/react-on-rails-pro` - passes with React 18 (RSC tests skipped) - [x] Verify RSC tests will run on React 19 in CI 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> * **Chores** * Updated RSC test infrastructure to conditionally run based on React version; tests now execute for React 19+ and skip for earlier versions. * Modernized Jest setup configuration to use ES module imports instead of dynamic requires, improving compatibility with modern JavaScript standards. <sub>✏️ Tip: You can customize this high-level summary in your review settings.</sub> <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Claude <[email protected]>
1 parent 3ef26ab commit b8b5a92

File tree

5 files changed

+45
-14
lines changed

5 files changed

+45
-14
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
# Root Gemfile.lock (delegates to react_on_rails/Gemfile, lock is there)
2+
/Gemfile.lock
3+
14
.bundle/
25
/.yardoc
36
/_yardoc/

packages/react-on-rails-pro/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
"clean": "rm -rf ./lib",
1010
"test": "pnpm run test:non-rsc && pnpm run test:rsc",
1111
"test:non-rsc": "jest tests --testPathIgnorePatterns=\".*(RSC|stream|registerServerComponent|serverRenderReactComponent|SuspenseHydration).*\"",
12-
"test:rsc": "echo 'TODO: RSC tests disabled - jest.setup.js uses require() incompatible with ESM mode. Re-enable after converting setup to ESM.' && exit 0",
12+
"test:rsc": "node scripts/check-react-version.cjs || NODE_CONDITIONS=react-server jest tests/*.rsc.test.*",
1313
"type-check": "tsc --noEmit --noErrorTruncation",
1414
"prepare": "[ -f lib/ReactOnRails.full.js ] || (rm -rf ./lib && tsc)",
1515
"prepublishOnly": "pnpm run build",
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/**
2+
* Check if React version supports RSC features (React 19+).
3+
* Exits with code 0 if React < 19 (skip RSC tests).
4+
* Exits with code 1 if React >= 19 (run RSC tests).
5+
*
6+
* This is a CommonJS file (.cjs) because it needs to use require()
7+
* and the parent package has "type": "module".
8+
*/
9+
const v = require('react/package.json').version;
10+
11+
const majorVersion = parseInt(v, 10);
12+
13+
if (majorVersion < 19) {
14+
console.log(`RSC tests skipped (requires React 19+, found ${v})`);
15+
process.exit(0);
16+
}
17+
18+
// Exit with code 1 so the || chain continues to run Jest
19+
process.exit(1);

packages/react-on-rails-pro/tests/jest.setup.js

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
import { TextEncoder, TextDecoder } from 'util';
2+
import { Readable } from 'stream';
3+
import { ReadableStream, ReadableStreamDefaultReader } from 'stream/web';
4+
import { jest } from '@jest/globals';
5+
16
// If jsdom environment is set and TextEncoder is not defined, then define TextEncoder and TextDecoder
27
// The current version of jsdom does not support TextEncoder and TextDecoder
38
// The following code will tell us when jsdom supports TextEncoder and TextDecoder
@@ -11,13 +16,6 @@ if (typeof window !== 'undefined' && typeof window.MessageChannel !== 'undefined
1116
}
1217

1318
if (typeof window !== 'undefined') {
14-
// eslint-disable-next-line global-require
15-
const { TextEncoder, TextDecoder } = require('util');
16-
// eslint-disable-next-line global-require
17-
const { Readable } = require('stream');
18-
// eslint-disable-next-line global-require
19-
const { ReadableStream, ReadableStreamDefaultReader } = require('stream/web');
20-
2119
// Mock the fetch function to return a ReadableStream instead of Node's Readable stream
2220
// This matches browser behavior where fetch responses have ReadableStream bodies
2321
// Node's fetch and polyfills like jest-fetch-mock return Node's Readable stream,

script/convert

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,20 @@ gsub_file_content(
4444
'"test:non-rsc": "jest tests --testPathIgnorePatterns=\".*(RSC|stream|' \
4545
'registerServerComponent|serverRenderReactComponent|SuspenseHydration).*\"",'
4646
)
47-
# Make test:rsc script do nothing on React 18
48-
gsub_file_content(
49-
"../packages/react-on-rails-pro/package.json",
50-
/"test:rsc": "(?:\\"|[^"])*",/,
51-
'"test:rsc": "exit 0",'
52-
)
47+
# test:rsc script now automatically detects React version and skips on React 18
48+
# No override needed - the script checks React version and exits cleanly if < 19
49+
# Keep modern JSX transform for React 18+
50+
# gsub_file_content("../tsconfig.json", "react-jsx", "react")
51+
# gsub_file_content("../spec/dummy/babel.config.js", "runtime: 'automatic'", "runtime: 'classic'")
52+
# Keep modern ReScript configuration for React 18+
53+
# gsub_file_content("../spec/dummy/rescript.json", '"version": 4', '"version": 4, "mode": "classic"')
54+
# Skip React 16 file replacements since we're using React 18+
55+
# Dir.glob(File.expand_path("../spec/dummy/**/app-react16/**/*.*", __dir__)).each do |file|
56+
# move(file, file.gsub("-react16", ""))
57+
# end
58+
59+
# These replacements were incorrect - generateWebpackConfig() is the correct function from shakapacker
60+
# gsub_file_content("../spec/dummy/config/webpack/commonWebpackConfig.js", /generateWebpackConfig(\(\))?/,
61+
# "webpackConfig")
62+
#
63+
# gsub_file_content("../spec/dummy/config/webpack/webpack.config.js", /generateWebpackConfig(\(\))?/, "webpackConfig")

0 commit comments

Comments
 (0)