@@ -18,98 +18,114 @@ #include #include #import "TestsAppDelegate.h" -static OFString *module = @"OFXMLParser"; +static OFString *const module = @"OFXMLParser"; static int i = 0; -enum event_type { - PROCESSING_INSTRUCTIONS, - TAG_OPEN, - TAG_CLOSE, - STRING, - CDATA, - COMMENT +enum EventType { + eventTypeProcessingInstruction, + eventTypeTagOpen, + eventTypeTagClose, + eventTypeString, + eventTypeCDATA, + eventTypeComment }; @implementation TestsAppDelegate (OFXMLParser) - (void)parser: (OFXMLParser *)parser - didCreateEvent: (enum event_type)type + didCreateEvent: (enum EventType)type name: (OFString *)name prefix: (OFString *)prefix - namespace: (OFString *)ns + namespace: (OFString *)namespace attributes: (OFArray *)attrs string: (OFString *)string { - OFString *msg; + OFString *message; i++; - msg = [OFString stringWithFormat: @"Parsing part #%d", i]; + message = [OFString stringWithFormat: @"Parsing part #%d", i]; switch (i) { case 1: - TEST(msg, type == PROCESSING_INSTRUCTIONS && - [string isEqual: @"xml version='1.0'"]) + TEST(message, + type == eventTypeProcessingInstruction && + [name isEqual: @"xml"] && + [string isEqual: @"version='1.0'"]) break; case 2: - TEST(msg, type == PROCESSING_INSTRUCTIONS && - [string isEqual: @"p?i"]) + TEST(message, + type == eventTypeProcessingInstruction && + [name isEqual: @"p?i"] && string == nil) break; case 3: - TEST(msg, type == TAG_OPEN && [name isEqual: @"root"] && - prefix == nil && ns == nil && attrs.count == 0) + TEST(message, + type == eventTypeTagOpen && [name isEqual: @"root"] && + prefix == nil && namespace == nil && attrs.count == 0) break; case 4: - TEST(msg, type == STRING && [string isEqual: @"\n\n "]) + TEST(message, + type == eventTypeString && [string isEqual: @"\n\n "]) break; case 5: - TEST(msg, type == CDATA && [string isEqual: @"f<]]]oo]"] && + TEST(message, + type == eventTypeCDATA && [string isEqual: @"f<]]]oo]"] && parser.lineNumber == 3) break; case 6: - TEST(msg, type == TAG_OPEN && [name isEqual: @"bar"] && - prefix == nil && ns == nil && attrs == nil) + TEST(message, + type == eventTypeTagOpen && [name isEqual: @"bar"] && + prefix == nil && namespace == nil && attrs == nil) break; case 7: - TEST(msg, type == TAG_CLOSE && [name isEqual: @"bar"] && - prefix == nil && ns == nil && attrs == nil) + TEST(message, + type == eventTypeTagClose && [name isEqual: @"bar"] && + prefix == nil && namespace == nil && attrs == nil) break; case 8: - TEST(msg, type == STRING && [string isEqual: @"\n "]) + TEST(message, + type == eventTypeString && [string isEqual: @"\n "]) break; case 9: - TEST(msg, type == TAG_OPEN && [name isEqual: @"foobar"] && - prefix == nil && [ns isEqual: @"urn:objfw:test:foobar"] && + 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(msg, type == STRING && [string isEqual: @"\n "]) + TEST(message, + type == eventTypeString && [string isEqual: @"\n "]) break; case 11: - TEST(msg, type == TAG_OPEN && [name isEqual: @"qux"] && - prefix == nil && [ns isEqual: @"urn:objfw:test:foobar"] && + 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(msg, type == STRING && [string isEqual: @"\n "]) + TEST(message, + type == eventTypeString && [string isEqual: @"\n "]) break; case 13: - TEST(msg, type == TAG_OPEN && [name isEqual: @"bla"] && + TEST(message, + type == eventTypeTagOpen && [name isEqual: @"bla"] && [prefix isEqual: @"foo"] && - [ns isEqual: @"urn:objfw:test: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"] && @@ -118,15 +134,18 @@ [[[attrs objectAtIndex: 1] name] isEqual: @"blafoo"] && [[attrs objectAtIndex: 1] namespace] == nil && [[[attrs objectAtIndex: 1] stringValue] isEqual: @"foo"]) break; case 14: - TEST(msg, type == STRING && [string isEqual: @"\n "]) + TEST(message, + type == eventTypeString && [string isEqual: @"\n "]) break; case 15: - TEST(msg, type == TAG_OPEN && [name isEqual: @"blup"] && - prefix == nil && [ns isEqual: @"urn:objfw:test:foobar"] && + 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"] && @@ -135,20 +154,25 @@ [[[attrs objectAtIndex: 1] name] isEqual: @"quxqux"] && [[attrs objectAtIndex: 1] namespace] == nil && [[[attrs objectAtIndex: 1] stringValue] isEqual: @"test"]) break; case 16: - TEST(msg, type == TAG_CLOSE && [name isEqual: @"blup"] && - prefix == nil && [ns isEqual: @"urn:objfw:test:foobar"]) + TEST(message, + type == eventTypeTagClose && [name isEqual: @"blup"] && + prefix == nil && + [namespace isEqual: @"urn:objfw:test:foobar"]) break; case 17: - TEST(msg, type == STRING && [string isEqual: @"\n "]) + TEST(message, + type == eventTypeString && [string isEqual: @"\n "]) break; case 18: - TEST(msg, type == TAG_OPEN && [name isEqual: @"bla"] && + TEST(message, + type == eventTypeTagOpen && [name isEqual: @"bla"] && [prefix isEqual: @"bla"] && - [ns isEqual: @"urn:objfw:test:bla"] && attrs.count == 3 && + [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: @@ -162,20 +186,24 @@ [[[attrs objectAtIndex: 2] namespace] isEqual: @"urn:objfw:test:bla"] && [[[attrs objectAtIndex: 2] stringValue] isEqual: @"blafoo"]) break; case 19: - TEST(msg, type == TAG_CLOSE && [name isEqual: @"bla"] && + TEST(message, + type == eventTypeTagClose && [name isEqual: @"bla"] && [prefix isEqual: @"bla"] && - [ns isEqual: @"urn:objfw:test:bla"]) + [namespace isEqual: @"urn:objfw:test:bla"]) break; case 20: - TEST(msg, type == STRING && [string isEqual: @"\n "]) + TEST(message, + type == eventTypeString && [string isEqual: @"\n "]) break; case 21: - TEST(msg, type == TAG_OPEN && [name isEqual: @"abc"] && - prefix == nil && [ns isEqual: @"urn:objfw:test:abc"] && + 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: @@ -189,121 +217,132 @@ [[[attrs objectAtIndex: 2] namespace] isEqual: @"urn:objfw:test:foo"] && [[[attrs objectAtIndex: 2] stringValue] isEqual: @"abc"]) break; case 22: - TEST(msg, type == TAG_CLOSE && [name isEqual: @"abc"] && - prefix == nil && [ns isEqual: @"urn:objfw:test:abc"]) - break; - case 23: - TEST(msg, type == STRING && [string isEqual: @"\n "]) - break; - case 24: - TEST(msg, type == TAG_CLOSE && [name isEqual: @"bla"] && - [prefix isEqual: @"foo"] && - [ns isEqual: @"urn:objfw:test:foo"]) - break; - case 25: - TEST(msg, type == STRING && [string isEqual: @"\n "]) - break; - case 26: - TEST(msg, type == COMMENT && [string isEqual: @" commänt "]) - break; - case 27: - TEST(msg, type == STRING && [string isEqual: @"\n "]) - break; - case 28: - TEST(msg, type == TAG_CLOSE && [name isEqual: @"qux"] && - prefix == nil && [ns isEqual: @"urn:objfw:test:foobar"]) - break; - case 29: - TEST(msg, type == STRING && [string isEqual: @"\n "]) - break; - case 30: - TEST(msg, type == TAG_CLOSE && [name isEqual: @"foobar"] && - prefix == nil && [ns isEqual: @"urn:objfw:test:foobar"]) - break; - case 31: - TEST(msg, type == STRING && [string isEqual: @"\n"]) - break; - case 32: - TEST(msg, type == TAG_CLOSE && [name isEqual: @"root"] && - prefix == nil && ns == nil); - break; - } -} - -- (void)parser: (OFXMLParser *)parser - foundProcessingInstructions: (OFString *)pi -{ - [self parser: parser - didCreateEvent: PROCESSING_INSTRUCTIONS - name: nil - prefix: nil - namespace: nil - attributes: nil - string: pi]; + 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 + data: (OFString *)data +{ + [self parser: parser + didCreateEvent: eventTypeProcessingInstruction + name: target + prefix: nil + namespace: nil + attributes: nil + string: data]; } - (void)parser: (OFXMLParser *)parser didStartElement: (OFString *)name prefix: (OFString *)prefix - namespace: (OFString *)ns + namespace: (OFString *)namespace attributes: (OFArray *)attrs { [self parser: parser - didCreateEvent: TAG_OPEN + didCreateEvent: eventTypeTagOpen name: name prefix: prefix - namespace: ns + namespace: namespace attributes: attrs string: nil]; } - (void)parser: (OFXMLParser *)parser didEndElement: (OFString *)name prefix: (OFString *)prefix - namespace: (OFString *)ns + namespace: (OFString *)namespace { [self parser: parser - didCreateEvent: TAG_CLOSE + didCreateEvent: eventTypeTagClose name: name prefix: prefix - namespace: ns + namespace: namespace attributes: nil string: nil]; } -- (void)parser: (OFXMLParser *)parser - foundCharacters: (OFString *)string +- (void)parser: (OFXMLParser *)parser foundCharacters: (OFString *)string { [self parser: parser - didCreateEvent: STRING + didCreateEvent: eventTypeString name: nil prefix: nil namespace: nil attributes: nil string: string]; } -- (void)parser: (OFXMLParser *)parser - foundCDATA: (OFString *)cdata +- (void)parser: (OFXMLParser *)parser foundCDATA: (OFString *)CDATA { [self parser: parser - didCreateEvent: CDATA + didCreateEvent: eventTypeCDATA name: nil prefix: nil namespace: nil attributes: nil - string: cdata]; + string: CDATA]; } -- (void)parser: (OFXMLParser *)parser - foundComment: (OFString *)comment +- (void)parser: (OFXMLParser *)parser foundComment: (OFString *)comment { [self parser: parser - didCreateEvent: COMMENT + didCreateEvent: eventTypeComment name: nil prefix: nil namespace: nil attributes: nil string: comment]; @@ -319,11 +358,11 @@ } - (void)XMLParserTests { void *pool = objc_autoreleasePoolPush(); - const char *str = "\xEF\xBB\xBF" + const char *string = "\xEF\xBB\xBF" "\r\r" " \n" " \r\n" " \n" " \n" @@ -335,29 +374,27 @@ " \n" " \n" " \n" ""; OFXMLParser *parser; - size_t j, len; + size_t j, length; TEST(@"+[parser]", (parser = [OFXMLParser parser])) TEST(@"-[setDelegate:]", (parser.delegate = self)) /* Simulate a stream where we only get chunks */ - len = strlen(str); + length = strlen(string); - for (j = 0; j < len; j+= 2) { + for (j = 0; j < length; j+= 2) { if (parser.hasFinishedParsing) abort(); - if (j + 2 > len) - [parser parseBuffer: str + j - length: 1]; + if (j + 2 > length) + [parser parseBuffer: string + j length: 1]; else - [parser parseBuffer: str + j - length: 2]; + [parser parseBuffer: string + j length: 2]; } TEST(@"Checking if everything was parsed", i == 32 && parser.lineNumber == 18) @@ -374,22 +411,22 @@ EXPECT_EXCEPTION(@"Detection of junk after the document #2", OFMalformedXMLException, [parser parseString: @""]) parser = [OFXMLParser parser]; - EXPECT_EXCEPTION(@"Detection of invalid XML processing instructions #2", + EXPECT_EXCEPTION(@"Detection of invalid XML processing instruction #2", OFInvalidEncodingException, [parser parseString: @""]) parser = [OFXMLParser parser]; - EXPECT_EXCEPTION(@"Detection of invalid XML processing instructions #3", + EXPECT_EXCEPTION(@"Detection of invalid XML processing instruction #3", OFMalformedXMLException, [parser parseString: @""]) objc_autoreleasePoolPop(pool); } @end