-
Notifications
You must be signed in to change notification settings - Fork 7
integration test on Windows CI #113
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
Closed
Changes from 6 commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
280bd6f
integration test on Windows CI
matthargett 4c8f14c
add missing file
matthargett 436119b
abstract the cmake invocation to a script file so we can make the pro…
matthargett 3617213
add unit test for the copy-examples job, which had a pathing issue on…
matthargett 53886f7
go ahead and run these tests under linux as well
matthargett 80614dd
use clang from the Android NDK
matthargett 1f93a0d
Merge branch 'main' into moar-windows-tests
matthargett File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
150 changes: 150 additions & 0 deletions
150
packages/node-addon-examples/scripts/cmake-projects.test.mts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,150 @@ | ||
| import assert from "node:assert/strict"; | ||
| import { describe, it, TestContext } from "node:test"; | ||
| import path from "node:path"; | ||
| import fs from "node:fs"; | ||
| import os from "node:os"; | ||
|
|
||
| import { EXAMPLES_DIR, findCMakeProjects } from "./cmake-projects.mjs"; | ||
|
|
||
| function setupTempDirectory(context: TestContext, files: Record<string, string>) { | ||
| const tempDirectoryPath = fs.realpathSync( | ||
| fs.mkdtempSync(path.join(os.tmpdir(), "cmake-projects-test-")) | ||
| ); | ||
|
|
||
| context.after(() => { | ||
| fs.rmSync(tempDirectoryPath, { recursive: true, force: true }); | ||
| }); | ||
|
|
||
| for (const [filePath, content] of Object.entries(files)) { | ||
| const fullPath = path.join(tempDirectoryPath, filePath); | ||
| fs.mkdirSync(path.dirname(fullPath), { recursive: true }); | ||
| fs.writeFileSync(fullPath, content, "utf8"); | ||
| } | ||
|
|
||
| return tempDirectoryPath; | ||
| } | ||
|
|
||
| describe("EXAMPLES_DIR", () => { | ||
| it("should resolve to a valid platform-specific path", () => { | ||
| // Check that EXAMPLES_DIR is an absolute path | ||
| assert(path.isAbsolute(EXAMPLES_DIR), "EXAMPLES_DIR should be absolute"); | ||
|
|
||
| // On Windows, should not start with / | ||
| if (process.platform === "win32") { | ||
| assert( | ||
| !EXAMPLES_DIR.startsWith("/"), | ||
| "Windows path should not start with /" | ||
| ); | ||
| // Should match Windows path pattern (e.g., C:\... or D:\...) | ||
| assert( | ||
| /^[A-Za-z]:[\\/]/.test(EXAMPLES_DIR), | ||
| "Windows path should start with drive letter" | ||
| ); | ||
| } else { | ||
| // On Unix-like systems, should start with / | ||
| assert( | ||
| EXAMPLES_DIR.startsWith("/"), | ||
| "Unix path should start with /" | ||
| ); | ||
| } | ||
| }); | ||
|
|
||
| it("should work correctly with path.join operations", (context) => { | ||
| const tempDir = setupTempDirectory(context, { | ||
| "test/subdir/file.txt": "test content", | ||
| }); | ||
|
|
||
| // Simulate what happens in copy-examples.mts | ||
| const relativePath = "test/subdir"; | ||
| const joinedPath = path.join(tempDir, relativePath); | ||
|
|
||
| // The joined path should exist and be accessible | ||
| assert(fs.existsSync(joinedPath), "Joined path should exist"); | ||
| assert( | ||
| fs.statSync(joinedPath).isDirectory(), | ||
| "Joined path should be a directory" | ||
| ); | ||
| }); | ||
|
|
||
| it("should handle URL to path conversion correctly on all platforms", () => { | ||
| // Create a test URL similar to how EXAMPLES_DIR is created | ||
| const testUrl = new URL("../examples", import.meta.url); | ||
| const convertedPath = testUrl.pathname; | ||
|
|
||
| // The converted path should work with fs operations | ||
| // We can't test the actual EXAMPLES_DIR since it might not exist, | ||
| // but we can verify the conversion produces valid paths | ||
| if (process.platform === "win32") { | ||
| // On Windows, URL.pathname returns /C:/... which is invalid | ||
| // Our fix uses fileURLToPath which returns C:\... | ||
| assert( | ||
| !path.isAbsolute(convertedPath) || convertedPath.startsWith("/"), | ||
| "Direct URL.pathname on Windows produces invalid absolute paths" | ||
| ); | ||
| } | ||
| }); | ||
| }); | ||
|
|
||
| describe("findCMakeProjects", () => { | ||
| it("should find CMakeLists.txt files recursively", (context) => { | ||
| const tempDir = setupTempDirectory(context, { | ||
| "project1/CMakeLists.txt": "# CMake file 1", | ||
| "project2/subdir/CMakeLists.txt": "# CMake file 2", | ||
| "project3/CMakeLists.txt": "# CMake file 3", | ||
| "not-a-project/other.txt": "not cmake", | ||
| }); | ||
|
|
||
| const projects = findCMakeProjects(tempDir); | ||
|
|
||
| assert.equal(projects.length, 3, "Should find 3 CMake projects"); | ||
|
|
||
| // Sort for consistent comparison | ||
| const sortedProjects = projects.sort(); | ||
| const expectedProjects = [ | ||
| path.join(tempDir, "project1"), | ||
| path.join(tempDir, "project2", "subdir"), | ||
| path.join(tempDir, "project3"), | ||
| ].sort(); | ||
|
|
||
| assert.deepEqual(sortedProjects, expectedProjects); | ||
| }); | ||
|
|
||
| it("should handle empty directories", (context) => { | ||
| const tempDir = setupTempDirectory(context, {}); | ||
| const projects = findCMakeProjects(tempDir); | ||
| assert.equal(projects.length, 0, "Should find no projects in empty dir"); | ||
| }); | ||
|
|
||
| it("should handle nested CMake projects", (context) => { | ||
| const tempDir = setupTempDirectory(context, { | ||
| "parent/CMakeLists.txt": "# Parent CMake", | ||
| "parent/child/CMakeLists.txt": "# Child CMake", | ||
| "parent/child/grandchild/CMakeLists.txt": "# Grandchild CMake", | ||
| }); | ||
|
|
||
| const projects = findCMakeProjects(tempDir); | ||
|
|
||
| assert.equal(projects.length, 3, "Should find all nested projects"); | ||
| assert( | ||
| projects.includes(path.join(tempDir, "parent")), | ||
| "Should include parent project" | ||
| ); | ||
| assert( | ||
| projects.includes(path.join(tempDir, "parent", "child")), | ||
| "Should include child project" | ||
| ); | ||
| assert( | ||
| projects.includes(path.join(tempDir, "parent", "child", "grandchild")), | ||
| "Should include grandchild project" | ||
| ); | ||
| }); | ||
|
|
||
| it("should work with Windows-style paths", { skip: process.platform !== "win32" }, (context) => { | ||
| const tempDir = setupTempDirectory(context, { | ||
| "windows\\style\\path\\CMakeLists.txt": "# CMake file", | ||
| }); | ||
|
|
||
| const projects = findCMakeProjects(tempDir); | ||
| assert.equal(projects.length, 1, "Should find project with Windows path"); | ||
| }); | ||
| }); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
34 changes: 34 additions & 0 deletions
34
packages/react-native-node-api-modules/scripts/build-weak-node-api.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| #!/usr/bin/env tsx | ||
|
|
||
| import { execSync } from "node:child_process"; | ||
| import { platform } from "node:os"; | ||
|
|
||
| // First generate the weak node API | ||
| execSync("npm run generate-weak-node-api", { stdio: "inherit" }); | ||
|
|
||
| // Build command with common flags | ||
| const baseCommand = "react-native-node-api-cmake --no-auto-link --no-weak-node-api-linkage --source ./weak-node-api"; | ||
|
|
||
| // Platform-specific flags | ||
| let platformFlags = ""; | ||
| switch (platform()) { | ||
| case "darwin": | ||
| // macOS: build for both Android and Apple | ||
| platformFlags = "--android --apple --xcframework-extension"; | ||
| break; | ||
| case "win32": | ||
| // Windows: only Android (no Apple/Xcode support) | ||
| platformFlags = "--android"; | ||
| break; | ||
| case "linux": | ||
| // Linux: only Android | ||
| platformFlags = "--android"; | ||
| break; | ||
| default: | ||
| console.error(`Unsupported platform: ${platform()}`); | ||
| process.exit(1); | ||
| } | ||
|
|
||
| const fullCommand = `${baseCommand} ${platformFlags}`; | ||
| console.log(`Running: ${fullCommand}`); | ||
| execSync(fullCommand, { stdio: "inherit" }); | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could extend the CLI to have an
--all-supportedflag which would include all triplets which are supported by the platform. I think that would make this a bit more DRY, solve the immediate issue and provide a feature for users too.