From c9d84009369f6414b0b15952bf80be34a7c9fe7b Mon Sep 17 00:00:00 2001 From: "gln@google.com" Date: Mon, 1 Aug 2011 21:30:04 +0000 Subject: [PATCH] Add email, smtp, and isbn result parsers. git-svn-id: https://zxing.googlecode.com/svn/trunk@1872 59b500cc-1b3d-0410-9834-0bbf25fbcc57 --- .../Classes/parsedResults/ISBNParsedResult.h | 31 +++++ .../Classes/parsedResults/ISBNParsedResult.m | 32 +++++ .../resultParsers/EmailAddressResultParser.h | 31 +++++ .../resultParsers/EmailAddressResultParser.m | 130 ++++++++++++++++++ .../Classes/resultParsers/ISBNResultParser.m | 57 ++++++++ .../Classes/resultParsers/ResultParser.h | 1 + .../Classes/resultParsers/ResultParser.m | 36 +++++ .../Classes/resultParsers/SMTPResultParser.h | 27 ++++ .../Classes/resultParsers/SMTPResultParser.m | 74 ++++++++++ .../resultParsers/UniversalResultParser.m | 6 + .../Tests/EmailAddressResultParserTests.m | 130 ++++++++++++++++++ .../ZXingWidget/Tests/ISBNResultParserTests.m | 52 +++++++ .../ZXingWidget/Tests/SMTPResultParserTests.m | 86 ++++++++++++ .../ZXingWidget.xcodeproj/project.pbxproj | 40 ++++++ 14 files changed, 733 insertions(+) create mode 100644 iphone/ZXingWidget/Classes/parsedResults/ISBNParsedResult.h create mode 100644 iphone/ZXingWidget/Classes/parsedResults/ISBNParsedResult.m create mode 100644 iphone/ZXingWidget/Classes/resultParsers/EmailAddressResultParser.h create mode 100644 iphone/ZXingWidget/Classes/resultParsers/EmailAddressResultParser.m create mode 100644 iphone/ZXingWidget/Classes/resultParsers/ISBNResultParser.m create mode 100644 iphone/ZXingWidget/Classes/resultParsers/SMTPResultParser.h create mode 100644 iphone/ZXingWidget/Classes/resultParsers/SMTPResultParser.m create mode 100644 iphone/ZXingWidget/Tests/EmailAddressResultParserTests.m create mode 100644 iphone/ZXingWidget/Tests/ISBNResultParserTests.m create mode 100644 iphone/ZXingWidget/Tests/SMTPResultParserTests.m diff --git a/iphone/ZXingWidget/Classes/parsedResults/ISBNParsedResult.h b/iphone/ZXingWidget/Classes/parsedResults/ISBNParsedResult.h new file mode 100644 index 000000000..fd3cd85f0 --- /dev/null +++ b/iphone/ZXingWidget/Classes/parsedResults/ISBNParsedResult.h @@ -0,0 +1,31 @@ +// +// ISBNParsedResult.h +// ZXing +// +// Ported to Objective C by George Nachman on 8/1/2011. +/* + * Copyright 2008 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import +#import "ParsedResult.h" + +@interface ISBNParsedResult : ParsedResult { + NSString *value; +} + +@property (nonatomic, copy) NSString *value; + +@end diff --git a/iphone/ZXingWidget/Classes/parsedResults/ISBNParsedResult.m b/iphone/ZXingWidget/Classes/parsedResults/ISBNParsedResult.m new file mode 100644 index 000000000..0e65aea7b --- /dev/null +++ b/iphone/ZXingWidget/Classes/parsedResults/ISBNParsedResult.m @@ -0,0 +1,32 @@ +// +// ISBNParsedResult.m +// ZXing +// +// Ported to Objective C by George Nachman on 8/1/2011 +/* + * Copyright 2008 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "ISBNParsedResult.h" + +@implementation ISBNParsedResult + +@synthesize value; + +- (NSString *)stringForDisplay { + return value; +} + +@end diff --git a/iphone/ZXingWidget/Classes/resultParsers/EmailAddressResultParser.h b/iphone/ZXingWidget/Classes/resultParsers/EmailAddressResultParser.h new file mode 100644 index 000000000..d50211f3c --- /dev/null +++ b/iphone/ZXingWidget/Classes/resultParsers/EmailAddressResultParser.h @@ -0,0 +1,31 @@ +// +// EmailAddressResultParser.h +// ZXing +// +// Ported to Objective C by George Nachman on 8/1/2011 +/* + * Copyright 2008 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import +#import "ResultParser.h" + +@interface EmailAddressResultParser : ResultParser { + +} + ++ (BOOL)isBasicallyValidEmailAddress:(NSString *)address; + +@end diff --git a/iphone/ZXingWidget/Classes/resultParsers/EmailAddressResultParser.m b/iphone/ZXingWidget/Classes/resultParsers/EmailAddressResultParser.m new file mode 100644 index 000000000..5ce1270c5 --- /dev/null +++ b/iphone/ZXingWidget/Classes/resultParsers/EmailAddressResultParser.m @@ -0,0 +1,130 @@ +// +// EmailAddressResultParser.m +// ZXing +// +// Ported to Objective-C by George Nachman on 7/29/2011 +/* + * Copyright 2008 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "EmailAddressResultParser.h" +#import "EmailParsedResult.h" +#import "ArrayAndStringCategories.h" + +// +// Represents a result that encodes an e-mail address, either as a plain address +// like "joe@example.org" or a mailto: URL like "mailto:joe@example.org". +// It can also take query parameters. For example: +// "mailto:joe@example.org?subject=hello&body=hello+world" +// "mailto:?to=joe%40example.org&subject=hello&body=hello+world" +// +// A query paramter of "to" will supercede the user/host portion of the URL if +// both are present. +// +// If the mailto: prefix is absent, this will recognize strings that look +// approximately like email addresses: they have an @ sign and no characters +// outlawed by RFC 2822. +// +// Originally by Sean Owen +// +@implementation EmailAddressResultParser + ++ (void)load { + [ResultParser registerResultParserClass:self]; +} + ++ (ParsedResult *)parsedResultForString:(NSString *)rawText + format:(BarcodeFormat)format { + if (rawText == nil) { + return nil; + } + NSString *kMailto = @"mailto"; + NSURL *url = [NSURL URLWithString:rawText]; + if (url && [[[url scheme] lowercaseString] isEqualToString:kMailto]) { + NSDictionary *nameValues = nil; + if ([url query]) { + nameValues = [ResultParser dictionaryForQueryString:[url query]]; + } + + // Set the "to" value with the query parameter or as much of the + // user+host as we have. + NSString *user = [url user]; + NSString *host = [url host]; + NSString *emailAddress = nil; + EmailParsedResult *result = + [[[EmailParsedResult alloc] init] autorelease]; + if ([nameValues objectForKey:@"to"]) { + emailAddress = [nameValues objectForKey:@"to"]; + } else if (user && host) { + emailAddress = [NSString stringWithFormat:@"%@@%@", user, host]; + } else if (user) { + emailAddress = user; + } + if (!emailAddress) { + return nil; + } + + // Add optional fields if present. + result.to = emailAddress; + if ([nameValues objectForKey:@"subject"]) { + result.subject = [nameValues objectForKey:@"subject"]; + } + if ([nameValues objectForKey:@"body"]) { + result.body = [nameValues objectForKey:@"body"]; + } + return result; + } else { + // It doesn't start with mailto:, but maybe it looks like an email + // address. + if (![self isBasicallyValidEmailAddress:rawText]) { + return nil; + } + EmailParsedResult *result = + [[[EmailParsedResult alloc] init] autorelease]; + result.to = rawText; + return result; + } +} + +// This implements only the most basic checking for an email address's validity: +// that it contains an '@' contains no characters disallowed by RFC 2822. +// This is an overly lenient definition of validity. We want to generally be +// lenient here since this class is only intended to encapsulate what's in a +// barcode, not "judge" it. ++ (BOOL)isBasicallyValidEmailAddress:(NSString *)address { + NSRange atRange = [address rangeOfString:@"@"]; + if (atRange.location == NSNotFound) { + return NO; + } + // Strip out the first at sign (exactly one is allowed). + NSString *atlessEmail = + [address stringByReplacingCharactersInRange:atRange + withString:@""]; + // Set of non-alphanumeric characters allowed by rfc2822. + NSString *allowedChars = @"!#$%&'*+-/=?^_`{}|~."; + NSMutableCharacterSet *allowedSet = + [NSCharacterSet characterSetWithCharactersInString:allowedChars]; + [allowedSet formUnionWithCharacterSet: + [NSCharacterSet alphanumericCharacterSet]]; + NSCharacterSet *bogusSet = [allowedSet invertedSet]; + + if ([atlessEmail rangeOfCharacterFromSet:bogusSet].location != NSNotFound) { + return NO; + } + return YES; +} + +@end + diff --git a/iphone/ZXingWidget/Classes/resultParsers/ISBNResultParser.m b/iphone/ZXingWidget/Classes/resultParsers/ISBNResultParser.m new file mode 100644 index 000000000..0434258b3 --- /dev/null +++ b/iphone/ZXingWidget/Classes/resultParsers/ISBNResultParser.m @@ -0,0 +1,57 @@ +// +// ISBNResultParser.m +// ZXing +// +// Ported to Objective-C by George Nachman on 7/29/2011 +/* + * Copyright 2008 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "ISBNResultParser.h" +#import "ISBNParsedResult.h" +#import "ArrayAndStringCategories.h" + +@implementation ISBNResultParser + ++ (void)load { + [ResultParser registerResultParserClass:self]; +} + +// Parses strings of digits that represent an ISBN +// ISBN-13 For Dummies +// http://www.bisg.org/isbn-13/for.dummies.html +// Originally by jbreiden@google.com (Jeff Breidenbach) ++ (ParsedResult *)parsedResultForString:(NSString *)rawText + format:(BarcodeFormat)format { + if (format != BarcodeFormat_EAN_13) { + return nil; + } + if (rawText == nil) { + return nil; + } + if ([rawText length] != 13) { + return nil; + } + if (![rawText hasPrefix:@"978"] && + ![rawText hasPrefix:@"979"]) { + return nil; + } + + ISBNParsedResult *result = [[[ISBNParsedResult alloc] init] autorelease]; + result.value = rawText; + return result; +} + +@end diff --git a/iphone/ZXingWidget/Classes/resultParsers/ResultParser.h b/iphone/ZXingWidget/Classes/resultParsers/ResultParser.h index f8761f93e..baba6f92e 100644 --- a/iphone/ZXingWidget/Classes/resultParsers/ResultParser.h +++ b/iphone/ZXingWidget/Classes/resultParsers/ResultParser.h @@ -30,5 +30,6 @@ + (ParsedResult *)parsedResultForString:(NSString *)s; + (ParsedResult *)parsedResultForString:(NSString *)s format:(BarcodeFormat)barcodeFormat; ++ (NSDictionary*)dictionaryForQueryString:(NSString *)uri; @end diff --git a/iphone/ZXingWidget/Classes/resultParsers/ResultParser.m b/iphone/ZXingWidget/Classes/resultParsers/ResultParser.m index d57f5e6a8..dc47a353d 100644 --- a/iphone/ZXingWidget/Classes/resultParsers/ResultParser.m +++ b/iphone/ZXingWidget/Classes/resultParsers/ResultParser.m @@ -22,6 +22,12 @@ #import "ResultParser.h" #import "TextResultParser.h" +@interface ResultParser(Private) + ++ (NSString *)urlDecode:(NSString *)str; + +@end + @implementation ResultParser static NSMutableSet *sResultParsers = nil; @@ -73,4 +79,34 @@ static NSMutableSet *sResultParsers = nil; return [ResultParser parsedResultForString:s format:BarcodeFormat_None]; } ++ (NSDictionary*)dictionaryForQueryString:(NSString *)queryString { + NSMutableDictionary *result = [NSMutableDictionary dictionary]; + NSArray *keyValuePairs = [queryString componentsSeparatedByString:@"&"]; + for (NSString *kvp in keyValuePairs) { + NSRange equals = [kvp rangeOfString:@"="]; + if (equals.location != NSNotFound) { + NSString *key = + [kvp substringWithRange:NSMakeRange(0, equals.location)]; + NSUInteger i = equals.location + 1; + NSString *value = + [kvp substringWithRange:NSMakeRange(i, [kvp length] - i)]; + [result setObject:[self urlDecode:value] + forKey:[self urlDecode:key]]; + } + } + return result; +} + +@end + +@implementation ResultParser(Private) + ++ (NSString *)urlDecode:(NSString *)str { + // Obj-C's url decoder does everything except + to space conversion. + NSString *result = [str stringByReplacingOccurrencesOfString:@"+" + withString:@" "]; + return [result stringByReplacingPercentEscapesUsingEncoding: + NSUTF8StringEncoding]; +} + @end diff --git a/iphone/ZXingWidget/Classes/resultParsers/SMTPResultParser.h b/iphone/ZXingWidget/Classes/resultParsers/SMTPResultParser.h new file mode 100644 index 000000000..7ec73afba --- /dev/null +++ b/iphone/ZXingWidget/Classes/resultParsers/SMTPResultParser.h @@ -0,0 +1,27 @@ +// +// SMTPResultParser.h +// ZXing +// +// Ported to Objective C by George Nachman on 8/1/2011 +/* + * Copyright 2008 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "ResultParser.h" + +@interface SMTPResultParser : ResultParser { +} + +@end diff --git a/iphone/ZXingWidget/Classes/resultParsers/SMTPResultParser.m b/iphone/ZXingWidget/Classes/resultParsers/SMTPResultParser.m new file mode 100644 index 000000000..ba3ddcedb --- /dev/null +++ b/iphone/ZXingWidget/Classes/resultParsers/SMTPResultParser.m @@ -0,0 +1,74 @@ +// +// SMTPResultParser.m +// ZXing +// +// Ported to Objective-C by George Nachman on 7/29/2011 +/* + * Copyright 2008 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "SMTPResultParser.h" +#import "EmailParsedResult.h" +#import "ArrayAndStringCategories.h" + +@implementation SMTPResultParser + ++ (void)load { + [ResultParser registerResultParserClass:self]; +} + +// +// Parses an "smtp:" URI result, whose format is not standardized but appears +// to be like one of these: +// smtp:to +// smtp:to:subject +// smtp:to:subject:body +// +// See http://code.google.com/p/zxing/issues/detail?id=536 +// +// Originally by Sean Owen +// ++ (ParsedResult *)parsedResultForString:(NSString *)rawText + format:(BarcodeFormat)format { + if (rawText == nil) { + return nil; + } + NSString *kSmtp = @"smtp:"; + if ([rawText length] <= [kSmtp length] || + (![rawText hasPrefix:kSmtp] && + ![rawText hasPrefix:[kSmtp uppercaseString]])) { + return nil; + } + + NSArray *components = [rawText componentsSeparatedByString:@":"]; + const NSUInteger n = [components count]; + if (n < 2 || n > 4) { + return nil; + } + + EmailParsedResult *result = [[[EmailParsedResult alloc] init] autorelease]; + if (n >= 2) { + result.to = [components objectAtIndex:1]; + } + if (n >= 3) { + result.subject = [components objectAtIndex:2]; + } + if (n >= 4) { + result.body = [components objectAtIndex:3]; + } + return result; +} + +@end diff --git a/iphone/ZXingWidget/Classes/resultParsers/UniversalResultParser.m b/iphone/ZXingWidget/Classes/resultParsers/UniversalResultParser.m index 42b6fd075..f059a1ac5 100644 --- a/iphone/ZXingWidget/Classes/resultParsers/UniversalResultParser.m +++ b/iphone/ZXingWidget/Classes/resultParsers/UniversalResultParser.m @@ -23,6 +23,9 @@ #import "BizcardResultParser.h" #import "AddressBookAUResultParser.h" #import "VCardResultParser.h" +#import "SMTPResultParser.h" +#import "ISBNResultParser.h" +#import "EmailAddressResultParser.h" @implementation UniversalResultParser static NSMutableArray *sTheResultParsers = nil; @@ -50,13 +53,16 @@ static NSMutableArray *sTheResultParsers = nil; [self addParserClass:[AddressBookAUResultParser class]]; [self addParserClass:[VCardResultParser class]]; [self addParserClass:[BizcardResultParser class]]; + [self addParserClass:[EmailAddressResultParser class]]; [self addParserClass:[PlainEmailResultParser class]]; + [self addParserClass:[SMTPResultParser class]]; [self addParserClass:[TelResultParser class]]; [self addParserClass:[SMSResultParser class]]; [self addParserClass:[SMSTOResultParser class]]; [self addParserClass:[GeoResultParser class]]; [self addParserClass:[URLTOResultParser class]]; [self addParserClass:[URLResultParser class]]; + [self addParserClass:[ISBNResultParser class]]; [self addParserClass:[ProductResultParser class]]; [self addParserClass:[TextResultParser class]]; } diff --git a/iphone/ZXingWidget/Tests/EmailAddressResultParserTests.m b/iphone/ZXingWidget/Tests/EmailAddressResultParserTests.m new file mode 100644 index 000000000..8c8ca8b65 --- /dev/null +++ b/iphone/ZXingWidget/Tests/EmailAddressResultParserTests.m @@ -0,0 +1,130 @@ +// +// EmailAddressResultParserTests.m +// ZXingWidget +// +// Created by George Nachman on 7/27/11. +// Copyright 2011 ZXing Authors. All rights reserved. +// + +#import +#import +#import "EmailAddressResultParserResultParser.h" +#import "URIParsedResult.h" + +@interface EmailAddressResultParserTests : SenTestCase +@end + +@implementation EmailAddressResultParserTests + +- (void)testWellFormedEmailAddressResultParser { + NSString *msg = + @"mailto:user@example.com?subject=the+subject&body=the%20body"; + EmailParsedResult *result = (EmailParsedResult *) + [EmailAddressResultParserResultParser parsedResultForString:msg + format:BarcodeFormat_QR_CODE]; + STAssertTrue([result.to isEqualToString:@"user@example.com"], + @"Wrong to %@", result.to); + STAssertTrue([result.subject isEqualToString:@"the subject"], + @"Wrong subject %@", result.subject); + STAssertTrue([result.body isEqualToString:@"the body"], + @"Wrong body %@", result.body); +} + +- (void)testWellFormedEmailAddressWithToResultParser { + NSString *msg = + @"mailto:bogus@example.com?to=user@exampe.com&subject=the+subject&" + @"body=the%20body"; + EmailParsedResult *result = (EmailParsedResult *) + [EmailAddressResultParserResultParser parsedResultForString:msg + format:BarcodeFormat_QR_CODE]; + STAssertTrue([result.to isEqualToString:@"user@example.com"], + @"Wrong to %@", result.to); + STAssertTrue([result.subject isEqualToString:@"the subject"], + @"Wrong subject %@", result.subject); + STAssertTrue([result.body isEqualToString:@"the body"], + @"Wrong body %@", result.body); +} + +- (void)testWellFormedEmailAddressNoQueryResultParser { + NSString *msg = + @"mailto:user@example.com"; + EmailParsedResult *result = (EmailParsedResult *) + [EmailAddressResultParserResultParser parsedResultForString:msg + format:BarcodeFormat_QR_CODE]; + STAssertTrue([result.to isEqualToString:@"user@example.com"], + @"Wrong to %@", result.to); + STAssertNil(result.subject, @"Wrong subject %@", result.subject); + STAssertNil(result.body, @"Wrong body %@", result.body); +} + +- (void)testWellFormedEmailAddressNoHostResultParser { + NSString *msg = + @"mailto:user"; + EmailParsedResult *result = (EmailParsedResult *) + [EmailAddressResultParserResultParser parsedResultForString:msg + format:BarcodeFormat_QR_CODE]; + STAssertTrue([result.to isEqualToString:@"user"], + @"Wrong to %@", result.to); + STAssertNil(result.subject, @"Wrong subject %@", result.subject); + STAssertNil(result.body, @"Wrong body %@", result.body); +} + +- (void)testSimpleEmailAddressResultParser { + NSString *msg = + @"user@example.com"; + EmailParsedResult *result = (EmailParsedResult *) + [EmailAddressResultParserResultParser parsedResultForString:msg + format:BarcodeFormat_QR_CODE]; + STAssertTrue([result.to isEqualToString:@"user@example.com"], + @"Wrong to %@", result.to); + STAssertNil(result.subject, + @"Wrong subject %@", result.subject); + STAssertNil(result.body, + @"Wrong body %@", result.body); +} + +- (void)testMalformedEmailAddressResultParser { + NSString *msg = + @"I like traffic lights"; + EmailParsedResult *result = (EmailParsedResult *) + [EmailAddressResultParserResultParser parsedResultForString:msg + format:BarcodeFormat_QR_CODE]; + STAssertNil(result, @"Bogus message parsed"); +} + +- (void)testMalformedDoubleAtEmailAddressResultParser { + NSString *msg = + @"me@here@there" + EmailParsedResult *result = (EmailParsedResult *) + [EmailAddressResultParserResultParser parsedResultForString:msg + format:BarcodeFormat_QR_CODE]; + STAssertNil(result, @"Bogus message parsed"); +} + +- (void)testMalformedBogusCharEmailAddressResultParser { + NSString *msg = + @"me(yeah)me@google.com" + EmailParsedResult *result = (EmailParsedResult *) + [EmailAddressResultParserResultParser parsedResultForString:msg + format:BarcodeFormat_QR_CODE]; + STAssertNil(result, @"Bogus message parsed"); +} + +- (void)testMalformedJustMailtoEmailAddressResultParser { + NSString *msg = + @"mailto:" + EmailParsedResult *result = (EmailParsedResult *) + [EmailAddressResultParserResultParser parsedResultForString:msg + format:BarcodeFormat_QR_CODE]; + STAssertNil(result, @"Bogus message parsed"); +} + +- (void)testMalformedEmptyEmailAddressResultParser { + NSString *msg = + @"" + EmailParsedResult *result = (EmailParsedResult *) + [EmailAddressResultParserResultParser parsedResultForString:msg + format:BarcodeFormat_QR_CODE]; + STAssertNil(result, @"Bogus message parsed"); +} +@end diff --git a/iphone/ZXingWidget/Tests/ISBNResultParserTests.m b/iphone/ZXingWidget/Tests/ISBNResultParserTests.m new file mode 100644 index 000000000..00cf28730 --- /dev/null +++ b/iphone/ZXingWidget/Tests/ISBNResultParserTests.m @@ -0,0 +1,52 @@ +// +// ISBNResultParserTests.m +// ZXingWidget +// +// Created by George Nachman on 7/27/11. +// Copyright 2011 ZXing Authors. All rights reserved. +// + +#import +#import +#import "ISBNResultParser.h" +#import "ISBNParsedResult.h" + +@interface ISBNResultParserTests : SenTestCase +@end + +@implementation ISBNResultParserTests + +- (void)testWellFormedISBNResultParser { + NSString *msg = @"9781234567890"; + ISBNParsedResult *result = (ISBNParsedResult *) + [ISBNResultParser parsedResultForString:msg + format:BarcodeFormat_EAN_13]; + STAssertTrue([result.value isEqualToString:msg], + @"Wrong value %@", result.value); +} + +- (void)testMalformedNumDigitsISBNResultParser { + NSString *msg = @"1234"; + ISBNParsedResult *result = (ISBNParsedResult *) + [ISBNResultParser parsedResultForString:msg + format:BarcodeFormat_EAN_13]; + STAssertNil(result, @"Bogus message parsed"); +} + +- (void)testMalformedPrefixISBNResultParser { + NSString *msg = @"9991234567890"; + ISBNParsedResult *result = (ISBNParsedResult *) + [ISBNResultParser parsedResultForString:msg + format:BarcodeFormat_EAN_13]; + STAssertNil(result, @"Bogus message parsed"); +} + +- (void)testMalformedISBNResultParser { + NSString *msg = @"I like traffic lights"; + ISBNParsedResult *result = (ISBNParsedResult *) + [ISBNResultParser parsedResultForString:msg + format:BarcodeFormat_EAN_13]; + STAssertNil(result, @"Bogus message parsed"); +} + +@end diff --git a/iphone/ZXingWidget/Tests/SMTPResultParserTests.m b/iphone/ZXingWidget/Tests/SMTPResultParserTests.m new file mode 100644 index 000000000..e2c06985d --- /dev/null +++ b/iphone/ZXingWidget/Tests/SMTPResultParserTests.m @@ -0,0 +1,86 @@ +// +// SMTPResultParserTests.m +// ZXingWidget +// +// Created by George Nachman on 7/27/11. +// Copyright 2011 ZXing Authors. All rights reserved. +// + +#import +#import +#import "SMTPResultParser.h" +#import "EmailParsedResult.h" + +@interface SMTPResultParserTests : SenTestCase +@end + +@implementation SMTPResultParserTests + +- (void)testWellFormedSMTPResultParser { + NSString *msg = + @"smtp:user@example.com:the subject:the body"; + EmailParsedResult *result = (EmailParsedResult *) + [SMTPResultParser parsedResultForString:msg + format:BarcodeFormat_QR_CODE]; + STAssertTrue([result.to isEqualToString:@"user@example.com"], + @"Wrong to %@", result.to); + STAssertTrue([result.subject isEqualToString:@"the subject"], + @"Wrong subject %@", result.subject); + STAssertTrue([result.body isEqualToString:@"the body"], + @"Wrong body %@", result.body); +} + +- (void)testWellFormedNoBodySMTPResultParser { + NSString *msg = + @"smtp:user@example.com:the subject"; + EmailParsedResult *result = (EmailParsedResult *) + [SMTPResultParser parsedResultForString:msg + format:BarcodeFormat_QR_CODE]; + STAssertTrue([result.to isEqualToString:@"user@example.com"], + @"Wrong to %@", result.to); + STAssertTrue([result.subject isEqualToString:@"the subject"], + @"Wrong subject %@", result.subject); + STAssertNil(result.body, + @"Wrong body %@", result.body); +} + +- (void)testWellFormedNoSubjectSMTPResultParser { + NSString *msg = @"smtp:user@example.com"; + EmailParsedResult *result = (EmailParsedResult *) + [SMTPResultParser parsedResultForString:msg + format:BarcodeFormat_QR_CODE]; + STAssertTrue([result.to isEqualToString:@"user@example.com"], + @"Wrong to %@", result.to); + STAssertNil(result.subject, + @"Wrong subject %@", result.subject); + STAssertNil(result.body, + @"Wrong body %@", result.body); +} + +- (void)testMalformedHeaderOnlySMTPResultParser { + NSString *msg = + @"smtp:"; + EmailParsedResult *result = (EmailParsedResult *) + [SMTPResultParser parsedResultForString:msg + format:BarcodeFormat_QR_CODE]; + STAssertNil(result, @"Bogus message parsed"); +} + +- (void)testMalformedEmptySMTPResultParser { + NSString *msg = + @""; + EmailParsedResult *result = (EmailParsedResult *) + [SMTPResultParser parsedResultForString:msg + format:BarcodeFormat_QR_CODE]; + STAssertNil(result, @"Bogus message parsed"); +} + +- (void)testMalformedSMTPResultParser { + NSString *msg = + @"I like traffic lights"; + EmailParsedResult *result = (EmailParsedResult *) + [SMTPResultParser parsedResultForString:msg + format:BarcodeFormat_QR_CODE]; + STAssertNil(result, @"Bogus message parsed"); +} +@end diff --git a/iphone/ZXingWidget/ZXingWidget.xcodeproj/project.pbxproj b/iphone/ZXingWidget/ZXingWidget.xcodeproj/project.pbxproj index 8c22882ae..62eb3f5e4 100644 --- a/iphone/ZXingWidget/ZXingWidget.xcodeproj/project.pbxproj +++ b/iphone/ZXingWidget/ZXingWidget.xcodeproj/project.pbxproj @@ -25,6 +25,16 @@ 1D603D7913E0B60D006F4B51 /* VCardResultParserTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D603D7313E0B60D006F4B51 /* VCardResultParserTests.m */; }; 1D603E6413E20AF1006F4B51 /* ArrayAndStringCategories.h in Headers */ = {isa = PBXBuildFile; fileRef = 1D603E6213E20AF1006F4B51 /* ArrayAndStringCategories.h */; }; 1D603E6513E20AF1006F4B51 /* ArrayAndStringCategories.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D603E6313E20AF1006F4B51 /* ArrayAndStringCategories.m */; }; + 1D60411613E36BF8006F4B51 /* EmailAddressResultParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 1D60411013E36BF8006F4B51 /* EmailAddressResultParser.h */; }; + 1D60411713E36BF8006F4B51 /* EmailAddressResultParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D60411113E36BF8006F4B51 /* EmailAddressResultParser.m */; }; + 1D60411813E36BF8006F4B51 /* ISBNResultParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 1D60411213E36BF8006F4B51 /* ISBNResultParser.h */; }; + 1D60411913E36BF8006F4B51 /* ISBNResultParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D60411313E36BF8006F4B51 /* ISBNResultParser.m */; }; + 1D60411A13E36BF8006F4B51 /* SMTPResultParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 1D60411413E36BF8006F4B51 /* SMTPResultParser.h */; }; + 1D60411B13E36BF8006F4B51 /* SMTPResultParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D60411513E36BF8006F4B51 /* SMTPResultParser.m */; }; + 1D60412313E36C2D006F4B51 /* ISBNParsedResult.h in Headers */ = {isa = PBXBuildFile; fileRef = 1D60412113E36C2D006F4B51 /* ISBNParsedResult.h */; }; + 1D60412413E36C2D006F4B51 /* ISBNParsedResult.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D60412213E36C2D006F4B51 /* ISBNParsedResult.m */; }; + 1D60412A13E36C55006F4B51 /* ISBNResultParserTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D60412713E36C55006F4B51 /* ISBNResultParserTests.m */; }; + 1D60412B13E36C55006F4B51 /* SMTPResultParserTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D60412813E36C55006F4B51 /* SMTPResultParserTests.m */; }; 1DFA090C13CE1A3900599044 /* CBarcodeFormat.h in Headers */ = {isa = PBXBuildFile; fileRef = 1DFA090A13CE1A3900599044 /* CBarcodeFormat.h */; }; 1DFA090D13CE1A3900599044 /* CBarcodeFormat.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1DFA090B13CE1A3900599044 /* CBarcodeFormat.mm */; }; 1DFA092413CE251600599044 /* ProductParsedResult.h in Headers */ = {isa = PBXBuildFile; fileRef = 1DFA092213CE251600599044 /* ProductParsedResult.h */; }; @@ -286,6 +296,16 @@ 1D603E6213E20AF1006F4B51 /* ArrayAndStringCategories.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ArrayAndStringCategories.h; path = Classes/ArrayAndStringCategories.h; sourceTree = ""; }; 1D603E6313E20AF1006F4B51 /* ArrayAndStringCategories.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ArrayAndStringCategories.m; path = Classes/ArrayAndStringCategories.m; sourceTree = ""; }; 1D6040C413E3393B006F4B51 /* AVFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = System/Library/Frameworks/AVFoundation.framework; sourceTree = SDKROOT; }; + 1D60411013E36BF8006F4B51 /* EmailAddressResultParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = EmailAddressResultParser.h; path = Classes/resultParsers/EmailAddressResultParser.h; sourceTree = ""; }; + 1D60411113E36BF8006F4B51 /* EmailAddressResultParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = EmailAddressResultParser.m; path = Classes/resultParsers/EmailAddressResultParser.m; sourceTree = ""; }; + 1D60411213E36BF8006F4B51 /* ISBNResultParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ISBNResultParser.h; path = Classes/resultParsers/ISBNResultParser.h; sourceTree = ""; }; + 1D60411313E36BF8006F4B51 /* ISBNResultParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ISBNResultParser.m; path = Classes/resultParsers/ISBNResultParser.m; sourceTree = ""; }; + 1D60411413E36BF8006F4B51 /* SMTPResultParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SMTPResultParser.h; path = Classes/resultParsers/SMTPResultParser.h; sourceTree = ""; }; + 1D60411513E36BF8006F4B51 /* SMTPResultParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SMTPResultParser.m; path = Classes/resultParsers/SMTPResultParser.m; sourceTree = ""; }; + 1D60412113E36C2D006F4B51 /* ISBNParsedResult.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ISBNParsedResult.h; path = Classes/parsedResults/ISBNParsedResult.h; sourceTree = ""; }; + 1D60412213E36C2D006F4B51 /* ISBNParsedResult.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ISBNParsedResult.m; path = Classes/parsedResults/ISBNParsedResult.m; sourceTree = ""; }; + 1D60412713E36C55006F4B51 /* ISBNResultParserTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ISBNResultParserTests.m; path = Tests/ISBNResultParserTests.m; sourceTree = ""; }; + 1D60412813E36C55006F4B51 /* SMTPResultParserTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SMTPResultParserTests.m; path = Tests/SMTPResultParserTests.m; sourceTree = ""; }; 1DFA090A13CE1A3900599044 /* CBarcodeFormat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CBarcodeFormat.h; path = Classes/CBarcodeFormat.h; sourceTree = ""; }; 1DFA090B13CE1A3900599044 /* CBarcodeFormat.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = CBarcodeFormat.mm; path = Classes/CBarcodeFormat.mm; sourceTree = ""; }; 1DFA092213CE251600599044 /* ProductParsedResult.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ProductParsedResult.h; path = Classes/parsedResults/ProductParsedResult.h; sourceTree = ""; }; @@ -627,7 +647,9 @@ 1D603D6B13E0B60D006F4B51 /* BizcardResultParserTests.m */, 1D603D6D13E0B60D006F4B51 /* BookmarkDoCoMoTests.m */, 1D603D6F13E0B60D006F4B51 /* EmailDoCoMoResultParserTests.m */, + 1D60412713E36C55006F4B51 /* ISBNResultParserTests.m */, 1D603D7113E0B60D006F4B51 /* MeCardParserTests.m */, + 1D60412813E36C55006F4B51 /* SMTPResultParserTests.m */, 1D603D7313E0B60D006F4B51 /* VCardResultParserTests.m */, ); name = Tests; @@ -881,10 +903,14 @@ 1D0CBDF813D0DD5D003D0F8D /* BizcardResultParser.m */, 1F027FFB11A7BF06006B06DE /* BookmarkDoCoMoResultParser.h */, 1F027FFC11A7BF06006B06DE /* BookmarkDoCoMoResultParser.m */, + 1D60411013E36BF8006F4B51 /* EmailAddressResultParser.h */, + 1D60411113E36BF8006F4B51 /* EmailAddressResultParser.m */, 1F027FFF11A7BF06006B06DE /* EmailDoCoMoResultParser.h */, 1F02800011A7BF06006B06DE /* EmailDoCoMoResultParser.m */, 1F02800111A7BF06006B06DE /* GeoResultParser.h */, 1F02800211A7BF06006B06DE /* GeoResultParser.m */, + 1D60411213E36BF8006F4B51 /* ISBNResultParser.h */, + 1D60411313E36BF8006F4B51 /* ISBNResultParser.m */, 1F02800311A7BF06006B06DE /* MeCardParser.h */, 1F02800411A7BF06006B06DE /* MeCardParser.m */, 1F02800511A7BF06006B06DE /* PlainEmailResultParser.h */, @@ -897,6 +923,8 @@ 1F02800A11A7BF06006B06DE /* SMSResultParser.m */, 1F02800B11A7BF06006B06DE /* SMSTOResultParser.h */, 1F02800C11A7BF06006B06DE /* SMSTOResultParser.m */, + 1D60411413E36BF8006F4B51 /* SMTPResultParser.h */, + 1D60411513E36BF8006F4B51 /* SMTPResultParser.m */, 1F02800D11A7BF06006B06DE /* TelResultParser.h */, 1F02800E11A7BF06006B06DE /* TelResultParser.m */, 1F02800F11A7BF06006B06DE /* TextResultParser.h */, @@ -920,6 +948,8 @@ 1F027FDE11A7BEEB006B06DE /* EmailParsedResult.m */, 1F027FDF11A7BEEB006B06DE /* GeoParsedResult.h */, 1F027FE011A7BEEB006B06DE /* GeoParsedResult.m */, + 1D60412113E36C2D006F4B51 /* ISBNParsedResult.h */, + 1D60412213E36C2D006F4B51 /* ISBNParsedResult.m */, 1F027FE111A7BEEB006B06DE /* ParsedResult.h */, 1F027FE211A7BEEB006B06DE /* ParsedResult.m */, 1DFA092213CE251600599044 /* ProductParsedResult.h */, @@ -1088,6 +1118,10 @@ 1D0CBDF913D0DD5D003D0F8D /* BizcardResultParser.h in Headers */, 1D4F11FB13D89EFD0032F754 /* VCardResultParser.h in Headers */, 1D603E6413E20AF1006F4B51 /* ArrayAndStringCategories.h in Headers */, + 1D60411613E36BF8006F4B51 /* EmailAddressResultParser.h in Headers */, + 1D60411813E36BF8006F4B51 /* ISBNResultParser.h in Headers */, + 1D60411A13E36BF8006F4B51 /* SMTPResultParser.h in Headers */, + 1D60412313E36C2D006F4B51 /* ISBNParsedResult.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1193,6 +1227,8 @@ 1D603D7713E0B60D006F4B51 /* EmailDoCoMoResultParserTests.m in Sources */, 1D603D7813E0B60D006F4B51 /* MeCardParserTests.m in Sources */, 1D603D7913E0B60D006F4B51 /* VCardResultParserTests.m in Sources */, + 1D60412A13E36C55006F4B51 /* ISBNResultParserTests.m in Sources */, + 1D60412B13E36C55006F4B51 /* SMTPResultParserTests.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1315,6 +1351,10 @@ 1D0CBDFA13D0DD5D003D0F8D /* BizcardResultParser.m in Sources */, 1D4F11FC13D89EFD0032F754 /* VCardResultParser.m in Sources */, 1D603E6513E20AF1006F4B51 /* ArrayAndStringCategories.m in Sources */, + 1D60411713E36BF8006F4B51 /* EmailAddressResultParser.m in Sources */, + 1D60411913E36BF8006F4B51 /* ISBNResultParser.m in Sources */, + 1D60411B13E36BF8006F4B51 /* SMTPResultParser.m in Sources */, + 1D60412413E36C2D006F4B51 /* ISBNParsedResult.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; };