Tests/OrgCoreTests/TableElTests.swift
51 lines · 2724 bytes
5 symbols in this file
1import Foundation
2import Testing
3@testable import OrgCore
4
5/// table.el tables against ox-html: the rows, each cell's spans and text.
6struct TableElTests {
7 static let tables = [
8 "+-----+-----+\n| a | b |\n+-----+-----+\n| c d |\n| more |\n+-----+-----+\n| e | f |\n+-----+-----+\n",
9 "+---+---+\n| a | b |\n| +---+\n| | c |\n+---+---+\n",
10 " +----+---+----+\n | x | y | z |\n +----+---+----+\n | wide row |\n +----+--------+\n | p | q & <r>|\n +----+--------+\n",
11 "+---+\n| 1 |\n| 2 |\n+---+\n",
12 ]
13
14 static func describe(_ cells: [TableEl.Cell]) -> [String] {
15 Dictionary(grouping: cells, by: \.row).keys.sorted().map { row in
16 cells.filter { $0.row == row }.map { "\($0.colspan)x\($0.rowspan):" + $0.lines.reversed().drop { $0.isEmpty }.reversed().joined(separator: "/") }.joined(separator: " ")
17 }
18 }
19
20 /// The rows of ox-html's table, in the same terms.
21 static func describe(html: String) -> [String] {
22 html.components(separatedBy: "<tr>").dropFirst().map { row in
23 row.components(separatedBy: "<td").dropFirst().map { cell -> String in
24 let colspan = cell.firstMatch(of: /colspan="([0-9]+)"/).map { String($0.1) } ?? "1"
25 let rowspan = cell.firstMatch(of: /rowspan="([0-9]+)"/).map { String($0.1) } ?? "1"
26 let body = cell[cell.firstIndex(of: ">")!...].dropFirst().components(separatedBy: "</td>")[0]
27 let lines = body.components(separatedBy: "<br />").map {
28 $0.replacingOccurrences(of: " ", with: " ").replacingOccurrences(of: "&", with: "&")
29 .replacingOccurrences(of: "<", with: "<").replacingOccurrences(of: ">", with: ">")
30 .trimmingCharacters(in: .whitespacesAndNewlines)
31 }
32 return "\(colspan)x\(rowspan):" + lines.reversed().drop { $0.isEmpty }.reversed().joined(separator: "/")
33 }.joined(separator: " ")
34 }
35 }
36
37 @Test(.enabled(if: ProcessInfo.processInfo.environment["ORGSTAR_SKIP_ORACLE"] == nil))
38 func cellsMatchOxHtml() throws {
39 for table in Self.tables {
40 let html = try EmacsOracle.evaluate(table, "(progn (require 'ox-html) (list (org-export-as 'html nil nil t)))")[0]
41 let ours = try #require(TableEl.cells(table))
42 #expect(Self.describe(ours) == Self.describe(html: html), "\(table)\n\(html)")
43 }
44 }
45
46 @Test func exportsATable() {
47 let page = HTMLExport.page(Self.tables[0], fallbackTitle: "t")
48 #expect(page.contains("<td colspan=\"2\">c d<br>more</td>"))
49 #expect(!page.contains("<pre"))
50 }
51}