chore(lint): make it harder for me to accidentally product ai slop code - #143
Conversation
Vendor the generic anti-slop Oxlint plugin and run it after ESLint so the Expo SDK matches the Web SDK lint bar without dropping eslint-config-expo or the native i18n ESLint checks. Co-authored-by: Cameron Pak <cameronandrewpak@gmail.com>
…y MMKV Drop app-module jest.mock from core tests. Native runtimes stay shimmed in jest.setup.js. Tests spyOn named exports, steer hooks through hookOverrides, and use the real mmkvStorage backed by the in-memory MMKV factory. Co-authored-by: Cameron Pak <cameronandrewpak@gmail.com>
jest.setup.js mocks are process-wide jest.fn instances. spyOn returns those same mocks, so call history leaked across cases until each suite clears them in beforeEach. Co-authored-by: Cameron Pak <cameronandrewpak@gmail.com>
Replace file-level jest.mock of DOM wrappers, sibling sheets, and core hooks with setImpls/captureDom/installBibleReaderTestImpls and YouVersionProvider hookOverrides. Safe-area setup now honors SafeAreaProvider initialMetrics so inset tests do not need module mocks. Co-authored-by: Cameron Pak <cameronandrewpak@gmail.com>
Seed the highlight write queue in MMKV instead of spying on a non-configurable core export. Route BibleReader highlight stubs through useHighlightPermissionFlow, unwrap the Gorhom mock default export, and assert the real missing-provider error from useYouVersion. Co-authored-by: Cameron Pak <cameronandrewpak@gmail.com>
NativeSheet default-imports BottomSheet. The official CJS mock is a
namespace object, so React tried to mount it ("got: object"). Setup now
exports a capturing forwardRef default and BottomSheetView testIDs.
Co-authored-by: Cameron Pak <cameronandrewpak@gmail.com>
NativeSheet reads the RN getter over Libraries/Utilities/useWindowDimensions, so spyOn(ReactNative, useWindowDimensions) never reached the sheet. Setup now mocks that module; NativeSheet tests assign width before render. Co-authored-by: Cameron Pak <cameronandrewpak@gmail.com>
Replace jest.mock of DOM, sheets, and core hooks with render-time registries so tests do not mount 'use dom' or live fetch. Co-authored-by: Cameron Pak <cameronandrewpak@gmail.com>
Drop ESLint. Port native i18n and Expo DOM rules onto oxlint jsPlugins, enable tsgolint, and pin typescript@7.0.2. Co-authored-by: Cameron Pak <cameronandrewpak@gmail.com>
Parse persist/token I/O with zod, replace Record widenings with satisfies, type catch sites through toMessage(Error), and add explicit component/hook return types without suppressing anti-slop rules. Co-authored-by: Cameron Pak <cameronandrewpak@gmail.com>
Co-authored-by: Cameron Pak <cameronandrewpak@gmail.com>
Replace setImpls with setImpl, name DOM/sheet capture types, drop runtime typeof and chained assertions, and type fetch/JSON/JWT fixtures at their boundaries without suppressing anti-slop rules. Co-authored-by: Cameron Pak <cameronandrewpak@gmail.com>
Give lastRequest a named return type and extract RequestInit bodies through instanceof narrowing so oxlint stays clean in the API tests. Co-authored-by: Cameron Pak <cameronandrewpak@gmail.com>
Keep x-yvp-sdk as the exact object key the client sends, and throw synchronously from getOrSetInstallationId so requestPermissions catch can surface a transient failure. Co-authored-by: Cameron Pak <cameronandrewpak@gmail.com>
document.createElement is unavailable in the native test environment. Keep a typed style-map fixture and assert to HTMLElement with SAFETY. Co-authored-by: Cameron Pak <cameronandrewpak@gmail.com>
Narrow mock.calls before use, type SignInResult and WebBrowser dismiss mocks, export AuthContextValue, and override DOM reader actions with Omit so TS 7 and oxlint stay clean. Co-authored-by: Cameron Pak <cameronandrewpak@gmail.com>
Avoid the mocked WebBrowserResultType enum at runtime, restore nullable backdrop checks, and resolve tsc via typescript/package.json so Jest can find it. Co-authored-by: Cameron Pak <cameronandrewpak@gmail.com>
Oxlint ignorePatterns does not expand {ts,tsx} braces, so list
__tests__ and *.test.tsx explicitly.
Co-authored-by: Cameron Pak <cameronandrewpak@gmail.com>
CI regenerates locales/index.ts and fails if the committed file differs. Keep SdkI18nResourceMap in the generator template. Co-authored-by: Cameron Pak <cameronandrewpak@gmail.com>
|
@greptile-apps, please review this PR |
Override wrappers still call the real hook for rules of hooks, but gate GET, drain notify, and cache persist so authenticated test seams cannot hit the network. Co-authored-by: Cameron Pak <cameronandrewpak@gmail.com>
|
@greptile-apps, updates have been made, so please re-review |
Keep hookOverrides live-gating and component-impls test seams. Keep host highlight paint (enabled/useHighlightPaint) and version filter lists from main. Convert incoming highlights-bridge suites off jest.mock of DOM modules. Co-authored-by: Cameron Pak <cameronandrewpak@gmail.com>
Incoming highlight-paint and version-filter code tripped anti-slop and explicit return types. Keep the new behavior; drop jest.mock of app modules and runtime typeof checks. Co-authored-by: Cameron Pak <cameronandrewpak@gmail.com>
Keep getImpl, ReactNode, and lint-safe fetch helpers. Take platform-core/react-ui 2.8.0 header combining (X-YVP-Sdk / ReactSDK) and drop unused useCallback/useMemo wraps from #141. Co-authored-by: Cameron Pak <cameronandrewpak@gmail.com>
Co-authored-by: Cameron Pak <cameronandrewpak@gmail.com>
|
@greptile-apps, please re-review. You don't have to re-review every single file, because I just did some small fixes, but honestly, you do whatever's best for you. |
Conflicting-intent merge with main after #146 (YPE-5118). Keep InternalLocaleProps and locale={locale} on every DOM WebView plus native pass-through. Keep oxlint ReactNode returns, typed DOMProps, getImpl test seams, and SAFETY comments. Lockfile regenerated with pnpm install --config.minimumReleaseAge=0. Co-authored-by: Cameron Pak <cameronandrewpak@gmail.com>
Keep #146 device-resolved locale assertions. Steer expo-localization through spyOn so oxlint no-module-mocking stays clean. Co-authored-by: Cameron Pak <cameronandrewpak@gmail.com>
|
@greptile-apps, review this and rip it to shreds to make sure the PR is bulletproof |
camrun91
left a comment
There was a problem hiding this comment.
Marking as requesting changes as there are a few things that at least should be discussed. There are a few other things that claude called out but I do not think are big enough right now. if they show back up when these are closed I may surface them.
Reading window.localStorage can throw in a sandboxed WebView. Catch that read separately and still install the memory shim, matching old main. Co-authored-by: Cameron Pak <cameronandrewpak@gmail.com>
One wrong-typed field no longer nulls book, chapter, and versionId. Restore per-field parse after JSON.parse; keep typed-but-invalid rehydrate. Co-authored-by: Cameron Pak <cameronandrewpak@gmail.com>
startWrite now follows the same live flag as fetch and persist. A permission-only hook override no longer enqueues or transmits apply/remove. Co-authored-by: Cameron Pak <cameronandrewpak@gmail.com>
Switching to oxlint does not drop warn-fail. Keep lint:native-i18n in Lint. Co-authored-by: Cameron Pak <cameronandrewpak@gmail.com>
The scripts fixture was ignored, so the regression never ran. Point the test at a packages/ui file so a global no-literal-string rule would fail it. Co-authored-by: Cameron Pak <cameronandrewpak@gmail.com>
Named WindowStub lets the accessor test install a throwing getter without an assertion that oxlint rejects at --max-warnings=0. Co-authored-by: Cameron Pak <cameronandrewpak@gmail.com>
View has no headerTitle. Keep the literal attributes on a typed host so oxlint still inspects them and typecheck stays clean. Co-authored-by: Cameron Pak <cameronandrewpak@gmail.com>
|
@greptile-apps, it's time for a re-review. Scrutinize this PR to make it as good as it can be. |
camrun91
left a comment
There was a problem hiding this comment.
Re-reviewed after the latest push. The five fixes all check out. I traced 765ef28 against main's old per-field semantics across every edge case (numeric chapter, 3.7, 0, -1, NaN, Infinity, "abc", "", booleans, string versionId, arrays, non-object JSON) and they all match. 6cbda01's guard is the first statement in startWrite, before any state touch, and live is always true without overrides, so production is untouched. The number_of_files > 0 guard in 9a72036 is better than what I suggested — it makes that test fail closed.
Three items are inline. Two more are below, because their lines fall outside this PR's diff.
Orphaned ESLint script now points at a deleted fixture (new)
9a72036 deleted scripts/eslint-fixtures/native-i18n/outside-native-scope.tsx, but scripts/test-native-i18n-eslint.mjs:115 still reads that exact path. That file is already unreachable — nothing invokes it since lint:native-i18n moved to the oxlint version, and eslint / eslint-config-expo were dropped from devDependencies — so it can't even run to fail. scripts/eslint-native-i18n-config.mjs (its only import target) is equally orphaned. Anyone opening either file to understand the i18n scoping rules reads instructions for a linter this repo no longer has.
Suggest: delete both files. (Not inline — neither is in this PR's diff.)
web-yv-provider.test.tsx:114 locale assertion fails open (inherited from #146, not this PR)
Flagging for a follow-up on main rather than as a blocker here — I confirmed both this assertion and the two-branch reader already exist on main.
expect(source).toMatch(/locale=\{locale\}/) with a non-global regex is a single "appears anywhere" check, but dom/bible-reader.tsx has two YouVersionProvider return branches (includeAuth true / false). Delete locale={locale} from the includeAuth branch at line 321 and every test stays green — the regex matches the surviving occurrence at line 338, and the runtime tests stub BibleReaderDom through setImpl so they never reach the web provider. Authenticated readers (the branch consumers hit whenever auth is configured) would render English inside the WebView with nothing red. The version-filter assertion above it has the same weakness, for the same reason.
Suggest: assert an occurrence count, or one match per <YouVersionProvider block.
Deliberately not filed
oxlint.config.ts:51 still excludes **/scripts/**, **/*.config.*, **/*.d.ts, and **/jest.setup.js from lint, where the old ESLint config covered scripts/. This push is itself evidence of the cost — 9a72036 had to relocate the i18n fixture out of scripts/ precisely because oxlint never inspects it. Still open, just not blocking.
|
Went ahead and had my robo friend Claude look into it the fixes look good I had it post the other high ones and two new ones that I also validated. |
One wrong-typed field no longer drops font size, family, and spacing. Parse the persist envelope as unknown optional keys, then validate each field on its own. Twin wrong-type test matches reader location. Co-authored-by: Cameron Pak <cameronandrewpak@gmail.com>
Nothing invoked these after lint:native-i18n moved to oxlint. The old fixture path is gone. Co-authored-by: Cameron Pak <cameronandrewpak@gmail.com>
|
Too many files changed for review (190 files, 100 file limit). Bypass the limit by tagging |
|
Orphaned ESLint scripts: deleted. Nothing invoked them after oxlint. Locale source-regex fail-open: inherited from #146. Follow-up on main. oxlint scripts ignore: left alone. You said not blocking. Code Implementor, sent on behalf of Cam. I am AI. |
Bring in hide-swatches-when-unauth from main plus version packages. Keep hookOverrides test seams. Empty swatch tray when auth is null. Co-authored-by: Cameron Pak <cameronandrewpak@gmail.com>
This PR now has no changeset, but it still adds public APIMerging That leaves the branch adding public API with nothing to version it:
Suggest: a Scoping note, since I overstated this in earlier review notes: I checked whether the |
camrun91
left a comment
There was a problem hiding this comment.
One thing to call out but It may not be blocking.
Adds oxlint anti-slop to the Expo SDK. Generated slop fails lint.
Replaces
jest.mockwithhookOverridesand component impls. Tests do not hoist mocks or mountuse dom.Keeps #146. Provider locale still reaches every DOM WebView (YPE-5118).
Inspiration: https://x.com/dillon_mulroy/status/2087531327000117630
Greptile Summary
The PR replaces application-module Jest mocks with explicit hook and component test seams while moving lint enforcement to type-aware Oxlint.
hookOverridesand native component implementations for tests without mounting Expo DOM components.Confidence Score: 5/5
The PR appears safe to merge.
No blocking failure remains; the previously reported live-work and live-write paths are now gated before their observable side effects.
Important Files Changed
Reviews (5): Last reviewed commit: "fix(test): type the outside-native-scope..." | Re-trigger Greptile