| OLD | NEW |
| (Empty) | |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "base/strings/sys_string_conversions.h" |
| 6 #import "testing/gtest_mac.h" |
| 7 #include "testing/platform_test.h" |
| 8 |
| 9 // Chromium code relies on NSRegularExpression class to match regular |
| 10 // expressions. Any subtle changes in behavior can lead to hard to diagnose |
| 11 // problems. This files tests how NSRegularExpression handles various regular |
| 12 // expression features. |
| 13 |
| 14 namespace { |
| 15 |
| 16 // Checks that capture groups from |testString| substituted into |
| 17 // |templateString| matches |expected|. |
| 18 void ExpectRegexMatched(NSRegularExpression* regex, |
| 19 NSString* testString, |
| 20 NSString* templateString, |
| 21 NSString* expected) { |
| 22 NSRange testRange = NSMakeRange(0, [testString length]); |
| 23 NSString* outputString = |
| 24 [regex stringByReplacingMatchesInString:testString |
| 25 options:0 |
| 26 range:testRange |
| 27 withTemplate:templateString]; |
| 28 EXPECT_TRUE(outputString && [outputString isEqualToString:expected]) |
| 29 << "ExpectRegexMatched: '" << base::SysNSStringToUTF8(expected) << "' != " |
| 30 << (!outputString ? "(nil)" |
| 31 : "'" + base::SysNSStringToUTF8(outputString) + "'"); |
| 32 } |
| 33 |
| 34 // Checks that |testString| is not matched by |regex|. |
| 35 void ExpectRegexNotMatched(NSRegularExpression* regex, NSString* testString) { |
| 36 __block BOOL matched = NO; |
| 37 NSRange testRange = NSMakeRange(0, [testString length]); |
| 38 [regex enumerateMatchesInString:testString |
| 39 options:0 |
| 40 range:testRange |
| 41 usingBlock:^(NSTextCheckingResult* result, |
| 42 NSMatchingFlags flags, BOOL* stop) { |
| 43 if (NSEqualRanges([result range], testRange)) { |
| 44 *stop = YES; |
| 45 matched = YES; |
| 46 } |
| 47 }]; |
| 48 EXPECT_FALSE(matched) << "ExpectRegexNotMatched: '" |
| 49 << base::SysNSStringToUTF8(testString) << "' " |
| 50 << "pattern:" |
| 51 << base::SysNSStringToUTF8([regex pattern]); |
| 52 } |
| 53 |
| 54 // Returns an autoreleased NSRegularExpression object from the regular |
| 55 // expression |pattern|. |
| 56 NSRegularExpression* MakeRegularExpression(NSString* pattern) { |
| 57 NSError* error = nil; |
| 58 return [NSRegularExpression regularExpressionWithPattern:pattern |
| 59 options:0 |
| 60 error:&error]; |
| 61 } |
| 62 |
| 63 TEST(NSRegularExpressionTest, TestSimpleRegex) { |
| 64 NSRegularExpression* regex = MakeRegularExpression(@"foo(.*)bar(.*)"); |
| 65 ExpectRegexMatched(regex, @"fooONEbarTWO", @"first $1, second $2", |
| 66 @"first ONE, second TWO"); |
| 67 } |
| 68 |
| 69 TEST(NSRegularExpressionTest, TestComplexRegex) { |
| 70 NSString* expression = @"^http[s]?://" |
| 71 "(?:" |
| 72 "(?:youtu\\.be/)|" |
| 73 "(?:.*\\.youtube\\.com/watch\\?v=)|" |
| 74 "(?:.*\\.youtube\\.com/index\\?)" |
| 75 ")" |
| 76 "([^&]*)[\\&]?(?:.*)$"; |
| 77 NSString* templateString = @"vnd.youtube://$1"; |
| 78 NSString* expectedOutput = @"vnd.youtube://ndRXe3tTnsA"; |
| 79 NSRegularExpression* regex = MakeRegularExpression(expression); |
| 80 ExpectRegexMatched(regex, @"http://youtu.be/ndRXe3tTnsA", templateString, |
| 81 expectedOutput); |
| 82 ExpectRegexMatched(regex, @"http://www.youtube.com/watch?v=ndRXe3tTnsA", |
| 83 templateString, expectedOutput); |
| 84 ExpectRegexNotMatched(regex, @"http://www.google.com"); |
| 85 ExpectRegexNotMatched(regex, @"http://www.youtube.com/embed/GkOZ8DfO248"); |
| 86 } |
| 87 |
| 88 TEST(NSRegularExpressionTest, TestSimpleAlternation) { |
| 89 // This test verifies how NSRegularExpression works. |
| 90 // Regex 'ab|c' matches 'ab', 'ac', or 'c'. Does not match 'abc', 'a', or 'b'. |
| 91 NSRegularExpression* regex = MakeRegularExpression(@"^ab|c$"); |
| 92 ExpectRegexMatched(regex, @"ab", @"$0", @"ab"); |
| 93 ExpectRegexMatched(regex, @"c", @"$0", @"c"); |
| 94 ExpectRegexMatched(regex, @"ac", @"$0", @"ac"); |
| 95 ExpectRegexNotMatched(regex, @"abc"); |
| 96 ExpectRegexNotMatched(regex, @"a"); |
| 97 ExpectRegexNotMatched(regex, @"b"); |
| 98 |
| 99 // Tests for '(?:ab)|(?:c)', which is slightly different from 'ab|c'. |
| 100 regex = MakeRegularExpression(@"^(?:ab)|(?:c)$"); |
| 101 ExpectRegexMatched(regex, @"ab", @"$0", @"ab"); |
| 102 ExpectRegexMatched(regex, @"c", @"$0", @"c"); |
| 103 ExpectRegexNotMatched(regex, @"ac"); |
| 104 ExpectRegexNotMatched(regex, @"abc"); |
| 105 |
| 106 // This other regex: 'a(b|c)' matches either 'ab' or 'ac'. |
| 107 regex = MakeRegularExpression(@"^a(?:b|c)$"); |
| 108 ExpectRegexMatched(regex, @"ab", @"$0", @"ab"); |
| 109 ExpectRegexMatched(regex, @"ac", @"$0", @"ac"); |
| 110 ExpectRegexNotMatched(regex, @"a"); |
| 111 ExpectRegexNotMatched(regex, @"abc"); |
| 112 } |
| 113 |
| 114 TEST(NSRegularExpressionTest, TestUberCaptureGroup) { |
| 115 // The absence of an uber-capture group caused NSRegularExpression to crash on |
| 116 // iOS 5.x. This tests to make sure that it is not happening on iOS 6+ |
| 117 // environments. |
| 118 NSRegularExpression* regex = MakeRegularExpression(@"^(ab|cd|ef)ghij$"); |
| 119 ExpectRegexMatched(regex, @"abghij", @"$0", @"abghij"); |
| 120 ExpectRegexMatched(regex, @"cdghij", @"$0", @"cdghij"); |
| 121 ExpectRegexMatched(regex, @"efghij", @"$0", @"efghij"); |
| 122 ExpectRegexNotMatched(regex, @"abcdefghij"); |
| 123 |
| 124 regex = MakeRegularExpression(@"^ab|cd|efghij$"); |
| 125 ExpectRegexMatched(regex, @"ab", @"$0", @"ab"); |
| 126 ExpectRegexMatched(regex, @"cd", @"$0", @"cd"); |
| 127 ExpectRegexMatched(regex, @"efghij", @"$0", @"efghij"); |
| 128 ExpectRegexNotMatched(regex, @"abcdefghij"); |
| 129 ExpectRegexNotMatched(regex, @"abghij"); |
| 130 ExpectRegexNotMatched(regex, @"cdghij"); |
| 131 } |
| 132 |
| 133 } // namespace |
| OLD | NEW |