import Foundation import XCTest @testable import DocsKit final class DocumentWordCountsTests: XCTestCase { @MainActor func testSelectedWordsIgnoreInlineHardBreakAndImage() throws { let data = Data(#"{"children":[{"id":"p","type":"paragraph","children":[{"id":"a","type":"text","runs":[{"insert":"before"}]},{"id":"br","type":"hard_break"},{"id":"b","type":"text","runs":[{"insert":"middle"}]},{"id":"im","type":"image","attrs":{"alt":"excluded"}},{"id":"c","type":"text","runs":[{"insert":"after"}]}]}],"canUndo":false,"canRedo":false}"#.utf8) let projection = try JSONDecoder().decode(CRDTProjection.self, from: data) let content = NativeTextProjection.render(projection) let counts = DocumentWordCounts(projection: projection, content: content, selection: NSRange(location: 0, length: content.length)) XCTAssertEqual(counts.words, 1) XCTAssertEqual(counts.selectedWords, counts.words) } func testUnicodeWordsAreNotWhitespaceChunks() { XCTAssertEqual(DocumentWordCounts.countWords("Hello,world!"), 2) XCTAssertGreaterThan(DocumentWordCounts.countWords("私は日本語を話します"), 1) XCTAssertEqual(DocumentWordCounts.countWords(" — … 😀"), 0) } @MainActor func testDocumentSemanticsAndSelectedText() throws { let data = Data(#"{"children":[{"id":"p1","type":"paragraph","children":[{"id":"t1","type":"text","runs":[{"insert":"Hi 😀"}]},{"id":"im","type":"image","attrs":{"alt":"never count image alt"}}]},{"id":"list","type":"bullet_list","children":[{"id":"li","type":"list_item","children":[{"id":"p2","type":"paragraph","children":[{"id":"t2","type":"text","runs":[{"insert":"two words"}]}]}]}]},{"id":"rule","type":"horizontal_rule"}],"canUndo":false,"canRedo":false}"#.utf8) let projection = try JSONDecoder().decode(CRDTProjection.self, from: data) let content = NativeTextProjection.render(projection) let selected = (content.string as NSString).range(of: "two words") let counts = DocumentWordCounts(projection: projection, content: content, selection: selected) XCTAssertEqual(counts.words, 3) // Each visited block separates text, as in the web model walker. XCTAssertEqual(counts.characters, "Hi 😀 two words ".utf16.count) XCTAssertEqual(counts.charactersNoSpaces, "Hi😀twowords".utf16.count) XCTAssertEqual(counts.paragraphs, 2) XCTAssertEqual(counts.selectedWords, 2) XCTAssertNil(DocumentWordCounts(projection: projection, content: content, selection: NSRange(location: 0, length: 0)).selectedWords) } }