| // |
| // GTMRegexTest.m |
| // |
| // Copyright 2007-2008 Google Inc. |
| // |
| // 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 "GTMSenTestCase.h" |
| #import "GTMRegex.h" |
| |
| // |
| // NOTE: |
| // |
| // We don't really test any of the pattern matching since that's testing |
| // libregex, we just want to test our wrapper. |
| // |
| |
| #pragma clang diagnostic push |
| // Ignore all of the deprecation warnings for GTMRegex |
| #pragma clang diagnostic ignored "-Wdeprecated-declarations" |
| |
| @interface GTMRegexTest : GTMTestCase |
| @end |
| |
| @interface NSString_GTMRegexAdditions : GTMTestCase |
| @end |
| |
| @implementation GTMRegexTest |
| |
| - (void)testEscapedPatternForString { |
| XCTAssertEqualStrings([GTMRegex escapedPatternForString:@"abcdefghijklmnopqrstuvwxyz0123456789"], |
| @"abcdefghijklmnopqrstuvwxyz0123456789"); |
| XCTAssertEqualStrings([GTMRegex escapedPatternForString:@"^.[$()|*+?{\\"], |
| @"\\^\\.\\[\\$\\(\\)\\|\\*\\+\\?\\{\\\\"); |
| XCTAssertEqualStrings([GTMRegex escapedPatternForString:@"a^b.c[d$e(f)g|h*i+j?k{l\\m"], |
| @"a\\^b\\.c\\[d\\$e\\(f\\)g\\|h\\*i\\+j\\?k\\{l\\\\m"); |
| |
| XCTAssertNil([GTMRegex escapedPatternForString:nil]); |
| XCTAssertEqualStrings([GTMRegex escapedPatternForString:@""], @""); |
| } |
| |
| |
| - (void)testInit { |
| |
| // fail cases |
| XCTAssertNil([[[GTMRegex alloc] init] autorelease]); |
| XCTAssertNil([[[GTMRegex alloc] initWithPattern:nil] autorelease]); |
| XCTAssertNil([[[GTMRegex alloc] initWithPattern:nil |
| options:kGTMRegexOptionIgnoreCase] autorelease]); |
| XCTAssertNil([[[GTMRegex alloc] initWithPattern:@"(."] autorelease]); |
| XCTAssertNil([[[GTMRegex alloc] initWithPattern:@"(." |
| options:kGTMRegexOptionIgnoreCase] autorelease]); |
| // fail cases w/ error param |
| NSError *error = nil; |
| XCTAssertNil([[[GTMRegex alloc] initWithPattern:nil |
| options:kGTMRegexOptionIgnoreCase |
| withError:&error] autorelease]); |
| XCTAssertNil(error, @"no pattern, shouldn't get error object"); |
| XCTAssertNil([[[GTMRegex alloc] initWithPattern:@"(." |
| options:kGTMRegexOptionIgnoreCase |
| withError:&error] autorelease]); |
| XCTAssertNotNil(error); |
| XCTAssertEqualObjects([error domain], kGTMRegexErrorDomain); |
| XCTAssertEqual([error code], (NSInteger)kGTMRegexPatternParseFailedError); |
| NSDictionary *userInfo = [error userInfo]; |
| XCTAssertNotNil(userInfo, @"failed to get userInfo from error"); |
| XCTAssertEqualObjects([userInfo objectForKey:kGTMRegexPatternErrorPattern], @"(."); |
| XCTAssertNotNil([userInfo objectForKey:kGTMRegexPatternErrorErrorString]); |
| |
| // basic pattern w/ options |
| XCTAssertNotNil([[[GTMRegex alloc] initWithPattern:@"(.*)"] autorelease]); |
| XCTAssertNotNil([[[GTMRegex alloc] initWithPattern:@"(.*)" |
| options:0] autorelease]); |
| XCTAssertNotNil([[[GTMRegex alloc] initWithPattern:@"(.*)" |
| options:kGTMRegexOptionIgnoreCase] autorelease]); |
| error = nil; |
| XCTAssertNotNil([[[GTMRegex alloc] initWithPattern:@"(.*)" |
| options:kGTMRegexOptionIgnoreCase |
| withError:&error] autorelease]); |
| XCTAssertNil(error, @"shouldn't have been any error"); |
| |
| // fail cases (helper) |
| XCTAssertNil([GTMRegex regexWithPattern:nil]); |
| XCTAssertNil([GTMRegex regexWithPattern:nil |
| options:0]); |
| XCTAssertNil([GTMRegex regexWithPattern:@"(."]); |
| XCTAssertNil([GTMRegex regexWithPattern:@"(." |
| options:0]); |
| // fail cases (helper) w/ error param |
| XCTAssertNil([GTMRegex regexWithPattern:nil |
| options:kGTMRegexOptionIgnoreCase |
| withError:&error]); |
| XCTAssertNil(error, @"no pattern, shouldn't get error object"); |
| XCTAssertNil([GTMRegex regexWithPattern:@"(." |
| options:kGTMRegexOptionIgnoreCase |
| withError:&error]); |
| XCTAssertNotNil(error); |
| XCTAssertEqualObjects([error domain], kGTMRegexErrorDomain); |
| XCTAssertEqual([error code], (NSInteger)kGTMRegexPatternParseFailedError); |
| userInfo = [error userInfo]; |
| XCTAssertNotNil(userInfo, @"failed to get userInfo from error"); |
| XCTAssertEqualObjects([userInfo objectForKey:kGTMRegexPatternErrorPattern], @"(."); |
| XCTAssertNotNil([userInfo objectForKey:kGTMRegexPatternErrorErrorString]); |
| |
| // basic pattern w/ options (helper) |
| XCTAssertNotNil([GTMRegex regexWithPattern:@"(.*)"]); |
| XCTAssertNotNil([GTMRegex regexWithPattern:@"(.*)" |
| options:0]); |
| XCTAssertNotNil([GTMRegex regexWithPattern:@"(.*)" |
| options:kGTMRegexOptionIgnoreCase]); |
| error = nil; |
| XCTAssertNotNil([GTMRegex regexWithPattern:@"(.*)" |
| options:kGTMRegexOptionIgnoreCase |
| withError:&error]); |
| XCTAssertNil(error, @"shouldn't have been any error"); |
| |
| // not really a test on GTMRegex, but make sure we block attempts to directly |
| // alloc/init a GTMRegexStringSegment. |
| XCTAssertThrowsSpecificNamed([[[GTMRegexStringSegment alloc] init] autorelease], |
| NSException, NSInvalidArgumentException, |
| @"shouldn't have been able to alloc/init a GTMRegexStringSegment"); |
| } |
| |
| - (void)testOptions { |
| |
| NSString *testString = @"aaa AAA\nbbb BBB\n aaa aAa\n bbb BbB"; |
| |
| // default options |
| GTMRegex *regex = [GTMRegex regexWithPattern:@"a+"]; |
| XCTAssertNotNil(regex); |
| NSEnumerator *enumerator = [regex segmentEnumeratorForString:testString]; |
| XCTAssertNotNil(enumerator); |
| // "aaa" |
| GTMRegexStringSegment *seg = [enumerator nextObject]; |
| XCTAssertNotNil(seg); |
| XCTAssertTrue([seg isMatch]); |
| XCTAssertEqualStrings([seg string], @"aaa"); |
| // " AAA\nbbb BBB\n " |
| seg = [enumerator nextObject]; |
| XCTAssertNotNil(seg); |
| XCTAssertFalse([seg isMatch]); |
| XCTAssertEqualStrings([seg string], @" AAA\nbbb BBB\n "); |
| // "aaa" |
| seg = [enumerator nextObject]; |
| XCTAssertNotNil(seg); |
| XCTAssertTrue([seg isMatch]); |
| XCTAssertEqualStrings([seg string], @"aaa"); |
| // " " |
| seg = [enumerator nextObject]; |
| XCTAssertNotNil(seg); |
| XCTAssertFalse([seg isMatch]); |
| XCTAssertEqualStrings([seg string], @" "); |
| // "a" |
| seg = [enumerator nextObject]; |
| XCTAssertNotNil(seg); |
| XCTAssertTrue([seg isMatch]); |
| XCTAssertEqualStrings([seg string], @"a"); |
| // "A" |
| seg = [enumerator nextObject]; |
| XCTAssertNotNil(seg); |
| XCTAssertFalse([seg isMatch]); |
| XCTAssertEqualStrings([seg string], @"A"); |
| // "a" |
| seg = [enumerator nextObject]; |
| XCTAssertNotNil(seg); |
| XCTAssertTrue([seg isMatch]); |
| XCTAssertEqualStrings([seg string], @"a"); |
| // "\n bbb BbB" |
| seg = [enumerator nextObject]; |
| XCTAssertNotNil(seg); |
| XCTAssertFalse([seg isMatch]); |
| XCTAssertEqualStrings([seg string], @"\n bbb BbB"); |
| // (end) |
| seg = [enumerator nextObject]; |
| XCTAssertNil(seg); |
| |
| // kGTMRegexOptionIgnoreCase |
| regex = [GTMRegex regexWithPattern:@"a+" options:kGTMRegexOptionIgnoreCase]; |
| XCTAssertNotNil(regex); |
| enumerator = [regex segmentEnumeratorForString:testString]; |
| XCTAssertNotNil(enumerator); |
| // "aaa" |
| seg = [enumerator nextObject]; |
| XCTAssertNotNil(seg); |
| XCTAssertTrue([seg isMatch]); |
| XCTAssertEqualStrings([seg string], @"aaa"); |
| // " " |
| seg = [enumerator nextObject]; |
| XCTAssertNotNil(seg); |
| XCTAssertFalse([seg isMatch]); |
| XCTAssertEqualStrings([seg string], @" "); |
| // "AAA" |
| seg = [enumerator nextObject]; |
| XCTAssertNotNil(seg); |
| XCTAssertTrue([seg isMatch]); |
| XCTAssertEqualStrings([seg string], @"AAA"); |
| // "\nbbb BBB\n " |
| seg = [enumerator nextObject]; |
| XCTAssertNotNil(seg); |
| XCTAssertFalse([seg isMatch]); |
| XCTAssertEqualStrings([seg string], @"\nbbb BBB\n "); |
| // "aaa" |
| seg = [enumerator nextObject]; |
| XCTAssertNotNil(seg); |
| XCTAssertTrue([seg isMatch]); |
| XCTAssertEqualStrings([seg string], @"aaa"); |
| // " " |
| seg = [enumerator nextObject]; |
| XCTAssertNotNil(seg); |
| XCTAssertFalse([seg isMatch]); |
| XCTAssertEqualStrings([seg string], @" "); |
| // "aAa" |
| seg = [enumerator nextObject]; |
| XCTAssertNotNil(seg); |
| XCTAssertTrue([seg isMatch]); |
| XCTAssertEqualStrings([seg string], @"aAa"); |
| // "\n bbb BbB" |
| seg = [enumerator nextObject]; |
| XCTAssertNotNil(seg); |
| XCTAssertFalse([seg isMatch]); |
| XCTAssertEqualStrings([seg string], @"\n bbb BbB"); |
| // (end) |
| seg = [enumerator nextObject]; |
| XCTAssertNil(seg); |
| |
| // defaults w/ '^' |
| regex = [GTMRegex regexWithPattern:@"^a+"]; |
| XCTAssertNotNil(regex); |
| enumerator = [regex segmentEnumeratorForString:testString]; |
| XCTAssertNotNil(enumerator); |
| // "aaa" |
| seg = [enumerator nextObject]; |
| XCTAssertNotNil(seg); |
| XCTAssertTrue([seg isMatch]); |
| XCTAssertEqualStrings([seg string], @"aaa"); |
| // " AAA\nbbb BBB\n aaa aAa\n bbb BbB" |
| seg = [enumerator nextObject]; |
| XCTAssertNotNil(seg); |
| XCTAssertFalse([seg isMatch]); |
| XCTAssertEqualStrings([seg string], @" AAA\nbbb BBB\n aaa aAa\n bbb BbB"); |
| // (end) |
| seg = [enumerator nextObject]; |
| XCTAssertNil(seg); |
| |
| // defaults w/ '$' |
| regex = [GTMRegex regexWithPattern:@"B+$"]; |
| XCTAssertNotNil(regex); |
| enumerator = [regex segmentEnumeratorForString:testString]; |
| XCTAssertNotNil(enumerator); |
| // "aaa AAA\nbbb " |
| seg = [enumerator nextObject]; |
| XCTAssertNotNil(seg); |
| XCTAssertFalse([seg isMatch]); |
| XCTAssertEqualStrings([seg string], @"aaa AAA\nbbb "); |
| // "BBB" |
| seg = [enumerator nextObject]; |
| XCTAssertNotNil(seg); |
| XCTAssertTrue([seg isMatch]); |
| XCTAssertEqualStrings([seg string], @"BBB"); |
| // "\n aaa aAa\n bbb Bb" |
| seg = [enumerator nextObject]; |
| XCTAssertNotNil(seg); |
| XCTAssertFalse([seg isMatch]); |
| XCTAssertEqualStrings([seg string], @"\n aaa aAa\n bbb Bb"); |
| // "B" |
| seg = [enumerator nextObject]; |
| XCTAssertNotNil(seg); |
| XCTAssertTrue([seg isMatch]); |
| XCTAssertEqualStrings([seg string], @"B"); |
| // (end) |
| seg = [enumerator nextObject]; |
| XCTAssertNil(seg); |
| |
| // kGTMRegexOptionIgnoreCase w/ '$' |
| regex = [GTMRegex regexWithPattern:@"B+$" |
| options:kGTMRegexOptionIgnoreCase]; |
| XCTAssertNotNil(regex); |
| enumerator = [regex segmentEnumeratorForString:testString]; |
| XCTAssertNotNil(enumerator); |
| // "aaa AAA\nbbb " |
| seg = [enumerator nextObject]; |
| XCTAssertNotNil(seg); |
| XCTAssertFalse([seg isMatch]); |
| XCTAssertEqualStrings([seg string], @"aaa AAA\nbbb "); |
| // "BBB" |
| seg = [enumerator nextObject]; |
| XCTAssertNotNil(seg); |
| XCTAssertTrue([seg isMatch]); |
| XCTAssertEqualStrings([seg string], @"BBB"); |
| // "\n aaa aAa\n bbb " |
| seg = [enumerator nextObject]; |
| XCTAssertNotNil(seg); |
| XCTAssertFalse([seg isMatch]); |
| XCTAssertEqualStrings([seg string], @"\n aaa aAa\n bbb "); |
| // "BbB" |
| seg = [enumerator nextObject]; |
| XCTAssertNotNil(seg); |
| XCTAssertTrue([seg isMatch]); |
| XCTAssertEqualStrings([seg string], @"BbB"); |
| // (end) |
| seg = [enumerator nextObject]; |
| XCTAssertNil(seg); |
| |
| // test w/ kGTMRegexOptionSupressNewlineSupport and \n in the string |
| regex = [GTMRegex regexWithPattern:@"a.*b" options:kGTMRegexOptionSupressNewlineSupport]; |
| XCTAssertNotNil(regex); |
| enumerator = [regex segmentEnumeratorForString:testString]; |
| XCTAssertNotNil(enumerator); |
| // "aaa AAA\nbbb BBB\n aaa aAa\n bbb Bb" |
| seg = [enumerator nextObject]; |
| XCTAssertNotNil(seg); |
| XCTAssertTrue([seg isMatch]); |
| XCTAssertEqualStrings([seg string], @"aaa AAA\nbbb BBB\n aaa aAa\n bbb Bb"); |
| // "B" |
| seg = [enumerator nextObject]; |
| XCTAssertNotNil(seg); |
| XCTAssertFalse([seg isMatch]); |
| XCTAssertEqualStrings([seg string], @"B"); |
| // (end) |
| seg = [enumerator nextObject]; |
| XCTAssertNil(seg); |
| |
| // test w/o kGTMRegexOptionSupressNewlineSupport and \n in the string |
| // (this is no match since it '.' can't match the '\n') |
| regex = [GTMRegex regexWithPattern:@"a.*b"]; |
| XCTAssertNotNil(regex); |
| enumerator = [regex segmentEnumeratorForString:testString]; |
| XCTAssertNotNil(enumerator); |
| // "aaa AAA\nbbb BBB\n aaa aAa\n bbb BbB" |
| seg = [enumerator nextObject]; |
| XCTAssertNotNil(seg); |
| XCTAssertFalse([seg isMatch]); |
| XCTAssertEqualStrings([seg string], @"aaa AAA\nbbb BBB\n aaa aAa\n bbb BbB"); |
| // (end) |
| seg = [enumerator nextObject]; |
| XCTAssertNil(seg); |
| |
| // kGTMRegexOptionSupressNewlineSupport w/ '^' |
| regex = [GTMRegex regexWithPattern:@"^a+" options:kGTMRegexOptionSupressNewlineSupport]; |
| XCTAssertNotNil(regex); |
| enumerator = [regex segmentEnumeratorForString:testString]; |
| XCTAssertNotNil(enumerator); |
| // "aaa" |
| seg = [enumerator nextObject]; |
| XCTAssertNotNil(seg); |
| XCTAssertTrue([seg isMatch]); |
| XCTAssertEqualStrings([seg string], @"aaa"); |
| // " AAA\nbbb BBB\n aaa aAa\n bbb BbB" |
| seg = [enumerator nextObject]; |
| XCTAssertNotNil(seg); |
| XCTAssertFalse([seg isMatch]); |
| XCTAssertEqualStrings([seg string], @" AAA\nbbb BBB\n aaa aAa\n bbb BbB"); |
| // (end) |
| seg = [enumerator nextObject]; |
| XCTAssertNil(seg); |
| |
| // kGTMRegexOptionSupressNewlineSupport w/ '$' |
| regex = [GTMRegex regexWithPattern:@"B+$" options:kGTMRegexOptionSupressNewlineSupport]; |
| XCTAssertNotNil(regex); |
| enumerator = [regex segmentEnumeratorForString:testString]; |
| XCTAssertNotNil(enumerator); |
| // "aaa AAA\nbbb BBB\n aaa aAa\n bbb Bb" |
| seg = [enumerator nextObject]; |
| XCTAssertNotNil(seg); |
| XCTAssertFalse([seg isMatch]); |
| XCTAssertEqualStrings([seg string], @"aaa AAA\nbbb BBB\n aaa aAa\n bbb Bb"); |
| // "B" |
| seg = [enumerator nextObject]; |
| XCTAssertNotNil(seg); |
| XCTAssertTrue([seg isMatch]); |
| XCTAssertEqualStrings([seg string], @"B"); |
| // (end) |
| seg = [enumerator nextObject]; |
| XCTAssertNil(seg); |
| } |
| |
| - (void)testSubPatternCount { |
| XCTAssertEqual((NSUInteger)0, [[GTMRegex regexWithPattern:@".*"] subPatternCount]); |
| XCTAssertEqual((NSUInteger)1, [[GTMRegex regexWithPattern:@"(.*)"] subPatternCount]); |
| XCTAssertEqual((NSUInteger)1, [[GTMRegex regexWithPattern:@"[fo]*(.*)[bar]*"] subPatternCount]); |
| XCTAssertEqual((NSUInteger)3, |
| [[GTMRegex regexWithPattern:@"([fo]*)(.*)([bar]*)"] subPatternCount]); |
| XCTAssertEqual((NSUInteger)7, |
| [[GTMRegex regexWithPattern:@"(([bar]*)|([fo]*))(.*)(([bar]*)|([fo]*))"] subPatternCount]); |
| } |
| |
| - (void)testMatchesString { |
| // simple pattern |
| GTMRegex *regex = [GTMRegex regexWithPattern:@"foo.*bar"]; |
| XCTAssertNotNil(regex); |
| XCTAssertTrue([regex matchesString:@"foobar"]); |
| XCTAssertTrue([regex matchesString:@"foobydoo spambar"]); |
| XCTAssertFalse([regex matchesString:@"zzfoobarzz"]); |
| XCTAssertFalse([regex matchesString:@"zzfoobydoo spambarzz"]); |
| XCTAssertFalse([regex matchesString:@"abcdef"]); |
| XCTAssertFalse([regex matchesString:@""]); |
| XCTAssertFalse([regex matchesString:nil]); |
| // pattern w/ sub patterns |
| regex = [GTMRegex regexWithPattern:@"(foo)(.*)(bar)"]; |
| XCTAssertNotNil(regex); |
| XCTAssertTrue([regex matchesString:@"foobar"]); |
| XCTAssertTrue([regex matchesString:@"foobydoo spambar"]); |
| XCTAssertFalse([regex matchesString:@"zzfoobarzz"]); |
| XCTAssertFalse([regex matchesString:@"zzfoobydoo spambarzz"]); |
| XCTAssertFalse([regex matchesString:@"abcdef"]); |
| XCTAssertFalse([regex matchesString:@""]); |
| XCTAssertFalse([regex matchesString:nil]); |
| } |
| |
| - (void)testSubPatternsOfString { |
| GTMRegex *regex = [GTMRegex regexWithPattern:@"(fo(o+))((bar)|(baz))"]; |
| XCTAssertNotNil(regex); |
| XCTAssertEqual((NSUInteger)5, [regex subPatternCount]); |
| NSArray *subPatterns = [regex subPatternsOfString:@"foooooobaz"]; |
| XCTAssertNotNil(subPatterns); |
| XCTAssertEqual((NSUInteger)6, [subPatterns count]); |
| XCTAssertEqualStrings(@"foooooobaz", [subPatterns objectAtIndex:0]); |
| XCTAssertEqualStrings(@"foooooo", [subPatterns objectAtIndex:1]); |
| XCTAssertEqualStrings(@"ooooo", [subPatterns objectAtIndex:2]); |
| XCTAssertEqualStrings(@"baz", [subPatterns objectAtIndex:3]); |
| XCTAssertEqualObjects([NSNull null], [subPatterns objectAtIndex:4]); |
| XCTAssertEqualStrings(@"baz", [subPatterns objectAtIndex:5]); |
| |
| // not there |
| subPatterns = [regex subPatternsOfString:@"aaa"]; |
| XCTAssertNil(subPatterns); |
| |
| // not extra stuff on either end |
| subPatterns = [regex subPatternsOfString:@"ZZZfoooooobaz"]; |
| XCTAssertNil(subPatterns); |
| subPatterns = [regex subPatternsOfString:@"foooooobazZZZ"]; |
| XCTAssertNil(subPatterns); |
| subPatterns = [regex subPatternsOfString:@"ZZZfoooooobazZZZ"]; |
| XCTAssertNil(subPatterns); |
| } |
| |
| - (void)testFirstSubStringMatchedInString { |
| // simple pattern |
| GTMRegex *regex = [GTMRegex regexWithPattern:@"foo.*bar"]; |
| XCTAssertNotNil(regex); |
| XCTAssertEqualStrings([regex firstSubStringMatchedInString:@"foobar"], |
| @"foobar"); |
| XCTAssertEqualStrings([regex firstSubStringMatchedInString:@"foobydoo spambar"], |
| @"foobydoo spambar"); |
| XCTAssertEqualStrings([regex firstSubStringMatchedInString:@"zzfoobarzz"], |
| @"foobar"); |
| XCTAssertEqualStrings([regex firstSubStringMatchedInString:@"zzfoobydoo spambarzz"], |
| @"foobydoo spambar"); |
| XCTAssertNil([regex firstSubStringMatchedInString:@"abcdef"]); |
| XCTAssertNil([regex firstSubStringMatchedInString:@""]); |
| // pattern w/ sub patterns |
| regex = [GTMRegex regexWithPattern:@"(foo)(.*)(bar)"]; |
| XCTAssertNotNil(regex); |
| XCTAssertEqualStrings([regex firstSubStringMatchedInString:@"foobar"], |
| @"foobar"); |
| XCTAssertEqualStrings([regex firstSubStringMatchedInString:@"foobydoo spambar"], |
| @"foobydoo spambar"); |
| XCTAssertEqualStrings([regex firstSubStringMatchedInString:@"zzfoobarzz"], |
| @"foobar"); |
| XCTAssertEqualStrings([regex firstSubStringMatchedInString:@"zzfoobydoo spambarzz"], |
| @"foobydoo spambar"); |
| XCTAssertNil([regex firstSubStringMatchedInString:@"abcdef"]); |
| XCTAssertNil([regex firstSubStringMatchedInString:@""]); |
| } |
| |
| - (void)testMatchesSubStringInString { |
| // simple pattern |
| GTMRegex *regex = [GTMRegex regexWithPattern:@"foo.*bar"]; |
| XCTAssertNotNil(regex); |
| XCTAssertTrue([regex matchesSubStringInString:@"foobar"]); |
| XCTAssertTrue([regex matchesSubStringInString:@"foobydoo spambar"]); |
| XCTAssertTrue([regex matchesSubStringInString:@"zzfoobarzz"]); |
| XCTAssertTrue([regex matchesSubStringInString:@"zzfoobydoo spambarzz"]); |
| XCTAssertFalse([regex matchesSubStringInString:@"abcdef"]); |
| XCTAssertFalse([regex matchesSubStringInString:@""]); |
| // pattern w/ sub patterns |
| regex = [GTMRegex regexWithPattern:@"(foo)(.*)(bar)"]; |
| XCTAssertNotNil(regex); |
| XCTAssertTrue([regex matchesSubStringInString:@"foobar"]); |
| XCTAssertTrue([regex matchesSubStringInString:@"foobydoo spambar"]); |
| XCTAssertTrue([regex matchesSubStringInString:@"zzfoobarzz"]); |
| XCTAssertTrue([regex matchesSubStringInString:@"zzfoobydoo spambarzz"]); |
| XCTAssertFalse([regex matchesSubStringInString:@"abcdef"]); |
| XCTAssertFalse([regex matchesSubStringInString:@""]); |
| } |
| |
| - (void)testSegmentEnumeratorForString { |
| GTMRegex *regex = [GTMRegex regexWithPattern:@"foo+ba+r"]; |
| XCTAssertNotNil(regex); |
| |
| // test odd input |
| NSEnumerator *enumerator = [regex segmentEnumeratorForString:@""]; |
| XCTAssertNotNil(enumerator); |
| enumerator = [regex segmentEnumeratorForString:nil]; |
| XCTAssertNil(enumerator); |
| |
| // on w/ the normal tests |
| enumerator = [regex segmentEnumeratorForString:@"afoobarbfooobaarfoobarzz"]; |
| XCTAssertNotNil(enumerator); |
| // "a" |
| GTMRegexStringSegment *seg = [enumerator nextObject]; |
| XCTAssertNotNil(seg); |
| XCTAssertFalse([seg isMatch]); |
| XCTAssertEqualStrings([seg string], @"a"); |
| // "foobar" |
| seg = [enumerator nextObject]; |
| XCTAssertNotNil(seg); |
| XCTAssertTrue([seg isMatch]); |
| XCTAssertEqualStrings([seg string], @"foobar"); |
| // "b" |
| seg = [enumerator nextObject]; |
| XCTAssertNotNil(seg); |
| XCTAssertFalse([seg isMatch]); |
| XCTAssertEqualStrings([seg string], @"b"); |
| // "fooobaar" |
| seg = [enumerator nextObject]; |
| XCTAssertNotNil(seg); |
| XCTAssertTrue([seg isMatch]); |
| XCTAssertEqualStrings([seg string], @"fooobaar"); |
| // "foobar" |
| seg = [enumerator nextObject]; |
| XCTAssertNotNil(seg); |
| XCTAssertTrue([seg isMatch]); |
| XCTAssertEqualStrings([seg string], @"foobar"); |
| // "zz" |
| seg = [enumerator nextObject]; |
| XCTAssertNotNil(seg); |
| XCTAssertFalse([seg isMatch]); |
| XCTAssertEqualStrings([seg string], @"zz"); |
| // (end) |
| seg = [enumerator nextObject]; |
| XCTAssertNil(seg); |
| |
| // test no match |
| enumerator = [regex segmentEnumeratorForString:@"aaa"]; |
| XCTAssertNotNil(enumerator); |
| seg = [enumerator nextObject]; |
| XCTAssertNotNil(seg); |
| XCTAssertFalse([seg isMatch]); |
| XCTAssertEqualStrings([seg string], @"aaa"); |
| seg = [enumerator nextObject]; |
| XCTAssertNil(seg); |
| |
| // test only match |
| enumerator = [regex segmentEnumeratorForString:@"foobar"]; |
| XCTAssertNotNil(enumerator); |
| seg = [enumerator nextObject]; |
| XCTAssertNotNil(seg); |
| XCTAssertTrue([seg isMatch]); |
| XCTAssertEqualStrings([seg string], @"foobar"); |
| seg = [enumerator nextObject]; |
| XCTAssertNil(seg); |
| |
| // now test the saved sub segments |
| regex = [GTMRegex regexWithPattern:@"(foo)((bar)|(baz))"]; |
| XCTAssertNotNil(regex); |
| XCTAssertEqual((NSUInteger)4, [regex subPatternCount]); |
| enumerator = [regex segmentEnumeratorForString:@"foobarxxfoobaz"]; |
| XCTAssertNotNil(enumerator); |
| // "foobar" |
| seg = [enumerator nextObject]; |
| XCTAssertNotNil(seg); |
| XCTAssertTrue([seg isMatch]); |
| XCTAssertEqualStrings([seg string], @"foobar"); |
| XCTAssertEqualStrings([seg subPatternString:0], @"foobar"); |
| XCTAssertEqualStrings([seg subPatternString:1], @"foo"); |
| XCTAssertEqualStrings([seg subPatternString:2], @"bar"); |
| XCTAssertEqualStrings([seg subPatternString:3], @"bar"); |
| XCTAssertNil([seg subPatternString:4]); // nothing matched "(baz)" |
| XCTAssertNil([seg subPatternString:5]); |
| // "xx" |
| seg = [enumerator nextObject]; |
| XCTAssertNotNil(seg); |
| XCTAssertFalse([seg isMatch]); |
| XCTAssertEqualStrings([seg string], @"xx"); |
| XCTAssertEqualStrings([seg subPatternString:0], @"xx"); |
| XCTAssertNil([seg subPatternString:1]); |
| // "foobaz" |
| seg = [enumerator nextObject]; |
| XCTAssertNotNil(seg); |
| XCTAssertTrue([seg isMatch]); |
| XCTAssertEqualStrings([seg string], @"foobaz"); |
| XCTAssertEqualStrings([seg subPatternString:0], @"foobaz"); |
| XCTAssertEqualStrings([seg subPatternString:1], @"foo"); |
| XCTAssertEqualStrings([seg subPatternString:2], @"baz"); |
| XCTAssertNil([seg subPatternString:3]); // (nothing matched "(bar)" |
| XCTAssertEqualStrings([seg subPatternString:4], @"baz"); |
| XCTAssertNil([seg subPatternString:5]); |
| // (end) |
| seg = [enumerator nextObject]; |
| XCTAssertNil(seg); |
| |
| // test all objects |
| regex = [GTMRegex regexWithPattern:@"foo+ba+r"]; |
| XCTAssertNotNil(regex); |
| enumerator = [regex segmentEnumeratorForString:@"afoobarbfooobaarfoobarzz"]; |
| XCTAssertNotNil(enumerator); |
| NSArray *allSegments = [enumerator allObjects]; |
| XCTAssertNotNil(allSegments); |
| XCTAssertEqual((NSUInteger)6, [allSegments count]); |
| |
| // test we are getting the flags right for newline |
| regex = [GTMRegex regexWithPattern:@"^a"]; |
| XCTAssertNotNil(regex); |
| enumerator = [regex segmentEnumeratorForString:@"aa\naa"]; |
| XCTAssertNotNil(enumerator); |
| // "a" |
| seg = [enumerator nextObject]; |
| XCTAssertNotNil(seg); |
| XCTAssertTrue([seg isMatch]); |
| XCTAssertEqualStrings([seg string], @"a"); |
| // "a\n" |
| seg = [enumerator nextObject]; |
| XCTAssertNotNil(seg); |
| XCTAssertFalse([seg isMatch]); |
| XCTAssertEqualStrings([seg string], @"a\n"); |
| // "a" |
| seg = [enumerator nextObject]; |
| XCTAssertNotNil(seg); |
| XCTAssertTrue([seg isMatch]); |
| XCTAssertEqualStrings([seg string], @"a"); |
| // "a" |
| seg = [enumerator nextObject]; |
| XCTAssertNotNil(seg); |
| XCTAssertFalse([seg isMatch]); |
| XCTAssertEqualStrings([seg string], @"a"); |
| // (end) |
| seg = [enumerator nextObject]; |
| XCTAssertNil(seg); |
| |
| // test we are getting the flags right for newline, part 2 |
| regex = [GTMRegex regexWithPattern:@"^a*$"]; |
| XCTAssertNotNil(regex); |
| enumerator = [regex segmentEnumeratorForString:@"aa\naa\nbb\naa"]; |
| XCTAssertNotNil(enumerator); |
| // "aa" |
| seg = [enumerator nextObject]; |
| XCTAssertNotNil(seg); |
| XCTAssertTrue([seg isMatch]); |
| XCTAssertEqualStrings([seg string], @"aa"); |
| // "\n" |
| seg = [enumerator nextObject]; |
| XCTAssertNotNil(seg); |
| XCTAssertFalse([seg isMatch]); |
| XCTAssertEqualStrings([seg string], @"\n"); |
| // "aa" |
| seg = [enumerator nextObject]; |
| XCTAssertNotNil(seg); |
| XCTAssertTrue([seg isMatch]); |
| XCTAssertEqualStrings([seg string], @"aa"); |
| // "\nbb\n" |
| seg = [enumerator nextObject]; |
| XCTAssertNotNil(seg); |
| XCTAssertFalse([seg isMatch]); |
| XCTAssertEqualStrings([seg string], @"\nbb\n"); |
| // "aa" |
| seg = [enumerator nextObject]; |
| XCTAssertNotNil(seg); |
| XCTAssertTrue([seg isMatch]); |
| XCTAssertEqualStrings([seg string], @"aa"); |
| // (end) |
| seg = [enumerator nextObject]; |
| XCTAssertNil(seg); |
| |
| // make sure the enum cleans up if not walked to the end |
| regex = [GTMRegex regexWithPattern:@"b+"]; |
| XCTAssertNotNil(regex); |
| enumerator = [regex segmentEnumeratorForString:@"aabbcc"]; |
| XCTAssertNotNil(enumerator); |
| // "aa" |
| seg = [enumerator nextObject]; |
| XCTAssertNotNil(seg); |
| XCTAssertFalse([seg isMatch]); |
| XCTAssertEqualStrings([seg string], @"aa"); |
| // and done w/o walking the rest |
| } |
| |
| - (void)testMatchSegmentEnumeratorForString { |
| GTMRegex *regex = [GTMRegex regexWithPattern:@"foo+ba+r"]; |
| XCTAssertNotNil(regex); |
| |
| // test odd input |
| NSEnumerator *enumerator = [regex matchSegmentEnumeratorForString:@""]; |
| XCTAssertNotNil(enumerator); |
| enumerator = [regex matchSegmentEnumeratorForString:nil]; |
| XCTAssertNil(enumerator); |
| |
| // on w/ the normal tests |
| enumerator = [regex matchSegmentEnumeratorForString:@"afoobarbfooobaarfoobarzz"]; |
| XCTAssertNotNil(enumerator); |
| // "a" - skipped |
| // "foobar" |
| GTMRegexStringSegment *seg = [enumerator nextObject]; |
| XCTAssertNotNil(seg); |
| XCTAssertTrue([seg isMatch]); |
| XCTAssertEqualStrings([seg string], @"foobar"); |
| // "b" - skipped |
| // "fooobaar" |
| seg = [enumerator nextObject]; |
| XCTAssertNotNil(seg); |
| XCTAssertTrue([seg isMatch]); |
| XCTAssertEqualStrings([seg string], @"fooobaar"); |
| // "foobar" |
| seg = [enumerator nextObject]; |
| XCTAssertNotNil(seg); |
| XCTAssertTrue([seg isMatch]); |
| XCTAssertEqualStrings([seg string], @"foobar"); |
| // "zz" - skipped |
| // (end) |
| seg = [enumerator nextObject]; |
| XCTAssertNil(seg); |
| |
| // test no match |
| enumerator = [regex matchSegmentEnumeratorForString:@"aaa"]; |
| XCTAssertNotNil(enumerator); |
| seg = [enumerator nextObject]; |
| XCTAssertNil(seg); // should have gotten nothing |
| |
| // test only match |
| enumerator = [regex matchSegmentEnumeratorForString:@"foobar"]; |
| XCTAssertNotNil(enumerator); |
| seg = [enumerator nextObject]; |
| XCTAssertNotNil(seg); |
| XCTAssertTrue([seg isMatch]); |
| XCTAssertEqualStrings([seg string], @"foobar"); |
| seg = [enumerator nextObject]; |
| XCTAssertNil(seg); |
| |
| // now test the saved sub segments |
| regex = [GTMRegex regexWithPattern:@"(foo)((bar)|(baz))"]; |
| XCTAssertNotNil(regex); |
| XCTAssertEqual((NSUInteger)4, [regex subPatternCount]); |
| enumerator = [regex matchSegmentEnumeratorForString:@"foobarxxfoobaz"]; |
| XCTAssertNotNil(enumerator); |
| // "foobar" |
| seg = [enumerator nextObject]; |
| XCTAssertNotNil(seg); |
| XCTAssertTrue([seg isMatch]); |
| XCTAssertEqualStrings([seg string], @"foobar"); |
| XCTAssertEqualStrings([seg subPatternString:0], @"foobar"); |
| XCTAssertEqualStrings([seg subPatternString:1], @"foo"); |
| XCTAssertEqualStrings([seg subPatternString:2], @"bar"); |
| XCTAssertEqualStrings([seg subPatternString:3], @"bar"); |
| XCTAssertNil([seg subPatternString:4]); // nothing matched "(baz)" |
| XCTAssertNil([seg subPatternString:5]); |
| // "xx" - skipped |
| // "foobaz" |
| seg = [enumerator nextObject]; |
| XCTAssertNotNil(seg); |
| XCTAssertTrue([seg isMatch]); |
| XCTAssertEqualStrings([seg string], @"foobaz"); |
| XCTAssertEqualStrings([seg subPatternString:0], @"foobaz"); |
| XCTAssertEqualStrings([seg subPatternString:1], @"foo"); |
| XCTAssertEqualStrings([seg subPatternString:2], @"baz"); |
| XCTAssertNil([seg subPatternString:3]); // (nothing matched "(bar)" |
| XCTAssertEqualStrings([seg subPatternString:4], @"baz"); |
| XCTAssertNil([seg subPatternString:5]); |
| // (end) |
| seg = [enumerator nextObject]; |
| XCTAssertNil(seg); |
| |
| // test all objects |
| regex = [GTMRegex regexWithPattern:@"foo+ba+r"]; |
| XCTAssertNotNil(regex); |
| enumerator = [regex matchSegmentEnumeratorForString:@"afoobarbfooobaarfoobarzz"]; |
| XCTAssertNotNil(enumerator); |
| NSArray *allSegments = [enumerator allObjects]; |
| XCTAssertNotNil(allSegments); |
| XCTAssertEqual((NSUInteger)3, [allSegments count]); |
| |
| // test we are getting the flags right for newline |
| regex = [GTMRegex regexWithPattern:@"^a"]; |
| XCTAssertNotNil(regex); |
| enumerator = [regex matchSegmentEnumeratorForString:@"aa\naa"]; |
| XCTAssertNotNil(enumerator); |
| // "a" |
| seg = [enumerator nextObject]; |
| XCTAssertNotNil(seg); |
| XCTAssertTrue([seg isMatch]); |
| XCTAssertEqualStrings([seg string], @"a"); |
| // "a\n" - skipped |
| // "a" |
| seg = [enumerator nextObject]; |
| XCTAssertNotNil(seg); |
| XCTAssertTrue([seg isMatch]); |
| XCTAssertEqualStrings([seg string], @"a"); |
| // "a" - skipped |
| // (end) |
| seg = [enumerator nextObject]; |
| XCTAssertNil(seg); |
| |
| // test we are getting the flags right for newline, part 2 |
| regex = [GTMRegex regexWithPattern:@"^a*$"]; |
| XCTAssertNotNil(regex); |
| enumerator = [regex matchSegmentEnumeratorForString:@"aa\naa\nbb\naa"]; |
| XCTAssertNotNil(enumerator); |
| // "aa" |
| seg = [enumerator nextObject]; |
| XCTAssertNotNil(seg); |
| XCTAssertTrue([seg isMatch]); |
| XCTAssertEqualStrings([seg string], @"aa"); |
| // "\n" - skipped |
| // "aa" |
| seg = [enumerator nextObject]; |
| XCTAssertNotNil(seg); |
| XCTAssertTrue([seg isMatch]); |
| XCTAssertEqualStrings([seg string], @"aa"); |
| // "\nbb\n" - skipped |
| // "aa" |
| seg = [enumerator nextObject]; |
| XCTAssertNotNil(seg); |
| XCTAssertTrue([seg isMatch]); |
| XCTAssertEqualStrings([seg string], @"aa"); |
| // (end) |
| seg = [enumerator nextObject]; |
| XCTAssertNil(seg); |
| } |
| |
| - (void)testStringByReplacingMatchesInStringWithReplacement { |
| GTMRegex *regex = [GTMRegex regexWithPattern:@"(foo)(.*)(bar)"]; |
| XCTAssertNotNil(regex); |
| // the basics |
| XCTAssertEqualStrings(@"weeZbarZbydoo spamZfooZdoggies", |
| [regex stringByReplacingMatchesInString:@"weefoobydoo spambardoggies" |
| withReplacement:@"Z\\3Z\\2Z\\1Z"]); |
| // nil/empty replacement |
| XCTAssertEqualStrings(@"weedoggies", |
| [regex stringByReplacingMatchesInString:@"weefoobydoo spambardoggies" |
| withReplacement:nil]); |
| XCTAssertEqualStrings(@"weedoggies", |
| [regex stringByReplacingMatchesInString:@"weefoobydoo spambardoggies" |
| withReplacement:@""]); |
| XCTAssertEqualStrings(@"", |
| [regex stringByReplacingMatchesInString:@"" |
| withReplacement:@"abc"]); |
| XCTAssertNil([regex stringByReplacingMatchesInString:nil |
| withReplacement:@"abc"]); |
| // use optional and invale subexpression parts to confirm that works |
| regex = [GTMRegex regexWithPattern:@"(fo(o+))((bar)|(baz))"]; |
| XCTAssertNotNil(regex); |
| XCTAssertEqualStrings(@"aaa baz bar bar foo baz aaa", |
| [regex stringByReplacingMatchesInString:@"aaa foooooobaz fooobar bar foo baz aaa" |
| withReplacement:@"\\4\\5"]); |
| XCTAssertEqualStrings(@"aaa ZZZ ZZZ bar foo baz aaa", |
| [regex stringByReplacingMatchesInString:@"aaa foooooobaz fooobar bar foo baz aaa" |
| withReplacement:@"Z\\10Z\\12Z"]); |
| // test slashes in replacement that aren't part of the subpattern reference |
| regex = [GTMRegex regexWithPattern:@"a+"]; |
| XCTAssertNotNil(regex); |
| XCTAssertEqualStrings(@"z\\\\0 \\\\a \\\\\\\\0z", |
| [regex stringByReplacingMatchesInString:@"zaz" |
| withReplacement:@"\\\\0 \\\\\\0 \\\\\\\\0"]); |
| XCTAssertEqualStrings(@"z\\\\a \\\\\\\\0 \\\\\\\\az", |
| [regex stringByReplacingMatchesInString:@"zaz" |
| withReplacement:@"\\\\\\0 \\\\\\\\0 \\\\\\\\\\0"]); |
| XCTAssertEqualStrings(@"z\\\\\\\\0 \\\\\\\\a \\\\\\\\\\\\0z", |
| [regex stringByReplacingMatchesInString:@"zaz" |
| withReplacement:@"\\\\\\\\0 \\\\\\\\\\0 \\\\\\\\\\\\0"]); |
| } |
| |
| - (void)testDescriptions { |
| // default options |
| GTMRegex *regex = [GTMRegex regexWithPattern:@"a+"]; |
| XCTAssertNotNil(regex); |
| XCTAssertGreaterThan([[regex description] length], (NSUInteger)10, |
| @"failed to get a reasonable description for regex"); |
| // enumerator |
| NSEnumerator *enumerator = [regex segmentEnumeratorForString:@"aaabbbccc"]; |
| XCTAssertNotNil(enumerator); |
| XCTAssertGreaterThan([[enumerator description] length], (NSUInteger)10, |
| @"failed to get a reasonable description for regex enumerator"); |
| // string segment |
| GTMRegexStringSegment *seg = [enumerator nextObject]; |
| XCTAssertNotNil(seg); |
| XCTAssertGreaterThan([[seg description] length], (NSUInteger)10, |
| @"failed to get a reasonable description for regex string segment"); |
| // regex w/ other options |
| regex = [GTMRegex regexWithPattern:@"a+" |
| options:(kGTMRegexOptionIgnoreCase | kGTMRegexOptionSupressNewlineSupport)]; |
| XCTAssertNotNil(regex); |
| XCTAssertGreaterThan([[regex description] length], (NSUInteger)10, |
| @"failed to get a reasonable description for regex w/ options"); |
| } |
| |
| @end |
| |
| @implementation NSString_GTMRegexAdditions |
| // Only partial tests to test that the call get through correctly since the |
| // above really tests them. |
| |
| - (void)testMatchesPattern { |
| // simple pattern |
| XCTAssertTrue([@"foobar" gtm_matchesPattern:@"foo.*bar"]); |
| XCTAssertTrue([@"foobydoo spambar" gtm_matchesPattern:@"foo.*bar"]); |
| XCTAssertFalse([@"zzfoobarzz" gtm_matchesPattern:@"foo.*bar"]); |
| XCTAssertFalse([@"zzfoobydoo spambarzz" gtm_matchesPattern:@"foo.*bar"]); |
| XCTAssertFalse([@"abcdef" gtm_matchesPattern:@"foo.*bar"]); |
| XCTAssertFalse([@"" gtm_matchesPattern:@"foo.*bar"]); |
| // pattern w/ sub patterns |
| XCTAssertTrue([@"foobar" gtm_matchesPattern:@"(foo)(.*)(bar)"]); |
| XCTAssertTrue([@"foobydoo spambar" gtm_matchesPattern:@"(foo)(.*)(bar)"]); |
| XCTAssertFalse([@"zzfoobarzz" gtm_matchesPattern:@"(foo)(.*)(bar)"]); |
| XCTAssertFalse([@"zzfoobydoo spambarzz" gtm_matchesPattern:@"(foo)(.*)(bar)"]); |
| XCTAssertFalse([@"abcdef" gtm_matchesPattern:@"(foo)(.*)(bar)"]); |
| XCTAssertFalse([@"" gtm_matchesPattern:@"(foo)(.*)(bar)"]); |
| } |
| |
| - (void)testSubPatternsOfPattern { |
| NSArray *subPatterns = [@"foooooobaz" gtm_subPatternsOfPattern:@"(fo(o+))((bar)|(baz))"]; |
| XCTAssertNotNil(subPatterns); |
| XCTAssertEqual((NSUInteger)6, [subPatterns count]); |
| XCTAssertEqualStrings(@"foooooobaz", [subPatterns objectAtIndex:0]); |
| XCTAssertEqualStrings(@"foooooo", [subPatterns objectAtIndex:1]); |
| XCTAssertEqualStrings(@"ooooo", [subPatterns objectAtIndex:2]); |
| XCTAssertEqualStrings(@"baz", [subPatterns objectAtIndex:3]); |
| XCTAssertEqualObjects([NSNull null], [subPatterns objectAtIndex:4]); |
| XCTAssertEqualStrings(@"baz", [subPatterns objectAtIndex:5]); |
| |
| // not there |
| subPatterns = [@"aaa" gtm_subPatternsOfPattern:@"(fo(o+))((bar)|(baz))"]; |
| XCTAssertNil(subPatterns); |
| |
| // not extra stuff on either end |
| subPatterns = [@"ZZZfoooooobaz" gtm_subPatternsOfPattern:@"(fo(o+))((bar)|(baz))"]; |
| XCTAssertNil(subPatterns); |
| subPatterns = [@"foooooobazZZZ" gtm_subPatternsOfPattern:@"(fo(o+))((bar)|(baz))"]; |
| XCTAssertNil(subPatterns); |
| subPatterns = [@"ZZZfoooooobazZZZ" gtm_subPatternsOfPattern:@"(fo(o+))((bar)|(baz))"]; |
| XCTAssertNil(subPatterns); |
| } |
| |
| - (void)testFirstSubStringMatchedByPattern { |
| // simple pattern |
| XCTAssertEqualStrings([@"foobar" gtm_firstSubStringMatchedByPattern:@"foo.*bar"], |
| @"foobar"); |
| XCTAssertEqualStrings([@"foobydoo spambar" gtm_firstSubStringMatchedByPattern:@"foo.*bar"], |
| @"foobydoo spambar"); |
| XCTAssertEqualStrings([@"zzfoobarzz" gtm_firstSubStringMatchedByPattern:@"foo.*bar"], |
| @"foobar"); |
| XCTAssertEqualStrings([@"zzfoobydoo spambarzz" gtm_firstSubStringMatchedByPattern:@"foo.*bar"], |
| @"foobydoo spambar"); |
| XCTAssertNil([@"abcdef" gtm_firstSubStringMatchedByPattern:@"foo.*bar"]); |
| XCTAssertNil([@"" gtm_firstSubStringMatchedByPattern:@"foo.*bar"]); |
| // pattern w/ sub patterns |
| XCTAssertEqualStrings([@"foobar" gtm_firstSubStringMatchedByPattern:@"(foo)(.*)(bar)"], |
| @"foobar"); |
| XCTAssertEqualStrings([@"foobydoo spambar" gtm_firstSubStringMatchedByPattern:@"(foo)(.*)(bar)"], |
| @"foobydoo spambar"); |
| XCTAssertEqualStrings([@"zzfoobarzz" gtm_firstSubStringMatchedByPattern:@"(foo)(.*)(bar)"], |
| @"foobar"); |
| XCTAssertEqualStrings([@"zzfoobydoo spambarzz" gtm_firstSubStringMatchedByPattern:@"(foo)(.*)(bar)"], |
| @"foobydoo spambar"); |
| XCTAssertNil([@"abcdef" gtm_firstSubStringMatchedByPattern:@"(foo)(.*)(bar)"]); |
| XCTAssertNil([@"" gtm_firstSubStringMatchedByPattern:@"(foo)(.*)(bar)"]); |
| } |
| |
| - (void)testSubStringMatchesPattern { |
| // simple pattern |
| XCTAssertTrue([@"foobar" gtm_subStringMatchesPattern:@"foo.*bar"]); |
| XCTAssertTrue([@"foobydoo spambar" gtm_subStringMatchesPattern:@"foo.*bar"]); |
| XCTAssertTrue([@"zzfoobarzz" gtm_subStringMatchesPattern:@"foo.*bar"]); |
| XCTAssertTrue([@"zzfoobydoo spambarzz" gtm_subStringMatchesPattern:@"foo.*bar"]); |
| XCTAssertFalse([@"abcdef" gtm_subStringMatchesPattern:@"foo.*bar"]); |
| XCTAssertFalse([@"" gtm_subStringMatchesPattern:@"foo.*bar"]); |
| // pattern w/ sub patterns |
| XCTAssertTrue([@"foobar" gtm_subStringMatchesPattern:@"(foo)(.*)(bar)"]); |
| XCTAssertTrue([@"foobydoo spambar" gtm_subStringMatchesPattern:@"(foo)(.*)(bar)"]); |
| XCTAssertTrue([@"zzfoobarzz" gtm_subStringMatchesPattern:@"(foo)(.*)(bar)"]); |
| XCTAssertTrue([@"zzfoobydoo spambarzz" gtm_subStringMatchesPattern:@"(foo)(.*)(bar)"]); |
| XCTAssertFalse([@"abcdef" gtm_subStringMatchesPattern:@"(foo)(.*)(bar)"]); |
| XCTAssertFalse([@"" gtm_subStringMatchesPattern:@"(foo)(.*)(bar)"]); |
| } |
| |
| - (void)testSegmentEnumeratorForPattern { |
| NSEnumerator *enumerator = |
| [@"afoobarbfooobaarfoobarzz" gtm_segmentEnumeratorForPattern:@"foo+ba+r"]; |
| XCTAssertNotNil(enumerator); |
| // "a" |
| GTMRegexStringSegment *seg = [enumerator nextObject]; |
| XCTAssertNotNil(seg); |
| XCTAssertFalse([seg isMatch]); |
| XCTAssertEqualStrings([seg string], @"a"); |
| // "foobar" |
| seg = [enumerator nextObject]; |
| XCTAssertNotNil(seg); |
| XCTAssertTrue([seg isMatch]); |
| XCTAssertEqualStrings([seg string], @"foobar"); |
| // "b" |
| seg = [enumerator nextObject]; |
| XCTAssertNotNil(seg); |
| XCTAssertFalse([seg isMatch]); |
| XCTAssertEqualStrings([seg string], @"b"); |
| // "fooobaar" |
| seg = [enumerator nextObject]; |
| XCTAssertNotNil(seg); |
| XCTAssertTrue([seg isMatch]); |
| XCTAssertEqualStrings([seg string], @"fooobaar"); |
| // "foobar" |
| seg = [enumerator nextObject]; |
| XCTAssertNotNil(seg); |
| XCTAssertTrue([seg isMatch]); |
| XCTAssertEqualStrings([seg string], @"foobar"); |
| // "zz" |
| seg = [enumerator nextObject]; |
| XCTAssertNotNil(seg); |
| XCTAssertFalse([seg isMatch]); |
| XCTAssertEqualStrings([seg string], @"zz"); |
| // (end) |
| seg = [enumerator nextObject]; |
| XCTAssertNil(seg); |
| |
| // test no match |
| enumerator = [@"aaa" gtm_segmentEnumeratorForPattern:@"foo+ba+r"]; |
| XCTAssertNotNil(enumerator); |
| seg = [enumerator nextObject]; |
| XCTAssertNotNil(seg); |
| XCTAssertFalse([seg isMatch]); |
| XCTAssertEqualStrings([seg string], @"aaa"); |
| seg = [enumerator nextObject]; |
| XCTAssertNil(seg); |
| |
| // test only match |
| enumerator = [@"foobar" gtm_segmentEnumeratorForPattern:@"foo+ba+r"]; |
| XCTAssertNotNil(enumerator); |
| seg = [enumerator nextObject]; |
| XCTAssertNotNil(seg); |
| XCTAssertTrue([seg isMatch]); |
| XCTAssertEqualStrings([seg string], @"foobar"); |
| seg = [enumerator nextObject]; |
| XCTAssertNil(seg); |
| |
| // now test the saved sub segments |
| enumerator = |
| [@"foobarxxfoobaz" gtm_segmentEnumeratorForPattern:@"(foo)((bar)|(baz))"]; |
| XCTAssertNotNil(enumerator); |
| // "foobar" |
| seg = [enumerator nextObject]; |
| XCTAssertNotNil(seg); |
| XCTAssertTrue([seg isMatch]); |
| XCTAssertEqualStrings([seg string], @"foobar"); |
| XCTAssertEqualStrings([seg subPatternString:0], @"foobar"); |
| XCTAssertEqualStrings([seg subPatternString:1], @"foo"); |
| XCTAssertEqualStrings([seg subPatternString:2], @"bar"); |
| XCTAssertEqualStrings([seg subPatternString:3], @"bar"); |
| XCTAssertNil([seg subPatternString:4]); // nothing matched "(baz)" |
| XCTAssertNil([seg subPatternString:5]); |
| // "xx" |
| seg = [enumerator nextObject]; |
| XCTAssertNotNil(seg); |
| XCTAssertFalse([seg isMatch]); |
| XCTAssertEqualStrings([seg string], @"xx"); |
| XCTAssertEqualStrings([seg subPatternString:0], @"xx"); |
| XCTAssertNil([seg subPatternString:1]); |
| // "foobaz" |
| seg = [enumerator nextObject]; |
| XCTAssertNotNil(seg); |
| XCTAssertTrue([seg isMatch]); |
| XCTAssertEqualStrings([seg string], @"foobaz"); |
| XCTAssertEqualStrings([seg subPatternString:0], @"foobaz"); |
| XCTAssertEqualStrings([seg subPatternString:1], @"foo"); |
| XCTAssertEqualStrings([seg subPatternString:2], @"baz"); |
| XCTAssertNil([seg subPatternString:3]); // (nothing matched "(bar)" |
| XCTAssertEqualStrings([seg subPatternString:4], @"baz"); |
| XCTAssertNil([seg subPatternString:5]); |
| // (end) |
| seg = [enumerator nextObject]; |
| XCTAssertNil(seg); |
| |
| // test all objects |
| enumerator = [@"afoobarbfooobaarfoobarzz" gtm_segmentEnumeratorForPattern:@"foo+ba+r"]; |
| XCTAssertNotNil(enumerator); |
| NSArray *allSegments = [enumerator allObjects]; |
| XCTAssertNotNil(allSegments); |
| XCTAssertEqual((NSUInteger)6, [allSegments count]); |
| } |
| |
| - (void)testMatchSegmentEnumeratorForPattern { |
| NSEnumerator *enumerator = |
| [@"afoobarbfooobaarfoobarzz" gtm_matchSegmentEnumeratorForPattern:@"foo+ba+r"]; |
| XCTAssertNotNil(enumerator); |
| // "a" - skipped |
| // "foobar" |
| GTMRegexStringSegment *seg = [enumerator nextObject]; |
| XCTAssertNotNil(seg); |
| XCTAssertTrue([seg isMatch]); |
| XCTAssertEqualStrings([seg string], @"foobar"); |
| // "b" - skipped |
| // "fooobaar" |
| seg = [enumerator nextObject]; |
| XCTAssertNotNil(seg); |
| XCTAssertTrue([seg isMatch]); |
| XCTAssertEqualStrings([seg string], @"fooobaar"); |
| // "foobar" |
| seg = [enumerator nextObject]; |
| XCTAssertNotNil(seg); |
| XCTAssertTrue([seg isMatch]); |
| XCTAssertEqualStrings([seg string], @"foobar"); |
| // "zz" - skipped |
| // (end) |
| seg = [enumerator nextObject]; |
| XCTAssertNil(seg); |
| |
| // test no match |
| enumerator = [@"aaa" gtm_matchSegmentEnumeratorForPattern:@"foo+ba+r"]; |
| XCTAssertNotNil(enumerator); |
| seg = [enumerator nextObject]; |
| XCTAssertNil(seg); |
| |
| // test only match |
| enumerator = [@"foobar" gtm_matchSegmentEnumeratorForPattern:@"foo+ba+r"]; |
| XCTAssertNotNil(enumerator); |
| seg = [enumerator nextObject]; |
| XCTAssertNotNil(seg); |
| XCTAssertTrue([seg isMatch]); |
| XCTAssertEqualStrings([seg string], @"foobar"); |
| seg = [enumerator nextObject]; |
| XCTAssertNil(seg); |
| |
| // now test the saved sub segments |
| enumerator = |
| [@"foobarxxfoobaz" gtm_matchSegmentEnumeratorForPattern:@"(foo)((bar)|(baz))"]; |
| XCTAssertNotNil(enumerator); |
| // "foobar" |
| seg = [enumerator nextObject]; |
| XCTAssertNotNil(seg); |
| XCTAssertTrue([seg isMatch]); |
| XCTAssertEqualStrings([seg string], @"foobar"); |
| XCTAssertEqualStrings([seg subPatternString:0], @"foobar"); |
| XCTAssertEqualStrings([seg subPatternString:1], @"foo"); |
| XCTAssertEqualStrings([seg subPatternString:2], @"bar"); |
| XCTAssertEqualStrings([seg subPatternString:3], @"bar"); |
| XCTAssertNil([seg subPatternString:4]); // nothing matched "(baz)" |
| XCTAssertNil([seg subPatternString:5]); |
| // "xx" - skipped |
| // "foobaz" |
| seg = [enumerator nextObject]; |
| XCTAssertNotNil(seg); |
| XCTAssertTrue([seg isMatch]); |
| XCTAssertEqualStrings([seg string], @"foobaz"); |
| XCTAssertEqualStrings([seg subPatternString:0], @"foobaz"); |
| XCTAssertEqualStrings([seg subPatternString:1], @"foo"); |
| XCTAssertEqualStrings([seg subPatternString:2], @"baz"); |
| XCTAssertNil([seg subPatternString:3]); // (nothing matched "(bar)" |
| XCTAssertEqualStrings([seg subPatternString:4], @"baz"); |
| XCTAssertNil([seg subPatternString:5]); |
| // (end) |
| seg = [enumerator nextObject]; |
| XCTAssertNil(seg); |
| |
| // test all objects |
| enumerator = [@"afoobarbfooobaarfoobarzz" gtm_matchSegmentEnumeratorForPattern:@"foo+ba+r"]; |
| XCTAssertNotNil(enumerator); |
| NSArray *allSegments = [enumerator allObjects]; |
| XCTAssertNotNil(allSegments); |
| XCTAssertEqual((NSUInteger)3, [allSegments count]); |
| } |
| |
| - (void)testAllSubstringsMatchedByPattern { |
| NSArray *segments = |
| [@"afoobarbfooobaarfoobarzz" gtm_allSubstringsMatchedByPattern:@"foo+ba+r"]; |
| XCTAssertNotNil(segments); |
| XCTAssertEqual((NSUInteger)3, [segments count]); |
| XCTAssertEqualStrings([segments objectAtIndex:0], @"foobar"); |
| XCTAssertEqualStrings([segments objectAtIndex:1], @"fooobaar"); |
| XCTAssertEqualStrings([segments objectAtIndex:2], @"foobar"); |
| |
| // test no match |
| segments = [@"aaa" gtm_allSubstringsMatchedByPattern:@"foo+ba+r"]; |
| XCTAssertNotNil(segments); |
| XCTAssertEqual((NSUInteger)0, [segments count]); |
| |
| // test only match |
| segments = [@"foobar" gtm_allSubstringsMatchedByPattern:@"foo+ba+r"]; |
| XCTAssertNotNil(segments); |
| XCTAssertEqual((NSUInteger)1, [segments count]); |
| XCTAssertEqualStrings([segments objectAtIndex:0], @"foobar"); |
| } |
| |
| - (void)testStringByReplacingMatchesOfPatternWithReplacement { |
| // the basics |
| XCTAssertEqualStrings(@"weeZbarZbydoo spamZfooZdoggies", |
| [@"weefoobydoo spambardoggies" gtm_stringByReplacingMatchesOfPattern:@"(foo)(.*)(bar)" |
| withReplacement:@"Z\\3Z\\2Z\\1Z"]); |
| // nil/empty replacement |
| XCTAssertEqualStrings(@"weedoggies", |
| [@"weefoobydoo spambardoggies" gtm_stringByReplacingMatchesOfPattern:@"(foo)(.*)(bar)" |
| withReplacement:nil]); |
| XCTAssertEqualStrings(@"weedoggies", |
| [@"weefoobydoo spambardoggies" gtm_stringByReplacingMatchesOfPattern:@"(foo)(.*)(bar)" |
| withReplacement:@""]); |
| XCTAssertEqualStrings(@"", |
| [@"" gtm_stringByReplacingMatchesOfPattern:@"(foo)(.*)(bar)" |
| withReplacement:@"abc"]); |
| // use optional and invale subexpression parts to confirm that works |
| XCTAssertEqualStrings(@"aaa baz bar bar foo baz aaa", |
| [@"aaa foooooobaz fooobar bar foo baz aaa" gtm_stringByReplacingMatchesOfPattern:@"(fo(o+))((bar)|(baz))" |
| withReplacement:@"\\4\\5"]); |
| XCTAssertEqualStrings(@"aaa ZZZ ZZZ bar foo baz aaa", |
| [@"aaa foooooobaz fooobar bar foo baz aaa" gtm_stringByReplacingMatchesOfPattern:@"(fo(o+))((bar)|(baz))" |
| withReplacement:@"Z\\10Z\\12Z"]); |
| // test slashes in replacement that aren't part of the subpattern reference |
| XCTAssertEqualStrings(@"z\\\\0 \\\\a \\\\\\\\0z", |
| [@"zaz" gtm_stringByReplacingMatchesOfPattern:@"a+" |
| withReplacement:@"\\\\0 \\\\\\0 \\\\\\\\0"]); |
| XCTAssertEqualStrings(@"z\\\\a \\\\\\\\0 \\\\\\\\az", |
| [@"zaz" gtm_stringByReplacingMatchesOfPattern:@"a+" |
| withReplacement:@"\\\\\\0 \\\\\\\\0 \\\\\\\\\\0"]); |
| XCTAssertEqualStrings(@"z\\\\\\\\0 \\\\\\\\a \\\\\\\\\\\\0z", |
| [@"zaz" gtm_stringByReplacingMatchesOfPattern:@"a+" |
| withReplacement:@"\\\\\\\\0 \\\\\\\\\\0 \\\\\\\\\\\\0"]); |
| } |
| |
| @end |
| |
| #pragma clang diagnostic pop |