Skip to content

Commit 0985b83

Browse files
committed
iOS: bspatch integration
1 parent 36ca242 commit 0985b83

39 files changed

Lines changed: 514 additions & 38 deletions

File tree

.github/workflows/ci-test.yml

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -104,14 +104,14 @@ jobs:
104104
arch: x86
105105
disable-animations: true
106106
# connectedAndroidTest is included here (rather than a separate job or step) to reuse
107-
# this job's already-booted emulator, even though it means it runs once per matrix
108-
# variant. The android-emulator-runner action has no post-cleanup step, so a second
109-
# step would boot and tear down a second emulator; ::group:: markers keep the two
110-
# test runs visually separated in the Actions log instead.
107+
# this job's already-booted emulator.
111108
script: |
112-
echo "::group::Instrumented tests"
113-
(cd android && ./gradlew :app:connectedAndroidTest)
114-
echo "::endgroup::"
109+
if [ "${{ matrix.variant }}" = "bare" ]; then
110+
# These tests are independent of the bare/expo distinction. Bare tests are slightly faster.
111+
echo "::group::Instrumented tests"
112+
(cd android && ./gradlew :app:connectedAndroidTest)
113+
echo "::endgroup::"
114+
fi
115115
echo "::group::E2E tests"
116116
npm run ${{ matrix.test-command }}
117117
echo "::endgroup::"
@@ -141,10 +141,16 @@ jobs:
141141
restore-keys: |
142142
${{ runner.os }}-npm-
143143
144-
- name: Run iOS Tests
145-
run: |
146-
npm install
147-
npm run ${{ matrix.test-command }}
144+
- name: Install dependencies
145+
run: npm install
146+
147+
- name: Run iOS unit tests
148+
# These tests are independent of the bare/expo distinction. Bare tests are slightly faster.
149+
if: matrix.variant == 'bare'
150+
run: npm run test:unit:ios
151+
152+
- name: Run iOS E2E Tests
153+
run: npm run ${{ matrix.test-command }}
148154

149155
- name: Upload iOS Simulator crash reports
150156
if: failure()

.npmignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ android/.gradle
5252
android/**/*.iml
5353
android/.idea
5454

55+
ios/CodePushDiffPatchTests/
56+
5557

5658
# Windows
5759
windows/.vs/

CLAUDE.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,10 @@ React Native CodePush is a native module that enables over-the-air updates for R
1010

1111
#### Unit tests
1212

13-
- `cd android && ./gradlew :app:test`
14-
- iOS: no unit tests yet.
13+
- `npm run test:unit:android`
14+
- `npm run test:unit:ios`
15+
16+
Prefer unit testing what's possible (even though, on iOS, this involves a simulator). Legacy code used E2E tests for everything, which is complex, error-prone, and slow. The existing E2E tests are still useful, but this is not a pattern to follow.
1517

1618
#### E2E Tests
1719
- `npm run test:android` - Run Android-specific tests
@@ -54,7 +56,7 @@ React Native CodePush is a native module that enables over-the-air updates for R
5456
- **Custom Test Runner**: TypeScript-based test framework in `test/`
5557
- **Real App Testing**: Creates actual React Native apps for integration testing
5658
- **Scenario Testing**: Update, rollback, and error scenarios
57-
- **No unit test infra for JS/iOS yet**: JS/iOS only have the mocha-based integration suite above. `src/acquisition-sdk/__tests__/` contains tests ported from upstream `microsoft/code-push`, kept for future reference - they are deliberately not wired into `npm test` or any runner. Don't assume they're dead/forgotten code, and don't wire them in without setting up real unit test infra first.
59+
- **No unit test infra for JS yet**: JS only has the mocha-based integration suite above. `src/acquisition-sdk/__tests__/` contains tests ported from upstream `microsoft/code-push`, kept for future reference - they are deliberately not wired into `npm test` or any runner. Don't assume they're dead/forgotten code, and don't wire them in without setting up real unit test infra first.
5860
- **Templates**: `test/template/` holds native files (Podfile, AppDelegate, Android app files) and JS scenarios copied over top of a freshly generated RN/Expo app during test setup, overwriting its defaults — edit files here, not the generated project, for changes to persist
5961
- **`test:ios` vs `test:setup:ios` vs `test:fast:ios`**: `test:ios` is just `test:setup:ios` followed by `test:fast:ios` — the two are meant to be split apart for local iteration.
6062
- `test:setup:ios` (mocha `--ios --setup`) boots the simulator and provisions the test app once: copies templates, runs `pod install`, patches Info.plist/AppDelegate. It never builds or runs any test scenario.

