Skip to content

fix: rn-no-raw-text false positives for nested-Text wrappers and test files#790

Merged
aidenybai merged 6 commits into
mainfrom
devin/1781216818-rn-no-raw-text-wrapper-fp
Jun 12, 2026
Merged

fix: rn-no-raw-text false positives for nested-Text wrappers and test files#790
aidenybai merged 6 commits into
mainfrom
devin/1781216818-rn-no-raw-text-wrapper-fp

Conversation

@devin-ai-integration

@devin-ai-integration devin-ai-integration Bot commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

Summary

Fixes #788rn-no-raw-text flagged render(<Chip>Test Chip</Chip>) in Chip.test.tsx even though Chip forwards its children into a <Text>.

Two changes:

  1. test-noise tag on rn-no-raw-text. All 10 reported false positives were in __tests__/. Raw text rendered through RNTL in jest never reaches a device, and a single-file lint pass fundamentally cannot verify what an imported wrapper (<Chip> defined in another file) does with its children — test files were the main source of unfixable noise. Precedent: rn-no-scroll-state is an error-severity RN rule with the same tag.

  2. Deeper in-file wrapper detection. collectTextWrapperComponents previously only recognized wrappers whose returned root is a <Text>. It now also recognizes the issue's Chip shape — a nested text element that directly receives the forwarded children:

    const Chip = ({ children }) => (
      <View>
        <Text>{children}</Text>   // ← now detected ({children} or {props.children})
      </View>
    );
    const App = () => <Chip>Test Chip</Chip>; // no longer reported

    Detection also unwraps return (...) parenthesized bodies via the existing stripParenExpression util (the old root check silently missed any multi-line return ( <Text>… )). A wrapper whose nested <Text> receives something other than children (e.g. {title}, with bare {children} under the <View>) still reports.

Cross-file wrappers in non-test app code remain out of scope for the single-file pass; rawTextWrapperComponents config still covers those.

Tests: nested-forwarder pass cases ({children}, {props.children}), a still-fires case for non-children forwarding, and a testlike-filename skip case. nr test for react-native rules, nr lint, nr typecheck, nr format all pass (unrelated preexisting failures in no-multi-comp/jsx-no-new-* confirmed on clean main).

Link to Devin session: https://app.devin.ai/sessions/a6234d4616c3449f826c1a9b4d80ca04
Requested by: @aidenybai


Note

Medium Risk
Lint behavior changes: fewer app-code reports from expanded wrapper heuristics (with guarded fail cases), and the rule is fully suppressed in test-like files unless users re-enable the tag.

