import AppKit import ConjureKit import Testing @testable import Conjure @Test @MainActor func codeBlocksHighlightTokensWithoutInterpretingTheirLiteralMarkdown() throws { _ = NSApplication.shared for fence in ["```", "~~~~"] { let source = "# Heading 🦊\n\(fence)py\ndef main():\n # comment\n return \"**not bold**\"\n\(fence)\nAfter\n```unknown-language\n# literal\n```" let editor = NotesTextView(frame: NSRect(x: 0, y: 0, width: 600, height: 500)) editor.setDocumentContents(NoteDocument.importMarkdown(NSAttributedString(string: source))) let storage = try #require(editor.textStorage) func attributes(_ token: String) -> [NSAttributedString.Key: Any] { storage.attributes(at: (editor.string as NSString).range(of: token).location, effectiveRange: nil) } let keyword = try #require(attributes("def")[.foregroundColor] as? NSColor) let name = try #require(attributes("main")[.foregroundColor] as? NSColor) let comment = try #require(attributes("# comment")[.foregroundColor] as? NSColor) #expect(keyword != name) #expect(comment != keyword) #expect((attributes("**not bold**")[.font] as? NSFont)?.isFixedPitch == true) #expect(attributes("**not bold**")[NoteAttributes.bold] as? Bool != true) #expect(attributes("# literal")[NoteAttributes.headingLevel] == nil) #expect(attributes("# literal")[NoteAttributes.block] as? String == "code") #expect(editor.string == "Heading 🦊\ndef main():\n # comment\n return \"**not bold**\"\nAfter\n# literal") editor.setDocumentContents(NoteDocument.importMarkdown(NSAttributedString(string: "```python\ndef main():\n pass"))) let unfinished = try #require(editor.textStorage) #expect(unfinished.attribute(.foregroundColor, at: 0, effectiveRange: nil) as? NSColor == keyword) #expect(editor.string == "def main():\n pass") } } @Test @MainActor func headingLevelsUseDescendingSizesAndCodeRemainsBodySized() throws { _ = NSApplication.shared let editor = NotesTextView(frame: NSRect(x: 0, y: 0, width: 600, height: 600)) let source = "# One\n## Two\n### Three\n#### Four\n##### Five\n###### Six\nBody\n## **Bold** and *italic*\n```text\n# Literal\n```\n####### Not a heading" editor.setDocumentContents(NoteDocument.importMarkdown(NSAttributedString(string: source))) let storage = try #require(editor.textStorage) func font(_ token: String) throws -> NSFont { try #require(storage.attribute(.font, at: (editor.string as NSString).range(of: token).location, effectiveRange: nil) as? NSFont) } let sizes = try ["One", "Two", "Three", "Four", "Five", "Six"].map { try font($0).pointSize } for (larger, smaller) in zip(sizes, sizes.dropFirst()) { #expect(larger > smaller) } #expect(try font("Six").pointSize >= font("Body").pointSize) #expect(try font("Bold").pointSize == font("Two").pointSize) #expect(try font("italic").pointSize == font("Two").pointSize) #expect(try font("Literal").pointSize == font("Body").pointSize) #expect(try font("Not a heading").pointSize == font("Body").pointSize) #expect(try font("Three").isFixedPitch) let three = (editor.string as NSString).range(of: "Three") editor.setSelectedRange(three) for _ in 0..<4 { editor.format(0) } #expect(editor.string.contains("Three")) #expect(try font("Three").pointSize == font("Body").pointSize) }