SwiftSoup/Tests/SwiftSoupTests/XmlTreeBuilderTest.swift

181 lines
7.8 KiB
Swift

//
// XmlTreeBuilderTest.swift
// SwiftSoup
//
// Created by Nabil Chatbi on 14/10/16.
// Copyright © 2016 Nabil Chatbi.. All rights reserved.
//
import XCTest
import SwiftSoup
class XmlTreeBuilderTest: XCTestCase {
func testSimpleXmlParse()throws {
let xml = "<doc id=2 href='/bar'>Foo <br /><link>One</link><link>Two</link></doc>"
let tb: XmlTreeBuilder = XmlTreeBuilder()
let doc: Document = try tb.parse(xml, "http://foo.com/")
XCTAssertEqual("<doc id=\"2\" href=\"/bar\">Foo <br /><link>One</link><link>Two</link></doc>",try TextUtil.stripNewlines(doc.html()))
XCTAssertEqual(try doc.getElementById("2")?.absUrl("href"), "http://foo.com/bar")
}
func testPopToClose()throws {
// test: </val> closes Two, </bar> ignored
let xml = "<doc><val>One<val>Two</val></bar>Three</doc>"
let tb: XmlTreeBuilder = XmlTreeBuilder()
let doc = try tb.parse(xml, "http://foo.com/")
XCTAssertEqual("<doc><val>One<val>Two</val>Three</val></doc>",try TextUtil.stripNewlines(doc.html()))
}
func testCommentAndDocType()throws {
let xml = "<!DOCTYPE HTML><!-- a comment -->One <qux />Two"
let tb: XmlTreeBuilder = XmlTreeBuilder()
let doc = try tb.parse(xml, "http://foo.com/")
XCTAssertEqual("<!DOCTYPE HTML><!-- a comment -->One <qux />Two",try TextUtil.stripNewlines(doc.html()))
}
func testSupplyParserToJsoupClass()throws {
let xml = "<doc><val>One<val>Two</val></bar>Three</doc>"
let doc = try SwiftSoup.parse(xml, "http://foo.com/", Parser.xmlParser())
try XCTAssertEqual("<doc><val>One<val>Two</val>Three</val></doc>",TextUtil.stripNewlines(doc.html()))
}
//TODO: nabil
// public void testSupplyParserToConnection() throws IOException {
// String xmlUrl = "http://direct.infohound.net/tools/jsoup-xml-test.xml";
//
// // parse with both xml and html parser, ensure different
// Document xmlDoc = Jsoup.connect(xmlUrl).parser(Parser.xmlParser()).get();
// Document htmlDoc = Jsoup.connect(xmlUrl).parser(Parser.htmlParser()).get();
// Document autoXmlDoc = Jsoup.connect(xmlUrl).get(); // check connection auto detects xml, uses xml parser
//
// XCTAssertEqual("<doc><val>One<val>Two</val>Three</val></doc>",
// TextUtil.stripNewlines(xmlDoc.html()));
// assertFalse(htmlDoc.equals(xmlDoc));
// XCTAssertEqual(xmlDoc, autoXmlDoc);
// XCTAssertEqual(1, htmlDoc.select("head").size()); // html parser normalises
// XCTAssertEqual(0, xmlDoc.select("head").size()); // xml parser does not
// XCTAssertEqual(0, autoXmlDoc.select("head").size()); // xml parser does not
// }
//TODO: nabil
// func testSupplyParserToDataStream()throws {
// let testBundle = Bundle(for: type(of: self))
// let fileURL = testBundle.url(forResource: "xml-test", withExtension: "xml")
// File xmlFile = new File(XmlTreeBuilder.class.getResource("/htmltests/xml-test.xml").toURI());
// InputStream inStream = new FileInputStream(xmlFile);
// let doc = Jsoup.parse(inStream, null, "http://foo.com", Parser.xmlParser());
// XCTAssertEqual("<doc><val>One<val>Two</val>Three</val></doc>",
// TextUtil.stripNewlines(doc.html()));
// }
func testDoesNotForceSelfClosingKnownTags()throws {
// html will force "<br>one</br>" to logically "<br />One<br />". XML should be stay "<br>one</br> -- don't recognise tag.
let htmlDoc = try SwiftSoup.parse("<br>one</br>")
XCTAssertEqual("<br>one\n<br>", try htmlDoc.body()?.html())
let xmlDoc = try SwiftSoup.parse("<br>one</br>", "",Parser.xmlParser())
XCTAssertEqual("<br>one</br>", try xmlDoc.html())
}
func testHandlesXmlDeclarationAsDeclaration()throws {
let html = "<?xml encoding='UTF-8' ?><body>One</body><!-- comment -->"
let doc = try SwiftSoup.parse(html, "", Parser.xmlParser())
try XCTAssertEqual("<?xml encoding=\"UTF-8\"?> <body> One </body> <!-- comment -->",StringUtil.normaliseWhitespace(doc.outerHtml()))
XCTAssertEqual("#declaration", doc.childNode(0).nodeName())
XCTAssertEqual("#comment", doc.childNode(2).nodeName())
}
func testXmlFragment()throws {
let xml = "<one src='/foo/' />Two<three><four /></three>"
let nodes: Array<Node> = try Parser.parseXmlFragment(xml, "http://example.com/")
XCTAssertEqual(3, nodes.count)
try XCTAssertEqual("http://example.com/foo/", nodes[0].absUrl("src"))
XCTAssertEqual("one", nodes[0].nodeName())
XCTAssertEqual("Two", (nodes[1] as? TextNode)?.text())
}
func testXmlParseDefaultsToHtmlOutputSyntax()throws {
let doc = try SwiftSoup.parse("x", "", Parser.xmlParser())
XCTAssertEqual(OutputSettings.Syntax.xml, doc.outputSettings().syntax())
}
func testDoesHandleEOFInTag()throws {
let html = "<img src=asdf onerror=\"alert(1)\" x="
let xmlDoc = try SwiftSoup.parse(html, "", Parser.xmlParser())
try XCTAssertEqual("<img src=\"asdf\" onerror=\"alert(1)\" x=\"\" />", xmlDoc.html())
}
//todo:
// func testDetectCharsetEncodingDeclaration()throws{
// File xmlFile = new File(XmlTreeBuilder.class.getResource("/htmltests/xml-charset.xml").toURI());
// InputStream inStream = new FileInputStream(xmlFile);
// let doc = Jsoup.parse(inStream, null, "http://example.com/", Parser.xmlParser());
// XCTAssertEqual("ISO-8859-1", doc.charset().name());
// XCTAssertEqual("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?> <data>äöåéü</data>",
// TextUtil.stripNewlines(doc.html()));
// }
func testParseDeclarationAttributes()throws {
let xml = "<?xml version='1' encoding='UTF-8' something='else'?><val>One</val>"
let doc = try SwiftSoup.parse(xml, "", Parser.xmlParser())
let decl: XmlDeclaration = doc.childNode(0) as! XmlDeclaration
try XCTAssertEqual("1", decl.attr("version"))
try XCTAssertEqual("UTF-8", decl.attr("encoding"))
try XCTAssertEqual("else", decl.attr("something"))
try XCTAssertEqual("version=\"1\" encoding=\"UTF-8\" something=\"else\"", decl.getWholeDeclaration())
try XCTAssertEqual("<?xml version=\"1\" encoding=\"UTF-8\" something=\"else\"?>", decl.outerHtml())
}
func testCaseSensitiveDeclaration()throws {
let xml = "<?XML version='1' encoding='UTF-8' something='else'?>"
let doc = try SwiftSoup.parse(xml, "", Parser.xmlParser())
try XCTAssertEqual("<?XML version=\"1\" encoding=\"UTF-8\" something=\"else\"?>", doc.outerHtml())
}
func testCreatesValidProlog()throws {
let document = Document.createShell("")
document.outputSettings().syntax(syntax: OutputSettings.Syntax.xml)
try document.charset(String.Encoding.utf8)
try XCTAssertEqual("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
"<html>\n" +
" <head></head>\n" +
" <body></body>\n" +
"</html>", document.outerHtml())
}
func preservesCaseByDefault()throws {
let xml = "<TEST ID=1>Check</TEST>"
let doc = try SwiftSoup.parse(xml, "", Parser.xmlParser())
try XCTAssertEqual("<TEST ID=\"1\">Check</TEST>", TextUtil.stripNewlines(doc.html()))
}
func canNormalizeCase()throws {
let xml = "<TEST ID=1>Check</TEST>"
let doc = try SwiftSoup.parse(xml, "", Parser.xmlParser().settings(ParseSettings.htmlDefault))
try XCTAssertEqual("<test id=\"1\">Check</test>", TextUtil.stripNewlines(doc.html()))
}
static var allTests = {
return [
("testSimpleXmlParse" , testSimpleXmlParse),
("testPopToClose" , testPopToClose),
("testCommentAndDocType" , testCommentAndDocType),
("testSupplyParserToJsoupClass" , testSupplyParserToJsoupClass),
("testDoesNotForceSelfClosingKnownTags" , testDoesNotForceSelfClosingKnownTags),
("testHandlesXmlDeclarationAsDeclaration" , testHandlesXmlDeclarationAsDeclaration),
("testXmlFragment" , testXmlFragment),
("testXmlParseDefaultsToHtmlOutputSyntax" , testXmlParseDefaultsToHtmlOutputSyntax),
("testDoesHandleEOFInTag" , testDoesHandleEOFInTag),
("testParseDeclarationAttributes" , testParseDeclarationAttributes),
("testCaseSensitiveDeclaration" , testCaseSensitiveDeclaration),
("testCreatesValidProlog" , testCreatesValidProlog),
("preservesCaseByDefault" , preservesCaseByDefault),
("canNormalizeCase" , canNormalizeCase)
]
}()
}