Skip to content

comparison forest#27660

Open
daesunp wants to merge 1 commit into
microsoft:mainfrom
daesunp:comparison-forest
Open

comparison forest#27660
daesunp wants to merge 1 commit into
microsoft:mainfrom
daesunp:comparison-forest

Conversation

@daesunp

@daesunp daesunp commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Description

Adds ComparisonForest which wraps a main forest and a reference forest. Every delta is applied to both forests, and their contents are asserted to be equal after each delta.

ForestTypeExpensiveDebug now uses ComparisonForest, and the top-level, move, and undoRedo fuzz tests also run it again it.

@github-actions

github-actions Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Hi! Thank you for opening this PR. Want me to review it?

Based on the diff (448 lines, 12 files), I've queued these reviewers:

  • Correctness — logic errors, race conditions, lifecycle issues
  • Security — vulnerabilities, secret exposure, injection
  • API Compatibility — breaking changes, release tags, type design
  • Performance — algorithmic regressions, memory leaks
  • Testing — coverage gaps, hollow tests

How this works

  • Adjust the reviewer set by ticking/unticking boxes above. Reviewer toggles alone don't trigger anything.

  • Tick Start review below to dispatch the review fleet.

  • After review finishes, tick Start review again to request another run — it auto-resets after each dispatch.

  • This comment updates as new commits land; your reviewer selections are preserved.

  • Start review

@daesunp daesunp marked this pull request as ready for review July 9, 2026 20:18
@daesunp daesunp requested a review from a team as a code owner July 9, 2026 20:18
Copilot AI review requested due to automatic review settings July 9, 2026 20:18

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot reviewed 12 out of 12 changed files in this pull request and generated no comments.

@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Bundle size comparison

Base commit: 74474fd81f41b17db16a59e1983b19ebd2342740
Head commit: 9755f885371b537e8b1772d65e2385e75bd95a24

⚠️ Comparison unavailable.

The PR's CI build failed — fix the build and the comment will update once the next run succeeds.

const reference = this.reference;
const mainVisitor = main.acquireVisitor();
const referenceVisitor = reference.acquireVisitor();
const visitor: DeltaVisitor = {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Can you implement this using our existing combineVisitors(visitors: readonly CombinableVisitor[]): CombinedVisitor util?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

maybe combine those two visitors with a third that just has the assertForestsEqual on free?

@@ -0,0 +1,258 @@
/*!
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

this file should be in our test code not in the production code, and should use existing tree comparison utils (I think we have an assertTreeEqual or some exiting way to compare forests) it can use.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actually, I guess hooking thus up via a exported Forest type (expensive debug) means this stays out of the bundle for people who don't use it. Maybe this is fine? That does leave us without access to our nice tree comparison utilities with their existing logic for making nice errors.

Maybe moving those into here and reusing them would be a better solution? I would like to avoid having an extra copy of tree compare with nice human facing error message logic.

* This is implemented iteratively (using an explicit work stack rather than recursion) so that comparing
* deeply nested trees does not risk exhausting the call stack.
*/
function deepEqual(a: unknown, b: unknown): boolean {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Avoid trying to deep compare "unknown". Its always going to be problematic (cycles, identify of functions etc) and thus only work for more specific cases, which we should simply describe using the types.

const mainContent = detachedFieldsContent(main);
const referenceContent = detachedFieldsContent(reference);
if (!deepEqual(mainContent, referenceContent)) {
fail(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

this is invalid, and CI should detect it. You cannot use fail with a non constant string for the first parameter.

You can however use the API I added where you can have a debug build only second parameter which computes a nicer message

}

public allocateCursor(source?: string): ITreeSubscriptionCursor {
return this.main.allocateCursor(source);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I imagine it would be a bit of a pain to implement, but this could validate the cursors match as well, by pairing together both options. Lets not do that yet, but note it as possible:

Suggested change
return this.main.allocateCursor(source);
// Currently we just use the cursor from "main", but we could use "reference" or a custom cursor ensuring both match in behavior.
// TODO: Add a custom combined cursor type which validates two cursors match, and use it here.
return this.main.allocateCursor(source);

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.

3 participants