Files
orca/mobile/src/worktree/structural-equality.test.ts
T
Jinwoo Hong 0c42285eb2 perf(mobile): skip re-rendering unchanged worktree rows (#28058)
* perf(mobile): skip re-rendering unchanged worktree rows

Rows reach the host list freshly parsed and copied on every changed
worktree.ps poll, so the row memo never skipped and every mounted row
re-rendered each poll. The row memo now compares the item by value with
the catalog's areWorktreesEqual, extended to every Worktree and agent row
field, and every other prop by identity.

Claude-Session: https://claude.ai/code/session_01JNnE9qzUZMMnqpZWCqM3nb

* refactor(mobile): compare worktree rows by structural equality

The hand-written Worktree field list needed a completeness guard that no
compiler checks, since mobile test files sit outside tsc. A generic
structural equality covers every field by construction, so a new field
can never be skipped and freeze a row. Rows memo on it directly: the item
and repo icon compare by value, callbacks and `now` by identity.

Claude-Session: https://claude.ai/code/session_01JNnE9qzUZMMnqpZWCqM3nb
2026-10-12 20:54:20 -04:00

41 lines
1.6 KiB
TypeScript

import { describe, expect, it } from 'vitest'
import { areStructurallyEqual } from './structural-equality'
describe('areStructurallyEqual', () => {
it('equates value-equal nested objects and arrays', () => {
const value = () => ({ id: 'a', agents: [{ state: 'working', mainAgent: { stopping: true } }] })
expect(areStructurallyEqual(value(), value())).toBe(true)
expect(areStructurallyEqual([1, [2, { x: null }]], [1, [2, { x: null }]])).toBe(true)
})
it('detects a changed nested value', () => {
expect(
areStructurallyEqual({ agents: [{ state: 'working' }] }, { agents: [{ state: 'done' }] })
).toBe(false)
expect(areStructurallyEqual([1, 2], [1, 2, 3])).toBe(false)
})
it('counts keys, so an added or removed key is a change even when undefined', () => {
expect(areStructurallyEqual({ a: 1 }, { a: 1, b: 2 })).toBe(false)
expect(areStructurallyEqual({ a: 1, b: undefined }, { a: 1 })).toBe(false)
expect(areStructurallyEqual({ a: 1 }, { b: 1 })).toBe(false)
})
it('compares functions by identity', () => {
const press = () => {}
expect(areStructurallyEqual({ press }, { press })).toBe(true)
expect(areStructurallyEqual({ press }, { press: () => {} })).toBe(false)
})
it('does not equate an array with an object of the same entries', () => {
expect(areStructurallyEqual(['a'], { 0: 'a' })).toBe(false)
expect(areStructurallyEqual([], {})).toBe(false)
})
it('compares primitives with Object.is', () => {
expect(areStructurallyEqual(Number.NaN, Number.NaN)).toBe(true)
expect(areStructurallyEqual(null, undefined)).toBe(false)
expect(areStructurallyEqual(0, '0')).toBe(false)
})
})