From 7984d4ee6c36bded65a47df0ea356b2092ae3ff2 Mon Sep 17 00:00:00 2001 From: Gowtham G Date: Tue, 6 Oct 2026 22:18:44 +0530 Subject: [PATCH 1/3] fix: scope MDImage image-size effect to uri changes The effect ran after every render and re-fetched on each update, causing a render loop under async act. --- src/components/MDImage.tsx | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/components/MDImage.tsx b/src/components/MDImage.tsx index 6fcaaa1d..78e2bd8a 100644 --- a/src/components/MDImage.tsx +++ b/src/components/MDImage.tsx @@ -38,7 +38,7 @@ const MDImage: FunctionComponent = ({ * Fetches image dimension * Sets aspect ratio if resolved */ - const fetchOriginalSizeFromRemoteImage = () => { + useEffect(() => { Image.getSize( uri, (width: number, height: number) => { @@ -57,11 +57,7 @@ const MDImage: FunctionComponent = ({ }); }, ); - }; - - useEffect(() => { - fetchOriginalSizeFromRemoteImage(); - }); + }, [uri]); return ( Date: Tue, 6 Oct 2026 22:18:51 +0530 Subject: [PATCH 2/3] chore: update react-native-testing-library to v14 Migrate tests to async render/fireEvent APIs. Add test-renderer peer dep, drop universal-test-renderer. --- package-lock.json | 179 ++-- package.json | 6 +- .../useMarkdownWithComponents.spec.tsx | 36 +- src/lib/__tests__/Markdown.spec.tsx | 226 ++--- src/lib/__tests__/Renderer.spec.tsx | 92 +- .../__snapshots__/Markdown.spec.tsx.snap | 30 +- .../__snapshots__/Renderer.spec.tsx.snap | 816 ++++++++++++++---- 7 files changed, 869 insertions(+), 516 deletions(-) diff --git a/package-lock.json b/package-lock.json index 54b3cb0e..c9f95de9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -26,7 +26,7 @@ "@evilmartians/lefthook": "2.1.17", "@react-native/babel-preset": "0.78.2", "@release-it/conventional-changelog": "12.0.2", - "@testing-library/react-native": "v14.0.0-alpha.1", + "@testing-library/react-native": "14.0.1", "@types/jest": "30.0.0", "@types/node": "24.19.1", "@types/react": "19.3.0", @@ -44,8 +44,8 @@ "react-native-svg": "15.15.5", "reassure": "1.6.0", "release-it": "21.1.0", - "typescript": "6.0.3", - "universal-test-renderer": "0.6.0" + "test-renderer": "1.3.0", + "typescript": "6.0.3" }, "engines": { "node": ">=18" @@ -88,10 +88,6 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/code-frame/node_modules/picocolors": { - "version": "1.1.1", - "license": "ISC" - }, "node_modules/@babel/core": { "version": "7.29.7", "license": "MIT", @@ -227,10 +223,6 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, - "node_modules/@babel/core/node_modules/picocolors": { - "version": "1.1.1", - "license": "ISC" - }, "node_modules/@babel/generator": { "version": "7.25.0", "license": "MIT", @@ -869,10 +861,6 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/helpers/node_modules/picocolors": { - "version": "1.1.1", - "license": "ISC" - }, "node_modules/@babel/parser": { "version": "7.19.3", "license": "MIT", @@ -2818,10 +2806,6 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/preset-env/node_modules/picocolors": { - "version": "1.1.1", - "license": "ISC" - }, "node_modules/@babel/preset-modules": { "version": "0.1.6-no-external-plugins", "license": "MIT", @@ -3183,10 +3167,6 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, - "node_modules/@babel/traverse/node_modules/picocolors": { - "version": "1.1.1", - "license": "ISC" - }, "node_modules/@babel/types": { "version": "7.19.3", "license": "MIT", @@ -3637,11 +3617,6 @@ "node": ">=22.12.0" } }, - "node_modules/@commitlint/format/node_modules/picocolors": { - "version": "1.1.1", - "dev": true, - "license": "ISC" - }, "node_modules/@commitlint/is-ignored": { "version": "21.2.3", "dev": true, @@ -3717,11 +3692,6 @@ "node": ">=22.12.0" } }, - "node_modules/@commitlint/load/node_modules/picocolors": { - "version": "1.1.1", - "dev": true, - "license": "ISC" - }, "node_modules/@commitlint/message": { "version": "21.2.0", "dev": true, @@ -3825,11 +3795,6 @@ "node": ">=22.12.0" } }, - "node_modules/@commitlint/types/node_modules/picocolors": { - "version": "1.1.1", - "dev": true, - "license": "ISC" - }, "node_modules/@conventional-changelog/git-client": { "version": "3.1.0", "dev": true, @@ -6372,23 +6337,25 @@ } }, "node_modules/@testing-library/react-native": { - "version": "14.0.0-alpha.1", + "version": "14.0.1", + "resolved": "https://registry.npmjs.org/@testing-library/react-native/-/react-native-14.0.1.tgz", + "integrity": "sha512-2r2e2y8SkUNRWKRXlUGqDYunB+AkbdXUPn49Bs5rpv9oxRb0K3USBVugbPbAKJjfj4w5Ba91NJ8LcQCZyopUZA==", "dev": true, "license": "MIT", "dependencies": { - "chalk": "^4.1.2", - "jest-matcher-utils": "^29.7.0", - "pretty-format": "^29.7.0", + "jest-matcher-utils": "^30.4.1", + "picocolors": "^1.1.1", + "pretty-format": "^30.4.1", "redent": "^3.0.0" }, "engines": { - "node": ">=20" + "node": "^22.13.0 || >=24" }, "peerDependencies": { "jest": ">=29.0.0", "react": ">=19.0.0", - "react-native": ">=0.77", - "universal-test-renderer": "0.6.0" + "react-native": ">=0.78", + "test-renderer": "^1.0.0" }, "peerDependenciesMeta": { "jest": { @@ -6396,47 +6363,6 @@ } } }, - "node_modules/@testing-library/react-native/node_modules/jest-diff": { - "version": "29.7.0", - "dev": true, - "license": "MIT", - "dependencies": { - "chalk": "^4.0.0", - "diff-sequences": "^29.6.3", - "jest-get-type": "^29.6.3", - "pretty-format": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@testing-library/react-native/node_modules/jest-matcher-utils": { - "version": "29.7.0", - "dev": true, - "license": "MIT", - "dependencies": { - "chalk": "^4.0.0", - "jest-diff": "^29.7.0", - "jest-get-type": "^29.6.3", - "pretty-format": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@testing-library/react-native/node_modules/pretty-format": { - "version": "29.7.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/schemas": "^29.6.3", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, "node_modules/@tootallnate/once": { "version": "2.0.1", "dev": true, @@ -6562,6 +6488,16 @@ "csstype": "^3.2.2" } }, + "node_modules/@types/react-reconciler": { + "version": "0.33.1", + "resolved": "https://registry.npmjs.org/@types/react-reconciler/-/react-reconciler-0.33.1.tgz", + "integrity": "sha512-0kF59ji2mKuHUd5wytHSpmORybMYVerJvq0K10pz9ZFoOlJ3e+w1LBjLshWpCrokeyQOioRodNbO4PH4ddvRfg==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@types/react": "*" + } + }, "node_modules/@types/stack-utils": { "version": "2.0.3", "license": "MIT" @@ -8260,10 +8196,6 @@ "version": "2.0.27", "license": "MIT" }, - "node_modules/core-js-compat/node_modules/picocolors": { - "version": "1.1.1", - "license": "ISC" - }, "node_modules/core-js-compat/node_modules/update-browserslist-db": { "version": "1.2.2", "funding": [ @@ -8903,14 +8835,6 @@ "node": ">=8" } }, - "node_modules/diff-sequences": { - "version": "29.6.3", - "dev": true, - "license": "MIT", - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, "node_modules/dom-serializer": { "version": "2.0.0", "dev": true, @@ -11744,10 +11668,6 @@ "node": ">=6.9.0" } }, - "node_modules/jscodeshift/node_modules/picocolors": { - "version": "1.0.1", - "license": "ISC" - }, "node_modules/jsdom": { "version": "20.0.3", "dev": true, @@ -13329,6 +13249,12 @@ "dev": true, "license": "MIT" }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "license": "ISC" + }, "node_modules/picomatch": { "version": "2.3.1", "license": "MIT", @@ -13934,11 +13860,6 @@ "node": ">=18" } }, - "node_modules/react-native-builder-bob/node_modules/picocolors": { - "version": "1.1.1", - "dev": true, - "license": "ISC" - }, "node_modules/react-native-builder-bob/node_modules/string-width": { "version": "7.2.0", "dev": true, @@ -14207,19 +14128,28 @@ } }, "node_modules/react-reconciler": { - "version": "0.31.0", + "version": "0.34.0", + "resolved": "https://registry.npmjs.org/react-reconciler/-/react-reconciler-0.34.0.tgz", + "integrity": "sha512-eVibvB1fc9j5Qf1KRkiM3GzRPBdjg2P6G6QV2f3P6Eb3OGMxRBhdg2rrUwjbV5JrQaJj8nOa8uajmmJA5tJWjQ==", "dev": true, "license": "MIT", "dependencies": { - "scheduler": "^0.25.0" + "scheduler": "^0.28.0" }, "engines": { "node": ">=0.10.0" }, "peerDependencies": { - "react": "^19.0.0" + "react": "^19.3.0" } }, + "node_modules/react-reconciler/node_modules/scheduler": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.28.0.tgz", + "integrity": "sha512-juorfCmIkIw8tT+p5BXSm6PJjQF/ycEYmKyzURCIt/RaZIhL+PulbQ9Yu2z1HdOJDdqDTlxA1+xKBmHXJsczAw==", + "dev": true, + "license": "MIT" + }, "node_modules/react-refresh": { "version": "0.14.2", "license": "MIT", @@ -15281,6 +15211,20 @@ "node": "*" } }, + "node_modules/test-renderer": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/test-renderer/-/test-renderer-1.3.0.tgz", + "integrity": "sha512-DXyHv7JrVmDc5dKpfVHFhJ0Evo/EFY3TqlNt8CR65ua3SCsI09K/mQDJmYUOnZz36GANYqjp0ApeRER/mOxktQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/react-reconciler": "~0.33.0", + "react-reconciler": "~0.34.0" + }, + "peerDependencies": { + "react": "^19.0.0" + } + }, "node_modules/throat": { "version": "5.0.0", "license": "MIT" @@ -15527,17 +15471,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/universal-test-renderer": { - "version": "0.6.0", - "dev": true, - "license": "MIT", - "dependencies": { - "react-reconciler": "~0.31.0" - }, - "peerDependencies": { - "react": "^19.0.0" - } - }, "node_modules/universal-user-agent": { "version": "7.0.2", "dev": true, @@ -15629,10 +15562,6 @@ "node": ">=6" } }, - "node_modules/update-browserslist-db/node_modules/picocolors": { - "version": "1.0.1", - "license": "ISC" - }, "node_modules/uri-js": { "version": "4.4.1", "dev": true, diff --git a/package.json b/package.json index c745a8eb..a66aee90 100644 --- a/package.json +++ b/package.json @@ -62,7 +62,7 @@ "@evilmartians/lefthook": "2.1.17", "@react-native/babel-preset": "0.78.2", "@release-it/conventional-changelog": "12.0.2", - "@testing-library/react-native": "v14.0.0-alpha.1", + "@testing-library/react-native": "14.0.1", "@types/jest": "30.0.0", "@types/node": "24.19.1", "@types/react": "19.3.0", @@ -80,8 +80,8 @@ "react-native-svg": "15.15.5", "reassure": "1.6.0", "release-it": "21.1.0", - "typescript": "6.0.3", - "universal-test-renderer": "0.6.0" + "test-renderer": "1.3.0", + "typescript": "6.0.3" }, "peerDependencies": { "react": ">=16.8.6", diff --git a/src/hooks/__tests__/useMarkdownWithComponents.spec.tsx b/src/hooks/__tests__/useMarkdownWithComponents.spec.tsx index 633d3ad2..7fc52075 100644 --- a/src/hooks/__tests__/useMarkdownWithComponents.spec.tsx +++ b/src/hooks/__tests__/useMarkdownWithComponents.spec.tsx @@ -32,13 +32,13 @@ const InnerRenderer = ({ value }: { value: string }) => { describe("useMarkdownWithComponents", () => { describe("without registry", () => { - it("renders regular markdown without components", () => { - render(); + it("renders regular markdown without components", async () => { + await render(); expect(screen.queryByText("Hello World")).toBeTruthy(); }); - it("removes unregistered components from output", () => { - render(); + it("removes unregistered components from output", async () => { + await render(); expect(screen.queryByText("Before")).toBeTruthy(); expect(screen.queryByText("After")).toBeTruthy(); }); @@ -61,8 +61,8 @@ describe("useMarkdownWithComponents", () => { ), }; - it("renders a self-closing component", () => { - render( + it("renders a self-closing component", async () => { + await render( { expect(screen.queryByText("Click me")).toBeTruthy(); }); - it("renders a component with children", () => { - render( + it("renders a component with children", async () => { + await render( { expect(screen.queryByText("Important info")).toBeTruthy(); }); - it("renders components mixed with markdown", () => { + it("renders components mixed with markdown", async () => { const markdown = `# Title Some text before. @@ -93,7 +93,7 @@ Some text before. Some text after.`; - render(); + await render(); expect(screen.queryByText("Title")).toBeTruthy(); expect(screen.queryByText("Some text before.")).toBeTruthy(); @@ -102,19 +102,19 @@ Some text after.`; expect(screen.queryByText("Some text after.")).toBeTruthy(); }); - it("removes components not in registry", () => { + it("removes components not in registry", async () => { const markdown = `