Repository navigation
Commit 9dbb7e5
Add regression tests for the iOS SwiftPM tooling (#59217)
Summary:
Recent fixes to the iOS SwiftPM tooling (`scripts/spm`) all fixed bugs that CI did not catch. Adopters found them first. Each fix added a test for its own bug only. The bugs fall into a few classes: output that changes when nothing changed, generated names that collide or do not resolve, values that are hard-coded instead of read from the app, machine-specific paths in files that users commit, and malformed files that Xcode tolerates.
This PR adds two test-only tools that look for each class in general. They run in the existing Linux Jest job (`test_js`). No production code changes.
1. **Invariant checker** (`spm-invariants.js`, not a test file itself). It reads the files that the tooling generates and returns a list of violations:
- no machine paths (temp dir, `$HOME`, absolute build-setting values) in `project.pbxproj`, `.xcscheme`, or `.spm-injected.json`;
- the scheme parses as XML, and the pre-action script keeps its line breaks;
- in every generated `Package.swift`, target and product names are unique (also case-insensitive) and valid C99 identifiers, and every dependency resolves, including products of local `.package(path:)` dependencies;
- every generated or scaffolded manifest uses the app's iOS deployment target; the codegen manifest, whose template fixes `.iOS(.v15)`, must not be above it;
- `project.pbxproj` is balanced, every referenced object ID is defined, and the frameworks in `.spm-injected.json` match the project.
Each rule also fails when the file or field it checks is missing, so a check cannot pass by finding nothing.
2. **Lifecycle test** (`spm-lifecycle-test.js` + `spm-fixture-app.js`). It builds a fake app on disk (deployment target 16.4), fake prebuilt artifacts for two React Native versions, and four fake libraries: one with its own `Package.swift`, one podspec-only library with `module_name` different from its npm name, one scoped `acme/…` package, and one autolinking plugin with a flavored framework. It then runs `scaffold → add → sync → sync → update (same version) → update (next version) → deinit` through `setup-apple-spm.js`, and runs the checker after each step. It also asserts:
- a second sync changes no byte and replaces no `libs/` entry;
- the build-time stale check reacts to the right changes and ignores files that Xcode writes;
- a plugin framework mismatch makes sync exit with code 2;
- `update` to the same version and `deinit` restore the project and scheme byte for byte.
Network access, `plutil`, `otool`, codegen and `pod` are mocked, so the test runs offline on Linux.
## Changelog:
[INTERNAL] [ADDED] - Add regression tests for the iOS SwiftPM tooling
Pull Request resolved: #59217
Test Plan:
```
yarn jest --no-cache -i packages/react-native/scripts/spm/__tests__
```
Result: 24 suites, 1124 tests, all passed, about 23 s (on main at dd9b6c5). The two new suites take about 4 s.
Each earlier fix was undone one at a time with `git show <sha> -- ':!**/__tests__/**' | git apply -R`, and the new tests failed each time:
| Fix reverted | New tests failing |
|---|---|
| #58826 (scheme pre-action newlines) | 9 |
| #58292 (absolute `HERMES_CLI_PATH` in pbxproj) | 9 |
| #58597 (`libs/` rewritten on every sync) | 2 |
| #58828 (watched path absent at add time) | 1 |
`yarn eslint` and `prettier --check` on the new files: clean.
Not run: Linux locally. The `test_js` job on this PR is the first Linux run.
Reviewed By: cortinico
Differential Revision: D126304581
Pulled By: cipolleschi
fbshipit-source-id: c1bacf9ef2c6955a262cac0053491d69535375e9
(cherry picked from commit fba55e2)1 parent 84e60bc commit 9dbb7e5
4 files changed
Lines changed: 2202 additions & 0 deletions
File tree
- packages/react-native/scripts/spm/__tests__
0 commit comments