diff --git a/HTMLKit.xcodeproj/project.pbxproj b/HTMLKit.xcodeproj/project.pbxproj index 331e6d4..0770a06 100644 --- a/HTMLKit.xcodeproj/project.pbxproj +++ b/HTMLKit.xcodeproj/project.pbxproj @@ -179,6 +179,8 @@ 62F501651BC9576B0069F47B /* CSSNthExpressionParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 62F501631BC9576B0069F47B /* CSSNthExpressionParser.h */; settings = {ASSET_TAGS = (); }; }; 62F501661BC9576B0069F47B /* CSSNthExpressionParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 62F501641BC9576B0069F47B /* CSSNthExpressionParser.m */; settings = {ASSET_TAGS = (); }; }; 62F501671BC9576B0069F47B /* CSSNthExpressionParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 62F501641BC9576B0069F47B /* CSSNthExpressionParser.m */; settings = {ASSET_TAGS = (); }; }; + 62F658701BD83C8E0045F137 /* CSSNThExpressionSelectorTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 62F6586F1BD83C8E0045F137 /* CSSNThExpressionSelectorTests.m */; settings = {ASSET_TAGS = (); }; }; + 62F658711BD83C8E0045F137 /* CSSNThExpressionSelectorTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 62F6586F1BD83C8E0045F137 /* CSSNThExpressionSelectorTests.m */; settings = {ASSET_TAGS = (); }; }; 62F873EB19E088C90062683C /* HTMLParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 62F873E919E088C90062683C /* HTMLParser.h */; }; 62F873EC19E088C90062683C /* HTMLParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 62F873EA19E088C90062683C /* HTMLParser.m */; }; 62F873ED19E088C90062683C /* HTMLParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 62F873EA19E088C90062683C /* HTMLParser.m */; }; @@ -350,6 +352,7 @@ 62F31FDC19E9DCCF007F0657 /* HTMLTokenizerEntities.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HTMLTokenizerEntities.m; sourceTree = ""; }; 62F501631BC9576B0069F47B /* CSSNthExpressionParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSSNthExpressionParser.h; sourceTree = ""; }; 62F501641BC9576B0069F47B /* CSSNthExpressionParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSNthExpressionParser.m; sourceTree = ""; }; + 62F6586F1BD83C8E0045F137 /* CSSNThExpressionSelectorTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSNThExpressionSelectorTests.m; sourceTree = ""; }; 62F873E919E088C90062683C /* HTMLParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTMLParser.h; sourceTree = ""; }; 62F873EA19E088C90062683C /* HTMLParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HTMLParser.m; sourceTree = ""; }; 62FA98031BD57B6200A2AF86 /* CSSSelectors.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CSSSelectors.m; sourceTree = ""; }; @@ -598,6 +601,7 @@ 624AB3161B0508AE00F3830D /* CSSTypeSelectorTests.m */, 624AB3191B050A4D00F3830D /* CSSAttributeSelectorTests.m */, 628AF62E1BC99A6C00496128 /* CSSNthExpressionsParserTests.m */, + 62F6586F1BD83C8E0045F137 /* CSSNThExpressionSelectorTests.m */, ); name = Tests; path = HTMLKitTests; @@ -941,6 +945,7 @@ buildActionMask = 2147483647; files = ( 6239755B1AC362CA007E26F1 /* HTMLKitTreeConstructionTests.m in Sources */, + 62F658711BD83C8E0045F137 /* CSSNThExpressionSelectorTests.m in Sources */, 623CAF9E1AD88BEA00E34C32 /* HTMLKitParserPerformance.m in Sources */, 6247171D1B2240B800C11912 /* HTMLTreeWalkerTests.m in Sources */, 62EC7AE71AEEAC6F0015D3BE /* HTMLKitMutationAlgorithmsTests.m in Sources */, @@ -1014,6 +1019,7 @@ buildActionMask = 2147483647; files = ( 6239755A1AC362CA007E26F1 /* HTMLKitTreeConstructionTests.m in Sources */, + 62F658701BD83C8E0045F137 /* CSSNThExpressionSelectorTests.m in Sources */, 623CAF9D1AD88BEA00E34C32 /* HTMLKitParserPerformance.m in Sources */, 6247171C1B2240B800C11912 /* HTMLTreeWalkerTests.m in Sources */, 62EC7AE61AEEAC6F0015D3BE /* HTMLKitMutationAlgorithmsTests.m in Sources */, diff --git a/HTMLKitTests/CSSNThExpressionSelectorTests.m b/HTMLKitTests/CSSNThExpressionSelectorTests.m new file mode 100644 index 0000000..b107eeb --- /dev/null +++ b/HTMLKitTests/CSSNThExpressionSelectorTests.m @@ -0,0 +1,352 @@ +// +// CSSNThExpressionSelectorTests.m +// HTMLKit +// +// Created by Iska on 21/10/15. +// Copyright © 2015 BrainCookie. All rights reserved. +// + +#import +#import "CSSSelectors.h" +#import "HTMLParser.h" +#import "HTMLDOM.h" + +@interface CSSNThExpressionSelectorTests : XCTestCase +{ + HTMLDocument *_childTree; + HTMLDocument *_typeTree; +} +@end + +@implementation CSSNThExpressionSelectorTests + +- (void)setUp +{ + [super setUp]; + + /* + |
+ | + | + | + | + | + |
11
12
13
14
+ |
+ |
+ | + | + |
21
+ |
+ |
+ | + | + | + | + | + | + | + |
31
32
33
34
35
36
+ |
+ */ + _childTree = [[[HTMLParser alloc] initWithString:@"
" + "" + "" + "" + "" + "
11
12
13
14
" + "
" + "" + "
21
" + "
" + "" + "" + "" + "" + "" + "" + "
31
32
33
34
35
36
"] document]; + + /* + |
+ | s11 + | s12 + | s13 + | b1 + |
+ |
+ | b2 + | s21 + | s22 + | s23 + |
+ |
+ | s31 + | b3 + | s32 + | b4 + | s33 + | b5 + | s34 + |
+ */ + _typeTree = [[[HTMLParser alloc] initWithString:@"
" + "s11" + "s12" + "s13" + "b1" + "
" + "
" + "b2" + "s21" + "s22" + "s23" + "
" + "
" + "s31" + "b3" + "s32" + "b4" + "s33" + "b5" + "s34" + "
"] document]; +} + +- (void)testOddSelector +{ + NSArray *elements = [_childTree elementsMatchingSelector:allOf(@[typeSelector(@"tr"), oddSelector()])]; + NSArray *expected = @[@"11", @"13", @"21", @"31", @"33", @"35"]; + XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected); +} + +- (void)testEvenSelector +{ + NSArray *elements = [_childTree elementsMatchingSelector:allOf(@[typeSelector(@"tr"), evenSlector()])]; + NSArray *expected = @[@"12", @"14", @"32", @"34", @"36"]; + XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected); +} + +- (void)testFirstChildSelector +{ + NSArray *elements = [_childTree elementsMatchingSelector:allOf(@[typeSelector(@"tr"), firstChildSelector()])]; + NSArray *expected = @[@"11", @"21", @"31"]; + XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected); +} + +- (void)testLastChildSelector +{ + NSArray *elements = [_childTree elementsMatchingSelector:allOf(@[typeSelector(@"tr"), lastChildSelector()])]; + NSArray *expected = @[@"14", @"21", @"36"]; + XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected); +} + +- (void)testFirstOfTypeSelector +{ + NSArray *elements = [_typeTree elementsMatchingSelector:allOf(@[typeSelector(@"span"), firstOfTypeSelector()])]; + NSArray *expected = @[@"s11", @"s21", @"s31"]; + XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected); +} + +- (void)testLastOfTypeSelector +{ + NSArray *elements = [_typeTree elementsMatchingSelector:allOf(@[typeSelector(@"span"), lastOfTypeSelector()])]; + NSArray *expected = @[@"s13", @"s23", @"s34"]; + XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected); +} + +- (void)testOnlyChildSelector +{ + NSArray *elements = [_childTree elementsMatchingSelector:allOf(@[typeSelector(@"tr"), onlyChildSelector()])]; + NSArray *expected = @[@"21"]; + XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected); +} + +- (void)testOnlyOfTypeSelector +{ + NSArray *elements = [_typeTree elementsMatchingSelector:allOf(@[typeSelector(@"tr"), onlyOfTypeSelector()])]; + NSArray *expected = @[]; + XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected); + + elements = [_typeTree elementsMatchingSelector:allOf(@[typeSelector(@"span"), onlyOfTypeSelector()])]; + expected = @[]; + XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected); + + elements = [_typeTree elementsMatchingSelector:allOf(@[typeSelector(@"b"), onlyOfTypeSelector()])]; + expected = @[@"b1", @"b2"]; + XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected); +} + +#pragma mark - Nth-Child Selector + +- (void)test_NthChild_B_Selector +{ + NSArray *elements = [_childTree elementsMatchingSelector:allOf(@[typeSelector(@"tr"), nthChildSelector(CSSNthExpressionMake(0, 1))])]; + NSArray *expected = @[@"11", @"21", @"31"]; + XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected); + + elements = [_childTree elementsMatchingSelector:allOf(@[typeSelector(@"tr"), nthChildSelector(CSSNthExpressionMake(0, 2))])]; + expected = @[@"12", @"32"]; + XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected); + + elements = [_childTree elementsMatchingSelector:allOf(@[typeSelector(@"tr"), nthChildSelector(CSSNthExpressionMake(0, 3))])]; + expected = @[@"13", @"33"]; + XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected); +} + +- (void)test_NthChild_An_Selector +{ + NSArray *elements = [_childTree elementsMatchingSelector:allOf(@[typeSelector(@"tr"), nthChildSelector(CSSNthExpressionMake(2, 0))])]; + NSArray *expected = @[@"12", @"14", @"32", @"34", @"36"]; + XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected); + + elements = [_childTree elementsMatchingSelector:allOf(@[typeSelector(@"tr"), nthChildSelector(CSSNthExpressionMake(3, 0))])]; + expected = @[@"13", @"33", @"36"]; + XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected); + + elements = [_childTree elementsMatchingSelector:allOf(@[typeSelector(@"tr"), nthChildSelector(CSSNthExpressionMake(4, 0))])]; + expected = @[@"14", @"34"]; + XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected); +} + +- (void)test_NthChild_An_B_Selector +{ + NSArray *elements = [_childTree elementsMatchingSelector:allOf(@[typeSelector(@"tr"), nthChildSelector(CSSNthExpressionMake(3, 1))])]; + NSArray *expected = @[@"11", @"14", @"21", @"31", @"34"]; + XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected); + + elements = [_childTree elementsMatchingSelector:allOf(@[typeSelector(@"tr"), nthChildSelector(CSSNthExpressionMake(3, 2))])]; + expected = @[@"12", @"32", @"35"]; + XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected); +} + +#pragma mark - Nth-Last-Child Selector + +- (void)test_NthLastChild_B_Selector +{ + NSArray *elements = [_childTree elementsMatchingSelector:allOf(@[typeSelector(@"tr"), nthLastChildSelector(CSSNthExpressionMake(0, 1))])]; + NSArray *expected = @[@"14", @"21", @"36"]; + XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected); + + elements = [_childTree elementsMatchingSelector:allOf(@[typeSelector(@"tr"), nthLastChildSelector(CSSNthExpressionMake(0, 2))])]; + expected = @[@"13", @"35"]; + XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected); + + elements = [_childTree elementsMatchingSelector:allOf(@[typeSelector(@"tr"), nthLastChildSelector(CSSNthExpressionMake(0, 3))])]; + expected = @[@"12", @"34"]; + XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected); +} + +- (void)test_NthLastChild_An_Selector +{ + NSArray *elements = [_childTree elementsMatchingSelector:allOf(@[typeSelector(@"tr"), nthLastChildSelector(CSSNthExpressionMake(2, 0))])]; + NSArray *expected = @[@"11", @"13", @"31", @"33", @"35"]; + XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected); + + elements = [_childTree elementsMatchingSelector:allOf(@[typeSelector(@"tr"), nthLastChildSelector(CSSNthExpressionMake(3, 0))])]; + expected = @[@"12", @"31", @"34"]; + XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected); + + elements = [_childTree elementsMatchingSelector:allOf(@[typeSelector(@"tr"), nthLastChildSelector(CSSNthExpressionMake(4, 0))])]; + expected = @[@"11", @"33"]; + XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected); +} + +- (void)test_NthLastChild_An_B_Selector +{ + NSArray *elements = [_childTree elementsMatchingSelector:allOf(@[typeSelector(@"tr"), nthLastChildSelector(CSSNthExpressionMake(3, 1))])]; + NSArray *expected = @[@"11", @"14", @"21", @"33", @"36"]; + XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected); + + elements = [_childTree elementsMatchingSelector:allOf(@[typeSelector(@"tr"), nthLastChildSelector(CSSNthExpressionMake(3, 2))])]; + expected = @[@"13", @"32", @"35"]; + XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected); +} + +#pragma mark - Nth-Of-Type Selector + +- (void)test_NthOfType_B_Selector +{ + NSArray *elements = [_typeTree elementsMatchingSelector:allOf(@[typeSelector(@"span"), nthOfTypeSelector(CSSNthExpressionMake(0, 1))])]; + NSArray *expected = @[@"s11", @"s21", @"s31"]; + XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected); + + elements = [_typeTree elementsMatchingSelector:allOf(@[typeSelector(@"span"), nthOfTypeSelector(CSSNthExpressionMake(0, 2))])]; + expected = @[@"s12", @"s22", @"s32"]; + XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected); + + elements = [_typeTree elementsMatchingSelector:allOf(@[typeSelector(@"span"), nthOfTypeSelector(CSSNthExpressionMake(0, 3))])]; + expected = @[@"s13", @"s23", @"s33"]; + XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected); +} + +- (void)test_NthOfType_An_Selector +{ + NSArray *elements = [_typeTree elementsMatchingSelector:allOf(@[typeSelector(@"span"), nthOfTypeSelector(CSSNthExpressionMake(2, 0))])]; + NSArray *expected = @[@"s12", @"s22", @"s32", @"s34"]; + XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected); + + elements = [_typeTree elementsMatchingSelector:allOf(@[typeSelector(@"span"), nthOfTypeSelector(CSSNthExpressionMake(3, 0))])]; + expected = @[@"s13", @"s23", @"s33"]; + XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected); + + elements = [_typeTree elementsMatchingSelector:allOf(@[typeSelector(@"span"), nthOfTypeSelector(CSSNthExpressionMake(4, 0))])]; + expected = @[@"s34"]; + XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected); +} + +- (void)test_NthOfType_An_B_Selector +{ + NSArray *elements = [_typeTree elementsMatchingSelector:allOf(@[typeSelector(@"span"), nthOfTypeSelector(CSSNthExpressionMake(2, 1))])]; + NSArray *expected = @[@"s11", @"s13", @"s21", @"s23", @"s31", @"s33"]; + XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected); + + elements = [_typeTree elementsMatchingSelector:allOf(@[typeSelector(@"span"), nthOfTypeSelector(CSSNthExpressionMake(2, 2))])]; + expected = @[@"s12", @"s22", @"s32", @"s34"]; + XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected); +} + +#pragma mark - Nth-Last-Of-Type Selector + +- (void)test_NthLastOfType_B_Selector +{ + NSArray *elements = [_typeTree elementsMatchingSelector:allOf(@[typeSelector(@"span"), nthLastOfTypeSelector(CSSNthExpressionMake(0, 1))])]; + NSArray *expected = @[@"s13", @"s23", @"s34"]; + XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected); + + elements = [_typeTree elementsMatchingSelector:allOf(@[typeSelector(@"span"), nthLastOfTypeSelector(CSSNthExpressionMake(0, 2))])]; + expected = @[@"s12", @"s22", @"s33"]; + XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected); + + elements = [_typeTree elementsMatchingSelector:allOf(@[typeSelector(@"span"), nthLastOfTypeSelector(CSSNthExpressionMake(0, 3))])]; + expected = @[@"s11", @"s21", @"s32"]; + XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected); +} + +- (void)test_NthLastOfType_An_Selector +{ + NSArray *elements = [_typeTree elementsMatchingSelector:allOf(@[typeSelector(@"span"), nthLastOfTypeSelector(CSSNthExpressionMake(2, 0))])]; + NSArray *expected = @[@"s12", @"s22", @"s31", @"s33"]; + XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected); + + elements = [_typeTree elementsMatchingSelector:allOf(@[typeSelector(@"span"), nthLastOfTypeSelector(CSSNthExpressionMake(3, 0))])]; + expected = @[@"s11", @"s21", @"s32"]; + XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected); + + elements = [_typeTree elementsMatchingSelector:allOf(@[typeSelector(@"span"), nthLastOfTypeSelector(CSSNthExpressionMake(4, 0))])]; + expected = @[@"s31"]; + XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected); +} + +- (void)test_NthLastOfType_An_B_Selector +{ + NSArray *elements = [_typeTree elementsMatchingSelector:allOf(@[typeSelector(@"span"), nthLastOfTypeSelector(CSSNthExpressionMake(2, 1))])]; + NSArray *expected = @[@"s11", @"s13", @"s21", @"s23", @"s32", @"s34"]; + XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected); + + elements = [_typeTree elementsMatchingSelector:allOf(@[typeSelector(@"span"), nthLastOfTypeSelector(CSSNthExpressionMake(2, 2))])]; + expected = @[@"s12", @"s22", @"s31", @"s33"]; + XCTAssertEqualObjects([elements valueForKeyPath:@"attributes.id"], expected); +} + +@end