diff options
Diffstat (limited to 'Foundation/GTMRegexTest.m')
-rw-r--r-- | Foundation/GTMRegexTest.m | 955 |
1 files changed, 955 insertions, 0 deletions
diff --git a/Foundation/GTMRegexTest.m b/Foundation/GTMRegexTest.m new file mode 100644 index 0000000..ef7d1e5 --- /dev/null +++ b/Foundation/GTMRegexTest.m @@ -0,0 +1,955 @@ +// +// 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 <SenTestingKit/SenTestingKit.h> + +#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. +// + +@interface GTMRegexTest : SenTestCase +@end + +@interface NSString_GTMRegexAdditions : SenTestCase +@end + +@implementation GTMRegexTest + +- (void)testEscapedPatternForString { + STAssertEqualStrings([GTMRegex escapedPatternForString:@"abcdefghijklmnopqrstuvwxyz0123456789"], + @"abcdefghijklmnopqrstuvwxyz0123456789", + nil); + STAssertEqualStrings([GTMRegex escapedPatternForString:@"^.[$()|*+?{\\"], + @"\\^\\.\\[\\$\\(\\)\\|\\*\\+\\?\\{\\\\", + nil); + STAssertEqualStrings([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", + nil); + + STAssertNil([GTMRegex escapedPatternForString:nil], nil); + STAssertEqualStrings([GTMRegex escapedPatternForString:@""], @"", nil); +} + + +- (void)testInit { + + // fail cases + STAssertNil([[[GTMRegex alloc] init] autorelease], nil); + STAssertNil([[[GTMRegex alloc] initWithPattern:nil] autorelease], nil); + STAssertNil([[[GTMRegex alloc] initWithPattern:nil + options:kGTMRegexOptionIgnoreCase] autorelease], nil); + STAssertNil([[[GTMRegex alloc] initWithPattern:@"(."] autorelease], nil); + STAssertNil([[[GTMRegex alloc] initWithPattern:@"(." + options:kGTMRegexOptionIgnoreCase] autorelease], nil); + + // basic pattern w/ options + STAssertNotNil([[[GTMRegex alloc] initWithPattern:@"(.*)"] autorelease], nil); + STAssertNotNil([[[GTMRegex alloc] initWithPattern:@"(.*)" + options:0] autorelease], nil); + STAssertNotNil([[[GTMRegex alloc] initWithPattern:@"(.*)" + options:kGTMRegexOptionIgnoreCase] autorelease], nil); + + // fail cases (helper) + STAssertNil([GTMRegex regexWithPattern:nil], nil); + STAssertNil([GTMRegex regexWithPattern:nil + options:0], nil); + STAssertNil([GTMRegex regexWithPattern:@"(."], nil); + STAssertNil([GTMRegex regexWithPattern:@"(." + options:0], nil); + + // basic pattern w/ options (helper) + STAssertNotNil([GTMRegex regexWithPattern:@"(.*)"], nil); + STAssertNotNil([GTMRegex regexWithPattern:@"(.*)" + options:0], nil); + STAssertNotNil([GTMRegex regexWithPattern:@"(.*)" + options:kGTMRegexOptionIgnoreCase], nil); +} + +- (void)testOptions { + + NSString *testString = @"aaa AAA\nbbb BBB\n aaa aAa\n bbb BbB"; + + // default options + GTMRegex *regex = [GTMRegex regexWithPattern:@"a+"]; + STAssertNotNil(regex, nil); + NSEnumerator *enumerator = [regex segmentEnumeratorForString:testString]; + STAssertNotNil(enumerator, nil); + // "aaa" + GTMRegexStringSegment *seg = [enumerator nextObject]; + STAssertNotNil(seg, nil); + STAssertTrue([seg isMatch], nil); + STAssertEqualStrings([seg string], @"aaa", nil); + // " AAA\nbbb BBB\n " + seg = [enumerator nextObject]; + STAssertNotNil(seg, nil); + STAssertFalse([seg isMatch], nil); + STAssertEqualStrings([seg string], @" AAA\nbbb BBB\n ", nil); + // "aaa" + seg = [enumerator nextObject]; + STAssertNotNil(seg, nil); + STAssertTrue([seg isMatch], nil); + STAssertEqualStrings([seg string], @"aaa", nil); + // " " + seg = [enumerator nextObject]; + STAssertNotNil(seg, nil); + STAssertFalse([seg isMatch], nil); + STAssertEqualStrings([seg string], @" ", nil); + // "a" + seg = [enumerator nextObject]; + STAssertNotNil(seg, nil); + STAssertTrue([seg isMatch], nil); + STAssertEqualStrings([seg string], @"a", nil); + // "A" + seg = [enumerator nextObject]; + STAssertNotNil(seg, nil); + STAssertFalse([seg isMatch], nil); + STAssertEqualStrings([seg string], @"A", nil); + // "a" + seg = [enumerator nextObject]; + STAssertNotNil(seg, nil); + STAssertTrue([seg isMatch], nil); + STAssertEqualStrings([seg string], @"a", nil); + // "\n bbb BbB" + seg = [enumerator nextObject]; + STAssertNotNil(seg, nil); + STAssertFalse([seg isMatch], nil); + STAssertEqualStrings([seg string], @"\n bbb BbB", nil); + // (end) + seg = [enumerator nextObject]; + STAssertNil(seg, nil); + + // kGTMRegexOptionIgnoreCase + regex = [GTMRegex regexWithPattern:@"a+" options:kGTMRegexOptionIgnoreCase]; + STAssertNotNil(regex, nil); + enumerator = [regex segmentEnumeratorForString:testString]; + STAssertNotNil(enumerator, nil); + // "aaa" + seg = [enumerator nextObject]; + STAssertNotNil(seg, nil); + STAssertTrue([seg isMatch], nil); + STAssertEqualStrings([seg string], @"aaa", nil); + // " " + seg = [enumerator nextObject]; + STAssertNotNil(seg, nil); + STAssertFalse([seg isMatch], nil); + STAssertEqualStrings([seg string], @" ", nil); + // "AAA" + seg = [enumerator nextObject]; + STAssertNotNil(seg, nil); + STAssertTrue([seg isMatch], nil); + STAssertEqualStrings([seg string], @"AAA", nil); + // "\nbbb BBB\n " + seg = [enumerator nextObject]; + STAssertNotNil(seg, nil); + STAssertFalse([seg isMatch], nil); + STAssertEqualStrings([seg string], @"\nbbb BBB\n ", nil); + // "aaa" + seg = [enumerator nextObject]; + STAssertNotNil(seg, nil); + STAssertTrue([seg isMatch], nil); + STAssertEqualStrings([seg string], @"aaa", nil); + // " " + seg = [enumerator nextObject]; + STAssertNotNil(seg, nil); + STAssertFalse([seg isMatch], nil); + STAssertEqualStrings([seg string], @" ", nil); + // "aAa" + seg = [enumerator nextObject]; + STAssertNotNil(seg, nil); + STAssertTrue([seg isMatch], nil); + STAssertEqualStrings([seg string], @"aAa", nil); + // "\n bbb BbB" + seg = [enumerator nextObject]; + STAssertNotNil(seg, nil); + STAssertFalse([seg isMatch], nil); + STAssertEqualStrings([seg string], @"\n bbb BbB", nil); + // (end) + seg = [enumerator nextObject]; + STAssertNil(seg, nil); + + // defaults w/ '^' + regex = [GTMRegex regexWithPattern:@"^a+"]; + STAssertNotNil(regex, nil); + enumerator = [regex segmentEnumeratorForString:testString]; + STAssertNotNil(enumerator, nil); + // "aaa" + seg = [enumerator nextObject]; + STAssertNotNil(seg, nil); + STAssertTrue([seg isMatch], nil); + STAssertEqualStrings([seg string], @"aaa", nil); + // " AAA\nbbb BBB\n aaa aAa\n bbb BbB" + seg = [enumerator nextObject]; + STAssertNotNil(seg, nil); + STAssertFalse([seg isMatch], nil); + STAssertEqualStrings([seg string], @" AAA\nbbb BBB\n aaa aAa\n bbb BbB", nil); + // (end) + seg = [enumerator nextObject]; + STAssertNil(seg, nil); + + // defaults w/ '$' + regex = [GTMRegex regexWithPattern:@"B+$"]; + STAssertNotNil(regex, nil); + enumerator = [regex segmentEnumeratorForString:testString]; + STAssertNotNil(enumerator, nil); + // "aaa AAA\nbbb " + seg = [enumerator nextObject]; + STAssertNotNil(seg, nil); + STAssertFalse([seg isMatch], nil); + STAssertEqualStrings([seg string], @"aaa AAA\nbbb ", nil); + // "BBB" + seg = [enumerator nextObject]; + STAssertNotNil(seg, nil); + STAssertTrue([seg isMatch], nil); + STAssertEqualStrings([seg string], @"BBB", nil); + // "\n aaa aAa\n bbb Bb" + seg = [enumerator nextObject]; + STAssertNotNil(seg, nil); + STAssertFalse([seg isMatch], nil); + STAssertEqualStrings([seg string], @"\n aaa aAa\n bbb Bb", nil); + // "B" + seg = [enumerator nextObject]; + STAssertNotNil(seg, nil); + STAssertTrue([seg isMatch], nil); + STAssertEqualStrings([seg string], @"B", nil); + // (end) + seg = [enumerator nextObject]; + STAssertNil(seg, nil); + + // kGTMRegexOptionIgnoreCase w/ '$' + regex = [GTMRegex regexWithPattern:@"B+$" + options:kGTMRegexOptionIgnoreCase]; + STAssertNotNil(regex, nil); + enumerator = [regex segmentEnumeratorForString:testString]; + STAssertNotNil(enumerator, nil); + // "aaa AAA\nbbb " + seg = [enumerator nextObject]; + STAssertNotNil(seg, nil); + STAssertFalse([seg isMatch], nil); + STAssertEqualStrings([seg string], @"aaa AAA\nbbb ", nil); + // "BBB" + seg = [enumerator nextObject]; + STAssertNotNil(seg, nil); + STAssertTrue([seg isMatch], nil); + STAssertEqualStrings([seg string], @"BBB", nil); + // "\n aaa aAa\n bbb " + seg = [enumerator nextObject]; + STAssertNotNil(seg, nil); + STAssertFalse([seg isMatch], nil); + STAssertEqualStrings([seg string], @"\n aaa aAa\n bbb ", nil); + // "BbB" + seg = [enumerator nextObject]; + STAssertNotNil(seg, nil); + STAssertTrue([seg isMatch], nil); + STAssertEqualStrings([seg string], @"BbB", nil); + // (end) + seg = [enumerator nextObject]; + STAssertNil(seg, nil); + + // test w/ kGTMRegexOptionSupressNewlineSupport and \n in the string + regex = [GTMRegex regexWithPattern:@"a.*b" options:kGTMRegexOptionSupressNewlineSupport]; + STAssertNotNil(regex, nil); + enumerator = [regex segmentEnumeratorForString:testString]; + STAssertNotNil(enumerator, nil); + // "aaa AAA\nbbb BBB\n aaa aAa\n bbb Bb" + seg = [enumerator nextObject]; + STAssertNotNil(seg, nil); + STAssertTrue([seg isMatch], nil); + STAssertEqualStrings([seg string], @"aaa AAA\nbbb BBB\n aaa aAa\n bbb Bb", nil); + // "B" + seg = [enumerator nextObject]; + STAssertNotNil(seg, nil); + STAssertFalse([seg isMatch], nil); + STAssertEqualStrings([seg string], @"B", nil); + // (end) + seg = [enumerator nextObject]; + STAssertNil(seg, nil); + + // 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"]; + STAssertNotNil(regex, nil); + enumerator = [regex segmentEnumeratorForString:testString]; + STAssertNotNil(enumerator, nil); + // "aaa AAA\nbbb BBB\n aaa aAa\n bbb BbB" + seg = [enumerator nextObject]; + STAssertNotNil(seg, nil); + STAssertFalse([seg isMatch], nil); + STAssertEqualStrings([seg string], @"aaa AAA\nbbb BBB\n aaa aAa\n bbb BbB", nil); + // (end) + seg = [enumerator nextObject]; + STAssertNil(seg, nil); + + // kGTMRegexOptionSupressNewlineSupport w/ '^' + regex = [GTMRegex regexWithPattern:@"^a+" options:kGTMRegexOptionSupressNewlineSupport]; + STAssertNotNil(regex, nil); + enumerator = [regex segmentEnumeratorForString:testString]; + STAssertNotNil(enumerator, nil); + // "aaa" + seg = [enumerator nextObject]; + STAssertNotNil(seg, nil); + STAssertTrue([seg isMatch], nil); + STAssertEqualStrings([seg string], @"aaa", nil); + // " AAA\nbbb BBB\n aaa aAa\n bbb BbB" + seg = [enumerator nextObject]; + STAssertNotNil(seg, nil); + STAssertFalse([seg isMatch], nil); + STAssertEqualStrings([seg string], @" AAA\nbbb BBB\n aaa aAa\n bbb BbB", nil); + // (end) + seg = [enumerator nextObject]; + STAssertNil(seg, nil); + + // kGTMRegexOptionSupressNewlineSupport w/ '$' + regex = [GTMRegex regexWithPattern:@"B+$" options:kGTMRegexOptionSupressNewlineSupport]; + STAssertNotNil(regex, nil); + enumerator = [regex segmentEnumeratorForString:testString]; + STAssertNotNil(enumerator, nil); + // "aaa AAA\nbbb BBB\n aaa aAa\n bbb Bb" + seg = [enumerator nextObject]; + STAssertNotNil(seg, nil); + STAssertFalse([seg isMatch], nil); + STAssertEqualStrings([seg string], @"aaa AAA\nbbb BBB\n aaa aAa\n bbb Bb", nil); + // "B" + seg = [enumerator nextObject]; + STAssertNotNil(seg, nil); + STAssertTrue([seg isMatch], nil); + STAssertEqualStrings([seg string], @"B", nil); + // (end) + seg = [enumerator nextObject]; + STAssertNil(seg, nil); +} + +- (void)testSubPatternCount { + STAssertEquals(0, [[GTMRegex regexWithPattern:@".*"] subPatternCount], nil); + STAssertEquals(1, [[GTMRegex regexWithPattern:@"(.*)"] subPatternCount], nil); + STAssertEquals(1, [[GTMRegex regexWithPattern:@"[fo]*(.*)[bar]*"] subPatternCount], nil); + STAssertEquals(3, [[GTMRegex regexWithPattern:@"([fo]*)(.*)([bar]*)"] subPatternCount], nil); + STAssertEquals(7, [[GTMRegex regexWithPattern:@"(([bar]*)|([fo]*))(.*)(([bar]*)|([fo]*))"] subPatternCount], nil); +} + +- (void)testMatchesString { + // simple pattern + GTMRegex *regex = [GTMRegex regexWithPattern:@"foo.*bar"]; + STAssertNotNil(regex, nil); + STAssertTrue([regex matchesString:@"foobar"], nil); + STAssertTrue([regex matchesString:@"foobydoo spambar"], nil); + STAssertFalse([regex matchesString:@"zzfoobarzz"], nil); + STAssertFalse([regex matchesString:@"zzfoobydoo spambarzz"], nil); + STAssertFalse([regex matchesString:@"abcdef"], nil); + STAssertFalse([regex matchesString:@""], nil); + STAssertFalse([regex matchesString:nil], nil); + // pattern w/ sub patterns + regex = [GTMRegex regexWithPattern:@"(foo)(.*)(bar)"]; + STAssertNotNil(regex, nil); + STAssertTrue([regex matchesString:@"foobar"], nil); + STAssertTrue([regex matchesString:@"foobydoo spambar"], nil); + STAssertFalse([regex matchesString:@"zzfoobarzz"], nil); + STAssertFalse([regex matchesString:@"zzfoobydoo spambarzz"], nil); + STAssertFalse([regex matchesString:@"abcdef"], nil); + STAssertFalse([regex matchesString:@""], nil); + STAssertFalse([regex matchesString:nil], nil); +} + +- (void)testSubPatternsOfString { + GTMRegex *regex = [GTMRegex regexWithPattern:@"(fo(o+))((bar)|(baz))"]; + STAssertNotNil(regex, nil); + STAssertEquals(5, [regex subPatternCount], nil); + NSArray *subPatterns = [regex subPatternsOfString:@"foooooobaz"]; + STAssertNotNil(subPatterns, nil); + STAssertEquals(6U, [subPatterns count], nil); + STAssertEqualStrings(@"foooooobaz", [subPatterns objectAtIndex:0], nil); + STAssertEqualStrings(@"foooooo", [subPatterns objectAtIndex:1], nil); + STAssertEqualStrings(@"ooooo", [subPatterns objectAtIndex:2], nil); + STAssertEqualStrings(@"baz", [subPatterns objectAtIndex:3], nil); + STAssertTrue(([NSNull null] == [subPatterns objectAtIndex:4]), nil); + STAssertEqualStrings(@"baz", [subPatterns objectAtIndex:5], nil); + + // not there + subPatterns = [regex subPatternsOfString:@"aaa"]; + STAssertNil(subPatterns, nil); + + // not extra stuff on either end + subPatterns = [regex subPatternsOfString:@"ZZZfoooooobaz"]; + STAssertNil(subPatterns, nil); + subPatterns = [regex subPatternsOfString:@"foooooobazZZZ"]; + STAssertNil(subPatterns, nil); + subPatterns = [regex subPatternsOfString:@"ZZZfoooooobazZZZ"]; + STAssertNil(subPatterns, nil); +} + +- (void)testSegmentEnumeratorForString { + GTMRegex *regex = [GTMRegex regexWithPattern:@"foo+ba+r"]; + STAssertNotNil(regex, nil); + NSEnumerator *enumerator = [regex segmentEnumeratorForString:@"afoobarbfooobaarfoobarzz"]; + STAssertNotNil(enumerator, nil); + // "a" + GTMRegexStringSegment *seg = [enumerator nextObject]; + STAssertNotNil(seg, nil); + STAssertFalse([seg isMatch], nil); + STAssertEqualStrings([seg string], @"a", nil); + // "foobar" + seg = [enumerator nextObject]; + STAssertNotNil(seg, nil); + STAssertTrue([seg isMatch], nil); + STAssertEqualStrings([seg string], @"foobar", nil); + // "b" + seg = [enumerator nextObject]; + STAssertNotNil(seg, nil); + STAssertFalse([seg isMatch], nil); + STAssertEqualStrings([seg string], @"b", nil); + // "fooobaar" + seg = [enumerator nextObject]; + STAssertNotNil(seg, nil); + STAssertTrue([seg isMatch], nil); + STAssertEqualStrings([seg string], @"fooobaar", nil); + // "foobar" + seg = [enumerator nextObject]; + STAssertNotNil(seg, nil); + STAssertTrue([seg isMatch], nil); + STAssertEqualStrings([seg string], @"foobar", nil); + // "zz" + seg = [enumerator nextObject]; + STAssertNotNil(seg, nil); + STAssertFalse([seg isMatch], nil); + STAssertEqualStrings([seg string], @"zz", nil); + // (end) + seg = [enumerator nextObject]; + STAssertNil(seg, nil); + + // test no match + enumerator = [regex segmentEnumeratorForString:@"aaa"]; + STAssertNotNil(enumerator, nil); + seg = [enumerator nextObject]; + STAssertNotNil(seg, nil); + STAssertFalse([seg isMatch], nil); + STAssertEqualStrings([seg string], @"aaa", nil); + seg = [enumerator nextObject]; + STAssertNil(seg, nil); + + // test only match + enumerator = [regex segmentEnumeratorForString:@"foobar"]; + STAssertNotNil(enumerator, nil); + seg = [enumerator nextObject]; + STAssertNotNil(seg, nil); + STAssertTrue([seg isMatch], nil); + STAssertEqualStrings([seg string], @"foobar", nil); + seg = [enumerator nextObject]; + STAssertNil(seg, nil); + + // now test the saved sub segments + regex = [GTMRegex regexWithPattern:@"(foo)((bar)|(baz))"]; + STAssertNotNil(regex, nil); + STAssertEquals(4, [regex subPatternCount], nil); + enumerator = [regex segmentEnumeratorForString:@"foobarxxfoobaz"]; + STAssertNotNil(enumerator, nil); + // "foobar" + seg = [enumerator nextObject]; + STAssertNotNil(seg, nil); + STAssertTrue([seg isMatch], nil); + STAssertEqualStrings([seg string], @"foobar", nil); + STAssertEqualStrings([seg subPatternString:0], @"foobar", nil); + STAssertEqualStrings([seg subPatternString:1], @"foo", nil); + STAssertEqualStrings([seg subPatternString:2], @"bar", nil); + STAssertEqualStrings([seg subPatternString:3], @"bar", nil); + STAssertNil([seg subPatternString:4], nil); // nothing matched "(baz)" + STAssertNil([seg subPatternString:5], nil); + // "xx" + seg = [enumerator nextObject]; + STAssertNotNil(seg, nil); + STAssertFalse([seg isMatch], nil); + STAssertEqualStrings([seg string], @"xx", nil); + STAssertEqualStrings([seg subPatternString:0], @"xx", nil); + STAssertNil([seg subPatternString:1], nil); + // "foobaz" + seg = [enumerator nextObject]; + STAssertNotNil(seg, nil); + STAssertTrue([seg isMatch], nil); + STAssertEqualStrings([seg string], @"foobaz", nil); + STAssertEqualStrings([seg subPatternString:0], @"foobaz", nil); + STAssertEqualStrings([seg subPatternString:1], @"foo", nil); + STAssertEqualStrings([seg subPatternString:2], @"baz", nil); + STAssertNil([seg subPatternString:3], nil); // (nothing matched "(bar)" + STAssertEqualStrings([seg subPatternString:4], @"baz", nil); + STAssertNil([seg subPatternString:5], nil); + // (end) + seg = [enumerator nextObject]; + STAssertNil(seg, nil); + + // test all objects + regex = [GTMRegex regexWithPattern:@"foo+ba+r"]; + STAssertNotNil(regex, nil); + enumerator = [regex segmentEnumeratorForString:@"afoobarbfooobaarfoobarzz"]; + STAssertNotNil(enumerator, nil); + NSArray *allSegments = [enumerator allObjects]; + STAssertNotNil(allSegments, nil); + STAssertEquals(6U, [allSegments count], nil); +} + +- (void)testMatchSegmentEnumeratorForString { + GTMRegex *regex = [GTMRegex regexWithPattern:@"foo+ba+r"]; + STAssertNotNil(regex, nil); + NSEnumerator *enumerator = [regex matchSegmentEnumeratorForString:@"afoobarbfooobaarfoobarzz"]; + STAssertNotNil(enumerator, nil); + // "a" - skipped + // "foobar" + GTMRegexStringSegment *seg = [enumerator nextObject]; + STAssertNotNil(seg, nil); + STAssertTrue([seg isMatch], nil); + STAssertEqualStrings([seg string], @"foobar", nil); + // "b" - skipped + // "fooobaar" + seg = [enumerator nextObject]; + STAssertNotNil(seg, nil); + STAssertTrue([seg isMatch], nil); + STAssertEqualStrings([seg string], @"fooobaar", nil); + // "foobar" + seg = [enumerator nextObject]; + STAssertNotNil(seg, nil); + STAssertTrue([seg isMatch], nil); + STAssertEqualStrings([seg string], @"foobar", nil); + // "zz" - skipped + // (end) + seg = [enumerator nextObject]; + STAssertNil(seg, nil); + + // test no match + enumerator = [regex matchSegmentEnumeratorForString:@"aaa"]; + STAssertNotNil(enumerator, nil); + seg = [enumerator nextObject]; + STAssertNil(seg, nil); // should have gotten nothing + + // test only match + enumerator = [regex matchSegmentEnumeratorForString:@"foobar"]; + STAssertNotNil(enumerator, nil); + seg = [enumerator nextObject]; + STAssertNotNil(seg, nil); + STAssertTrue([seg isMatch], nil); + STAssertEqualStrings([seg string], @"foobar", nil); + seg = [enumerator nextObject]; + STAssertNil(seg, nil); + + // now test the saved sub segments + regex = [GTMRegex regexWithPattern:@"(foo)((bar)|(baz))"]; + STAssertNotNil(regex, nil); + STAssertEquals(4, [regex subPatternCount], nil); + enumerator = [regex matchSegmentEnumeratorForString:@"foobarxxfoobaz"]; + STAssertNotNil(enumerator, nil); + // "foobar" + seg = [enumerator nextObject]; + STAssertNotNil(seg, nil); + STAssertTrue([seg isMatch], nil); + STAssertEqualStrings([seg string], @"foobar", nil); + STAssertEqualStrings([seg subPatternString:0], @"foobar", nil); + STAssertEqualStrings([seg subPatternString:1], @"foo", nil); + STAssertEqualStrings([seg subPatternString:2], @"bar", nil); + STAssertEqualStrings([seg subPatternString:3], @"bar", nil); + STAssertNil([seg subPatternString:4], nil); // nothing matched "(baz)" + STAssertNil([seg subPatternString:5], nil); + // "xx" - skipped + // "foobaz" + seg = [enumerator nextObject]; + STAssertNotNil(seg, nil); + STAssertTrue([seg isMatch], nil); + STAssertEqualStrings([seg string], @"foobaz", nil); + STAssertEqualStrings([seg subPatternString:0], @"foobaz", nil); + STAssertEqualStrings([seg subPatternString:1], @"foo", nil); + STAssertEqualStrings([seg subPatternString:2], @"baz", nil); + STAssertNil([seg subPatternString:3], nil); // (nothing matched "(bar)" + STAssertEqualStrings([seg subPatternString:4], @"baz", nil); + STAssertNil([seg subPatternString:5], nil); + // (end) + seg = [enumerator nextObject]; + STAssertNil(seg, nil); + + // test all objects + regex = [GTMRegex regexWithPattern:@"foo+ba+r"]; + STAssertNotNil(regex, nil); + enumerator = [regex matchSegmentEnumeratorForString:@"afoobarbfooobaarfoobarzz"]; + STAssertNotNil(enumerator, nil); + NSArray *allSegments = [enumerator allObjects]; + STAssertNotNil(allSegments, nil); + STAssertEquals(3U, [allSegments count], nil); +} + +- (void)testStringByReplacingMatchesInStringWithReplacement { + GTMRegex *regex = [GTMRegex regexWithPattern:@"(foo)(.*)(bar)"]; + STAssertNotNil(regex, nil); + // the basics + STAssertEqualStrings(@"weeZbarZbydoo spamZfooZdoggies", + [regex stringByReplacingMatchesInString:@"weefoobydoo spambardoggies" + withReplacement:@"Z\\3Z\\2Z\\1Z"], + nil); + // nil/empty replacement + STAssertEqualStrings(@"weedoggies", + [regex stringByReplacingMatchesInString:@"weefoobydoo spambardoggies" + withReplacement:nil], + nil); + STAssertEqualStrings(@"weedoggies", + [regex stringByReplacingMatchesInString:@"weefoobydoo spambardoggies" + withReplacement:@""], + nil); + // use optional and invale subexpression parts to confirm that works + regex = [GTMRegex regexWithPattern:@"(fo(o+))((bar)|(baz))"]; + STAssertNotNil(regex, nil); + STAssertEqualStrings(@"aaa baz bar bar foo baz aaa", + [regex stringByReplacingMatchesInString:@"aaa foooooobaz fooobar bar foo baz aaa" + withReplacement:@"\\4\\5"], + nil); + STAssertEqualStrings(@"aaa ZZZ ZZZ bar foo baz aaa", + [regex stringByReplacingMatchesInString:@"aaa foooooobaz fooobar bar foo baz aaa" + withReplacement:@"Z\\10Z\\12Z"], + nil); + // test slashes in replacement that aren't part of the subpattern reference + regex = [GTMRegex regexWithPattern:@"a+"]; + STAssertNotNil(regex, nil); + STAssertEqualStrings(@"z\\\\0 \\\\a \\\\\\\\0z", + [regex stringByReplacingMatchesInString:@"zaz" + withReplacement:@"\\\\0 \\\\\\0 \\\\\\\\0"], + nil); + STAssertEqualStrings(@"z\\\\a \\\\\\\\0 \\\\\\\\az", + [regex stringByReplacingMatchesInString:@"zaz" + withReplacement:@"\\\\\\0 \\\\\\\\0 \\\\\\\\\\0"], + nil); + STAssertEqualStrings(@"z\\\\\\\\0 \\\\\\\\a \\\\\\\\\\\\0z", + [regex stringByReplacingMatchesInString:@"zaz" + withReplacement:@"\\\\\\\\0 \\\\\\\\\\0 \\\\\\\\\\\\0"], + nil); +} + +@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 + STAssertTrue([@"foobar" gtm_matchesPattern:@"foo.*bar"], nil); + STAssertTrue([@"foobydoo spambar" gtm_matchesPattern:@"foo.*bar"], nil); + STAssertFalse([@"zzfoobarzz" gtm_matchesPattern:@"foo.*bar"], nil); + STAssertFalse([@"zzfoobydoo spambarzz" gtm_matchesPattern:@"foo.*bar"], nil); + STAssertFalse([@"abcdef" gtm_matchesPattern:@"foo.*bar"], nil); + STAssertFalse([@"" gtm_matchesPattern:@"foo.*bar"], nil); + // pattern w/ sub patterns + STAssertTrue([@"foobar" gtm_matchesPattern:@"(foo)(.*)(bar)"], nil); + STAssertTrue([@"foobydoo spambar" gtm_matchesPattern:@"(foo)(.*)(bar)"], nil); + STAssertFalse([@"zzfoobarzz" gtm_matchesPattern:@"(foo)(.*)(bar)"], nil); + STAssertFalse([@"zzfoobydoo spambarzz" gtm_matchesPattern:@"(foo)(.*)(bar)"], nil); + STAssertFalse([@"abcdef" gtm_matchesPattern:@"(foo)(.*)(bar)"], nil); + STAssertFalse([@"" gtm_matchesPattern:@"(foo)(.*)(bar)"], nil); +} + +- (void)testSubPatternsOfPattern { + NSArray *subPatterns = [@"foooooobaz" gtm_subPatternsOfPattern:@"(fo(o+))((bar)|(baz))"]; + STAssertNotNil(subPatterns, nil); + STAssertEquals(6U, [subPatterns count], nil); + STAssertEqualStrings(@"foooooobaz", [subPatterns objectAtIndex:0], nil); + STAssertEqualStrings(@"foooooo", [subPatterns objectAtIndex:1], nil); + STAssertEqualStrings(@"ooooo", [subPatterns objectAtIndex:2], nil); + STAssertEqualStrings(@"baz", [subPatterns objectAtIndex:3], nil); + STAssertTrue(([NSNull null] == [subPatterns objectAtIndex:4]), nil); + STAssertEqualStrings(@"baz", [subPatterns objectAtIndex:5], nil); + + // not there + subPatterns = [@"aaa" gtm_subPatternsOfPattern:@"(fo(o+))((bar)|(baz))"]; + STAssertNil(subPatterns, nil); + + // not extra stuff on either end + subPatterns = [@"ZZZfoooooobaz" gtm_subPatternsOfPattern:@"(fo(o+))((bar)|(baz))"]; + STAssertNil(subPatterns, nil); + subPatterns = [@"foooooobazZZZ" gtm_subPatternsOfPattern:@"(fo(o+))((bar)|(baz))"]; + STAssertNil(subPatterns, nil); + subPatterns = [@"ZZZfoooooobazZZZ" gtm_subPatternsOfPattern:@"(fo(o+))((bar)|(baz))"]; + STAssertNil(subPatterns, nil); +} + +- (void)testFirstSubStringMatchedByPattern { + // simple pattern + STAssertEqualStrings([@"foobar" gtm_firstSubStringMatchedByPattern:@"foo.*bar"], + @"foobar", nil); + STAssertEqualStrings([@"foobydoo spambar" gtm_firstSubStringMatchedByPattern:@"foo.*bar"], + @"foobydoo spambar", nil); + STAssertEqualStrings([@"zzfoobarzz" gtm_firstSubStringMatchedByPattern:@"foo.*bar"], + @"foobar", nil); + STAssertEqualStrings([@"zzfoobydoo spambarzz" gtm_firstSubStringMatchedByPattern:@"foo.*bar"], + @"foobydoo spambar", nil); + STAssertNil([@"abcdef" gtm_firstSubStringMatchedByPattern:@"foo.*bar"], nil); + STAssertNil([@"" gtm_firstSubStringMatchedByPattern:@"foo.*bar"], nil); + // pattern w/ sub patterns + STAssertEqualStrings([@"foobar" gtm_firstSubStringMatchedByPattern:@"(foo)(.*)(bar)"], + @"foobar", nil); + STAssertEqualStrings([@"foobydoo spambar" gtm_firstSubStringMatchedByPattern:@"(foo)(.*)(bar)"], + @"foobydoo spambar", nil); + STAssertEqualStrings([@"zzfoobarzz" gtm_firstSubStringMatchedByPattern:@"(foo)(.*)(bar)"], + @"foobar", nil); + STAssertEqualStrings([@"zzfoobydoo spambarzz" gtm_firstSubStringMatchedByPattern:@"(foo)(.*)(bar)"], + @"foobydoo spambar", nil); + STAssertNil([@"abcdef" gtm_firstSubStringMatchedByPattern:@"(foo)(.*)(bar)"], nil); + STAssertNil([@"" gtm_firstSubStringMatchedByPattern:@"(foo)(.*)(bar)"], nil); +} + +- (void)testSegmentEnumeratorForPattern { + NSEnumerator *enumerator = + [@"afoobarbfooobaarfoobarzz" gtm_segmentEnumeratorForPattern:@"foo+ba+r"]; + STAssertNotNil(enumerator, nil); + // "a" + GTMRegexStringSegment *seg = [enumerator nextObject]; + STAssertNotNil(seg, nil); + STAssertFalse([seg isMatch], nil); + STAssertEqualStrings([seg string], @"a", nil); + // "foobar" + seg = [enumerator nextObject]; + STAssertNotNil(seg, nil); + STAssertTrue([seg isMatch], nil); + STAssertEqualStrings([seg string], @"foobar", nil); + // "b" + seg = [enumerator nextObject]; + STAssertNotNil(seg, nil); + STAssertFalse([seg isMatch], nil); + STAssertEqualStrings([seg string], @"b", nil); + // "fooobaar" + seg = [enumerator nextObject]; + STAssertNotNil(seg, nil); + STAssertTrue([seg isMatch], nil); + STAssertEqualStrings([seg string], @"fooobaar", nil); + // "foobar" + seg = [enumerator nextObject]; + STAssertNotNil(seg, nil); + STAssertTrue([seg isMatch], nil); + STAssertEqualStrings([seg string], @"foobar", nil); + // "zz" + seg = [enumerator nextObject]; + STAssertNotNil(seg, nil); + STAssertFalse([seg isMatch], nil); + STAssertEqualStrings([seg string], @"zz", nil); + // (end) + seg = [enumerator nextObject]; + STAssertNil(seg, nil); + + // test no match + enumerator = [@"aaa" gtm_segmentEnumeratorForPattern:@"foo+ba+r"]; + STAssertNotNil(enumerator, nil); + seg = [enumerator nextObject]; + STAssertNotNil(seg, nil); + STAssertFalse([seg isMatch], nil); + STAssertEqualStrings([seg string], @"aaa", nil); + seg = [enumerator nextObject]; + STAssertNil(seg, nil); + + // test only match + enumerator = [@"foobar" gtm_segmentEnumeratorForPattern:@"foo+ba+r"]; + STAssertNotNil(enumerator, nil); + seg = [enumerator nextObject]; + STAssertNotNil(seg, nil); + STAssertTrue([seg isMatch], nil); + STAssertEqualStrings([seg string], @"foobar", nil); + seg = [enumerator nextObject]; + STAssertNil(seg, nil); + + // now test the saved sub segments + enumerator = + [@"foobarxxfoobaz" gtm_segmentEnumeratorForPattern:@"(foo)((bar)|(baz))"]; + STAssertNotNil(enumerator, nil); + // "foobar" + seg = [enumerator nextObject]; + STAssertNotNil(seg, nil); + STAssertTrue([seg isMatch], nil); + STAssertEqualStrings([seg string], @"foobar", nil); + STAssertEqualStrings([seg subPatternString:0], @"foobar", nil); + STAssertEqualStrings([seg subPatternString:1], @"foo", nil); + STAssertEqualStrings([seg subPatternString:2], @"bar", nil); + STAssertEqualStrings([seg subPatternString:3], @"bar", nil); + STAssertNil([seg subPatternString:4], nil); // nothing matched "(baz)" + STAssertNil([seg subPatternString:5], nil); + // "xx" + seg = [enumerator nextObject]; + STAssertNotNil(seg, nil); + STAssertFalse([seg isMatch], nil); + STAssertEqualStrings([seg string], @"xx", nil); + STAssertEqualStrings([seg subPatternString:0], @"xx", nil); + STAssertNil([seg subPatternString:1], nil); + // "foobaz" + seg = [enumerator nextObject]; + STAssertNotNil(seg, nil); + STAssertTrue([seg isMatch], nil); + STAssertEqualStrings([seg string], @"foobaz", nil); + STAssertEqualStrings([seg subPatternString:0], @"foobaz", nil); + STAssertEqualStrings([seg subPatternString:1], @"foo", nil); + STAssertEqualStrings([seg subPatternString:2], @"baz", nil); + STAssertNil([seg subPatternString:3], nil); // (nothing matched "(bar)" + STAssertEqualStrings([seg subPatternString:4], @"baz", nil); + STAssertNil([seg subPatternString:5], nil); + // (end) + seg = [enumerator nextObject]; + STAssertNil(seg, nil); + + // test all objects + enumerator = [@"afoobarbfooobaarfoobarzz" gtm_segmentEnumeratorForPattern:@"foo+ba+r"]; + STAssertNotNil(enumerator, nil); + NSArray *allSegments = [enumerator allObjects]; + STAssertNotNil(allSegments, nil); + STAssertEquals(6U, [allSegments count], nil); +} + +- (void)testMatchSegmentEnumeratorForPattern { + NSEnumerator *enumerator = + [@"afoobarbfooobaarfoobarzz" gtm_matchSegmentEnumeratorForPattern:@"foo+ba+r"]; + STAssertNotNil(enumerator, nil); + // "a" - skipped + // "foobar" + GTMRegexStringSegment *seg = [enumerator nextObject]; + STAssertNotNil(seg, nil); + STAssertTrue([seg isMatch], nil); + STAssertEqualStrings([seg string], @"foobar", nil); + // "b" - skipped + // "fooobaar" + seg = [enumerator nextObject]; + STAssertNotNil(seg, nil); + STAssertTrue([seg isMatch], nil); + STAssertEqualStrings([seg string], @"fooobaar", nil); + // "foobar" + seg = [enumerator nextObject]; + STAssertNotNil(seg, nil); + STAssertTrue([seg isMatch], nil); + STAssertEqualStrings([seg string], @"foobar", nil); + // "zz" - skipped + // (end) + seg = [enumerator nextObject]; + STAssertNil(seg, nil); + + // test no match + enumerator = [@"aaa" gtm_matchSegmentEnumeratorForPattern:@"foo+ba+r"]; + STAssertNotNil(enumerator, nil); + seg = [enumerator nextObject]; + STAssertNil(seg, nil); + + // test only match + enumerator = [@"foobar" gtm_matchSegmentEnumeratorForPattern:@"foo+ba+r"]; + STAssertNotNil(enumerator, nil); + seg = [enumerator nextObject]; + STAssertNotNil(seg, nil); + STAssertTrue([seg isMatch], nil); + STAssertEqualStrings([seg string], @"foobar", nil); + seg = [enumerator nextObject]; + STAssertNil(seg, nil); + + // now test the saved sub segments + enumerator = + [@"foobarxxfoobaz" gtm_matchSegmentEnumeratorForPattern:@"(foo)((bar)|(baz))"]; + STAssertNotNil(enumerator, nil); + // "foobar" + seg = [enumerator nextObject]; + STAssertNotNil(seg, nil); + STAssertTrue([seg isMatch], nil); + STAssertEqualStrings([seg string], @"foobar", nil); + STAssertEqualStrings([seg subPatternString:0], @"foobar", nil); + STAssertEqualStrings([seg subPatternString:1], @"foo", nil); + STAssertEqualStrings([seg subPatternString:2], @"bar", nil); + STAssertEqualStrings([seg subPatternString:3], @"bar", nil); + STAssertNil([seg subPatternString:4], nil); // nothing matched "(baz)" + STAssertNil([seg subPatternString:5], nil); + // "xx" - skipped + // "foobaz" + seg = [enumerator nextObject]; + STAssertNotNil(seg, nil); + STAssertTrue([seg isMatch], nil); + STAssertEqualStrings([seg string], @"foobaz", nil); + STAssertEqualStrings([seg subPatternString:0], @"foobaz", nil); + STAssertEqualStrings([seg subPatternString:1], @"foo", nil); + STAssertEqualStrings([seg subPatternString:2], @"baz", nil); + STAssertNil([seg subPatternString:3], nil); // (nothing matched "(bar)" + STAssertEqualStrings([seg subPatternString:4], @"baz", nil); + STAssertNil([seg subPatternString:5], nil); + // (end) + seg = [enumerator nextObject]; + STAssertNil(seg, nil); + + // test all objects + enumerator = [@"afoobarbfooobaarfoobarzz" gtm_matchSegmentEnumeratorForPattern:@"foo+ba+r"]; + STAssertNotNil(enumerator, nil); + NSArray *allSegments = [enumerator allObjects]; + STAssertNotNil(allSegments, nil); + STAssertEquals(3U, [allSegments count], nil); +} + +- (void)testAllSubstringsMatchedByPattern { + NSArray *segments = + [@"afoobarbfooobaarfoobarzz" gtm_allSubstringsMatchedByPattern:@"foo+ba+r"]; + STAssertNotNil(segments, nil); + STAssertEquals(3U, [segments count], nil); + STAssertEqualStrings([segments objectAtIndex:0], @"foobar", nil); + STAssertEqualStrings([segments objectAtIndex:1], @"fooobaar", nil); + STAssertEqualStrings([segments objectAtIndex:2], @"foobar", nil); + + // test no match + segments = [@"aaa" gtm_allSubstringsMatchedByPattern:@"foo+ba+r"]; + STAssertNotNil(segments, nil); + STAssertEquals(0U, [segments count], nil); + + // test only match + segments = [@"foobar" gtm_allSubstringsMatchedByPattern:@"foo+ba+r"]; + STAssertNotNil(segments, nil); + STAssertEquals(1U, [segments count], nil); + STAssertEqualStrings([segments objectAtIndex:0], @"foobar", nil); +} + +- (void)testStringByReplacingMatchesOfPatternWithReplacement { + // the basics + STAssertEqualStrings(@"weeZbarZbydoo spamZfooZdoggies", + [@"weefoobydoo spambardoggies" gtm_stringByReplacingMatchesOfPattern:@"(foo)(.*)(bar)" + withReplacement:@"Z\\3Z\\2Z\\1Z"], + nil); + // nil/empty replacement + STAssertEqualStrings(@"weedoggies", + [@"weefoobydoo spambardoggies" gtm_stringByReplacingMatchesOfPattern:@"(foo)(.*)(bar)" + withReplacement:nil], + nil); + STAssertEqualStrings(@"weedoggies", + [@"weefoobydoo spambardoggies" gtm_stringByReplacingMatchesOfPattern:@"(foo)(.*)(bar)" + withReplacement:@""], + nil); + // use optional and invale subexpression parts to confirm that works + STAssertEqualStrings(@"aaa baz bar bar foo baz aaa", + [@"aaa foooooobaz fooobar bar foo baz aaa" gtm_stringByReplacingMatchesOfPattern:@"(fo(o+))((bar)|(baz))" + withReplacement:@"\\4\\5"], + nil); + STAssertEqualStrings(@"aaa ZZZ ZZZ bar foo baz aaa", + [@"aaa foooooobaz fooobar bar foo baz aaa" gtm_stringByReplacingMatchesOfPattern:@"(fo(o+))((bar)|(baz))" + withReplacement:@"Z\\10Z\\12Z"], + nil); + // test slashes in replacement that aren't part of the subpattern reference + STAssertEqualStrings(@"z\\\\0 \\\\a \\\\\\\\0z", + [@"zaz" gtm_stringByReplacingMatchesOfPattern:@"a+" + withReplacement:@"\\\\0 \\\\\\0 \\\\\\\\0"], + nil); + STAssertEqualStrings(@"z\\\\a \\\\\\\\0 \\\\\\\\az", + [@"zaz" gtm_stringByReplacingMatchesOfPattern:@"a+" + withReplacement:@"\\\\\\0 \\\\\\\\0 \\\\\\\\\\0"], + nil); + STAssertEqualStrings(@"z\\\\\\\\0 \\\\\\\\a \\\\\\\\\\\\0z", + [@"zaz" gtm_stringByReplacingMatchesOfPattern:@"a+" + withReplacement:@"\\\\\\\\0 \\\\\\\\\\0 \\\\\\\\\\\\0"], + nil); +} + +@end |