// // TestParser.m // ICeCoffEE // // Created by Nicholas Riley on 6/22/07. // Copyright 2007 Nicholas Riley. All rights reserved. // #import #import "ICeCoffEEParser.h" #include static void ps(NSString *format, ...) { va_list args; va_start(args, format); NSString *s = [[NSString alloc] initWithFormat: format arguments: args]; va_end(args); printf("%s\n", [s cString]); [s release]; } static void pr(NSString *s, NSRange r) { ps([[NSString alloc] initWithFormat: @"%@%@>%@<", s, [@"" stringByPaddingToLength: r.location withString: @" " startingAtIndex: 0], [@"" stringByPaddingToLength: r.length withString: @"-" startingAtIndex: 0]]); } static NSString *tc(NSString *s) { NSMutableString *rs = [s mutableCopy]; [rs replaceOccurrencesOfString: @"\n" withString: @"\\" options: 0 range: NSMakeRange(0, [s length])]; [rs replaceOccurrencesOfString: @"\t" withString: @">" options: 0 range: NSMakeRange(0, [s length])]; return [rs autorelease]; } NSString *ICCF_ErrString(OSStatus err, NSString *context) { return [NSString stringWithFormat: @"%@ (%d)", context, (int)err]; } void ICCF_CheckRange(NSRange range) { if (range.length > 0) return; pr(@"Invalid ", range); @throw([NSException exceptionWithName: NSRangeException reason: @"No URL is selected" userInfo: nil]); } // XXX move elsewhere static NSString *ICCF_StringByRemovingCharactersInSet(NSString *s, NSCharacterSet *set) { NSRange range = [s rangeOfCharacterFromSet: set options: 0 range: NSMakeRange(0, [s length])]; if (range.location == NSNotFound) return s; NSMutableString *ms = [s mutableCopy]; do { [ms deleteCharactersInRange: range]; range.length = [ms length] - range.location; range = [ms rangeOfCharacterFromSet: set options: 0 range: range]; } while (range.location != NSNotFound); s = [[ms copy] autorelease]; [ms release]; return s; } static BOOL check_parse(NSString *uri, NSString *text, NSRange delimitedURIRange, NSRange initialSelectionRange) { // XXX figure XFAIL-type error checking NSRange enclosingRange; NSString *parsedURI = nil; NSException *parseException = nil; @try { enclosingRange = ICCF_URLEnclosingRange(text, initialSelectionRange); // XXX move trimming elsewhere parsedURI = ICCF_StringByRemovingCharactersInSet([text substringWithRange: enclosingRange], [NSCharacterSet whitespaceAndNewlineCharacterSet]); } @catch (NSException *e) { parseException = e; } if ([uri isEqualToString: parsedURI]) { return YES; } ps(@"Text %@", tc(text)); pr(@"Available ", delimitedURIRange); pr(@"Starting ", initialSelectionRange); if (parseException != nil) { ps(@"Exception %@", parseException); } else { pr(@"Parsed ", enclosingRange); ps(@"Parsed %@", tc(parsedURI)); ps(@"Desired %@", tc(uri)); } return NO; } CFBundleRef ICCF_bundle = NULL; int main(int argc, char *argv[]) { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; NSArray *a = [NSArray arrayWithContentsOfFile: @"urls.plist"]; NSCAssert(a != nil, @"Can't get array from urls.plist (wrong cwd? invalid format?)"); ICCF_StartIC(); unsigned pass = 0, fail = 0; NSEnumerator *e = [a objectEnumerator]; NSDictionary *d; while ( (d = [e nextObject]) != nil) { ps(@""); NSString *uri = [d objectForKey: @"uri"]; NSString *text = [d objectForKey: @"text"]; NSCAssert1(uri != nil, @"No URI in test case description %@", d); NSRange delimitedURIRange; if (text != nil) { NSArray *bits = [text componentsSeparatedByString: @"|"]; NSCAssert1([bits count] == 3, @"Sample text is not of the form 'foo|bar|baz': %@", text); text = [bits componentsJoinedByString: @""]; delimitedURIRange.location = [(NSString *)[bits objectAtIndex: 0] length]; delimitedURIRange.length = [(NSString *)[bits objectAtIndex: 1] length]; } else { text = uri; delimitedURIRange.location = 0; delimitedURIRange.length = [uri length]; } NSArray *bits = [text componentsSeparatedByString: @"^"]; if ([bits count] == 3) { NSString *joined = [bits componentsJoinedByString: @""]; NSRange initialSelectionRange = { [(NSString *)[bits objectAtIndex: 0] length], [(NSString *)[bits objectAtIndex: 1] length] }; delimitedURIRange.length -= 2; // remove ^^ if (check_parse(uri == text ? joined : uri, joined, delimitedURIRange, initialSelectionRange)) { pass++; } else { fail++; goto summary; } if (uri == text) continue; text = joined; } for (unsigned startOffset = 0 ; startOffset < delimitedURIRange.length ; ++startOffset) { NSRange initialSelectionRange = { delimitedURIRange.location + startOffset, delimitedURIRange.length != 0 }; if (check_parse(uri, text, delimitedURIRange, initialSelectionRange)) { pass++; } else { fail++; goto summary; } } } summary: ps(@"PASS %d FAIL %d", pass, fail); ICCF_StopIC(); [pool release]; }