HTMLStreamer/Tests/HTMLStreamerTests/TextConverterTests.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>"), "")
}
}