android/app/src/main/cpp/CMakeLists.txt

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,12 @@ project(codepush_diffpatch C)
1212
# See third_party/README.md for what we vendor and why.
1313
add_library(codepush_diffpatch SHARED
1414
diffpatch_jni.c
15-
bspatch_bridge.c
15+
../../../../../shared/diffpatch/bspatch_bridge.c
16+
17+
../../../../../shared/third_party/hdiffpatch/libHDiffPatch/HPatch/patch.c
18+
../../../../../shared/third_party/hdiffpatch/bsdiff_wrapper/bspatch_wrapper.c
19+
../../../../../shared/third_party/hdiffpatch/file_for_patch.c
1620

17-
third_party/hdiffpatch/libHDiffPatch/HPatch/patch.c
18-
third_party/hdiffpatch/bsdiff_wrapper/bspatch_wrapper.c
19-
third_party/hdiffpatch/file_for_patch.c
20-
2121
bzip2_error_stub.c
2222
third_party/bzip2/bzlib.c
2323
third_party/bzip2/decompress.c
@@ -28,6 +28,8 @@ add_library(codepush_diffpatch SHARED
2828

2929
target_include_directories(codepush_diffpatch PRIVATE
3030
.
31+
../../../../../shared/diffpatch
32+
../../../../../shared
3133
third_party/bzip2
3234
)
3335

android/app/src/main/cpp/third_party/README.md

Lines changed: 1 addition & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,6 @@
11
# Vendored sources
22

3-
These directories contain trimmed copies of two upstream libraries, pinned
4-
to a specific commit. Only the files needed to *apply* a BSDIFF40-style
5-
patch (the `hdiffz -BSD` producer output) are vendored. `hdiffpatch/` is an
6-
unmodified-source copy; `bzip2/bzlib.c` carries one small, documented patch
7-
(see below).
8-
9-
## hdiffpatch/
10-
11-
Source: https://github.com/sisong/HDiffPatch
12-
Pinned commit: `3b9dca715ca492873bf2c49e22e5d5b7d2a78620` (2026-07-31)
13-
License: MIT.
14-
15-
Files were chosen by tracing the actual dependency graph of
16-
`bsdiff_wrapper/bspatch_wrapper.c` (the BSDIFF40-compatible patch applier),
17-
not by directory boundaries. In particular `libHDiffPatch/HPatch/patch.c`
18-
(~157KB) is HDiffPatch's own diff-format decoder, but it's still required
19-
here because `bspatch_wrapper.c` shares its low-level stream-cache helpers
20-
(`_TOutStreamCache_*`, `getStreamClip`, `_patch_cache_all_old`, etc.).
3+
Note: `shared/third_party/` also contains vendored sources, shared between Android and iOS.
214

225
## bzip2/
236

android/app/src/main/java/com/microsoft/codepush/react/diffpatch/DiffPatch.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ object DiffPatch {
3737
UNKNOWN;
3838

3939
companion object {
40-
// Keep in sync with cpp/bspatch_bridge.h
40+
// Keep in sync with shared/diffpatch/bspatch_bridge.h
4141
fun fromNativeCode(code: Int): PatchResult = when (code) {
4242
0 -> OK
4343
1 -> BAD_DIFF_HEADER

0 commit comments

Comments
 (0)