1// Copyright (C) 2017 The Libphonenumber Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15// Tests that all implementations of MatcherApi are consistent.
16
17#include "phonenumbers/matcher_api.h"
18
19#include <string>
20#include <vector>
21
22#include <gtest/gtest.h>
23
24#include "phonenumbers/regex_based_matcher.h"
25#include "phonenumbers/phonemetadata.pb.h"
26
27namespace i18n {
28namespace phonenumbers {
29
30namespace {
31
32string ToString(const PhoneNumberDesc& desc) {
33  string str = "pattern: ";
34  if (desc.has_national_number_pattern()) {
35    str += desc.national_number_pattern();
36  } else {
37    str += "none";
38  }
39  return str;
40}
41
42void ExpectMatched(
43    const MatcherApi& matcher,
44    const string& number,
45    const PhoneNumberDesc& desc) {
46  EXPECT_TRUE(matcher.MatchNationalNumber(number, desc, false))
47      << number << " should have matched " << ToString(desc);
48  EXPECT_TRUE(matcher.MatchNationalNumber(number, desc, true))
49      << number << " should have matched " << ToString(desc);
50}
51
52void ExpectInvalid(
53    const MatcherApi& matcher,
54    const string& number,
55    const PhoneNumberDesc& desc) {
56  EXPECT_FALSE(matcher.MatchNationalNumber(number, desc, false))
57      << number << " should not have matched " << ToString(desc);
58  EXPECT_FALSE(matcher.MatchNationalNumber(number, desc, true))
59      << number << " should not have matched " << ToString(desc);
60}
61
62void ExpectTooLong(
63    const MatcherApi& matcher,
64    const string& number,
65    const PhoneNumberDesc& desc) {
66  EXPECT_FALSE(matcher.MatchNationalNumber(number, desc, false))
67      << number << " should have been too long for " << ToString(desc);
68  EXPECT_TRUE(matcher.MatchNationalNumber(number, desc, true))
69      << number << " should have been too long for " << ToString(desc);
70}
71
72}  // namespace
73
74class MatcherTest : public testing::Test {
75 protected:
76  void CheckMatcherBehavesAsExpected(const MatcherApi& matcher) const {
77    PhoneNumberDesc desc;
78
79    desc = CreateDesc("");
80    // Test if there is no matcher data.
81    ExpectInvalid(matcher, "1", desc);
82
83    desc = CreateDesc("9\\d{2}");
84    ExpectInvalid(matcher, "91", desc);
85    ExpectInvalid(matcher, "81", desc);
86    ExpectMatched(matcher, "911", desc);
87    ExpectInvalid(matcher, "811", desc);
88    ExpectTooLong(matcher, "9111", desc);
89    ExpectInvalid(matcher, "8111", desc);
90
91    desc = CreateDesc("\\d{1,2}");
92    ExpectMatched(matcher, "2", desc);
93    ExpectMatched(matcher, "20", desc);
94
95    desc = CreateDesc("20?");
96    ExpectMatched(matcher, "2", desc);
97    ExpectMatched(matcher, "20", desc);
98
99    desc = CreateDesc("2|20");
100    ExpectMatched(matcher, "2", desc);
101    // Subtle case where lookingAt() and matches() result in different end()s.
102    ExpectMatched(matcher, "20", desc);
103  }
104
105 private:
106  // Helper method to set national number fields in the PhoneNumberDesc proto.
107  // Empty fields won't be set.
108  PhoneNumberDesc CreateDesc(
109      const string& national_number_pattern) const {
110    PhoneNumberDesc desc;
111    if (!national_number_pattern.empty()) {
112      desc.set_national_number_pattern(national_number_pattern);
113    }
114    return desc;
115  }
116};
117
118TEST_F(MatcherTest, RegexBasedMatcher) {
119  RegexBasedMatcher matcher;
120  CheckMatcherBehavesAsExpected(matcher);
121}
122
123}  // namespace phonenumbers
124}  // namespace i18n
125