Index: new_tests/Makefile ================================================================== --- new_tests/Makefile +++ new_tests/Makefile @@ -52,10 +52,11 @@ OFSetTests.m \ OFStringTests.m \ OFSystemInfoTests.m \ OFUTF8StringTests.m \ OFXMLElementBuilderTests.m \ + OFXMLParserTests.m \ ${RUNTIME_ARC_TESTS_M} \ RuntimeTests.m \ ${USE_SRCS_PLUGINS} \ ${USE_SRCS_SOCKETS} \ ${USE_SRCS_SUBPROCESSES} \ ADDED new_tests/OFXMLParserTests.m Index: new_tests/OFXMLParserTests.m ================================================================== --- new_tests/OFXMLParserTests.m +++ new_tests/OFXMLParserTests.m @@ -0,0 +1,415 @@ +/* + * Copyright (c) 2008-2024 Jonathan Schleifer + * + * All rights reserved. + * + * This file is part of ObjFW. It may be distributed under the terms of the + * Q Public License 1.0, which can be found in the file LICENSE.QPL included in + * the packaging of this file. + * + * Alternatively, it may be distributed under the terms of the GNU General + * Public License, either version 2 or 3, which can be found in the file + * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this + * file. + */ + +#include "config.h" + +#include +#include + +#import "ObjFW.h" +#import "ObjFWTest.h" + +@interface OFXMLParserTests: OTTestCase +{ + int _i; +} +@end + +enum EventType { + eventTypeProcessingInstruction, + eventTypeTagOpen, + eventTypeTagClose, + eventTypeString, + eventTypeCDATA, + eventTypeComment +}; + +@implementation OFXMLParserTests +- (void)parser: (OFXMLParser *)parser + didCreateEvent: (enum EventType)type + name: (OFString *)name + prefix: (OFString *)prefix + namespace: (OFString *)namespace + attributes: (OFArray *)attrs + string: (OFString *)string +{ + switch (_i++) { + case 0: + OTAssertEqual(type, eventTypeProcessingInstruction); + OTAssertEqualObjects(name, @"xml"); + OTAssertEqualObjects(string, @"version='1.0'"); + break; + case 1: + OTAssertEqual(type, eventTypeProcessingInstruction); + OTAssertEqualObjects(name, @"p?i"); + OTAssertNil(string); + break; + case 2: + OTAssertEqual(type, eventTypeTagOpen); + OTAssertEqualObjects(name, @"root"); + OTAssertNil(prefix); + OTAssertNil(namespace); + OTAssertEqual(attrs.count, 0); + break; + case 3: + OTAssertEqual(type, eventTypeString); + OTAssertEqualObjects(string, @"\n\n "); + break; + case 4: + OTAssertEqual(type, eventTypeCDATA); + OTAssertEqualObjects(string, @"f<]]]oo]"); + OTAssertEqual(parser.lineNumber, 3); + break; + case 5: + OTAssertEqual(type, eventTypeTagOpen); + OTAssertEqualObjects(name, @"bar"); + OTAssertNil(prefix); + OTAssertNil(namespace); + OTAssertNil(attrs); + break; + case 6: + OTAssertEqual(type, eventTypeTagClose); + OTAssertEqualObjects(name, @"bar"); + OTAssertNil(prefix); + OTAssertNil(namespace); + OTAssertNil(attrs); + break; + case 7: + OTAssertEqual(type, eventTypeString); + OTAssertEqualObjects(string, @"\n "); + break; + case 8: + OTAssertEqual(type, eventTypeTagOpen); + OTAssertEqualObjects(name, @"foobar"); + OTAssertNil(prefix); + OTAssertEqualObjects(namespace, @"urn:objfw:test:foobar"); + OTAssertEqualObjects(attrs, [OFArray arrayWithObject: + [OFXMLAttribute attributeWithName: @"xmlns" + stringValue: @"urn:objfw:test:" + @"foobar"]]); + break; + case 9: + OTAssertEqual(type, eventTypeString); + OTAssertEqualObjects(string, @"\n "); + break; + case 10: + OTAssertEqual(type, eventTypeTagOpen); + OTAssertEqualObjects(name, @"qux"); + OTAssertNil(prefix); + OTAssertEqualObjects(namespace, @"urn:objfw:test:foobar"); + OTAssertEqualObjects(attrs, [OFArray arrayWithObject: + [OFXMLAttribute attributeWithName: @"foo" + namespace: @"http://www.w3.org/" + @"2000/xmlns/" + stringValue: @"urn:objfw:test:foo"]]); + break; + case 11: + OTAssertEqual(type, eventTypeString); + OTAssertEqualObjects(string, @"\n "); + break; + case 12: + OTAssertEqual(type, eventTypeTagOpen); + OTAssertEqualObjects(name, @"bla"); + OTAssertEqualObjects(prefix, @"foo"); + OTAssertEqualObjects(namespace, @"urn:objfw:test:foo"); + OTAssertEqualObjects(attrs, ([OFArray arrayWithObjects: + [OFXMLAttribute attributeWithName: @"bla" + namespace: @"urn:objfw:test:foo" + stringValue: @"bla"], + [OFXMLAttribute attributeWithName: @"blafoo" + stringValue: @"foo"], nil])); + break; + case 13: + OTAssertEqual(type, eventTypeString); + OTAssertEqualObjects(string, @"\n "); + break; + case 14: + OTAssertEqual(type, eventTypeTagOpen); + OTAssertEqualObjects(name, @"blup"); + OTAssertNil(prefix); + OTAssertEqualObjects(namespace, @"urn:objfw:test:foobar"); + OTAssertEqualObjects(attrs, ([OFArray arrayWithObjects: + [OFXMLAttribute attributeWithName: @"qux" + namespace: @"urn:objfw:test:foo" + stringValue: @"asd"], + [OFXMLAttribute attributeWithName: @"quxqux" + stringValue: @"test"], nil])); + break; + case 15: + OTAssertEqual(type, eventTypeTagClose); + OTAssertEqualObjects(name, @"blup"); + OTAssertNil(prefix); + OTAssertEqualObjects(namespace, @"urn:objfw:test:foobar"); + break; + case 16: + OTAssertEqual(type, eventTypeString); + OTAssertEqualObjects(string, @"\n "); + break; + case 17: + OTAssertEqual(type, eventTypeTagOpen); + OTAssertEqualObjects(name, @"bla"); + OTAssertEqualObjects(prefix, @"bla"); + OTAssertEqualObjects(namespace, @"urn:objfw:test:bla"); + OTAssertEqualObjects(attrs, ([OFArray arrayWithObjects: + [OFXMLAttribute attributeWithName: @"bla" + namespace: @"http://www.w3.org/" + @"2000/xmlns/" + stringValue: @"urn:objfw:test:bla"], + [OFXMLAttribute attributeWithName: @"qux" + stringValue: @"qux"], + [OFXMLAttribute attributeWithName: @"foo" + namespace: @"urn:objfw:test:bla" + stringValue: @"blafoo"], nil])); + break; + case 18: + OTAssertEqual(type, eventTypeTagClose); + OTAssertEqualObjects(name, @"bla"); + OTAssertEqualObjects(prefix, @"bla"); + OTAssertEqualObjects(namespace, @"urn:objfw:test:bla"); + break; + case 19: + OTAssertEqual(type, eventTypeString); + OTAssertEqualObjects(string, @"\n "); + break; + case 20: + OTAssertEqual(type, eventTypeTagOpen); + OTAssertEqualObjects(name, @"abc"); + OTAssertNil(prefix); + OTAssertEqualObjects(namespace, @"urn:objfw:test:abc"); + OTAssertEqualObjects(attrs, ([OFArray arrayWithObjects: + [OFXMLAttribute attributeWithName: @"xmlns" + stringValue: @"urn:objfw:test:abc"], + [OFXMLAttribute attributeWithName: @"abc" + stringValue: @"abc"], + [OFXMLAttribute attributeWithName: @"abc" + namespace: @"urn:objfw:test:foo" + stringValue: @"abc"], nil])); + break; + case 21: + OTAssertEqual(type, eventTypeTagClose); + OTAssertEqualObjects(name, @"abc"); + OTAssertNil(prefix); + OTAssertEqualObjects(namespace, @"urn:objfw:test:abc"); + break; + case 22: + OTAssertEqual(type, eventTypeString); + OTAssertEqualObjects(string, @"\n "); + break; + case 23: + OTAssertEqual(type, eventTypeTagClose); + OTAssertEqualObjects(name, @"bla"); + OTAssertEqualObjects(prefix, @"foo"); + OTAssertEqualObjects(namespace, @"urn:objfw:test:foo"); + break; + case 24: + OTAssertEqual(type, eventTypeString); + OTAssertEqualObjects(string, @"\n "); + break; + case 25: + OTAssertEqual(type, eventTypeComment); + OTAssertEqualObjects(string, @" commänt "); + break; + case 26: + OTAssertEqual(type, eventTypeString); + OTAssertEqualObjects(string, @"\n "); + break; + case 27: + OTAssertEqual(type, eventTypeTagClose); + OTAssertEqualObjects(name, @"qux"); + OTAssertNil(prefix); + OTAssertEqualObjects(namespace, @"urn:objfw:test:foobar"); + break; + case 28: + OTAssertEqual(type, eventTypeString); + OTAssertEqualObjects(string, @"\n "); + break; + case 29: + OTAssertEqual(type, eventTypeTagClose); + OTAssertEqualObjects(name, @"foobar"); + OTAssertNil(prefix); + OTAssertEqualObjects(namespace, @"urn:objfw:test:foobar"); + break; + case 30: + OTAssertEqual(type, eventTypeString); + OTAssertEqualObjects(string, @"\n"); + break; + case 31: + OTAssertEqual(type, eventTypeTagClose); + OTAssertEqualObjects(name, @"root"); + OTAssertNil(prefix); + OTAssertNil(namespace); + break; + } +} + +- (void)parser: (OFXMLParser *)parser + foundProcessingInstructionWithTarget: (OFString *)target + text: (OFString *)text +{ + [self parser: parser + didCreateEvent: eventTypeProcessingInstruction + name: target + prefix: nil + namespace: nil + attributes: nil + string: text]; +} + +- (void)parser: (OFXMLParser *)parser + didStartElement: (OFString *)name + prefix: (OFString *)prefix + namespace: (OFString *)namespace + attributes: (OFArray *)attrs +{ + [self parser: parser + didCreateEvent: eventTypeTagOpen + name: name + prefix: prefix + namespace: namespace + attributes: attrs + string: nil]; +} + +- (void)parser: (OFXMLParser *)parser + didEndElement: (OFString *)name + prefix: (OFString *)prefix + namespace: (OFString *)namespace +{ + [self parser: parser + didCreateEvent: eventTypeTagClose + name: name + prefix: prefix + namespace: namespace + attributes: nil + string: nil]; +} + +- (void)parser: (OFXMLParser *)parser foundCharacters: (OFString *)string +{ + [self parser: parser + didCreateEvent: eventTypeString + name: nil + prefix: nil + namespace: nil + attributes: nil + string: string]; +} + +- (void)parser: (OFXMLParser *)parser foundCDATA: (OFString *)CDATA +{ + [self parser: parser + didCreateEvent: eventTypeCDATA + name: nil + prefix: nil + namespace: nil + attributes: nil + string: CDATA]; +} + +- (void)parser: (OFXMLParser *)parser foundComment: (OFString *)comment +{ + [self parser: parser + didCreateEvent: eventTypeComment + name: nil + prefix: nil + namespace: nil + attributes: nil + string: comment]; +} + +- (OFString *)parser: (OFXMLParser *)parser + foundUnknownEntityNamed: (OFString *)entity +{ + if ([entity isEqual: @"foo"]) + return @"foobar"; + + return nil; +} + +- (void)testParser +{ + static const char *string = "\xEF\xBB\xBF" + "\r\r" + " \n" + " \r\n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + ""; + OFXMLParser *parser; + size_t j, length; + + parser = [OFXMLParser parser]; + parser.delegate = self; + + /* Simulate a stream where we only get chunks */ + length = strlen(string); + + for (j = 0; j < length; j+= 2) { + if (parser.hasFinishedParsing) + abort(); + + if (j + 2 > length) + [parser parseBuffer: string + j length: 1]; + else + [parser parseBuffer: string + j length: 2]; + } + + OTAssertEqual(_i, 32); + OTAssertEqual(parser.lineNumber, 18); + OTAssertTrue(parser.hasFinishedParsing); + + /* Parsing whitespaces after the document */ + [parser parseString: @" \t\r\n "]; + + /* Parsing comments after the document */ + [parser parseString: @" \t\r\n "]; + + /* Detection of junk after the document */ + OTAssertThrowsSpecific([parser parseString: @"a"], + OFMalformedXMLException); + OTAssertThrowsSpecific([parser parseString: @""], + OFMalformedXMLException); + + parser = [OFXMLParser parser]; + OTAssertThrowsSpecific([parser parseString: @""], + OFMalformedXMLException); +} + +- (void)testDetectionOfInvalidEncoding +{ + OFXMLParser *parser = [OFXMLParser parser]; + + OTAssertThrowsSpecific( + [parser parseString: @""], + OFInvalidEncodingException); +} +@end Index: tests/Makefile ================================================================== --- tests/Makefile +++ tests/Makefile @@ -14,11 +14,10 @@ PROG_NOINST = tests${PROG_SUFFIX} STATIC_LIB_NOINST = ${TESTS_STATIC_LIB} SRCS = OFStreamTests.m \ OFValueTests.m \ OFXMLNodeTests.m \ - OFXMLParserTests.m \ TestsAppDelegate.m IOS_USER ?= mobile IOS_TMP ?= /tmp/objfw-test DELETED tests/OFXMLParserTests.m Index: tests/OFXMLParserTests.m ================================================================== --- tests/OFXMLParserTests.m +++ tests/OFXMLParserTests.m @@ -1,432 +0,0 @@ -/* - * Copyright (c) 2008-2024 Jonathan Schleifer - * - * All rights reserved. - * - * This file is part of ObjFW. It may be distributed under the terms of the - * Q Public License 1.0, which can be found in the file LICENSE.QPL included in - * the packaging of this file. - * - * Alternatively, it may be distributed under the terms of the GNU General - * Public License, either version 2 or 3, which can be found in the file - * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this - * file. - */ - -#include "config.h" - -#include -#include - -#import "TestsAppDelegate.h" - -static OFString *const module = @"OFXMLParser"; -static int i = 0; - -enum EventType { - eventTypeProcessingInstruction, - eventTypeTagOpen, - eventTypeTagClose, - eventTypeString, - eventTypeCDATA, - eventTypeComment -}; - -@implementation TestsAppDelegate (OFXMLParser) -- (void)parser: (OFXMLParser *)parser - didCreateEvent: (enum EventType)type - name: (OFString *)name - prefix: (OFString *)prefix - namespace: (OFString *)namespace - attributes: (OFArray *)attrs - string: (OFString *)string -{ - OFString *message; - - i++; - message = [OFString stringWithFormat: @"Parsing part #%d", i]; - - switch (i) { - case 1: - TEST(message, - type == eventTypeProcessingInstruction && - [name isEqual: @"xml"] && - [string isEqual: @"version='1.0'"]) - break; - case 2: - TEST(message, - type == eventTypeProcessingInstruction && - [name isEqual: @"p?i"] && string == nil) - break; - case 3: - TEST(message, - type == eventTypeTagOpen && [name isEqual: @"root"] && - prefix == nil && namespace == nil && attrs.count == 0) - break; - case 4: - TEST(message, - type == eventTypeString && [string isEqual: @"\n\n "]) - break; - case 5: - TEST(message, - type == eventTypeCDATA && [string isEqual: @"f<]]]oo]"] && - parser.lineNumber == 3) - break; - case 6: - TEST(message, - type == eventTypeTagOpen && [name isEqual: @"bar"] && - prefix == nil && namespace == nil && attrs == nil) - break; - case 7: - TEST(message, - type == eventTypeTagClose && [name isEqual: @"bar"] && - prefix == nil && namespace == nil && attrs == nil) - break; - case 8: - TEST(message, - type == eventTypeString && [string isEqual: @"\n "]) - break; - case 9: - TEST(message, - type == eventTypeTagOpen && [name isEqual: @"foobar"] && - prefix == nil && - [namespace isEqual: @"urn:objfw:test:foobar"] && - attrs.count == 1 && - /* xmlns attr */ - [[[attrs objectAtIndex: 0] name] isEqual: @"xmlns"] && - [[attrs objectAtIndex: 0] namespace] == nil && - [[[attrs objectAtIndex: 0] stringValue] isEqual: - @"urn:objfw:test:foobar"]) - break; - case 10: - TEST(message, - type == eventTypeString && [string isEqual: @"\n "]) - break; - case 11: - TEST(message, - type == eventTypeTagOpen && [name isEqual: @"qux"] && - prefix == nil && - [namespace isEqual: @"urn:objfw:test:foobar"] && - attrs.count == 1 && - /* xmlns:foo attr */ - [[[attrs objectAtIndex: 0] name] isEqual: @"foo"] && - [[[attrs objectAtIndex: 0] namespace] isEqual: - @"http://www.w3.org/2000/xmlns/"] && - [[[attrs objectAtIndex: 0] stringValue] isEqual: - @"urn:objfw:test:foo"]) - break; - case 12: - TEST(message, - type == eventTypeString && [string isEqual: @"\n "]) - break; - case 13: - TEST(message, - type == eventTypeTagOpen && [name isEqual: @"bla"] && - [prefix isEqual: @"foo"] && - [namespace isEqual: @"urn:objfw:test:foo"] && - attrs.count == 2 && - /* foo:bla attr */ - [[[attrs objectAtIndex: 0] name] isEqual: @"bla"] && - [[[attrs objectAtIndex: 0] namespace] isEqual: - @"urn:objfw:test:foo"] && - [[[attrs objectAtIndex: 0] stringValue] isEqual: @"bla"] && - /* blafoo attr */ - [[[attrs objectAtIndex: 1] name] isEqual: @"blafoo"] && - [[attrs objectAtIndex: 1] namespace] == nil && - [[[attrs objectAtIndex: 1] stringValue] isEqual: @"foo"]) - break; - case 14: - TEST(message, - type == eventTypeString && [string isEqual: @"\n "]) - break; - case 15: - TEST(message, - type == eventTypeTagOpen && [name isEqual: @"blup"] && - prefix == nil && - [namespace isEqual: @"urn:objfw:test:foobar"] && - attrs.count == 2 && - /* foo:qux attr */ - [[[attrs objectAtIndex: 0] name] isEqual: @"qux"] && - [[[attrs objectAtIndex: 0] namespace] isEqual: - @"urn:objfw:test:foo"] && - [[[attrs objectAtIndex: 0] stringValue] isEqual: @"asd"] && - /* quxqux attr */ - [[[attrs objectAtIndex: 1] name] isEqual: @"quxqux"] && - [[attrs objectAtIndex: 1] namespace] == nil && - [[[attrs objectAtIndex: 1] stringValue] isEqual: @"test"]) - break; - case 16: - TEST(message, - type == eventTypeTagClose && [name isEqual: @"blup"] && - prefix == nil && - [namespace isEqual: @"urn:objfw:test:foobar"]) - break; - case 17: - TEST(message, - type == eventTypeString && [string isEqual: @"\n "]) - break; - case 18: - TEST(message, - type == eventTypeTagOpen && [name isEqual: @"bla"] && - [prefix isEqual: @"bla"] && - [namespace isEqual: @"urn:objfw:test:bla"] && - attrs.count == 3 && - /* xmlns:bla attr */ - [[[attrs objectAtIndex: 0] name] isEqual: @"bla"] && - [[[attrs objectAtIndex: 0] namespace] isEqual: - @"http://www.w3.org/2000/xmlns/"] && - [[[attrs objectAtIndex: 0] stringValue] isEqual: - @"urn:objfw:test:bla"] && - /* qux attr */ - [[[attrs objectAtIndex: 1] name] isEqual: @"qux"] && - [[attrs objectAtIndex: 1] namespace] == nil && - [[[attrs objectAtIndex: 1] stringValue] isEqual: @"qux"] && - /* bla:foo attr */ - [[[attrs objectAtIndex: 2] name] isEqual: @"foo"] && - [[[attrs objectAtIndex: 2] namespace] isEqual: - @"urn:objfw:test:bla"] && - [[[attrs objectAtIndex: 2] stringValue] isEqual: @"blafoo"]) - break; - case 19: - TEST(message, - type == eventTypeTagClose && [name isEqual: @"bla"] && - [prefix isEqual: @"bla"] && - [namespace isEqual: @"urn:objfw:test:bla"]) - break; - case 20: - TEST(message, - type == eventTypeString && [string isEqual: @"\n "]) - break; - case 21: - TEST(message, - type == eventTypeTagOpen && [name isEqual: @"abc"] && - prefix == nil && - [namespace isEqual: @"urn:objfw:test:abc"] && - attrs.count == 3 && - /* xmlns attr */ - [[[attrs objectAtIndex: 0] name] isEqual: @"xmlns"] && - [[attrs objectAtIndex: 0] namespace] == nil && - [[[attrs objectAtIndex: 0] stringValue] isEqual: - @"urn:objfw:test:abc"] && - /* abc attr */ - [[[attrs objectAtIndex: 1] name] isEqual: @"abc"] && - [[attrs objectAtIndex: 1] namespace] == nil && - [[[attrs objectAtIndex: 1] stringValue] isEqual: @"abc"] && - /* foo:abc attr */ - [[[attrs objectAtIndex: 2] name] isEqual: @"abc"] && - [[[attrs objectAtIndex: 2] namespace] isEqual: - @"urn:objfw:test:foo"] && - [[[attrs objectAtIndex: 2] stringValue] isEqual: @"abc"]) - break; - case 22: - TEST(message, - type == eventTypeTagClose && [name isEqual: @"abc"] && - prefix == nil && [namespace isEqual: @"urn:objfw:test:abc"]) - break; - case 23: - TEST(message, - type == eventTypeString && [string isEqual: @"\n "]) - break; - case 24: - TEST(message, - type == eventTypeTagClose && [name isEqual: @"bla"] && - [prefix isEqual: @"foo"] && - [namespace isEqual: @"urn:objfw:test:foo"]) - break; - case 25: - TEST(message, - type == eventTypeString && [string isEqual: @"\n "]) - break; - case 26: - TEST(message, - type == eventTypeComment && [string isEqual: @" commänt "]) - break; - case 27: - TEST(message, - type == eventTypeString && [string isEqual: @"\n "]) - break; - case 28: - TEST(message, - type == eventTypeTagClose && [name isEqual: @"qux"] && - prefix == nil && - [namespace isEqual: @"urn:objfw:test:foobar"]) - break; - case 29: - TEST(message, - type == eventTypeString && [string isEqual: @"\n "]) - break; - case 30: - TEST(message, - type == eventTypeTagClose && [name isEqual: @"foobar"] && - prefix == nil && - [namespace isEqual: @"urn:objfw:test:foobar"]) - break; - case 31: - TEST(message, - type == eventTypeString && [string isEqual: @"\n"]) - break; - case 32: - TEST(message, - type == eventTypeTagClose && [name isEqual: @"root"] && - prefix == nil && namespace == nil); - break; - } -} - -- (void)parser: (OFXMLParser *)parser - foundProcessingInstructionWithTarget: (OFString *)target - text: (OFString *)text -{ - [self parser: parser - didCreateEvent: eventTypeProcessingInstruction - name: target - prefix: nil - namespace: nil - attributes: nil - string: text]; -} - -- (void)parser: (OFXMLParser *)parser - didStartElement: (OFString *)name - prefix: (OFString *)prefix - namespace: (OFString *)namespace - attributes: (OFArray *)attrs -{ - [self parser: parser - didCreateEvent: eventTypeTagOpen - name: name - prefix: prefix - namespace: namespace - attributes: attrs - string: nil]; -} - -- (void)parser: (OFXMLParser *)parser - didEndElement: (OFString *)name - prefix: (OFString *)prefix - namespace: (OFString *)namespace -{ - [self parser: parser - didCreateEvent: eventTypeTagClose - name: name - prefix: prefix - namespace: namespace - attributes: nil - string: nil]; -} - -- (void)parser: (OFXMLParser *)parser foundCharacters: (OFString *)string -{ - [self parser: parser - didCreateEvent: eventTypeString - name: nil - prefix: nil - namespace: nil - attributes: nil - string: string]; -} - -- (void)parser: (OFXMLParser *)parser foundCDATA: (OFString *)CDATA -{ - [self parser: parser - didCreateEvent: eventTypeCDATA - name: nil - prefix: nil - namespace: nil - attributes: nil - string: CDATA]; -} - -- (void)parser: (OFXMLParser *)parser foundComment: (OFString *)comment -{ - [self parser: parser - didCreateEvent: eventTypeComment - name: nil - prefix: nil - namespace: nil - attributes: nil - string: comment]; -} - -- (OFString *)parser: (OFXMLParser *)parser - foundUnknownEntityNamed: (OFString *)entity -{ - if ([entity isEqual: @"foo"]) - return @"foobar"; - - return nil; -} - -- (void)XMLParserTests -{ - void *pool = objc_autoreleasePoolPush(); - const char *string = "\xEF\xBB\xBF" - "\r\r" - " \n" - " \r\n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - ""; - OFXMLParser *parser; - size_t j, length; - - TEST(@"+[parser]", (parser = [OFXMLParser parser])) - - TEST(@"-[setDelegate:]", (parser.delegate = self)) - - /* Simulate a stream where we only get chunks */ - length = strlen(string); - - for (j = 0; j < length; j+= 2) { - if (parser.hasFinishedParsing) - abort(); - - if (j + 2 > length) - [parser parseBuffer: string + j length: 1]; - else - [parser parseBuffer: string + j length: 2]; - } - - TEST(@"Checking if everything was parsed", - i == 32 && parser.lineNumber == 18) - - TEST(@"-[hasFinishedParsing]", parser.hasFinishedParsing) - - TEST(@"Parsing whitespaces after the document", - R([parser parseString: @" \t\r\n "])) - - TEST(@"Parsing comments after the document", - R([parser parseString: @" \t\r\n "])) - - EXPECT_EXCEPTION(@"Detection of junk after the document #1", - OFMalformedXMLException, [parser parseString: @"a"]) - - EXPECT_EXCEPTION(@"Detection of junk after the document #2", - OFMalformedXMLException, [parser parseString: @""]) - - parser = [OFXMLParser parser]; - EXPECT_EXCEPTION(@"Detection of invalid XML processing instruction #2", - OFInvalidEncodingException, - [parser parseString: @""]) - - parser = [OFXMLParser parser]; - EXPECT_EXCEPTION(@"Detection of invalid XML processing instruction #3", - OFMalformedXMLException, - [parser parseString: @""]) - - objc_autoreleasePoolPop(pool); -} -@end Index: tests/TestsAppDelegate.h ================================================================== --- tests/TestsAppDelegate.h +++ tests/TestsAppDelegate.h @@ -68,10 +68,5 @@ @end @interface TestsAppDelegate (OFXMLNodeTests) - (void)XMLNodeTests; @end - -@interface TestsAppDelegate (OFXMLParserTests) - -- (void)XMLParserTests; -@end Index: tests/TestsAppDelegate.m ================================================================== --- tests/TestsAppDelegate.m +++ tests/TestsAppDelegate.m @@ -370,11 +370,10 @@ changeCurrentDirectoryPath: @"/apps/objfw-tests"]; #endif [self valueTests]; [self streamTests]; - [self XMLParserTests]; [self XMLNodeTests]; [OFStdOut reset]; #if defined(OF_IOS)