ReviewOS

also looking at this

craft-native/craft

fix(native): retain keyed controls and correct map and tab chrome

#368
Merged chris wants to merge codex/native-repeated-selector-identity into main
32 files +449 -100

Review threads live on the whole diff, not on one commit, so none are shown here - a thread's line means something in the branch's final form, and painting it into an intermediate step would put it on code it is not about.

packages/android/fixtures/native-navigation/NativeMutationTest.ktmodified+24-0
Changes to packages/android/fixtures/native-navigation/NativeMutationTest.kt
@@ -53,6 +53,30 @@ class NativeMutationTest {
5353 assertNull(removed.document)
5454 }
5555
56 @Test
57 fun preservesAuthoredKeysAcrossImportCreationUpdatesAndMoves() {
58 val document = CraftNativeMutationDocument()
59 document.replace(JSONObject("""
60 {"id":"root","type":"View","key":"root-key","children":[
61 {"id":"existing","type":"TextInput","key":"draft-key","props":{"value":"draft"}}
62 ]}
63 """.trimIndent()))
64 assertEquals("draft-key", document.node("existing")?.getString("key"))
65 val result = document.apply(batch(1, """
66 [
67 {"op":"createNode","id":"created","node":{"type":"View","key":"created-key"}},
68 {"op":"insertChild","parentId":"root","childId":"created","index":1},
69 {"op":"updateNode","id":"existing","patch":{"props":{"value":"edited"}}},
70 {"op":"moveChild","parentId":"root","childId":"created","index":0}
71 ]
72 """.trimIndent()))
73 val rendered = requireNotNull(result.document)
74 assertEquals("root-key", rendered.getString("key"))
75 assertEquals("created-key", rendered.getJSONArray("children").getJSONObject(0).getString("key"))
76 assertEquals("draft-key", rendered.getJSONArray("children").getJSONObject(1).getString("key"))
77 assertEquals("edited", document.node("existing")?.getJSONObject("props")?.getString("value"))
78 }
79
5680 @Test
5781 fun rejectsWholeBatchWithDeterministicFailure() {
5882 val document = CraftNativeMutationDocument()
packages/ios/fixtures/native-screen/NativeRenderUnitTests.swiftmodified+22-0
Changes to packages/ios/fixtures/native-screen/NativeRenderUnitTests.swift
@@ -822,6 +822,28 @@ final class NativeRenderUnitTests: XCTestCase {
822822 XCTAssertTrue(scroll === find(UIScrollView.self, key: "scroll", below: controller.view))
823823 }
824824
825 func testMutationPreservesAuthoredKeysAcrossImportCreationUpdatesAndMoves() throws {
826 let document = CraftNativeMutationDocument()
827 document.replace(with: [
828 "id": "root", "type": "View", "key": "root-key", "children": [
829 ["id": "existing", "type": "TextInput", "key": "draft-key", "props": ["value": "draft"]],
830 ],
831 ])
832 XCTAssertEqual(document.node("existing")?["key"] as? String, "draft-key")
833 let result = try document.apply(batch(1, [
834 ["op": "createNode", "id": "created", "node": ["type": "View", "key": "created-key"]],
835 ["op": "insertChild", "parentId": "root", "childId": "created", "index": 1],
836 ["op": "updateNode", "id": "existing", "patch": ["props": ["value": "edited"]]],
837 ["op": "moveChild", "parentId": "root", "childId": "created", "index": 0],
838 ]))
839 let rendered = try XCTUnwrap(result.document)
840 let children = try XCTUnwrap(rendered["children"] as? [[String: Any]])
841 XCTAssertEqual(rendered["key"] as? String, "root-key")
842 XCTAssertEqual(children[0]["key"] as? String, "created-key")
843 XCTAssertEqual(children[1]["key"] as? String, "draft-key")
844 XCTAssertEqual((document.node("existing")?["props"] as? [String: Any])?["value"] as? String, "edited")
845 }
846
825847 func testEveryContainerTheRendererDrawsTakesChildrenAndALeafDoesNot() throws {
826848 for type in CraftNativeMutationDocument.containerTypes.sorted() + ["svg", "pressable"] {
827849 let document = CraftNativeMutationDocument()