2024-04-03 06:43:06 +02:00
|
|
|
//
|
|
|
|
// EntityDecodingTests.swift
|
|
|
|
// RSParserTests
|
|
|
|
//
|
|
|
|
// Created by Brent Simmons on 12/30/17.
|
|
|
|
// Copyright © 2017 Ranchero Software, LLC. All rights reserved.
|
|
|
|
//
|
|
|
|
|
|
|
|
import XCTest
|
2024-09-24 23:45:53 +02:00
|
|
|
import Parser
|
2024-04-03 06:43:06 +02:00
|
|
|
|
2024-09-24 06:39:00 +02:00
|
|
|
final class EntityDecodingTests: XCTestCase {
|
2024-09-17 06:57:05 +02:00
|
|
|
|
|
|
|
func test39Decoding() {
|
|
|
|
|
|
|
|
// Bug found by Manton Reece — the ' entity was not getting decoded by NetNewsWire in JSON Feeds from micro.blog.
|
|
|
|
|
|
|
|
let s = "These are the times that try men's souls."
|
2024-09-29 07:14:51 +02:00
|
|
|
let decoded = decodedString(s)
|
2024-09-17 06:57:05 +02:00
|
|
|
|
|
|
|
XCTAssertEqual(decoded, "These are the times that try men's souls.")
|
|
|
|
}
|
|
|
|
|
2024-09-17 07:07:31 +02:00
|
|
|
func testEntityAtBeginning() {
|
|
|
|
|
|
|
|
let s = "'leading single quote"
|
2024-09-29 07:14:51 +02:00
|
|
|
let decoded = decodedString(s)
|
2024-09-17 07:07:31 +02:00
|
|
|
|
|
|
|
XCTAssertEqual(decoded, "'leading single quote")
|
|
|
|
}
|
|
|
|
|
|
|
|
func testEntityAtEnd() {
|
|
|
|
|
|
|
|
let s = "trailing single quote'"
|
2024-09-29 07:14:51 +02:00
|
|
|
let decoded = decodedString(s)
|
2024-09-17 07:07:31 +02:00
|
|
|
|
|
|
|
XCTAssertEqual(decoded, "trailing single quote'")
|
|
|
|
}
|
|
|
|
|
|
|
|
func testEntityInMiddle() {
|
|
|
|
|
|
|
|
let s = "entity ç in middle"
|
2024-09-29 07:14:51 +02:00
|
|
|
let decoded = decodedString(s)
|
2024-09-17 07:07:31 +02:00
|
|
|
|
|
|
|
XCTAssertEqual(decoded, "entity ç in middle")
|
|
|
|
}
|
|
|
|
|
|
|
|
func testMultipleEntitiesInARow() {
|
|
|
|
|
|
|
|
let s = "çèmult……iple 'æ"entities÷♥"
|
2024-09-29 07:14:51 +02:00
|
|
|
let decoded = decodedString(s)
|
2024-09-17 07:07:31 +02:00
|
|
|
|
|
|
|
XCTAssertEqual(decoded, "çèmult……iple 'æ\"entities÷♥")
|
|
|
|
}
|
|
|
|
|
2024-09-29 07:14:51 +02:00
|
|
|
func testFakeoutEntities() {
|
|
|
|
|
|
|
|
var s = "&&;&#;&#x;&#X;& ;&# \t;&\r&&&&&;"
|
|
|
|
XCTAssertEqual(decodedString(s), s)
|
|
|
|
|
|
|
|
s = "#;&#x;&#X;& {"
|
|
|
|
XCTAssertEqual(decodedString(s), s)
|
|
|
|
|
|
|
|
s = " &lsquo "
|
|
|
|
XCTAssertEqual(decodedString(s), s)
|
|
|
|
|
|
|
|
s = "&&&&&&&&&&&&&&&&&&&;;;;;;&;&;&##;#X::&;&;&;&"
|
|
|
|
XCTAssertEqual(decodedString(s), s)
|
|
|
|
}
|
|
|
|
|
|
|
|
func testFakeSquirrelEntities() {
|
|
|
|
|
|
|
|
var s = "&squirrel;"
|
|
|
|
XCTAssertEqual(decodedString(s), s)
|
|
|
|
|
|
|
|
s = "&squirrel;&#squirrel;"
|
|
|
|
XCTAssertEqual(decodedString(s), s)
|
|
|
|
|
|
|
|
s = "&squirrel;&#squirrel;&#xsquirrel;&#Xsquirrel;"
|
|
|
|
XCTAssertEqual(decodedString(s), s)
|
|
|
|
|
|
|
|
s = "'squirrel;"
|
|
|
|
XCTAssertEqual(decodedString(s), s)
|
|
|
|
|
|
|
|
s = "&squirrel;&#squirrel;&#xsquirrel;&#Xsquirrel;'squirrel;"
|
|
|
|
XCTAssertEqual(decodedString(s), s)
|
|
|
|
|
|
|
|
s = "&squirrel;&#squirrel;&#xsquirrel;&#Xsquirrel;'squirrel;&&;;;;&;&;&#squi#;#rrelX::&;&;&;&"
|
|
|
|
XCTAssertEqual(decodedString(s), s)
|
|
|
|
}
|
|
|
|
|
|
|
|
func testLongFakeoutEntities() {
|
|
|
|
|
|
|
|
var s = "&thisIsALongNotRealEntityThatShouldBeHandledPerfectlyWellByTheParserBasicallyIgnored;"
|
|
|
|
XCTAssertEqual(decodedString(s), s)
|
|
|
|
|
|
|
|
s = "�"
|
|
|
|
XCTAssertEqual(decodedString(s), s)
|
|
|
|
|
|
|
|
s = "�"
|
|
|
|
XCTAssertEqual(decodedString(s), s)
|
|
|
|
|
|
|
|
s = "�"
|
|
|
|
XCTAssertEqual(decodedString(s), s)
|
|
|
|
|
|
|
|
s = "�"
|
|
|
|
XCTAssertEqual(decodedString(s), s)
|
|
|
|
|
|
|
|
s = "�"
|
|
|
|
XCTAssertEqual(decodedString(s), s)
|
|
|
|
}
|
|
|
|
|
2024-09-17 07:07:31 +02:00
|
|
|
func testOnlyEntity() {
|
2024-09-17 06:57:05 +02:00
|
|
|
var s = "…"
|
2024-09-29 07:14:51 +02:00
|
|
|
var decoded = decodedString(s)
|
2024-09-17 06:57:05 +02:00
|
|
|
|
|
|
|
XCTAssertEqual(decoded, "…")
|
|
|
|
|
|
|
|
s = "…"
|
2024-09-29 07:14:51 +02:00
|
|
|
decoded = decodedString(s)
|
2024-09-17 06:57:05 +02:00
|
|
|
XCTAssertEqual(decoded, "…")
|
|
|
|
|
|
|
|
s = "'"
|
2024-09-29 07:14:51 +02:00
|
|
|
decoded = decodedString(s)
|
2024-09-17 06:57:05 +02:00
|
|
|
XCTAssertEqual(decoded, "'")
|
|
|
|
|
|
|
|
s = "§"
|
2024-09-29 07:14:51 +02:00
|
|
|
decoded = decodedString(s)
|
2024-09-17 06:57:05 +02:00
|
|
|
XCTAssertEqual(decoded, "§")
|
|
|
|
|
|
|
|
s = "£"
|
2024-09-29 07:14:51 +02:00
|
|
|
decoded = decodedString(s)
|
2024-09-17 06:57:05 +02:00
|
|
|
XCTAssertEqual(decoded, "£")
|
|
|
|
}
|
2024-09-27 04:52:51 +02:00
|
|
|
|
|
|
|
func testPerformance() {
|
|
|
|
|
2024-09-29 07:14:51 +02:00
|
|
|
// 0.003 sec on my M1 Mac Studio.
|
2024-09-27 04:52:51 +02:00
|
|
|
let s = stringForResource("DaringFireball", "html")
|
2024-09-29 07:14:51 +02:00
|
|
|
|
2024-09-27 04:52:51 +02:00
|
|
|
self.measure {
|
2024-09-29 07:14:51 +02:00
|
|
|
_ = decodedString(s)
|
2024-09-27 04:52:51 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func stringForResource(_ filename: String, _ fileExtension: String) -> String {
|
|
|
|
|
|
|
|
let filename = "Resources/\(filename)"
|
|
|
|
let path = Bundle.module.path(forResource: filename, ofType: fileExtension)!
|
|
|
|
return try! String(contentsOfFile: path)
|
2024-09-17 06:57:05 +02:00
|
|
|
}
|
2024-09-29 07:14:51 +02:00
|
|
|
|
|
|
|
func decodedString(_ s: String) -> String {
|
|
|
|
|
2024-09-29 07:25:35 +02:00
|
|
|
HTMLEntityDecoder.decodedString(s)
|
2024-09-29 07:14:51 +02:00
|
|
|
}
|