Skip to content

Conversation

@remorses
Copy link
Contributor

@remorses remorses commented Oct 9, 2025

Added support for passing a custom renderer in React render and make it wait until React commits

I added a ready field to the TestRenderer to be able to await the React commit. Because React renders asynchronously

@remorses remorses marked this pull request as ready for review October 9, 2025 16:33
@remorses remorses requested review from Adictya and msmps as code owners October 9, 2025 16:33
Copilot AI review requested due to automatic review settings October 9, 2025 16:33
@remorses remorses changed the title Add support for testing react components Add support for testing React components Oct 9, 2025
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR adds support for testing React components by enabling the use of a custom TestRenderer with the existing render function and implementing proper await mechanisms for React's asynchronous rendering. The changes allow tests to wait for React commits to complete before assertions.

Key changes:

  • Modified the render function to accept either a CliRendererConfig or CliRenderer instance
  • Added callback support to the reconciler to notify when rendering is complete
  • Extended TestRenderer with ready Promise for awaiting render completion

Reviewed Changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
packages/react/src/reconciler/renderer.ts Modified render function to accept TestRenderer and added Promise-based completion handling
packages/react/src/reconciler/renderer.test.tsx Added comprehensive test suite demonstrating React component testing with state updates
packages/react/src/reconciler/reconciler.ts Added optional callback parameter to _render function
packages/react/src/reconciler/host-config.ts Added TestRenderer ready Promise management in resetAfterCommit
packages/core/src/testing/test-renderer.ts Extended TestRenderer interface and implementation with ready Promise support

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

Comment on lines +24 to +25
if ("resolveReady" in renderer && "ready" in renderer) {
const testRenderer = renderer as TestRenderer
Copy link

Copilot AI Oct 9, 2025

Choose a reason for hiding this comment

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

The type checking using 'in' operator followed by type assertion is fragile. Consider using a proper type guard function or checking if renderer is an instance of TestRenderer.

Copilot uses AI. Check for mistakes.
Comment on lines +86 to +87
if ("resolveReady" in containerInfo.ctx && "ready" in containerInfo.ctx) {
const testRenderer = containerInfo.ctx as TestRenderer
Copy link

Copilot AI Oct 9, 2025

Choose a reason for hiding this comment

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

Duplicate type checking pattern from renderer.ts. This logic should be extracted into a reusable type guard function to avoid code duplication.

Copilot uses AI. Check for mistakes.

const renderer = new CliRenderer(ziglib, rendererPtr, stdin, stdout, width, height, config)

const renderer = new CliRenderer(ziglib, rendererPtr, stdin, stdout, width, height, config) as TestRenderer
Copy link

Copilot AI Oct 9, 2025

Choose a reason for hiding this comment

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

Type assertion 'as TestRenderer' is unsafe. The CliRenderer instance doesn't actually have the ready and resolveReady properties at this point. Consider properly extending the class or using Object.assign to add the properties.

Suggested change
const renderer = new CliRenderer(ziglib, rendererPtr, stdin, stdout, width, height, config) as TestRenderer
const renderer = Object.assign(
new CliRenderer(ziglib, rendererPtr, stdin, stdout, width, height, config),
{ ready: undefined, resolveReady: undefined }
) as TestRenderer

Copilot uses AI. Check for mistakes.
@msmps
Copy link
Collaborator

msmps commented Oct 9, 2025

i'm not sure on this one... i had started looking into changing the api for this previously but didn't finish it! i was leaning towards exposing a createRoot method that takes a renderer to align with standards.

Something like:

import { createCliRenderer } from "@opentui/core";
import { createRoot } from "@opentui/react";

const renderer = await createCliRenderer(<config>);
createRoot(renderer).render(<App />);

@remorses remorses marked this pull request as draft October 9, 2025 17:43
@remorses
Copy link
Contributor Author

remorses commented Oct 9, 2025

That makes sense. I also have some issues creating the promise for ready in a way that does not create issues with Solid

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.

2 participants