"];
return document;
}
- (void)testThatTreeWalkerParentHasNoEffectCurrentNodeWhenParentIsNotUnderRoot
{
HTMLDocument *document = self.currentNodeDOM;
HTMLNode *first = document.body.firstChild;
HTMLTreeWalker *walker = [[HTMLTreeWalker alloc] initWithNode:first
showOptions:HTMLNodeFilterShowElement
filter:nil];
AssertElementWithId(walker.currentNode, @"first");
XCTAssertNil(walker.parentNode);
AssertElementWithId(walker.currentNode, @"first");
}
- (void)testThatSettingCurrentNodeToNodesNotUnderRootIsHandledCorrectly
{
HTMLDocument *document = self.currentNodeDOM;
HTMLNode *first = document.body.firstChild;
HTMLTreeWalker *walker = [[HTMLTreeWalker alloc] initWithNode:first
showOptions:HTMLNodeFilterShowElement|HTMLNodeFilterShowComment
filter:nil];
walker.currentNode = document.documentElement;
XCTAssertNil(walker.parentNode);
XCTAssertEqualObjects(walker.currentNode, document.documentElement);
walker.currentNode = document.documentElement;
XCTAssertEqualObjects(walker.nextNode, document.documentElement.firstChild);
XCTAssertEqualObjects(walker.currentNode, document.documentElement.firstChild);
walker.currentNode = document.documentElement;
XCTAssertNil(walker.previousNode);
XCTAssertEqualObjects(walker.currentNode, document.documentElement);
walker.currentNode = document.documentElement;
XCTAssertEqualObjects(walker.firstChild, document.documentElement.firstChild);
XCTAssertEqualObjects(walker.currentNode, document.documentElement.firstChild);
walker.currentNode = document.documentElement;
XCTAssertEqualObjects(walker.lastChild, document.documentElement.lastChild);
XCTAssertEqualObjects(walker.currentNode, document.documentElement.lastChild);
walker.currentNode = document.documentElement;
XCTAssertNil(walker.nextSibling);
XCTAssertEqualObjects(walker.currentNode, document.documentElement);
walker.currentNode = document.documentElement;
XCTAssertNil(walker.previousSibling);
XCTAssertEqualObjects(walker.currentNode, document.documentElement);
}
#pragma mark - Filter
- (HTMLElement *)filterBasicDOM
{
HTMLElement *root = [[HTMLElement alloc] initWithTagName:@"div" attributes:@{@"id": @"root"}];
HTMLElement *a1 = [[HTMLElement alloc] initWithTagName:@"div" attributes:@{@"id": @"A1"}];
HTMLElement *b1 = [[HTMLElement alloc] initWithTagName:@"div" attributes:@{@"id": @"B1"}];
HTMLElement *b2 = [[HTMLElement alloc] initWithTagName:@"div" attributes:@{@"id": @"B2"}];
[root appendNode:a1];
[a1 appendNode:b1];
[a1 appendNode:b2];
return root;
}
- (void)testTreeWalkerNilFilter
{
HTMLElement *root = self.filterBasicDOM;
HTMLTreeWalker *walker = [[HTMLTreeWalker alloc] initWithNode:root
showOptions:HTMLNodeFilterShowElement
filter:nil];
AssertElementWithId(walker.currentNode, @"root");
AssertElementWithId(walker.firstChild, @"A1");
AssertElementWithId(walker.currentNode, @"A1");
AssertElementWithId(walker.nextNode, @"B1");
AssertElementWithId(walker.currentNode, @"B1");
}
- (void)testTreeWalkerWithFilter
{
HTMLElement *root = self.filterBasicDOM;
id
filter = [HTMLNodeFilterBlock filterWithBlock:^HTMLNodeFilterValue(HTMLNode *node) {
if ([node.asElement[@"id"] isEqualToString:@"B1"]) {
return HTMLNodeFilterSkip;
}
return HTMLNodeFilterAccept;
}];
HTMLTreeWalker *walker = [[HTMLTreeWalker alloc] initWithNode:root
showOptions:HTMLNodeFilterShowElement
filter:filter];
AssertElementWithId(walker.currentNode, @"root");
AssertElementWithId(walker.firstChild, @"A1");
AssertElementWithId(walker.currentNode, @"A1");
AssertElementWithId(walker.nextNode, @"B2");
AssertElementWithId(walker.currentNode, @"B2");
}
#pragma mark - Filter Skip
- (HTMLElement *)filterDOM
{
HTMLElement *root = [[HTMLElement alloc] initWithTagName:@"div" attributes:@{@"id": @"root"}];
HTMLElement *a1 = [[HTMLElement alloc] initWithTagName:@"div" attributes:@{@"id": @"A1"}];
HTMLElement *b1 = [[HTMLElement alloc] initWithTagName:@"div" attributes:@{@"id": @"B1"}];
HTMLElement *b2 = [[HTMLElement alloc] initWithTagName:@"div" attributes:@{@"id": @"B2"}];
HTMLElement *b3 = [[HTMLElement alloc] initWithTagName:@"div" attributes:@{@"id": @"B3"}];
HTMLElement *c1 = [[HTMLElement alloc] initWithTagName:@"div" attributes:@{@"id": @"C1"}];
[root appendNode:a1];
[a1 appendNode:b1];
[a1 appendNode:b2];
[a1 appendNode:b3];
[b1 appendNode:c1];
return root;
}
- (id)skipB1Filter
{
id filter = [HTMLNodeFilterBlock filterWithBlock:^HTMLNodeFilterValue(HTMLNode *node) {
if ([node.asElement[@"id"] isEqualToString:@"B1"]) {
return HTMLNodeFilterSkip;
}
return HTMLNodeFilterAccept;
}];
return filter;
}
- (id)skipB2Filter
{
id filter = [HTMLNodeFilterBlock filterWithBlock:^HTMLNodeFilterValue(HTMLNode *node) {
if ([node.asElement[@"id"] isEqualToString:@"B2"]) {
return HTMLNodeFilterSkip;
}
return HTMLNodeFilterAccept;
}];
return filter;
}
- (id)rejectB1Filter
{
id filter = [HTMLNodeFilterBlock filterWithBlock:^HTMLNodeFilterValue(HTMLNode *node) {
if ([node.asElement[@"id"] isEqualToString:@"B1"]) {
return HTMLNodeFilterReject;
}
return HTMLNodeFilterAccept;
}];
return filter;
}
- (id)rejectB2Filter
{
id filter = [HTMLNodeFilterBlock filterWithBlock:^HTMLNodeFilterValue(HTMLNode *node) {
if ([node.asElement[@"id"] isEqualToString:@"B2"]) {
return HTMLNodeFilterReject;
}
return HTMLNodeFilterAccept;
}];
return filter;
}
static HTMLElement * (^ FindElementById)(HTMLNode *, NSString *) = ^ HTMLElement * (HTMLNode *root, NSString *id) {
for (HTMLNode *node in [root nodeIteratorWithShowOptions:HTMLNodeFilterShowElement filter:nil]) {
if ([node.asElement[@"id"] isEqualToString:id]) {
return node.asElement;
}
}
return nil;
};
- (void)testThatFilterSkipsNextNode
{
HTMLElement *root = self.filterDOM;
id filter = self.skipB1Filter;
HTMLTreeWalker *walker = [[HTMLTreeWalker alloc] initWithNode:root
showOptions:HTMLNodeFilterShowElement
filter:filter];
AssertElementWithId(walker.nextNode, @"A1");
AssertElementWithId(walker.nextNode, @"C1");
AssertElementWithId(walker.nextNode, @"B2");
AssertElementWithId(walker.nextNode, @"B3");
}
- (void)testThatFilterSkipsFirstChild
{
HTMLElement *root = self.filterDOM;
id filter = self.skipB1Filter;
HTMLTreeWalker *walker = [[HTMLTreeWalker alloc] initWithNode:root
showOptions:HTMLNodeFilterShowElement
filter:filter];
AssertElementWithId(walker.firstChild, @"A1");
AssertElementWithId(walker.firstChild, @"C1");
}
- (void)testThatFilterSkipsNextSibling
{
HTMLElement *root = self.filterDOM;
id filter = self.skipB2Filter;
HTMLTreeWalker *walker = [[HTMLTreeWalker alloc] initWithNode:root
showOptions:HTMLNodeFilterShowElement
filter:filter];
AssertElementWithId(walker.firstChild, @"A1");
AssertElementWithId(walker.firstChild, @"B1");
AssertElementWithId(walker.nextSibling, @"B3");
}
- (void)testThatFilterSkipsParentNode
{
HTMLElement *root = self.filterDOM;
id filter = self.skipB1Filter;
HTMLTreeWalker *walker = [[HTMLTreeWalker alloc] initWithNode:root
showOptions:HTMLNodeFilterShowElement
filter:filter];
walker.currentNode = FindElementById(root, @"C1");
AssertElementWithId(walker.parentNode, @"A1");
}
- (void)testThatFilterSkipsPreviousSibling
{
HTMLElement *root = self.filterDOM;
id filter = self.skipB2Filter;
HTMLTreeWalker *walker = [[HTMLTreeWalker alloc] initWithNode:root
showOptions:HTMLNodeFilterShowElement
filter:filter];
walker.currentNode = FindElementById(root, @"B3");
AssertElementWithId(walker.previousSibling, @"B1");
}
- (void)testThatFilterSkipsPreviousNode
{
HTMLElement *root = self.filterDOM;
id filter = self.skipB1Filter;
HTMLTreeWalker *walker = [[HTMLTreeWalker alloc] initWithNode:root
showOptions:HTMLNodeFilterShowElement
filter:filter];
walker.currentNode = FindElementById(root, @"B3");
AssertElementWithId(walker.previousNode, @"B2");
AssertElementWithId(walker.previousNode, @"C1");
AssertElementWithId(walker.previousNode, @"A1");
}
#pragma mark - Filter Reject
- (void)testThatFilterRejectsNextNode
{
HTMLElement *root = self.filterDOM;
id filter = self.rejectB1Filter;
HTMLTreeWalker *walker = [[HTMLTreeWalker alloc] initWithNode:root
showOptions:HTMLNodeFilterShowElement
filter:filter];
AssertElementWithId(walker.nextNode, @"A1");
AssertElementWithId(walker.nextNode, @"B2");
AssertElementWithId(walker.nextNode, @"B3");
}
- (void)testThatFilterRejectsFirstChild
{
HTMLElement *root = self.filterDOM;
id filter = self.rejectB1Filter;
HTMLTreeWalker *walker = [[HTMLTreeWalker alloc] initWithNode:root
showOptions:HTMLNodeFilterShowElement
filter:filter];
AssertElementWithId(walker.firstChild, @"A1");
AssertElementWithId(walker.firstChild, @"B2");
}
- (void)testThatFilterRejectsNextSibling
{
HTMLElement *root = self.filterDOM;
id filter = self.rejectB2Filter;
HTMLTreeWalker *walker = [[HTMLTreeWalker alloc] initWithNode:root
showOptions:HTMLNodeFilterShowElement
filter:filter];
AssertElementWithId(walker.firstChild, @"A1");
AssertElementWithId(walker.firstChild, @"B1");
AssertElementWithId(walker.nextSibling, @"B3");
}
- (void)testThatFilterRejectsParentNode
{
HTMLElement *root = self.filterDOM;
id filter = self.rejectB1Filter;
HTMLTreeWalker *walker = [[HTMLTreeWalker alloc] initWithNode:root
showOptions:HTMLNodeFilterShowElement
filter:filter];
walker.currentNode = FindElementById(root, @"C1");
AssertElementWithId(walker.parentNode, @"A1");
}
- (void)testThatFilterRejectsPreviousSibling
{
HTMLElement *root = self.filterDOM;
id filter = self.rejectB2Filter;
HTMLTreeWalker *walker = [[HTMLTreeWalker alloc] initWithNode:root
showOptions:HTMLNodeFilterShowElement
filter:filter];
walker.currentNode = FindElementById(root, @"B3");
AssertElementWithId(walker.previousSibling, @"B1");
}
- (void)testThatFilterRejectsPreviousNode
{
HTMLElement *root = self.filterDOM;
id filter = self.rejectB1Filter;
HTMLTreeWalker *walker = [[HTMLTreeWalker alloc] initWithNode:root
showOptions:HTMLNodeFilterShowElement
filter:filter];
walker.currentNode = FindElementById(root, @"B3");
AssertElementWithId(walker.previousNode, @"B2");
AssertElementWithId(walker.previousNode, @"A1");
}
@end