fix: rn-no-raw-text false positives for nested-Text wrappers and test files#790
Conversation
… files (#788) Co-Authored-By: Aiden Bai <aiden.bai05@gmail.com>
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
commit: |
|
No React Doctor issues found. 🎉 Reviewed by React Doctor for commit |
Co-Authored-By: Aiden Bai <aiden.bai05@gmail.com>
Devin test results — issue #788 repro (CLI end-to-end)Built this branch and ran the CLI against a fresh repro project mirroring #788 (
🟢 PR build on the issue repro (FP gone)(remaining warning is an unrelated unused-file note inherent to the minimal repro) 🔴 Baseline react-doctor@0.5.1 (bug reproduces)🟢 Still fires on a genuine bug; in-file wrapper suppressed
|
…ditional returns, renamed children, children prop, transitive wrappers) Co-Authored-By: Aiden Bai <aiden.bai05@gmail.com>
|
/rde parity |
|
❗ Parity changed: +1 added · -1 removed across 1 repo Baseline: tldraw/tldraw (packages/tlschema) — +1 / -1✨ Added in this PR (not present in baseline)
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)
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'
trace |
…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>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 2 potential issues.
There are 3 total unresolved issues (including 1 from previous review).
❌ 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>

Summary
Fixes #788 —
rn-no-raw-textflaggedrender(<Chip>Test Chip</Chip>)inChip.test.tsxeven thoughChipforwards its children into a<Text>.Two changes:
test-noisetag onrn-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-stateis an error-severity RN rule with the same tag.Deeper in-file wrapper detection.
collectTextWrapperComponentspreviously only recognized wrappers whose returned root is a<Text>. It now also recognizes the issue'sChipshape — a nested text element that directly receives the forwarded children:Detection also unwraps
return (...)parenthesized bodies via the existingstripParenExpressionutil (the old root check silently missed any multi-linereturn ( <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;
rawTextWrapperComponentsconfig 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 testfor react-native rules,nr lint,nr typecheck,nr formatall pass (unrelated preexisting failures inno-multi-comp/jsx-no-new-*confirmed on cleanmain).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-textfalse positives (#788) by tightening when the rule runs and how in-file “text wrapper” components are recognized.test-noisetag — The rule now opts into the existing auto-suppress path for test/story files, so diagnostics from paths likeChip.test.tsxare dropped even when RNTL renders raw text inside imported wrappers the single-file pass cannot analyze.In-file wrapper detection —
collectTextWrapperComponentsno longer requires the returned JSX root to be<Text>. It treats a component as safe when any return path forwards the component’s ownchildren(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 formemo/forwardRef, parenthesized returns, conditionals/logical returns, fragments, classrender,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-noiseonrn-no-raw-text).Reviewed by Cursor Bugbot for commit eb7188a. Bugbot is set up for automated code reviews on this repo. Configure here.