Repository navigation
[agent-cli] E2E-cover the status cases the flag removal left uncovered - #72
Conversation
ae8f645 to
870a8ea
Compare
870a8ea to
34d5d52
Compare
34d5d52 to
b49c535
Compare
b49c535 to
b168aa5
Compare
b168aa5 to
b0a5c2b
Compare
b0a5c2b to
285bb92
Compare
285bb92 to
c37d9fc
Compare
c37d9fc to
dfdf7dc
Compare
6202928 to
8c2dd26
Compare
An audit of `status` against `e2e/__tests__/status-test.ts`, branch by branch, after `--explain` went. What was missing, now covered through the published bin: - `--build <id>` end to end. The shared stub `eas` answers `fingerprint:compare` and `build:view`, and a stub `fingerprint` diffs the two sides the way the real CLI does. A matching build, a differing one and what it costs, the text that names the base, the gate judging the eas axis under `--assert`, a build whose platform EAS cannot name (attributed to none, exit 22), and a comparison that fails (report kept, id echoed, note printed — F66). - A directory that is not an Expo app: `isExpoApp: false`, `next` is `new my-app`, the fact second on the project line, exit 0. - The change detail at scale: eight rows then a count, and platforms whose lists agree printed once. - The file-level view under a committed tree: nothing changed, a JavaScript edit (`files 1 changed · 1 js`), and `metro.config.js` raising the class to `dev-client-compatible` with the restart follow-up. - The follow-ups `runtime-errors`, `install-dev-client` and `skills-sync`, each on the one fact that fires it; the class ladder's head beside the OTA verdict. - Step 2 of the discovery ladder: a dev server the project's own `start.log` names, found with no URL given and reported as `source: log`. Co-authored-by: kudo <46429+kudo@users.noreply.github.com>
Co-authored-by: kudo <46429+kudo@users.noreply.github.com>
…l change Co-authored-by: kudo <46429+kudo@users.noreply.github.com>
8c2dd26 to
27bb0e2
Compare
|
|
||
| const json = await runBuildAsync(projectRoot, ['--json'], { STUB_EAS_COMPARE_EXIT: '1' }); | ||
| const report: StatusReport = JSON.parse(json.stdout); | ||
| expect(report.errors.freshness).toContain(BUILD_ID); |
There was a problem hiding this comment.
[💡 suggestion] This PR teaches the shared stub to answer fingerprint:compare. That changes what the older test 'takes --build, and echoes the build it was given' does: it now runs the success path, not the failure path its removed comment described (F66). This new failure test does not take over the F66 check. Its text assertion toContain(BUILD_ID) passes from the vs EAS build <id> header alone. errors.freshness names the id in any case. If compareAgainstEasBuildAsync went back to writing comparison after the call (the F66 bug), both halves would still pass. The unit test mocks the error text, so it does not pin this either. Add expect(report.freshness!.comparison).toMatchObject({ kind: 'eas-build', buildId: BUILD_ID }) to the JSON half, and also assert json.exitCode.
There was a problem hiding this comment.
Done in 8ac51d0. The JSON half now asserts json.exitCode is 0 and report.freshness.comparison matches { kind: 'eas-build', buildId: BUILD_ID }. I checked that it pins F66: with the comparison write moved back after the call, this test fails (kind: 'last-build').
|
|
||
| const report = await reportInAsync(projectRoot); | ||
|
|
||
| expect(report.next).toMatchObject({ command: 'npx @expo/agent-cli new my-app' }); |
There was a problem hiding this comment.
[💡 suggestion] project-shapes-test.ts ('lets status report, and stops it recommending a build here' and 'says so on the project line') already covers isExpoApp: false, next.rule, empty steps, exit 0 and the project line. This test adds only the new my-app command. The behavior that is not pinned is that buildStatusFollowUps returns only not-expo-app and drops every other rung (llp/0004 §Not an Expo app). Assert report.followups.map((f) => f.id) equals ['not-expo-app'], or move this assertion into the existing project-shapes test. As written, the PR body overstates what this test adds.
There was a problem hiding this comment.
Done in 8ac51d0. The test now asserts report.followups.map((f) => f.id) equals ['not-expo-app']. I also changed the PR body so it claims only this, the new my-app command and the follow-up, and points to project-shapes-test.ts for the rest.
| // @ref llp/0011-impact-and-freshness.rfc.md §When the fingerprint did not move | ||
| describe('the changed files, when the fingerprint did not move', () => { | ||
| const APP_CONFIG = { type: 'file', filePath: 'app.json', reasons: ['expoConfig'], hash: 'cc' }; | ||
| const STUB_FINGERPRINT = `#!/usr/bin/env node |
There was a problem hiding this comment.
[🐧 nit] This is the sixth copy of the env-driven STUB_FINGERPRINT and its install-into-.stub-bin-and-node_modules/.bin setup in this file (the other copies are at lines 846, 978, 1266, 1690 and 1891, and this PR adds two of them). Move it to one top-level helper, for example installEnvFingerprintStubAsync(projectRoot, { diff?: boolean }), so the next change to the stub contract is made in one place.
There was a problem hiding this comment.
Done in 8ac51d0. installEnvFingerprintStubAsync(projectRoot, { diff?, platformHashes? }) is now the one place the env-driven stub lives. All six copies use it: diff: true for the --build block, and platformHashes for the EAS lookup block, which printed a different hash per platform. #77 and #159 add no copies of their own.
…e2e, and share one fingerprint stub helper
… the tunnel lines of status (#77) Stack 5/5 of the `status` plan. Based on #72. Tests only. ## Why The last `status` branches without an e2e were the ones that depend on what the runner has: `xcrun simctl` and `adb`. #72 listed them as left out; this closes them. ## How - A stub `xcrun` in `.stub-bin` (first on the `PATH` the run gets) answers `simctl list devices booted -j` with a booted iPhone or with none. A stub `adb` under a per-test `ANDROID_HOME/platform-tools` answers `devices -l` with an emulator or with none — the resolver reads `ANDROID_HOME` before `PATH` (`src/device/adb.ts`). - "Cannot be run" (`unknown`): the execute bit withheld **and** a `PATH` of the stub directory alone, because a `PATH` search skips a file it cannot run and finds the machine's own `xcrun` next. `adb` is spawned by path, so the bit alone suffices there. - Cases: attached Android device (text `android emulator-5554`); booted iOS simulator by name with both devices listed (F106; macOS only, the probe does not run elsewhere); `absent` with the tools' reasons; `unknown`, never rounded down to none (POSIX only — a `.cmd` shim has no execute bit to withhold); a dev server up with nothing attached and no device → an `exp://` address or `navigate / --print-url`, never `navigate /`; an EAS Simulator session on record → `smoke --ios --eas` with an app connected, `navigate / --eas` without, the session still named when the tools could not answer, and the local path kept when a device *is* here (K7a); a tunnelled dev server (lock + detached log newer than it) → `hostType: tunnel`, `tunnelUrl`, `openUrls` on the tunnel host, the `tunnel` fact and `open in …: exp://…` lines (K7c, K8); a stale tunnel dropped once its dev server is gone. - Left out on purpose: the 8082–8085 port-scan rung (fixed ports collide on shared runners). ## Test Plan - `bun run typecheck`, `bun run lint`, `bun run test:e2e -- status-test` (130 pass locally on macOS; 2 cases skip on Windows, 1 on Linux by design). --------- Co-authored-by: expo-tuft[bot] <288127324+expo-tuft[bot]@users.noreply.github.com> Co-authored-by: kudo <46429+kudo@users.noreply.github.com> Co-authored-by: Kudo Chien <kudo@expo.dev>
Stack 4/4 of the plan to remove
status --explain. Based on #71. Tests only; no CHANGELOG entry.Why
Kudo asked for e2e coverage of every
statuscase. This is the audit ofstatusagainste2e/__tests__/status-test.tsafter the flag went, and the cases it was missing.What is covered now
--build <id>end to end. The shared stubeas(e2e/stubs/eas.js) answersfingerprint:compare(STUB_EAS_COMPARE_JSON/STUB_EAS_COMPARE_EXIT) andbuild:view(STUB_EAS_BUILD_VIEW_PLATFORM/STUB_EAS_BUILD_VIEW_EXIT). The sharedinstallEnvFingerprintStubAsynchelper, withdiff: true, gives a stubfingerprintthat answersfingerprint:diffby diffing the two files, the way the real CLI does. Cases: a matching build (eas axis fresh on the build's platform, "not compared" on the other, local axis untouched); a differing build and what it costs (needs-native-build, the added source listed); the text namingvs EAS build <id>;--assert js-only --buildjudging the eas axis (20 / 0); a build whose platform EAS cannot name (comparison attributed to none, both axes "not compared",--assertexits 22); a failing comparison (exit 0 in text and JSON,freshness noteprinted, andcomparisonstill names the build: F66).next.commandisnpx @expo/agent-cli new my-app, andnot-expo-appis the only follow-up (llp/0004 §Not an Expo app).project-shapes-test.tsalready covers the rest.… and 2 more, in --json, and platforms whose lists agree printed once (ios, android: 10 sources). The class ladder's head in the follow-ups beside the OTA verdict.total: 0), a JavaScript edit (files 1 changed · 1 js · 0 config · 0 native, classjs-only),metro.config.jsraising the class todev-client-compatiblewith thechange-restart-metrofollow-up.runtime-errorswith an app connected,install-dev-clientfor a project Expo Go cannot run and that has no dev client,skills-syncwhen discovered skills are not linked.start.lognames, found with no URL given,source: log.Still uncovered, on purpose
The device section's
present/absent/unknownand the cloud-sessionnextvariants depend onxcrun simctlandadbon the runner. They need stubbed platform tools onPATH/ANDROID_HOMEand are a separate change.Test Plan
bun run typecheck,bun run test:e2e -- status-test(119 pass, 17 new).