91 lines
3.7 KiB
Swift
91 lines
3.7 KiB
Swift
//
|
|
// TextConverterTests.swift
|
|
//
|
|
//
|
|
// Created by Shadowfacts on 12/22/23.
|
|
//
|
|
|
|
import XCTest
|
|
@testable import HTMLStreamer
|
|
|
|
final class TextConverterTests: XCTestCase {
|
|
|
|
private func convert(_ html: String, configuration: TextConverterConfiguration = .init()) -> String {
|
|
convert(html, configuration: configuration, callbacks: DefaultCallbacks.self)
|
|
}
|
|
|
|
private func convert<Callbacks: HTMLConversionCallbacks>(_ html: String, configuration: TextConverterConfiguration = .init(), callbacks _: Callbacks.Type = Callbacks.self) -> String {
|
|
var converter = TextConverter<Callbacks>(configuration: configuration)
|
|
return converter.convert(html: html)
|
|
}
|
|
|
|
func testConvertBR() {
|
|
XCTAssertEqual(convert("a<br>b"), "a\nb")
|
|
XCTAssertEqual(convert("a<br />b"), "a\nb")
|
|
}
|
|
|
|
func testConvertA() {
|
|
XCTAssertEqual(convert("<a href='https://example.com'>link</a>"), "link")
|
|
}
|
|
|
|
func testIncorrectNesting() {
|
|
XCTAssertEqual(convert("<strong>bold <em>both</strong> italic</em>"), "bold both italic")
|
|
}
|
|
|
|
func testTextAfterBlockElement() {
|
|
XCTAssertEqual(convert("<blockquote>wee</blockquote>after"), "wee\n\nafter")
|
|
XCTAssertEqual(convert("<blockquote>wee</blockquote>after", configuration: .init(insertNewlines: false)), "wee after")
|
|
}
|
|
|
|
func testMultipleBlockElements() {
|
|
XCTAssertEqual(convert("<blockquote>a</blockquote><blockquote>b</blockquote>"), "a\n\nb")
|
|
XCTAssertEqual(convert("<blockquote>a</blockquote><blockquote>b</blockquote>", configuration: .init(insertNewlines: false)), "a b")
|
|
}
|
|
|
|
func testElementActionCallback() {
|
|
struct Callbacks: HTMLConversionCallbacks {
|
|
static func elementAction(name: String, attributes: [Attribute]) -> ElementAction {
|
|
let clazz = attributes.attributeValue(for: "class")
|
|
if clazz == "skip" {
|
|
return .skip
|
|
} else if clazz == "replace" {
|
|
return .replace("…")
|
|
} else if clazz == "append" {
|
|
return .append("…")
|
|
} else {
|
|
return .default
|
|
}
|
|
}
|
|
}
|
|
let skipped = convert("<span class='skip'>test</span>", callbacks: Callbacks.self)
|
|
XCTAssertEqual(skipped, "")
|
|
let skipNested = convert("<span class='skip'><b>test</b></span>", callbacks: Callbacks.self)
|
|
XCTAssertEqual(skipNested, "")
|
|
let replaced = convert("<span class='replace'>test</span>", callbacks: Callbacks.self)
|
|
XCTAssertEqual(replaced, "…")
|
|
let appended = convert("<span class='append'>test</span>", callbacks: Callbacks.self)
|
|
XCTAssertEqual(appended, "test…")
|
|
let appended2 = convert("<span class='append'>test <span>blah</span></span>", callbacks: Callbacks.self)
|
|
XCTAssertEqual(appended2, "test blah…")
|
|
|
|
}
|
|
|
|
func testEmptyBlockElements() {
|
|
XCTAssertEqual(convert("<p></p><blockquote><span>inside<br>quote</span></blockquote><span>after</span><p></p>"), "inside\nquote\n\nafter")
|
|
}
|
|
|
|
func testSkipElementActionFollowingUnfinishedRun() {
|
|
struct Callbacks: HTMLConversionCallbacks {
|
|
static func elementAction(name: String, attributes: [Attribute]) -> ElementAction {
|
|
attributes.attributeValue(for: "class") == "invisible" ? .skip : .default
|
|
}
|
|
}
|
|
XCTAssertEqual(convert(#"<a href="https://example.com"><span class="invisible">https://</span><span>example.com</span><span class="invisible"></span></a>"#, callbacks: Callbacks.self), "example.com")
|
|
}
|
|
|
|
func testMalformedOnlyClosingTag() {
|
|
XCTAssertEqual(convert("</span>"), "")
|
|
}
|
|
|
|
}
|