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