diff --git a/HTMLKit.xcodeproj/project.pbxproj b/HTMLKit.xcodeproj/project.pbxproj
index 5422c48..e00d8ff 100644
--- a/HTMLKit.xcodeproj/project.pbxproj
+++ b/HTMLKit.xcodeproj/project.pbxproj
@@ -126,6 +126,8 @@
62D89DB51AE7081600B6243D /* HTMLElementAdjustment.h in Headers */ = {isa = PBXBuildFile; fileRef = 6234C3361AB3BF710046F527 /* HTMLElementAdjustment.h */; };
62D89DB61AE7081600B6243D /* HTMLParserInsertionModes.h in Headers */ = {isa = PBXBuildFile; fileRef = 6279F87119E17DC700F12EE5 /* HTMLParserInsertionModes.h */; };
62D89DB71AE7081600B6243D /* HTMLQuirksMode.h in Headers */ = {isa = PBXBuildFile; fileRef = 623719431AA12EE8002E03C8 /* HTMLQuirksMode.h */; };
+ 62EC7AE61AEEAC6F0015D3BE /* HTMLKitMutationAlgorithmsTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 62EC7AE51AEEAC6F0015D3BE /* HTMLKitMutationAlgorithmsTests.m */; };
+ 62EC7AE71AEEAC6F0015D3BE /* HTMLKitMutationAlgorithmsTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 62EC7AE51AEEAC6F0015D3BE /* HTMLKitMutationAlgorithmsTests.m */; };
62F31FDD19E9DCCF007F0657 /* HTMLTokenizerEntities.h in Headers */ = {isa = PBXBuildFile; fileRef = 62F31FDB19E9DCCF007F0657 /* HTMLTokenizerEntities.h */; };
62F31FDE19E9DCCF007F0657 /* HTMLTokenizerEntities.m in Sources */ = {isa = PBXBuildFile; fileRef = 62F31FDC19E9DCCF007F0657 /* HTMLTokenizerEntities.m */; };
62F31FDF19E9DCCF007F0657 /* HTMLTokenizerEntities.m in Sources */ = {isa = PBXBuildFile; fileRef = 62F31FDC19E9DCCF007F0657 /* HTMLTokenizerEntities.m */; };
@@ -253,6 +255,7 @@
62D8345719FB1AC4009205A9 /* HTML5LibTokenizerTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTML5LibTokenizerTest.h; sourceTree = ""; };
62D8345819FB1AC4009205A9 /* HTML5LibTokenizerTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HTML5LibTokenizerTest.m; sourceTree = ""; };
62E7CAAE19CDFFB500465A83 /* HTMLTokenizerCharacters.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HTMLTokenizerCharacters.h; sourceTree = ""; };
+ 62EC7AE51AEEAC6F0015D3BE /* HTMLKitMutationAlgorithmsTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HTMLKitMutationAlgorithmsTests.m; sourceTree = ""; };
62F31FDB19E9DCCF007F0657 /* HTMLTokenizerEntities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTMLTokenizerEntities.h; sourceTree = ""; };
62F31FDC19E9DCCF007F0657 /* HTMLTokenizerEntities.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HTMLTokenizerEntities.m; sourceTree = ""; };
62F873E919E088C90062683C /* HTMLParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTMLParser.h; sourceTree = ""; };
@@ -354,6 +357,7 @@
623916C61AC7209E0066B4FE /* HTMLKitNodeTreeEnumratorTests.m */,
624B9FB41AE0391400646C4C /* HTMLKitOrderedDictionaryTests.m */,
624FC3791AE591D80015DDF9 /* HTMLKitNodesTests.m */,
+ 62EC7AE51AEEAC6F0015D3BE /* HTMLKitMutationAlgorithmsTests.m */,
);
name = Nodes;
sourceTree = "";
@@ -755,6 +759,7 @@
files = (
6239755B1AC362CA007E26F1 /* HTMLKitTreeConstructionTests.m in Sources */,
623CAF9E1AD88BEA00E34C32 /* HTMLKitParserPerformance.m in Sources */,
+ 62EC7AE71AEEAC6F0015D3BE /* HTMLKitMutationAlgorithmsTests.m in Sources */,
624B9FB61AE0391400646C4C /* HTMLKitOrderedDictionaryTests.m in Sources */,
6236738F1AC0CE2500FF89B3 /* HTMLKitTokenizerPerformance.m in Sources */,
624AC90219FBF9ED00BD3C4A /* HTMLKitTokenizerTests.m in Sources */,
@@ -806,6 +811,7 @@
files = (
6239755A1AC362CA007E26F1 /* HTMLKitTreeConstructionTests.m in Sources */,
623CAF9D1AD88BEA00E34C32 /* HTMLKitParserPerformance.m in Sources */,
+ 62EC7AE61AEEAC6F0015D3BE /* HTMLKitMutationAlgorithmsTests.m in Sources */,
624B9FB51AE0391400646C4C /* HTMLKitOrderedDictionaryTests.m in Sources */,
6236738E1AC0CE2500FF89B3 /* HTMLKitTokenizerPerformance.m in Sources */,
624AC90119FBF9ED00BD3C4A /* HTMLKitTokenizerTests.m in Sources */,
diff --git a/HTMLKitTests/HTMLKitMutationAlgorithmsTests.m b/HTMLKitTests/HTMLKitMutationAlgorithmsTests.m
new file mode 100644
index 0000000..4f69454
--- /dev/null
+++ b/HTMLKitTests/HTMLKitMutationAlgorithmsTests.m
@@ -0,0 +1,373 @@
+//
+// HTMLKitMutationAlgorithmsTests.m
+// HTMLKit
+//
+// Created by Iska on 27/04/15.
+// Copyright (c) 2015 BrainCookie. All rights reserved.
+//
+
+#import
+#import "HTMLNodes.h"
+
+@interface HTMLKitMutationAlgorithmsTests : XCTestCase
+
+@end
+
+@implementation HTMLKitMutationAlgorithmsTests
+
+- (void)testValidParentNodeWhenAppending
+{
+ HTMLElement *element = [[HTMLElement alloc] initWithTagName:@"div"];
+
+ id parent = [HTMLDocument new];
+ XCTAssertNoThrow([parent appendNode:element]);
+
+ parent = [HTMLDocumentFragment new];
+ XCTAssertNoThrow([parent appendNode:element]);
+
+ parent = [HTMLElement new];
+ XCTAssertNoThrow([parent appendNode:element]);
+
+ parent = [HTMLTemplate new];
+ XCTAssertNoThrow([parent appendNode:element]);
+
+ parent = [HTMLDocumentType new];
+ XCTAssertThrows([parent appendNode:element]);
+
+ parent = [HTMLComment new];
+ XCTAssertThrows([parent appendNode:element]);
+
+ parent = [HTMLText new];
+ XCTAssertThrows([parent appendNode:element]);
+}
+
+- (void)testValidParentNodeWhenInserting
+{
+ HTMLElement *element = [[HTMLElement alloc] initWithTagName:@"div"];
+
+ id parent = [HTMLDocument new];
+ XCTAssertNoThrow([parent insertNode:element beforeChildNode:nil]);
+
+ parent = [HTMLDocumentFragment new];
+ XCTAssertNoThrow([parent insertNode:element beforeChildNode:nil]);
+
+ parent = [HTMLElement new];
+ XCTAssertNoThrow([parent insertNode:element beforeChildNode:nil]);
+
+ parent = [HTMLTemplate new];
+ XCTAssertNoThrow([parent insertNode:element beforeChildNode:nil]);
+
+ parent = [HTMLDocumentType new];
+ XCTAssertThrows([parent insertNode:element beforeChildNode:nil]);
+
+ parent = [HTMLComment new];
+ XCTAssertThrows([parent insertNode:element beforeChildNode:nil]);
+
+ parent = [HTMLText new];
+ XCTAssertThrows([parent insertNode:element beforeChildNode:nil]);
+}
+
+- (void)testValidChildNodeWhenInserting
+{
+ HTMLElement *div = [[HTMLElement alloc] initWithTagName:@"div"];
+ HTMLElement *p = [[HTMLElement alloc] initWithTagName:@"p"];
+ [div appendNode:p];
+
+ HTMLElement *table = [[HTMLElement alloc] initWithTagName:@"table"];
+
+ XCTAssertNoThrow([div insertNode:table beforeChildNode:p]);
+
+ [div removeChildNode:p];
+
+ HTMLElement *section = [[HTMLElement alloc] initWithTagName:@"section"];
+ XCTAssertThrows([div insertNode:section beforeChildNode:p]);
+}
+
+- (void)testValidChildNodeWhenReplacing
+{
+ HTMLElement *div = [[HTMLElement alloc] initWithTagName:@"div"];
+ HTMLElement *p = [[HTMLElement alloc] initWithTagName:@"p"];
+ [div appendNode:p];
+
+ HTMLElement *table = [[HTMLElement alloc] initWithTagName:@"table"];
+
+ XCTAssertNoThrow([div replaceChildNode:p withNode:table]);
+
+ XCTAssertThrows([div replaceChildNode:p withNode:[HTMLComment new]]);
+}
+
+- (void)testValidChildNodeWhenRemoving
+{
+ HTMLElement *div = [[HTMLElement alloc] initWithTagName:@"div"];
+ HTMLElement *p = [[HTMLElement alloc] initWithTagName:@"p"];
+ [div appendNode:p];
+
+ XCTAssertNoThrow([div removeChildNode:p]);
+ XCTAssertThrows([div removeChildNode:p]);
+}
+
+- (void)testValidInsertedNode
+{
+ HTMLDocument *document = [HTMLDocument new];
+
+ XCTAssertNoThrow([document appendNode:[HTMLDocumentFragment new]]);
+ XCTAssertNoThrow([document appendNode:[HTMLDocumentType new]]);
+ XCTAssertNoThrow([document appendNode:[HTMLElement new]]);
+
+ HTMLElement *element = [HTMLElement new];
+
+ XCTAssertNoThrow([element appendNode:[HTMLTemplate new]]);
+ XCTAssertNoThrow([element appendNode:[HTMLComment new]]);
+ XCTAssertNoThrow([element appendNode:[HTMLText new]]);
+}
+
+- (void)testValidParentForDoctype
+{
+ HTMLDocumentType *doctype = [HTMLDocumentType new];
+
+ XCTAssertNoThrow([[HTMLDocument new] appendNode:doctype]);
+
+ XCTAssertThrows([[HTMLDocumentFragment new] appendNode:doctype]);
+ XCTAssertThrows([[HTMLDocumentType new] appendNode:doctype]);
+ XCTAssertThrows([[HTMLElement new] appendNode:doctype]);
+ XCTAssertThrows([[HTMLTemplate new] appendNode:doctype]);
+ XCTAssertThrows([[HTMLComment new] appendNode:doctype]);
+ XCTAssertThrows([[HTMLText new] appendNode:doctype]);
+}
+
+- (void)testValidParentForText
+{
+ HTMLText *text = [HTMLText new];
+
+ XCTAssertThrows([[HTMLDocument new] appendNode:text]);
+ XCTAssertThrows([[HTMLDocumentType new] appendNode:text]);
+ XCTAssertThrows([[HTMLComment new] appendNode:text]);
+ XCTAssertThrows([[HTMLText new] appendNode:text]);
+
+ XCTAssertNoThrow([[HTMLDocumentFragment new] appendNode:text]);
+ XCTAssertNoThrow([[HTMLElement new] appendNode:text]);
+ XCTAssertNoThrow([[HTMLTemplate new] appendNode:text]);
+}
+
+- (void)testValidDocumentFragmentInsertionIntoDocument
+{
+ HTMLDocument *document = [HTMLDocument new];
+ HTMLDocumentFragment *fragment = [[HTMLDocumentFragment alloc] initWithDocument:document];
+
+ void (^ reset)() = ^ {
+ [fragment removeAllChildNodes];
+ [document removeAllChildNodes];
+ };
+
+ /**
+ * Fragment has a Text node child
+ */
+ [fragment appendNode:[HTMLText new]];
+ XCTAssertThrows([document appendNode:fragment]);
+
+ /**
+ * Fragment has more than one Element child
+ */
+ reset();
+ [fragment appendNode:[HTMLElement new]];
+ [fragment appendNode:[HTMLElement new]];
+ XCTAssertThrows([document appendNode:fragment]);
+
+
+ /**
+ * Fragment has one node child
+ * Document has an Element child
+ */
+ reset();
+ [fragment appendNode:[HTMLElement new]];
+ [document appendNode:[HTMLElement new]];
+ XCTAssertThrows([document appendNode:fragment]);
+
+ /**
+ * Fragment has one node child
+ * "before child" is a Doctype
+ */
+ reset();
+ HTMLDocumentType *doctype = [HTMLDocumentType new];
+ [fragment appendNode:[HTMLElement new]];
+ [document appendNode:doctype];
+ XCTAssertThrows([document insertNode:fragment beforeChildNode:doctype]);
+
+ /**
+ * Fragment has one node child
+ * "before child" is following a Doctype
+ */
+ reset();
+ HTMLComment *doctypePreviousSibling = [HTMLComment new];
+ [fragment appendNode:[HTMLElement new]];
+ [document appendNode:doctypePreviousSibling];
+ [document appendNode:doctype];
+ XCTAssertThrows([document insertNode:fragment beforeChildNode:doctypePreviousSibling]);
+}
+
+- (void)testValidElementInsertionIntoDocument
+{
+ HTMLDocument *document = [HTMLDocument new];
+ HTMLElement *element = [HTMLElement new];
+
+ void (^ reset)() = ^ {
+ [element removeAllChildNodes];
+ [document removeAllChildNodes];
+ };
+
+ /**
+ * Document has an Element child
+ */
+ [document appendNode:[HTMLElement new]];
+ XCTAssertThrows([document appendNode:element]);
+
+ /**
+ * "before child" is a Doctype
+ */
+ reset();
+ HTMLDocumentType *doctype = [HTMLDocumentType new];
+ [document appendNode:doctype];
+ XCTAssertThrows([document insertNode:element beforeChildNode:doctype]);
+
+ /**
+ * Doctype is following the "before child"
+ */
+ reset();
+ HTMLComment *doctypePreviousSibling = [HTMLComment new];
+ [document appendNode:doctypePreviousSibling];
+ [document appendNode:doctype];
+ XCTAssertThrows([document insertNode:element beforeChildNode:doctypePreviousSibling]);
+}
+
+- (void)testValidDoctypeInsertionIntoDocument
+{
+ HTMLDocument *document = [HTMLDocument new];
+ HTMLDocumentType *doctype = [HTMLDocumentType new];
+
+ void (^ reset)() = ^ {
+ [document removeAllChildNodes];
+ };
+
+ /**
+ * Document has a Doctype child
+ */
+ [document appendNode:[HTMLDocumentType new]];
+ XCTAssertThrows([document appendNode:doctype]);
+
+ /**
+ * An Element is preceding the "before child"
+ */
+ reset();
+ HTMLComment *secondChild = [HTMLComment new];
+ [document appendNode:[HTMLElement new]];
+ [document appendNode:secondChild];
+ XCTAssertThrows([document insertNode:doctype beforeChildNode:secondChild]);
+
+ /**
+ * Document has an Element child
+ */
+ reset();
+ [document appendNode:[HTMLElement new]];
+ XCTAssertThrows([document appendNode:doctype]);
+}
+
+- (void)testValidDocumentFragmentReplacementIntoDocument
+{
+ HTMLDocument *document = [HTMLDocument new];
+ HTMLComment *child = [HTMLComment new];
+ HTMLDocumentFragment *replacement = [[HTMLDocumentFragment alloc] initWithDocument:document];
+
+ void (^ reset)() = ^ {
+ [replacement removeAllChildNodes];
+ [document removeAllChildNodes];
+ [document appendNode:child];
+ };
+
+ /**
+ * Replacement Fragment has a Text node child
+ */
+ [replacement appendNode:[HTMLText new]];
+ XCTAssertThrows([document replaceChildNode:child withNode:replacement]);
+
+ /**
+ * Replacement Fragment has more than one Element child
+ */
+ reset();
+ [replacement appendNode:[HTMLElement new]];
+ [replacement appendNode:[HTMLElement new]];
+ XCTAssertThrows([document replaceChildNode:child withNode:replacement]);
+
+ /**
+ * Replacement Fragment has one Element child
+ * Document has an Element child that is not the Replacement
+ */
+ reset();
+ [replacement appendNode:[HTMLElement new]];
+ [document appendNode:[HTMLElement new]];
+ XCTAssertThrows([document replaceChildNode:child withNode:replacement]);
+
+ /**
+ * Replacement Fragment has one Element child
+ * Doctype is following the child node
+ */
+ reset();
+ HTMLDocumentType *doctype = [HTMLDocumentType new];
+ [replacement appendNode:[HTMLElement new]];
+ [document appendNode:doctype];
+ XCTAssertThrows([document replaceChildNode:child withNode:replacement]);
+}
+
+- (void)testValidElementReplacementIntoDocument
+{
+ HTMLDocument *document = [HTMLDocument new];
+ HTMLComment *child = [HTMLComment new];
+ HTMLElement *replacement = [HTMLElement new];
+
+ void (^ reset)() = ^ {
+ [replacement removeAllChildNodes];
+ [document removeAllChildNodes];
+ [document appendNode:child];
+ };
+
+ /**
+ * Docment has an Element child that is not replacement
+ */
+ [document appendNode:[HTMLElement new]];
+ XCTAssertThrows([document replaceChildNode:child withNode:replacement]);
+
+ /**
+ * Doctype is following the child node
+ */
+ reset();
+ HTMLDocumentType *doctype = [HTMLDocumentType new];
+ [document appendNode:doctype];
+ XCTAssertThrows([document replaceChildNode:child withNode:replacement]);
+}
+
+- (void)testValidDoctypeReplacementIntoDocument
+{
+ HTMLDocument *document = [HTMLDocument new];
+ HTMLComment *child = [HTMLComment new];
+ HTMLDocumentType *replacement = [HTMLDocumentType new];
+
+ void (^ reset)() = ^ {
+ [replacement removeAllChildNodes];
+ [document removeAllChildNodes];
+ [document appendNode:child];
+ };
+
+ /**
+ * Docment has an Doctype child that is not replacement
+ */
+ [document appendNode:[HTMLDocumentType new]];
+ XCTAssertThrows([document replaceChildNode:child withNode:replacement]);
+
+ /**
+ * An Element is preceding the child node
+ */
+ reset();
+ [document insertNode:[HTMLElement new] beforeChildNode:child];
+ XCTAssertThrows([document replaceChildNode:child withNode:replacement]);
+}
+
+@end
diff --git a/HTMLKitTests/HTMLKitNodesTests.m b/HTMLKitTests/HTMLKitNodesTests.m
index 0625c11..56a5d6a 100644
--- a/HTMLKitTests/HTMLKitNodesTests.m
+++ b/HTMLKitTests/HTMLKitNodesTests.m
@@ -403,359 +403,4 @@
XCTAssertEqualObjects(thirdChild.parentNode, newParent);
}
-- (void)testValidParentNodeWhenAppending
-{
- HTMLElement *element = [[HTMLElement alloc] initWithTagName:@"div"];
-
- id parent = [HTMLDocument new];
- XCTAssertNoThrow([parent appendNode:element]);
-
- parent = [HTMLDocumentFragment new];
- XCTAssertNoThrow([parent appendNode:element]);
-
- parent = [HTMLElement new];
- XCTAssertNoThrow([parent appendNode:element]);
-
- parent = [HTMLTemplate new];
- XCTAssertNoThrow([parent appendNode:element]);
-
- parent = [HTMLDocumentType new];
- XCTAssertThrows([parent appendNode:element]);
-
- parent = [HTMLComment new];
- XCTAssertThrows([parent appendNode:element]);
-
- parent = [HTMLText new];
- XCTAssertThrows([parent appendNode:element]);
-}
-
-- (void)testValidParentNodeWhenInserting
-{
- HTMLElement *element = [[HTMLElement alloc] initWithTagName:@"div"];
-
- id parent = [HTMLDocument new];
- XCTAssertNoThrow([parent insertNode:element beforeChildNode:nil]);
-
- parent = [HTMLDocumentFragment new];
- XCTAssertNoThrow([parent insertNode:element beforeChildNode:nil]);
-
- parent = [HTMLElement new];
- XCTAssertNoThrow([parent insertNode:element beforeChildNode:nil]);
-
- parent = [HTMLTemplate new];
- XCTAssertNoThrow([parent insertNode:element beforeChildNode:nil]);
-
- parent = [HTMLDocumentType new];
- XCTAssertThrows([parent insertNode:element beforeChildNode:nil]);
-
- parent = [HTMLComment new];
- XCTAssertThrows([parent insertNode:element beforeChildNode:nil]);
-
- parent = [HTMLText new];
- XCTAssertThrows([parent insertNode:element beforeChildNode:nil]);
-}
-
-- (void)testValidChildNodeWhenInserting
-{
- HTMLElement *div = [[HTMLElement alloc] initWithTagName:@"div"];
- HTMLElement *p = [[HTMLElement alloc] initWithTagName:@"p"];
- [div appendNode:p];
-
- HTMLElement *table = [[HTMLElement alloc] initWithTagName:@"table"];
-
- XCTAssertNoThrow([div insertNode:table beforeChildNode:p]);
-
- [div removeChildNode:p];
-
- HTMLElement *section = [[HTMLElement alloc] initWithTagName:@"section"];
- XCTAssertThrows([div insertNode:section beforeChildNode:p]);
-}
-
-- (void)testValidChildNodeWhenReplacing
-{
- HTMLElement *div = [[HTMLElement alloc] initWithTagName:@"div"];
- HTMLElement *p = [[HTMLElement alloc] initWithTagName:@"p"];
- [div appendNode:p];
-
- HTMLElement *table = [[HTMLElement alloc] initWithTagName:@"table"];
-
- XCTAssertNoThrow([div replaceChildNode:p withNode:table]);
-
- XCTAssertThrows([div replaceChildNode:p withNode:[HTMLComment new]]);
-}
-
-- (void)testValidChildNodeWhenRemoving
-{
- HTMLElement *div = [[HTMLElement alloc] initWithTagName:@"div"];
- HTMLElement *p = [[HTMLElement alloc] initWithTagName:@"p"];
- [div appendNode:p];
-
- XCTAssertNoThrow([div removeChildNode:p]);
- XCTAssertThrows([div removeChildNode:p]);
-}
-
-- (void)testValidInsertedNode
-{
- HTMLDocument *document = [HTMLDocument new];
-
- XCTAssertNoThrow([document appendNode:[HTMLDocumentFragment new]]);
- XCTAssertNoThrow([document appendNode:[HTMLDocumentType new]]);
- XCTAssertNoThrow([document appendNode:[HTMLElement new]]);
-
- HTMLElement *element = [HTMLElement new];
-
- XCTAssertNoThrow([element appendNode:[HTMLTemplate new]]);
- XCTAssertNoThrow([element appendNode:[HTMLComment new]]);
- XCTAssertNoThrow([element appendNode:[HTMLText new]]);
-}
-
-- (void)testValidParentForDoctype
-{
- HTMLDocumentType *doctype = [HTMLDocumentType new];
-
- XCTAssertNoThrow([[HTMLDocument new] appendNode:doctype]);
-
- XCTAssertThrows([[HTMLDocumentFragment new] appendNode:doctype]);
- XCTAssertThrows([[HTMLDocumentType new] appendNode:doctype]);
- XCTAssertThrows([[HTMLElement new] appendNode:doctype]);
- XCTAssertThrows([[HTMLTemplate new] appendNode:doctype]);
- XCTAssertThrows([[HTMLComment new] appendNode:doctype]);
- XCTAssertThrows([[HTMLText new] appendNode:doctype]);
-}
-
-- (void)testValidParentForText
-{
- HTMLText *text = [HTMLText new];
-
- XCTAssertThrows([[HTMLDocument new] appendNode:text]);
- XCTAssertThrows([[HTMLDocumentType new] appendNode:text]);
- XCTAssertThrows([[HTMLComment new] appendNode:text]);
- XCTAssertThrows([[HTMLText new] appendNode:text]);
-
- XCTAssertNoThrow([[HTMLDocumentFragment new] appendNode:text]);
- XCTAssertNoThrow([[HTMLElement new] appendNode:text]);
- XCTAssertNoThrow([[HTMLTemplate new] appendNode:text]);
-}
-
-- (void)testValidDocumentFragmentInsertionIntoDocument
-{
- HTMLDocument *document = [HTMLDocument new];
- HTMLDocumentFragment *fragment = [[HTMLDocumentFragment alloc] initWithDocument:document];
-
- void (^ reset)() = ^ {
- [fragment removeAllChildNodes];
- [document removeAllChildNodes];
- };
-
- /**
- * Fragment has a Text node child
- */
- [fragment appendNode:[HTMLText new]];
- XCTAssertThrows([document appendNode:fragment]);
-
- /**
- * Fragment has more than one Element child
- */
- reset();
- [fragment appendNode:[HTMLElement new]];
- [fragment appendNode:[HTMLElement new]];
- XCTAssertThrows([document appendNode:fragment]);
-
-
- /**
- * Fragment has one node child
- * Document has an Element child
- */
- reset();
- [fragment appendNode:[HTMLElement new]];
- [document appendNode:[HTMLElement new]];
- XCTAssertThrows([document appendNode:fragment]);
-
- /**
- * Fragment has one node child
- * "before child" is a Doctype
- */
- reset();
- HTMLDocumentType *doctype = [HTMLDocumentType new];
- [fragment appendNode:[HTMLElement new]];
- [document appendNode:doctype];
- XCTAssertThrows([document insertNode:fragment beforeChildNode:doctype]);
-
- /**
- * Fragment has one node child
- * "before child" is following a Doctype
- */
- reset();
- HTMLComment *doctypePreviousSibling = [HTMLComment new];
- [fragment appendNode:[HTMLElement new]];
- [document appendNode:doctypePreviousSibling];
- [document appendNode:doctype];
- XCTAssertThrows([document insertNode:fragment beforeChildNode:doctypePreviousSibling]);
-}
-
-- (void)testValidElementInsertionIntoDocument
-{
- HTMLDocument *document = [HTMLDocument new];
- HTMLElement *element = [HTMLElement new];
-
- void (^ reset)() = ^ {
- [element removeAllChildNodes];
- [document removeAllChildNodes];
- };
-
- /**
- * Document has an Element child
- */
- [document appendNode:[HTMLElement new]];
- XCTAssertThrows([document appendNode:element]);
-
- /**
- * "before child" is a Doctype
- */
- reset();
- HTMLDocumentType *doctype = [HTMLDocumentType new];
- [document appendNode:doctype];
- XCTAssertThrows([document insertNode:element beforeChildNode:doctype]);
-
- /**
- * Doctype is following the "before child"
- */
- reset();
- HTMLComment *doctypePreviousSibling = [HTMLComment new];
- [document appendNode:doctypePreviousSibling];
- [document appendNode:doctype];
- XCTAssertThrows([document insertNode:element beforeChildNode:doctypePreviousSibling]);
-}
-
-- (void)testValidDoctypeInsertionIntoDocument
-{
- HTMLDocument *document = [HTMLDocument new];
- HTMLDocumentType *doctype = [HTMLDocumentType new];
-
- void (^ reset)() = ^ {
- [document removeAllChildNodes];
- };
-
- /**
- * Document has a Doctype child
- */
- [document appendNode:[HTMLDocumentType new]];
- XCTAssertThrows([document appendNode:doctype]);
-
- /**
- * An Element is preceding the "before child"
- */
- reset();
- HTMLComment *secondChild = [HTMLComment new];
- [document appendNode:[HTMLElement new]];
- [document appendNode:secondChild];
- XCTAssertThrows([document insertNode:doctype beforeChildNode:secondChild]);
-
- /**
- * Document has an Element child
- */
- reset();
- [document appendNode:[HTMLElement new]];
- XCTAssertThrows([document appendNode:doctype]);
-}
-
-- (void)testValidDocumentFragmentReplacementIntoDocument
-{
- HTMLDocument *document = [HTMLDocument new];
- HTMLComment *child = [HTMLComment new];
- HTMLDocumentFragment *replacement = [[HTMLDocumentFragment alloc] initWithDocument:document];
-
- void (^ reset)() = ^ {
- [replacement removeAllChildNodes];
- [document removeAllChildNodes];
- [document appendNode:child];
- };
-
- /**
- * Replacement Fragment has a Text node child
- */
- [replacement appendNode:[HTMLText new]];
- XCTAssertThrows([document replaceChildNode:child withNode:replacement]);
-
- /**
- * Replacement Fragment has more than one Element child
- */
- reset();
- [replacement appendNode:[HTMLElement new]];
- [replacement appendNode:[HTMLElement new]];
- XCTAssertThrows([document replaceChildNode:child withNode:replacement]);
-
- /**
- * Replacement Fragment has one Element child
- * Document has an Element child that is not the Replacement
- */
- reset();
- [replacement appendNode:[HTMLElement new]];
- [document appendNode:[HTMLElement new]];
- XCTAssertThrows([document replaceChildNode:child withNode:replacement]);
-
- /**
- * Replacement Fragment has one Element child
- * Doctype is following the child node
- */
- reset();
- HTMLDocumentType *doctype = [HTMLDocumentType new];
- [replacement appendNode:[HTMLElement new]];
- [document appendNode:doctype];
- XCTAssertThrows([document replaceChildNode:child withNode:replacement]);
-}
-
-- (void)testValidElementReplacementIntoDocument
-{
- HTMLDocument *document = [HTMLDocument new];
- HTMLComment *child = [HTMLComment new];
- HTMLElement *replacement = [HTMLElement new];
-
- void (^ reset)() = ^ {
- [replacement removeAllChildNodes];
- [document removeAllChildNodes];
- [document appendNode:child];
- };
-
- /**
- * Docment has an Element child that is not replacement
- */
- [document appendNode:[HTMLElement new]];
- XCTAssertThrows([document replaceChildNode:child withNode:replacement]);
-
- /**
- * Doctype is following the child node
- */
- reset();
- HTMLDocumentType *doctype = [HTMLDocumentType new];
- [document appendNode:doctype];
- XCTAssertThrows([document replaceChildNode:child withNode:replacement]);
-}
-
-- (void)testValidDoctypeReplacementIntoDocument
-{
- HTMLDocument *document = [HTMLDocument new];
- HTMLComment *child = [HTMLComment new];
- HTMLDocumentType *replacement = [HTMLDocumentType new];
-
- void (^ reset)() = ^ {
- [replacement removeAllChildNodes];
- [document removeAllChildNodes];
- [document appendNode:child];
- };
-
- /**
- * Docment has an Doctype child that is not replacement
- */
- [document appendNode:[HTMLDocumentType new]];
- XCTAssertThrows([document replaceChildNode:child withNode:replacement]);
-
- /**
- * An Element is preceding the child node
- */
- reset();
- [document insertNode:[HTMLElement new] beforeChildNode:child];
- XCTAssertThrows([document replaceChildNode:child withNode:replacement]);
-}
-
@end