// // GeminiFormatTests.swift // GeminiFormatTests // // Created by Shadowfacts on 7/12/20. // import XCTest @testable import GeminiFormat class GeminiFormatTests: XCTestCase { func assertParseLines(text: String, lines expected: [Document.Line], message: String, file: StaticString = #filePath, line: UInt = #line) { let doc = GeminiParser.parse(text: text, baseURL: URL(string: "gemini://example.com")!) XCTAssertEqual(doc.lines, expected, message, file: file, line: line) } func testParsePlainLines() { assertParseLines(text: "test", lines: [.text("test")], message: "parse a plain text line") assertParseLines(text: "one\ntwo", lines: [ .text("one"), .text("two") ], message: "parse multiple, newline delmited plain lines") assertParseLines(text: "one\r\ntwo", lines: [ .text("one"), .text("two") ], message: "parse multiple, CRLF delmited plain lines") } func testParseLinkLines() { assertParseLines(text: "=> gemini://blah.com", lines: [ .link(URL(string: "gemini://blah.com")!, text: nil) ], message: "parse a bare link line") assertParseLines(text: "=> gemini://blah.com:1234/foo/bar?baz", lines: [ .link(URL(string: "gemini://blah.com:1234/foo/bar?baz")!, text: nil) ], message: "parse a more complex bare link line") assertParseLines(text: "=> gemini://blah.com \t Link to example", lines: [ .link(URL(string: "gemini://blah.com")!, text: "Link to example") ], message: "parse a simple link line with associated text") assertParseLines(text: "=> gemini://blah.com/foo Link to foo", lines: [ .link(URL(string: "gemini://blah.com/foo")!, text: "Link to foo") ], message: "parse a more complex link line with associated text") assertParseLines(text: "=> https://example.com", lines: [ .link(URL(string: "https://example.com")!, text: nil) ], message: "parse a link with a different protocol") assertParseLines(text: "=> /foo/bar/baz", lines: [ .link(URL(string: "gemini://example.com/foo/bar/baz")!, text: nil) ], message: "resolve a relative path link") assertParseLines(text: "=>gemini://blah.com", lines: [ .link(URL(string: "gemini://blah.com")!, text: nil) ], message: "parse link without whitespace after =>") } func testParseHeadingLines() { assertParseLines(text: "# test", lines: [ .heading("test", level: .h1) ], message: "level 1 heading") assertParseLines(text: "#test", lines: [ .heading("test", level: .h1) ], message: "level 1 heading without whitespace") assertParseLines(text: "#test\n## two\r\n###three", lines: [ .heading("test", level: .h1), .heading("two", level: .h2), .heading("three", level: .h3) ], message: "multiples headings with and without whitespace") } func testParseListItemLines() { assertParseLines(text: "* test list item", lines: [ .unorderedListItem("test list item") ], message: "parse simple list item") assertParseLines(text: "*test", lines: [ .text("*test") ], message: "don't parse list item without space after asterisk") assertParseLines(text: "* one\n* two\n*three", lines: [ .unorderedListItem("one"), .unorderedListItem("two"), .text("*three") ], message: "parse multiple list items") } func testParseQuoteLines() { assertParseLines(text: "> quote", lines: [ .quote("quote") ], message: "parse quote line") assertParseLines(text: ">quote", lines: [ .quote("quote") ], message: "parse quote line without space after >") assertParseLines(text: ">one\n> two\n>three", lines: [ .quote("one"), .quote("two"), .quote("three") ], message: "parse multiple quote lines") } func testParsePreformattedLines() { assertParseLines(text: "```\nsomething\n```", lines: [ .preformattedText("something", alt: nil) ], message: "parse simple preformatted line") assertParseLines(text: "```alt\nsomething\n```", lines: [ .preformattedText("something", alt: "alt") ], message: "parse simple preformatted line with alt") assertParseLines(text: "```alt\nsomething\n```other", lines: [ .preformattedText("something", alt: "alt") ], message: "ignore extra text after closing ```") assertParseLines(text: "```\n# not a heading\n* not a list item\n>not a quote\n=> /link not a link\n```", lines: [ .preformattedText("# not a heading", alt: nil), .preformattedText("* not a list item", alt: nil), .preformattedText(">not a quote", alt: nil), .preformattedText("=> /link not a link", alt: nil), ], message: "don't parse special lines inside preformatted") } }