Add generic HTML5LibTest class for performing HTML5lib tests
https://github.com/html5lib/html5lib-tests
This commit is contained in:
@@ -13,6 +13,9 @@
|
||||
624493AC19CD0CBE00BCDDF4 /* HTMLToken.h in Headers */ = {isa = PBXBuildFile; fileRef = 624493AA19CD0CBE00BCDDF4 /* HTMLToken.h */; };
|
||||
624493AD19CD0CBE00BCDDF4 /* HTMLToken.m in Sources */ = {isa = PBXBuildFile; fileRef = 624493AB19CD0CBE00BCDDF4 /* HTMLToken.m */; };
|
||||
624493AE19CD0CBE00BCDDF4 /* HTMLToken.m in Sources */ = {isa = PBXBuildFile; fileRef = 624493AB19CD0CBE00BCDDF4 /* HTMLToken.m */; };
|
||||
624AC8FF19FBF59800BD3C4A /* HTMLTokens.h in Headers */ = {isa = PBXBuildFile; fileRef = 624AC8FE19FBF4F700BD3C4A /* HTMLTokens.h */; };
|
||||
624AC90119FBF9ED00BD3C4A /* HTMLTokenizerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 624AC90019FBF9ED00BD3C4A /* HTMLTokenizerTests.m */; };
|
||||
624AC90219FBF9ED00BD3C4A /* HTMLTokenizerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 624AC90019FBF9ED00BD3C4A /* HTMLTokenizerTests.m */; };
|
||||
625A14B019C7829400AD0C32 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 625A14AF19C7829400AD0C32 /* Cocoa.framework */; };
|
||||
625A14BA19C7829400AD0C32 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 625A14B819C7829400AD0C32 /* InfoPlist.strings */; };
|
||||
625A14BE19C7829400AD0C32 /* HTMLKit.m in Sources */ = {isa = PBXBuildFile; fileRef = 625A14BD19C7829400AD0C32 /* HTMLKit.m */; };
|
||||
@@ -56,6 +59,8 @@
|
||||
62AE594E19F9A17A0043F069 /* HTMLEOFToken.h in Headers */ = {isa = PBXBuildFile; fileRef = 62AE594C19F9A17A0043F069 /* HTMLEOFToken.h */; };
|
||||
62AE594F19F9A17A0043F069 /* HTMLEOFToken.m in Sources */ = {isa = PBXBuildFile; fileRef = 62AE594D19F9A17A0043F069 /* HTMLEOFToken.m */; };
|
||||
62AE595019F9A17A0043F069 /* HTMLEOFToken.m in Sources */ = {isa = PBXBuildFile; fileRef = 62AE594D19F9A17A0043F069 /* HTMLEOFToken.m */; };
|
||||
62D8345919FB1AC4009205A9 /* HTML5LibTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 62D8345819FB1AC4009205A9 /* HTML5LibTest.m */; };
|
||||
62D8345A19FB1AC4009205A9 /* HTML5LibTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 62D8345819FB1AC4009205A9 /* HTML5LibTest.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 */; };
|
||||
@@ -100,6 +105,8 @@
|
||||
624493A919CCE84A00BCDDF4 /* HTMLTokenizerStates.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HTMLTokenizerStates.h; sourceTree = "<group>"; };
|
||||
624493AA19CD0CBE00BCDDF4 /* HTMLToken.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTMLToken.h; sourceTree = "<group>"; };
|
||||
624493AB19CD0CBE00BCDDF4 /* HTMLToken.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HTMLToken.m; sourceTree = "<group>"; };
|
||||
624AC8FE19FBF4F700BD3C4A /* HTMLTokens.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HTMLTokens.h; sourceTree = "<group>"; };
|
||||
624AC90019FBF9ED00BD3C4A /* HTMLTokenizerTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HTMLTokenizerTests.m; sourceTree = "<group>"; };
|
||||
625A14AC19C7829400AD0C32 /* HTMLKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = HTMLKit.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
625A14AF19C7829400AD0C32 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; };
|
||||
625A14B219C7829400AD0C32 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
|
||||
@@ -137,6 +144,8 @@
|
||||
62AE594819F9948A0043F069 /* HTMLCharacterToken.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HTMLCharacterToken.m; sourceTree = "<group>"; };
|
||||
62AE594C19F9A17A0043F069 /* HTMLEOFToken.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTMLEOFToken.h; sourceTree = "<group>"; };
|
||||
62AE594D19F9A17A0043F069 /* HTMLEOFToken.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HTMLEOFToken.m; sourceTree = "<group>"; };
|
||||
62D8345719FB1AC4009205A9 /* HTML5LibTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTML5LibTest.h; sourceTree = "<group>"; };
|
||||
62D8345819FB1AC4009205A9 /* HTML5LibTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HTML5LibTest.m; sourceTree = "<group>"; };
|
||||
62E7CAAE19CDFFB500465A83 /* HTMLTokenizerCharacters.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HTMLTokenizerCharacters.h; sourceTree = "<group>"; };
|
||||
62F31FDB19E9DCCF007F0657 /* HTMLTokenizerEntities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTMLTokenizerEntities.h; sourceTree = "<group>"; };
|
||||
62F31FDC19E9DCCF007F0657 /* HTMLTokenizerEntities.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HTMLTokenizerEntities.m; sourceTree = "<group>"; };
|
||||
@@ -256,6 +265,9 @@
|
||||
625A14CA19C7829400AD0C32 /* Tests */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
62D8345719FB1AC4009205A9 /* HTML5LibTest.h */,
|
||||
62D8345819FB1AC4009205A9 /* HTML5LibTest.m */,
|
||||
624AC90019FBF9ED00BD3C4A /* HTMLTokenizerTests.m */,
|
||||
625A14D019C7829400AD0C32 /* HTMLKitTests.m */,
|
||||
625A14CB19C7829400AD0C32 /* Supporting Files */,
|
||||
);
|
||||
@@ -285,6 +297,7 @@
|
||||
62E7CAAE19CDFFB500465A83 /* HTMLTokenizerCharacters.h */,
|
||||
62F31FDB19E9DCCF007F0657 /* HTMLTokenizerEntities.h */,
|
||||
62F31FDC19E9DCCF007F0657 /* HTMLTokenizerEntities.m */,
|
||||
624AC8FE19FBF4F700BD3C4A /* HTMLTokens.h */,
|
||||
624493AA19CD0CBE00BCDDF4 /* HTMLToken.h */,
|
||||
624493AB19CD0CBE00BCDDF4 /* HTMLToken.m */,
|
||||
62AE594719F9948A0043F069 /* HTMLCharacterToken.h */,
|
||||
@@ -311,6 +324,7 @@
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
62F873EB19E088C90062683C /* HTMLParser.h in Headers */,
|
||||
624AC8FF19FBF59800BD3C4A /* HTMLTokens.h in Headers */,
|
||||
62AE594419F992F30043F069 /* HTMLCommentToken.h in Headers */,
|
||||
62AE594E19F9A17A0043F069 /* HTMLEOFToken.h in Headers */,
|
||||
624493AC19CD0CBE00BCDDF4 /* HTMLToken.h in Headers */,
|
||||
@@ -490,6 +504,8 @@
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
624AC90219FBF9ED00BD3C4A /* HTMLTokenizerTests.m in Sources */,
|
||||
62D8345A19FB1AC4009205A9 /* HTML5LibTest.m in Sources */,
|
||||
625A14D119C7829400AD0C32 /* HTMLKitTests.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
@@ -519,6 +535,8 @@
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
624AC90119FBF9ED00BD3C4A /* HTMLTokenizerTests.m in Sources */,
|
||||
62D8345919FB1AC4009205A9 /* HTML5LibTest.m in Sources */,
|
||||
625A150519C783FD00AD0C32 /* HTMLKitTests.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
//
|
||||
// HTMLTokens.h
|
||||
// HTMLKit
|
||||
//
|
||||
// Created by Iska on 25/10/14.
|
||||
// Copyright (c) 2014 BrainCookie. All rights reserved.
|
||||
//
|
||||
|
||||
#import "HTMLToken.h"
|
||||
#import "HTMLCharacterToken.h"
|
||||
#import "HTMLCommentToken.h"
|
||||
#import "HTMLDOCTYPEToken.h"
|
||||
#import "HTMLEOFToken.h"
|
||||
#import "HTMLParseErrorToken.h"
|
||||
#import "HTMLTagToken.h"
|
||||
@@ -0,0 +1,22 @@
|
||||
//
|
||||
// HTML5LibTest.h
|
||||
// HTMLKit
|
||||
//
|
||||
// Created by Iska on 25/10/14.
|
||||
// Copyright (c) 2014 BrainCookie. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface HTML5LibTest : NSObject
|
||||
|
||||
@property (nonatomic, strong) NSString *description;
|
||||
@property (nonatomic, strong) NSString *input;
|
||||
@property (nonatomic, strong) NSArray *output;
|
||||
@property (nonatomic, strong) NSArray *initialStates;
|
||||
@property (nonatomic, strong) NSString *lastStartTag;
|
||||
@property (nonatomic, assign) BOOL ignoreErrorOrder;
|
||||
|
||||
- (instancetype)initWithFixture:(NSDictionary *)fixture;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,138 @@
|
||||
//
|
||||
// HTML5LibTest.m
|
||||
// HTMLKit
|
||||
//
|
||||
// Created by Iska on 25/10/14.
|
||||
// Copyright (c) 2014 BrainCookie. All rights reserved.
|
||||
//
|
||||
|
||||
#import "HTML5LibTest.h"
|
||||
#import "HTMLTokenizerStates.h"
|
||||
#import "HTMLTokens.h"
|
||||
|
||||
@implementation HTML5LibTest
|
||||
|
||||
- (instancetype)initWithFixture:(NSDictionary *)fixture
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
[self loadFixture:fixture];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)loadFixture:(NSDictionary *)fixture
|
||||
{
|
||||
BOOL doubleEscaped = [fixture[@"doubleEscaped"] boolValue];
|
||||
|
||||
// Test Description
|
||||
self.description = fixture[@"description"];
|
||||
|
||||
// Test Input
|
||||
self.input = fixture[@"input"];
|
||||
if (doubleEscaped) {
|
||||
self.input = [self processDoubleEscaped:self.input];
|
||||
}
|
||||
|
||||
// Test Output
|
||||
NSMutableArray *tokens = [NSMutableArray array];
|
||||
NSArray *outputs = fixture[@"output"];
|
||||
for (NSArray *output in outputs) {
|
||||
HTMLToken *token = [self processOutputToken:output doubleEscaped:doubleEscaped];
|
||||
[tokens addObject:token];
|
||||
}
|
||||
self.output = tokens;
|
||||
|
||||
// Test Initial States
|
||||
NSMutableArray *initialStates = [NSMutableArray array];
|
||||
|
||||
NSArray *states = fixture[@"initialStates"];
|
||||
for (NSString *name in states) {
|
||||
HTMLTokenizerState state = HTMLTokenizerStateData;
|
||||
if ([name isEqualToString:@"PLAINTEXT state"]) {
|
||||
state = HTMLTokenizerStatePLAINTEXT;
|
||||
} else if ([name isEqualToString:@"RCDATA state"]) {
|
||||
state = HTMLTokenizerStateRCDATA;
|
||||
} else if ([name isEqualToString:@"RAWTEXT state"]) {
|
||||
state = HTMLTokenizerStateRAWTEXT;
|
||||
}
|
||||
[initialStates addObject:@(state)];
|
||||
}
|
||||
if (initialStates.count == 0) {
|
||||
[initialStates addObject:@(HTMLTokenizerStateData)];
|
||||
}
|
||||
|
||||
self.initialStates = initialStates;
|
||||
|
||||
// Test Last Start Tag
|
||||
self.lastStartTag = fixture[@"lastStartTag"];
|
||||
|
||||
// Ignore Error Order
|
||||
self.ignoreErrorOrder = [fixture[@"ignoreErrorOrder"] boolValue];
|
||||
}
|
||||
|
||||
- (HTMLToken *)processOutputToken:(NSArray *)output doubleEscaped:(BOOL)doubleEscaped
|
||||
{
|
||||
NSString *type = [output firstObject];
|
||||
|
||||
NSString *data = nil;
|
||||
if (output.count > 1) {
|
||||
NSString *data = [output lastObject];
|
||||
if (doubleEscaped) {
|
||||
data = [self processDoubleEscaped:data];
|
||||
}
|
||||
}
|
||||
|
||||
if ([type isEqualToString:@"Character"]) {
|
||||
return [[HTMLCharacterToken alloc] initWithString:data];
|
||||
} else if ([type isEqualToString:@"Comment"]) {
|
||||
return [[HTMLCommentToken alloc] initWithData:data];
|
||||
} else if ([type isEqualToString:@"DOCTYPE"]) {
|
||||
HTMLDOCTYPEToken *token = [[HTMLDOCTYPEToken alloc] initWithName:data];
|
||||
token.publicIdentifier = output[2];
|
||||
token.systemIdentifier = output[3];
|
||||
token.forceQuirks = ([output[4] boolValue] == NO);
|
||||
return token;
|
||||
} else if ([type isEqualToString:@"EndTag"]) {
|
||||
return [[HTMLEndTagToken alloc] initWithTagName:data];
|
||||
} else if ([type isEqualToString:@"ParseError"]) {
|
||||
return [HTMLParseErrorToken new];
|
||||
} else if ([type isEqualToString:@"StartTag"]) {
|
||||
HTMLStartTagToken *token = [[HTMLStartTagToken alloc] initWithTagName:data];
|
||||
NSDictionary *attributes = output[2];
|
||||
for (NSString *name in attributes) {
|
||||
NSString *value = [attributes objectForKey:name];
|
||||
[token.attributes setObject:value forKey:name];
|
||||
}
|
||||
token.selfClosing = (output.count == 4);
|
||||
return token;
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (NSString *)processDoubleEscaped:(NSString *)string
|
||||
{
|
||||
NSError *error = nil;
|
||||
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"\\\\u([0-9a-f]{4})"
|
||||
options:NSRegularExpressionCaseInsensitive
|
||||
error:&error];
|
||||
|
||||
NSArray *matches = [regex matchesInString:string options:0 range:NSMakeRange(0, string.length)];
|
||||
|
||||
for(NSTextCheckingResult *match in [matches reverseObjectEnumerator]) {
|
||||
|
||||
NSRange hexRange = [match rangeAtIndex:2];
|
||||
NSString *hexString = [string substringWithRange:hexRange];
|
||||
NSScanner *scanner = [NSScanner scannerWithString:hexString];
|
||||
unsigned int codepint;
|
||||
[scanner scanHexInt:&codepint];
|
||||
NSString *replacement = [NSString stringWithFormat:@"%C", (unichar)codepint];
|
||||
|
||||
NSRange matchRange = [match rangeAtIndex:1];
|
||||
string = [string stringByReplacingCharactersInRange:matchRange withString:replacement];
|
||||
}
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -7,6 +7,7 @@
|
||||
//
|
||||
|
||||
#import <XCTest/XCTest.h>
|
||||
#import "HTMLTokenizer.h"
|
||||
|
||||
@interface HTMLKitTests : XCTestCase
|
||||
|
||||
@@ -31,4 +32,41 @@
|
||||
XCTFail(@"No implementation for \"%s\"", __PRETTY_FUNCTION__);
|
||||
}
|
||||
|
||||
- (void)testX
|
||||
{
|
||||
NSString *s = @"<!doctype html>\n\n<html lang=\"en\">\n<head>\n <meta charset=\"utf-8\">\n\n <title>The HTML5 Herald</title>\n <meta name=\"description\" content=\"The HTML5 Herald\">\n <meta name=\"author\" content=\"SitePoint\">\n\n <link rel=\"stylesheet\" href=\"css/styles.css?v=1.0\">\n\n <!--[if lt IE 9]>\n <script src=\"http://html5shiv.googlecode.com/svn/trunk/html5.js\"></script>\n <![endif]-->\n</head>\n\n<body>\n <script src=\"js/scripts.js\"></script>\n</body>\n</html>";
|
||||
|
||||
HTMLTokenizer *t = [[HTMLTokenizer alloc] initWithString:s];
|
||||
|
||||
HTMLToken *token = nil;
|
||||
do {
|
||||
token = [t nextToken];
|
||||
NSLog(@"%@", token);
|
||||
} while (token !=nil && ![token isEOFToken]);
|
||||
}
|
||||
|
||||
- (void)testY
|
||||
{
|
||||
NSString *string = @"\\u003Efoo\\uFEFFbar";
|
||||
|
||||
NSError *error = nil;
|
||||
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"(\\\\u([0-9a-f]{4}))"
|
||||
options:NSRegularExpressionCaseInsensitive
|
||||
error:&error];
|
||||
|
||||
NSArray *matches = [regex matchesInString:string options:0 range:NSMakeRange(0, string.length)];
|
||||
|
||||
for(NSTextCheckingResult *match in [matches reverseObjectEnumerator]) {
|
||||
NSRange matchRange = [match rangeAtIndex:1];
|
||||
NSRange hexRange = [match rangeAtIndex:2];
|
||||
NSString *hexString = [string substringWithRange:hexRange];
|
||||
NSScanner *scanner = [NSScanner scannerWithString:hexString];
|
||||
unsigned int codepint;
|
||||
[scanner scanHexInt:&codepint];
|
||||
NSString *replacement = [NSString stringWithFormat:@"%C", (unichar)codepint];
|
||||
string = [string stringByReplacingCharactersInRange:matchRange withString:replacement];
|
||||
}
|
||||
NSLog(@"%@", string);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
//
|
||||
// HTMLTokenizerTests.m
|
||||
// HTMLKit
|
||||
//
|
||||
// Created by Iska on 25/10/14.
|
||||
// Copyright (c) 2014 BrainCookie. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import <XCTest/XCTest.h>
|
||||
#import "HTML5LibTest.h"
|
||||
|
||||
@interface HTMLTokenizerTests : XCTestCase
|
||||
|
||||
@end
|
||||
|
||||
@implementation HTMLTokenizerTests
|
||||
|
||||
- (void)setUp {
|
||||
[super setUp];
|
||||
// Put setup code here. This method is called before the invocation of each test method in the class.
|
||||
}
|
||||
|
||||
- (void)tearDown {
|
||||
// Put teardown code here. This method is called after the invocation of each test method in the class.
|
||||
[super tearDown];
|
||||
}
|
||||
|
||||
- (void)testExample {
|
||||
// This is an example of a functional test case.
|
||||
XCTAssert(YES, @"Pass");
|
||||
}
|
||||
|
||||
- (void)testPerformanceExample {
|
||||
// This is an example of a performance test case.
|
||||
[self measureBlock:^{
|
||||
// Put the code you want to measure the time of here.
|
||||
}];
|
||||
}
|
||||
|
||||
@end
|
||||
Reference in New Issue
Block a user