Overview
Fixes rn-no-raw-text false positives (#788) by tightening when the rule runs and how in-file “text wrapper” components are recognized.

test-noise tag — The rule now opts into the existing auto-suppress path for test/story files, so diagnostics from paths like Chip.test.tsx are dropped even when RNTL renders raw text inside imported wrappers the single-file pass cannot analyze.

In-file wrapper detectioncollectTextWrapperComponents no longer requires the returned JSX root to be <Text>. It treats a component as safe when any return path forwards the component’s own children (or props carrying children) into a text-handling element—e.g. <View><Text>{children}</Text></View>—while still rejecting paths that render those children outside <Text>. Detection was extended for memo/forwardRef, parenthesized returns, conditionals/logical returns, fragments, class render, styled(Text) / styled.Text, props spreads, aliases/destructures, and bounded transitive wrapper chains.

Tests cover the new pass/fail matrix and tag registration (react-native + test-noise on rn-no-raw-text).

Reviewed by Cursor Bugbot for commit eb7188a. Bugbot is set up for automated code reviews on this repo. Configure here.

… files (#788)

Co-Authored-By: Aiden Bai <aiden.bai05@gmail.com>
@devin-ai-integration

Copy link
Copy Markdown
Contributor Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment, CI, and merge conflict monitoring

@pkg-pr-new

pkg-pr-new Bot commented Jun 11, 2026

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/eslint-plugin-react-doctor@790
npm i https://pkg.pr.new/oxlint-plugin-react-doctor@790
npm i https://pkg.pr.new/react-doctor@790

commit: eb7188a

@github-actions

github-actions Bot commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

No React Doctor issues found. 🎉

Reviewed by React Doctor for commit eb7188a.

Co-Authored-By: Aiden Bai <aiden.bai05@gmail.com>
@devin-ai-integration

Copy link
Copy Markdown
Contributor Author

Devin test results — issue #788 repro (CLI end-to-end)

Built this branch and ran the CLI against a fresh repro project mirroring #788 (Chip.tsx forwarding children into a nested <Text> inside a <View>, plus __tests__/shared/components/Chip.test.tsx rendering <Chip>Test Chip</Chip>). All shell-based, so evidence is CLI output.

  • ✅ Baseline react-doctor@0.5.1 reproduces the false positive at Chip.test.tsx:6
  • ✅ PR build: no rn-no-raw-text diagnostic on the repro
  • ✅ No over-suppression: <View>Hello</View> in a non-test src/App.tsx still reported (and is the only raw-text diagnostic)
  • ✅ In-file Chip-shaped wrapper usage in a non-test file (src/ChipUsage.tsx) not reported
🟢 PR build on the issue repro (FP gone)
✔ Scanned 2 files in 1.0s [~8 workers]

  ⚠ Maintainability: deslop/unused-file
    src/shared/components/Chip.tsx

  All 1 issue
  Maintainability › 1 warning

(remaining warning is an unrelated unused-file note inherent to the minimal repro)

🔴 Baseline react-doctor@0.5.1 (bug reproduces)
  ✖ Bugs: Raw text outside a Text component
    Your users hit a crash when raw "Test Chip" renders outside
    a <Text> component on React Native.

    __tests__/shared/components/Chip.test.tsx:6
    │ > 6 |     render(<Chip>Test Chip</Chip>);
🟢 Still fires on a genuine bug; in-file wrapper suppressed
✔ Scanned 4 files in 1.0s [~8 workers]

  ✖ Bugs: Raw text outside a Text component
    Your users hit a crash when raw "Hello" renders outside a
    <Text> component on React Native.

    src/App.tsx:3
    │ > 3 | const App = () => <View>Hello</View>;

  ⚠ Maintainability: deslop/unused-file ×2
    src/ChipUsage.tsx
    src/shared/components/Chip.tsx

grep -c "Raw text outside" over the full verbose output = 1.

Devin session

…ditional returns, renamed children, children prop, transitive wrappers)

Co-Authored-By: Aiden Bai <aiden.bai05@gmail.com>
@aidenybai

Copy link
Copy Markdown
Member

/rde parity

@react-doctor-evals

react-doctor-evals Bot commented Jun 11, 2026

Copy link
Copy Markdown

Parity changed: +1 added · -1 removed across 1 repo

Baseline: main · This PR: devin/1781216818-rn-no-raw-text-wrapper-fp (3707de2)

tldraw/tldraw (packages/tlschema) — +1 / -1

✨ Added in this PR (not present in baseline)

circular-dependencysrc/TLStore.ts:0:0

Circular import cycle: src/TLStore.ts → src/records/TLAsset.ts → src/records/TLShape.ts �� src/shapes/TLArrowShape.ts → src/records/TLBinding.ts → src/recordsWithProps.ts → src/createTLSchema.ts. Modules in the cycle can observe partially initialized exports, causing order-dependent bugs.

   1 | import { Signal, computed } from '@tldraw/state'
   2 | import {
   3 | 	SerializedStore,
   4 | 	Store,
   5 | 	StoreSchema,
   6 | 	StoreSnapshot,
   7 | 	StoreValidationFailure,
   8 | } from '@tldraw/store'
   9 | import { IndexKey, JsonObject, annotateError, sortByIndex, structuredClone } from '@tldraw/utils'
  10 | import { TLAsset, TLAssetId } from './records/TLAsset'
  11 | import { CameraRecordType, TLCameraId } from './records/TLCamera'
  12 | import { DocumentRecordType, TLDOCUMENT_ID } from './records/TLDocument'

✅ Removed (fixed) in this PR (were in baseline)

circular-dependencysrc/TLStore.ts:0:0

Circular import cycle: src/TLStore.ts → src/records/TLAsset.ts → src/records/TLShape.ts → src/shapes/TLArrowShape.ts → src/records/TLBinding.ts → src/recordsWithProps.ts → src/createTLSchema.ts. Modules in the cycle can observe partially initialized exports, causing order-dependent bugs.

   1 | import { Signal, computed } from '@tldraw/state'
   2 | import {
   3 | 	SerializedStore,
   4 | 	Store,
   5 | 	StoreSchema,
   6 | 	StoreSnapshot,
   7 | 	StoreValidationFailure,
   8 | } from '@tldraw/store'
   9 | import { IndexKey, JsonObject, annotateError, sortByIndex, structuredClone } from '@tldraw/utils'
  10 | import { TLAsset, TLAssetId } from './records/TLAsset'
  11 | import { CameraRecordType, TLCameraId } from './records/TLCamera'
  12 | import { DocumentRecordType, TLDOCUMENT_ID } from './records/TLDocument'

⚠️ Partial coverage — 21 scans failed and are excluded from parity:

  • tldraw/tldraw#templates/vite — React Doctor failed: Invoking react-doctor on a worker failed
  • twentyhq/twenty#packages/twenty-front — React Doctor failed: Invoking react-doctor on a worker failed
  • tldraw/tldraw#packages/tldraw — React Doctor failed: Invoking react-doctor on a worker failed
  • makeplane/plane#packages/propel — React Doctor failed: Invoking react-doctor on a worker failed
  • twentyhq/twenty#packages/twenty-website-new — React Doctor failed: Invoking react-doctor on a worker failed
  • twentyhq/twenty#packages/twenty-ui — React Doctor failed: Invoking react-doctor on a worker failed
  • twentyhq/twenty#packages/twenty-server — React Doctor failed: Invoking react-doctor on a worker failed
  • makeplane/plane#packages/editor — React Doctor failed: Invoking react-doctor on a worker failed
  • excalidraw/excalidraw#packages/excalidraw — React Doctor failed: Invoking react-doctor on a worker failed
  • twentyhq/twenty#packages/twenty-sdk — React Doctor failed: Invoking react-doctor on a worker failed
  • tldraw/tldraw#packages/editor — React Doctor failed: Invoking react-doctor on a worker failed
  • tldraw/tldraw#packages/tldraw — React Doctor failed: Invoking react-doctor on a worker failed
  • makeplane/plane#packages/propel — React Doctor failed: Invoking react-doctor on a worker failed
  • twentyhq/twenty#packages/twenty-sdk — React Doctor failed: Invoking react-doctor on a worker failed
  • tldraw/tldraw#packages/editor — React Doctor failed: Invoking react-doctor on a worker failed
  • twentyhq/twenty#packages/twenty-server — React Doctor failed: Invoking react-doctor on a worker failed
  • twentyhq/twenty#packages/twenty-front — React Doctor failed: Invoking react-doctor on a worker failed
  • twentyhq/twenty#packages/twenty-website-new — React Doctor failed: Invoking react-doctor on a worker failed
  • excalidraw/excalidraw#packages/excalidraw — React Doctor failed: Invoking react-doctor on a worker failed
  • makeplane/plane#packages/editor — React Doctor failed: Invoking react-doctor on a worker failed
  • twentyhq/twenty#packages/twenty-ui — React Doctor failed: Invoking react-doctor on a worker failed

ℹ️ Re-run this parity check by commenting /rde parity on this PR.

trace 949cbc79862b9014e47fdea4965ad72d · rde

…yled(Text) factories as text wrappers

Co-Authored-By: Aiden Bai <aiden.bai05@gmail.com>
…en destructures

Co-Authored-By: Aiden Bai <aiden.bai05@gmail.com>

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 2 potential issues.

There are 3 total unresolved issues (including 1 from previous review).

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 67109b4. Configure here.

…reat childless props spreads as unsafe

Co-Authored-By: Aiden Bai <aiden.bai05@gmail.com>
@aidenybai aidenybai merged commit f52bd07 into main Jun 12, 2026
20 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

False positive for rn-no-raw-text with children inside custom component

1 participant