Fixed stupid subclassing bug (and added test to avoid that in the future)

This commit is contained in:
relikd
2018-12-29 22:43:27 +01:00
parent 8fae59721b
commit 2732573003
7 changed files with 25 additions and 13 deletions

View File

@@ -27,7 +27,7 @@ In the previous version, the test case for parsing a non-opml file (with `RSOPML
``` ```
RSXMLData *xmlData = [[RSXMLData alloc] initWithData:d urlString:@"https://www.example.org"]; RSXMLData *xmlData = [[RSXMLData alloc] initWithData:d urlString:@"https://www.example.org"];
// TODO: check xmlData.parserError // TODO: check xmlData.parserError
RSFeedParser *parser = [[RSFeedParser alloc] initWithXMLData:xmlData]; RSFeedParser *parser = [RSFeedParser parserWithXMLData:xmlData];
// TODO: check [parser canParse] // TODO: check [parser canParse]
// TODO: alternatively check error after parseSync: // TODO: alternatively check error after parseSync:
NSError *parseError; NSError *parseError;

View File

@@ -201,7 +201,7 @@ static const NSInteger numberOfCharactersToSearch = 4096;
/// @return Kind of @c RSXMLParser or @c nil if no suitable parser found. /// @return Kind of @c RSXMLParser or @c nil if no suitable parser found.
- (id)getParser { - (id)getParser {
return [[_parserClass alloc] initWithXMLData:self]; return [_parserClass parserWithXMLData:self];
} }
/// @return @c YES if any parser, regardless of type, is suitable. /// @return @c YES if any parser, regardless of type, is suitable.

View File

@@ -51,8 +51,6 @@
+ (BOOL)isOPMLParser; + (BOOL)isOPMLParser;
/// @return @c YES if parser supports parsing HTML files. /// @return @c YES if parser supports parsing HTML files.
+ (BOOL)isHTMLParser; + (BOOL)isHTMLParser;
/// Keeps an internal pointer to the @c RSXMLData and initializes a new @c RSSAXParser.
- (instancetype)initWithXMLData:(RSXMLData * _Nonnull)xmlData;
/// Will be called after the parsing is finished. @return Reference to parsed object. /// Will be called after the parsing is finished. @return Reference to parsed object.
- (id)xmlParserWillReturnDocument; - (id)xmlParserWillReturnDocument;
@end @end
@@ -61,6 +59,8 @@
@interface RSXMLParser<__covariant T> : NSObject <RSXMLParserDelegate, RSSAXParserDelegate> @interface RSXMLParser<__covariant T> : NSObject <RSXMLParserDelegate, RSSAXParserDelegate>
@property (nonatomic, readonly, nonnull, copy) NSString *documentURI; @property (nonatomic, readonly, nonnull, copy) NSString *documentURI;
+ (instancetype)parserWithXMLData:(RSXMLData * _Nonnull)xmlData;
- (T _Nullable)parseSync:(NSError ** _Nullable)error; - (T _Nullable)parseSync:(NSError ** _Nullable)error;
- (void)parseAsync:(void(^)(T _Nullable parsedDocument, NSError * _Nullable error))block; - (void)parseAsync:(void(^)(T _Nullable parsedDocument, NSError * _Nullable error))block;
- (BOOL)canParse; - (BOOL)canParse;

View File

@@ -43,6 +43,18 @@
/** /**
Designated initializer. Runs a check whether it matches the detected parser in @c RSXMLData. Designated initializer. Runs a check whether it matches the detected parser in @c RSXMLData.
Keeps an internal pointer to the @c RSXMLData and initializes a new @c RSSAXParser.
*/
+ (instancetype)parserWithXMLData:(nonnull RSXMLData *)xmlData {
if ([xmlData.parserClass isSubclassOfClass:[super class]]) {
return [[xmlData.parserClass alloc] initWithXMLData:xmlData];
}
return [[super alloc] initWithXMLData:xmlData];
}
/**
Internal initializer. Use the class initializer to automatically initialize to proper subclass.
Keeps an internal pointer to the @c RSXMLData and initializes a new @c RSSAXParser.
*/ */
- (instancetype)initWithXMLData:(nonnull RSXMLData *)xmlData { - (instancetype)initWithXMLData:(nonnull RSXMLData *)xmlData {
self = [super init]; self = [super init];
@@ -85,7 +97,6 @@
NSString *errMsg = [[NSString stringWithFormat:@"%s", msg] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; NSString *errMsg = [[NSString stringWithFormat:@"%s", msg] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
*error = [NSError errorWithDomain:kLIBXMLParserErrorDomain code:errCode userInfo:@{NSLocalizedDescriptionKey: errMsg}]; *error = [NSError errorWithDomain:kLIBXMLParserErrorDomain code:errCode userInfo:@{NSLocalizedDescriptionKey: errMsg}];
} }
// *error = RSXMLMakeErrorFromLIBXMLError();
xmlResetLastError(); xmlResetLastError();
} }
} }

View File

@@ -44,7 +44,7 @@
RSXMLData *xmlData = [self xmlData:@"DaringFireball" urlString:@"http://daringfireball.net/"]; RSXMLData *xmlData = [self xmlData:@"DaringFireball" urlString:@"http://daringfireball.net/"];
XCTAssertTrue([xmlData.parserClass isHTMLParser]); XCTAssertTrue([xmlData.parserClass isHTMLParser]);
RSHTMLMetadataParser *parser = [[RSHTMLMetadataParser alloc] initWithXMLData:xmlData]; RSHTMLMetadataParser *parser = [RSHTMLMetadataParser parserWithXMLData:xmlData];
NSError *error; NSError *error;
RSHTMLMetadata *metadata = [parser parseSync:&error]; RSHTMLMetadata *metadata = [parser parseSync:&error];
XCTAssertNil(error); XCTAssertNil(error);
@@ -66,7 +66,7 @@
RSXMLData *xmlData = [self xmlData:@"furbo" urlString:@"http://furbo.org/"]; RSXMLData *xmlData = [self xmlData:@"furbo" urlString:@"http://furbo.org/"];
XCTAssertTrue([xmlData.parserClass isHTMLParser]); XCTAssertTrue([xmlData.parserClass isHTMLParser]);
RSHTMLMetadataParser *parser = [[RSHTMLMetadataParser alloc] initWithXMLData:xmlData]; RSHTMLMetadataParser *parser = [RSHTMLMetadataParser parserWithXMLData:xmlData];
NSError *error; NSError *error;
RSHTMLMetadata *metadata = [parser parseSync:&error]; RSHTMLMetadata *metadata = [parser parseSync:&error];
XCTAssertNil(error); XCTAssertNil(error);
@@ -87,7 +87,7 @@
RSXMLData *xmlData = [self xmlData:@"inessential" urlString:@"http://inessential.com/"]; RSXMLData *xmlData = [self xmlData:@"inessential" urlString:@"http://inessential.com/"];
XCTAssertTrue([xmlData.parserClass isHTMLParser]); XCTAssertTrue([xmlData.parserClass isHTMLParser]);
RSHTMLMetadataParser *parser = [[RSHTMLMetadataParser alloc] initWithXMLData:xmlData]; RSHTMLMetadataParser *parser = [RSHTMLMetadataParser parserWithXMLData:xmlData];
NSError *error; NSError *error;
RSHTMLMetadata *metadata = [parser parseSync:&error]; RSHTMLMetadata *metadata = [parser parseSync:&error];
XCTAssertNil(error); XCTAssertNil(error);
@@ -111,7 +111,7 @@
RSXMLData *xmlData = [self xmlData:@"sixcolors" urlString:@"https://sixcolors.com/"]; RSXMLData *xmlData = [self xmlData:@"sixcolors" urlString:@"https://sixcolors.com/"];
XCTAssertTrue([xmlData.parserClass isHTMLParser]); XCTAssertTrue([xmlData.parserClass isHTMLParser]);
RSHTMLMetadataParser *parser = [[RSHTMLMetadataParser alloc] initWithXMLData:xmlData]; RSHTMLMetadataParser *parser = [RSHTMLMetadataParser parserWithXMLData:xmlData];
NSError *error; NSError *error;
RSHTMLMetadata *metadata = [parser parseSync:&error]; RSHTMLMetadata *metadata = [parser parseSync:&error];
XCTAssertNil(error); XCTAssertNil(error);
@@ -143,7 +143,7 @@
RSXMLData *xmlData = [self xmlData:@"sixcolors" urlString:@"https://sixcolors.com/"]; RSXMLData *xmlData = [self xmlData:@"sixcolors" urlString:@"https://sixcolors.com/"];
XCTAssertTrue([xmlData.parserClass isHTMLParser]); XCTAssertTrue([xmlData.parserClass isHTMLParser]);
RSHTMLLinkParser *parser = [[RSHTMLLinkParser alloc] initWithXMLData:xmlData]; RSHTMLLinkParser *parser = [RSHTMLLinkParser parserWithXMLData:xmlData];
NSError *error; NSError *error;
NSArray<RSHTMLMetadataAnchor*> *links = [parser parseSync:&error]; NSArray<RSHTMLMetadataAnchor*> *links = [parser parseSync:&error];
XCTAssertNil(error); XCTAssertNil(error);

View File

@@ -61,7 +61,7 @@
NSData *importData = [exportString dataUsingEncoding:NSUTF8StringEncoding]; NSData *importData = [exportString dataUsingEncoding:NSUTF8StringEncoding];
RSXMLData *xmlData = [[RSXMLData alloc] initWithData:importData urlString:@"none"]; RSXMLData *xmlData = [[RSXMLData alloc] initWithData:importData urlString:@"none"];
XCTAssertEqual(xmlData.parserClass, [RSOPMLParser class]); XCTAssertEqual(xmlData.parserClass, [RSOPMLParser class]);
RSOPMLParser *parser = [[RSOPMLParser alloc] initWithXMLData:xmlData]; RSOPMLParser *parser = [RSOPMLParser parserWithXMLData:xmlData];
XCTAssertNotNil(parser); XCTAssertNotNil(parser);
NSError *error; NSError *error;
RSOPMLItem *document = [parser parseSync:&error]; RSOPMLItem *document = [parser parseSync:&error];
@@ -81,7 +81,7 @@
XCTAssertNotEqualObjects(xmlData.parserClass, [RSOPMLParser class]); XCTAssertNotEqualObjects(xmlData.parserClass, [RSOPMLParser class]);
XCTAssertNil(xmlData.parserError); XCTAssertNil(xmlData.parserError);
RSOPMLParser *parser = [[RSOPMLParser alloc] initWithXMLData:xmlData]; RSOPMLParser *parser = [RSOPMLParser parserWithXMLData:xmlData];
RSOPMLItem *document = [parser parseSync:&error]; RSOPMLItem *document = [parser parseSync:&error];
XCTAssertNil(document); XCTAssertNil(document);
XCTAssertNotNil(error); XCTAssertNotNil(error);

View File

@@ -95,8 +95,9 @@
RSXMLData *xmlData = [self xmlFile:@"OneFootTsunami" extension:@"atom"]; RSXMLData *xmlData = [self xmlFile:@"OneFootTsunami" extension:@"atom"];
XCTAssertEqual(xmlData.parserClass, [RSAtomParser class]); XCTAssertEqual(xmlData.parserClass, [RSAtomParser class]);
RSFeedParser *parser = [RSFeedParser parserWithXMLData:xmlData];
NSError *error = nil; NSError *error = nil;
RSParsedFeed *parsedFeed = [[xmlData getParser] parseSync:&error]; RSParsedFeed *parsedFeed = [parser parseSync:&error];
XCTAssertEqualObjects(parsedFeed.title, @"One Foot Tsunami"); XCTAssertEqualObjects(parsedFeed.title, @"One Foot Tsunami");
XCTAssertEqualObjects(parsedFeed.subtitle, @"Slightly less disappointing than it sounds"); XCTAssertEqualObjects(parsedFeed.subtitle, @"Slightly less disappointing than it sounds");
XCTAssertEqualObjects(parsedFeed.link, @"http://onefoottsunami.com"); XCTAssertEqualObjects(parsedFeed.link, @"http://onefoottsunami.com");