import Foundation import Testing @testable import OrgCore /// Keys typed with `electric-pair-mode` in an Org buffer, against Emacs. struct ElectricPairTests { struct Typing { let text: String let point: Int var mark: Int? let keys: [String] } static let cases: [Typing] = [ Typing(text: "", point: 0, keys: ["("]), Typing(text: "foo", point: 3, keys: ["(", "x", ")"]), Typing(text: ")", point: 0, keys: ["("]), Typing(text: "(", point: 1, keys: [")"]), Typing(text: "", point: 0, keys: ["\"", "a", "\""]), Typing(text: "a \"b", point: 4, keys: ["\""]), Typing(text: "(foo )", point: 4, keys: [")"]), Typing(text: "x", point: 1, keys: ["<", ">"]), Typing(text: "", point: 0, keys: ["[", "[", "a", "]", "]"]), Typing(text: "{}", point: 1, keys: ["}"]), Typing(text: "(())", point: 2, keys: [")", ")"]), Typing(text: "[(])", point: 2, keys: [")"]), Typing(text: "()", point: 1, keys: ["DEL"]), Typing(text: "(x)", point: 2, keys: ["DEL"]), Typing(text: "\"\"", point: 1, keys: ["DEL"]), Typing(text: "()", point: 1, keys: ["RET"]), Typing(text: "word", point: 4, mark: 0, keys: ["("]), Typing(text: "word", point: 4, mark: 0, keys: [")"]), Typing(text: "word", point: 4, mark: 0, keys: ["\""]), Typing(text: "say ", point: 4, keys: ["“", "hi", "”"]), Typing(text: "\"a b\"", point: 2, keys: ["("]), Typing(text: "\"a b\"", point: 2, keys: ["<"]), Typing(text: "* Heading\nit", point: 12, keys: ["'", "s"]), Typing(text: "a (b", point: 4, keys: [")"]), Typing(text: "a b)", point: 2, keys: ["("]), Typing(text: "(a\n )", point: 2, keys: [")"]), Typing(text: "word", point: 0, keys: ["\""]), Typing(text: "say \"x\" and ", point: 12, keys: ["\"", "y", "\""]), Typing(text: "- item (see [[x]]", point: 17, keys: [")"]), Typing(text: "<2026-10-06 Tue>", point: 16, keys: ["DEL"]), Typing(text: "f(\"(\")", point: 4, keys: [")"]), ] /// The keys typed into our side: `ElectricPairKey` where it applies, otherwise as the /// text view types them. static func ours(_ c: Typing) -> (text: String, point: Int) { var text = c.text var selection = (c.mark ?? c.point).. c.point { selection = c.point.. $1.range.lowerBound }) { text = edit.apply(to: text) } selection = result.selection!.first! continue } let ns = text as NSString let caret = selection.upperBound switch key { case "DEL": text = ns.replacingCharacters(in: NSRange(location: caret - 1, length: 1), with: "") selection = caret - 1..