oficina / docs Public

Clone
git clone https://amadan.net/oficina/docs

Plain git — no account needed to clone.

Download

Download this file

1import Foundation
2import XCTest
3@testable import DocsKit
4
5final class DocumentListCommandTests: XCTestCase {
6 @MainActor func testSelectedListConversionAndLiftSurviveReplacedNodeIDs() async throws {
7 let replica = CRDTReplica(guid: "native-list-command-test")
8 _ = try await replica.open(update: Data())
9 _ = try await replica.command(["op": .string("insert_element"), "at": .number(0), "type": .string("paragraph")])
10 let paste = #"{"op":"display_paste","at":0,"length":0,"blocks":[{"type":"bullet_list","children":[{"type":"list_item","children":[{"type":"paragraph","children":[{"type":"text","runs":[{"insert":"first"}]}]}]},{"type":"list_item","children":[{"type":"paragraph","children":[{"type":"text","runs":[{"insert":"second"}]}]}]},{"type":"list_item","children":[{"type":"paragraph","children":[{"type":"text","runs":[{"insert":"third"}]}]}]}]}]}"#
11 _ = try await replica.command(JSONDecoder().decode([String: JSONValue].self, from: Data(paste.utf8)))
12 for type in ["ordered_list", "ordered_list"] {
13 let source = try await replica.presentation(source: 0, selection: NSRange(location: 0, length: 0))
14 let (generation, projection, _) = try XCTUnwrap(source)
15 let paths = pathsToParagraphs(projection.children).filter { $0.contains { $0.type == "list_item" } }
16 let commands = DocumentCommands.listCommands(type: type, paths: paths)
17 _ = try await replica.command(["op": .string("batch"), "generation": .number(Double(generation)), "commands": .array(commands.map(JSONValue.object))])
18 await replica.retainGenerations([])
19 }
20 let final = try await replica.projection()
21 XCTAssertEqual(final.children.map(\.plainText).filter { !$0.isEmpty }, ["first", "second", "third"])
22 XCTAssertFalse(final.children.contains { ["bullet_list", "ordered_list"].contains($0.type) })
23 await replica.close()
24 }
25
26 private func pathsToParagraphs(_ nodes: [CRDTNode], ancestors: [CRDTNode] = []) -> [[CRDTNode]] {
27 nodes.flatMap { node in
28 let path = ancestors + [node]
29 return node.type == "paragraph" ? [path] : pathsToParagraphs(node.children ?? [], ancestors: path)
30 }
31 }
32}
33