Completed
Pull Request — master (#170)
by Joshua
18:13 queued 09:08
created

testGetExampleNumberWithoutRegion()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 7
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 4
nc 1
nop 0
1
<?php
2
3
namespace libphonenumber\Tests\core;
4
5
use libphonenumber\CountryCodeSource;
6
use libphonenumber\CountryCodeToRegionCodeMapForTesting;
7
use libphonenumber\MatchType;
8
use libphonenumber\NumberFormat;
9
use libphonenumber\NumberParseException;
10
use libphonenumber\PhoneMetadata;
11
use libphonenumber\PhoneNumber;
12
use libphonenumber\PhoneNumberDesc;
13
use libphonenumber\PhoneNumberFormat;
14
use libphonenumber\PhoneNumberType;
15
use libphonenumber\PhoneNumberUtil;
16
use libphonenumber\RegionCode;
17
use libphonenumber\ValidationResult;
18
19
class PhoneNumberUtilTest extends \PHPUnit_Framework_TestCase
20
{
21
    const TEST_META_DATA_FILE_PREFIX = "../../tests/core/data/PhoneNumberMetadataForTesting";
22
    private static $bsNumber = null;
23
    private static $internationalTollFree = null;
24
    private static $sgNumber = null;
25
    private static $usShortByOneNumber = null;
26
    private static $usTollFree = null;
27
    private static $usNumber = null;
28
    private static $usLocalNumber = null;
29
    private static $usLongNumber = null;
30
    private static $nzNumber = null;
31
    private static $usPremium = null;
32
    private static $usSpoof = null;
33
    private static $usSpoofWithRawInput = null;
34
    private static $gbMobile = null;
35
    private static $bsMobile = null;
36
    private static $gbNumber = null;
37
    private static $deShortNumber = null;
38
    private static $itMobile = null;
39
    private static $itNumber = null;
40
    private static $auNumber = null;
41
    private static $arMobile = null;
42
    private static $arNumber = null;
43
    private static $mxMobile1 = null;
44
    private static $mxNumber1 = null;
45
    private static $mxMobile2 = null;
46
    private static $mxNumber2 = null;
47
    private static $deNumber = null;
48
    private static $jpStarNumber = null;
49
    private static $internationalTollFreeTooLong = null;
50
    private static $universalPremiumRate = null;
51
    private static $alphaNumericNumber = null;
52
    private static $aeUAN = null;
53
    private static $unknownCountryCodeNoRawInput = null;
54
    /**
55
     * @var PhoneNumberUtil
56
     */
57
    protected $phoneUtil;
58
59
    public function setUp()
60
    {
61
        $this->phoneUtil = self::initializePhoneUtilForTesting();
62
    }
63
64
    private static function initializePhoneUtilForTesting()
65
    {
66
        self::$bsNumber = new PhoneNumber();
67
        self::$bsNumber->setCountryCode(1)->setNationalNumber(2423651234);
68
        self::$bsMobile = new PhoneNumber();
69
        self::$bsMobile->setCountryCode(1)->setNationalNumber(2423591234);
70
        self::$internationalTollFree = new PhoneNumber();
71
        self::$internationalTollFree->setCountryCode(800)->setNationalNumber(12345678);
72
        self::$internationalTollFreeTooLong = new PhoneNumber();
73
        self::$internationalTollFreeTooLong->setCountryCode(800)->setNationalNumber(123456789);
74
        self::$universalPremiumRate = new PhoneNumber();
75
        self::$universalPremiumRate->setCountryCode(979)->setNationalNumber(123456789);
76
        self::$sgNumber = new PhoneNumber();
77
        self::$sgNumber->setCountryCode(65)->setNationalNumber(65218000);
78
        // A too-long and hence invalid US number.
79
        self::$usLongNumber = new PhoneNumber();
80
        self::$usLongNumber->setCountryCode(1)->setNationalNumber(65025300001);
81
        self::$usShortByOneNumber = new PhoneNumber();
82
        self::$usShortByOneNumber->setCountryCode(1)->setNationalNumber(650253000);
83
        self::$usTollFree = new PhoneNumber();
84
        self::$usTollFree->setCountryCode(1)->setNationalNumber(8002530000);
85
        self::$usNumber = new PhoneNumber();
86
        self::$usNumber->setCountryCode(1)->setNationalNumber(6502530000);
87
        self::$usLocalNumber = new PhoneNumber();
88
        self::$usLocalNumber->setCountryCode(1)->setNationalNumber(2530000);
89
        self::$nzNumber = new PhoneNumber();
90
        self::$nzNumber->setCountryCode(64)->setNationalNumber(33316005);
91
        self::$usPremium = new PhoneNumber();
92
        self::$usPremium->setCountryCode(1)->setNationalNumber(9002530000);
93
        self::$usSpoof = new PhoneNumber();
94
        self::$usSpoof->setCountryCode(1)->setNationalNumber(0);
95
        self::$usSpoofWithRawInput = new PhoneNumber();
96
        self::$usSpoofWithRawInput->setCountryCode(1)->setNationalNumber(0)->setRawInput("000-000-0000");
97
        self::$gbMobile = new PhoneNumber();
98
        self::$gbMobile->setCountryCode(44)->setNationalNumber(7912345678);
99
        self::$gbNumber = new PhoneNumber();
100
        self::$gbNumber->setCountryCode(44)->setNationalNumber(2070313000);
101
        self::$deShortNumber = new PhoneNumber();
102
        self::$deShortNumber->setCountryCode(49)->setNationalNumber(1234);
103
        self::$itMobile = new PhoneNumber();
104
        self::$itMobile->setCountryCode(39)->setNationalNumber(345678901);
105
        self::$itNumber = new PhoneNumber();
106
        self::$itNumber->setCountryCode(39)->setNationalNumber(236618300)->setItalianLeadingZero(true);
107
        self::$auNumber = new PhoneNumber();
108
        self::$auNumber->setCountryCode(61)->setNationalNumber(236618300);
109
        self::$arMobile = new PhoneNumber();
110
        self::$arMobile->setCountryCode(54)->setNationalNumber(91187654321);
111
        self::$arNumber = new PhoneNumber();
112
        self::$arNumber->setCountryCode(54)->setNationalNumber(1187654321);
113
114
        self::$mxMobile1 = new PhoneNumber();
115
        self::$mxMobile1->setCountryCode(52)->setNationalNumber(12345678900);
116
        self::$mxNumber1 = new PhoneNumber();
117
        self::$mxNumber1->setCountryCode(52)->setNationalNumber(3312345678);
118
        self::$mxMobile2 = new PhoneNumber();
119
        self::$mxMobile2->setCountryCode(52)->setNationalNumber(15512345678);
120
        self::$mxNumber2 = new PhoneNumber();
121
        self::$mxNumber2->setCountryCode(52)->setNationalNumber(8211234567);
122
        // Note that this is the same as the example number for DE in the metadata.
123
        self::$deNumber = new PhoneNumber();
124
        self::$deNumber->setCountryCode(49)->setNationalNumber(30123456);
125
        self::$jpStarNumber = new PhoneNumber();
126
        self::$jpStarNumber->setCountryCode(81)->setNationalNumber(2345);
127
        self::$alphaNumericNumber = new PhoneNumber();
128
        self::$alphaNumericNumber->setCountryCode(1)->setNationalNumber(80074935247);
129
        self::$aeUAN = new PhoneNumber();
130
        self::$aeUAN->setCountryCode(971)->setNationalNumber(600123456);
131
        self::$unknownCountryCodeNoRawInput = new PhoneNumber();
132
        self::$unknownCountryCodeNoRawInput->setCountryCode(2)->setNationalNumber(12345);
133
134
        PhoneNumberUtil::resetInstance();
135
        return PhoneNumberUtil::getInstance(
136
            self::TEST_META_DATA_FILE_PREFIX,
137
            CountryCodeToRegionCodeMapForTesting::$countryCodeToRegionCodeMapForTesting
138
        );
139
    }
140
141
    public function testGetSupportedRegions()
142
    {
143
        $this->assertGreaterThan(0, count($this->phoneUtil->getSupportedRegions()));
144
    }
145
146
    public function testGetSupportedGlobalNetworkCallingCodes()
147
    {
148
        $globalNetworkCallingCodes = $this->phoneUtil->getSupportedGlobalNetworkCallingCodes();
149
150
        $this->assertGreaterThan(0, count($globalNetworkCallingCodes));
151
152
        foreach ($globalNetworkCallingCodes as $callingCode) {
153
            $this->assertGreaterThan(0, $callingCode);
154
            $this->assertEquals(RegionCode::UN001, $this->phoneUtil->getRegionCodeForCountryCode($callingCode));
155
        }
156
    }
157
158
    public function testGetInstanceLoadBadMetadata()
159
    {
160
        $this->assertNull($this->phoneUtil->getMetadataForRegion("No Such Region"));
161
        $this->assertNull($this->phoneUtil->getMetadataForRegion(-1));
162
    }
163
164
    public function testGetSupportedTypesForRegion()
165
    {
166
        $this->assertContains(PhoneNumberType::FIXED_LINE, $this->phoneUtil->getSupportedTypesForRegion(RegionCode::BR));
167
        // Our test data has no mobile numbers for Brazil.
168
        $this->assertNotContains(PhoneNumberType::MOBILE, $this->phoneUtil->getSupportedTypesForRegion(RegionCode::BR));
169
        // UNKNOWN should never be returned.
170
        $this->assertNotContains(PhoneNumberType::UNKNOWN, $this->phoneUtil->getSupportedTypesForRegion(RegionCode::BR));
171
172
        // In the US, many numbers are classified as FIXED_LINE_OR_MOBILE; but we don't want to expose
173
        // this as a supported type, instead we say FIXED_LINE and MOBILE are both present
174
        $this->assertContains(PhoneNumberType::FIXED_LINE, $this->phoneUtil->getSupportedTypesForRegion(RegionCode::US));
175
        $this->assertContains(PhoneNumberType::MOBILE, $this->phoneUtil->getSupportedTypesForRegion(RegionCode::US));
176
        $this->assertNotContains(PhoneNumberType::FIXED_LINE_OR_MOBILE, $this->phoneUtil->getSupportedTypesForRegion(RegionCode::US));
177
178
        // Test the invalid region code.
179
        $this->assertCount(0, $this->phoneUtil->getSupportedTypesForRegion(RegionCode::ZZ));
180
    }
181
182
    public function testGetSupportedTypesForNonGeoEntity()
183
    {
184
        // No data exists for 999 at all, no types should be returned.
185
        $this->assertCount(0, $this->phoneUtil->getSupportedTypesForNonGeoEntity(999));
186
187
        $typesFor979 = $this->phoneUtil->getSupportedTypesForNonGeoEntity(979);
188
        $this->assertContains(PhoneNumberType::PREMIUM_RATE, $typesFor979);
189
        $this->assertNotContains(PhoneNumberType::MOBILE, $typesFor979);
190
        $this->assertNotContains(PhoneNumberType::UNKNOWN, $typesFor979);
191
    }
192
193
    public function testGetInstanceLoadUSMetadata()
194
    {
195
        $metadata = $this->phoneUtil->getMetadataForRegion(RegionCode::US);
196
        $this->assertEquals("US", $metadata->getId());
197
        $this->assertEquals(1, $metadata->getCountryCode());
198
        $this->assertEquals("011", $metadata->getInternationalPrefix());
199
        $this->assertTrue($metadata->hasNationalPrefix());
200
        $this->assertEquals(2, $metadata->numberFormatSize());
201
        $this->assertEquals("(\\d{3})(\\d{3})(\\d{4})", $metadata->getNumberFormat(1)->getPattern());
202
        $this->assertEquals("$1 $2 $3", $metadata->getNumberFormat(1)->getFormat());
203
        $this->assertEquals("[13-689]\\d{9}|2[0-35-9]\\d{8}", $metadata->getGeneralDesc()->getNationalNumberPattern());
204
        $this->assertEquals("[13-689]\\d{9}|2[0-35-9]\\d{8}", $metadata->getFixedLine()->getNationalNumberPattern());
205
        $this->assertCount(1, $metadata->getGeneralDesc()->getPossibleLength());
206
        $possibleLength = $metadata->getGeneralDesc()->getPossibleLength();
207
        $this->assertEquals(10, $possibleLength[0]);
208
        // Possible lengths are the same as the general description, so aren't stored separately in the
209
        // toll free element as well.
210
        $this->assertCount(0, $metadata->getTollFree()->getPossibleLength());
211
        $this->assertEquals("900\\d{7}", $metadata->getPremiumRate()->getNationalNumberPattern());
212
        // No shared-cost data is available, so it should be initialised to "NA".
213
        $this->assertEquals("NA", $metadata->getSharedCost()->getNationalNumberPattern());
214
    }
215
216
    public function testGetInstanceLoadDEMetadata()
217
    {
218
        $metadata = $this->phoneUtil->getMetadataForRegion(RegionCode::DE);
219
        $this->assertEquals("DE", $metadata->getId());
220
        $this->assertEquals(49, $metadata->getCountryCode());
221
        $this->assertEquals("00", $metadata->getInternationalPrefix());
222
        $this->assertEquals("0", $metadata->getNationalPrefix());
223
        $this->assertEquals(6, $metadata->numberFormatSize());
224
        $this->assertEquals(1, $metadata->getNumberFormat(5)->leadingDigitsPatternSize());
225
        $this->assertEquals("900", $metadata->getNumberFormat(5)->getLeadingDigitsPattern(0));
226
        $this->assertEquals("(\\d{3})(\\d{3,4})(\\d{4})", $metadata->getNumberFormat(5)->getPattern());
227
        $this->assertEquals("$1 $2 $3", $metadata->getNumberFormat(5)->getFormat());
228
        $this->assertCount(2, $metadata->getGeneralDesc()->getPossibleLengthLocalOnly());
229
        $this->assertCount(8, $metadata->getGeneralDesc()->getPossibleLength());
230
        // Nothing is present for fixed-line, since it is the same as the general desc, so for
231
        // efficiency reasons we don't store an extra value.
232
        $this->assertCount(0, $metadata->getFixedLine()->getPossibleLength());
233
        $this->assertCount(2, $metadata->getMobile()->getPossibleLength());
234
235
        $this->assertEquals(
236
            "(?:[24-6]\\d{2}|3[03-9]\\d|[789](?:0[2-9]|[1-9]\\d))\\d{1,8}",
237
            $metadata->getFixedLine()->getNationalNumberPattern()
238
        );
239
        $this->assertEquals("30123456", $metadata->getFixedLine()->getExampleNumber());
240
        $this->assertContains(10, $metadata->getTollFree()->getPossibleLength());
241
        $this->assertEquals("900([135]\\d{6}|9\\d{7})", $metadata->getPremiumRate()->getNationalNumberPattern());
242
    }
243
244
    public function testGetInstanceLoadARMetadata()
245
    {
246
        $metadata = $this->phoneUtil->getMetadataForRegion(RegionCode::AR);
247
        $this->assertEquals("AR", $metadata->getId());
248
        $this->assertEquals(54, $metadata->getCountryCode());
249
        $this->assertEquals("00", $metadata->getInternationalPrefix());
250
        $this->assertEquals("0", $metadata->getNationalPrefix());
251
        $this->assertEquals("0(?:(11|343|3715)15)?", $metadata->getNationalPrefixForParsing());
252
        $this->assertEquals("9$1", $metadata->getNationalPrefixTransformRule());
253
        $this->assertEquals("$2 15 $3-$4", $metadata->getNumberFormat(2)->getFormat());
254
        $this->assertEquals("(9)(\\d{4})(\\d{2})(\\d{4})", $metadata->getNumberFormat(3)->getPattern());
255
        $this->assertEquals("(9)(\\d{4})(\\d{2})(\\d{4})", $metadata->getIntlNumberFormat(3)->getPattern());
256
        $this->assertEquals("$1 $2 $3 $4", $metadata->getIntlNumberFormat(3)->getFormat());
257
    }
258
259
    public function testGetInstanceLoadInternationalTollFreeMetadata()
260
    {
261
        $metadata = $this->phoneUtil->getMetadataForNonGeographicalRegion(800);
262
        $this->assertEquals("001", $metadata->getId());
263
        $this->assertEquals(800, $metadata->getCountryCode());
264
        $this->assertEquals("$1 $2", $metadata->getNumberFormat(0)->getFormat());
265
        $this->assertEquals("(\\d{4})(\\d{4})", $metadata->getNumberFormat(0)->getPattern());
266
        $this->assertCount(0, $metadata->getGeneralDesc()->getPossibleLengthLocalOnly());
267
        $this->assertCount(1, $metadata->getGeneralDesc()->getPossibleLength());
268
        $this->assertEquals("12345678", $metadata->getTollFree()->getExampleNumber());
269
    }
270
271
    public function testIsNumberGeographical()
272
    {
273
        $this->assertFalse($this->phoneUtil->isNumberGeographical(self::$bsMobile)); // Bahamas, mobile phone number.
274
        $this->assertTrue($this->phoneUtil->isNumberGeographical(self::$auNumber)); // Australian fixed line number.
275
        $this->assertFalse($this->phoneUtil->isNumberGeographical(self::$internationalTollFree)); // International toll
276
        // free number
277
    }
278
279
    public function testIsLeadingZeroPossible()
280
    {
281
        $this->assertTrue($this->phoneUtil->isLeadingZeroPossible(39)); // Italy
282
        $this->assertFalse($this->phoneUtil->isLeadingZeroPossible(1)); // USA
283
        $this->assertTrue($this->phoneUtil->isLeadingZeroPossible(800)); // International toll free numbers
284
        $this->assertFalse($this->phoneUtil->isLeadingZeroPossible(979)); // International premium-rate
285
        $this->assertFalse(
286
            $this->phoneUtil->isLeadingZeroPossible(888)
287
        ); // Not in metadata file, just default to false.
288
    }
289
290
    public function testGetLengthOfGeographicalAreaCode()
291
    {
292
        // Google MTV, which has area code "650".
293
        $this->assertEquals(3, $this->phoneUtil->getLengthOfGeographicalAreaCode(self::$usNumber));
294
295
        // A North America toll-free number, which has no area code.
296
        $this->assertEquals(0, $this->phoneUtil->getLengthOfGeographicalAreaCode(self::$usTollFree));
297
298
        // Google London, which has area code "20".
299
        $this->assertEquals(2, $this->phoneUtil->getLengthOfGeographicalAreaCode(self::$gbNumber));
300
301
        // A mobile number in the UK does not have an area code (by default, mobile numbers do not,
302
        // unless they have been added to our list of exceptions).
303
        $this->assertEquals(0, $this->phoneUtil->getLengthOfGeographicalAreaCode(self::$gbMobile));
304
305
        // A UK mobile phone, which has no area code.
306
        $this->assertEquals(0, $this->phoneUtil->getLengthOfGeographicalAreaCode(self::$gbMobile));
307
308
        // Google Buenos Aires, which has area code "11".
309
        $this->assertEquals(2, $this->phoneUtil->getLengthOfGeographicalAreaCode(self::$arNumber));
310
311
        // A mobile number in Argentina also has an area code.
312
        $this->assertEquals(3, $this->phoneUtil->getLengthOfGeographicalAreaCode(self::$arMobile));
313
314
        // Google Sydney, which has area code "2".
315
        $this->assertEquals(1, $this->phoneUtil->getLengthOfGeographicalAreaCode(self::$auNumber));
316
317
        // Italian numbers - there is no national prefix, but it still has an area code.
318
        $this->assertEquals(2, $this->phoneUtil->getLengthOfGeographicalAreaCode(self::$itNumber));
319
320
        // Google Singapore. Singapore has no area code and no national prefix.
321
        $this->assertEquals(0, $this->phoneUtil->getLengthOfGeographicalAreaCode(self::$sgNumber));
322
323
        // An invalid US number (1 digit shorter), which has no area code.
324
        $this->assertEquals(0, $this->phoneUtil->getLengthOfGeographicalAreaCode(self::$usShortByOneNumber));
325
326
        // An international toll free number, which has no area code.
327
        $this->assertEquals(0, $this->phoneUtil->getLengthOfGeographicalAreaCode(self::$internationalTollFree));
328
329
        // A mobile number from China is geographical, but does not have an area code.
330
        $cnMobile = new PhoneNumber();
331
        $cnMobile->setCountryCode(86)->setNationalNumber('18912341234');
332
333
        $this->assertEquals(0, $this->phoneUtil->getLengthOfGeographicalAreaCode($cnMobile));
334
    }
335
336
    public function testGetLengthOfNationalDestinationCode()
337
    {
338
        // Google MTV, which has national destination code (NDC) "650".
339
        $this->assertEquals(3, $this->phoneUtil->getLengthOfNationalDestinationCode(self::$usNumber));
340
341
        // A North America toll-free number, which has NDC "800".
342
        $this->assertEquals(3, $this->phoneUtil->getLengthOfNationalDestinationCode(self::$usTollFree));
343
344
        // Google London, which has NDC "20".
345
        $this->assertEquals(2, $this->phoneUtil->getLengthOfNationalDestinationCode(self::$gbNumber));
346
347
        // A UK mobile phone, which has NDC "7912".
348
        $this->assertEquals(4, $this->phoneUtil->getLengthOfNationalDestinationCode(self::$gbMobile));
349
350
        // Google Buenos Aires, which has NDC "11".
351
        $this->assertEquals(2, $this->phoneUtil->getLengthOfNationalDestinationCode(self::$arNumber));
352
353
        // An Argentinian mobile which has NDC "911".
354
        $this->assertEquals(3, $this->phoneUtil->getLengthOfNationalDestinationCode(self::$arMobile));
355
356
        // Google Sydney, which has NDC "2".
357
        $this->assertEquals(1, $this->phoneUtil->getLengthOfNationalDestinationCode(self::$auNumber));
358
359
        // Google Singapore, which has NDC "6521".
360
        $this->assertEquals(4, $this->phoneUtil->getLengthOfNationalDestinationCode(self::$sgNumber));
361
362
        // An invalid US number (1 digit shorter), which has no NDC.
363
        $this->assertEquals(0, $this->phoneUtil->getLengthOfNationalDestinationCode(self::$usShortByOneNumber));
364
365
        // A number containing an invalid country calling code, which shouldn't have any NDC.
366
        $number = new PhoneNumber();
367
        $number->setCountryCode(123)->setNationalNumber(6502530000);
368
        $this->assertEquals(0, $this->phoneUtil->getLengthOfNationalDestinationCode($number));
369
370
        // An international toll free number, which has NDC "1234".
371
        $this->assertEquals(4, $this->phoneUtil->getLengthOfNationalDestinationCode(self::$internationalTollFree));
372
373
        // A mobile number from China is geographical, but does not have an area code: however it still
374
        // can be considered to have a national destination code.
375
        $cnMobile= new PhoneNumber();
376
        $cnMobile->setCountryCode(86)->setNationalNumber('18912341234');
377
378
        $this->assertEquals(3, $this->phoneUtil->getLengthOfNationalDestinationCode($cnMobile));
379
    }
380
381
    public function testGetCountryMobileToken()
382
    {
383
        $this->assertEquals(
384
            "1",
385
            PhoneNumberUtil::getCountryMobileToken($this->phoneUtil->getCountryCodeForRegion(RegionCode::MX))
386
        );
387
388
        // Country calling code for Sweden, which has no mobile token.
389
        $this->assertEquals(
390
            "",
391
            PhoneNumberUtil::getCountryMobileToken($this->phoneUtil->getCountryCodeForRegion(RegionCode::SE))
392
        );
393
    }
394
395
    public function testGetNationalSignificantNumber()
396
    {
397
        $this->assertEquals("6502530000", $this->phoneUtil->getNationalSignificantNumber(self::$usNumber));
398
399
        // An Italian mobile number.
400
        $this->assertEquals("345678901", $this->phoneUtil->getNationalSignificantNumber(self::$itMobile));
401
402
        // An Italian fixed line number.
403
        $this->assertEquals("0236618300", $this->phoneUtil->getNationalSignificantNumber(self::$itNumber));
404
405
        $this->assertEquals("12345678", $this->phoneUtil->getNationalSignificantNumber(self::$internationalTollFree));
406
    }
407
408
    public function testGetNationalSignificantNumber_ManyLeadingZeros()
409
    {
410
        $number = new PhoneNumber();
411
        $number->setCountryCode(1);
412
        $number->setNationalNumber(650);
413
        $number->setItalianLeadingZero(true);
414
        $number->setNumberOfLeadingZeros(2);
415
416
        $this->assertEquals('00650', $this->phoneUtil->getNationalSignificantNumber($number));
417
418
        // Set a bad value; we shouldn't crash; we shouldn't output any leading zeros at all;
419
        $number->setNumberOfLeadingZeros(-3);
420
        $this->assertEquals('650', $this->phoneUtil->getNationalSignificantNumber($number));
421
    }
422
423
    public function testGetExampleNumber()
424
    {
425
        $this->assertEquals(self::$deNumber, $this->phoneUtil->getExampleNumber(RegionCode::DE));
426
427
        $this->assertEquals(
428
            self::$deNumber,
429
            $this->phoneUtil->getExampleNumberForType(RegionCode::DE, PhoneNumberType::FIXED_LINE)
430
        );
431
        // Should return the sample response if asked for FIXED_LINE_OR_MOBILE too.
432
        $this->assertEquals(
433
            self::$deNumber,
434
            $this->phoneUtil->getExampleNumberForType(RegionCode::DE, PhoneNumberType::FIXED_LINE_OR_MOBILE)
435
        );
436
        $this->assertNotNull($this->phoneUtil->getExampleNumberForType(RegionCode::US, PhoneNumberType::FIXED_LINE));
437
        $this->assertNotNull($this->phoneUtil->getExampleNumberForType(RegionCode::US, PhoneNumberType::MOBILE));
438
        // We have data for the US, but no data for VOICEMAIL, so return null
439
        $this->assertNull($this->phoneUtil->getExampleNumberForType(RegionCode::US, PhoneNumberType::VOICEMAIL));
440
        // CS is an invalid region, so we have no data for it.
441
        $this->assertNull($this->phoneUtil->getExampleNumberForType(RegionCode::CS, PhoneNumberType::MOBILE));
442
        // RegionCode 001 is reserved for supporting non-geographical country calling code. We don't
443
        // support getting an example number for it with this method.
444
        $this->assertEquals(null, $this->phoneUtil->getExampleNumber(RegionCode::UN001));
445
    }
446
447
    public function testGetExampleNumberForNonGeoEntity()
448
    {
449
        $this->assertEquals(self::$internationalTollFree, $this->phoneUtil->getExampleNumberForNonGeoEntity(800));
450
        $this->assertEquals(self::$universalPremiumRate, $this->phoneUtil->getExampleNumberForNonGeoEntity(979));
451
    }
452
453
    public function testGetExampleNumberWithoutRegion()
454
    {
455
        // In our test metadata we don't cover all types: in our real metadata, we do.
456
        $this->assertNotnull($this->phoneUtil->getExampleNumberForType(PhoneNumberType::FIXED_LINE));
457
        $this->assertNotnull($this->phoneUtil->getExampleNumberForType(PhoneNumberType::MOBILE));
458
        $this->assertNotnull($this->phoneUtil->getExampleNumberForType(PhoneNumberType::PREMIUM_RATE));
459
    }
460
461
    public function testConvertAlphaCharactersInNumber()
462
    {
463
        $input = "1800-ABC-DEF";
464
        // Alpha chars are converted to digits; everything else is left untouched.
465
        $expectedOutput = "1800-222-333";
466
        $this->assertEquals($expectedOutput, PhoneNumberUtil::convertAlphaCharactersInNumber($input));
467
    }
468
469
    public function testNormaliseRemovePunctuation()
470
    {
471
        $inputNumber = "034-56&+#2" . pack('H*', 'c2ad') . "34";
472
        $expectedOutput = "03456234";
473
        $this->assertEquals(
474
            $expectedOutput,
475
            PhoneNumberUtil::normalize($inputNumber),
476
            "Conversion did not correctly remove punctuation"
477
        );
478
    }
479
480
    public function testNormaliseReplaceAlphaCharacters()
481
    {
482
        $inputNumber = "034-I-am-HUNGRY";
483
        $expectedOutput = "034426486479";
484
        $this->assertEquals(
485
            $expectedOutput,
486
            PhoneNumberUtil::normalize($inputNumber),
487
            "Conversion did not correctly replace alpha characters"
488
        );
489
    }
490
491
    public function testNormaliseOtherDigits()
492
    {
493
        $inputNumber = "\xEF\xBC\x92" . "5\xD9\xA5" /* "25٥" */
494
        ;
495
        $expectedOutput = "255";
496
        $this->assertEquals(
497
            $expectedOutput,
498
            PhoneNumberUtil::normalize($inputNumber),
499
            "Conversion did not correctly replace non-latin digits"
500
        );
501
        // Eastern-Arabic digits.
502
        $inputNumber = "\xDB\xB5" . "2\xDB\xB0" /* "۵2۰" */
503
        ;
504
        $expectedOutput = "520";
505
        $this->assertEquals(
506
            $expectedOutput,
507
            PhoneNumberUtil::normalize($inputNumber),
508
            "Conversion did not correctly replace non-latin digits"
509
        );
510
    }
511
512
    public function testNormaliseStripAlphaCharacters()
513
    {
514
        $inputNumber = "034-56&+a#234";
515
        $expectedOutput = "03456234";
516
        $this->assertEquals(
517
            $expectedOutput,
518
            PhoneNumberUtil::normalizeDigitsOnly($inputNumber),
519
            "Conversion did not correctly remove alpha character"
520
        );
521
    }
522
523
    public function testNormaliseStripNonDiallableCharacters()
524
    {
525
        $inputNumber = "03*4-56&+1a#234";
526
        $expectedOutput = "03*456+1#234";
527
        $this->assertEquals(
528
            $expectedOutput,
529
            PhoneNumberUtil::normalizeDiallableCharsOnly($inputNumber),
530
            "Conversion did not correctly remove non-diallable characters"
531
        );
532
    }
533
534
    public function testFormatUSNumber()
535
    {
536
        $this->assertEquals("650 253 0000", $this->phoneUtil->format(self::$usNumber, PhoneNumberFormat::NATIONAL));
537
        $this->assertEquals(
538
            "+1 650 253 0000",
539
            $this->phoneUtil->format(self::$usNumber, PhoneNumberFormat::INTERNATIONAL)
540
        );
541
542
        $this->assertEquals("800 253 0000", $this->phoneUtil->format(self::$usTollFree, PhoneNumberFormat::NATIONAL));
543
        $this->assertEquals(
544
            "+1 800 253 0000",
545
            $this->phoneUtil->format(self::$usTollFree, PhoneNumberFormat::INTERNATIONAL)
546
        );
547
548
        $this->assertEquals("900 253 0000", $this->phoneUtil->format(self::$usPremium, PhoneNumberFormat::NATIONAL));
549
        $this->assertEquals(
550
            "+1 900 253 0000",
551
            $this->phoneUtil->format(self::$usPremium, PhoneNumberFormat::INTERNATIONAL)
552
        );
553
        $this->assertEquals(
554
            "tel:+1-900-253-0000",
555
            $this->phoneUtil->format(self::$usPremium, PhoneNumberFormat::RFC3966)
556
        );
557
        // Numbers with all zeros in the national number part will be formatted by using the raw_input
558
        // if that is available no matter which format is specified.
559
        $this->assertEquals(
560
            "000-000-0000",
561
            $this->phoneUtil->format(self::$usSpoofWithRawInput, PhoneNumberFormat::NATIONAL)
562
        );
563
        $this->assertEquals("0", $this->phoneUtil->format(self::$usSpoof, PhoneNumberFormat::NATIONAL));
564
    }
565
566
    public function testFormatBSNumber()
567
    {
568
        $this->assertEquals("242 365 1234", $this->phoneUtil->format(self::$bsNumber, PhoneNumberFormat::NATIONAL));
569
        $this->assertEquals(
570
            "+1 242 365 1234",
571
            $this->phoneUtil->format(self::$bsNumber, PhoneNumberFormat::INTERNATIONAL)
572
        );
573
    }
574
575
    public function testFormatGBNumber()
576
    {
577
        $this->assertEquals("(020) 7031 3000", $this->phoneUtil->format(self::$gbNumber, PhoneNumberFormat::NATIONAL));
578
        $this->assertEquals(
579
            "+44 20 7031 3000",
580
            $this->phoneUtil->format(self::$gbNumber, PhoneNumberFormat::INTERNATIONAL)
581
        );
582
583
        $this->assertEquals("(07912) 345 678", $this->phoneUtil->format(self::$gbMobile, PhoneNumberFormat::NATIONAL));
584
        $this->assertEquals(
585
            "+44 7912 345 678",
586
            $this->phoneUtil->format(self::$gbMobile, PhoneNumberFormat::INTERNATIONAL)
587
        );
588
    }
589
590
    public function testFormatDENumber()
591
    {
592
        $deNumber = new PhoneNumber();
593
        $deNumber->setCountryCode(49)->setNationalNumber(301234);
594
        $this->assertEquals("030/1234", $this->phoneUtil->format($deNumber, PhoneNumberFormat::NATIONAL));
595
        $this->assertEquals("+49 30/1234", $this->phoneUtil->format($deNumber, PhoneNumberFormat::INTERNATIONAL));
596
        $this->assertEquals("tel:+49-30-1234", $this->phoneUtil->format($deNumber, PhoneNumberFormat::RFC3966));
597
598
        $deNumber->clear();
599
        $deNumber->setCountryCode(49)->setNationalNumber(291123);
600
        $this->assertEquals("0291 123", $this->phoneUtil->format($deNumber, PhoneNumberFormat::NATIONAL));
601
        $this->assertEquals("+49 291 123", $this->phoneUtil->format($deNumber, PhoneNumberFormat::INTERNATIONAL));
602
603
        $deNumber->clear();
604
        $deNumber->setCountryCode(49)->setNationalNumber(29112345678);
605
        $this->assertEquals("0291 12345678", $this->phoneUtil->format($deNumber, PhoneNumberFormat::NATIONAL));
606
        $this->assertEquals("+49 291 12345678", $this->phoneUtil->format($deNumber, PhoneNumberFormat::INTERNATIONAL));
607
608
        $deNumber->clear();
609
        $deNumber->setCountryCode(49)->setNationalNumber(912312345);
610
        $this->assertEquals("09123 12345", $this->phoneUtil->format($deNumber, PhoneNumberFormat::NATIONAL));
611
        $this->assertEquals("+49 9123 12345", $this->phoneUtil->format($deNumber, PhoneNumberFormat::INTERNATIONAL));
612
        $deNumber->clear();
613
        $deNumber->setCountryCode(49)->setNationalNumber(80212345);
614
        $this->assertEquals("08021 2345", $this->phoneUtil->format($deNumber, PhoneNumberFormat::NATIONAL));
615
        $this->assertEquals("+49 8021 2345", $this->phoneUtil->format($deNumber, PhoneNumberFormat::INTERNATIONAL));
616
        // Note this number is correctly formatted without national prefix. Most of the numbers that
617
        // are treated as invalid numbers by the library are short numbers, and they are usually not
618
        // dialed with national prefix.
619
        $this->assertEquals("1234", $this->phoneUtil->format(self::$deShortNumber, PhoneNumberFormat::NATIONAL));
620
        $this->assertEquals(
621
            "+49 1234",
622
            $this->phoneUtil->format(self::$deShortNumber, PhoneNumberFormat::INTERNATIONAL)
623
        );
624
625
        $deNumber->clear();
626
        $deNumber->setCountryCode(49)->setNationalNumber(41341234);
627
        $this->assertEquals("04134 1234", $this->phoneUtil->format($deNumber, PhoneNumberFormat::NATIONAL));
628
    }
629
630
    public function testFormatITNumber()
631
    {
632
        $this->assertEquals("02 3661 8300", $this->phoneUtil->format(self::$itNumber, PhoneNumberFormat::NATIONAL));
633
        $this->assertEquals(
634
            "+39 02 3661 8300",
635
            $this->phoneUtil->format(self::$itNumber, PhoneNumberFormat::INTERNATIONAL)
636
        );
637
        $this->assertEquals("+390236618300", $this->phoneUtil->format(self::$itNumber, PhoneNumberFormat::E164));
638
639
        $this->assertEquals("345 678 901", $this->phoneUtil->format(self::$itMobile, PhoneNumberFormat::NATIONAL));
640
        $this->assertEquals(
641
            "+39 345 678 901",
642
            $this->phoneUtil->format(self::$itMobile, PhoneNumberFormat::INTERNATIONAL)
643
        );
644
        $this->assertEquals("+39345678901", $this->phoneUtil->format(self::$itMobile, PhoneNumberFormat::E164));
645
    }
646
647
    public function testFormatAUNumber()
648
    {
649
        $this->assertEquals("02 3661 8300", $this->phoneUtil->format(self::$auNumber, PhoneNumberFormat::NATIONAL));
650
        $this->assertEquals(
651
            "+61 2 3661 8300",
652
            $this->phoneUtil->format(self::$auNumber, PhoneNumberFormat::INTERNATIONAL)
653
        );
654
        $this->assertEquals("+61236618300", $this->phoneUtil->format(self::$auNumber, PhoneNumberFormat::E164));
655
656
        $auNumber = new PhoneNumber();
657
        $auNumber->setCountryCode(61)->setNationalNumber(1800123456);
658
        $this->assertEquals("1800 123 456", $this->phoneUtil->format($auNumber, PhoneNumberFormat::NATIONAL));
659
        $this->assertEquals("+61 1800 123 456", $this->phoneUtil->format($auNumber, PhoneNumberFormat::INTERNATIONAL));
660
        $this->assertEquals("+611800123456", $this->phoneUtil->format($auNumber, PhoneNumberFormat::E164));
661
    }
662
663
    public function testFormatARNumber()
664
    {
665
        $this->assertEquals("011 8765-4321", $this->phoneUtil->format(self::$arNumber, PhoneNumberFormat::NATIONAL));
666
        $this->assertEquals(
667
            "+54 11 8765-4321",
668
            $this->phoneUtil->format(self::$arNumber, PhoneNumberFormat::INTERNATIONAL)
669
        );
670
        $this->assertEquals("+541187654321", $this->phoneUtil->format(self::$arNumber, PhoneNumberFormat::E164));
671
672
        $this->assertEquals("011 15 8765-4321", $this->phoneUtil->format(self::$arMobile, PhoneNumberFormat::NATIONAL));
673
        $this->assertEquals(
674
            "+54 9 11 8765 4321",
675
            $this->phoneUtil->format(self::$arMobile, PhoneNumberFormat::INTERNATIONAL)
676
        );
677
        $this->assertEquals("+5491187654321", $this->phoneUtil->format(self::$arMobile, PhoneNumberFormat::E164));
678
    }
679
680
    public function testFormatMXNumber()
681
    {
682
        $this->assertEquals(
683
            "045 234 567 8900",
684
            $this->phoneUtil->format(self::$mxMobile1, PhoneNumberFormat::NATIONAL)
685
        );
686
        $this->assertEquals(
687
            "+52 1 234 567 8900",
688
            $this->phoneUtil->format(self::$mxMobile1, PhoneNumberFormat::INTERNATIONAL)
689
        );
690
        $this->assertEquals("+5212345678900", $this->phoneUtil->format(self::$mxMobile1, PhoneNumberFormat::E164));
691
692
        $this->assertEquals(
693
            "045 55 1234 5678",
694
            $this->phoneUtil->format(self::$mxMobile2, PhoneNumberFormat::NATIONAL)
695
        );
696
        $this->assertEquals(
697
            "+52 1 55 1234 5678",
698
            $this->phoneUtil->format(self::$mxMobile2, PhoneNumberFormat::INTERNATIONAL)
699
        );
700
        $this->assertEquals("+5215512345678", $this->phoneUtil->format(self::$mxMobile2, PhoneNumberFormat::E164));
701
702
        $this->assertEquals("01 33 1234 5678", $this->phoneUtil->format(self::$mxNumber1, PhoneNumberFormat::NATIONAL));
703
        $this->assertEquals(
704
            "+52 33 1234 5678",
705
            $this->phoneUtil->format(self::$mxNumber1, PhoneNumberFormat::INTERNATIONAL)
706
        );
707
        $this->assertEquals("+523312345678", $this->phoneUtil->format(self::$mxNumber1, PhoneNumberFormat::E164));
708
709
        $this->assertEquals("01 821 123 4567", $this->phoneUtil->format(self::$mxNumber2, PhoneNumberFormat::NATIONAL));
710
        $this->assertEquals(
711
            "+52 821 123 4567",
712
            $this->phoneUtil->format(self::$mxNumber2, PhoneNumberFormat::INTERNATIONAL)
713
        );
714
        $this->assertEquals("+528211234567", $this->phoneUtil->format(self::$mxNumber2, PhoneNumberFormat::E164));
715
    }
716
717
    public function testFormatOutOfCountryCallingNumber()
718
    {
719
        $this->assertEquals(
720
            "00 1 900 253 0000",
721
            $this->phoneUtil->formatOutOfCountryCallingNumber(self::$usPremium, RegionCode::DE)
722
        );
723
        $this->assertEquals(
724
            "1 650 253 0000",
725
            $this->phoneUtil->formatOutOfCountryCallingNumber(self::$usNumber, RegionCode::BS)
726
        );
727
728
        $this->assertEquals(
729
            "00 1 650 253 0000",
730
            $this->phoneUtil->formatOutOfCountryCallingNumber(self::$usNumber, RegionCode::PL)
731
        );
732
733
        $this->assertEquals(
734
            "011 44 7912 345 678",
735
            $this->phoneUtil->formatOutOfCountryCallingNumber(self::$gbMobile, RegionCode::US)
736
        );
737
738
        $this->assertEquals(
739
            "00 49 1234",
740
            $this->phoneUtil->formatOutOfCountryCallingNumber(self::$deShortNumber, RegionCode::GB)
741
        );
742
        // Note this number is correctly formatted without national prefix. Most of the numbers that
743
        // are treated as invalid numbers by the library are short numbers, and they are usually not
744
        // dialed with national prefix.
745
        $this->assertEquals(
746
            "1234",
747
            $this->phoneUtil->formatOutOfCountryCallingNumber(self::$deShortNumber, RegionCode::DE)
748
        );
749
750
        $this->assertEquals(
751
            "011 39 02 3661 8300",
752
            $this->phoneUtil->formatOutOfCountryCallingNumber(self::$itNumber, RegionCode::US)
753
        );
754
        $this->assertEquals(
755
            "02 3661 8300",
756
            $this->phoneUtil->formatOutOfCountryCallingNumber(self::$itNumber, RegionCode::IT)
757
        );
758
        $this->assertEquals(
759
            "+39 02 3661 8300",
760
            $this->phoneUtil->formatOutOfCountryCallingNumber(self::$itNumber, RegionCode::SG)
761
        );
762
763
        $this->assertEquals(
764
            "6521 8000",
765
            $this->phoneUtil->formatOutOfCountryCallingNumber(self::$sgNumber, RegionCode::SG)
766
        );
767
768
        $this->assertEquals(
769
            "011 54 9 11 8765 4321",
770
            $this->phoneUtil->formatOutOfCountryCallingNumber(self::$arMobile, RegionCode::US)
771
        );
772
        $this->assertEquals(
773
            "011 800 1234 5678",
774
            $this->phoneUtil->formatOutOfCountryCallingNumber(self::$internationalTollFree, RegionCode::US)
775
        );
776
777
        $arNumberWithExtn = new PhoneNumber();
778
        $arNumberWithExtn->mergeFrom(self::$arMobile)->setExtension("1234");
779
        $this->assertEquals(
780
            "011 54 9 11 8765 4321 ext. 1234",
781
            $this->phoneUtil->formatOutOfCountryCallingNumber($arNumberWithExtn, RegionCode::US)
782
        );
783
        $this->assertEquals(
784
            "0011 54 9 11 8765 4321 ext. 1234",
785
            $this->phoneUtil->formatOutOfCountryCallingNumber($arNumberWithExtn, RegionCode::AU)
786
        );
787
        $this->assertEquals(
788
            "011 15 8765-4321 ext. 1234",
789
            $this->phoneUtil->formatOutOfCountryCallingNumber($arNumberWithExtn, RegionCode::AR)
790
        );
791
    }
792
793
    public function testFormatOutOfCountryWithInvalidRegion()
794
    {
795
        // AQ/Antarctica isn't a valid region code for phone number formatting,
796
        // so this falls back to intl formatting.
797
        $this->assertEquals(
798
            "+1 650 253 0000",
799
            $this->phoneUtil->formatOutOfCountryCallingNumber(self::$usNumber, RegionCode::AQ)
800
        );
801
        // For region code 001, the out-of-country format always turns into the international format.
802
        $this->assertEquals(
803
            "+1 650 253 0000",
804
            $this->phoneUtil->formatOutOfCountryCallingNumber(self::$usNumber, RegionCode::UN001)
805
        );
806
    }
807
808
    public function testFormatOutOfCountryWithPreferredIntlPrefix()
809
    {
810
        // This should use 0011, since that is the preferred international prefix (both 0011 and 0012
811
        // are accepted as possible international prefixes in our test metadta.)
812
        $this->assertEquals(
813
            "0011 39 02 3661 8300",
814
            $this->phoneUtil->formatOutOfCountryCallingNumber(self::$itNumber, RegionCode::AU)
815
        );
816
    }
817
818
    public function testFormatOutOfCountryKeepingAlphaChars()
819
    {
820
        $alphaNumericNumber = new PhoneNumber();
821
        $alphaNumericNumber->setCountryCode(1)->setNationalNumber(8007493524)->setRawInput("1800 six-flag");
822
        $this->assertEquals(
823
            "0011 1 800 SIX-FLAG",
824
            $this->phoneUtil->formatOutOfCountryKeepingAlphaChars($alphaNumericNumber, RegionCode::AU)
825
        );
826
827
        $alphaNumericNumber->setRawInput("1-800-SIX-flag");
828
        $this->assertEquals(
829
            "0011 1 800-SIX-FLAG",
830
            $this->phoneUtil->formatOutOfCountryKeepingAlphaChars($alphaNumericNumber, RegionCode::AU)
831
        );
832
833
        $alphaNumericNumber->setRawInput("Call us from UK: 00 1 800 SIX-flag");
834
        $this->assertEquals(
835
            "0011 1 800 SIX-FLAG",
836
            $this->phoneUtil->formatOutOfCountryKeepingAlphaChars($alphaNumericNumber, RegionCode::AU)
837
        );
838
839
        $alphaNumericNumber->setRawInput("800 SIX-flag");
840
        $this->assertEquals(
841
            "0011 1 800 SIX-FLAG",
842
            $this->phoneUtil->formatOutOfCountryKeepingAlphaChars($alphaNumericNumber, RegionCode::AU)
843
        );
844
845
        // Formatting from within the NANPA region.
846
        $this->assertEquals(
847
            "1 800 SIX-FLAG",
848
            $this->phoneUtil->formatOutOfCountryKeepingAlphaChars($alphaNumericNumber, RegionCode::US)
849
        );
850
851
        $this->assertEquals(
852
            "1 800 SIX-FLAG",
853
            $this->phoneUtil->formatOutOfCountryKeepingAlphaChars($alphaNumericNumber, RegionCode::BS)
854
        );
855
856
        // Testing that if the raw input doesn't exist, it is formatted using
857
        // formatOutOfCountryCallingNumber.
858
        $alphaNumericNumber->clearRawInput();
859
        $this->assertEquals(
860
            "00 1 800 749 3524",
861
            $this->phoneUtil->formatOutOfCountryKeepingAlphaChars($alphaNumericNumber, RegionCode::DE)
862
        );
863
864
        // Testing AU alpha number formatted from Australia.
865
        $alphaNumericNumber->setCountryCode(61)->setNationalNumber(827493524)->setRawInput("+61 82749-FLAG");
866
        // This number should have the national prefix fixed.
867
        $this->assertEquals(
868
            "082749-FLAG",
869
            $this->phoneUtil->formatOutOfCountryKeepingAlphaChars($alphaNumericNumber, RegionCode::AU)
870
        );
871
872
        $alphaNumericNumber->setRawInput("082749-FLAG");
873
        $this->assertEquals(
874
            "082749-FLAG",
875
            $this->phoneUtil->formatOutOfCountryKeepingAlphaChars($alphaNumericNumber, RegionCode::AU)
876
        );
877
878
        $alphaNumericNumber->setNationalNumber(18007493524)->setRawInput("1-800-SIX-flag");
879
        // This number should not have the national prefix prefixed, in accordance with the override for
880
        // this specific formatting rule.
881
        $this->assertEquals(
882
            "1-800-SIX-FLAG",
883
            $this->phoneUtil->formatOutOfCountryKeepingAlphaChars($alphaNumericNumber, RegionCode::AU)
884
        );
885
886
        // The metadata should not be permanently changed, since we copied it before modifying patterns.
887
        // Here we check this.
888
        $alphaNumericNumber->setNationalNumber(1800749352);
889
        $this->assertEquals(
890
            "1800 749 352",
891
            $this->phoneUtil->formatOutOfCountryCallingNumber($alphaNumericNumber, RegionCode::AU)
892
        );
893
894
        // Testing a region with multiple international prefixes.
895
        $this->assertEquals(
896
            "+61 1-800-SIX-FLAG",
897
            $this->phoneUtil->formatOutOfCountryKeepingAlphaChars($alphaNumericNumber, RegionCode::SG)
898
        );
899
        // Testing the case of calling from a non-supported region.
900
        $this->assertEquals(
901
            "+61 1-800-SIX-FLAG",
902
            $this->phoneUtil->formatOutOfCountryKeepingAlphaChars($alphaNumericNumber, RegionCode::AQ)
903
        );
904
905
        // Testing the case with an invalid country calling code.
906
        $alphaNumericNumber->setCountryCode(0)->setNationalNumber(18007493524)->setRawInput("1-800-SIX-flag");
907
        // Uses the raw input only.
908
        $this->assertEquals(
909
            "1-800-SIX-flag",
910
            $this->phoneUtil->formatOutOfCountryKeepingAlphaChars($alphaNumericNumber, RegionCode::DE)
911
        );
912
913
        // Testing the case of an invalid alpha number.
914
        $alphaNumericNumber->setCountryCode(1)->setNationalNumber(80749)->setRawInput("180-SIX");
915
        // No country-code stripping can be done.
916
        $this->assertEquals(
917
            "00 1 180-SIX",
918
            $this->phoneUtil->formatOutOfCountryKeepingAlphaChars($alphaNumericNumber, RegionCode::DE)
919
        );
920
921
        // Testing the case of calling from a non-supported region.
922
        $alphaNumericNumber->setCountryCode(1)->setNationalNumber(80749)->setRawInput("180-SIX");
923
        // No country-code stripping can be done since the number is invalid.
924
        $this->assertEquals(
925
            "+1 180-SIX",
926
            $this->phoneUtil->formatOutOfCountryKeepingAlphaChars($alphaNumericNumber, RegionCode::AQ)
927
        );
928
    }
929
930
    public function testFormatWithCarrierCode()
931
    {
932
        // We only support this for AR in our test metadata, and only for mobile numbers starting with
933
        // certain values.
934
        $arMobile = new PhoneNumber();
935
        $arMobile->setCountryCode(54)->setNationalNumber(92234654321);
936
        $this->assertEquals("02234 65-4321", $this->phoneUtil->format($arMobile, PhoneNumberFormat::NATIONAL));
937
        // Here we force 14 as the carrier code.
938
        $this->assertEquals(
939
            "02234 14 65-4321",
940
            $this->phoneUtil->formatNationalNumberWithCarrierCode($arMobile, "14")
941
        );
942
        // Here we force the number to be shown with no carrier code.
943
        $this->assertEquals(
944
            "02234 65-4321",
945
            $this->phoneUtil->formatNationalNumberWithCarrierCode($arMobile, "")
946
        );
947
        // Here the international rule is used, so no carrier code should be present.
948
        $this->assertEquals("+5492234654321", $this->phoneUtil->format($arMobile, PhoneNumberFormat::E164));
949
        // We don't support this for the US so there should be no change.
950
        $this->assertEquals(
951
            "650 253 0000",
952
            $this->phoneUtil->formatNationalNumberWithCarrierCode(self::$usNumber, "15")
953
        );
954
955
        // Invalid country code should just get the NSN.
956
        $this->assertEquals(
957
            "12345",
958
            $this->phoneUtil->formatNationalNumberWithCarrierCode(self::$unknownCountryCodeNoRawInput, "89")
959
        );
960
    }
961
962
    public function testFormatWithPreferredCarrierCode()
963
    {
964
        // We only support this for AR in our test metadata.
965
        $arNumber = new PhoneNumber();
966
        $arNumber->setCountryCode(54)->setNationalNumber(91234125678);
967
        // Test formatting with no preferred carrier code stored in the number itself.
968
        $this->assertEquals(
969
            "01234 15 12-5678",
970
            $this->phoneUtil->formatNationalNumberWithPreferredCarrierCode($arNumber, "15")
971
        );
972
        $this->assertEquals(
973
            "01234 12-5678",
974
            $this->phoneUtil->formatNationalNumberWithPreferredCarrierCode($arNumber, "")
975
        );
976
        // Test formatting with preferred carrier code present.
977
        $arNumber->setPreferredDomesticCarrierCode("19");
978
        $this->assertEquals("01234 12-5678", $this->phoneUtil->format($arNumber, PhoneNumberFormat::NATIONAL));
979
        $this->assertEquals(
980
            "01234 19 12-5678",
981
            $this->phoneUtil->formatNationalNumberWithPreferredCarrierCode($arNumber, "15")
982
        );
983
        $this->assertEquals(
984
            "01234 19 12-5678",
985
            $this->phoneUtil->formatNationalNumberWithPreferredCarrierCode($arNumber, "")
986
        );
987
        // When the preferred_domestic_carrier_code is present (even when it is just a space), use it
988
        // instead of the default carrier code passed in.
989
        $arNumber->setPreferredDomesticCarrierCode(" ");
990
        $this->assertEquals(
991
            "01234   12-5678",
992
            $this->phoneUtil->formatNationalNumberWithPreferredCarrierCode($arNumber, "15")
993
        );
994
        // When the preferred_domestic_carrier_code is present but empty, treat it as unset and use
995
        // instead of the default carrier code passed in.
996
        $arNumber->setPreferredDomesticCarrierCode("");
997
        $this->assertEquals(
998
            "01234 15 12-5678",
999
            $this->phoneUtil->formatNationalNumberWithPreferredCarrierCode($arNumber, "15")
1000
        );
1001
        // We don't support this for the US so there should be no change.
1002
        $usNumber = new PhoneNumber();
1003
        $usNumber->setCountryCode(1)->setNationalNumber(4241231234)->setPreferredDomesticCarrierCode("99");
1004
        $this->assertEquals("424 123 1234", $this->phoneUtil->format($usNumber, PhoneNumberFormat::NATIONAL));
1005
        $this->assertEquals(
1006
            "424 123 1234",
1007
            $this->phoneUtil->formatNationalNumberWithPreferredCarrierCode($usNumber, "15")
1008
        );
1009
    }
1010
1011
    public function testFormatNumberForMobileDialing()
1012
    {
1013
        // Numbers are normally dialed in national format in-country, and international format from
1014
        // outside the country.
1015
        $this->assertEquals(
1016
            "030123456",
1017
            $this->phoneUtil->formatNumberForMobileDialing(self::$deNumber, RegionCode::DE, false)
1018
        );
1019
        $this->assertEquals(
1020
            "+4930123456",
1021
            $this->phoneUtil->formatNumberForMobileDialing(self::$deNumber, RegionCode::CH, false)
1022
        );
1023
        $this->assertEquals(
1024
            "+4930123456",
1025
            $this->phoneUtil->formatNumberForMobileDialing(self::$deNumber, RegionCode::CH, false)
1026
        );
1027
        $deNumberWithExtn = new PhoneNumber();
1028
        $deNumberWithExtn->mergeFrom(self::$deNumber)->setExtension("1234");
1029
        $this->assertEquals(
1030
            "030123456",
1031
            $this->phoneUtil->formatNumberForMobileDialing($deNumberWithExtn, RegionCode::DE, false)
1032
        );
1033
        $this->assertEquals(
1034
            "+4930123456",
1035
            $this->phoneUtil->formatNumberForMobileDialing($deNumberWithExtn, RegionCode::CH, false)
1036
        );
1037
1038
        // US toll free numbers are marked as noInternationalDialling in the test metadata for testing
1039
        // purposes. For such numbers, we expect nothing to be returned when the region code is not the
1040
        // same one.
1041
        $this->assertEquals(
1042
            "800 253 0000",
1043
            $this->phoneUtil->formatNumberForMobileDialing(
1044
                self::$usTollFree,
1045
                RegionCode::US,
1046
                true /*  keep formatting */
1047
            )
1048
        );
1049
        $this->assertEquals(
1050
            "",
1051
            $this->phoneUtil->formatNumberForMobileDialing(self::$usTollFree, RegionCode::CN, true)
1052
        );
1053
        $this->assertEquals(
1054
            "+1 650 253 0000",
1055
            $this->phoneUtil->formatNumberForMobileDialing(self::$usNumber, RegionCode::US, true)
1056
        );
1057
        $usNumberWithExtn = new PhoneNumber();
1058
        $usNumberWithExtn->mergeFrom(self::$usNumber)->setExtension("1234");
1059
        $this->assertEquals(
1060
            "+1 650 253 0000",
1061
            $this->phoneUtil->formatNumberForMobileDialing($usNumberWithExtn, RegionCode::US, true)
1062
        );
1063
1064
        $this->assertEquals(
1065
            "8002530000",
1066
            $this->phoneUtil->formatNumberForMobileDialing(
1067
                self::$usTollFree,
1068
                RegionCode::US,
1069
                false /* remove formatting */
1070
            )
1071
        );
1072
        $this->assertEquals(
1073
            "",
1074
            $this->phoneUtil->formatNumberForMobileDialing(self::$usTollFree, RegionCode::CN, false)
1075
        );
1076
        $this->assertEquals(
1077
            "+16502530000",
1078
            $this->phoneUtil->formatNumberForMobileDialing(self::$usNumber, RegionCode::US, false)
1079
        );
1080
        $this->assertEquals(
1081
            "+16502530000",
1082
            $this->phoneUtil->formatNumberForMobileDialing($usNumberWithExtn, RegionCode::US, false)
1083
        );
1084
1085
        // An invalid US number, which is one digit too long.
1086
        $this->assertEquals(
1087
            "+165025300001",
1088
            $this->phoneUtil->formatNumberForMobileDialing(self::$usLongNumber, RegionCode::US, false)
1089
        );
1090
        $this->assertEquals(
1091
            "+1 65025300001",
1092
            $this->phoneUtil->formatNumberForMobileDialing(self::$usLongNumber, RegionCode::US, true)
1093
        );
1094
1095
        // Star numbers. In real life they appear in Israel, but we have them in JP in our test
1096
        // metadata.
1097
        $this->assertEquals(
1098
            "*2345",
1099
            $this->phoneUtil->formatNumberForMobileDialing(self::$jpStarNumber, RegionCode::JP, false)
1100
        );
1101
        $this->assertEquals(
1102
            "*2345",
1103
            $this->phoneUtil->formatNumberForMobileDialing(self::$jpStarNumber, RegionCode::JP, true)
1104
        );
1105
1106
        $this->assertEquals(
1107
            "+80012345678",
1108
            $this->phoneUtil->formatNumberForMobileDialing(self::$internationalTollFree, RegionCode::JP, false)
1109
        );
1110
        $this->assertEquals(
1111
            "+800 1234 5678",
1112
            $this->phoneUtil->formatNumberForMobileDialing(self::$internationalTollFree, RegionCode::JP, true)
1113
        );
1114
1115
        // UAE numbers beginning with 600 (classified as UAN) need to be dialled without +971 locally.
1116
        $this->assertEquals(
1117
            "+971600123456",
1118
            $this->phoneUtil->formatNumberForMobileDialing(self::$aeUAN, RegionCode::JP, false)
1119
        );
1120
        $this->assertEquals(
1121
            "600123456",
1122
            $this->phoneUtil->formatNumberForMobileDialing(self::$aeUAN, RegionCode::AE, false)
1123
        );
1124
1125
        $this->assertEquals(
1126
            "+523312345678",
1127
            $this->phoneUtil->formatNumberForMobileDialing(self::$mxNumber1, RegionCode::MX, false)
1128
        );
1129
        $this->assertEquals(
1130
            "+523312345678",
1131
            $this->phoneUtil->formatNumberForMobileDialing(self::$mxNumber1, RegionCode::US, false)
1132
        );
1133
1134
        // Non-geographical numbers should always be dialed in international format.
1135
        $this->assertEquals(
1136
            "+80012345678",
1137
            $this->phoneUtil->formatNumberForMobileDialing(self::$internationalTollFree, RegionCode::US, false)
1138
        );
1139
        $this->assertEquals(
1140
            "+80012345678",
1141
            $this->phoneUtil->formatNumberForMobileDialing(self::$internationalTollFree, RegionCode::UN001, false)
1142
        );
1143
1144
        // Test that a short number is formatted correctly for mobile dialing within the region,
1145
        // and is not diallable from outside the region.
1146
        $deShortNumber = new PhoneNumber();
1147
        $deShortNumber->setCountryCode(49)->setNationalNumber(123);
1148
        $this->assertEquals(
1149
            "123",
1150
            $this->phoneUtil->formatNumberForMobileDialing($deShortNumber, RegionCode::DE, false)
1151
        );
1152
        $this->assertEquals("", $this->phoneUtil->formatNumberForMobileDialing($deShortNumber, RegionCode::IT, false));
1153
1154
        // Test the special logic for Hungary, where the national prefix must be added before dialing
1155
        // from a mobile phone for regular length numbers, but not for short numbers.
1156
        $huRegularNumber = new PhoneNumber();
1157
        $huRegularNumber->setCountryCode(36)->setNationalNumber(301234567);
1158
        $this->assertEquals(
1159
            "06301234567",
1160
            $this->phoneUtil->formatNumberForMobileDialing($huRegularNumber, RegionCode::HU, false)
1161
        );
1162
        $this->assertEquals(
1163
            "+36301234567",
1164
            $this->phoneUtil->formatNumberForMobileDialing($huRegularNumber, RegionCode::JP, false)
1165
        );
1166
        $huShortNumber = new PhoneNumber();
1167
        $huShortNumber->setCountryCode(36)->setNationalNumber(104);
1168
        $this->assertEquals(
1169
            "104",
1170
            $this->phoneUtil->formatNumberForMobileDialing($huShortNumber, RegionCode::HU, false)
1171
        );
1172
        $this->assertEquals("", $this->phoneUtil->formatNumberForMobileDialing($huShortNumber, RegionCode::JP, false));
1173
1174
        // Test the special logic for NANPA countries, for which regular length phone numbers are always
1175
        // output in international format, but short numbers are in national format.
1176
        $this->assertEquals(
1177
            "+16502530000",
1178
            $this->phoneUtil->formatNumberForMobileDialing(self::$usNumber, RegionCode::US, false)
1179
        );
1180
        $this->assertEquals(
1181
            "+16502530000",
1182
            $this->phoneUtil->formatNumberForMobileDialing(self::$usNumber, RegionCode::CA, false)
1183
        );
1184
        $this->assertEquals(
1185
            "+16502530000",
1186
            $this->phoneUtil->formatNumberForMobileDialing(self::$usNumber, RegionCode::BR, false)
1187
        );
1188
        $usShortNumber = new PhoneNumber();
1189
        $usShortNumber->setCountryCode(1)->setNationalNumber(911);
1190
        $this->assertEquals(
1191
            "911",
1192
            $this->phoneUtil->formatNumberForMobileDialing($usShortNumber, RegionCode::US, false)
1193
        );
1194
        $this->assertEquals("", $this->phoneUtil->formatNumberForMobileDialing($usShortNumber, RegionCode::CA, false));
1195
        $this->assertEquals("", $this->phoneUtil->formatNumberForMobileDialing($usShortNumber, RegionCode::BR, false));
1196
1197
        // Test that the Australian emergency number 000 is formatted correctly.
1198
        $auNumber = new PhoneNumber();
1199
        $auNumber->setCountryCode(61)->setNationalNumber(0)->setItalianLeadingZero(true)->setNumberOfLeadingZeros(2);
1200
        $this->assertEquals("000", $this->phoneUtil->formatNumberForMobileDialing($auNumber, RegionCode::AU, false));
1201
        $this->assertEquals("", $this->phoneUtil->formatNumberForMobileDialing($auNumber, RegionCode::NZ, false));
1202
    }
1203
1204
    public function testFormatByPattern()
1205
    {
1206
        $newNumFormat = new NumberFormat();
1207
        $newNumFormat->setPattern("(\\d{3})(\\d{3})(\\d{4})");
1208
        $newNumFormat->setFormat("($1) $2-$3");
1209
        $newNumberFormats = array();
1210
        $newNumberFormats[] = $newNumFormat;
1211
1212
        $this->assertEquals(
1213
            "(650) 253-0000",
1214
            $this->phoneUtil->formatByPattern(
1215
                self::$usNumber,
1216
                PhoneNumberFormat::NATIONAL,
1217
                $newNumberFormats
1218
            )
1219
        );
1220
        $this->assertEquals(
1221
            "+1 (650) 253-0000",
1222
            $this->phoneUtil->formatByPattern(
1223
                self::$usNumber,
1224
                PhoneNumberFormat::INTERNATIONAL,
1225
                $newNumberFormats
1226
            )
1227
        );
1228
        $this->assertEquals(
1229
            "tel:+1-650-253-0000",
1230
            $this->phoneUtil->formatByPattern(
1231
                self::$usNumber,
1232
                PhoneNumberFormat::RFC3966,
1233
                $newNumberFormats
1234
            )
1235
        );
1236
1237
        // $NP is set to '1' for the US. Here we check that for other NANPA countries the US rules are
1238
        // followed.
1239
        $newNumFormat->setNationalPrefixFormattingRule('$NP ($FG)');
1240
        $newNumFormat->setFormat("$1 $2-$3");
1241
        $this->assertEquals(
1242
            "1 (242) 365-1234",
1243
            $this->phoneUtil->formatByPattern(
1244
                self::$bsNumber,
1245
                PhoneNumberFormat::NATIONAL,
1246
                $newNumberFormats
1247
            )
1248
        );
1249
        $this->assertEquals(
1250
            "+1 242 365-1234",
1251
            $this->phoneUtil->formatByPattern(
1252
                self::$bsNumber,
1253
                PhoneNumberFormat::INTERNATIONAL,
1254
                $newNumberFormats
1255
            )
1256
        );
1257
1258
        $newNumFormat->setPattern("(\\d{2})(\\d{5})(\\d{3})");
1259
        $newNumFormat->setFormat("$1-$2 $3");
1260
        $newNumberFormats[0] = $newNumFormat;
1261
1262
        $this->assertEquals(
1263
            "02-36618 300",
1264
            $this->phoneUtil->formatByPattern(
1265
                self::$itNumber,
1266
                PhoneNumberFormat::NATIONAL,
1267
                $newNumberFormats
1268
            )
1269
        );
1270
        $this->assertEquals(
1271
            "+39 02-36618 300",
1272
            $this->phoneUtil->formatByPattern(
1273
                self::$itNumber,
1274
                PhoneNumberFormat::INTERNATIONAL,
1275
                $newNumberFormats
1276
            )
1277
        );
1278
1279
        $newNumFormat->setNationalPrefixFormattingRule('$NP$FG');
1280
        $newNumFormat->setPattern("(\\d{2})(\\d{4})(\\d{4})");
1281
        $newNumFormat->setFormat("$1 $2 $3");
1282
        $newNumberFormats[0] = $newNumFormat;
1283
        $this->assertEquals(
1284
            "020 7031 3000",
1285
            $this->phoneUtil->formatByPattern(
1286
                self::$gbNumber,
1287
                PhoneNumberFormat::NATIONAL,
1288
                $newNumberFormats
1289
            )
1290
        );
1291
1292
        $newNumFormat->setNationalPrefixFormattingRule('($NP$FG)');
1293
        $this->assertEquals(
1294
            "(020) 7031 3000",
1295
            $this->phoneUtil->formatByPattern(
1296
                self::$gbNumber,
1297
                PhoneNumberFormat::NATIONAL,
1298
                $newNumberFormats
1299
            )
1300
        );
1301
1302
        $newNumFormat->setNationalPrefixFormattingRule("");
1303
        $this->assertEquals(
1304
            "20 7031 3000",
1305
            $this->phoneUtil->formatByPattern(
1306
                self::$gbNumber,
1307
                PhoneNumberFormat::NATIONAL,
1308
                $newNumberFormats
1309
            )
1310
        );
1311
1312
        $this->assertEquals(
1313
            "+44 20 7031 3000",
1314
            $this->phoneUtil->formatByPattern(
1315
                self::$gbNumber,
1316
                PhoneNumberFormat::INTERNATIONAL,
1317
                $newNumberFormats
1318
            )
1319
        );
1320
    }
1321
1322
    public function testFormatE164Number()
1323
    {
1324
        $this->assertEquals("+16502530000", $this->phoneUtil->format(self::$usNumber, PhoneNumberFormat::E164));
1325
        $this->assertEquals("+4930123456", $this->phoneUtil->format(self::$deNumber, PhoneNumberFormat::E164));
1326
        $this->assertEquals(
1327
            "+80012345678",
1328
            $this->phoneUtil->format(self::$internationalTollFree, PhoneNumberFormat::E164)
1329
        );
1330
    }
1331
1332
    public function testFormatNumberWithExtension()
1333
    {
1334
        $nzNumber = new PhoneNumber();
1335
        $nzNumber->mergeFrom(self::$nzNumber)->setExtension("1234");
1336
        // Uses default extension prefix:
1337
        $this->assertEquals("03-331 6005 ext. 1234", $this->phoneUtil->format($nzNumber, PhoneNumberFormat::NATIONAL));
1338
        // Uses RFC 3966 syntax.
1339
        $this->assertEquals(
1340
            "tel:+64-3-331-6005;ext=1234",
1341
            $this->phoneUtil->format($nzNumber, PhoneNumberFormat::RFC3966)
1342
        );
1343
        // Extension prefix overridden in the territory information for the US:
1344
        $usNumberWithExtension = new PhoneNumber();
1345
        $usNumberWithExtension->mergeFrom(self::$usNumber)->setExtension("4567");
1346
        $this->assertEquals(
1347
            "650 253 0000 extn. 4567",
1348
            $this->phoneUtil->format($usNumberWithExtension, PhoneNumberFormat::NATIONAL)
1349
        );
1350
    }
1351
1352
    public function testFormatInOriginalFormat()
1353
    {
1354
        $number1 = $this->phoneUtil->parseAndKeepRawInput("+442087654321", RegionCode::GB);
1355
        $this->assertEquals("+44 20 8765 4321", $this->phoneUtil->formatInOriginalFormat($number1, RegionCode::GB));
1356
1357
        $number2 = $this->phoneUtil->parseAndKeepRawInput("02087654321", RegionCode::GB);
1358
        $this->assertEquals("(020) 8765 4321", $this->phoneUtil->formatInOriginalFormat($number2, RegionCode::GB));
1359
1360
        $number3 = $this->phoneUtil->parseAndKeepRawInput("011442087654321", RegionCode::US);
1361
        $this->assertEquals("011 44 20 8765 4321", $this->phoneUtil->formatInOriginalFormat($number3, RegionCode::US));
1362
1363
        $number4 = $this->phoneUtil->parseAndKeepRawInput("442087654321", RegionCode::GB);
1364
        $this->assertEquals("44 20 8765 4321", $this->phoneUtil->formatInOriginalFormat($number4, RegionCode::GB));
1365
1366
        $number5 = $this->phoneUtil->parse("+442087654321", RegionCode::GB);
1367
        $this->assertEquals("(020) 8765 4321", $this->phoneUtil->formatInOriginalFormat($number5, RegionCode::GB));
1368
1369
        // Invalid numbers that we have a formatting pattern for should be formatted properly. Note area
1370
        // codes starting with 7 are intentionally excluded in the test metadata for testing purposes.
1371
        $number6 = $this->phoneUtil->parseAndKeepRawInput("7345678901", RegionCode::US);
1372
        $this->assertEquals("734 567 8901", $this->phoneUtil->formatInOriginalFormat($number6, RegionCode::US));
1373
1374
        // US is not a leading zero country, and the presence of the leading zero leads us to format the
1375
        // number using raw_input.
1376
        $number7 = $this->phoneUtil->parseAndKeepRawInput("0734567 8901", RegionCode::US);
1377
        $this->assertEquals("0734567 8901", $this->phoneUtil->formatInOriginalFormat($number7, RegionCode::US));
1378
1379
        // This number is valid, but we don't have a formatting pattern for it. Fall back to the raw
1380
        // input.
1381
        $number8 = $this->phoneUtil->parseAndKeepRawInput("02-4567-8900", RegionCode::KR);
1382
        $this->assertEquals("02-4567-8900", $this->phoneUtil->formatInOriginalFormat($number8, RegionCode::KR));
1383
1384
        $number9 = $this->phoneUtil->parseAndKeepRawInput("01180012345678", RegionCode::US);
1385
        $this->assertEquals("011 800 1234 5678", $this->phoneUtil->formatInOriginalFormat($number9, RegionCode::US));
1386
1387
        $number10 = $this->phoneUtil->parseAndKeepRawInput("+80012345678", RegionCode::KR);
1388
        $this->assertEquals("+800 1234 5678", $this->phoneUtil->formatInOriginalFormat($number10, RegionCode::KR));
1389
1390
        // US local numbers are formatted correctly, as we have formatting patterns for them.
1391
        $localNumberUS = $this->phoneUtil->parseAndKeepRawInput("2530000", RegionCode::US);
1392
        $this->assertEquals("253 0000", $this->phoneUtil->formatInOriginalFormat($localNumberUS, RegionCode::US));
1393
1394
        $numberWithNationalPrefixUS =
1395
            $this->phoneUtil->parseAndKeepRawInput("18003456789", RegionCode::US);
1396
        $this->assertEquals(
1397
            "1 800 345 6789",
1398
            $this->phoneUtil->formatInOriginalFormat($numberWithNationalPrefixUS, RegionCode::US)
1399
        );
1400
1401
        $numberWithoutNationalPrefixGB =
1402
            $this->phoneUtil->parseAndKeepRawInput("2087654321", RegionCode::GB);
1403
        $this->assertEquals(
1404
            "20 8765 4321",
1405
            $this->phoneUtil->formatInOriginalFormat($numberWithoutNationalPrefixGB, RegionCode::GB)
1406
        );
1407
        // Make sure no metadata is modified as a result of the previous function call.
1408
        $this->assertEquals("(020) 8765 4321", $this->phoneUtil->formatInOriginalFormat($number5, RegionCode::GB));
1409
1410
        $numberWithNationalPrefixMX =
1411
            $this->phoneUtil->parseAndKeepRawInput("013312345678", RegionCode::MX);
1412
        $this->assertEquals(
1413
            "01 33 1234 5678",
1414
            $this->phoneUtil->formatInOriginalFormat($numberWithNationalPrefixMX, RegionCode::MX)
1415
        );
1416
1417
        $numberWithoutNationalPrefixMX =
1418
            $this->phoneUtil->parseAndKeepRawInput("3312345678", RegionCode::MX);
1419
        $this->assertEquals(
1420
            "33 1234 5678",
1421
            $this->phoneUtil->formatInOriginalFormat($numberWithoutNationalPrefixMX, RegionCode::MX)
1422
        );
1423
1424
        $italianFixedLineNumber =
1425
            $this->phoneUtil->parseAndKeepRawInput("0212345678", RegionCode::IT);
1426
        $this->assertEquals(
1427
            "02 1234 5678",
1428
            $this->phoneUtil->formatInOriginalFormat($italianFixedLineNumber, RegionCode::IT)
1429
        );
1430
1431
        $numberWithNationalPrefixJP =
1432
            $this->phoneUtil->parseAndKeepRawInput("00777012", RegionCode::JP);
1433
        $this->assertEquals(
1434
            "0077-7012",
1435
            $this->phoneUtil->formatInOriginalFormat($numberWithNationalPrefixJP, RegionCode::JP)
1436
        );
1437
1438
        $numberWithoutNationalPrefixJP =
1439
            $this->phoneUtil->parseAndKeepRawInput("0777012", RegionCode::JP);
1440
        $this->assertEquals(
1441
            "0777012",
1442
            $this->phoneUtil->formatInOriginalFormat($numberWithoutNationalPrefixJP, RegionCode::JP)
1443
        );
1444
1445
        $numberWithCarrierCodeBR =
1446
            $this->phoneUtil->parseAndKeepRawInput("012 3121286979", RegionCode::BR);
1447
        $this->assertEquals(
1448
            "012 3121286979",
1449
            $this->phoneUtil->formatInOriginalFormat($numberWithCarrierCodeBR, RegionCode::BR)
1450
        );
1451
1452
        // The default national prefix used in this case is 045. When a number with national prefix 044
1453
        // is entered, we return the raw input as we don't want to change the number entered.
1454
        $numberWithNationalPrefixMX1 =
1455
            $this->phoneUtil->parseAndKeepRawInput("044(33)1234-5678", RegionCode::MX);
1456
        $this->assertEquals(
1457
            "044(33)1234-5678",
1458
            $this->phoneUtil->formatInOriginalFormat($numberWithNationalPrefixMX1, RegionCode::MX)
1459
        );
1460
1461
        $numberWithNationalPrefixMX2 =
1462
            $this->phoneUtil->parseAndKeepRawInput("045(33)1234-5678", RegionCode::MX);
1463
        $this->assertEquals(
1464
            "045 33 1234 5678",
1465
            $this->phoneUtil->formatInOriginalFormat($numberWithNationalPrefixMX2, RegionCode::MX)
1466
        );
1467
1468
        // The default international prefix used in this case is 0011. When a number with international
1469
        // prefix 0012 is entered, we return the raw input as we don't want to change the number
1470
        // entered.
1471
        $outOfCountryNumberFromAU1 =
1472
            $this->phoneUtil->parseAndKeepRawInput("0012 16502530000", RegionCode::AU);
1473
        $this->assertEquals(
1474
            "0012 16502530000",
1475
            $this->phoneUtil->formatInOriginalFormat($outOfCountryNumberFromAU1, RegionCode::AU)
1476
        );
1477
1478
        $outOfCountryNumberFromAU2 =
1479
            $this->phoneUtil->parseAndKeepRawInput("0011 16502530000", RegionCode::AU);
1480
        $this->assertEquals(
1481
            "0011 1 650 253 0000",
1482
            $this->phoneUtil->formatInOriginalFormat($outOfCountryNumberFromAU2, RegionCode::AU)
1483
        );
1484
1485
        // Test the star sign is not removed from or added to the original input by this method.
1486
        $starNumber = $this->phoneUtil->parseAndKeepRawInput("*1234", RegionCode::JP);
1487
        $this->assertEquals("*1234", $this->phoneUtil->formatInOriginalFormat($starNumber, RegionCode::JP));
1488
        $numberWithoutStar = $this->phoneUtil->parseAndKeepRawInput("1234", RegionCode::JP);
1489
        $this->assertEquals("1234", $this->phoneUtil->formatInOriginalFormat($numberWithoutStar, RegionCode::JP));
1490
1491
        // Test an invalid national number without raw input is just formatted as the national number.
1492
        $this->assertEquals(
1493
            "650253000",
1494
            $this->phoneUtil->formatInOriginalFormat(self::$usShortByOneNumber, RegionCode::US)
1495
        );
1496
    }
1497
1498
    public function testIsPremiumRate()
1499
    {
1500
        $this->assertEquals(PhoneNumberType::PREMIUM_RATE, $this->phoneUtil->getNumberType(self::$usPremium));
1501
1502
        $premiumRateNumber = new PhoneNumber();
1503
        $premiumRateNumber->setCountryCode(39)->setNationalNumber(892123);
1504
        $this->assertEquals(
1505
            PhoneNumberType::PREMIUM_RATE,
1506
            $this->phoneUtil->getNumberType($premiumRateNumber)
1507
        );
1508
1509
        $premiumRateNumber->clear();
1510
        $premiumRateNumber->setCountryCode(44)->setNationalNumber(9187654321);
1511
        $this->assertEquals(
1512
            PhoneNumberType::PREMIUM_RATE,
1513
            $this->phoneUtil->getNumberType($premiumRateNumber)
1514
        );
1515
1516
        $premiumRateNumber->clear();
1517
        $premiumRateNumber->setCountryCode(49)->setNationalNumber(9001654321);
1518
        $this->assertEquals(
1519
            PhoneNumberType::PREMIUM_RATE,
1520
            $this->phoneUtil->getNumberType($premiumRateNumber)
1521
        );
1522
1523
        $premiumRateNumber->clear();
1524
        $premiumRateNumber->setCountryCode(49)->setNationalNumber(90091234567);
1525
        $this->assertEquals(
1526
            PhoneNumberType::PREMIUM_RATE,
1527
            $this->phoneUtil->getNumberType($premiumRateNumber)
1528
        );
1529
    }
1530
1531
    public function testIsTollFree()
1532
    {
1533
        $tollFreeNumber = new PhoneNumber();
1534
1535
        $tollFreeNumber->setCountryCode(1)->setNationalNumber(8881234567);
1536
        $this->assertEquals(
1537
            PhoneNumberType::TOLL_FREE,
1538
            $this->phoneUtil->getNumberType($tollFreeNumber)
1539
        );
1540
1541
        $tollFreeNumber->clear();
1542
        $tollFreeNumber->setCountryCode(39)->setNationalNumber(803123);
1543
        $this->assertEquals(
1544
            PhoneNumberType::TOLL_FREE,
1545
            $this->phoneUtil->getNumberType($tollFreeNumber)
1546
        );
1547
1548
        $tollFreeNumber->clear();
1549
        $tollFreeNumber->setCountryCode(44)->setNationalNumber(8012345678);
1550
        $this->assertEquals(
1551
            PhoneNumberType::TOLL_FREE,
1552
            $this->phoneUtil->getNumberType($tollFreeNumber)
1553
        );
1554
1555
        $tollFreeNumber->clear();
1556
        $tollFreeNumber->setCountryCode(49)->setNationalNumber(8001234567);
1557
        $this->assertEquals(
1558
            PhoneNumberType::TOLL_FREE,
1559
            $this->phoneUtil->getNumberType($tollFreeNumber)
1560
        );
1561
1562
        $this->assertEquals(
1563
            PhoneNumberType::TOLL_FREE,
1564
            $this->phoneUtil->getNumberType(self::$internationalTollFree)
1565
        );
1566
    }
1567
1568
    public function testIsMobile()
1569
    {
1570
        $this->assertEquals(PhoneNumberType::MOBILE, $this->phoneUtil->getNumberType(self::$bsMobile));
1571
        $this->assertEquals(PhoneNumberType::MOBILE, $this->phoneUtil->getNumberType(self::$gbMobile));
1572
        $this->assertEquals(PhoneNumberType::MOBILE, $this->phoneUtil->getNumberType(self::$itMobile));
1573
        $this->assertEquals(PhoneNumberType::MOBILE, $this->phoneUtil->getNumberType(self::$arMobile));
1574
1575
        $mobileNumber = new PhoneNumber();
1576
        $mobileNumber->setCountryCode(49)->setNationalNumber(15123456789);
1577
        $this->assertEquals(PhoneNumberType::MOBILE, $this->phoneUtil->getNumberType($mobileNumber));
1578
    }
1579
1580
    public function testIsFixedLine()
1581
    {
1582
        $this->assertEquals(PhoneNumberType::FIXED_LINE, $this->phoneUtil->getNumberType(self::$bsNumber));
1583
        $this->assertEquals(PhoneNumberType::FIXED_LINE, $this->phoneUtil->getNumberType(self::$itNumber));
1584
        $this->assertEquals(PhoneNumberType::FIXED_LINE, $this->phoneUtil->getNumberType(self::$gbNumber));
1585
        $this->assertEquals(PhoneNumberType::FIXED_LINE, $this->phoneUtil->getNumberType(self::$deNumber));
1586
    }
1587
1588
    public function testIsFixedLineAndMobile()
1589
    {
1590
        $this->assertEquals(PhoneNumberType::FIXED_LINE_OR_MOBILE, $this->phoneUtil->getNumberType(self::$usNumber));
1591
1592
        $fixedLineAndMobileNumber = new PhoneNumber();
1593
        $fixedLineAndMobileNumber->setCountryCode(54)->setNationalNumber(1987654321);
1594
        $this->assertEquals(
1595
            PhoneNumberType::FIXED_LINE_OR_MOBILE,
1596
            $this->phoneUtil->getNumberType($fixedLineAndMobileNumber)
1597
        );
1598
    }
1599
1600
    public function testIsSharedCost()
1601
    {
1602
        $gbNumber = new PhoneNumber();
1603
        $gbNumber->setCountryCode(44)->setNationalNumber(8431231234);
1604
        $this->assertEquals(PhoneNumberType::SHARED_COST, $this->phoneUtil->getNumberType($gbNumber));
1605
    }
1606
1607
    public function testIsVoip()
1608
    {
1609
        $gbNumber = new PhoneNumber();
1610
        $gbNumber->setCountryCode(44)->setNationalNumber(5631231234);
1611
        $this->assertEquals(PhoneNumberType::VOIP, $this->phoneUtil->getNumberType($gbNumber));
1612
    }
1613
1614
    public function testIsPersonalNumber()
1615
    {
1616
        $gbNumber = new PhoneNumber();
1617
        $gbNumber->setCountryCode(44)->setNationalNumber(7031231234);
1618
        $this->assertEquals(PhoneNumberType::PERSONAL_NUMBER, $this->phoneUtil->getNumberType($gbNumber));
1619
    }
1620
1621
    public function testIsUnknown()
1622
    {
1623
        // Invalid numbers should be of type UNKNOWN.
1624
        $this->assertEquals(PhoneNumberType::UNKNOWN, $this->phoneUtil->getNumberType(self::$usLocalNumber));
1625
    }
1626
1627
    public function testIsValidNumber()
1628
    {
1629
        $this->assertTrue($this->phoneUtil->isValidNumber(self::$usNumber));
1630
        $this->assertTrue($this->phoneUtil->isValidNumber(self::$itNumber));
1631
        $this->assertTrue($this->phoneUtil->isValidNumber(self::$gbMobile));
1632
        $this->assertTrue($this->phoneUtil->isValidNumber(self::$internationalTollFree));
1633
        $this->assertTrue($this->phoneUtil->isValidNumber(self::$universalPremiumRate));
1634
1635
        $nzNumber = new PhoneNumber();
1636
        $nzNumber->setCountryCode(64)->setNationalNumber(21387835);
1637
        $this->assertTrue($this->phoneUtil->isValidNumber($nzNumber));
1638
    }
1639
1640
    public function testIsValidForRegion()
1641
    {
1642
        // This number is valid for the Bahamas, but is not a valid US number.
1643
        $this->assertTrue($this->phoneUtil->isValidNumber(self::$bsNumber));
1644
        $this->assertTrue($this->phoneUtil->isValidNumberForRegion(self::$bsNumber, RegionCode::BS));
1645
        $this->assertFalse($this->phoneUtil->isValidNumberForRegion(self::$bsNumber, RegionCode::US));
1646
        $bsInvalidNumber = new PhoneNumber();
1647
        $bsInvalidNumber->setCountryCode(1)->setNationalNumber(2421232345);
1648
        // This number is no longer valid.
1649
        $this->assertFalse($this->phoneUtil->isValidNumber($bsInvalidNumber));
1650
1651
        // La Mayotte and Reunion use 'leadingDigits' to differentiate them.
1652
        $reNumber = new PhoneNumber();
1653
        $reNumber->setCountryCode(262)->setNationalNumber(262123456);
1654
        $this->assertTrue($this->phoneUtil->isValidNumber($reNumber));
1655
        $this->assertTrue($this->phoneUtil->isValidNumberForRegion($reNumber, RegionCode::RE));
1656
        $this->assertFalse($this->phoneUtil->isValidNumberForRegion($reNumber, RegionCode::YT));
1657
        // Now change the number to be a number for La Mayotte.
1658
        $reNumber->setNationalNumber(269601234);
1659
        $this->assertTrue($this->phoneUtil->isValidNumberForRegion($reNumber, RegionCode::YT));
1660
        $this->assertFalse($this->phoneUtil->isValidNumberForRegion($reNumber, RegionCode::RE));
1661
        // This number is no longer valid for La Reunion.
1662
        $reNumber->setNationalNumber(269123456);
1663
        $this->assertFalse($this->phoneUtil->isValidNumberForRegion($reNumber, RegionCode::YT));
1664
        $this->assertFalse($this->phoneUtil->isValidNumberForRegion($reNumber, RegionCode::RE));
1665
        $this->assertFalse($this->phoneUtil->isValidNumber($reNumber));
1666
        // However, it should be recognised as from La Mayotte, since it is valid for this region.
1667
        $this->assertEquals(RegionCode::YT, $this->phoneUtil->getRegionCodeForNumber($reNumber));
1668
        // This number is valid in both places.
1669
        $reNumber->setNationalNumber(800123456);
1670
        $this->assertTrue($this->phoneUtil->isValidNumberForRegion($reNumber, RegionCode::YT));
1671
        $this->assertTrue($this->phoneUtil->isValidNumberForRegion($reNumber, RegionCode::RE));
1672
        $this->assertTrue($this->phoneUtil->isValidNumberForRegion(self::$internationalTollFree, RegionCode::UN001));
1673
        $this->assertFalse($this->phoneUtil->isValidNumberForRegion(self::$internationalTollFree, RegionCode::US));
1674
        $this->assertFalse($this->phoneUtil->isValidNumberForRegion(self::$internationalTollFree, RegionCode::ZZ));
1675
1676
        $invalidNumber = new PhoneNumber();
1677
        // Invalid country calling codes.
1678
        $invalidNumber->setCountryCode(3923)->setNationalNumber(2366);
1679
        $this->assertFalse($this->phoneUtil->isValidNumberForRegion($invalidNumber, RegionCode::ZZ));
1680
        $this->assertFalse($this->phoneUtil->isValidNumberForRegion($invalidNumber, RegionCode::UN001));
1681
        $invalidNumber->setCountryCode(0);
1682
        $this->assertFalse($this->phoneUtil->isValidNumberForRegion($invalidNumber, RegionCode::UN001));
1683
        $this->assertFalse($this->phoneUtil->isValidNumberForRegion($invalidNumber, RegionCode::ZZ));
1684
    }
1685
1686
    public function testIsNotValidNumber()
1687
    {
1688
        $this->assertFalse($this->phoneUtil->isValidNumber(self::$usLocalNumber));
1689
1690
        $invalidNumber = new PhoneNumber();
1691
        $invalidNumber->setCountryCode(39)->setNationalNumber(23661830000)->setItalianLeadingZero(true);
1692
        $this->assertFalse($this->phoneUtil->isValidNumber($invalidNumber));
1693
1694
        $invalidNumber->clear();
1695
        $invalidNumber->setCountryCode(44)->setNationalNumber(791234567);
1696
        $this->assertFalse($this->phoneUtil->isValidNumber($invalidNumber));
1697
1698
        $invalidNumber->clear();
1699
        $invalidNumber->setCountryCode(49)->setNationalNumber(1234);
1700
        $this->assertFalse($this->phoneUtil->isValidNumber($invalidNumber));
1701
1702
        $invalidNumber->clear();
1703
        $invalidNumber->setCountryCode(64)->setNationalNumber(3316005);
1704
        $this->assertFalse($this->phoneUtil->isValidNumber($invalidNumber));
1705
1706
        $invalidNumber->clear();
1707
        // Invalid country calling codes.
1708
        $invalidNumber->setCountryCode(3923)->setNationalNumber(2366);
1709
        $this->assertFalse($this->phoneUtil->isValidNumber($invalidNumber));
1710
        $invalidNumber->setCountryCode(0);
1711
        $this->assertFalse($this->phoneUtil->isValidNumber($invalidNumber));
1712
1713
        $this->assertFalse($this->phoneUtil->isValidNumber(self::$internationalTollFreeTooLong));
1714
    }
1715
1716
    public function testGetRegionCodeForCountryCode()
1717
    {
1718
        $this->assertEquals(RegionCode::US, $this->phoneUtil->getRegionCodeForCountryCode(1));
1719
        $this->assertEquals(RegionCode::GB, $this->phoneUtil->getRegionCodeForCountryCode(44));
1720
        $this->assertEquals(RegionCode::DE, $this->phoneUtil->getRegionCodeForCountryCode(49));
1721
        $this->assertEquals(RegionCode::UN001, $this->phoneUtil->getRegionCodeForCountryCode(800));
1722
        $this->assertEquals(RegionCode::UN001, $this->phoneUtil->getRegionCodeForCountryCode(979));
1723
    }
1724
1725
    public function testGetRegionCodeForNumber()
1726
    {
1727
        $this->assertEquals(RegionCode::BS, $this->phoneUtil->getRegionCodeForNumber(self::$bsNumber));
1728
        $this->assertEquals(RegionCode::US, $this->phoneUtil->getRegionCodeForNumber(self::$usNumber));
1729
        $this->assertEquals(RegionCode::GB, $this->phoneUtil->getRegionCodeForNumber(self::$gbMobile));
1730
        $this->assertEquals(RegionCode::UN001, $this->phoneUtil->getRegionCodeForNumber(self::$internationalTollFree));
1731
        $this->assertEquals(RegionCode::UN001, $this->phoneUtil->getRegionCodeForNumber(self::$universalPremiumRate));
1732
    }
1733
1734
    public function testGetRegionCodesForCountryCode()
1735
    {
1736
        $regionCodesForNANPA = $this->phoneUtil->getRegionCodesForCountryCode(1);
1737
        $this->assertContains(RegionCode::US, $regionCodesForNANPA);
1738
        $this->assertContains(RegionCode::BS, $regionCodesForNANPA);
1739
        $this->assertContains(RegionCode::GB, $this->phoneUtil->getRegionCodesForCountryCode(44));
1740
        $this->assertContains(RegionCode::DE, $this->phoneUtil->getRegionCodesForCountryCode(49));
1741
        $this->assertContains(RegionCode::UN001, $this->phoneUtil->getRegionCodesForCountryCode(800));
1742
        // Test with invalid country calling code.
1743
        $this->assertEmpty($this->phoneUtil->getRegionCodesForCountryCode(-1));
1744
    }
1745
1746
    public function testGetCountryCodeForRegion()
1747
    {
1748
        $this->assertEquals(1, $this->phoneUtil->getCountryCodeForRegion(RegionCode::US));
1749
        $this->assertEquals(64, $this->phoneUtil->getCountryCodeForRegion(RegionCode::NZ));
1750
        $this->assertEquals(0, $this->phoneUtil->getCountryCodeForRegion(null));
1751
        $this->assertEquals(0, $this->phoneUtil->getCountryCodeForRegion(RegionCode::ZZ));
1752
        $this->assertEquals(0, $this->phoneUtil->getCountryCodeForRegion(RegionCode::UN001));
1753
        // CS is already deprecated so the library doesn't support it
1754
        $this->assertEquals(0, $this->phoneUtil->getCountryCodeForRegion(RegionCode::CS));
1755
    }
1756
1757
    public function testGetNationalDiallingPrefixForRegion()
1758
    {
1759
        $this->assertEquals("1", $this->phoneUtil->getNddPrefixForRegion(RegionCode::US, false));
1760
        // Test non-main country to see it gets the national dialling prefix for the main country with
1761
        // that country calling code.
1762
        $this->assertEquals("1", $this->phoneUtil->getNddPrefixForRegion(RegionCode::BS, false));
1763
        $this->assertEquals("0", $this->phoneUtil->getNddPrefixForRegion(RegionCode::NZ, false));
1764
        // Test case with non digit in the national prefix.
1765
        $this->assertEquals("0~0", $this->phoneUtil->getNddPrefixForRegion(RegionCode::AO, false));
1766
        $this->assertEquals("00", $this->phoneUtil->getNddPrefixForRegion(RegionCode::AO, true));
1767
        // Test cases with invalid regions.
1768
        $this->assertNull($this->phoneUtil->getNddPrefixForRegion(null, false));
1769
        $this->assertNull($this->phoneUtil->getNddPrefixForRegion(RegionCode::ZZ, false));
1770
        $this->assertNull($this->phoneUtil->getNddPrefixForRegion(RegionCode::UN001, false));
1771
        // CS is already deprecated so the library doesn't support it.
1772
        $this->assertNull($this->phoneUtil->getNddPrefixForRegion(RegionCode::CS, false));
1773
    }
1774
1775
    public function testIsNANPACountry()
1776
    {
1777
        $this->assertTrue($this->phoneUtil->isNANPACountry(RegionCode::US));
1778
        $this->assertTrue($this->phoneUtil->isNANPACountry(RegionCode::BS));
1779
        $this->assertFalse($this->phoneUtil->isNANPACountry(RegionCode::DE));
1780
        $this->assertFalse($this->phoneUtil->isNANPACountry(RegionCode::ZZ));
1781
        $this->assertFalse($this->phoneUtil->isNANPACountry(RegionCode::UN001));
1782
        $this->assertFalse($this->phoneUtil->isNANPACountry(null));
1783
    }
1784
1785
    public function testIsPossibleNumber()
1786
    {
1787
        $this->assertTrue($this->phoneUtil->isPossibleNumber(self::$usNumber));
1788
        $this->assertTrue($this->phoneUtil->isPossibleNumber(self::$usLocalNumber));
1789
        $this->assertTrue($this->phoneUtil->isPossibleNumber(self::$gbNumber));
1790
        $this->assertTrue($this->phoneUtil->isPossibleNumber(self::$internationalTollFree));
1791
1792
        $this->assertTrue($this->phoneUtil->isPossibleNumber("+1 650 253 0000", RegionCode::US));
1793
        $this->assertTrue($this->phoneUtil->isPossibleNumber("+1 650 GOO OGLE", RegionCode::US));
1794
        $this->assertTrue($this->phoneUtil->isPossibleNumber("(650) 253-0000", RegionCode::US));
1795
        $this->assertTrue($this->phoneUtil->isPossibleNumber("253-0000", RegionCode::US));
1796
        $this->assertTrue($this->phoneUtil->isPossibleNumber("+1 650 253 0000", RegionCode::GB));
1797
        $this->assertTrue($this->phoneUtil->isPossibleNumber("+44 20 7031 3000", RegionCode::GB));
1798
        $this->assertTrue($this->phoneUtil->isPossibleNumber("(020) 7031 300", RegionCode::GB));
1799
        $this->assertTrue($this->phoneUtil->isPossibleNumber("7031 3000", RegionCode::GB));
1800
        $this->assertTrue($this->phoneUtil->isPossibleNumber("3331 6005", RegionCode::NZ));
1801
        $this->assertTrue($this->phoneUtil->isPossibleNumber("+800 1234 5678", RegionCode::UN001));
1802
    }
1803
1804
    public function testIsPossibleNumberForType_DifferentTypeLengths()
1805
    {
1806
        // We use Argentinian numbers since they have different possible lengths for different types.
1807
        $number = new PhoneNumber();
1808
        $number->setCountryCode(54)->setNationalNumber(12345);
1809
1810
        // Too short for any Argentinian number, including fixed-line.
1811
        $this->assertFalse($this->phoneUtil->isPossibleNumberForType($number, PhoneNumberType::FIXED_LINE));
1812
        $this->assertFalse($this->phoneUtil->isPossibleNumberForType($number, PhoneNumberType::UNKNOWN));
1813
1814
        // 6-digit numbers are oaky for fixed-line.
1815
        $number->setNationalNumber(1234567);
1816
        $this->assertTrue($this->phoneUtil->isPossibleNumberForType($number, PhoneNumberType::UNKNOWN));
1817
        $this->assertTrue($this->phoneUtil->isPossibleNumberForType($number, PhoneNumberType::FIXED_LINE));
1818
        // But too short for mobile.
1819
        $this->assertFalse($this->phoneUtil->isPossibleNumberForType($number, PhoneNumberType::MOBILE));
1820
        // And too short for toll-free
1821
        $this->assertFalse($this->phoneUtil->isPossibleNumberForType($number, PhoneNumberType::TOLL_FREE));
1822
1823
        // The same applies for 9-digit numbers
1824
        $number->setNationalNumber(123456789);
1825
        $this->assertTrue($this->phoneUtil->isPossibleNumberForType($number, PhoneNumberType::UNKNOWN));
1826
        $this->assertTrue($this->phoneUtil->isPossibleNumberForType($number, PhoneNumberType::FIXED_LINE));
1827
        $this->assertFalse($this->phoneUtil->isPossibleNumberForType($number, PhoneNumberType::MOBILE));
1828
        $this->assertFalse($this->phoneUtil->isPossibleNumberForType($number, PhoneNumberType::TOLL_FREE));
1829
1830
        // 10-digit numbers are universally possible.
1831
        $number->setNationalNumber(1234567890);
1832
        $this->assertTrue($this->phoneUtil->isPossibleNumberForType($number, PhoneNumberType::UNKNOWN));
1833
        $this->assertTrue($this->phoneUtil->isPossibleNumberForType($number, PhoneNumberType::FIXED_LINE));
1834
        $this->assertTrue($this->phoneUtil->isPossibleNumberForType($number, PhoneNumberType::MOBILE));
1835
        $this->assertTrue($this->phoneUtil->isPossibleNumberForType($number, PhoneNumberType::TOLL_FREE));
1836
1837
        // 11-digit numbers are only possible for mobile numbers. Note we don't require the leading 9,
1838
        // which all mobile numbers start with, and would be required for a valid mobile number.
1839
        $number->setNationalNumber(12345678901);
1840
        $this->assertTrue($this->phoneUtil->isPossibleNumberForType($number, PhoneNumberType::UNKNOWN));
1841
        $this->assertFalse($this->phoneUtil->isPossibleNumberForType($number, PhoneNumberType::FIXED_LINE));
1842
        $this->assertTrue($this->phoneUtil->isPossibleNumberForType($number, PhoneNumberType::MOBILE));
1843
        $this->assertFalse($this->phoneUtil->isPossibleNumberForType($number, PhoneNumberType::TOLL_FREE));
1844
    }
1845
1846
    public function testIsPossibleNumberForType_LocalOnly()
1847
    {
1848
        $number = new PhoneNumber();
1849
        // Here we test a number length which matches a local-only length.
1850
        $number->setCountryCode(49)->setNationalNumber(12);
1851
        $this->assertTrue($this->phoneUtil->isPossibleNumberForType($number, PhoneNumberType::UNKNOWN));
1852
        $this->assertTrue($this->phoneUtil->isPossibleNumberForType($number, PhoneNumberType::FIXED_LINE));
1853
        // Mobile numbers must be 10 or 11 digits, and there are no local-only lengths.
1854
        $this->assertFalse($this->phoneUtil->isPossibleNumberForType($number, PhoneNumberType::MOBILE));
1855
    }
1856
1857
    public function testIsPossibleNumberForType_DataMissingForSizeReasons()
1858
    {
1859
        $number = new PhoneNumber();
1860
        // Here we test something where the possible lengths match the possible lengths of the country
1861
        // as a whole, and hence aren't present in the binary for size reasons - this should still work.
1862
        // Local-only number.
1863
        $number->setCountryCode(55)->setNationalNumber(12345678);
1864
        $this->assertTrue($this->phoneUtil->isPossibleNumberForType($number, PhoneNumberType::UNKNOWN));
1865
        $this->assertTrue($this->phoneUtil->isPossibleNumberForType($number, PhoneNumberType::FIXED_LINE));
1866
1867
        $number->setNationalNumber(1234567890);
1868
        $this->assertTrue($this->phoneUtil->isPossibleNumberForType($number, PhoneNumberType::UNKNOWN));
1869
        $this->assertTrue($this->phoneUtil->isPossibleNumberForType($number, PhoneNumberType::FIXED_LINE));
1870
    }
1871
1872
    public function testIsPossibleNumberForType_NumberTypeNotSupportedForRegion()
1873
    {
1874
        $number = new PhoneNumber();
1875
        // There are *no* mobile numbers for this region at all, so we return false.
1876
        $number->setCountryCode(55)->setNationalNumber(12345678);
1877
        $this->assertFalse($this->phoneUtil->isPossibleNumberForType($number, PhoneNumberType::MOBILE));
1878
        // This matches a fixed-line length though.
1879
        $this->assertTrue($this->phoneUtil->isPossibleNumberForType($number, PhoneNumberType::FIXED_LINE));
1880
        $this->assertTrue($this->phoneUtil->isPossibleNumberForType($number, PhoneNumberType::FIXED_LINE_OR_MOBILE));
1881
1882
        // There are *no* fixed-line OR mobile numbers for this country calling code at all, so we
1883
        // return false for these
0 ignored issues
show
Unused Code Comprehensibility introduced by
38% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
1884
        $number->setCountryCode(979)->setNationalNumber(123456789);
1885
        $this->assertFalse($this->phoneUtil->isPossibleNumberForType($number, PhoneNumberType::MOBILE));
1886
        $this->assertFalse($this->phoneUtil->isPossibleNumberForType($number, PhoneNumberType::FIXED_LINE));
1887
        $this->assertFalse($this->phoneUtil->isPossibleNumberForType($number, PhoneNumberType::FIXED_LINE_OR_MOBILE));
1888
        $this->assertTrue($this->phoneUtil->isPossibleNumberForType($number, PhoneNumberType::PREMIUM_RATE));
1889
    }
1890
1891
    public function testIsPossibleNumberWithReason()
1892
    {
1893
        // National numbers for country calling code +1 that are within 7 to 10 digits are possible.
1894
        $this->assertEquals(
1895
            ValidationResult::IS_POSSIBLE,
1896
            $this->phoneUtil->isPossibleNumberWithReason(self::$usNumber)
1897
        );
1898
1899
        $this->assertEquals(
1900
            ValidationResult::IS_POSSIBLE,
1901
            $this->phoneUtil->isPossibleNumberWithReason(self::$usLocalNumber)
1902
        );
1903
1904
        $this->assertEquals(
1905
            ValidationResult::TOO_LONG,
1906
            $this->phoneUtil->isPossibleNumberWithReason(self::$usLongNumber)
1907
        );
1908
1909
        $number = new PhoneNumber();
1910
        $number->setCountryCode(0)->setNationalNumber(2530000);
1911
        $this->assertEquals(
1912
            ValidationResult::INVALID_COUNTRY_CODE,
1913
            $this->phoneUtil->isPossibleNumberWithReason($number)
1914
        );
1915
1916
        $number->clear();
1917
        $number->setCountryCode(1)->setNationalNumber(253000);
1918
        $this->assertEquals(ValidationResult::TOO_SHORT, $this->phoneUtil->isPossibleNumberWithReason($number));
1919
1920
        $number->clear();
1921
        $number->setCountryCode(65)->setNationalNumber(1234567890);
1922
        $this->assertEquals(ValidationResult::IS_POSSIBLE, $this->phoneUtil->isPossibleNumberWithReason($number));
1923
1924
        $this->assertEquals(
1925
            ValidationResult::TOO_LONG,
1926
            $this->phoneUtil->isPossibleNumberWithReason(self::$internationalTollFreeTooLong)
1927
        );
1928
    }
1929
1930
    public function testIsPossibleNumberForTypeWithReason_DifferentTypeLengths()
1931
    {
1932
        // We use Argentinian numbers since they have different possible lengths for different types.
1933
        $number = new PhoneNumber();
1934
        $number->setCountryCode(54)->setNationalNumber(12345);
1935
        // Too short for any Argentinian number.
1936
        $this->assertEquals(ValidationResult::TOO_SHORT,
1937
            $this->phoneUtil->isPossibleNumberForTypeWithReason($number, PhoneNumberType::UNKNOWN));
1938
        $this->assertEquals(ValidationResult::TOO_SHORT,
1939
            $this->phoneUtil->isPossibleNumberForTypeWithReason($number, PhoneNumberType::FIXED_LINE));
1940
1941
        // 6-digit numbers are okay for fixed-line.
1942
        $number->setNationalNumber(123456);
1943
        $this->assertEquals(ValidationResult::IS_POSSIBLE,
1944
            $this->phoneUtil->isPossibleNumberForTypeWithReason($number, PhoneNumberType::UNKNOWN));
1945
        $this->assertEquals(ValidationResult::IS_POSSIBLE,
1946
            $this->phoneUtil->isPossibleNumberForTypeWithReason($number, PhoneNumberType::FIXED_LINE));
1947
        // But too short for mobile.
1948
        $this->assertEquals(ValidationResult::TOO_SHORT,
1949
            $this->phoneUtil->isPossibleNumberForTypeWithReason($number, PhoneNumberType::MOBILE));
1950
        // And too short for toll-free.
1951
        $this->assertEquals(ValidationResult::TOO_SHORT,
1952
            $this->phoneUtil->isPossibleNumberForTypeWithReason($number, PhoneNumberType::TOLL_FREE));
1953
1954
        // The same applies to 9-digit numbers.
1955
        $number->setNationalNumber(123456789);
1956
        $this->assertEquals(ValidationResult::IS_POSSIBLE,
1957
            $this->phoneUtil->isPossibleNumberForTypeWithReason($number, PhoneNumberType::UNKNOWN));
1958
        $this->assertEquals(ValidationResult::IS_POSSIBLE,
1959
            $this->phoneUtil->isPossibleNumberForTypeWithReason($number, PhoneNumberType::FIXED_LINE));
1960
        $this->assertEquals(ValidationResult::TOO_SHORT,
1961
            $this->phoneUtil->isPossibleNumberForTypeWithReason($number, PhoneNumberType::MOBILE));
1962
        $this->assertEquals(ValidationResult::TOO_SHORT,
1963
            $this->phoneUtil->isPossibleNumberForTypeWithReason($number, PhoneNumberType::TOLL_FREE));
1964
1965
        // 10-digit numbers are universally possible.
1966
        $number->setNationalNumber(1234567890);
1967
        $this->assertEquals(ValidationResult::IS_POSSIBLE,
1968
            $this->phoneUtil->isPossibleNumberForTypeWithReason($number, PhoneNumberType::UNKNOWN));
1969
        $this->assertEquals(ValidationResult::IS_POSSIBLE,
1970
            $this->phoneUtil->isPossibleNumberForTypeWithReason($number, PhoneNumberType::FIXED_LINE));
1971
        $this->assertEquals(ValidationResult::IS_POSSIBLE,
1972
            $this->phoneUtil->isPossibleNumberForTypeWithReason($number, PhoneNumberType::MOBILE));
1973
        $this->assertEquals(ValidationResult::IS_POSSIBLE,
1974
            $this->phoneUtil->isPossibleNumberForTypeWithReason($number, PhoneNumberType::TOLL_FREE));
1975
1976
        // 11-digit numbers are only possible for mobile numbers. Note we don't require the leading 9,
1977
        // which all mobile numbers start with, and would be required for a valid mobile number.
1978
        $number->setNationalNumber(12345678901);
1979
        $this->assertEquals(ValidationResult::IS_POSSIBLE,
1980
            $this->phoneUtil->isPossibleNumberForTypeWithReason($number, PhoneNumberType::UNKNOWN));
1981
        $this->assertEquals(ValidationResult::TOO_LONG,
1982
            $this->phoneUtil->isPossibleNumberForTypeWithReason($number, PhoneNumberType::FIXED_LINE));
1983
        $this->assertEquals(ValidationResult::IS_POSSIBLE,
1984
            $this->phoneUtil->isPossibleNumberForTypeWithReason($number, PhoneNumberType::MOBILE));
1985
        $this->assertEquals(ValidationResult::TOO_LONG,
1986
            $this->phoneUtil->isPossibleNumberForTypeWithReason($number, PhoneNumberType::TOLL_FREE));
1987
    }
1988
1989
    public function testIsPossibleNumberForTypeWithReason_LocalOnly()
1990
    {
1991
        $number = new PhoneNumber();
1992
        // Here we test a number length which matches a local-only length.
1993
        $number->setCountryCode(49)->setNationalNumber(12);
1994
        $this->assertEquals(ValidationResult::IS_POSSIBLE,
1995
            $this->phoneUtil->isPossibleNumberForTypeWithReason($number, PhoneNumberType::UNKNOWN));
1996
        $this->assertEquals(ValidationResult::IS_POSSIBLE,
1997
            $this->phoneUtil->isPossibleNumberForTypeWithReason($number, PhoneNumberType::FIXED_LINE));
1998
        // Mobile numbers must be 10 or 11 digits, and there are no local-only lengths.
1999
        $this->assertEquals(ValidationResult::TOO_SHORT,
2000
            $this->phoneUtil->isPossibleNumberForTypeWithReason($number, PhoneNumberType::MOBILE));
2001
    }
2002
2003
    public function testIsPossibleNumberForTypeWithReason_DataMissingForSizeReasons()
2004
    {
2005
        $number = new PhoneNumber();
2006
        // Here we test something where the possible lengths match the possible lengths of the country
2007
        // as a whole, and hence aren't present in the binary for size reasons - this should still work.
2008
        // Local-only number.
2009
        $number->setCountryCode(55)->setNationalNumber(12345678);
2010
        $this->assertEquals(ValidationResult::IS_POSSIBLE,
2011
            $this->phoneUtil->isPossibleNumberForTypeWithReason($number, PhoneNumberType::UNKNOWN));
2012
        $this->assertEquals(ValidationResult::IS_POSSIBLE,
2013
            $this->phoneUtil->isPossibleNumberForTypeWithReason($number, PhoneNumberType::FIXED_LINE));
2014
2015
        // Normal-length number.
2016
        $number->setNationalNumber(1234567890);
2017
        $this->assertEquals(ValidationResult::IS_POSSIBLE,
2018
            $this->phoneUtil->isPossibleNumberForTypeWithReason($number, PhoneNumberType::UNKNOWN));
2019
        $this->assertEquals(ValidationResult::IS_POSSIBLE,
2020
            $this->phoneUtil->isPossibleNumberForTypeWithReason($number, PhoneNumberType::FIXED_LINE));
2021
    }
2022
2023
    public function testIsPossibleNumberForTypeWithReason_NumberTypeNotSupportedForRegion()
2024
    {
2025
        $number = new PhoneNumber();
2026
        // There are *no* mobile numbers for this region at all, so we return INVALID_LENGTH.
2027
        $number->setCountryCode(55)->setNationalNumber(12345678);
2028
        $this->assertEquals(ValidationResult::INVALID_LENGTH,
2029
            $this->phoneUtil->isPossibleNumberForTypeWithReason($number, PhoneNumberType::MOBILE));
2030
        // This matches a fixed-line length though.
2031
        $this->assertEquals(ValidationResult::IS_POSSIBLE,
2032
            $this->phoneUtil->isPossibleNumberForTypeWithReason($number, PhoneNumberType::FIXED_LINE_OR_MOBILE));
2033
        // This is too short for fixed-line, and no mobile numbers exist.
2034
        $number->setCountryCode(55)->setNationalNumber(1234567);
2035
        $this->assertEquals(ValidationResult::INVALID_LENGTH,
2036
            $this->phoneUtil->isPossibleNumberForTypeWithReason($number, PhoneNumberType::MOBILE));
2037
        $this->assertEquals(ValidationResult::TOO_SHORT,
2038
            $this->phoneUtil->isPossibleNumberForTypeWithReason($number, PhoneNumberType::FIXED_LINE_OR_MOBILE));
2039
        $this->assertEquals(ValidationResult::TOO_SHORT,
2040
            $this->phoneUtil->isPossibleNumberForTypeWithReason($number, PhoneNumberType::FIXED_LINE));
2041
2042
        // This is too short for mobile, and no fixed-line numbers exist.
2043
        $number->setCountryCode(882)->setNationalNumber(1234567);
2044
        $this->assertEquals(ValidationResult::TOO_SHORT,
2045
            $this->phoneUtil->isPossibleNumberForTypeWithReason($number, PhoneNumberType::MOBILE));
2046
        $this->assertEquals(ValidationResult::TOO_SHORT,
2047
            $this->phoneUtil->isPossibleNumberForTypeWithReason($number, PhoneNumberType::FIXED_LINE_OR_MOBILE));
2048
        $this->assertEquals(ValidationResult::INVALID_LENGTH,
2049
            $this->phoneUtil->isPossibleNumberForTypeWithReason($number, PhoneNumberType::FIXED_LINE));
2050
2051
        // There are *no* fixed-line OR mobile numbers for this country calling code at all, so we
2052
        // return INVALID_LENGTH.
2053
        $number->setCountryCode(979)->setNationalNumber(123456789);
2054
        $this->assertEquals(ValidationResult::INVALID_LENGTH,
2055
            $this->phoneUtil->isPossibleNumberForTypeWithReason($number, PhoneNumberType::MOBILE));
2056
        $this->assertEquals(ValidationResult::INVALID_LENGTH,
2057
            $this->phoneUtil->isPossibleNumberForTypeWithReason($number, PhoneNumberType::FIXED_LINE));
2058
        $this->assertEquals(ValidationResult::INVALID_LENGTH,
2059
            $this->phoneUtil->isPossibleNumberForTypeWithReason($number, PhoneNumberType::FIXED_LINE_OR_MOBILE));
2060
        $this->assertEquals(ValidationResult::IS_POSSIBLE,
2061
            $this->phoneUtil->isPossibleNumberForTypeWithReason($number, PhoneNumberType::PREMIUM_RATE));
2062
    }
2063
2064
    public function testIsPossibleNumberForTypeWithReason_FixedLineOrMobile()
2065
    {
2066
        $number = new PhoneNumber();
2067
        // For FIXED_LINE_OR_MOBILE, a number should be considered valid if it matches the possible
2068
        // lengths for mobile *or* fixed-line numbers.
2069
        $number->setCountryCode(290)->setNationalNumber(1234);
2070
        $this->assertEquals(ValidationResult::TOO_SHORT,
2071
            $this->phoneUtil->isPossibleNumberForTypeWithReason($number, PhoneNumberType::FIXED_LINE));
2072
        $this->assertEquals(ValidationResult::IS_POSSIBLE,
2073
            $this->phoneUtil->isPossibleNumberForTypeWithReason($number, PhoneNumberType::MOBILE));
2074
        $this->assertEquals(ValidationResult::IS_POSSIBLE,
2075
            $this->phoneUtil->isPossibleNumberForTypeWithReason($number, PhoneNumberType::FIXED_LINE_OR_MOBILE));
2076
2077
        $number->setNationalNumber(12345);
2078
        $this->assertEquals(ValidationResult::TOO_SHORT,
2079
            $this->phoneUtil->isPossibleNumberForTypeWithReason($number, PhoneNumberType::FIXED_LINE));
2080
        $this->assertEquals(ValidationResult::TOO_LONG,
2081
            $this->phoneUtil->isPossibleNumberForTypeWithReason($number, PhoneNumberType::MOBILE));
2082
        // This will change to INVALID_LENGTH once we start returning this type in the main
2083
        // isPossibleNumberWithReason API.
2084
        $this->assertEquals(ValidationResult::TOO_LONG,
2085
            $this->phoneUtil->isPossibleNumberForTypeWithReason($number, PhoneNumberType::FIXED_LINE_OR_MOBILE));
2086
2087
        $number->setNationalNumber(123456);
2088
        $this->assertEquals(ValidationResult::IS_POSSIBLE,
2089
            $this->phoneUtil->isPossibleNumberForTypeWithReason($number, PhoneNumberType::FIXED_LINE));
2090
        $this->assertEquals(ValidationResult::TOO_LONG,
2091
            $this->phoneUtil->isPossibleNumberForTypeWithReason($number, PhoneNumberType::MOBILE));
2092
        $this->assertEquals(ValidationResult::IS_POSSIBLE,
2093
            $this->phoneUtil->isPossibleNumberForTypeWithReason($number, PhoneNumberType::FIXED_LINE_OR_MOBILE));
2094
2095
        $number->setNationalNumber(1234567);
2096
        $this->assertEquals(ValidationResult::TOO_LONG,
2097
            $this->phoneUtil->isPossibleNumberForTypeWithReason($number, PhoneNumberType::FIXED_LINE));
2098
        $this->assertEquals(ValidationResult::TOO_LONG,
2099
            $this->phoneUtil->isPossibleNumberForTypeWithReason($number, PhoneNumberType::MOBILE));
2100
        $this->assertEquals(ValidationResult::TOO_LONG,
2101
            $this->phoneUtil->isPossibleNumberForTypeWithReason($number, PhoneNumberType::FIXED_LINE_OR_MOBILE));
2102
2103
        // 8-digit numbers are possible for toll-free and premium-rate numbers only.
2104
        $number->setNationalNumber(12345678);
2105
        $this->assertEquals(ValidationResult::IS_POSSIBLE,
2106
            $this->phoneUtil->isPossibleNumberForTypeWithReason($number, PhoneNumberType::TOLL_FREE));
2107
        $this->assertEquals(ValidationResult::TOO_LONG,
2108
            $this->phoneUtil->isPossibleNumberForTypeWithReason($number, PhoneNumberType::FIXED_LINE_OR_MOBILE));
2109
    }
2110
2111
    public function testIsNotPossibleNumber()
2112
    {
2113
        $this->assertFalse($this->phoneUtil->isPossibleNumber(self::$usLongNumber));
2114
        $this->assertFalse($this->phoneUtil->isPossibleNumber(self::$internationalTollFreeTooLong));
2115
2116
        $number = new PhoneNumber();
2117
        $number->setCountryCode(1)->setNationalNumber(253000);
2118
        $this->assertFalse($this->phoneUtil->isPossibleNumber($number));
2119
2120
        $number->clear();
2121
        $number->setCountryCode(44)->setNationalNumber(300);
2122
        $this->assertFalse($this->phoneUtil->isPossibleNumber($number));
2123
        $this->assertFalse($this->phoneUtil->isPossibleNumber("+1 650 253 00000", RegionCode::US));
2124
        $this->assertFalse($this->phoneUtil->isPossibleNumber("(650) 253-00000", RegionCode::US));
2125
        $this->assertFalse($this->phoneUtil->isPossibleNumber("I want a Pizza", RegionCode::US));
2126
        $this->assertFalse($this->phoneUtil->isPossibleNumber("253-000", RegionCode::US));
2127
        $this->assertFalse($this->phoneUtil->isPossibleNumber("1 3000", RegionCode::GB));
2128
        $this->assertFalse($this->phoneUtil->isPossibleNumber("+44 300", RegionCode::GB));
2129
        $this->assertFalse($this->phoneUtil->isPossibleNumber("+800 1234 5678 9", RegionCode::UN001));
2130
    }
2131
2132
    public function testTruncateTooLongNumber()
2133
    {
2134
        // GB number 080 1234 5678, but entered with 4 extra digits at the end.
2135
        $tooLongNumber = new PhoneNumber();
2136
        $tooLongNumber->setCountryCode(44)->setNationalNumber(80123456780123);
2137
        $validNumber = new PhoneNumber();
2138
        $validNumber->setCountryCode(44)->setNationalNumber(8012345678);
2139
        $this->assertTrue($this->phoneUtil->truncateTooLongNumber($tooLongNumber));
2140
        $this->assertEquals($validNumber, $tooLongNumber);
2141
2142
        // IT number 022 3456 7890, but entered with 3 extra digits at the end.
2143
        $tooLongNumber->clear();
2144
        $tooLongNumber->setCountryCode(39)->setNationalNumber(2234567890123)->setItalianLeadingZero(true);
2145
        $validNumber->clear();
2146
        $validNumber->setCountryCode(39)->setNationalNumber(2234567890)->setItalianLeadingZero(true);
2147
        $this->assertTrue($this->phoneUtil->truncateTooLongNumber($tooLongNumber));
2148
        $this->assertEquals($validNumber, $tooLongNumber);
2149
2150
        // US number 650-253-0000, but entered with one additional digit at the end.
2151
        $tooLongNumber->clear();
2152
        $tooLongNumber->mergeFrom(self::$usLongNumber);
2153
        $this->assertTrue($this->phoneUtil->truncateTooLongNumber($tooLongNumber));
2154
        $this->assertEquals(self::$usNumber, $tooLongNumber);
2155
2156
        $tooLongNumber->clear();
2157
        $tooLongNumber->mergeFrom(self::$internationalTollFreeTooLong);
2158
        $this->assertTrue($this->phoneUtil->truncateTooLongNumber($tooLongNumber));
2159
        $this->assertEquals(self::$internationalTollFree, $tooLongNumber);
2160
2161
        // Tests what happens when a valid number is passed in.
2162
        $validNumberCopy = new PhoneNumber();
2163
        $validNumberCopy->mergeFrom($validNumber);
2164
        $this->assertTrue($this->phoneUtil->truncateTooLongNumber($validNumber));
2165
2166
        // Tests the number is not modified.
2167
        $this->assertEquals($validNumberCopy, $validNumber);
2168
2169
        // Tests what happens when a number with invalid prefix is passed in.
2170
        $numberWithInvalidPrefix = new PhoneNumber();
2171
        // The test metadata says US numbers cannot have prefix 240.
2172
        $numberWithInvalidPrefix->setCountryCode(1)->setNationalNumber(2401234567);
2173
        $invalidNumberCopy = new PhoneNumber();
2174
        $invalidNumberCopy->mergeFrom($numberWithInvalidPrefix);
2175
        $this->assertFalse($this->phoneUtil->truncateTooLongNumber($numberWithInvalidPrefix));
2176
        // Tests the number is not modified.
2177
        $this->assertEquals($invalidNumberCopy, $numberWithInvalidPrefix);
2178
2179
        // Tests what happens when a too short number is passed in.
2180
        $tooShortNumber = new PhoneNumber();
2181
        $tooShortNumber->setCountryCode(1)->setNationalNumber(1234);
2182
        $tooShortNumberCopy = new PhoneNumber();
2183
        $tooShortNumberCopy->mergeFrom($tooShortNumber);
2184
        $this->assertFalse($this->phoneUtil->truncateTooLongNumber($tooShortNumber));
2185
        // Tests the number is not modified.
2186
        $this->assertEquals($tooShortNumberCopy, $tooShortNumber);
2187
    }
2188
2189
    public function testIsViablePhoneNumber()
2190
    {
2191
        $this->assertFalse(PhoneNumberUtil::isViablePhoneNumber("1"));
2192
        // Only one or two digits before strange non-possible punctuation.
2193
        $this->assertFalse(PhoneNumberUtil::isViablePhoneNumber("1+1+1"));
2194
        $this->assertFalse(PhoneNumberUtil::isViablePhoneNumber("80+0"));
2195
        // Two digits is viable.
2196
        $this->assertTrue(PhoneNumberUtil::isViablePhoneNumber("00"));
2197
        $this->assertTrue(PhoneNumberUtil::isViablePhoneNumber("111"));
2198
        // Alpha numbers.
2199
        $this->assertTrue(PhoneNumberUtil::isViablePhoneNumber("0800-4-pizza"));
2200
        $this->assertTrue(PhoneNumberUtil::isViablePhoneNumber("0800-4-PIZZA"));
2201
2202
        // We need at least three digits before any alpha characters.
2203
        $this->assertFalse(PhoneNumberUtil::isViablePhoneNumber("08-PIZZA"));
2204
        $this->assertFalse(PhoneNumberUtil::isViablePhoneNumber("8-PIZZA"));
2205
        $this->assertFalse(PhoneNumberUtil::isViablePhoneNumber("12. March"));
2206
    }
2207
2208
    public function testIsViablePhoneNumberNonAscii()
2209
    {
2210
        // Only one or two digits before possible punctuation followed by more digits.
2211
        $this->assertTrue(PhoneNumberUtil::isViablePhoneNumber("1" . pack('H*', 'e38080') . "34"));
2212
        $this->assertFalse(PhoneNumberUtil::isViablePhoneNumber("1" . pack('H*', 'e38080') . "3+4"));
2213
        // Unicode variants of possible starting character and other allowed punctuation/digits.
2214
        $this->assertTrue(
2215
            PhoneNumberUtil::isViablePhoneNumber(
2216
                pack('H*', 'efbc88') . "1" . pack("H*", 'efbc89') . pack('H*', 'e38080') . "3456789"
2217
            )
2218
        );
2219
        // Testing a leading + is okay.
2220
        $this->assertTrue(
2221
            PhoneNumberUtil::isViablePhoneNumber("+1" . pack("H*", 'efbc89') . pack('H*', 'e38080') . "3456789")
2222
        );
2223
    }
2224
2225
    public function testExtractPossibleNumber()
2226
    {
2227
        // Removes preceding funky punctuation and letters but leaves the rest untouched.
2228
        $this->assertEquals("0800-345-600", PhoneNumberUtil::extractPossibleNumber("Tel:0800-345-600"));
2229
        $this->assertEquals("0800 FOR PIZZA", PhoneNumberUtil::extractPossibleNumber("Tel:0800 FOR PIZZA"));
2230
        // Should not remove plus sign
2231
        $this->assertEquals("+800-345-600", PhoneNumberUtil::extractPossibleNumber("Tel:+800-345-600"));
2232
        // Should recognise wide digits as possible start values.
2233
        $this->assertEquals(
2234
            pack("H*", 'efbc90') . pack("H*", 'efbc92') . pack("H*", 'efbc93'),
2235
            PhoneNumberUtil::extractPossibleNumber(pack("H*", 'efbc90') . pack("H*", 'efbc92') . pack("H*", 'efbc93'))
2236
        );
2237
        // Dashes are not possible start values and should be removed.
2238
        $this->assertEquals(
2239
            pack("H*", 'efbc91') . pack("H*", 'efbc92') . pack("H*", 'efbc93'),
2240
            PhoneNumberUtil::extractPossibleNumber(
2241
                "Num-" . pack("H*", 'efbc91') . pack("H*", 'efbc92') . pack("H*", 'efbc93')
2242
            )
2243
        );
2244
        // If not possible number present, return empty string.
2245
        $this->assertEquals("", PhoneNumberUtil::extractPossibleNumber("Num-...."));
2246
        // Leading brackets are stripped - these are not used when parsing.
2247
        $this->assertEquals("650) 253-0000", PhoneNumberUtil::extractPossibleNumber("(650) 253-0000"));
2248
2249
        // Trailing non-alpha-numeric characters should be removed.
2250
        $this->assertEquals("650) 253-0000", PhoneNumberUtil::extractPossibleNumber("(650) 253-0000..- .."));
2251
        $this->assertEquals("650) 253-0000", PhoneNumberUtil::extractPossibleNumber("(650) 253-0000."));
2252
        // This case has a trailing RTL char.
2253
        $this->assertEquals(
2254
            "650) 253-0000",
2255
            PhoneNumberUtil::extractPossibleNumber("(650) 253-0000" . pack("H*", 'e2808f'))
2256
        );
2257
    }
2258
2259
    public function testMaybeStripNationalPrefix()
2260
    {
2261
        $metadata = new PhoneMetadata();
2262
        $metadata->setNationalPrefixForParsing("34");
2263
        $phoneNumberDesc = new PhoneNumberDesc();
2264
        $phoneNumberDesc->setNationalNumberPattern("\\d{4,8}");
2265
        $metadata->setGeneralDesc($phoneNumberDesc);
2266
2267
        $numberToStrip = "34356778";
2268
        $strippedNumber = "356778";
2269
2270
        $carrierCode = null;
2271
2272
        $this->assertTrue(
2273
            $this->phoneUtil->maybeStripNationalPrefixAndCarrierCode($numberToStrip, $metadata, $carrierCode)
2274
        );
2275
        $this->assertEquals($strippedNumber, $numberToStrip, "Should have had national prefix stripped.");
2276
        // Retry stripping - now the number should not start with the national prefix, so no more
2277
        // stripping should occur.
2278
        $carrierCode = null;
2279
        $this->assertFalse(
2280
            $this->phoneUtil->maybeStripNationalPrefixAndCarrierCode($numberToStrip, $metadata, $carrierCode)
2281
        );
2282
        $this->assertEquals($strippedNumber, $numberToStrip, "Should have had no change - no national prefix present.");
2283
2284
        // Some countries have no national prefix. Repeat test with none specified.
2285
        $metadata->setNationalPrefixForParsing("");
2286
        $carrierCode = null;
2287
        $this->assertFalse(
2288
            $this->phoneUtil->maybeStripNationalPrefixAndCarrierCode($numberToStrip, $metadata, $carrierCode)
2289
        );
2290
        $this->assertEquals($strippedNumber, $numberToStrip, "Should not strip anything with empty national prefix.");
2291
2292
        // If the resultant number doesn't match the national rule, it shouldn't be stripped.
2293
        $metadata->setNationalPrefixForParsing("3");
2294
        $numberToStrip = "3123";
2295
        $strippedNumber = "3123";
2296
        $carrierCode = null;
2297
        $this->assertFalse(
2298
            $this->phoneUtil->maybeStripNationalPrefixAndCarrierCode($numberToStrip, $metadata, $carrierCode)
2299
        );
2300
        $this->assertEquals(
2301
            $strippedNumber,
2302
            $numberToStrip,
2303
            "Should have had no change - after stripping, it wouldn't have matched the national rule."
2304
        );
2305
2306
        // Test extracting carrier selection code.
2307
        $metadata->setNationalPrefixForParsing("0(81)?");
2308
        $numberToStrip = "08122123456";
2309
        $strippedNumber = "22123456";
2310
        $carrierCode = "";
2311
        $this->assertTrue(
2312
            $this->phoneUtil->maybeStripNationalPrefixAndCarrierCode($numberToStrip, $metadata, $carrierCode)
2313
        );
2314
        $this->assertEquals("81", $carrierCode);
2315
        $this->assertEquals(
2316
            $strippedNumber,
2317
            $numberToStrip,
2318
            "Should have had national prefix and carrier code stripped."
2319
        );
2320
2321
        // If there was a transform rule, check it was applied.
2322
        $metadata->setNationalPrefixTransformRule("5\${1}5");
2323
        // Note that a capturing group is present here.
2324
        $metadata->setNationalPrefixForParsing("0(\\d{2})");
2325
        $numberToStrip = "031123";
2326
        $transformedNumber = "5315123";
2327
        $carrierCode = null;
2328
        $this->assertTrue(
2329
            $this->phoneUtil->maybeStripNationalPrefixAndCarrierCode($numberToStrip, $metadata, $carrierCode)
2330
        );
2331
        $this->assertEquals($transformedNumber, $numberToStrip, "Should transform the 031 to a 5315.");
2332
    }
2333
2334
    public function testMaybeStripInternationalPrefix()
2335
    {
2336
        $internationalPrefix = "00[39]";
2337
        $numberToStrip = "0034567700-3898003";
2338
        // Note the dash is removed as part of the normalization.
2339
        $strippedNumber = "45677003898003";
2340
        $this->assertEquals(
2341
            CountryCodeSource::FROM_NUMBER_WITH_IDD,
2342
            $this->phoneUtil->maybeStripInternationalPrefixAndNormalize($numberToStrip, $internationalPrefix)
2343
        );
2344
        $this->assertEquals(
2345
            $strippedNumber,
2346
            $numberToStrip,
2347
            "The number supplied was not stripped of its international prefix."
2348
        );
2349
2350
        // Now the number no longer starts with an IDD prefix, so it should now report
2351
        // FROM_DEFAULT_COUNTRY.
2352
        $this->assertEquals(
2353
            CountryCodeSource::FROM_DEFAULT_COUNTRY,
2354
            $this->phoneUtil->maybeStripInternationalPrefixAndNormalize($numberToStrip, $internationalPrefix)
2355
        );
2356
2357
        $numberToStrip = "00945677003898003";
2358
        $this->assertEquals(
2359
            CountryCodeSource::FROM_NUMBER_WITH_IDD,
2360
            $this->phoneUtil->maybeStripInternationalPrefixAndNormalize($numberToStrip, $internationalPrefix)
2361
        );
2362
        $this->assertEquals(
2363
            $strippedNumber,
2364
            $numberToStrip,
2365
            "The number supplied was not stripped of its international prefix."
2366
        );
2367
2368
        // Test it works when the international prefix is broken up by spaces.
2369
        $numberToStrip = "00 9 45677003898003";
2370
        $this->assertEquals(
2371
            CountryCodeSource::FROM_NUMBER_WITH_IDD,
2372
            $this->phoneUtil->maybeStripInternationalPrefixAndNormalize($numberToStrip, $internationalPrefix)
2373
        );
2374
        $this->assertEquals(
2375
            $strippedNumber,
2376
            $numberToStrip,
2377
            "The number supplied was not stripped of its international prefix."
2378
        );
2379
2380
        // Now the number no longer starts with an IDD prefix, so it should now report
2381
        // FROM_DEFAULT_COUNTRY.
2382
        $this->assertEquals(
2383
            CountryCodeSource::FROM_DEFAULT_COUNTRY,
2384
            $this->phoneUtil->maybeStripInternationalPrefixAndNormalize($numberToStrip, $internationalPrefix)
2385
        );
2386
2387
        // Test the + symbol is also recognised and stripped.
2388
        $numberToStrip = "+45677003898003";
2389
        $strippedNumber = "45677003898003";
2390
        $this->assertEquals(
2391
            CountryCodeSource::FROM_NUMBER_WITH_PLUS_SIGN,
2392
            $this->phoneUtil->maybeStripInternationalPrefixAndNormalize($numberToStrip, $internationalPrefix)
2393
        );
2394
        $this->assertEquals(
2395
            $strippedNumber,
2396
            $numberToStrip,
2397
            "The number supplied was not stripped of the plus symbol."
2398
        );
2399
2400
        // If the number afterwards is a zero, we should not strip this - no country calling code begins
2401
        // with 0.
2402
        $numberToStrip = "0090112-3123";
2403
        $strippedNumber = "00901123123";
2404
        $this->assertEquals(
2405
            CountryCodeSource::FROM_DEFAULT_COUNTRY,
2406
            $this->phoneUtil->maybeStripInternationalPrefixAndNormalize($numberToStrip, $internationalPrefix)
2407
        );
2408
        $this->assertEquals(
2409
            $strippedNumber,
2410
            $numberToStrip,
2411
            "The number supplied had a 0 after the match so shouldn't be stripped."
2412
        );
2413
2414
        // Here the 0 is separated by a space from the IDD.
2415
        $numberToStrip = "009 0-112-3123";
2416
        $this->assertEquals(
2417
            CountryCodeSource::FROM_DEFAULT_COUNTRY,
2418
            $this->phoneUtil->maybeStripInternationalPrefixAndNormalize($numberToStrip, $internationalPrefix)
2419
        );
2420
    }
2421
2422
    public function testMaybeExtractCountryCode()
2423
    {
2424
        $number = new PhoneNumber();
2425
        $metadata = $this->phoneUtil->getMetadataForRegion(RegionCode::US);
2426
        // Note that for the US, the IDD is 011.
2427
        try {
2428
            $phoneNumber = "011112-3456789";
2429
            $strippedNumber = "123456789";
2430
            $countryCallingCode = 1;
2431
            $numberToFill = "";
2432
            $this->assertEquals(
2433
                $countryCallingCode,
2434
                $this->phoneUtil->maybeExtractCountryCode($phoneNumber, $metadata, $numberToFill, true, $number),
2435
                "Did not extract country calling code " . $countryCallingCode . " correctly."
2436
            );
2437
            $this->assertEquals(
2438
                CountryCodeSource::FROM_NUMBER_WITH_IDD,
2439
                $number->getCountryCodeSource(),
2440
                "Did not figure out CountryCodeSource correctly"
2441
            );
2442
            // Should strip and normalize national significant number.
2443
            $this->assertEquals(
2444
                $strippedNumber,
2445
                $numberToFill,
2446
                "Did not strip off the country calling code correctly."
2447
            );
2448
        } catch (NumberParseException $e) {
2449
            $this->fail("Should not have thrown an exception: " . $e->getMessage());
2450
        }
2451
        $number->clear();
2452
        try {
2453
            $phoneNumber = "+6423456789";
2454
            $countryCallingCode = 64;
2455
            $numberToFill = "";
2456
            $this->assertEquals(
2457
                $countryCallingCode,
2458
                $this->phoneUtil->maybeExtractCountryCode($phoneNumber, $metadata, $numberToFill, true, $number),
2459
                "Did not extract country calling code " . $countryCallingCode . " correctly."
2460
            );
2461
            $this->assertEquals(
2462
                CountryCodeSource::FROM_NUMBER_WITH_PLUS_SIGN,
2463
                $number->getCountryCodeSource(),
2464
                "Did not figure out CountryCodeSource correctly"
2465
            );
2466
        } catch (NumberParseException $e) {
2467
            $this->fail("Should not have thrown an exception: " . $e->getMessage());
2468
        }
2469
        $number->clear();
2470
        try {
2471
            $phoneNumber = "+80012345678";
2472
            $countryCallingCode = 800;
2473
            $numberToFill = "";
2474
            $this->assertEquals(
2475
                $countryCallingCode,
2476
                $this->phoneUtil->maybeExtractCountryCode($phoneNumber, $metadata, $numberToFill, true, $number),
2477
                "Did not extract country calling code " . $countryCallingCode . " correctly."
2478
            );
2479
            $this->assertEquals(
2480
                CountryCodeSource::FROM_NUMBER_WITH_PLUS_SIGN,
2481
                $number->getCountryCodeSource(),
2482
                "Did not figure out CountryCodeSource correctly"
2483
            );
2484
        } catch (NumberParseException $e) {
2485
            $this->fail("Should not have thrown an exception: " . $e->getMessage());
2486
        }
2487
        $number->clear();
2488
        try {
2489
            $phoneNumber = "2345-6789";
2490
            $numberToFill = "";
2491
            $this->assertEquals(
2492
                0,
2493
                $this->phoneUtil->maybeExtractCountryCode($phoneNumber, $metadata, $numberToFill, true, $number),
2494
                "Should not have extracted a country calling code - no international prefix present."
2495
            );
2496
            $this->assertEquals(
2497
                CountryCodeSource::FROM_DEFAULT_COUNTRY,
2498
                $number->getCountryCodeSource(),
2499
                "Did not figure out CountryCodeSource correctly"
2500
            );
2501
        } catch (NumberParseException $e) {
2502
            $this->fail("Should not have thrown an exception: " . $e->getMessage());
2503
        }
2504
        $number->clear();
2505
        try {
2506
            $phoneNumber = "0119991123456789";
2507
            $numberToFill = "";
2508
            $this->phoneUtil->maybeExtractCountryCode($phoneNumber, $metadata, $numberToFill, true, $number);
2509
            $this->fail("Should have thrown an exception, no valid country calling code present.");
2510
        } catch (NumberParseException $e) {
2511
            // Expected.
2512
            $this->assertEquals(
2513
                NumberParseException::INVALID_COUNTRY_CODE,
2514
                $e->getErrorType(),
2515
                "Wrong error type stored in exception."
2516
            );
2517
        }
2518
        $number->clear();
2519
        try {
2520
            $phoneNumber = "(1 610) 619 4466";
2521
            $countryCallingCode = 1;
2522
            $numberToFill = "";
2523
            $this->assertEquals(
2524
                $countryCallingCode,
2525
                $this->phoneUtil->maybeExtractCountryCode($phoneNumber, $metadata, $numberToFill, true, $number),
2526
                "Should have extracted the country calling code of the region passed in"
2527
            );
2528
            $this->assertEquals(
2529
                CountryCodeSource::FROM_NUMBER_WITHOUT_PLUS_SIGN,
2530
                $number->getCountryCodeSource(),
2531
                "Did not figure out CountryCodeSource correctly"
2532
            );
2533
        } catch (NumberParseException $e) {
2534
            $this->fail("Should not have thrown an exception: " . $e->getMessage());
2535
        }
2536
        $number->clear();
2537
        try {
2538
            $phoneNumber = "(1 610) 619 4466";
2539
            $countryCallingCode = 1;
2540
            $numberToFill = "";
2541
            $this->assertEquals(
2542
                $countryCallingCode,
2543
                $this->phoneUtil->maybeExtractCountryCode($phoneNumber, $metadata, $numberToFill, false, $number),
2544
                "Should have extracted the country calling code of the region passed in"
2545
            );
2546
            $this->assertFalse($number->hasCountryCodeSource(), "Should not contain CountryCodeSource");
2547
        } catch (NumberParseException $e) {
2548
            $this->fail("Should not have thrown an exception: " . $e->getMessage());
2549
        }
2550
        $number->clear();
2551
        try {
2552
            $phoneNumber = "(1 610) 619 446";
2553
            $numberToFill = "";
2554
            $this->assertEquals(
2555
                0,
2556
                $this->phoneUtil->maybeExtractCountryCode($phoneNumber, $metadata, $numberToFill, false, $number),
2557
                "Should not have extracted a country calling code - invalid number after extraction of uncertain country calling code."
2558
            );
2559
            $this->assertFalse($number->hasCountryCodeSource(), "Should not contain CountryCodeSource");
2560
        } catch (NumberParseException $e) {
2561
            $this->fail("Should not have thrown an exception: " . $e->getMessage());
2562
        }
2563
        $number->clear();
2564
        try {
2565
            $phoneNumber = "(1 610) 619";
2566
            $numberToFill = "";
2567
            $this->assertEquals(
2568
                0,
2569
                $this->phoneUtil->maybeExtractCountryCode($phoneNumber, $metadata, $numberToFill, true, $number),
2570
                "Should not have extracted a country calling code - too short number both before and after extraction of uncertain country calling code."
2571
            );
2572
            $this->assertEquals(
2573
                CountryCodeSource::FROM_DEFAULT_COUNTRY,
2574
                $number->getCountryCodeSource(),
2575
                "Did not figure out CountryCodeSource correctly"
2576
            );
2577
        } catch (NumberParseException $e) {
2578
            $this->fail("Should not have thrown an exception: " . $e->getMessage());
2579
        }
2580
    }
2581
2582
    public function testParseNationalNumber()
2583
    {
2584
        // National prefix attached.
2585
        $this->assertEquals(self::$nzNumber, $this->phoneUtil->parse("033316005", RegionCode::NZ));
2586
        $this->assertEquals(self::$nzNumber, $this->phoneUtil->parse("33316005", RegionCode::NZ));
2587
        // National prefix attached and some formatting present.
2588
        $this->assertEquals(self::$nzNumber, $this->phoneUtil->parse("03-331 6005", RegionCode::NZ));
2589
        $this->assertEquals(self::$nzNumber, $this->phoneUtil->parse("03 331 6005", RegionCode::NZ));
2590
2591
        // Test parsing RFC3966 format with a phone context.
2592
        $this->assertEquals(
2593
            self::$nzNumber,
2594
            $this->phoneUtil->parse("tel:03-331-6005;phone-context=+64", RegionCode::NZ)
2595
        );
2596
        $this->assertEquals(
2597
            self::$nzNumber,
2598
            $this->phoneUtil->parse("tel:331-6005;phone-context=+64-3", RegionCode::NZ)
2599
        );
2600
        $this->assertEquals(
2601
            self::$nzNumber,
2602
            $this->phoneUtil->parse("tel:331-6005;phone-context=+64-3", RegionCode::US)
2603
        );
2604
        $this->assertEquals(
2605
            self::$nzNumber,
2606
            $this->phoneUtil->parse("My number is tel:03-331-6005;phone-context=+64", RegionCode::NZ)
2607
        );
2608
        // Test parsing RFC3966 format with optional user-defined parameters. The parameters will appear
2609
        // after the context if present.
2610
        $this->assertEquals(
2611
            self::$nzNumber,
2612
            $this->phoneUtil->parse("tel:03-331-6005;phone-context=+64;a=%A1", RegionCode::NZ)
2613
        );
2614
        // Test parsing RFC3966 with an ISDN subaddress.
2615
        $this->assertEquals(
2616
            self::$nzNumber,
2617
            $this->phoneUtil->parse("tel:03-331-6005;isub=12345;phone-context=+64", RegionCode::NZ)
2618
        );
2619
        $this->assertEquals(self::$nzNumber, $this->phoneUtil->parse("tel:+64-3-331-6005;isub=12345", RegionCode::NZ));
2620
2621
        // Test parsing RFC3966 with "tel:" missing
2622
        $this->assertEquals(self::$nzNumber, $this->phoneUtil->parse("03-331-6005;phone-context=+64", RegionCode::NZ));
2623
2624
        // Testing international prefixes.
2625
        // Should strip country calling code.
2626
        $this->assertEquals(self::$nzNumber, $this->phoneUtil->parse("0064 3 331 6005", RegionCode::NZ));
2627
        // Try again, but this time we have an international number with Region Code US. It should
2628
        // recognise the country calling code and parse accordingly.
2629
        $this->assertEquals(self::$nzNumber, $this->phoneUtil->parse("01164 3 331 6005", RegionCode::US));
2630
        $this->assertEquals(self::$nzNumber, $this->phoneUtil->parse("+64 3 331 6005", RegionCode::US));
2631
        // We should ignore the leading plus here, since it is not followed by a valid country code but
2632
        // instead is followed by the IDD for the US.
2633
        $this->assertEquals(self::$nzNumber, $this->phoneUtil->parse("+01164 3 331 6005", RegionCode::US));
2634
        $this->assertEquals(self::$nzNumber, $this->phoneUtil->parse("+0064 3 331 6005", RegionCode::NZ));
2635
        $this->assertEquals(self::$nzNumber, $this->phoneUtil->parse("+ 00 64 3 331 6005", RegionCode::NZ));
2636
2637
        $this->assertEquals(
2638
            self::$usLocalNumber,
2639
            $this->phoneUtil->parse("tel:253-0000;phone-context=www.google.com", RegionCode::US)
2640
        );
2641
        $this->assertEquals(
2642
            self::$usLocalNumber,
2643
            $this->phoneUtil->parse("tel:253-0000;isub=12345;phone-context=www.google.com", RegionCode::US)
2644
        );
2645
        // This is invalid because no "+" sign is present as part of phone-context. The phone context
2646
        // is simply ignored in this case just as if it contains a domain.
2647
        $this->assertEquals(
2648
            self::$usLocalNumber,
2649
            $this->phoneUtil->parse("tel:2530000;isub=12345;phone-context=1-650", RegionCode::US)
2650
        );
2651
        $this->assertEquals(
2652
            self::$usLocalNumber,
2653
            $this->phoneUtil->parse("tel:2530000;isub=12345;phone-context=1234.com", RegionCode::US)
2654
        );
2655
2656
        $nzNumber = new PhoneNumber();
2657
        $nzNumber->setCountryCode(64)->setNationalNumber(64123456);
2658
        $this->assertEquals($nzNumber, $this->phoneUtil->parse("64(0)64123456", RegionCode::NZ));
2659
        // Check that using a "/" is fine in a phone number.
2660
        $this->assertEquals(self::$deNumber, $this->phoneUtil->parse("301/23456", RegionCode::DE));
2661
2662
        $usNumber = new PhoneNumber();
2663
        // Check it doesn't use the '1' as a country calling code when parsing if the phone number was
2664
        // already possible.
2665
        $usNumber->setCountryCode(1)->setNationalNumber(1234567890);
2666
        $this->assertEquals($usNumber, $this->phoneUtil->parse("123-456-7890", RegionCode::US));
2667
2668
        // Test star numbers. Although this is not strictly valid, we would like to make sure we can
2669
        // parse the output we produce when formatting the number.
2670
        $this->assertEquals(self::$jpStarNumber, $this->phoneUtil->parse("+81 *2345", RegionCode::JP));
2671
2672
        $shortNumber = new PhoneNumber();
2673
        $shortNumber->setCountryCode(64)->setNationalNumber(12);
2674
        $this->assertEquals($shortNumber, $this->phoneUtil->parse("12", RegionCode::NZ));
2675
    }
2676
2677
    public function testParseNumberWithAlphaCharacters()
2678
    {
2679
        // Test case with alpha characters.
2680
        $tollFreeNumber = new PhoneNumber();
2681
        $tollFreeNumber->setCountryCode(64)->setNationalNumber(800332005);
2682
        $this->assertEquals($tollFreeNumber, $this->phoneUtil->parse("0800 DDA 005", RegionCode::NZ));
2683
2684
        $premiumNumber = new PhoneNumber();
2685
        $premiumNumber->setCountryCode(64)->setNationalNumber(9003326005);
2686
        $this->assertEquals($premiumNumber, $this->phoneUtil->parse("0900 DDA 6005", RegionCode::NZ));
2687
2688
        // Not enough alpha characters for them to be considered intentional, so they are stripped.
2689
        $this->assertEquals($premiumNumber, $this->phoneUtil->parse("0900 332 6005a", RegionCode::NZ));
2690
        $this->assertEquals($premiumNumber, $this->phoneUtil->parse("0900 332 600a5", RegionCode::NZ));
2691
        $this->assertEquals($premiumNumber, $this->phoneUtil->parse("0900 332 600A5", RegionCode::NZ));
2692
        $this->assertEquals($premiumNumber, $this->phoneUtil->parse("0900 a332 600A5", RegionCode::NZ));
2693
    }
2694
2695
    public function testParseMaliciousInput()
2696
    {
2697
        // Lots of leading + signs before the possible number.
2698
        $maliciousNumber = str_repeat("+", 6000);
2699
        $maliciousNumber .= "12222-33-244 extensioB 343+";
2700
2701
        try {
2702
            $this->phoneUtil->parse($maliciousNumber, RegionCode::US);
2703
            $this->fail("This should not parse without throwing an exception " . $maliciousNumber);
2704
        } catch (NumberParseException $e) {
2705
            // Expected this exception.
2706
            $this->assertEquals(
2707
                NumberParseException::TOO_LONG,
2708
                $e->getErrorType(),
2709
                "Wrong error type stored in exception."
2710
            );
2711
        }
2712
2713
        $maliciousNumberWithAlmostExt = str_repeat("200", 350);
2714
        $maliciousNumberWithAlmostExt .= " extensiOB 345";
2715
        try {
2716
            $this->phoneUtil->parse($maliciousNumberWithAlmostExt, RegionCode::US);
2717
            $this->fail("This should not parse without throwing an exception " . $maliciousNumberWithAlmostExt);
2718
        } catch (NumberParseException $e) {
2719
            // Expected this exception.
2720
            $this->assertEquals(
2721
                NumberParseException::TOO_LONG,
2722
                $e->getErrorType(),
2723
                "Wrong error type stored in exception."
2724
            );
2725
        }
2726
    }
2727
2728
    public function testParseWithInternationalPrefixes()
2729
    {
2730
        $this->assertEquals(self::$usNumber, $this->phoneUtil->parse("+1 (650) 253-0000", RegionCode::NZ));
2731
        $this->assertEquals(self::$internationalTollFree, $this->phoneUtil->parse("011 800 1234 5678", RegionCode::US));
2732
        $this->assertEquals(self::$usNumber, $this->phoneUtil->parse("1-650-253-0000", RegionCode::US));
2733
        // Calling the US number from Singapore by using different service providers
2734
        // 1st test: calling using SingTel IDD service (IDD is 001)
2735
        $this->assertEquals(self::$usNumber, $this->phoneUtil->parse("0011-650-253-0000", RegionCode::SG));
2736
        // 2nd test: calling using StarHub IDD service (IDD is 008)
2737
        $this->assertEquals(self::$usNumber, $this->phoneUtil->parse("0081-650-253-0000", RegionCode::SG));
2738
        // 3rd test: calling using SingTel V019 service (IDD is 019)
2739
        $this->assertEquals(self::$usNumber, $this->phoneUtil->parse("0191-650-253-0000", RegionCode::SG));
2740
        // Calling the US number from Poland
2741
        $this->assertEquals(self::$usNumber, $this->phoneUtil->parse("0~01-650-253-0000", RegionCode::PL));
2742
        // Using "++" at the start.
2743
        $this->assertEquals(self::$usNumber, $this->phoneUtil->parse("++1 (650) 253-0000", RegionCode::PL));
2744
    }
2745
2746
    public function testParseNonAscii()
2747
    {
2748
        // Using a full-width plus sign.
2749
        $this->assertEquals(
2750
            self::$usNumber,
2751
            $this->phoneUtil->parse(pack("H*", 'efbc8b') . "1 (650) 253-0000", RegionCode::SG)
2752
        );
2753
        // Using a soft hyphen U+00AD.
2754
        $this->assertEquals(
2755
            self::$usNumber,
2756
            $this->phoneUtil->parse("1 (650) 253" . pack("H*", 'c2ad') . "-0000", RegionCode::US)
2757
        );
2758
        // The whole number, including punctuation, is here represented in full-width form.
2759
        $this->assertEquals(
2760
            self::$usNumber,
2761
            $this->phoneUtil->parse(
2762
                pack("H*", 'efbc8b') . pack("H*", 'efbc91') . pack("H*", 'e38080') .
2763
                pack("H*", 'efbc88') . pack("H*", 'efbc96') . pack("H*", 'efbc95') . pack("H*", 'efbc90') . pack(
2764
                    "H*",
2765
                    'efbc89'
2766
                ) .
2767
                pack("H*", 'e38080') . pack("H*", 'efbc92') . pack("H*", 'efbc95') . pack("H*", 'efbc93') . pack(
2768
                    "H*",
2769
                    'efbc8d'
2770
                ) .
2771
                pack("H*", 'efbc90') . pack("H*", 'efbc90') . pack("H*", 'efbc90') . pack("H*", 'efbc90'),
2772
                RegionCode::SG
2773
            )
2774
        );
2775
        // Using U+30FC dash instead.
2776
        $this->assertEquals(
2777
            self::$usNumber,
2778
            $this->phoneUtil->parse(
2779
                pack("H*", 'efbc8b') . pack("H*", 'efbc91') . pack("H*", 'e38080') .
2780
                pack("H*", 'efbc88') . pack("H*", 'efbc96') . pack("H*", 'efbc95') . pack("H*", 'efbc90') . pack(
2781
                    "H*",
2782
                    'efbc89'
2783
                ) .
2784
                pack("H*", 'e38080') . pack("H*", 'efbc92') . pack("H*", 'efbc95') . pack("H*", 'efbc93') . pack(
2785
                    "H*",
2786
                    'e383bc'
2787
                ) .
2788
                pack("H*", 'efbc90') . pack("H*", 'efbc90') . pack("H*", 'efbc90') . pack("H*", 'efbc90'),
2789
                RegionCode::SG
2790
            )
2791
        );
2792
        // Using a very strange decimal digit range (Mongolian digits).
2793
        $this->assertEquals(
2794
            self::$usNumber,
2795
            $this->phoneUtil->parse(
2796
                pack('H*', 'e1a091') . " "
2797
                . pack('H*', 'e1a096') . pack('H*', 'e1a095') . pack('H*', 'e1a090') . " "
2798
                . pack('H*', 'e1a092') . pack('H*', 'e1a095') . pack('H*', 'e1a093') . " "
2799
                . pack('H*', 'e1a090') . pack('H*', 'e1a090') . pack('H*', 'e1a090') . pack('H*', 'e1a090'),
2800
                RegionCode::US
2801
            )
2802
        );
2803
    }
2804
2805
    public function testParseWithLeadingZero()
2806
    {
2807
        $this->assertEquals(self::$itNumber, $this->phoneUtil->parse("+39 02-36618 300", RegionCode::NZ));
2808
        $this->assertEquals(self::$itNumber, $this->phoneUtil->parse("02-36618 300", RegionCode::IT));
2809
2810
        $this->assertEquals(self::$itMobile, $this->phoneUtil->parse("345 678 901", RegionCode::IT));
2811
    }
2812
2813
    public function testParseNationalNumberArgentina()
2814
    {
2815
        // Test parsing mobile numbers of Argentina.
2816
        $arNumber = new PhoneNumber();
2817
        $arNumber->setCountryCode(54)->setNationalNumber(93435551212);
2818
        $this->assertEquals($arNumber, $this->phoneUtil->parse("+54 9 343 555 1212", RegionCode::AR));
2819
        $this->assertEquals($arNumber, $this->phoneUtil->parse("0343 15 555 1212", RegionCode::AR));
2820
2821
        $arNumber->clear();
2822
        $arNumber->setCountryCode(54)->setNationalNumber(93715654320);
2823
        $this->assertEquals($arNumber, $this->phoneUtil->parse("+54 9 3715 65 4320", RegionCode::AR));
2824
        $this->assertEquals($arNumber, $this->phoneUtil->parse("03715 15 65 4320", RegionCode::AR));
2825
        $this->assertEquals(self::$arMobile, $this->phoneUtil->parse("911 876 54321", RegionCode::AR));
2826
2827
        // Test parsing fixed-line numbers of Argentina.
2828
        $this->assertEquals(self::$arNumber, $this->phoneUtil->parse("+54 11 8765 4321", RegionCode::AR));
2829
        $this->assertEquals(self::$arNumber, $this->phoneUtil->parse("011 8765 4321", RegionCode::AR));
2830
2831
        $arNumber->clear();
2832
        $arNumber->setCountryCode(54)->setNationalNumber(3715654321);
2833
        $this->assertEquals($arNumber, $this->phoneUtil->parse("+54 3715 65 4321", RegionCode::AR));
2834
        $this->assertEquals($arNumber, $this->phoneUtil->parse("03715 65 4321", RegionCode::AR));
2835
2836
        $arNumber->clear();
2837
        $arNumber->setCountryCode(54)->setNationalNumber(2312340000);
2838
        $this->assertEquals($arNumber, $this->phoneUtil->parse("+54 23 1234 0000", RegionCode::AR));
2839
        $this->assertEquals($arNumber, $this->phoneUtil->parse("023 1234 0000", RegionCode::AR));
2840
    }
2841
2842
    public function testParseWithXInNumber()
2843
    {
2844
        // Test that having an 'x' in the phone number at the start is ok and that it just gets removed.
2845
        $this->assertEquals(self::$arNumber, $this->phoneUtil->parse("01187654321", RegionCode::AR));
2846
        $this->assertEquals(self::$arNumber, $this->phoneUtil->parse("(0) 1187654321", RegionCode::AR));
2847
        $this->assertEquals(self::$arNumber, $this->phoneUtil->parse("0 1187654321", RegionCode::AR));
2848
        $this->assertEquals(self::$arNumber, $this->phoneUtil->parse("(0xx) 1187654321", RegionCode::AR));
2849
2850
        $arFromUs = new PhoneNumber();
2851
        $arFromUs->setCountryCode(54)->setNationalNumber(81429712);
2852
        // This test is intentionally constructed such that the number of digit after xx is larger than
2853
        // 7, so that the number won't be mistakenly treated as an extension, as we allow extensions up
2854
        // to 7 digits. This assumption is okay for now as all the countries where a carrier selection
2855
        // code is written in the form of xx have a national significant number of length larger than 7.
2856
        $this->assertEquals($arFromUs, $this->phoneUtil->parse("011xx5481429712", RegionCode::US));
2857
    }
2858
2859
    public function testParseNumbersMexico()
2860
    {
2861
        // Test parsing fixed-line numbers of Mexico.
2862
        $mxNumber = new PhoneNumber();
2863
        $mxNumber->setCountryCode(52)->setNationalNumber(4499780001);
2864
        $this->assertEquals($mxNumber, $this->phoneUtil->parse("+52 (449)978-0001", RegionCode::MX));
2865
        $this->assertEquals($mxNumber, $this->phoneUtil->parse("01 (449)978-0001", RegionCode::MX));
2866
        $this->assertEquals($mxNumber, $this->phoneUtil->parse("(449)978-0001", RegionCode::MX));
2867
2868
        // Test parsing mobile numbers of Mexico.
2869
        $mxNumber->clear();
2870
        $mxNumber->setCountryCode(52)->setNationalNumber(13312345678);
2871
        $this->assertEquals($mxNumber, $this->phoneUtil->parse("+52 1 33 1234-5678", RegionCode::MX));
2872
        $this->assertEquals($mxNumber, $this->phoneUtil->parse("044 (33) 1234-5678", RegionCode::MX));
2873
        $this->assertEquals($mxNumber, $this->phoneUtil->parse("045 33 1234-5678", RegionCode::MX));
2874
    }
2875
2876
    public function testFailedParseOnInvalidNumbers()
2877
    {
2878
        try {
2879
            $sentencePhoneNumber = "This is not a phone number";
2880
            $this->phoneUtil->parse($sentencePhoneNumber, RegionCode::NZ);
2881
            $this->fail("This should not parse without throwing an exception " . $sentencePhoneNumber);
2882
        } catch (NumberParseException $e) {
2883
            // Expected this exception.
2884
            $this->assertEquals(
2885
                NumberParseException::NOT_A_NUMBER,
2886
                $e->getErrorType(),
2887
                "Wrong error type stored in exception."
2888
            );
2889
        }
2890
2891
        try {
2892
            $sentencePhoneNumber = "1 Still not a number";
2893
            $this->phoneUtil->parse($sentencePhoneNumber, RegionCode::NZ);
2894
            $this->fail("This should not parse without throwing an exception " . $sentencePhoneNumber);
2895
        } catch (NumberParseException $e) {
2896
            // Expected this exception.
2897
            $this->assertEquals(
2898
                NumberParseException::NOT_A_NUMBER,
2899
                $e->getErrorType(),
2900
                "Wrong error type stored in exception."
2901
            );
2902
        }
2903
2904
        try {
2905
            $sentencePhoneNumber = "1 MICROSOFT";
2906
            $this->phoneUtil->parse($sentencePhoneNumber, RegionCode::NZ);
2907
            $this->fail("This should not parse without throwing an exception " . $sentencePhoneNumber);
2908
        } catch (NumberParseException $e) {
2909
            // Expected this exception.
2910
            $this->assertEquals(
2911
                NumberParseException::NOT_A_NUMBER,
2912
                $e->getErrorType(),
2913
                "Wrong error type stored in exception."
2914
            );
2915
        }
2916
2917
        try {
2918
            $sentencePhoneNumber = "12 MICROSOFT";
2919
            $this->phoneUtil->parse($sentencePhoneNumber, RegionCode::NZ);
2920
            $this->fail("This should not parse without throwing an exception " . $sentencePhoneNumber);
2921
        } catch (NumberParseException $e) {
2922
            // Expected this exception.
2923
            $this->assertEquals(
2924
                NumberParseException::NOT_A_NUMBER,
2925
                $e->getErrorType(),
2926
                "Wrong error type stored in exception."
2927
            );
2928
        }
2929
2930
        try {
2931
            $tooLongPhoneNumber = "01495 72553301873 810104";
2932
            $this->phoneUtil->parse($tooLongPhoneNumber, RegionCode::GB);
2933
            $this->fail("This should not parse without throwing an exception " . $tooLongPhoneNumber);
2934
        } catch (NumberParseException $e) {
2935
            // Expected this exception.
2936
            $this->assertEquals(
2937
                NumberParseException::TOO_LONG,
2938
                $e->getErrorType(),
2939
                "Wrong error type stored in exception."
2940
            );
2941
        }
2942
2943
        try {
2944
            $plusMinusPhoneNumber = "+---";
2945
            $this->phoneUtil->parse($plusMinusPhoneNumber, RegionCode::DE);
2946
            $this->fail("This should not parse without throwing an exception " . $plusMinusPhoneNumber);
2947
        } catch (NumberParseException $e) {
2948
            // Expected this exception.
2949
            $this->assertEquals(
2950
                NumberParseException::NOT_A_NUMBER,
2951
                $e->getErrorType(),
2952
                "Wrong error type stored in exception."
2953
            );
2954
        }
2955
2956
        try {
2957
            $plusStar = "+***";
2958
            $this->phoneUtil->parse($plusStar, RegionCode::DE);
2959
            $this->fail("This should not parse without throwing an exception " . $plusStar);
2960
        } catch (NumberParseException $e) {
2961
            // Expected this exception.
2962
            $this->assertEquals(
2963
                NumberParseException::NOT_A_NUMBER,
2964
                $e->getErrorType(),
2965
                "Wrong error type stored in exception."
2966
            );
2967
        }
2968
2969
        try {
2970
            $plusStarPhoneNumber = "+*******91";
2971
            $this->phoneUtil->parse($plusStarPhoneNumber, RegionCode::DE);
2972
            $this->fail("This should not parse without throwing an exception " . $plusStarPhoneNumber);
2973
        } catch (NumberParseException $e) {
2974
            // Expected this exception.
2975
            $this->assertEquals(
2976
                NumberParseException::NOT_A_NUMBER,
2977
                $e->getErrorType(),
2978
                "Wrong error type stored in exception."
2979
            );
2980
        }
2981
2982
        try {
2983
            $tooShortPhoneNumber = "+49 0";
2984
            $this->phoneUtil->parse($tooShortPhoneNumber, RegionCode::DE);
2985
            $this->fail("This should not parse without throwing an exception " . $tooShortPhoneNumber);
2986
        } catch (NumberParseException $e) {
2987
            // Expected this exception.
2988
            $this->assertEquals(
2989
                NumberParseException::TOO_SHORT_NSN,
2990
                $e->getErrorType(),
2991
                "Wrong error type stored in exception."
2992
            );
2993
        }
2994
2995
        try {
2996
            $invalidCountryCode = "+210 3456 56789";
2997
            $this->phoneUtil->parse($invalidCountryCode, RegionCode::NZ);
2998
            $this->fail("This is not a recognised region code: should fail: " . $invalidCountryCode);
2999
        } catch (NumberParseException $e) {
3000
            // Expected this exception.
3001
            $this->assertEquals(
3002
                NumberParseException::INVALID_COUNTRY_CODE,
3003
                $e->getErrorType(),
3004
                "Wrong error type stored in exception."
3005
            );
3006
        }
3007
3008
        try {
3009
            $plusAndIddAndInvalidCountryCode = "+ 00 210 3 331 6005";
3010
            $this->phoneUtil->parse($plusAndIddAndInvalidCountryCode, RegionCode::NZ);
3011
            $this->fail("This should not parse without throwing an exception " . $plusAndIddAndInvalidCountryCode);
3012
        } catch (NumberParseException $e) {
3013
            // Expected this exception. 00 is a correct IDD, but 210 is not a valid country code.
3014
            $this->assertEquals(
3015
                NumberParseException::INVALID_COUNTRY_CODE,
3016
                $e->getErrorType(),
3017
                "Wrong error type stored in exception."
3018
            );
3019
        }
3020
3021
        try {
3022
            $someNumber = "123 456 7890";
3023
            $this->phoneUtil->parse($someNumber, RegionCode::ZZ);
3024
            $this->fail("'Unknown' region code not allowed: should fail.");
3025
        } catch (NumberParseException $e) {
3026
            // Expected this exception.
3027
            $this->assertEquals(
3028
                NumberParseException::INVALID_COUNTRY_CODE,
3029
                $e->getErrorType(),
3030
                "Wrong error type stored in exception."
3031
            );
3032
        }
3033
3034
        try {
3035
            $someNumber = "123 456 7890";
3036
            $this->phoneUtil->parse($someNumber, RegionCode::CS);
3037
            $this->fail("Deprecated region code not allowed: should fail.");
3038
        } catch (NumberParseException $e) {
3039
            // Expected this exception.
3040
            $this->assertEquals(
3041
                NumberParseException::INVALID_COUNTRY_CODE,
3042
                $e->getErrorType(),
3043
                "Wrong error type stored in exception."
3044
            );
3045
        }
3046
3047
        try {
3048
            $someNumber = "123 456 7890";
3049
            $this->phoneUtil->parse($someNumber, null);
3050
            $this->fail("Null region code not allowed: should fail.");
3051
        } catch (NumberParseException $e) {
3052
            // Expected this exception.
3053
            $this->assertEquals(
3054
                NumberParseException::INVALID_COUNTRY_CODE,
3055
                $e->getErrorType(),
3056
                "Wrong error type stored in exception."
3057
            );
3058
        }
3059
3060
        try {
3061
            $someNumber = "0044------";
3062
            $this->phoneUtil->parse($someNumber, RegionCode::GB);
3063
            $this->fail("No number provided, only region code: should fail");
3064
        } catch (NumberParseException $e) {
3065
            // Expected this exception.
3066
            $this->assertEquals(
3067
                NumberParseException::TOO_SHORT_AFTER_IDD,
3068
                $e->getErrorType(),
3069
                "Wrong error type stored in exception."
3070
            );
3071
        }
3072
3073
        try {
3074
            $someNumber = "0044";
3075
            $this->phoneUtil->parse($someNumber, RegionCode::GB);
3076
            $this->fail("No number provided, only region code: should fail");
3077
        } catch (NumberParseException $e) {
3078
            // Expected this exception.
3079
            $this->assertEquals(
3080
                NumberParseException::TOO_SHORT_AFTER_IDD,
3081
                $e->getErrorType(),
3082
                "Wrong error type stored in exception."
3083
            );
3084
        }
3085
3086
        try {
3087
            $someNumber = "011";
3088
            $this->phoneUtil->parse($someNumber, RegionCode::US);
3089
            $this->fail("Only IDD provided - should fail.");
3090
        } catch (NumberParseException $e) {
3091
            // Expected this exception.
3092
            $this->assertEquals(
3093
                NumberParseException::TOO_SHORT_AFTER_IDD,
3094
                $e->getErrorType(),
3095
                "Wrong error type stored in exception."
3096
            );
3097
        }
3098
3099
        try {
3100
            $someNumber = "0119";
3101
            $this->phoneUtil->parse($someNumber, RegionCode::US);
3102
            $this->fail("Only IDD provided and then 9 - should fail.");
3103
        } catch (NumberParseException $e) {
3104
            // Expected this exception.
3105
            $this->assertEquals(
3106
                NumberParseException::TOO_SHORT_AFTER_IDD,
3107
                $e->getErrorType(),
3108
                "Wrong error type stored in exception."
3109
            );
3110
        }
3111
3112
        try {
3113
            $emptyNumber = "";
3114
            // Invalid region.
3115
            $this->phoneUtil->parse($emptyNumber, RegionCode::ZZ);
3116
            $this->fail("Empty string - should fail.");
3117
        } catch (NumberParseException $e) {
3118
            // Expected this exception.
3119
            $this->assertEquals(
3120
                NumberParseException::NOT_A_NUMBER,
3121
                $e->getErrorType(),
3122
                "Wrong error type stored in exception."
3123
            );
3124
        }
3125
3126
        try {
3127
            $nullNumber = null;
3128
            // Invalid region.
3129
            $this->phoneUtil->parse($nullNumber, RegionCode::ZZ);
3130
            $this->fail("Null string - should fail.");
3131
        } catch (NumberParseException $e) {
3132
            // Expected this exception.
3133
            $this->assertEquals(
3134
                NumberParseException::NOT_A_NUMBER,
3135
                $e->getErrorType(),
3136
                "Wrong error type stored in exception."
3137
            );
3138
        }
3139
3140
        try {
3141
            $nullNumber = null;
3142
            $this->phoneUtil->parse($nullNumber, RegionCode::US);
3143
            $this->fail("Null string - should fail.");
3144
        } catch (NumberParseException $e) {
3145
            // Expected this exception.
3146
            $this->assertEquals(
3147
                NumberParseException::NOT_A_NUMBER,
3148
                $e->getErrorType(),
3149
                "Wrong error type stored in exception."
3150
            );
3151
        }
3152
3153
        try {
3154
            $domainRfcPhoneContext = "tel:555-1234;phone-context=www.google.com";
3155
            $this->phoneUtil->parse($domainRfcPhoneContext, RegionCode::ZZ);
3156
            $this->fail("'Unknown' region code not allowed: should fail.");
3157
        } catch (NumberParseException $e) {
3158
            // Expected this exception.
3159
            $this->assertEquals(
3160
                NumberParseException::INVALID_COUNTRY_CODE,
3161
                $e->getErrorType(),
3162
                "Wrong error type stored in exception."
3163
            );
3164
        }
3165
3166
        try {
3167
            // This is invalid because no "+" sign is present as part of phone-context. This should not
3168
            // succeed in being parsed.
3169
            $invalidRfcPhoneContext = "tel:555-1234;phone-context=1-331";
3170
            $this->phoneUtil->parse($invalidRfcPhoneContext, RegionCode::ZZ);
3171
            $this->fail("'Unknown' region code not allowed: should fail.");
3172
        } catch (NumberParseException $e) {
3173
            // Expected this exception.
3174
            $this->assertEquals(
3175
                NumberParseException::INVALID_COUNTRY_CODE,
3176
                $e->getErrorType(),
3177
                "Wrong error type stored in exception."
3178
            );
3179
        }
3180
    }
3181
3182
    public function testParseNumbersWithPlusWithNoRegion()
3183
    {
3184
        // RegionCode.ZZ is allowed only if the number starts with a '+' - then the country calling code
3185
        // can be calculated.
3186
        $this->assertEquals(self::$nzNumber, $this->phoneUtil->parse("+64 3 331 6005", RegionCode::ZZ));
3187
        // Test with full-width plus.
3188
        $this->assertEquals(self::$nzNumber, $this->phoneUtil->parse("+64 3 331 6005", RegionCode::ZZ));
3189
        // Test with normal plus but leading characters that need to be stripped.
3190
        $this->assertEquals(self::$nzNumber, $this->phoneUtil->parse("Tel: +64 3 331 6005", RegionCode::ZZ));
3191
        $this->assertEquals(self::$nzNumber, $this->phoneUtil->parse("+64 3 331 6005", null));
3192
        $this->assertEquals(self::$internationalTollFree, $this->phoneUtil->parse("+800 1234 5678", null));
3193
        $this->assertEquals(self::$universalPremiumRate, $this->phoneUtil->parse("+979 123 456 789", null));
3194
3195
        // Test parsing RFC3966 format with a phone context.
3196
        $this->assertEquals(
3197
            self::$nzNumber,
3198
            $this->phoneUtil->parse("tel:03-331-6005;phone-context=+64", RegionCode::ZZ)
3199
        );
3200
        $this->assertEquals(
3201
            self::$nzNumber,
3202
            $this->phoneUtil->parse("  tel:03-331-6005;phone-context=+64", RegionCode::ZZ)
3203
        );
3204
        $this->assertEquals(
3205
            self::$nzNumber,
3206
            $this->phoneUtil->parse("tel:03-331-6005;isub=12345;phone-context=+64", RegionCode::ZZ)
3207
        );
3208
3209
        $nzNumberWithRawInput = new PhoneNumber();
3210
        $nzNumberWithRawInput->mergeFrom(self::$nzNumber);
3211
        $nzNumberWithRawInput->setRawInput("+64 3 331 6005");
3212
        $nzNumberWithRawInput->setCountryCodeSource(CountryCodeSource::FROM_NUMBER_WITH_PLUS_SIGN);
3213
        $this->assertEquals(
3214
            $nzNumberWithRawInput,
3215
            $this->phoneUtil->parseAndKeepRawInput("+64 3 331 6005", RegionCode::ZZ)
3216
        );
3217
3218
        // Null is also allowed for the region code in these cases.
3219
        $this->assertEquals($nzNumberWithRawInput, $this->phoneUtil->parseAndKeepRawInput("+64 3 331 6005", null));
3220
    }
3221
3222
    public function testParseNumberTooShortIfNationalPrefixStripped()
3223
    {
3224
        // Test that a number whose first digits happen to coincide with the national prefix does not
3225
        // get them stripped if doing so would result in a number too short to be a possible (regular
3226
        // length) phone number for that region.
3227
        $byNumber = new PhoneNumber();
3228
        $byNumber->setCountryCode(375)->setNationalNumber(8123);
3229
        $this->assertEquals($byNumber, $this->phoneUtil->parse("8123", RegionCode::BY));
3230
        $byNumber->setNationalNumber(81234);
3231
        $this->assertEquals($byNumber, $this->phoneUtil->parse("81234", RegionCode::BY));
3232
3233
        // The prefix doesn't get stripped, since the input is a viable 6-digit number, whereas the
3234
        // result of stripping is only 5 digits.
3235
        $byNumber->setNationalNumber(812345);
3236
        $this->assertEquals($byNumber, $this->phoneUtil->parse("812345", RegionCode::BY));
3237
3238
        // The prefix gets stripped, since only 6-digit numbers are possible.
3239
        $byNumber->setNationalNumber(123456);
3240
        $this->assertEquals($byNumber, $this->phoneUtil->parse("8123456", RegionCode::BY));
3241
    }
3242
3243
    public function testParseExtensions()
3244
    {
3245
        $nzNumber = new PhoneNumber();
3246
        $nzNumber->setCountryCode(64)->setNationalNumber(33316005)->setExtension("3456");
3247
        $this->assertEquals($nzNumber, $this->phoneUtil->parse("03 331 6005 ext 3456", RegionCode::NZ));
3248
        $this->assertEquals($nzNumber, $this->phoneUtil->parse("03-3316005x3456", RegionCode::NZ));
3249
        $this->assertEquals($nzNumber, $this->phoneUtil->parse("03-3316005 int.3456", RegionCode::NZ));
3250
        $this->assertEquals($nzNumber, $this->phoneUtil->parse("03 3316005 #3456", RegionCode::NZ));
3251
        // Test the following do not extract extensions:
3252
        $this->assertEquals(self::$alphaNumericNumber, $this->phoneUtil->parse("1800 six-flags", RegionCode::US));
3253
        $this->assertEquals(self::$alphaNumericNumber, $this->phoneUtil->parse("1800 SIX FLAGS", RegionCode::US));
3254
        $this->assertEquals(self::$alphaNumericNumber, $this->phoneUtil->parse("0~0 1800 7493 5247", RegionCode::PL));
3255
        $this->assertEquals(self::$alphaNumericNumber, $this->phoneUtil->parse("(1800) 7493.5247", RegionCode::US));
3256
        // Check that the last instance of an extension token is matched.
3257
        $extnNumber = new PhoneNumber();
3258
        $extnNumber->mergeFrom(self::$alphaNumericNumber)->setExtension("1234");
3259
        $this->assertEquals($extnNumber, $this->phoneUtil->parse("0~0 1800 7493 5247 ~1234", RegionCode::PL));
3260
        // Verifying bug-fix where the last digit of a number was previously omitted if it was a 0 when
3261
        // extracting the extension. Also verifying a few different cases of extensions.
3262
        $ukNumber = new PhoneNumber();
3263
        $ukNumber->setCountryCode(44)->setNationalNumber(2034567890)->setExtension("456");
3264
        $this->assertEquals($ukNumber, $this->phoneUtil->parse("+44 2034567890x456", RegionCode::NZ));
3265
        $this->assertEquals($ukNumber, $this->phoneUtil->parse("+44 2034567890x456", RegionCode::GB));
3266
        $this->assertEquals($ukNumber, $this->phoneUtil->parse("+44 2034567890 x456", RegionCode::GB));
3267
        $this->assertEquals($ukNumber, $this->phoneUtil->parse("+44 2034567890 X456", RegionCode::GB));
3268
        $this->assertEquals($ukNumber, $this->phoneUtil->parse("+44 2034567890 X 456", RegionCode::GB));
3269
        $this->assertEquals($ukNumber, $this->phoneUtil->parse("+44 2034567890 X  456", RegionCode::GB));
3270
        $this->assertEquals($ukNumber, $this->phoneUtil->parse("+44 2034567890 x 456  ", RegionCode::GB));
3271
        $this->assertEquals($ukNumber, $this->phoneUtil->parse("+44 2034567890  X 456", RegionCode::GB));
3272
        $this->assertEquals($ukNumber, $this->phoneUtil->parse("+44-2034567890;ext=456", RegionCode::GB));
3273
        $this->assertEquals(
3274
            $ukNumber,
3275
            $this->phoneUtil->parse("tel:2034567890;ext=456;phone-context=+44", RegionCode::ZZ)
3276
        );
3277
3278
        // Full-width extension, "extn" only.
3279
        $this->assertEquals($ukNumber, $this->phoneUtil->parse("+442034567890extn456", RegionCode::GB));
3280
        // "xtn" only.
3281
        $this->assertEquals($ukNumber, $this->phoneUtil->parse("+442034567890xtn456", RegionCode::GB));
3282
        // "xt" only.
3283
        $this->assertEquals($ukNumber, $this->phoneUtil->parse("+442034567890xt456", RegionCode::GB));
3284
3285
        $usWithExtension = new PhoneNumber();
3286
        $usWithExtension->setCountryCode(1)->setNationalNumber(8009013355)->setExtension("7246433");
3287
        $this->assertEquals($usWithExtension, $this->phoneUtil->parse("(800) 901-3355 x 7246433", RegionCode::US));
3288
        $this->assertEquals($usWithExtension, $this->phoneUtil->parse("(800) 901-3355 , ext 7246433", RegionCode::US));
3289
        $this->assertEquals($usWithExtension, $this->phoneUtil->parse("(800) 901-3355 ; 7246433", RegionCode::US));
3290
        // To test an extension character without surrounding spaces.
3291
        $this->assertEquals($usWithExtension, $this->phoneUtil->parse("(800) 901-3355;7246433", RegionCode::US));
3292
        $this->assertEquals(
3293
            $usWithExtension,
3294
            $this->phoneUtil->parse("(800) 901-3355 ,extension 7246433", RegionCode::US)
3295
        );
3296
        $this->assertEquals(
3297
            $usWithExtension,
3298
            $this->phoneUtil->parse("(800) 901-3355 ,extensi" . pack("H*", 'c3b3') . "n 7246433", RegionCode::US)
3299
        );
3300
        // Repeat with the small letter o with acute accent created by combining characters.
3301
        $this->assertEquals(
3302
            $usWithExtension,
3303
            $this->phoneUtil->parse("(800) 901-3355 ,extensio" . pack('H*', 'cc81') . "n 7246433", RegionCode::US)
3304
        );
3305
        $this->assertEquals($usWithExtension, $this->phoneUtil->parse("(800) 901-3355 , 7246433", RegionCode::US));
3306
        $this->assertEquals($usWithExtension, $this->phoneUtil->parse("(800) 901-3355 ext: 7246433", RegionCode::US));
3307
3308
        // Test that if a number has two extensions specified, we ignore the second.
3309
        $usWithTwoExtensionsNumber = new PhoneNumber();
3310
        $usWithTwoExtensionsNumber->setCountryCode(1)->setNationalNumber(2121231234)->setExtension("508");
3311
        $this->assertEquals(
3312
            $usWithTwoExtensionsNumber,
3313
            $this->phoneUtil->parse("(212)123-1234 x508/x1234", RegionCode::US)
3314
        );
3315
        $this->assertEquals(
3316
            $usWithTwoExtensionsNumber,
3317
            $this->phoneUtil->parse("(212)123-1234 x508/ x1234", RegionCode::US)
3318
        );
3319
        $this->assertEquals(
3320
            $usWithTwoExtensionsNumber,
3321
            $this->phoneUtil->parse("(212)123-1234 x508\\x1234", RegionCode::US)
3322
        );
3323
3324
        // Test parsing numbers in the form (645) 123-1234-910# works, where the last 3 digits before
3325
        // the # are an extension.
3326
        $usWithExtension->clear();
3327
        $usWithExtension->setCountryCode(1)->setNationalNumber(6451231234)->setExtension("910");
3328
        $this->assertEquals($usWithExtension, $this->phoneUtil->parse("+1 (645) 123 1234-910#", RegionCode::US));
3329
        // Retry with the same number in a slightly different format.
3330
        $this->assertEquals($usWithExtension, $this->phoneUtil->parse("+1 (645) 123 1234 ext. 910#", RegionCode::US));
3331
    }
3332
3333
    public function testParseAndKeepRaw()
3334
    {
3335
        $alphaNumericNumber = new PhoneNumber();
3336
        $alphaNumericNumber->mergeFrom(self::$alphaNumericNumber);
3337
        $alphaNumericNumber->setRawInput("800 six-flags");
3338
        $alphaNumericNumber->setCountryCodeSource(CountryCodeSource::FROM_DEFAULT_COUNTRY);
3339
        $this->assertEquals(
3340
            $alphaNumericNumber,
3341
            $this->phoneUtil->parseAndKeepRawInput("800 six-flags", RegionCode::US)
3342
        );
3343
3344
        $shorterAlphaNumber = new PhoneNumber();
3345
        $shorterAlphaNumber->setCountryCode(1)->setNationalNumber(8007493524);
3346
        $shorterAlphaNumber
3347
            ->setRawInput("1800 six-flag")
3348
            ->setCountryCodeSource(CountryCodeSource::FROM_NUMBER_WITHOUT_PLUS_SIGN);
3349
        $this->assertEquals(
3350
            $shorterAlphaNumber,
3351
            $this->phoneUtil->parseAndKeepRawInput("1800 six-flag", RegionCode::US)
3352
        );
3353
3354
        $shorterAlphaNumber->setRawInput("+1800 six-flag")->setCountryCodeSource(
3355
            CountryCodeSource::FROM_NUMBER_WITH_PLUS_SIGN
3356
        );
3357
        $this->assertEquals(
3358
            $shorterAlphaNumber,
3359
            $this->phoneUtil->parseAndKeepRawInput("+1800 six-flag", RegionCode::NZ)
3360
        );
3361
3362
        $shorterAlphaNumber->setRawInput("001800 six-flag")->setCountryCodeSource(
3363
            CountryCodeSource::FROM_NUMBER_WITH_IDD
3364
        );
3365
        $this->assertEquals(
3366
            $shorterAlphaNumber,
3367
            $this->phoneUtil->parseAndKeepRawInput("001800 six-flag", RegionCode::NZ)
3368
        );
3369
3370
        // Invalid region code supplied.
3371
        try {
3372
            $this->phoneUtil->parseAndKeepRawInput("123 456 7890", RegionCode::CS);
3373
            $this->fail("Deprecated region code not allowed: should fail.");
3374
        } catch (NumberParseException $e) {
3375
            // Expected this exception.
3376
            $this->assertEquals(
3377
                NumberParseException::INVALID_COUNTRY_CODE,
3378
                $e->getErrorType(),
3379
                "Wrong error type stored in exception."
3380
            );
3381
        }
3382
3383
        $koreanNumber = new PhoneNumber();
3384
        $koreanNumber->setCountryCode(82)->setNationalNumber(22123456)->setRawInput(
3385
            "08122123456"
3386
        )->setCountryCodeSource(CountryCodeSource::FROM_DEFAULT_COUNTRY)->setPreferredDomesticCarrierCode("81");
3387
        $this->assertEquals($koreanNumber, $this->phoneUtil->parseAndKeepRawInput("08122123456", RegionCode::KR));
3388
    }
3389
3390
    public function testParseItalianLeadingZeros()
3391
    {
3392
        // Test the number "011".
3393
        $oneZero = new PhoneNumber();
3394
        $oneZero->setCountryCode(61)->setNationalNumber(11)->setItalianLeadingZero(true);
3395
        $this->assertEquals($oneZero, $this->phoneUtil->parse("011", RegionCode::AU));
3396
3397
        // Test the number "001".
3398
        $twoZeros = new PhoneNumber();
3399
        $twoZeros->setCountryCode(61)->setNationalNumber(1)->setItalianLeadingZero(true)->setNumberOfLeadingZeros(2);
3400
        $this->assertEquals($twoZeros, $this->phoneUtil->parse("001", RegionCode::AU));
3401
3402
        // Test the number "000". This number has 2 leading zeros.
3403
        $stillTwoZeros = new PhoneNumber();
3404
        $stillTwoZeros->setCountryCode(61)->setNationalNumber(0)->setItalianLeadingZero(true)->setNumberOfLeadingZeros(
3405
            2
3406
        );
3407
        $this->assertEquals($stillTwoZeros, $this->phoneUtil->parse("000", RegionCode::AU));
3408
3409
        // Test the number "0000". This number has 3 leading zeros.
3410
        $threeZeros = new PhoneNumber();
3411
        $threeZeros->setCountryCode(61)->setNationalNumber(0)->setItalianLeadingZero(true)->setNumberOfLeadingZeros(3);
3412
        $this->assertEquals($threeZeros, $this->phoneUtil->parse("0000", RegionCode::AU));
3413
    }
3414
3415
    public function testCountryWithNoNumberDesc()
3416
    {
3417
        // Andorra is a country where we don't have PhoneNumberDesc info in the metadata.
3418
        $adNumber = new PhoneNumber();
3419
        $adNumber->setCountryCode(376)->setNationalNumber(12345);
3420
3421
        $this->assertEquals("+376 12345", $this->phoneUtil->format($adNumber, PhoneNumberFormat::INTERNATIONAL));
3422
        $this->assertEquals("+37612345", $this->phoneUtil->format($adNumber, PhoneNumberFormat::E164));
3423
        $this->assertEquals("12345", $this->phoneUtil->format($adNumber, PhoneNumberFormat::NATIONAL));
3424
        $this->assertEquals(PhoneNumberType::UNKNOWN, $this->phoneUtil->getNumberType($adNumber));
3425
        $this->assertFalse($this->phoneUtil->isValidNumber($adNumber));
3426
3427
        // Test dialing a US number from within Andorra.
3428
        $this->assertEquals(
3429
            "00 1 650 253 0000",
3430
            $this->phoneUtil->formatOutOfCountryCallingNumber(self::$usNumber, RegionCode::AD)
3431
        );
3432
    }
3433
3434
    public function testUnknownCountryCallingCode()
3435
    {
3436
        $this->assertFalse($this->phoneUtil->isValidNumber(self::$unknownCountryCodeNoRawInput));
3437
        // It's not very well defined as to what the E164 representation for a number with an invalid
3438
        // country calling code is, but just prefixing the country code and national number is about
3439
        // the best we can do.
3440
        $this->assertEquals(
3441
            "+212345",
3442
            $this->phoneUtil->format(self::$unknownCountryCodeNoRawInput, PhoneNumberFormat::E164)
3443
        );
3444
    }
3445
3446
    public function testIsNumberMatchMatches()
3447
    {
3448
        // Test simple matches where formatting is different, or leading zeros, or country calling code
3449
        // has been specified.
3450
        $this->assertEquals(
3451
            MatchType::EXACT_MATCH,
3452
            $this->phoneUtil->isNumberMatch("+64 3 331 6005", "+64 03 331 6005")
3453
        );
3454
        $this->assertEquals(MatchType::EXACT_MATCH, $this->phoneUtil->isNumberMatch("+800 1234 5678", "+80012345678"));
3455
        $this->assertEquals(
3456
            MatchType::EXACT_MATCH,
3457
            $this->phoneUtil->isNumberMatch("+64 03 331-6005", "+64 03331 6005")
3458
        );
3459
        $this->assertEquals(MatchType::EXACT_MATCH, $this->phoneUtil->isNumberMatch("+643 331-6005", "+64033316005"));
3460
        $this->assertEquals(MatchType::EXACT_MATCH, $this->phoneUtil->isNumberMatch("+643 331-6005", "+6433316005"));
3461
        $this->assertEquals(MatchType::EXACT_MATCH, $this->phoneUtil->isNumberMatch("+64 3 331-6005", "+6433316005"));
3462
        $this->assertEquals(
3463
            MatchType::EXACT_MATCH,
3464
            $this->phoneUtil->isNumberMatch("+64 3 331-6005", "tel:+64-3-331-6005;isub=123")
3465
        );
3466
        // Test alpha numbers.
3467
        $this->assertEquals(
3468
            MatchType::EXACT_MATCH,
3469
            $this->phoneUtil->isNumberMatch("+1800 siX-Flags", "+1 800 7493 5247")
3470
        );
3471
        // Test numbers with extensions.
3472
        $this->assertEquals(
3473
            MatchType::EXACT_MATCH,
3474
            $this->phoneUtil->isNumberMatch("+64 3 331-6005 extn 1234", "+6433316005#1234")
3475
        );
3476
        $this->assertEquals(
3477
            MatchType::EXACT_MATCH,
3478
            $this->phoneUtil->isNumberMatch("+64 3 331-6005 ext. 1234", "+6433316005;1234")
3479
        );
3480
        // Test proto buffers.
3481
        $this->assertEquals(MatchType::EXACT_MATCH, $this->phoneUtil->isNumberMatch(self::$nzNumber, "+6403 331 6005"));
3482
3483
        $nzNumber = new PhoneNumber();
3484
        $nzNumber->mergeFrom(self::$nzNumber)->setExtension("3456");
3485
        $this->assertEquals(
3486
            MatchType::EXACT_MATCH,
3487
            $this->phoneUtil->isNumberMatch($nzNumber, "+643 331 6005 ext 3456")
3488
        );
3489
3490
        // Check empty extensions are ignored.
3491
        $nzNumber->setExtension("");
3492
        $this->assertEquals(MatchType::EXACT_MATCH, $this->phoneUtil->isNumberMatch($nzNumber, "+6403 331 6005"));
3493
        // Check variant with two proto buffers.
3494
        $this->assertEquals(
3495
            MatchType::EXACT_MATCH,
3496
            $this->phoneUtil->isNumberMatch($nzNumber, self::$nzNumber),
3497
            "Number " . (string)$nzNumber . " did not match " . (string)self::$nzNumber
3498
        );
3499
    }
3500
3501
    public function testIsNumberMatchShortMatchIfDiffNumLeadingZeros()
3502
    {
3503
        $nzNumberOne = new PhoneNumber();
3504
        $nzNumberTwo = new PhoneNumber();
3505
        $nzNumberOne->setCountryCode(64)->setNationalNumber(33316005)->setItalianLeadingZero(true);
3506
        $nzNumberTwo->setCountryCode(64)->setNationalNumber(33316005)->setItalianLeadingZero(true)->setNumberOfLeadingZeros(2);
3507
3508
        $this->assertEquals(MatchType::SHORT_NSN_MATCH, $this->phoneUtil->isNumberMatch($nzNumberOne, $nzNumberTwo));
3509
3510
        $nzNumberOne->setItalianLeadingZero(false)->setNumberOfLeadingZeros(1);
3511
        $nzNumberTwo->setItalianLeadingZero(true)->setNumberOfLeadingZeros(1);
3512
3513
        // Since one doesn't have the Italian leading zero set to true, we ignore the number of leading zeros present
3514
        // (1 is in any case the default value)
3515
        $this->assertEquals(MatchType::SHORT_NSN_MATCH, $this->phoneUtil->isNumberMatch($nzNumberOne, $nzNumberTwo));
3516
    }
3517
3518
    public function testIsNumberMatchAcceptsProtoDefaultsAsMatch()
3519
    {
3520
        $nzNumberOne = new PhoneNumber();
3521
        $nzNumberTwo = new PhoneNumber();
3522
3523
        $nzNumberOne->setCountryCode(64)->setNationalNumber(33316005)->setItalianLeadingZero(true);
3524
        // The default for number of leading zeros is 1, so it shouldn't normally be set, however if it
3525
        // is it should be considered equivalent.
3526
        $nzNumberTwo->setCountryCode(64)->setNationalNumber(33316005)->setItalianLeadingZero(true)->setNumberOfLeadingZeros(1);
3527
3528
        $this->assertEquals(MatchType::EXACT_MATCH, $this->phoneUtil->isNumberMatch($nzNumberOne, $nzNumberTwo));
3529
    }
3530
3531
    public function testIsNumberMatchMatchesDiffLeadingZerosIfItalianLeadingZeroFalse()
3532
    {
3533
        $nzNumberOne = new PhoneNumber();
3534
        $nzNumberTwo = new PhoneNumber();
3535
3536
        $nzNumberOne->setCountryCode(64)->setNationalNumber(33316005);
3537
        // The default for number of leading zeros is 1, so it shouldn't normally be set, however if it
3538
        // is it should be considered equivalent
3539
        $nzNumberTwo->setCountryCode(64)->setNationalNumber(33316005)->setNumberOfLeadingZeros(1);
3540
3541
        $this->assertEquals(MatchType::EXACT_MATCH, $this->phoneUtil->isNumberMatch($nzNumberOne, $nzNumberTwo));
3542
3543
        // Even if it is set to ten, it is still equivalent because in both cases
3544
        // italian leading zero is not true
3545
        $nzNumberTwo->setNumberOfLeadingZeros(10);
3546
        $this->assertEquals(MatchType::EXACT_MATCH, $this->phoneUtil->isNumberMatch($nzNumberOne, $nzNumberTwo));
3547
    }
3548
3549
    public function testIsNumberMatchIgnoresSomeFields()
3550
    {
3551
        // Check raw_input, country_code_source and preferred_domestic_carrier_code are ignored.
3552
        $brNumberOne = new PhoneNumber();
3553
        $brNumberTwo = new PhoneNumber();
3554
        $brNumberOne->setCountryCode(55)->setNationalNumber(3121286979)
3555
            ->setCountryCodeSource(CountryCodeSource::FROM_NUMBER_WITH_PLUS_SIGN)
3556
            ->setPreferredDomesticCarrierCode("12")->setRawInput("012 3121286979");
3557
        $brNumberTwo->setCountryCode(55)->setNationalNumber(3121286979)
3558
            ->setCountryCodeSource(CountryCodeSource::FROM_DEFAULT_COUNTRY)
3559
            ->setPreferredDomesticCarrierCode("14")->setRawInput("143121286979");
3560
3561
        $this->assertEquals(MatchType::EXACT_MATCH, $this->phoneUtil->isNumberMatch($brNumberOne, $brNumberTwo));
3562
    }
3563
3564
    public function testIsNumberMatchNonMatches()
3565
    {
3566
        // Non-matches.
3567
        $this->assertEquals(MatchType::NO_MATCH, $this->phoneUtil->isNumberMatch("03 331 6005", "03 331 6006"));
3568
        $this->assertEquals(MatchType::NO_MATCH, $this->phoneUtil->isNumberMatch("+800 1234 5678", "+1 800 1234 5678"));
3569
        // Different country calling code, partial number match.
3570
        $this->assertEquals(MatchType::NO_MATCH, $this->phoneUtil->isNumberMatch("+64 3 331-6005", "+16433316005"));
3571
        // Different country calling code, same number.
3572
        $this->assertEquals(MatchType::NO_MATCH, $this->phoneUtil->isNumberMatch("+64 3 331-6005", "+6133316005"));
3573
        // Extension different, all else the same.
3574
        $this->assertEquals(
3575
            MatchType::NO_MATCH,
3576
            $this->phoneUtil->isNumberMatch("+64 3 331-6005 extn 1234", "0116433316005#1235")
3577
        );
3578
        $this->assertEquals(
3579
            MatchType::NO_MATCH,
3580
            $this->phoneUtil->isNumberMatch("+64 3 331-6005 extn 1234", "tel:+64-3-331-6005;ext=1235")
3581
        );
3582
        // NSN matches, but extension is different - not the same number.
3583
        $this->assertEquals(
3584
            MatchType::NO_MATCH,
3585
            $this->phoneUtil->isNumberMatch("+64 3 331-6005 ext.1235", "3 331 6005#1234")
3586
        );
3587
3588
        // Invalid numbers that can't be parsed.
3589
        $this->assertEquals(MatchType::NOT_A_NUMBER, $this->phoneUtil->isNumberMatch("4", "3 331 6043"));
3590
        $this->assertEquals(MatchType::NOT_A_NUMBER, $this->phoneUtil->isNumberMatch("+43", "+64 3 331 6005"));
3591
        $this->assertEquals(MatchType::NOT_A_NUMBER, $this->phoneUtil->isNumberMatch("+43", "64 3 331 6005"));
3592
        $this->assertEquals(MatchType::NOT_A_NUMBER, $this->phoneUtil->isNumberMatch("Dog", "64 3 331 6005"));
3593
    }
3594
3595
    public function testIsNumberMatchNsnMatches()
3596
    {
3597
        // NSN matches.
3598
        $this->assertEquals(MatchType::NSN_MATCH, $this->phoneUtil->isNumberMatch("+64 3 331-6005", "03 331 6005"));
3599
        $this->assertEquals(
3600
            MatchType::NSN_MATCH,
3601
            $this->phoneUtil->isNumberMatch("+64 3 331-6005", "tel:03-331-6005;isub=1234;phone-context=abc.nz")
3602
        );
3603
        $this->assertEquals(MatchType::NSN_MATCH, $this->phoneUtil->isNumberMatch(self::$nzNumber, "03 331 6005"));
3604
        // Here the second number possibly starts with the country calling code for New Zealand,
3605
        // although we are unsure.
3606
        $unchangedNzNumber = new PhoneNumber();
3607
        $unchangedNzNumber->mergeFrom(self::$nzNumber);
3608
        $this->assertEquals(
3609
            MatchType::NSN_MATCH,
3610
            $this->phoneUtil->isNumberMatch($unchangedNzNumber, "(64-3) 331 6005")
3611
        );
3612
        // Check the phone number proto was not edited during the method call.
3613
        $this->assertEquals(self::$nzNumber, $unchangedNzNumber);
3614
3615
        // Here, the 1 might be a national prefix, if we compare it to the US number, so the resultant
3616
        // match is an NSN match.
3617
        $this->assertEquals(MatchType::NSN_MATCH, $this->phoneUtil->isNumberMatch(self::$usNumber, "1-650-253-0000"));
3618
        $this->assertEquals(MatchType::NSN_MATCH, $this->phoneUtil->isNumberMatch(self::$usNumber, "6502530000"));
3619
        $this->assertEquals(MatchType::NSN_MATCH, $this->phoneUtil->isNumberMatch("+1 650-253 0000", "1 650 253 0000"));
3620
        $this->assertEquals(MatchType::NSN_MATCH, $this->phoneUtil->isNumberMatch("1 650-253 0000", "1 650 253 0000"));
3621
        $this->assertEquals(MatchType::NSN_MATCH, $this->phoneUtil->isNumberMatch("1 650-253 0000", "+1 650 253 0000"));
3622
        // For this case, the match will be a short NSN match, because we cannot assume that the 1 might
3623
        // be a national prefix, so don't remove it when parsing.
3624
        $randomNumber = new PhoneNumber();
3625
        $randomNumber->setCountryCode(41)->setNationalNumber(6502530000);
3626
        $this->assertEquals(
3627
            MatchType::SHORT_NSN_MATCH,
3628
            $this->phoneUtil->isNumberMatch($randomNumber, "1-650-253-0000")
3629
        );
3630
    }
3631
3632
    public function testIsNumberMatchShortNsnMatches()
3633
    {
3634
        // Short NSN matches with the country not specified for either one or both numbers.
3635
        $this->assertEquals(MatchType::SHORT_NSN_MATCH, $this->phoneUtil->isNumberMatch("+64 3 331-6005", "331 6005"));
3636
        $this->assertEquals(
3637
            MatchType::SHORT_NSN_MATCH,
3638
            $this->phoneUtil->isNumberMatch("+64 3 331-6005", "tel:331-6005;phone-context=abc.nz")
3639
        );
3640
        $this->assertEquals(
3641
            MatchType::SHORT_NSN_MATCH,
3642
            $this->phoneUtil->isNumberMatch("+64 3 331-6005", "tel:331-6005;isub=1234;phone-context=abc.nz")
3643
        );
3644
        $this->assertEquals(
3645
            MatchType::SHORT_NSN_MATCH,
3646
            $this->phoneUtil->isNumberMatch("+64 3 331-6005", "tel:331-6005;isub=1234;phone-context=abc.nz;a=%A1")
3647
        );
3648
3649
        // We did not know that the "0" was a national prefix since neither number has a country code,
3650
        // so this is considered a SHORT_NSN_MATCH.
3651
        $this->assertEquals(MatchType::SHORT_NSN_MATCH, $this->phoneUtil->isNumberMatch("3 331-6005", "03 331 6005"));
3652
        $this->assertEquals(MatchType::SHORT_NSN_MATCH, $this->phoneUtil->isNumberMatch("3 331-6005", "331 6005"));
3653
        $this->assertEquals(
3654
            MatchType::SHORT_NSN_MATCH,
3655
            $this->phoneUtil->isNumberMatch("3 331-6005", "tel:331-6005;phone-context=abc.nz")
3656
        );
3657
        $this->assertEquals(MatchType::SHORT_NSN_MATCH, $this->phoneUtil->isNumberMatch("3 331-6005", "+64 331 6005"));
3658
3659
        // Short NSN match with the country specified.
3660
        $this->assertEquals(MatchType::SHORT_NSN_MATCH, $this->phoneUtil->isNumberMatch("03 331-6005", "331 6005"));
3661
        $this->assertEquals(MatchType::SHORT_NSN_MATCH, $this->phoneUtil->isNumberMatch("1 234 345 6789", "345 6789"));
3662
        $this->assertEquals(
3663
            MatchType::SHORT_NSN_MATCH,
3664
            $this->phoneUtil->isNumberMatch("+1 (234) 345 6789", "345 6789")
3665
        );
3666
        // NSN matches, country calling code omitted for one number, extension missing for one.
3667
        $this->assertEquals(
3668
            MatchType::SHORT_NSN_MATCH,
3669
            $this->phoneUtil->isNumberMatch("+64 3 331-6005", "3 331 6005#1234")
3670
        );
3671
        // One has Italian leading zero, one does not.
3672
        $italianNumberOne = new PhoneNumber();
3673
        $italianNumberOne->setCountryCode(39)->setNationalNumber(1234)->setItalianLeadingZero(true);
3674
        $italianNumberTwo = new PhoneNumber();
3675
        $italianNumberTwo->setCountryCode(39)->setNationalNumber(1234);
3676
        $this->assertEquals(
3677
            MatchType::SHORT_NSN_MATCH,
3678
            $this->phoneUtil->isNumberMatch($italianNumberOne, $italianNumberTwo)
3679
        );
3680
        // One has an extension, the other has an extension of "".
3681
        $italianNumberOne->setExtension("1234")->clearItalianLeadingZero();
3682
        $italianNumberTwo->setExtension("");
3683
        $this->assertEquals(
3684
            MatchType::SHORT_NSN_MATCH,
3685
            $this->phoneUtil->isNumberMatch($italianNumberOne, $italianNumberTwo)
3686
        );
3687
    }
3688
3689
    public function testCanBeInternationallyDialled()
3690
    {
3691
        // We have no-international-dialling rules for the US in our test metadata that say that
3692
        // toll-free numbers cannot be dialled internationally.
3693
        $this->assertFalse($this->phoneUtil->canBeInternationallyDialled(self::$usTollFree));
3694
        // Normal US numbers can be internationally dialled.
3695
        $this->assertTrue($this->phoneUtil->canBeInternationallyDialled(self::$usNumber));
3696
3697
        // Invalid number.
3698
        $this->assertTrue($this->phoneUtil->canBeInternationallyDialled(self::$usLocalNumber));
3699
3700
        // We have no data for NZ - should return true.
3701
        $this->assertTrue($this->phoneUtil->canBeInternationallyDialled(self::$nzNumber));
3702
        $this->assertTrue($this->phoneUtil->canBeInternationallyDialled(self::$internationalTollFree));
3703
    }
3704
3705
    public function testIsAlphaNumber()
3706
    {
3707
        $this->assertTrue($this->phoneUtil->isAlphaNumber("1800 six-flags"));
3708
        $this->assertTrue($this->phoneUtil->isAlphaNumber("1800 six-flags ext. 1234"));
3709
        $this->assertTrue($this->phoneUtil->isAlphaNumber("+800 six-flags"));
3710
        $this->assertTrue($this->phoneUtil->isAlphaNumber("180 six-flags"));
3711
        $this->assertFalse($this->phoneUtil->isAlphaNumber("1800 123-1234"));
3712
        $this->assertFalse($this->phoneUtil->isAlphaNumber("1 six-flags"));
3713
        $this->assertFalse($this->phoneUtil->isAlphaNumber("18 six-flags"));
3714
        $this->assertFalse($this->phoneUtil->isAlphaNumber("1800 123-1234 extension: 1234"));
3715
        $this->assertFalse($this->phoneUtil->isAlphaNumber("+800 1234-1234"));
3716
    }
3717
3718
    public function testIsMobileNumberPortableRegion()
3719
    {
3720
        $this->assertTrue($this->phoneUtil->isMobileNumberPortableRegion(RegionCode::US));
3721
        $this->assertTrue($this->phoneUtil->isMobileNumberPortableRegion(RegionCode::GB));
3722
        $this->assertFalse($this->phoneUtil->isMobileNumberPortableRegion(RegionCode::AE));
3723
        $this->assertFalse($this->phoneUtil->isMobileNumberPortableRegion(RegionCode::BS));
3724
    }
3725
}
3726