Completed
Push — upstream-8.3.0 ( 6d22b3 )
by Joshua
11:01
created

testIsNumberMatchShortMatchIfDiffNumLeadingZeros()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 16
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 16
rs 9.4285
cc 1
eloc 9
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 testGetInstanceLoadUSMetadata()
165
    {
166
        $metadata = $this->phoneUtil->getMetadataForRegion(RegionCode::US);
167
        $this->assertEquals("US", $metadata->getId());
168
        $this->assertEquals(1, $metadata->getCountryCode());
169
        $this->assertEquals("011", $metadata->getInternationalPrefix());
170
        $this->assertTrue($metadata->hasNationalPrefix());
171
        $this->assertEquals(2, $metadata->numberFormatSize());
172
        $this->assertEquals("(\\d{3})(\\d{3})(\\d{4})", $metadata->getNumberFormat(1)->getPattern());
173
        $this->assertEquals("$1 $2 $3", $metadata->getNumberFormat(1)->getFormat());
174
        $this->assertEquals("[13-689]\\d{9}|2[0-35-9]\\d{8}", $metadata->getGeneralDesc()->getNationalNumberPattern());
175
        $this->assertEquals("[13-689]\\d{9}|2[0-35-9]\\d{8}", $metadata->getFixedLine()->getNationalNumberPattern());
176
        $this->assertCount(1, $metadata->getGeneralDesc()->getPossibleLength());
177
        $possibleLength = $metadata->getGeneralDesc()->getPossibleLength();
178
        $this->assertEquals(10, $possibleLength[0]);
179
        // Possible lengths are the same as the general description, so aren't stored separately in the
180
        // toll free element as well.
181
        $this->assertCount(0, $metadata->getTollFree()->getPossibleLength());
182
        $this->assertEquals("900\\d{7}", $metadata->getPremiumRate()->getNationalNumberPattern());
183
        // No shared-cost data is available, so it should be initialised to "NA".
184
        $this->assertEquals("NA", $metadata->getSharedCost()->getNationalNumberPattern());
185
    }
186
187
    public function testGetInstanceLoadDEMetadata()
188
    {
189
        $metadata = $this->phoneUtil->getMetadataForRegion(RegionCode::DE);
190
        $this->assertEquals("DE", $metadata->getId());
191
        $this->assertEquals(49, $metadata->getCountryCode());
192
        $this->assertEquals("00", $metadata->getInternationalPrefix());
193
        $this->assertEquals("0", $metadata->getNationalPrefix());
194
        $this->assertEquals(6, $metadata->numberFormatSize());
195
        $this->assertEquals(1, $metadata->getNumberFormat(5)->leadingDigitsPatternSize());
196
        $this->assertEquals("900", $metadata->getNumberFormat(5)->getLeadingDigitsPattern(0));
197
        $this->assertEquals("(\\d{3})(\\d{3,4})(\\d{4})", $metadata->getNumberFormat(5)->getPattern());
198
        $this->assertEquals("$1 $2 $3", $metadata->getNumberFormat(5)->getFormat());
199
        $this->assertCount(2, $metadata->getGeneralDesc()->getPossibleLengthLocalOnly());
200
        $this->assertCount(8, $metadata->getGeneralDesc()->getPossibleLength());
201
        // Nothing is present for fixed-line, since it is the same as the general desc, so for
202
        // efficiency reasons we don't store an extra value.
203
        $this->assertCount(0, $metadata->getFixedLine()->getPossibleLength());
204
        $this->assertCount(2, $metadata->getMobile()->getPossibleLength());
205
206
        $this->assertEquals(
207
            "(?:[24-6]\\d{2}|3[03-9]\\d|[789](?:0[2-9]|[1-9]\\d))\\d{1,8}",
208
            $metadata->getFixedLine()->getNationalNumberPattern()
209
        );
210
        $this->assertEquals("30123456", $metadata->getFixedLine()->getExampleNumber());
211
        $this->assertContains(10, $metadata->getTollFree()->getPossibleLength());
212
        $this->assertEquals("900([135]\\d{6}|9\\d{7})", $metadata->getPremiumRate()->getNationalNumberPattern());
213
    }
214
215
    public function testGetInstanceLoadARMetadata()
216
    {
217
        $metadata = $this->phoneUtil->getMetadataForRegion(RegionCode::AR);
218
        $this->assertEquals("AR", $metadata->getId());
219
        $this->assertEquals(54, $metadata->getCountryCode());
220
        $this->assertEquals("00", $metadata->getInternationalPrefix());
221
        $this->assertEquals("0", $metadata->getNationalPrefix());
222
        $this->assertEquals("0(?:(11|343|3715)15)?", $metadata->getNationalPrefixForParsing());
223
        $this->assertEquals("9$1", $metadata->getNationalPrefixTransformRule());
224
        $this->assertEquals("$2 15 $3-$4", $metadata->getNumberFormat(2)->getFormat());
225
        $this->assertEquals("(9)(\\d{4})(\\d{2})(\\d{4})", $metadata->getNumberFormat(3)->getPattern());
226
        $this->assertEquals("(9)(\\d{4})(\\d{2})(\\d{4})", $metadata->getIntlNumberFormat(3)->getPattern());
227
        $this->assertEquals("$1 $2 $3 $4", $metadata->getIntlNumberFormat(3)->getFormat());
228
    }
229
230
    public function testGetInstanceLoadInternationalTollFreeMetadata()
231
    {
232
        $metadata = $this->phoneUtil->getMetadataForNonGeographicalRegion(800);
233
        $this->assertEquals("001", $metadata->getId());
234
        $this->assertEquals(800, $metadata->getCountryCode());
235
        $this->assertEquals("$1 $2", $metadata->getNumberFormat(0)->getFormat());
236
        $this->assertEquals("(\\d{4})(\\d{4})", $metadata->getNumberFormat(0)->getPattern());
237
        $this->assertCount(0, $metadata->getGeneralDesc()->getPossibleLengthLocalOnly());
238
        $this->assertCount(1, $metadata->getGeneralDesc()->getPossibleLength());
239
        $this->assertEquals("12345678", $metadata->getTollFree()->getExampleNumber());
240
    }
241
242
    public function testIsNumberGeographical()
243
    {
244
        $this->assertFalse($this->phoneUtil->isNumberGeographical(self::$bsMobile)); // Bahamas, mobile phone number.
245
        $this->assertTrue($this->phoneUtil->isNumberGeographical(self::$auNumber)); // Australian fixed line number.
246
        $this->assertFalse($this->phoneUtil->isNumberGeographical(self::$internationalTollFree)); // International toll
247
        // free number
248
    }
249
250
    public function testIsLeadingZeroPossible()
251
    {
252
        $this->assertTrue($this->phoneUtil->isLeadingZeroPossible(39)); // Italy
253
        $this->assertFalse($this->phoneUtil->isLeadingZeroPossible(1)); // USA
254
        $this->assertTrue($this->phoneUtil->isLeadingZeroPossible(800)); // International toll free numbers
255
        $this->assertFalse($this->phoneUtil->isLeadingZeroPossible(979)); // International premium-rate
256
        $this->assertFalse(
257
            $this->phoneUtil->isLeadingZeroPossible(888)
258
        ); // Not in metadata file, just default to false.
259
    }
260
261
    public function testGetLengthOfGeographicalAreaCode()
262
    {
263
        // Google MTV, which has area code "650".
264
        $this->assertEquals(3, $this->phoneUtil->getLengthOfGeographicalAreaCode(self::$usNumber));
265
266
        // A North America toll-free number, which has no area code.
267
        $this->assertEquals(0, $this->phoneUtil->getLengthOfGeographicalAreaCode(self::$usTollFree));
268
269
        // Google London, which has area code "20".
270
        $this->assertEquals(2, $this->phoneUtil->getLengthOfGeographicalAreaCode(self::$gbNumber));
271
272
        // A mobile number in the UK does not have an area code (by default, mobile numbers do not,
273
        // unless they have been added to our list of exceptions).
274
        $this->assertEquals(0, $this->phoneUtil->getLengthOfGeographicalAreaCode(self::$gbMobile));
275
276
        // A UK mobile phone, which has no area code.
277
        $this->assertEquals(0, $this->phoneUtil->getLengthOfGeographicalAreaCode(self::$gbMobile));
278
279
        // Google Buenos Aires, which has area code "11".
280
        $this->assertEquals(2, $this->phoneUtil->getLengthOfGeographicalAreaCode(self::$arNumber));
281
282
        // A mobile number in Argentina also has an area code.
283
        $this->assertEquals(3, $this->phoneUtil->getLengthOfGeographicalAreaCode(self::$arMobile));
284
285
        // Google Sydney, which has area code "2".
286
        $this->assertEquals(1, $this->phoneUtil->getLengthOfGeographicalAreaCode(self::$auNumber));
287
288
        // Italian numbers - there is no national prefix, but it still has an area code.
289
        $this->assertEquals(2, $this->phoneUtil->getLengthOfGeographicalAreaCode(self::$itNumber));
290
291
        // Google Singapore. Singapore has no area code and no national prefix.
292
        $this->assertEquals(0, $this->phoneUtil->getLengthOfGeographicalAreaCode(self::$sgNumber));
293
294
        // An invalid US number (1 digit shorter), which has no area code.
295
        $this->assertEquals(0, $this->phoneUtil->getLengthOfGeographicalAreaCode(self::$usShortByOneNumber));
296
297
        // An international toll free number, which has no area code.
298
        $this->assertEquals(0, $this->phoneUtil->getLengthOfGeographicalAreaCode(self::$internationalTollFree));
299
300
        // A mobile number from China is geographical, but does not have an area code.
301
        $cnMobile = new PhoneNumber();
302
        $cnMobile->setCountryCode(86)->setNationalNumber('18912341234');
303
304
        $this->assertEquals(0, $this->phoneUtil->getLengthOfGeographicalAreaCode($cnMobile));
305
    }
306
307
    public function testGetLengthOfNationalDestinationCode()
308
    {
309
        // Google MTV, which has national destination code (NDC) "650".
310
        $this->assertEquals(3, $this->phoneUtil->getLengthOfNationalDestinationCode(self::$usNumber));
311
312
        // A North America toll-free number, which has NDC "800".
313
        $this->assertEquals(3, $this->phoneUtil->getLengthOfNationalDestinationCode(self::$usTollFree));
314
315
        // Google London, which has NDC "20".
316
        $this->assertEquals(2, $this->phoneUtil->getLengthOfNationalDestinationCode(self::$gbNumber));
317
318
        // A UK mobile phone, which has NDC "7912".
319
        $this->assertEquals(4, $this->phoneUtil->getLengthOfNationalDestinationCode(self::$gbMobile));
320
321
        // Google Buenos Aires, which has NDC "11".
322
        $this->assertEquals(2, $this->phoneUtil->getLengthOfNationalDestinationCode(self::$arNumber));
323
324
        // An Argentinian mobile which has NDC "911".
325
        $this->assertEquals(3, $this->phoneUtil->getLengthOfNationalDestinationCode(self::$arMobile));
326
327
        // Google Sydney, which has NDC "2".
328
        $this->assertEquals(1, $this->phoneUtil->getLengthOfNationalDestinationCode(self::$auNumber));
329
330
        // Google Singapore, which has NDC "6521".
331
        $this->assertEquals(4, $this->phoneUtil->getLengthOfNationalDestinationCode(self::$sgNumber));
332
333
        // An invalid US number (1 digit shorter), which has no NDC.
334
        $this->assertEquals(0, $this->phoneUtil->getLengthOfNationalDestinationCode(self::$usShortByOneNumber));
335
336
        // A number containing an invalid country calling code, which shouldn't have any NDC.
337
        $number = new PhoneNumber();
338
        $number->setCountryCode(123)->setNationalNumber(6502530000);
339
        $this->assertEquals(0, $this->phoneUtil->getLengthOfNationalDestinationCode($number));
340
341
        // An international toll free number, which has NDC "1234".
342
        $this->assertEquals(4, $this->phoneUtil->getLengthOfNationalDestinationCode(self::$internationalTollFree));
343
344
        // A mobile number from China is geographical, but does not have an area code: however it still
345
        // can be considered to have a national destination code.
346
        $cnMobile= new PhoneNumber();
347
        $cnMobile->setCountryCode(86)->setNationalNumber('18912341234');
348
349
        $this->assertEquals(3, $this->phoneUtil->getLengthOfNationalDestinationCode($cnMobile));
350
    }
351
352
    public function testGetCountryMobileToken()
353
    {
354
        $this->assertEquals(
355
            "1",
356
            PhoneNumberUtil::getCountryMobileToken($this->phoneUtil->getCountryCodeForRegion(RegionCode::MX))
357
        );
358
359
        // Country calling code for Sweden, which has no mobile token.
360
        $this->assertEquals(
361
            "",
362
            PhoneNumberUtil::getCountryMobileToken($this->phoneUtil->getCountryCodeForRegion(RegionCode::SE))
363
        );
364
    }
365
366
    public function testGetNationalSignificantNumber()
367
    {
368
        $this->assertEquals("6502530000", $this->phoneUtil->getNationalSignificantNumber(self::$usNumber));
369
370
        // An Italian mobile number.
371
        $this->assertEquals("345678901", $this->phoneUtil->getNationalSignificantNumber(self::$itMobile));
372
373
        // An Italian fixed line number.
374
        $this->assertEquals("0236618300", $this->phoneUtil->getNationalSignificantNumber(self::$itNumber));
375
376
        $this->assertEquals("12345678", $this->phoneUtil->getNationalSignificantNumber(self::$internationalTollFree));
377
    }
378
379
    public function testGetExampleNumber()
380
    {
381
        $this->assertEquals(self::$deNumber, $this->phoneUtil->getExampleNumber(RegionCode::DE));
382
383
        $this->assertEquals(
384
            self::$deNumber,
385
            $this->phoneUtil->getExampleNumberForType(RegionCode::DE, PhoneNumberType::FIXED_LINE)
386
        );
387
        $this->assertEquals(null, $this->phoneUtil->getExampleNumberForType(RegionCode::DE, PhoneNumberType::MOBILE));
388
        $this->assertNotNull($this->phoneUtil->getExampleNumberForType(RegionCode::US, PhoneNumberType::FIXED_LINE));
389
        $this->assertNotNull($this->phoneUtil->getExampleNumberForType(RegionCode::US, PhoneNumberType::MOBILE));
390
        // CS is an invalid region, so we have no data for it.
391
        $this->assertNull($this->phoneUtil->getExampleNumberForType(RegionCode::CS, PhoneNumberType::MOBILE));
392
        // RegionCode 001 is reserved for supporting non-geographical country calling code. We don't
393
        // support getting an example number for it with this method.
394
        $this->assertEquals(null, $this->phoneUtil->getExampleNumber(RegionCode::UN001));
395
    }
396
397
    public function testGetExampleNumberForNonGeoEntity()
398
    {
399
        $this->assertEquals(self::$internationalTollFree, $this->phoneUtil->getExampleNumberForNonGeoEntity(800));
400
        $this->assertEquals(self::$universalPremiumRate, $this->phoneUtil->getExampleNumberForNonGeoEntity(979));
401
    }
402
403
    public function testConvertAlphaCharactersInNumber()
404
    {
405
        $input = "1800-ABC-DEF";
406
        // Alpha chars are converted to digits; everything else is left untouched.
407
        $expectedOutput = "1800-222-333";
408
        $this->assertEquals($expectedOutput, PhoneNumberUtil::convertAlphaCharactersInNumber($input));
409
    }
410
411
    public function testNormaliseRemovePunctuation()
412
    {
413
        $inputNumber = "034-56&+#2" . pack('H*', 'c2ad') . "34";
414
        $expectedOutput = "03456234";
415
        $this->assertEquals(
416
            $expectedOutput,
417
            PhoneNumberUtil::normalize($inputNumber),
418
            "Conversion did not correctly remove punctuation"
419
        );
420
    }
421
422
    public function testNormaliseReplaceAlphaCharacters()
423
    {
424
        $inputNumber = "034-I-am-HUNGRY";
425
        $expectedOutput = "034426486479";
426
        $this->assertEquals(
427
            $expectedOutput,
428
            PhoneNumberUtil::normalize($inputNumber),
429
            "Conversion did not correctly replace alpha characters"
430
        );
431
    }
432
433
    public function testNormaliseOtherDigits()
434
    {
435
        $inputNumber = "\xEF\xBC\x92" . "5\xD9\xA5" /* "25٥" */
436
        ;
437
        $expectedOutput = "255";
438
        $this->assertEquals(
439
            $expectedOutput,
440
            PhoneNumberUtil::normalize($inputNumber),
441
            "Conversion did not correctly replace non-latin digits"
442
        );
443
        // Eastern-Arabic digits.
444
        $inputNumber = "\xDB\xB5" . "2\xDB\xB0" /* "۵2۰" */
445
        ;
446
        $expectedOutput = "520";
447
        $this->assertEquals(
448
            $expectedOutput,
449
            PhoneNumberUtil::normalize($inputNumber),
450
            "Conversion did not correctly replace non-latin digits"
451
        );
452
    }
453
454
    public function testNormaliseStripAlphaCharacters()
455
    {
456
        $inputNumber = "034-56&+a#234";
457
        $expectedOutput = "03456234";
458
        $this->assertEquals(
459
            $expectedOutput,
460
            PhoneNumberUtil::normalizeDigitsOnly($inputNumber),
461
            "Conversion did not correctly remove alpha character"
462
        );
463
    }
464
465
    public function testNormaliseStripNonDiallableCharacters()
466
    {
467
        $inputNumber = "03*4-56&+1a#234";
468
        $expectedOutput = "03*456+1#234";
469
        $this->assertEquals(
470
            $expectedOutput,
471
            PhoneNumberUtil::normalizeDiallableCharsOnly($inputNumber),
472
            "Conversion did not correctly remove non-diallable characters"
473
        );
474
    }
475
476
    public function testFormatUSNumber()
477
    {
478
        $this->assertEquals("650 253 0000", $this->phoneUtil->format(self::$usNumber, PhoneNumberFormat::NATIONAL));
479
        $this->assertEquals(
480
            "+1 650 253 0000",
481
            $this->phoneUtil->format(self::$usNumber, PhoneNumberFormat::INTERNATIONAL)
482
        );
483
484
        $this->assertEquals("800 253 0000", $this->phoneUtil->format(self::$usTollFree, PhoneNumberFormat::NATIONAL));
485
        $this->assertEquals(
486
            "+1 800 253 0000",
487
            $this->phoneUtil->format(self::$usTollFree, PhoneNumberFormat::INTERNATIONAL)
488
        );
489
490
        $this->assertEquals("900 253 0000", $this->phoneUtil->format(self::$usPremium, PhoneNumberFormat::NATIONAL));
491
        $this->assertEquals(
492
            "+1 900 253 0000",
493
            $this->phoneUtil->format(self::$usPremium, PhoneNumberFormat::INTERNATIONAL)
494
        );
495
        $this->assertEquals(
496
            "tel:+1-900-253-0000",
497
            $this->phoneUtil->format(self::$usPremium, PhoneNumberFormat::RFC3966)
498
        );
499
        // Numbers with all zeros in the national number part will be formatted by using the raw_input
500
        // if that is available no matter which format is specified.
501
        $this->assertEquals(
502
            "000-000-0000",
503
            $this->phoneUtil->format(self::$usSpoofWithRawInput, PhoneNumberFormat::NATIONAL)
504
        );
505
        $this->assertEquals("0", $this->phoneUtil->format(self::$usSpoof, PhoneNumberFormat::NATIONAL));
506
    }
507
508
    public function testFormatBSNumber()
509
    {
510
        $this->assertEquals("242 365 1234", $this->phoneUtil->format(self::$bsNumber, PhoneNumberFormat::NATIONAL));
511
        $this->assertEquals(
512
            "+1 242 365 1234",
513
            $this->phoneUtil->format(self::$bsNumber, PhoneNumberFormat::INTERNATIONAL)
514
        );
515
    }
516
517
    public function testFormatGBNumber()
518
    {
519
        $this->assertEquals("(020) 7031 3000", $this->phoneUtil->format(self::$gbNumber, PhoneNumberFormat::NATIONAL));
520
        $this->assertEquals(
521
            "+44 20 7031 3000",
522
            $this->phoneUtil->format(self::$gbNumber, PhoneNumberFormat::INTERNATIONAL)
523
        );
524
525
        $this->assertEquals("(07912) 345 678", $this->phoneUtil->format(self::$gbMobile, PhoneNumberFormat::NATIONAL));
526
        $this->assertEquals(
527
            "+44 7912 345 678",
528
            $this->phoneUtil->format(self::$gbMobile, PhoneNumberFormat::INTERNATIONAL)
529
        );
530
    }
531
532
    public function testFormatDENumber()
533
    {
534
        $deNumber = new PhoneNumber();
535
        $deNumber->setCountryCode(49)->setNationalNumber(301234);
536
        $this->assertEquals("030/1234", $this->phoneUtil->format($deNumber, PhoneNumberFormat::NATIONAL));
537
        $this->assertEquals("+49 30/1234", $this->phoneUtil->format($deNumber, PhoneNumberFormat::INTERNATIONAL));
538
        $this->assertEquals("tel:+49-30-1234", $this->phoneUtil->format($deNumber, PhoneNumberFormat::RFC3966));
539
540
        $deNumber->clear();
541
        $deNumber->setCountryCode(49)->setNationalNumber(291123);
542
        $this->assertEquals("0291 123", $this->phoneUtil->format($deNumber, PhoneNumberFormat::NATIONAL));
543
        $this->assertEquals("+49 291 123", $this->phoneUtil->format($deNumber, PhoneNumberFormat::INTERNATIONAL));
544
545
        $deNumber->clear();
546
        $deNumber->setCountryCode(49)->setNationalNumber(29112345678);
547
        $this->assertEquals("0291 12345678", $this->phoneUtil->format($deNumber, PhoneNumberFormat::NATIONAL));
548
        $this->assertEquals("+49 291 12345678", $this->phoneUtil->format($deNumber, PhoneNumberFormat::INTERNATIONAL));
549
550
        $deNumber->clear();
551
        $deNumber->setCountryCode(49)->setNationalNumber(912312345);
552
        $this->assertEquals("09123 12345", $this->phoneUtil->format($deNumber, PhoneNumberFormat::NATIONAL));
553
        $this->assertEquals("+49 9123 12345", $this->phoneUtil->format($deNumber, PhoneNumberFormat::INTERNATIONAL));
554
        $deNumber->clear();
555
        $deNumber->setCountryCode(49)->setNationalNumber(80212345);
556
        $this->assertEquals("08021 2345", $this->phoneUtil->format($deNumber, PhoneNumberFormat::NATIONAL));
557
        $this->assertEquals("+49 8021 2345", $this->phoneUtil->format($deNumber, PhoneNumberFormat::INTERNATIONAL));
558
        // Note this number is correctly formatted without national prefix. Most of the numbers that
559
        // are treated as invalid numbers by the library are short numbers, and they are usually not
560
        // dialed with national prefix.
561
        $this->assertEquals("1234", $this->phoneUtil->format(self::$deShortNumber, PhoneNumberFormat::NATIONAL));
562
        $this->assertEquals(
563
            "+49 1234",
564
            $this->phoneUtil->format(self::$deShortNumber, PhoneNumberFormat::INTERNATIONAL)
565
        );
566
567
        $deNumber->clear();
568
        $deNumber->setCountryCode(49)->setNationalNumber(41341234);
569
        $this->assertEquals("04134 1234", $this->phoneUtil->format($deNumber, PhoneNumberFormat::NATIONAL));
570
    }
571
572
    public function testFormatITNumber()
573
    {
574
        $this->assertEquals("02 3661 8300", $this->phoneUtil->format(self::$itNumber, PhoneNumberFormat::NATIONAL));
575
        $this->assertEquals(
576
            "+39 02 3661 8300",
577
            $this->phoneUtil->format(self::$itNumber, PhoneNumberFormat::INTERNATIONAL)
578
        );
579
        $this->assertEquals("+390236618300", $this->phoneUtil->format(self::$itNumber, PhoneNumberFormat::E164));
580
581
        $this->assertEquals("345 678 901", $this->phoneUtil->format(self::$itMobile, PhoneNumberFormat::NATIONAL));
582
        $this->assertEquals(
583
            "+39 345 678 901",
584
            $this->phoneUtil->format(self::$itMobile, PhoneNumberFormat::INTERNATIONAL)
585
        );
586
        $this->assertEquals("+39345678901", $this->phoneUtil->format(self::$itMobile, PhoneNumberFormat::E164));
587
    }
588
589
    public function testFormatAUNumber()
590
    {
591
        $this->assertEquals("02 3661 8300", $this->phoneUtil->format(self::$auNumber, PhoneNumberFormat::NATIONAL));
592
        $this->assertEquals(
593
            "+61 2 3661 8300",
594
            $this->phoneUtil->format(self::$auNumber, PhoneNumberFormat::INTERNATIONAL)
595
        );
596
        $this->assertEquals("+61236618300", $this->phoneUtil->format(self::$auNumber, PhoneNumberFormat::E164));
597
598
        $auNumber = new PhoneNumber();
599
        $auNumber->setCountryCode(61)->setNationalNumber(1800123456);
600
        $this->assertEquals("1800 123 456", $this->phoneUtil->format($auNumber, PhoneNumberFormat::NATIONAL));
601
        $this->assertEquals("+61 1800 123 456", $this->phoneUtil->format($auNumber, PhoneNumberFormat::INTERNATIONAL));
602
        $this->assertEquals("+611800123456", $this->phoneUtil->format($auNumber, PhoneNumberFormat::E164));
603
    }
604
605
    public function testFormatARNumber()
606
    {
607
        $this->assertEquals("011 8765-4321", $this->phoneUtil->format(self::$arNumber, PhoneNumberFormat::NATIONAL));
608
        $this->assertEquals(
609
            "+54 11 8765-4321",
610
            $this->phoneUtil->format(self::$arNumber, PhoneNumberFormat::INTERNATIONAL)
611
        );
612
        $this->assertEquals("+541187654321", $this->phoneUtil->format(self::$arNumber, PhoneNumberFormat::E164));
613
614
        $this->assertEquals("011 15 8765-4321", $this->phoneUtil->format(self::$arMobile, PhoneNumberFormat::NATIONAL));
615
        $this->assertEquals(
616
            "+54 9 11 8765 4321",
617
            $this->phoneUtil->format(self::$arMobile, PhoneNumberFormat::INTERNATIONAL)
618
        );
619
        $this->assertEquals("+5491187654321", $this->phoneUtil->format(self::$arMobile, PhoneNumberFormat::E164));
620
    }
621
622
    public function testFormatMXNumber()
623
    {
624
        $this->assertEquals(
625
            "045 234 567 8900",
626
            $this->phoneUtil->format(self::$mxMobile1, PhoneNumberFormat::NATIONAL)
627
        );
628
        $this->assertEquals(
629
            "+52 1 234 567 8900",
630
            $this->phoneUtil->format(self::$mxMobile1, PhoneNumberFormat::INTERNATIONAL)
631
        );
632
        $this->assertEquals("+5212345678900", $this->phoneUtil->format(self::$mxMobile1, PhoneNumberFormat::E164));
633
634
        $this->assertEquals(
635
            "045 55 1234 5678",
636
            $this->phoneUtil->format(self::$mxMobile2, PhoneNumberFormat::NATIONAL)
637
        );
638
        $this->assertEquals(
639
            "+52 1 55 1234 5678",
640
            $this->phoneUtil->format(self::$mxMobile2, PhoneNumberFormat::INTERNATIONAL)
641
        );
642
        $this->assertEquals("+5215512345678", $this->phoneUtil->format(self::$mxMobile2, PhoneNumberFormat::E164));
643
644
        $this->assertEquals("01 33 1234 5678", $this->phoneUtil->format(self::$mxNumber1, PhoneNumberFormat::NATIONAL));
645
        $this->assertEquals(
646
            "+52 33 1234 5678",
647
            $this->phoneUtil->format(self::$mxNumber1, PhoneNumberFormat::INTERNATIONAL)
648
        );
649
        $this->assertEquals("+523312345678", $this->phoneUtil->format(self::$mxNumber1, PhoneNumberFormat::E164));
650
651
        $this->assertEquals("01 821 123 4567", $this->phoneUtil->format(self::$mxNumber2, PhoneNumberFormat::NATIONAL));
652
        $this->assertEquals(
653
            "+52 821 123 4567",
654
            $this->phoneUtil->format(self::$mxNumber2, PhoneNumberFormat::INTERNATIONAL)
655
        );
656
        $this->assertEquals("+528211234567", $this->phoneUtil->format(self::$mxNumber2, PhoneNumberFormat::E164));
657
    }
658
659
    public function testFormatOutOfCountryCallingNumber()
660
    {
661
        $this->assertEquals(
662
            "00 1 900 253 0000",
663
            $this->phoneUtil->formatOutOfCountryCallingNumber(self::$usPremium, RegionCode::DE)
664
        );
665
        $this->assertEquals(
666
            "1 650 253 0000",
667
            $this->phoneUtil->formatOutOfCountryCallingNumber(self::$usNumber, RegionCode::BS)
668
        );
669
670
        $this->assertEquals(
671
            "00 1 650 253 0000",
672
            $this->phoneUtil->formatOutOfCountryCallingNumber(self::$usNumber, RegionCode::PL)
673
        );
674
675
        $this->assertEquals(
676
            "011 44 7912 345 678",
677
            $this->phoneUtil->formatOutOfCountryCallingNumber(self::$gbMobile, RegionCode::US)
678
        );
679
680
        $this->assertEquals(
681
            "00 49 1234",
682
            $this->phoneUtil->formatOutOfCountryCallingNumber(self::$deShortNumber, RegionCode::GB)
683
        );
684
        // Note this number is correctly formatted without national prefix. Most of the numbers that
685
        // are treated as invalid numbers by the library are short numbers, and they are usually not
686
        // dialed with national prefix.
687
        $this->assertEquals(
688
            "1234",
689
            $this->phoneUtil->formatOutOfCountryCallingNumber(self::$deShortNumber, RegionCode::DE)
690
        );
691
692
        $this->assertEquals(
693
            "011 39 02 3661 8300",
694
            $this->phoneUtil->formatOutOfCountryCallingNumber(self::$itNumber, RegionCode::US)
695
        );
696
        $this->assertEquals(
697
            "02 3661 8300",
698
            $this->phoneUtil->formatOutOfCountryCallingNumber(self::$itNumber, RegionCode::IT)
699
        );
700
        $this->assertEquals(
701
            "+39 02 3661 8300",
702
            $this->phoneUtil->formatOutOfCountryCallingNumber(self::$itNumber, RegionCode::SG)
703
        );
704
705
        $this->assertEquals(
706
            "6521 8000",
707
            $this->phoneUtil->formatOutOfCountryCallingNumber(self::$sgNumber, RegionCode::SG)
708
        );
709
710
        $this->assertEquals(
711
            "011 54 9 11 8765 4321",
712
            $this->phoneUtil->formatOutOfCountryCallingNumber(self::$arMobile, RegionCode::US)
713
        );
714
        $this->assertEquals(
715
            "011 800 1234 5678",
716
            $this->phoneUtil->formatOutOfCountryCallingNumber(self::$internationalTollFree, RegionCode::US)
717
        );
718
719
        $arNumberWithExtn = new PhoneNumber();
720
        $arNumberWithExtn->mergeFrom(self::$arMobile)->setExtension("1234");
721
        $this->assertEquals(
722
            "011 54 9 11 8765 4321 ext. 1234",
723
            $this->phoneUtil->formatOutOfCountryCallingNumber($arNumberWithExtn, RegionCode::US)
724
        );
725
        $this->assertEquals(
726
            "0011 54 9 11 8765 4321 ext. 1234",
727
            $this->phoneUtil->formatOutOfCountryCallingNumber($arNumberWithExtn, RegionCode::AU)
728
        );
729
        $this->assertEquals(
730
            "011 15 8765-4321 ext. 1234",
731
            $this->phoneUtil->formatOutOfCountryCallingNumber($arNumberWithExtn, RegionCode::AR)
732
        );
733
    }
734
735
    public function testFormatOutOfCountryWithInvalidRegion()
736
    {
737
        // AQ/Antarctica isn't a valid region code for phone number formatting,
738
        // so this falls back to intl formatting.
739
        $this->assertEquals(
740
            "+1 650 253 0000",
741
            $this->phoneUtil->formatOutOfCountryCallingNumber(self::$usNumber, RegionCode::AQ)
742
        );
743
        // For region code 001, the out-of-country format always turns into the international format.
744
        $this->assertEquals(
745
            "+1 650 253 0000",
746
            $this->phoneUtil->formatOutOfCountryCallingNumber(self::$usNumber, RegionCode::UN001)
747
        );
748
    }
749
750
    public function testFormatOutOfCountryWithPreferredIntlPrefix()
751
    {
752
        // This should use 0011, since that is the preferred international prefix (both 0011 and 0012
753
        // are accepted as possible international prefixes in our test metadta.)
754
        $this->assertEquals(
755
            "0011 39 02 3661 8300",
756
            $this->phoneUtil->formatOutOfCountryCallingNumber(self::$itNumber, RegionCode::AU)
757
        );
758
    }
759
760
    public function testFormatOutOfCountryKeepingAlphaChars()
761
    {
762
        $alphaNumericNumber = new PhoneNumber();
763
        $alphaNumericNumber->setCountryCode(1)->setNationalNumber(8007493524)->setRawInput("1800 six-flag");
764
        $this->assertEquals(
765
            "0011 1 800 SIX-FLAG",
766
            $this->phoneUtil->formatOutOfCountryKeepingAlphaChars($alphaNumericNumber, RegionCode::AU)
767
        );
768
769
        $alphaNumericNumber->setRawInput("1-800-SIX-flag");
770
        $this->assertEquals(
771
            "0011 1 800-SIX-FLAG",
772
            $this->phoneUtil->formatOutOfCountryKeepingAlphaChars($alphaNumericNumber, RegionCode::AU)
773
        );
774
775
        $alphaNumericNumber->setRawInput("Call us from UK: 00 1 800 SIX-flag");
776
        $this->assertEquals(
777
            "0011 1 800 SIX-FLAG",
778
            $this->phoneUtil->formatOutOfCountryKeepingAlphaChars($alphaNumericNumber, RegionCode::AU)
779
        );
780
781
        $alphaNumericNumber->setRawInput("800 SIX-flag");
782
        $this->assertEquals(
783
            "0011 1 800 SIX-FLAG",
784
            $this->phoneUtil->formatOutOfCountryKeepingAlphaChars($alphaNumericNumber, RegionCode::AU)
785
        );
786
787
        // Formatting from within the NANPA region.
788
        $this->assertEquals(
789
            "1 800 SIX-FLAG",
790
            $this->phoneUtil->formatOutOfCountryKeepingAlphaChars($alphaNumericNumber, RegionCode::US)
791
        );
792
793
        $this->assertEquals(
794
            "1 800 SIX-FLAG",
795
            $this->phoneUtil->formatOutOfCountryKeepingAlphaChars($alphaNumericNumber, RegionCode::BS)
796
        );
797
798
        // Testing that if the raw input doesn't exist, it is formatted using
799
        // formatOutOfCountryCallingNumber.
800
        $alphaNumericNumber->clearRawInput();
801
        $this->assertEquals(
802
            "00 1 800 749 3524",
803
            $this->phoneUtil->formatOutOfCountryKeepingAlphaChars($alphaNumericNumber, RegionCode::DE)
804
        );
805
806
        // Testing AU alpha number formatted from Australia.
807
        $alphaNumericNumber->setCountryCode(61)->setNationalNumber(827493524)->setRawInput("+61 82749-FLAG");
808
        // This number should have the national prefix fixed.
809
        $this->assertEquals(
810
            "082749-FLAG",
811
            $this->phoneUtil->formatOutOfCountryKeepingAlphaChars($alphaNumericNumber, RegionCode::AU)
812
        );
813
814
        $alphaNumericNumber->setRawInput("082749-FLAG");
815
        $this->assertEquals(
816
            "082749-FLAG",
817
            $this->phoneUtil->formatOutOfCountryKeepingAlphaChars($alphaNumericNumber, RegionCode::AU)
818
        );
819
820
        $alphaNumericNumber->setNationalNumber(18007493524)->setRawInput("1-800-SIX-flag");
821
        // This number should not have the national prefix prefixed, in accordance with the override for
822
        // this specific formatting rule.
823
        $this->assertEquals(
824
            "1-800-SIX-FLAG",
825
            $this->phoneUtil->formatOutOfCountryKeepingAlphaChars($alphaNumericNumber, RegionCode::AU)
826
        );
827
828
        // The metadata should not be permanently changed, since we copied it before modifying patterns.
829
        // Here we check this.
830
        $alphaNumericNumber->setNationalNumber(1800749352);
831
        $this->assertEquals(
832
            "1800 749 352",
833
            $this->phoneUtil->formatOutOfCountryCallingNumber($alphaNumericNumber, RegionCode::AU)
834
        );
835
836
        // Testing a region with multiple international prefixes.
837
        $this->assertEquals(
838
            "+61 1-800-SIX-FLAG",
839
            $this->phoneUtil->formatOutOfCountryKeepingAlphaChars($alphaNumericNumber, RegionCode::SG)
840
        );
841
        // Testing the case of calling from a non-supported region.
842
        $this->assertEquals(
843
            "+61 1-800-SIX-FLAG",
844
            $this->phoneUtil->formatOutOfCountryKeepingAlphaChars($alphaNumericNumber, RegionCode::AQ)
845
        );
846
847
        // Testing the case with an invalid country calling code.
848
        $alphaNumericNumber->setCountryCode(0)->setNationalNumber(18007493524)->setRawInput("1-800-SIX-flag");
849
        // Uses the raw input only.
850
        $this->assertEquals(
851
            "1-800-SIX-flag",
852
            $this->phoneUtil->formatOutOfCountryKeepingAlphaChars($alphaNumericNumber, RegionCode::DE)
853
        );
854
855
        // Testing the case of an invalid alpha number.
856
        $alphaNumericNumber->setCountryCode(1)->setNationalNumber(80749)->setRawInput("180-SIX");
857
        // No country-code stripping can be done.
858
        $this->assertEquals(
859
            "00 1 180-SIX",
860
            $this->phoneUtil->formatOutOfCountryKeepingAlphaChars($alphaNumericNumber, RegionCode::DE)
861
        );
862
863
        // Testing the case of calling from a non-supported region.
864
        $alphaNumericNumber->setCountryCode(1)->setNationalNumber(80749)->setRawInput("180-SIX");
865
        // No country-code stripping can be done since the number is invalid.
866
        $this->assertEquals(
867
            "+1 180-SIX",
868
            $this->phoneUtil->formatOutOfCountryKeepingAlphaChars($alphaNumericNumber, RegionCode::AQ)
869
        );
870
    }
871
872
    public function testFormatWithCarrierCode()
873
    {
874
        // We only support this for AR in our test metadata, and only for mobile numbers starting with
875
        // certain values.
876
        $arMobile = new PhoneNumber();
877
        $arMobile->setCountryCode(54)->setNationalNumber(92234654321);
878
        $this->assertEquals("02234 65-4321", $this->phoneUtil->format($arMobile, PhoneNumberFormat::NATIONAL));
879
        // Here we force 14 as the carrier code.
880
        $this->assertEquals(
881
            "02234 14 65-4321",
882
            $this->phoneUtil->formatNationalNumberWithCarrierCode($arMobile, "14")
883
        );
884
        // Here we force the number to be shown with no carrier code.
885
        $this->assertEquals(
886
            "02234 65-4321",
887
            $this->phoneUtil->formatNationalNumberWithCarrierCode($arMobile, "")
888
        );
889
        // Here the international rule is used, so no carrier code should be present.
890
        $this->assertEquals("+5492234654321", $this->phoneUtil->format($arMobile, PhoneNumberFormat::E164));
891
        // We don't support this for the US so there should be no change.
892
        $this->assertEquals(
893
            "650 253 0000",
894
            $this->phoneUtil->formatNationalNumberWithCarrierCode(self::$usNumber, "15")
895
        );
896
897
        // Invalid country code should just get the NSN.
898
        $this->assertEquals(
899
            "12345",
900
            $this->phoneUtil->formatNationalNumberWithCarrierCode(self::$unknownCountryCodeNoRawInput, "89")
901
        );
902
    }
903
904
    public function testFormatWithPreferredCarrierCode()
905
    {
906
        // We only support this for AR in our test metadata.
907
        $arNumber = new PhoneNumber();
908
        $arNumber->setCountryCode(54)->setNationalNumber(91234125678);
909
        // Test formatting with no preferred carrier code stored in the number itself.
910
        $this->assertEquals(
911
            "01234 15 12-5678",
912
            $this->phoneUtil->formatNationalNumberWithPreferredCarrierCode($arNumber, "15")
913
        );
914
        $this->assertEquals(
915
            "01234 12-5678",
916
            $this->phoneUtil->formatNationalNumberWithPreferredCarrierCode($arNumber, "")
917
        );
918
        // Test formatting with preferred carrier code present.
919
        $arNumber->setPreferredDomesticCarrierCode("19");
920
        $this->assertEquals("01234 12-5678", $this->phoneUtil->format($arNumber, PhoneNumberFormat::NATIONAL));
921
        $this->assertEquals(
922
            "01234 19 12-5678",
923
            $this->phoneUtil->formatNationalNumberWithPreferredCarrierCode($arNumber, "15")
924
        );
925
        $this->assertEquals(
926
            "01234 19 12-5678",
927
            $this->phoneUtil->formatNationalNumberWithPreferredCarrierCode($arNumber, "")
928
        );
929
        // When the preferred_domestic_carrier_code is present (even when it is just a space), use it
930
        // instead of the default carrier code passed in.
931
        $arNumber->setPreferredDomesticCarrierCode(" ");
932
        $this->assertEquals(
933
            "01234   12-5678",
934
            $this->phoneUtil->formatNationalNumberWithPreferredCarrierCode($arNumber, "15")
935
        );
936
        // When the preferred_domestic_carrier_code is present but empty, treat it as unset and use
937
        // instead of the default carrier code passed in.
938
        $arNumber->setPreferredDomesticCarrierCode("");
939
        $this->assertEquals(
940
            "01234 15 12-5678",
941
            $this->phoneUtil->formatNationalNumberWithPreferredCarrierCode($arNumber, "15")
942
        );
943
        // We don't support this for the US so there should be no change.
944
        $usNumber = new PhoneNumber();
945
        $usNumber->setCountryCode(1)->setNationalNumber(4241231234)->setPreferredDomesticCarrierCode("99");
946
        $this->assertEquals("424 123 1234", $this->phoneUtil->format($usNumber, PhoneNumberFormat::NATIONAL));
947
        $this->assertEquals(
948
            "424 123 1234",
949
            $this->phoneUtil->formatNationalNumberWithPreferredCarrierCode($usNumber, "15")
950
        );
951
    }
952
953
    public function testFormatNumberForMobileDialing()
954
    {
955
        // Numbers are normally dialed in national format in-country, and international format from
956
        // outside the country.
957
        $this->assertEquals(
958
            "030123456",
959
            $this->phoneUtil->formatNumberForMobileDialing(self::$deNumber, RegionCode::DE, false)
960
        );
961
        $this->assertEquals(
962
            "+4930123456",
963
            $this->phoneUtil->formatNumberForMobileDialing(self::$deNumber, RegionCode::CH, false)
964
        );
965
        $this->assertEquals(
966
            "+4930123456",
967
            $this->phoneUtil->formatNumberForMobileDialing(self::$deNumber, RegionCode::CH, false)
968
        );
969
        $deNumberWithExtn = new PhoneNumber();
970
        $deNumberWithExtn->mergeFrom(self::$deNumber)->setExtension("1234");
971
        $this->assertEquals(
972
            "030123456",
973
            $this->phoneUtil->formatNumberForMobileDialing($deNumberWithExtn, RegionCode::DE, false)
974
        );
975
        $this->assertEquals(
976
            "+4930123456",
977
            $this->phoneUtil->formatNumberForMobileDialing($deNumberWithExtn, RegionCode::CH, false)
978
        );
979
980
        // US toll free numbers are marked as noInternationalDialling in the test metadata for testing
981
        // purposes. For such numbers, we expect nothing to be returned when the region code is not the
982
        // same one.
983
        $this->assertEquals(
984
            "800 253 0000",
985
            $this->phoneUtil->formatNumberForMobileDialing(
986
                self::$usTollFree,
987
                RegionCode::US,
988
                true /*  keep formatting */
989
            )
990
        );
991
        $this->assertEquals(
992
            "",
993
            $this->phoneUtil->formatNumberForMobileDialing(self::$usTollFree, RegionCode::CN, true)
994
        );
995
        $this->assertEquals(
996
            "+1 650 253 0000",
997
            $this->phoneUtil->formatNumberForMobileDialing(self::$usNumber, RegionCode::US, true)
998
        );
999
        $usNumberWithExtn = new PhoneNumber();
1000
        $usNumberWithExtn->mergeFrom(self::$usNumber)->setExtension("1234");
1001
        $this->assertEquals(
1002
            "+1 650 253 0000",
1003
            $this->phoneUtil->formatNumberForMobileDialing($usNumberWithExtn, RegionCode::US, true)
1004
        );
1005
1006
        $this->assertEquals(
1007
            "8002530000",
1008
            $this->phoneUtil->formatNumberForMobileDialing(
1009
                self::$usTollFree,
1010
                RegionCode::US,
1011
                false /* remove formatting */
1012
            )
1013
        );
1014
        $this->assertEquals(
1015
            "",
1016
            $this->phoneUtil->formatNumberForMobileDialing(self::$usTollFree, RegionCode::CN, false)
1017
        );
1018
        $this->assertEquals(
1019
            "+16502530000",
1020
            $this->phoneUtil->formatNumberForMobileDialing(self::$usNumber, RegionCode::US, false)
1021
        );
1022
        $this->assertEquals(
1023
            "+16502530000",
1024
            $this->phoneUtil->formatNumberForMobileDialing($usNumberWithExtn, RegionCode::US, false)
1025
        );
1026
1027
        // An invalid US number, which is one digit too long.
1028
        $this->assertEquals(
1029
            "+165025300001",
1030
            $this->phoneUtil->formatNumberForMobileDialing(self::$usLongNumber, RegionCode::US, false)
1031
        );
1032
        $this->assertEquals(
1033
            "+1 65025300001",
1034
            $this->phoneUtil->formatNumberForMobileDialing(self::$usLongNumber, RegionCode::US, true)
1035
        );
1036
1037
        // Star numbers. In real life they appear in Israel, but we have them in JP in our test
1038
        // metadata.
1039
        $this->assertEquals(
1040
            "*2345",
1041
            $this->phoneUtil->formatNumberForMobileDialing(self::$jpStarNumber, RegionCode::JP, false)
1042
        );
1043
        $this->assertEquals(
1044
            "*2345",
1045
            $this->phoneUtil->formatNumberForMobileDialing(self::$jpStarNumber, RegionCode::JP, true)
1046
        );
1047
1048
        $this->assertEquals(
1049
            "+80012345678",
1050
            $this->phoneUtil->formatNumberForMobileDialing(self::$internationalTollFree, RegionCode::JP, false)
1051
        );
1052
        $this->assertEquals(
1053
            "+800 1234 5678",
1054
            $this->phoneUtil->formatNumberForMobileDialing(self::$internationalTollFree, RegionCode::JP, true)
1055
        );
1056
1057
        // UAE numbers beginning with 600 (classified as UAN) need to be dialled without +971 locally.
1058
        $this->assertEquals(
1059
            "+971600123456",
1060
            $this->phoneUtil->formatNumberForMobileDialing(self::$aeUAN, RegionCode::JP, false)
1061
        );
1062
        $this->assertEquals(
1063
            "600123456",
1064
            $this->phoneUtil->formatNumberForMobileDialing(self::$aeUAN, RegionCode::AE, false)
1065
        );
1066
1067
        $this->assertEquals(
1068
            "+523312345678",
1069
            $this->phoneUtil->formatNumberForMobileDialing(self::$mxNumber1, RegionCode::MX, false)
1070
        );
1071
        $this->assertEquals(
1072
            "+523312345678",
1073
            $this->phoneUtil->formatNumberForMobileDialing(self::$mxNumber1, RegionCode::US, false)
1074
        );
1075
1076
        // Non-geographical numbers should always be dialed in international format.
1077
        $this->assertEquals(
1078
            "+80012345678",
1079
            $this->phoneUtil->formatNumberForMobileDialing(self::$internationalTollFree, RegionCode::US, false)
1080
        );
1081
        $this->assertEquals(
1082
            "+80012345678",
1083
            $this->phoneUtil->formatNumberForMobileDialing(self::$internationalTollFree, RegionCode::UN001, false)
1084
        );
1085
1086
        // Test that a short number is formatted correctly for mobile dialing within the region,
1087
        // and is not diallable from outside the region.
1088
        $deShortNumber = new PhoneNumber();
1089
        $deShortNumber->setCountryCode(49)->setNationalNumber(123);
1090
        $this->assertEquals(
1091
            "123",
1092
            $this->phoneUtil->formatNumberForMobileDialing($deShortNumber, RegionCode::DE, false)
1093
        );
1094
        $this->assertEquals("", $this->phoneUtil->formatNumberForMobileDialing($deShortNumber, RegionCode::IT, false));
1095
1096
        // Test the special logic for Hungary, where the national prefix must be added before dialing
1097
        // from a mobile phone for regular length numbers, but not for short numbers.
1098
        $huRegularNumber = new PhoneNumber();
1099
        $huRegularNumber->setCountryCode(36)->setNationalNumber(301234567);
1100
        $this->assertEquals(
1101
            "06301234567",
1102
            $this->phoneUtil->formatNumberForMobileDialing($huRegularNumber, RegionCode::HU, false)
1103
        );
1104
        $this->assertEquals(
1105
            "+36301234567",
1106
            $this->phoneUtil->formatNumberForMobileDialing($huRegularNumber, RegionCode::JP, false)
1107
        );
1108
        $huShortNumber = new PhoneNumber();
1109
        $huShortNumber->setCountryCode(36)->setNationalNumber(104);
1110
        $this->assertEquals(
1111
            "104",
1112
            $this->phoneUtil->formatNumberForMobileDialing($huShortNumber, RegionCode::HU, false)
1113
        );
1114
        $this->assertEquals("", $this->phoneUtil->formatNumberForMobileDialing($huShortNumber, RegionCode::JP, false));
1115
1116
        // Test the special logic for NANPA countries, for which regular length phone numbers are always
1117
        // output in international format, but short numbers are in national format.
1118
        $this->assertEquals(
1119
            "+16502530000",
1120
            $this->phoneUtil->formatNumberForMobileDialing(self::$usNumber, RegionCode::US, false)
1121
        );
1122
        $this->assertEquals(
1123
            "+16502530000",
1124
            $this->phoneUtil->formatNumberForMobileDialing(self::$usNumber, RegionCode::CA, false)
1125
        );
1126
        $this->assertEquals(
1127
            "+16502530000",
1128
            $this->phoneUtil->formatNumberForMobileDialing(self::$usNumber, RegionCode::BR, false)
1129
        );
1130
        $usShortNumber = new PhoneNumber();
1131
        $usShortNumber->setCountryCode(1)->setNationalNumber(911);
1132
        $this->assertEquals(
1133
            "911",
1134
            $this->phoneUtil->formatNumberForMobileDialing($usShortNumber, RegionCode::US, false)
1135
        );
1136
        $this->assertEquals("", $this->phoneUtil->formatNumberForMobileDialing($usShortNumber, RegionCode::CA, false));
1137
        $this->assertEquals("", $this->phoneUtil->formatNumberForMobileDialing($usShortNumber, RegionCode::BR, false));
1138
1139
        // Test that the Australian emergency number 000 is formatted correctly.
1140
        $auNumber = new PhoneNumber();
1141
        $auNumber->setCountryCode(61)->setNationalNumber(0)->setItalianLeadingZero(true)->setNumberOfLeadingZeros(2);
1142
        $this->assertEquals("000", $this->phoneUtil->formatNumberForMobileDialing($auNumber, RegionCode::AU, false));
1143
        $this->assertEquals("", $this->phoneUtil->formatNumberForMobileDialing($auNumber, RegionCode::NZ, false));
1144
    }
1145
1146
    public function testFormatByPattern()
1147
    {
1148
        $newNumFormat = new NumberFormat();
1149
        $newNumFormat->setPattern("(\\d{3})(\\d{3})(\\d{4})");
1150
        $newNumFormat->setFormat("($1) $2-$3");
1151
        $newNumberFormats = array();
1152
        $newNumberFormats[] = $newNumFormat;
1153
1154
        $this->assertEquals(
1155
            "(650) 253-0000",
1156
            $this->phoneUtil->formatByPattern(
1157
                self::$usNumber,
1158
                PhoneNumberFormat::NATIONAL,
1159
                $newNumberFormats
1160
            )
1161
        );
1162
        $this->assertEquals(
1163
            "+1 (650) 253-0000",
1164
            $this->phoneUtil->formatByPattern(
1165
                self::$usNumber,
1166
                PhoneNumberFormat::INTERNATIONAL,
1167
                $newNumberFormats
1168
            )
1169
        );
1170
        $this->assertEquals(
1171
            "tel:+1-650-253-0000",
1172
            $this->phoneUtil->formatByPattern(
1173
                self::$usNumber,
1174
                PhoneNumberFormat::RFC3966,
1175
                $newNumberFormats
1176
            )
1177
        );
1178
1179
        // $NP is set to '1' for the US. Here we check that for other NANPA countries the US rules are
1180
        // followed.
1181
        $newNumFormat->setNationalPrefixFormattingRule('$NP ($FG)');
1182
        $newNumFormat->setFormat("$1 $2-$3");
1183
        $this->assertEquals(
1184
            "1 (242) 365-1234",
1185
            $this->phoneUtil->formatByPattern(
1186
                self::$bsNumber,
1187
                PhoneNumberFormat::NATIONAL,
1188
                $newNumberFormats
1189
            )
1190
        );
1191
        $this->assertEquals(
1192
            "+1 242 365-1234",
1193
            $this->phoneUtil->formatByPattern(
1194
                self::$bsNumber,
1195
                PhoneNumberFormat::INTERNATIONAL,
1196
                $newNumberFormats
1197
            )
1198
        );
1199
1200
        $newNumFormat->setPattern("(\\d{2})(\\d{5})(\\d{3})");
1201
        $newNumFormat->setFormat("$1-$2 $3");
1202
        $newNumberFormats[0] = $newNumFormat;
1203
1204
        $this->assertEquals(
1205
            "02-36618 300",
1206
            $this->phoneUtil->formatByPattern(
1207
                self::$itNumber,
1208
                PhoneNumberFormat::NATIONAL,
1209
                $newNumberFormats
1210
            )
1211
        );
1212
        $this->assertEquals(
1213
            "+39 02-36618 300",
1214
            $this->phoneUtil->formatByPattern(
1215
                self::$itNumber,
1216
                PhoneNumberFormat::INTERNATIONAL,
1217
                $newNumberFormats
1218
            )
1219
        );
1220
1221
        $newNumFormat->setNationalPrefixFormattingRule('$NP$FG');
1222
        $newNumFormat->setPattern("(\\d{2})(\\d{4})(\\d{4})");
1223
        $newNumFormat->setFormat("$1 $2 $3");
1224
        $newNumberFormats[0] = $newNumFormat;
1225
        $this->assertEquals(
1226
            "020 7031 3000",
1227
            $this->phoneUtil->formatByPattern(
1228
                self::$gbNumber,
1229
                PhoneNumberFormat::NATIONAL,
1230
                $newNumberFormats
1231
            )
1232
        );
1233
1234
        $newNumFormat->setNationalPrefixFormattingRule('($NP$FG)');
1235
        $this->assertEquals(
1236
            "(020) 7031 3000",
1237
            $this->phoneUtil->formatByPattern(
1238
                self::$gbNumber,
1239
                PhoneNumberFormat::NATIONAL,
1240
                $newNumberFormats
1241
            )
1242
        );
1243
1244
        $newNumFormat->setNationalPrefixFormattingRule("");
1245
        $this->assertEquals(
1246
            "20 7031 3000",
1247
            $this->phoneUtil->formatByPattern(
1248
                self::$gbNumber,
1249
                PhoneNumberFormat::NATIONAL,
1250
                $newNumberFormats
1251
            )
1252
        );
1253
1254
        $this->assertEquals(
1255
            "+44 20 7031 3000",
1256
            $this->phoneUtil->formatByPattern(
1257
                self::$gbNumber,
1258
                PhoneNumberFormat::INTERNATIONAL,
1259
                $newNumberFormats
1260
            )
1261
        );
1262
    }
1263
1264
    public function testFormatE164Number()
1265
    {
1266
        $this->assertEquals("+16502530000", $this->phoneUtil->format(self::$usNumber, PhoneNumberFormat::E164));
1267
        $this->assertEquals("+4930123456", $this->phoneUtil->format(self::$deNumber, PhoneNumberFormat::E164));
1268
        $this->assertEquals(
1269
            "+80012345678",
1270
            $this->phoneUtil->format(self::$internationalTollFree, PhoneNumberFormat::E164)
1271
        );
1272
    }
1273
1274
    public function testFormatNumberWithExtension()
1275
    {
1276
        $nzNumber = new PhoneNumber();
1277
        $nzNumber->mergeFrom(self::$nzNumber)->setExtension("1234");
1278
        // Uses default extension prefix:
1279
        $this->assertEquals("03-331 6005 ext. 1234", $this->phoneUtil->format($nzNumber, PhoneNumberFormat::NATIONAL));
1280
        // Uses RFC 3966 syntax.
1281
        $this->assertEquals(
1282
            "tel:+64-3-331-6005;ext=1234",
1283
            $this->phoneUtil->format($nzNumber, PhoneNumberFormat::RFC3966)
1284
        );
1285
        // Extension prefix overridden in the territory information for the US:
1286
        $usNumberWithExtension = new PhoneNumber();
1287
        $usNumberWithExtension->mergeFrom(self::$usNumber)->setExtension("4567");
1288
        $this->assertEquals(
1289
            "650 253 0000 extn. 4567",
1290
            $this->phoneUtil->format($usNumberWithExtension, PhoneNumberFormat::NATIONAL)
1291
        );
1292
    }
1293
1294
    public function testFormatInOriginalFormat()
1295
    {
1296
        $number1 = $this->phoneUtil->parseAndKeepRawInput("+442087654321", RegionCode::GB);
1297
        $this->assertEquals("+44 20 8765 4321", $this->phoneUtil->formatInOriginalFormat($number1, RegionCode::GB));
1298
1299
        $number2 = $this->phoneUtil->parseAndKeepRawInput("02087654321", RegionCode::GB);
1300
        $this->assertEquals("(020) 8765 4321", $this->phoneUtil->formatInOriginalFormat($number2, RegionCode::GB));
1301
1302
        $number3 = $this->phoneUtil->parseAndKeepRawInput("011442087654321", RegionCode::US);
1303
        $this->assertEquals("011 44 20 8765 4321", $this->phoneUtil->formatInOriginalFormat($number3, RegionCode::US));
1304
1305
        $number4 = $this->phoneUtil->parseAndKeepRawInput("442087654321", RegionCode::GB);
1306
        $this->assertEquals("44 20 8765 4321", $this->phoneUtil->formatInOriginalFormat($number4, RegionCode::GB));
1307
1308
        $number5 = $this->phoneUtil->parse("+442087654321", RegionCode::GB);
1309
        $this->assertEquals("(020) 8765 4321", $this->phoneUtil->formatInOriginalFormat($number5, RegionCode::GB));
1310
1311
        // Invalid numbers that we have a formatting pattern for should be formatted properly. Note area
1312
        // codes starting with 7 are intentionally excluded in the test metadata for testing purposes.
1313
        $number6 = $this->phoneUtil->parseAndKeepRawInput("7345678901", RegionCode::US);
1314
        $this->assertEquals("734 567 8901", $this->phoneUtil->formatInOriginalFormat($number6, RegionCode::US));
1315
1316
        // US is not a leading zero country, and the presence of the leading zero leads us to format the
1317
        // number using raw_input.
1318
        $number7 = $this->phoneUtil->parseAndKeepRawInput("0734567 8901", RegionCode::US);
1319
        $this->assertEquals("0734567 8901", $this->phoneUtil->formatInOriginalFormat($number7, RegionCode::US));
1320
1321
        // This number is valid, but we don't have a formatting pattern for it. Fall back to the raw
1322
        // input.
1323
        $number8 = $this->phoneUtil->parseAndKeepRawInput("02-4567-8900", RegionCode::KR);
1324
        $this->assertEquals("02-4567-8900", $this->phoneUtil->formatInOriginalFormat($number8, RegionCode::KR));
1325
1326
        $number9 = $this->phoneUtil->parseAndKeepRawInput("01180012345678", RegionCode::US);
1327
        $this->assertEquals("011 800 1234 5678", $this->phoneUtil->formatInOriginalFormat($number9, RegionCode::US));
1328
1329
        $number10 = $this->phoneUtil->parseAndKeepRawInput("+80012345678", RegionCode::KR);
1330
        $this->assertEquals("+800 1234 5678", $this->phoneUtil->formatInOriginalFormat($number10, RegionCode::KR));
1331
1332
        // US local numbers are formatted correctly, as we have formatting patterns for them.
1333
        $localNumberUS = $this->phoneUtil->parseAndKeepRawInput("2530000", RegionCode::US);
1334
        $this->assertEquals("253 0000", $this->phoneUtil->formatInOriginalFormat($localNumberUS, RegionCode::US));
1335
1336
        $numberWithNationalPrefixUS =
1337
            $this->phoneUtil->parseAndKeepRawInput("18003456789", RegionCode::US);
1338
        $this->assertEquals(
1339
            "1 800 345 6789",
1340
            $this->phoneUtil->formatInOriginalFormat($numberWithNationalPrefixUS, RegionCode::US)
1341
        );
1342
1343
        $numberWithoutNationalPrefixGB =
1344
            $this->phoneUtil->parseAndKeepRawInput("2087654321", RegionCode::GB);
1345
        $this->assertEquals(
1346
            "20 8765 4321",
1347
            $this->phoneUtil->formatInOriginalFormat($numberWithoutNationalPrefixGB, RegionCode::GB)
1348
        );
1349
        // Make sure no metadata is modified as a result of the previous function call.
1350
        $this->assertEquals("(020) 8765 4321", $this->phoneUtil->formatInOriginalFormat($number5, RegionCode::GB));
1351
1352
        $numberWithNationalPrefixMX =
1353
            $this->phoneUtil->parseAndKeepRawInput("013312345678", RegionCode::MX);
1354
        $this->assertEquals(
1355
            "01 33 1234 5678",
1356
            $this->phoneUtil->formatInOriginalFormat($numberWithNationalPrefixMX, RegionCode::MX)
1357
        );
1358
1359
        $numberWithoutNationalPrefixMX =
1360
            $this->phoneUtil->parseAndKeepRawInput("3312345678", RegionCode::MX);
1361
        $this->assertEquals(
1362
            "33 1234 5678",
1363
            $this->phoneUtil->formatInOriginalFormat($numberWithoutNationalPrefixMX, RegionCode::MX)
1364
        );
1365
1366
        $italianFixedLineNumber =
1367
            $this->phoneUtil->parseAndKeepRawInput("0212345678", RegionCode::IT);
1368
        $this->assertEquals(
1369
            "02 1234 5678",
1370
            $this->phoneUtil->formatInOriginalFormat($italianFixedLineNumber, RegionCode::IT)
1371
        );
1372
1373
        $numberWithNationalPrefixJP =
1374
            $this->phoneUtil->parseAndKeepRawInput("00777012", RegionCode::JP);
1375
        $this->assertEquals(
1376
            "0077-7012",
1377
            $this->phoneUtil->formatInOriginalFormat($numberWithNationalPrefixJP, RegionCode::JP)
1378
        );
1379
1380
        $numberWithoutNationalPrefixJP =
1381
            $this->phoneUtil->parseAndKeepRawInput("0777012", RegionCode::JP);
1382
        $this->assertEquals(
1383
            "0777012",
1384
            $this->phoneUtil->formatInOriginalFormat($numberWithoutNationalPrefixJP, RegionCode::JP)
1385
        );
1386
1387
        $numberWithCarrierCodeBR =
1388
            $this->phoneUtil->parseAndKeepRawInput("012 3121286979", RegionCode::BR);
1389
        $this->assertEquals(
1390
            "012 3121286979",
1391
            $this->phoneUtil->formatInOriginalFormat($numberWithCarrierCodeBR, RegionCode::BR)
1392
        );
1393
1394
        // The default national prefix used in this case is 045. When a number with national prefix 044
1395
        // is entered, we return the raw input as we don't want to change the number entered.
1396
        $numberWithNationalPrefixMX1 =
1397
            $this->phoneUtil->parseAndKeepRawInput("044(33)1234-5678", RegionCode::MX);
1398
        $this->assertEquals(
1399
            "044(33)1234-5678",
1400
            $this->phoneUtil->formatInOriginalFormat($numberWithNationalPrefixMX1, RegionCode::MX)
1401
        );
1402
1403
        $numberWithNationalPrefixMX2 =
1404
            $this->phoneUtil->parseAndKeepRawInput("045(33)1234-5678", RegionCode::MX);
1405
        $this->assertEquals(
1406
            "045 33 1234 5678",
1407
            $this->phoneUtil->formatInOriginalFormat($numberWithNationalPrefixMX2, RegionCode::MX)
1408
        );
1409
1410
        // The default international prefix used in this case is 0011. When a number with international
1411
        // prefix 0012 is entered, we return the raw input as we don't want to change the number
1412
        // entered.
1413
        $outOfCountryNumberFromAU1 =
1414
            $this->phoneUtil->parseAndKeepRawInput("0012 16502530000", RegionCode::AU);
1415
        $this->assertEquals(
1416
            "0012 16502530000",
1417
            $this->phoneUtil->formatInOriginalFormat($outOfCountryNumberFromAU1, RegionCode::AU)
1418
        );
1419
1420
        $outOfCountryNumberFromAU2 =
1421
            $this->phoneUtil->parseAndKeepRawInput("0011 16502530000", RegionCode::AU);
1422
        $this->assertEquals(
1423
            "0011 1 650 253 0000",
1424
            $this->phoneUtil->formatInOriginalFormat($outOfCountryNumberFromAU2, RegionCode::AU)
1425
        );
1426
1427
        // Test the star sign is not removed from or added to the original input by this method.
1428
        $starNumber = $this->phoneUtil->parseAndKeepRawInput("*1234", RegionCode::JP);
1429
        $this->assertEquals("*1234", $this->phoneUtil->formatInOriginalFormat($starNumber, RegionCode::JP));
1430
        $numberWithoutStar = $this->phoneUtil->parseAndKeepRawInput("1234", RegionCode::JP);
1431
        $this->assertEquals("1234", $this->phoneUtil->formatInOriginalFormat($numberWithoutStar, RegionCode::JP));
1432
1433
        // Test an invalid national number without raw input is just formatted as the national number.
1434
        $this->assertEquals(
1435
            "650253000",
1436
            $this->phoneUtil->formatInOriginalFormat(self::$usShortByOneNumber, RegionCode::US)
1437
        );
1438
    }
1439
1440
    public function testIsPremiumRate()
1441
    {
1442
        $this->assertEquals(PhoneNumberType::PREMIUM_RATE, $this->phoneUtil->getNumberType(self::$usPremium));
1443
1444
        $premiumRateNumber = new PhoneNumber();
1445
        $premiumRateNumber->setCountryCode(39)->setNationalNumber(892123);
1446
        $this->assertEquals(
1447
            PhoneNumberType::PREMIUM_RATE,
1448
            $this->phoneUtil->getNumberType($premiumRateNumber)
1449
        );
1450
1451
        $premiumRateNumber->clear();
1452
        $premiumRateNumber->setCountryCode(44)->setNationalNumber(9187654321);
1453
        $this->assertEquals(
1454
            PhoneNumberType::PREMIUM_RATE,
1455
            $this->phoneUtil->getNumberType($premiumRateNumber)
1456
        );
1457
1458
        $premiumRateNumber->clear();
1459
        $premiumRateNumber->setCountryCode(49)->setNationalNumber(9001654321);
1460
        $this->assertEquals(
1461
            PhoneNumberType::PREMIUM_RATE,
1462
            $this->phoneUtil->getNumberType($premiumRateNumber)
1463
        );
1464
1465
        $premiumRateNumber->clear();
1466
        $premiumRateNumber->setCountryCode(49)->setNationalNumber(90091234567);
1467
        $this->assertEquals(
1468
            PhoneNumberType::PREMIUM_RATE,
1469
            $this->phoneUtil->getNumberType($premiumRateNumber)
1470
        );
1471
    }
1472
1473
    public function testIsTollFree()
1474
    {
1475
        $tollFreeNumber = new PhoneNumber();
1476
1477
        $tollFreeNumber->setCountryCode(1)->setNationalNumber(8881234567);
1478
        $this->assertEquals(
1479
            PhoneNumberType::TOLL_FREE,
1480
            $this->phoneUtil->getNumberType($tollFreeNumber)
1481
        );
1482
1483
        $tollFreeNumber->clear();
1484
        $tollFreeNumber->setCountryCode(39)->setNationalNumber(803123);
1485
        $this->assertEquals(
1486
            PhoneNumberType::TOLL_FREE,
1487
            $this->phoneUtil->getNumberType($tollFreeNumber)
1488
        );
1489
1490
        $tollFreeNumber->clear();
1491
        $tollFreeNumber->setCountryCode(44)->setNationalNumber(8012345678);
1492
        $this->assertEquals(
1493
            PhoneNumberType::TOLL_FREE,
1494
            $this->phoneUtil->getNumberType($tollFreeNumber)
1495
        );
1496
1497
        $tollFreeNumber->clear();
1498
        $tollFreeNumber->setCountryCode(49)->setNationalNumber(8001234567);
1499
        $this->assertEquals(
1500
            PhoneNumberType::TOLL_FREE,
1501
            $this->phoneUtil->getNumberType($tollFreeNumber)
1502
        );
1503
1504
        $this->assertEquals(
1505
            PhoneNumberType::TOLL_FREE,
1506
            $this->phoneUtil->getNumberType(self::$internationalTollFree)
1507
        );
1508
    }
1509
1510
    public function testIsMobile()
1511
    {
1512
        $this->assertEquals(PhoneNumberType::MOBILE, $this->phoneUtil->getNumberType(self::$bsMobile));
1513
        $this->assertEquals(PhoneNumberType::MOBILE, $this->phoneUtil->getNumberType(self::$gbMobile));
1514
        $this->assertEquals(PhoneNumberType::MOBILE, $this->phoneUtil->getNumberType(self::$itMobile));
1515
        $this->assertEquals(PhoneNumberType::MOBILE, $this->phoneUtil->getNumberType(self::$arMobile));
1516
1517
        $mobileNumber = new PhoneNumber();
1518
        $mobileNumber->setCountryCode(49)->setNationalNumber(15123456789);
1519
        $this->assertEquals(PhoneNumberType::MOBILE, $this->phoneUtil->getNumberType($mobileNumber));
1520
    }
1521
1522
    public function testIsFixedLine()
1523
    {
1524
        $this->assertEquals(PhoneNumberType::FIXED_LINE, $this->phoneUtil->getNumberType(self::$bsNumber));
1525
        $this->assertEquals(PhoneNumberType::FIXED_LINE, $this->phoneUtil->getNumberType(self::$itNumber));
1526
        $this->assertEquals(PhoneNumberType::FIXED_LINE, $this->phoneUtil->getNumberType(self::$gbNumber));
1527
        $this->assertEquals(PhoneNumberType::FIXED_LINE, $this->phoneUtil->getNumberType(self::$deNumber));
1528
    }
1529
1530
    public function testIsFixedLineAndMobile()
1531
    {
1532
        $this->assertEquals(PhoneNumberType::FIXED_LINE_OR_MOBILE, $this->phoneUtil->getNumberType(self::$usNumber));
1533
1534
        $fixedLineAndMobileNumber = new PhoneNumber();
1535
        $fixedLineAndMobileNumber->setCountryCode(54)->setNationalNumber(1987654321);
1536
        $this->assertEquals(
1537
            PhoneNumberType::FIXED_LINE_OR_MOBILE,
1538
            $this->phoneUtil->getNumberType($fixedLineAndMobileNumber)
1539
        );
1540
    }
1541
1542
    public function testIsSharedCost()
1543
    {
1544
        $gbNumber = new PhoneNumber();
1545
        $gbNumber->setCountryCode(44)->setNationalNumber(8431231234);
1546
        $this->assertEquals(PhoneNumberType::SHARED_COST, $this->phoneUtil->getNumberType($gbNumber));
1547
    }
1548
1549
    public function testIsVoip()
1550
    {
1551
        $gbNumber = new PhoneNumber();
1552
        $gbNumber->setCountryCode(44)->setNationalNumber(5631231234);
1553
        $this->assertEquals(PhoneNumberType::VOIP, $this->phoneUtil->getNumberType($gbNumber));
1554
    }
1555
1556
    public function testIsPersonalNumber()
1557
    {
1558
        $gbNumber = new PhoneNumber();
1559
        $gbNumber->setCountryCode(44)->setNationalNumber(7031231234);
1560
        $this->assertEquals(PhoneNumberType::PERSONAL_NUMBER, $this->phoneUtil->getNumberType($gbNumber));
1561
    }
1562
1563
    public function testIsUnknown()
1564
    {
1565
        // Invalid numbers should be of type UNKNOWN.
1566
        $this->assertEquals(PhoneNumberType::UNKNOWN, $this->phoneUtil->getNumberType(self::$usLocalNumber));
1567
    }
1568
1569
    public function testIsValidNumber()
1570
    {
1571
        $this->assertTrue($this->phoneUtil->isValidNumber(self::$usNumber));
1572
        $this->assertTrue($this->phoneUtil->isValidNumber(self::$itNumber));
1573
        $this->assertTrue($this->phoneUtil->isValidNumber(self::$gbMobile));
1574
        $this->assertTrue($this->phoneUtil->isValidNumber(self::$internationalTollFree));
1575
        $this->assertTrue($this->phoneUtil->isValidNumber(self::$universalPremiumRate));
1576
1577
        $nzNumber = new PhoneNumber();
1578
        $nzNumber->setCountryCode(64)->setNationalNumber(21387835);
1579
        $this->assertTrue($this->phoneUtil->isValidNumber($nzNumber));
1580
    }
1581
1582
    public function testIsValidForRegion()
1583
    {
1584
        // This number is valid for the Bahamas, but is not a valid US number.
1585
        $this->assertTrue($this->phoneUtil->isValidNumber(self::$bsNumber));
1586
        $this->assertTrue($this->phoneUtil->isValidNumberForRegion(self::$bsNumber, RegionCode::BS));
1587
        $this->assertFalse($this->phoneUtil->isValidNumberForRegion(self::$bsNumber, RegionCode::US));
1588
        $bsInvalidNumber = new PhoneNumber();
1589
        $bsInvalidNumber->setCountryCode(1)->setNationalNumber(2421232345);
1590
        // This number is no longer valid.
1591
        $this->assertFalse($this->phoneUtil->isValidNumber($bsInvalidNumber));
1592
1593
        // La Mayotte and Reunion use 'leadingDigits' to differentiate them.
1594
        $reNumber = new PhoneNumber();
1595
        $reNumber->setCountryCode(262)->setNationalNumber(262123456);
1596
        $this->assertTrue($this->phoneUtil->isValidNumber($reNumber));
1597
        $this->assertTrue($this->phoneUtil->isValidNumberForRegion($reNumber, RegionCode::RE));
1598
        $this->assertFalse($this->phoneUtil->isValidNumberForRegion($reNumber, RegionCode::YT));
1599
        // Now change the number to be a number for La Mayotte.
1600
        $reNumber->setNationalNumber(269601234);
1601
        $this->assertTrue($this->phoneUtil->isValidNumberForRegion($reNumber, RegionCode::YT));
1602
        $this->assertFalse($this->phoneUtil->isValidNumberForRegion($reNumber, RegionCode::RE));
1603
        // This number is no longer valid for La Reunion.
1604
        $reNumber->setNationalNumber(269123456);
1605
        $this->assertFalse($this->phoneUtil->isValidNumberForRegion($reNumber, RegionCode::YT));
1606
        $this->assertFalse($this->phoneUtil->isValidNumberForRegion($reNumber, RegionCode::RE));
1607
        $this->assertFalse($this->phoneUtil->isValidNumber($reNumber));
1608
        // However, it should be recognised as from La Mayotte, since it is valid for this region.
1609
        $this->assertEquals(RegionCode::YT, $this->phoneUtil->getRegionCodeForNumber($reNumber));
1610
        // This number is valid in both places.
1611
        $reNumber->setNationalNumber(800123456);
1612
        $this->assertTrue($this->phoneUtil->isValidNumberForRegion($reNumber, RegionCode::YT));
1613
        $this->assertTrue($this->phoneUtil->isValidNumberForRegion($reNumber, RegionCode::RE));
1614
        $this->assertTrue($this->phoneUtil->isValidNumberForRegion(self::$internationalTollFree, RegionCode::UN001));
1615
        $this->assertFalse($this->phoneUtil->isValidNumberForRegion(self::$internationalTollFree, RegionCode::US));
1616
        $this->assertFalse($this->phoneUtil->isValidNumberForRegion(self::$internationalTollFree, RegionCode::ZZ));
1617
1618
        $invalidNumber = new PhoneNumber();
1619
        // Invalid country calling codes.
1620
        $invalidNumber->setCountryCode(3923)->setNationalNumber(2366);
1621
        $this->assertFalse($this->phoneUtil->isValidNumberForRegion($invalidNumber, RegionCode::ZZ));
1622
        $this->assertFalse($this->phoneUtil->isValidNumberForRegion($invalidNumber, RegionCode::UN001));
1623
        $invalidNumber->setCountryCode(0);
1624
        $this->assertFalse($this->phoneUtil->isValidNumberForRegion($invalidNumber, RegionCode::UN001));
1625
        $this->assertFalse($this->phoneUtil->isValidNumberForRegion($invalidNumber, RegionCode::ZZ));
1626
    }
1627
1628
    public function testIsNotValidNumber()
1629
    {
1630
        $this->assertFalse($this->phoneUtil->isValidNumber(self::$usLocalNumber));
1631
1632
        $invalidNumber = new PhoneNumber();
1633
        $invalidNumber->setCountryCode(39)->setNationalNumber(23661830000)->setItalianLeadingZero(true);
1634
        $this->assertFalse($this->phoneUtil->isValidNumber($invalidNumber));
1635
1636
        $invalidNumber->clear();
1637
        $invalidNumber->setCountryCode(44)->setNationalNumber(791234567);
1638
        $this->assertFalse($this->phoneUtil->isValidNumber($invalidNumber));
1639
1640
        $invalidNumber->clear();
1641
        $invalidNumber->setCountryCode(49)->setNationalNumber(1234);
1642
        $this->assertFalse($this->phoneUtil->isValidNumber($invalidNumber));
1643
1644
        $invalidNumber->clear();
1645
        $invalidNumber->setCountryCode(64)->setNationalNumber(3316005);
1646
        $this->assertFalse($this->phoneUtil->isValidNumber($invalidNumber));
1647
1648
        $invalidNumber->clear();
1649
        // Invalid country calling codes.
1650
        $invalidNumber->setCountryCode(3923)->setNationalNumber(2366);
1651
        $this->assertFalse($this->phoneUtil->isValidNumber($invalidNumber));
1652
        $invalidNumber->setCountryCode(0);
1653
        $this->assertFalse($this->phoneUtil->isValidNumber($invalidNumber));
1654
1655
        $this->assertFalse($this->phoneUtil->isValidNumber(self::$internationalTollFreeTooLong));
1656
    }
1657
1658
    public function testGetRegionCodeForCountryCode()
1659
    {
1660
        $this->assertEquals(RegionCode::US, $this->phoneUtil->getRegionCodeForCountryCode(1));
1661
        $this->assertEquals(RegionCode::GB, $this->phoneUtil->getRegionCodeForCountryCode(44));
1662
        $this->assertEquals(RegionCode::DE, $this->phoneUtil->getRegionCodeForCountryCode(49));
1663
        $this->assertEquals(RegionCode::UN001, $this->phoneUtil->getRegionCodeForCountryCode(800));
1664
        $this->assertEquals(RegionCode::UN001, $this->phoneUtil->getRegionCodeForCountryCode(979));
1665
    }
1666
1667
    public function testGetRegionCodeForNumber()
1668
    {
1669
        $this->assertEquals(RegionCode::BS, $this->phoneUtil->getRegionCodeForNumber(self::$bsNumber));
1670
        $this->assertEquals(RegionCode::US, $this->phoneUtil->getRegionCodeForNumber(self::$usNumber));
1671
        $this->assertEquals(RegionCode::GB, $this->phoneUtil->getRegionCodeForNumber(self::$gbMobile));
1672
        $this->assertEquals(RegionCode::UN001, $this->phoneUtil->getRegionCodeForNumber(self::$internationalTollFree));
1673
        $this->assertEquals(RegionCode::UN001, $this->phoneUtil->getRegionCodeForNumber(self::$universalPremiumRate));
1674
    }
1675
1676
    public function testGetRegionCodesForCountryCode()
1677
    {
1678
        $regionCodesForNANPA = $this->phoneUtil->getRegionCodesForCountryCode(1);
1679
        $this->assertContains(RegionCode::US, $regionCodesForNANPA);
1680
        $this->assertContains(RegionCode::BS, $regionCodesForNANPA);
1681
        $this->assertContains(RegionCode::GB, $this->phoneUtil->getRegionCodesForCountryCode(44));
1682
        $this->assertContains(RegionCode::DE, $this->phoneUtil->getRegionCodesForCountryCode(49));
1683
        $this->assertContains(RegionCode::UN001, $this->phoneUtil->getRegionCodesForCountryCode(800));
1684
        // Test with invalid country calling code.
1685
        $this->assertEmpty($this->phoneUtil->getRegionCodesForCountryCode(-1));
1686
    }
1687
1688
    public function testGetCountryCodeForRegion()
1689
    {
1690
        $this->assertEquals(1, $this->phoneUtil->getCountryCodeForRegion(RegionCode::US));
1691
        $this->assertEquals(64, $this->phoneUtil->getCountryCodeForRegion(RegionCode::NZ));
1692
        $this->assertEquals(0, $this->phoneUtil->getCountryCodeForRegion(null));
1693
        $this->assertEquals(0, $this->phoneUtil->getCountryCodeForRegion(RegionCode::ZZ));
1694
        $this->assertEquals(0, $this->phoneUtil->getCountryCodeForRegion(RegionCode::UN001));
1695
        // CS is already deprecated so the library doesn't support it
1696
        $this->assertEquals(0, $this->phoneUtil->getCountryCodeForRegion(RegionCode::CS));
1697
    }
1698
1699
    public function testGetNationalDiallingPrefixForRegion()
1700
    {
1701
        $this->assertEquals("1", $this->phoneUtil->getNddPrefixForRegion(RegionCode::US, false));
1702
        // Test non-main country to see it gets the national dialling prefix for the main country with
1703
        // that country calling code.
1704
        $this->assertEquals("1", $this->phoneUtil->getNddPrefixForRegion(RegionCode::BS, false));
1705
        $this->assertEquals("0", $this->phoneUtil->getNddPrefixForRegion(RegionCode::NZ, false));
1706
        // Test case with non digit in the national prefix.
1707
        $this->assertEquals("0~0", $this->phoneUtil->getNddPrefixForRegion(RegionCode::AO, false));
1708
        $this->assertEquals("00", $this->phoneUtil->getNddPrefixForRegion(RegionCode::AO, true));
1709
        // Test cases with invalid regions.
1710
        $this->assertNull($this->phoneUtil->getNddPrefixForRegion(null, false));
1711
        $this->assertNull($this->phoneUtil->getNddPrefixForRegion(RegionCode::ZZ, false));
1712
        $this->assertNull($this->phoneUtil->getNddPrefixForRegion(RegionCode::UN001, false));
1713
        // CS is already deprecated so the library doesn't support it.
1714
        $this->assertNull($this->phoneUtil->getNddPrefixForRegion(RegionCode::CS, false));
1715
    }
1716
1717
    public function testIsNANPACountry()
1718
    {
1719
        $this->assertTrue($this->phoneUtil->isNANPACountry(RegionCode::US));
1720
        $this->assertTrue($this->phoneUtil->isNANPACountry(RegionCode::BS));
1721
        $this->assertFalse($this->phoneUtil->isNANPACountry(RegionCode::DE));
1722
        $this->assertFalse($this->phoneUtil->isNANPACountry(RegionCode::ZZ));
1723
        $this->assertFalse($this->phoneUtil->isNANPACountry(RegionCode::UN001));
1724
        $this->assertFalse($this->phoneUtil->isNANPACountry(null));
1725
    }
1726
1727
    public function testIsPossibleNumber()
1728
    {
1729
        $this->assertTrue($this->phoneUtil->isPossibleNumber(self::$usNumber));
1730
        $this->assertTrue($this->phoneUtil->isPossibleNumber(self::$usLocalNumber));
1731
        $this->assertTrue($this->phoneUtil->isPossibleNumber(self::$gbNumber));
1732
        $this->assertTrue($this->phoneUtil->isPossibleNumber(self::$internationalTollFree));
1733
1734
        $this->assertTrue($this->phoneUtil->isPossibleNumber("+1 650 253 0000", RegionCode::US));
1735
        $this->assertTrue($this->phoneUtil->isPossibleNumber("+1 650 GOO OGLE", RegionCode::US));
1736
        $this->assertTrue($this->phoneUtil->isPossibleNumber("(650) 253-0000", RegionCode::US));
1737
        $this->assertTrue($this->phoneUtil->isPossibleNumber("253-0000", RegionCode::US));
1738
        $this->assertTrue($this->phoneUtil->isPossibleNumber("+1 650 253 0000", RegionCode::GB));
1739
        $this->assertTrue($this->phoneUtil->isPossibleNumber("+44 20 7031 3000", RegionCode::GB));
1740
        $this->assertTrue($this->phoneUtil->isPossibleNumber("(020) 7031 300", RegionCode::GB));
1741
        $this->assertTrue($this->phoneUtil->isPossibleNumber("7031 3000", RegionCode::GB));
1742
        $this->assertTrue($this->phoneUtil->isPossibleNumber("3331 6005", RegionCode::NZ));
1743
        $this->assertTrue($this->phoneUtil->isPossibleNumber("+800 1234 5678", RegionCode::UN001));
1744
    }
1745
1746
    public function testIsPossibleNumberWithReason()
1747
    {
1748
        // National numbers for country calling code +1 that are within 7 to 10 digits are possible.
1749
        $this->assertEquals(
1750
            ValidationResult::IS_POSSIBLE,
1751
            $this->phoneUtil->isPossibleNumberWithReason(self::$usNumber)
1752
        );
1753
1754
        $this->assertEquals(
1755
            ValidationResult::IS_POSSIBLE,
1756
            $this->phoneUtil->isPossibleNumberWithReason(self::$usLocalNumber)
1757
        );
1758
1759
        $this->assertEquals(
1760
            ValidationResult::TOO_LONG,
1761
            $this->phoneUtil->isPossibleNumberWithReason(self::$usLongNumber)
1762
        );
1763
1764
        $number = new PhoneNumber();
1765
        $number->setCountryCode(0)->setNationalNumber(2530000);
1766
        $this->assertEquals(
1767
            ValidationResult::INVALID_COUNTRY_CODE,
1768
            $this->phoneUtil->isPossibleNumberWithReason($number)
1769
        );
1770
1771
        $number->clear();
1772
        $number->setCountryCode(1)->setNationalNumber(253000);
1773
        $this->assertEquals(ValidationResult::TOO_SHORT, $this->phoneUtil->isPossibleNumberWithReason($number));
1774
1775
        $number->clear();
1776
        $number->setCountryCode(65)->setNationalNumber(1234567890);
1777
        $this->assertEquals(ValidationResult::IS_POSSIBLE, $this->phoneUtil->isPossibleNumberWithReason($number));
1778
1779
        $this->assertEquals(
1780
            ValidationResult::TOO_LONG,
1781
            $this->phoneUtil->isPossibleNumberWithReason(self::$internationalTollFreeTooLong)
1782
        );
1783
    }
1784
1785
    public function testIsNotPossibleNumber()
1786
    {
1787
        $this->assertFalse($this->phoneUtil->isPossibleNumber(self::$usLongNumber));
1788
        $this->assertFalse($this->phoneUtil->isPossibleNumber(self::$internationalTollFreeTooLong));
1789
1790
        $number = new PhoneNumber();
1791
        $number->setCountryCode(1)->setNationalNumber(253000);
1792
        $this->assertFalse($this->phoneUtil->isPossibleNumber($number));
1793
1794
        $number->clear();
1795
        $number->setCountryCode(44)->setNationalNumber(300);
1796
        $this->assertFalse($this->phoneUtil->isPossibleNumber($number));
1797
        $this->assertFalse($this->phoneUtil->isPossibleNumber("+1 650 253 00000", RegionCode::US));
1798
        $this->assertFalse($this->phoneUtil->isPossibleNumber("(650) 253-00000", RegionCode::US));
1799
        $this->assertFalse($this->phoneUtil->isPossibleNumber("I want a Pizza", RegionCode::US));
1800
        $this->assertFalse($this->phoneUtil->isPossibleNumber("253-000", RegionCode::US));
1801
        $this->assertFalse($this->phoneUtil->isPossibleNumber("1 3000", RegionCode::GB));
1802
        $this->assertFalse($this->phoneUtil->isPossibleNumber("+44 300", RegionCode::GB));
1803
        $this->assertFalse($this->phoneUtil->isPossibleNumber("+800 1234 5678 9", RegionCode::UN001));
1804
    }
1805
1806
    public function testTruncateTooLongNumber()
1807
    {
1808
        // GB number 080 1234 5678, but entered with 4 extra digits at the end.
1809
        $tooLongNumber = new PhoneNumber();
1810
        $tooLongNumber->setCountryCode(44)->setNationalNumber(80123456780123);
1811
        $validNumber = new PhoneNumber();
1812
        $validNumber->setCountryCode(44)->setNationalNumber(8012345678);
1813
        $this->assertTrue($this->phoneUtil->truncateTooLongNumber($tooLongNumber));
1814
        $this->assertEquals($validNumber, $tooLongNumber);
1815
1816
        // IT number 022 3456 7890, but entered with 3 extra digits at the end.
1817
        $tooLongNumber->clear();
1818
        $tooLongNumber->setCountryCode(39)->setNationalNumber(2234567890123)->setItalianLeadingZero(true);
1819
        $validNumber->clear();
1820
        $validNumber->setCountryCode(39)->setNationalNumber(2234567890)->setItalianLeadingZero(true);
1821
        $this->assertTrue($this->phoneUtil->truncateTooLongNumber($tooLongNumber));
1822
        $this->assertEquals($validNumber, $tooLongNumber);
1823
1824
        // US number 650-253-0000, but entered with one additional digit at the end.
1825
        $tooLongNumber->clear();
1826
        $tooLongNumber->mergeFrom(self::$usLongNumber);
1827
        $this->assertTrue($this->phoneUtil->truncateTooLongNumber($tooLongNumber));
1828
        $this->assertEquals(self::$usNumber, $tooLongNumber);
1829
1830
        $tooLongNumber->clear();
1831
        $tooLongNumber->mergeFrom(self::$internationalTollFreeTooLong);
1832
        $this->assertTrue($this->phoneUtil->truncateTooLongNumber($tooLongNumber));
1833
        $this->assertEquals(self::$internationalTollFree, $tooLongNumber);
1834
1835
        // Tests what happens when a valid number is passed in.
1836
        $validNumberCopy = new PhoneNumber();
1837
        $validNumberCopy->mergeFrom($validNumber);
1838
        $this->assertTrue($this->phoneUtil->truncateTooLongNumber($validNumber));
1839
1840
        // Tests the number is not modified.
1841
        $this->assertEquals($validNumberCopy, $validNumber);
1842
1843
        // Tests what happens when a number with invalid prefix is passed in.
1844
        $numberWithInvalidPrefix = new PhoneNumber();
1845
        // The test metadata says US numbers cannot have prefix 240.
1846
        $numberWithInvalidPrefix->setCountryCode(1)->setNationalNumber(2401234567);
1847
        $invalidNumberCopy = new PhoneNumber();
1848
        $invalidNumberCopy->mergeFrom($numberWithInvalidPrefix);
1849
        $this->assertFalse($this->phoneUtil->truncateTooLongNumber($numberWithInvalidPrefix));
1850
        // Tests the number is not modified.
1851
        $this->assertEquals($invalidNumberCopy, $numberWithInvalidPrefix);
1852
1853
        // Tests what happens when a too short number is passed in.
1854
        $tooShortNumber = new PhoneNumber();
1855
        $tooShortNumber->setCountryCode(1)->setNationalNumber(1234);
1856
        $tooShortNumberCopy = new PhoneNumber();
1857
        $tooShortNumberCopy->mergeFrom($tooShortNumber);
1858
        $this->assertFalse($this->phoneUtil->truncateTooLongNumber($tooShortNumber));
1859
        // Tests the number is not modified.
1860
        $this->assertEquals($tooShortNumberCopy, $tooShortNumber);
1861
    }
1862
1863
    public function testIsViablePhoneNumber()
1864
    {
1865
        $this->assertFalse(PhoneNumberUtil::isViablePhoneNumber("1"));
1866
        // Only one or two digits before strange non-possible punctuation.
1867
        $this->assertFalse(PhoneNumberUtil::isViablePhoneNumber("1+1+1"));
1868
        $this->assertFalse(PhoneNumberUtil::isViablePhoneNumber("80+0"));
1869
        // Two digits is viable.
1870
        $this->assertTrue(PhoneNumberUtil::isViablePhoneNumber("00"));
1871
        $this->assertTrue(PhoneNumberUtil::isViablePhoneNumber("111"));
1872
        // Alpha numbers.
1873
        $this->assertTrue(PhoneNumberUtil::isViablePhoneNumber("0800-4-pizza"));
1874
        $this->assertTrue(PhoneNumberUtil::isViablePhoneNumber("0800-4-PIZZA"));
1875
1876
        // We need at least three digits before any alpha characters.
1877
        $this->assertFalse(PhoneNumberUtil::isViablePhoneNumber("08-PIZZA"));
1878
        $this->assertFalse(PhoneNumberUtil::isViablePhoneNumber("8-PIZZA"));
1879
        $this->assertFalse(PhoneNumberUtil::isViablePhoneNumber("12. March"));
1880
    }
1881
1882
    public function testIsViablePhoneNumberNonAscii()
1883
    {
1884
        // Only one or two digits before possible punctuation followed by more digits.
1885
        $this->assertTrue(PhoneNumberUtil::isViablePhoneNumber("1" . pack('H*', 'e38080') . "34"));
1886
        $this->assertFalse(PhoneNumberUtil::isViablePhoneNumber("1" . pack('H*', 'e38080') . "3+4"));
1887
        // Unicode variants of possible starting character and other allowed punctuation/digits.
1888
        $this->assertTrue(
1889
            PhoneNumberUtil::isViablePhoneNumber(
1890
                pack('H*', 'efbc88') . "1" . pack("H*", 'efbc89') . pack('H*', 'e38080') . "3456789"
1891
            )
1892
        );
1893
        // Testing a leading + is okay.
1894
        $this->assertTrue(
1895
            PhoneNumberUtil::isViablePhoneNumber("+1" . pack("H*", 'efbc89') . pack('H*', 'e38080') . "3456789")
1896
        );
1897
    }
1898
1899
    public function testExtractPossibleNumber()
1900
    {
1901
        // Removes preceding funky punctuation and letters but leaves the rest untouched.
1902
        $this->assertEquals("0800-345-600", PhoneNumberUtil::extractPossibleNumber("Tel:0800-345-600"));
1903
        $this->assertEquals("0800 FOR PIZZA", PhoneNumberUtil::extractPossibleNumber("Tel:0800 FOR PIZZA"));
1904
        // Should not remove plus sign
1905
        $this->assertEquals("+800-345-600", PhoneNumberUtil::extractPossibleNumber("Tel:+800-345-600"));
1906
        // Should recognise wide digits as possible start values.
1907
        $this->assertEquals(
1908
            pack("H*", 'efbc90') . pack("H*", 'efbc92') . pack("H*", 'efbc93'),
1909
            PhoneNumberUtil::extractPossibleNumber(pack("H*", 'efbc90') . pack("H*", 'efbc92') . pack("H*", 'efbc93'))
1910
        );
1911
        // Dashes are not possible start values and should be removed.
1912
        $this->assertEquals(
1913
            pack("H*", 'efbc91') . pack("H*", 'efbc92') . pack("H*", 'efbc93'),
1914
            PhoneNumberUtil::extractPossibleNumber(
1915
                "Num-" . pack("H*", 'efbc91') . pack("H*", 'efbc92') . pack("H*", 'efbc93')
1916
            )
1917
        );
1918
        // If not possible number present, return empty string.
1919
        $this->assertEquals("", PhoneNumberUtil::extractPossibleNumber("Num-...."));
1920
        // Leading brackets are stripped - these are not used when parsing.
1921
        $this->assertEquals("650) 253-0000", PhoneNumberUtil::extractPossibleNumber("(650) 253-0000"));
1922
1923
        // Trailing non-alpha-numeric characters should be removed.
1924
        $this->assertEquals("650) 253-0000", PhoneNumberUtil::extractPossibleNumber("(650) 253-0000..- .."));
1925
        $this->assertEquals("650) 253-0000", PhoneNumberUtil::extractPossibleNumber("(650) 253-0000."));
1926
        // This case has a trailing RTL char.
1927
        $this->assertEquals(
1928
            "650) 253-0000",
1929
            PhoneNumberUtil::extractPossibleNumber("(650) 253-0000" . pack("H*", 'e2808f'))
1930
        );
1931
    }
1932
1933
    public function testMaybeStripNationalPrefix()
1934
    {
1935
        $metadata = new PhoneMetadata();
1936
        $metadata->setNationalPrefixForParsing("34");
1937
        $phoneNumberDesc = new PhoneNumberDesc();
1938
        $phoneNumberDesc->setNationalNumberPattern("\\d{4,8}");
1939
        $metadata->setGeneralDesc($phoneNumberDesc);
1940
1941
        $numberToStrip = "34356778";
1942
        $strippedNumber = "356778";
1943
1944
        $carrierCode = null;
1945
1946
        $this->assertTrue(
1947
            $this->phoneUtil->maybeStripNationalPrefixAndCarrierCode($numberToStrip, $metadata, $carrierCode)
1948
        );
1949
        $this->assertEquals($strippedNumber, $numberToStrip, "Should have had national prefix stripped.");
1950
        // Retry stripping - now the number should not start with the national prefix, so no more
1951
        // stripping should occur.
1952
        $carrierCode = null;
1953
        $this->assertFalse(
1954
            $this->phoneUtil->maybeStripNationalPrefixAndCarrierCode($numberToStrip, $metadata, $carrierCode)
1955
        );
1956
        $this->assertEquals($strippedNumber, $numberToStrip, "Should have had no change - no national prefix present.");
1957
1958
        // Some countries have no national prefix. Repeat test with none specified.
1959
        $metadata->setNationalPrefixForParsing("");
1960
        $carrierCode = null;
1961
        $this->assertFalse(
1962
            $this->phoneUtil->maybeStripNationalPrefixAndCarrierCode($numberToStrip, $metadata, $carrierCode)
1963
        );
1964
        $this->assertEquals($strippedNumber, $numberToStrip, "Should not strip anything with empty national prefix.");
1965
1966
        // If the resultant number doesn't match the national rule, it shouldn't be stripped.
1967
        $metadata->setNationalPrefixForParsing("3");
1968
        $numberToStrip = "3123";
1969
        $strippedNumber = "3123";
1970
        $carrierCode = null;
1971
        $this->assertFalse(
1972
            $this->phoneUtil->maybeStripNationalPrefixAndCarrierCode($numberToStrip, $metadata, $carrierCode)
1973
        );
1974
        $this->assertEquals(
1975
            $strippedNumber,
1976
            $numberToStrip,
1977
            "Should have had no change - after stripping, it wouldn't have matched the national rule."
1978
        );
1979
1980
        // Test extracting carrier selection code.
1981
        $metadata->setNationalPrefixForParsing("0(81)?");
1982
        $numberToStrip = "08122123456";
1983
        $strippedNumber = "22123456";
1984
        $carrierCode = "";
1985
        $this->assertTrue(
1986
            $this->phoneUtil->maybeStripNationalPrefixAndCarrierCode($numberToStrip, $metadata, $carrierCode)
1987
        );
1988
        $this->assertEquals("81", $carrierCode);
1989
        $this->assertEquals(
1990
            $strippedNumber,
1991
            $numberToStrip,
1992
            "Should have had national prefix and carrier code stripped."
1993
        );
1994
1995
        // If there was a transform rule, check it was applied.
1996
        $metadata->setNationalPrefixTransformRule("5\${1}5");
1997
        // Note that a capturing group is present here.
1998
        $metadata->setNationalPrefixForParsing("0(\\d{2})");
1999
        $numberToStrip = "031123";
2000
        $transformedNumber = "5315123";
2001
        $carrierCode = null;
2002
        $this->assertTrue(
2003
            $this->phoneUtil->maybeStripNationalPrefixAndCarrierCode($numberToStrip, $metadata, $carrierCode)
2004
        );
2005
        $this->assertEquals($transformedNumber, $numberToStrip, "Should transform the 031 to a 5315.");
2006
    }
2007
2008
    public function testMaybeStripInternationalPrefix()
2009
    {
2010
        $internationalPrefix = "00[39]";
2011
        $numberToStrip = "0034567700-3898003";
2012
        // Note the dash is removed as part of the normalization.
2013
        $strippedNumber = "45677003898003";
2014
        $this->assertEquals(
2015
            CountryCodeSource::FROM_NUMBER_WITH_IDD,
2016
            $this->phoneUtil->maybeStripInternationalPrefixAndNormalize($numberToStrip, $internationalPrefix)
2017
        );
2018
        $this->assertEquals(
2019
            $strippedNumber,
2020
            $numberToStrip,
2021
            "The number supplied was not stripped of its international prefix."
2022
        );
2023
2024
        // Now the number no longer starts with an IDD prefix, so it should now report
2025
        // FROM_DEFAULT_COUNTRY.
2026
        $this->assertEquals(
2027
            CountryCodeSource::FROM_DEFAULT_COUNTRY,
2028
            $this->phoneUtil->maybeStripInternationalPrefixAndNormalize($numberToStrip, $internationalPrefix)
2029
        );
2030
2031
        $numberToStrip = "00945677003898003";
2032
        $this->assertEquals(
2033
            CountryCodeSource::FROM_NUMBER_WITH_IDD,
2034
            $this->phoneUtil->maybeStripInternationalPrefixAndNormalize($numberToStrip, $internationalPrefix)
2035
        );
2036
        $this->assertEquals(
2037
            $strippedNumber,
2038
            $numberToStrip,
2039
            "The number supplied was not stripped of its international prefix."
2040
        );
2041
2042
        // Test it works when the international prefix is broken up by spaces.
2043
        $numberToStrip = "00 9 45677003898003";
2044
        $this->assertEquals(
2045
            CountryCodeSource::FROM_NUMBER_WITH_IDD,
2046
            $this->phoneUtil->maybeStripInternationalPrefixAndNormalize($numberToStrip, $internationalPrefix)
2047
        );
2048
        $this->assertEquals(
2049
            $strippedNumber,
2050
            $numberToStrip,
2051
            "The number supplied was not stripped of its international prefix."
2052
        );
2053
2054
        // Now the number no longer starts with an IDD prefix, so it should now report
2055
        // FROM_DEFAULT_COUNTRY.
2056
        $this->assertEquals(
2057
            CountryCodeSource::FROM_DEFAULT_COUNTRY,
2058
            $this->phoneUtil->maybeStripInternationalPrefixAndNormalize($numberToStrip, $internationalPrefix)
2059
        );
2060
2061
        // Test the + symbol is also recognised and stripped.
2062
        $numberToStrip = "+45677003898003";
2063
        $strippedNumber = "45677003898003";
2064
        $this->assertEquals(
2065
            CountryCodeSource::FROM_NUMBER_WITH_PLUS_SIGN,
2066
            $this->phoneUtil->maybeStripInternationalPrefixAndNormalize($numberToStrip, $internationalPrefix)
2067
        );
2068
        $this->assertEquals(
2069
            $strippedNumber,
2070
            $numberToStrip,
2071
            "The number supplied was not stripped of the plus symbol."
2072
        );
2073
2074
        // If the number afterwards is a zero, we should not strip this - no country calling code begins
2075
        // with 0.
2076
        $numberToStrip = "0090112-3123";
2077
        $strippedNumber = "00901123123";
2078
        $this->assertEquals(
2079
            CountryCodeSource::FROM_DEFAULT_COUNTRY,
2080
            $this->phoneUtil->maybeStripInternationalPrefixAndNormalize($numberToStrip, $internationalPrefix)
2081
        );
2082
        $this->assertEquals(
2083
            $strippedNumber,
2084
            $numberToStrip,
2085
            "The number supplied had a 0 after the match so shouldn't be stripped."
2086
        );
2087
2088
        // Here the 0 is separated by a space from the IDD.
2089
        $numberToStrip = "009 0-112-3123";
2090
        $this->assertEquals(
2091
            CountryCodeSource::FROM_DEFAULT_COUNTRY,
2092
            $this->phoneUtil->maybeStripInternationalPrefixAndNormalize($numberToStrip, $internationalPrefix)
2093
        );
2094
    }
2095
2096
    public function testMaybeExtractCountryCode()
2097
    {
2098
        $number = new PhoneNumber();
2099
        $metadata = $this->phoneUtil->getMetadataForRegion(RegionCode::US);
2100
        // Note that for the US, the IDD is 011.
2101
        try {
2102
            $phoneNumber = "011112-3456789";
2103
            $strippedNumber = "123456789";
2104
            $countryCallingCode = 1;
2105
            $numberToFill = "";
2106
            $this->assertEquals(
2107
                $countryCallingCode,
2108
                $this->phoneUtil->maybeExtractCountryCode($phoneNumber, $metadata, $numberToFill, true, $number),
2109
                "Did not extract country calling code " . $countryCallingCode . " correctly."
2110
            );
2111
            $this->assertEquals(
2112
                CountryCodeSource::FROM_NUMBER_WITH_IDD,
2113
                $number->getCountryCodeSource(),
2114
                "Did not figure out CountryCodeSource correctly"
2115
            );
2116
            // Should strip and normalize national significant number.
2117
            $this->assertEquals(
2118
                $strippedNumber,
2119
                $numberToFill,
2120
                "Did not strip off the country calling code correctly."
2121
            );
2122
        } catch (NumberParseException $e) {
2123
            $this->fail("Should not have thrown an exception: " . $e->getMessage());
2124
        }
2125
        $number->clear();
2126
        try {
2127
            $phoneNumber = "+6423456789";
2128
            $countryCallingCode = 64;
2129
            $numberToFill = "";
2130
            $this->assertEquals(
2131
                $countryCallingCode,
2132
                $this->phoneUtil->maybeExtractCountryCode($phoneNumber, $metadata, $numberToFill, true, $number),
2133
                "Did not extract country calling code " . $countryCallingCode . " correctly."
2134
            );
2135
            $this->assertEquals(
2136
                CountryCodeSource::FROM_NUMBER_WITH_PLUS_SIGN,
2137
                $number->getCountryCodeSource(),
2138
                "Did not figure out CountryCodeSource correctly"
2139
            );
2140
        } catch (NumberParseException $e) {
2141
            $this->fail("Should not have thrown an exception: " . $e->getMessage());
2142
        }
2143
        $number->clear();
2144
        try {
2145
            $phoneNumber = "+80012345678";
2146
            $countryCallingCode = 800;
2147
            $numberToFill = "";
2148
            $this->assertEquals(
2149
                $countryCallingCode,
2150
                $this->phoneUtil->maybeExtractCountryCode($phoneNumber, $metadata, $numberToFill, true, $number),
2151
                "Did not extract country calling code " . $countryCallingCode . " correctly."
2152
            );
2153
            $this->assertEquals(
2154
                CountryCodeSource::FROM_NUMBER_WITH_PLUS_SIGN,
2155
                $number->getCountryCodeSource(),
2156
                "Did not figure out CountryCodeSource correctly"
2157
            );
2158
        } catch (NumberParseException $e) {
2159
            $this->fail("Should not have thrown an exception: " . $e->getMessage());
2160
        }
2161
        $number->clear();
2162
        try {
2163
            $phoneNumber = "2345-6789";
2164
            $numberToFill = "";
2165
            $this->assertEquals(
2166
                0,
2167
                $this->phoneUtil->maybeExtractCountryCode($phoneNumber, $metadata, $numberToFill, true, $number),
2168
                "Should not have extracted a country calling code - no international prefix present."
2169
            );
2170
            $this->assertEquals(
2171
                CountryCodeSource::FROM_DEFAULT_COUNTRY,
2172
                $number->getCountryCodeSource(),
2173
                "Did not figure out CountryCodeSource correctly"
2174
            );
2175
        } catch (NumberParseException $e) {
2176
            $this->fail("Should not have thrown an exception: " . $e->getMessage());
2177
        }
2178
        $number->clear();
2179
        try {
2180
            $phoneNumber = "0119991123456789";
2181
            $numberToFill = "";
2182
            $this->phoneUtil->maybeExtractCountryCode($phoneNumber, $metadata, $numberToFill, true, $number);
2183
            $this->fail("Should have thrown an exception, no valid country calling code present.");
2184
        } catch (NumberParseException $e) {
2185
            // Expected.
2186
            $this->assertEquals(
2187
                NumberParseException::INVALID_COUNTRY_CODE,
2188
                $e->getErrorType(),
2189
                "Wrong error type stored in exception."
2190
            );
2191
        }
2192
        $number->clear();
2193
        try {
2194
            $phoneNumber = "(1 610) 619 4466";
2195
            $countryCallingCode = 1;
2196
            $numberToFill = "";
2197
            $this->assertEquals(
2198
                $countryCallingCode,
2199
                $this->phoneUtil->maybeExtractCountryCode($phoneNumber, $metadata, $numberToFill, true, $number),
2200
                "Should have extracted the country calling code of the region passed in"
2201
            );
2202
            $this->assertEquals(
2203
                CountryCodeSource::FROM_NUMBER_WITHOUT_PLUS_SIGN,
2204
                $number->getCountryCodeSource(),
2205
                "Did not figure out CountryCodeSource correctly"
2206
            );
2207
        } catch (NumberParseException $e) {
2208
            $this->fail("Should not have thrown an exception: " . $e->getMessage());
2209
        }
2210
        $number->clear();
2211
        try {
2212
            $phoneNumber = "(1 610) 619 4466";
2213
            $countryCallingCode = 1;
2214
            $numberToFill = "";
2215
            $this->assertEquals(
2216
                $countryCallingCode,
2217
                $this->phoneUtil->maybeExtractCountryCode($phoneNumber, $metadata, $numberToFill, false, $number),
2218
                "Should have extracted the country calling code of the region passed in"
2219
            );
2220
            $this->assertFalse($number->hasCountryCodeSource(), "Should not contain CountryCodeSource");
2221
        } catch (NumberParseException $e) {
2222
            $this->fail("Should not have thrown an exception: " . $e->getMessage());
2223
        }
2224
        $number->clear();
2225
        try {
2226
            $phoneNumber = "(1 610) 619 446";
2227
            $numberToFill = "";
2228
            $this->assertEquals(
2229
                0,
2230
                $this->phoneUtil->maybeExtractCountryCode($phoneNumber, $metadata, $numberToFill, false, $number),
2231
                "Should not have extracted a country calling code - invalid number after extraction of uncertain country calling code."
2232
            );
2233
            $this->assertFalse($number->hasCountryCodeSource(), "Should not contain CountryCodeSource");
2234
        } catch (NumberParseException $e) {
2235
            $this->fail("Should not have thrown an exception: " . $e->getMessage());
2236
        }
2237
        $number->clear();
2238
        try {
2239
            $phoneNumber = "(1 610) 619";
2240
            $numberToFill = "";
2241
            $this->assertEquals(
2242
                0,
2243
                $this->phoneUtil->maybeExtractCountryCode($phoneNumber, $metadata, $numberToFill, true, $number),
2244
                "Should not have extracted a country calling code - too short number both before and after extraction of uncertain country calling code."
2245
            );
2246
            $this->assertEquals(
2247
                CountryCodeSource::FROM_DEFAULT_COUNTRY,
2248
                $number->getCountryCodeSource(),
2249
                "Did not figure out CountryCodeSource correctly"
2250
            );
2251
        } catch (NumberParseException $e) {
2252
            $this->fail("Should not have thrown an exception: " . $e->getMessage());
2253
        }
2254
    }
2255
2256
    public function testParseNationalNumber()
2257
    {
2258
        // National prefix attached.
2259
        $this->assertEquals(self::$nzNumber, $this->phoneUtil->parse("033316005", RegionCode::NZ));
2260
        $this->assertEquals(self::$nzNumber, $this->phoneUtil->parse("33316005", RegionCode::NZ));
2261
        // National prefix attached and some formatting present.
2262
        $this->assertEquals(self::$nzNumber, $this->phoneUtil->parse("03-331 6005", RegionCode::NZ));
2263
        $this->assertEquals(self::$nzNumber, $this->phoneUtil->parse("03 331 6005", RegionCode::NZ));
2264
2265
        // Test parsing RFC3966 format with a phone context.
2266
        $this->assertEquals(
2267
            self::$nzNumber,
2268
            $this->phoneUtil->parse("tel:03-331-6005;phone-context=+64", RegionCode::NZ)
2269
        );
2270
        $this->assertEquals(
2271
            self::$nzNumber,
2272
            $this->phoneUtil->parse("tel:331-6005;phone-context=+64-3", RegionCode::NZ)
2273
        );
2274
        $this->assertEquals(
2275
            self::$nzNumber,
2276
            $this->phoneUtil->parse("tel:331-6005;phone-context=+64-3", RegionCode::US)
2277
        );
2278
        $this->assertEquals(
2279
            self::$nzNumber,
2280
            $this->phoneUtil->parse("My number is tel:03-331-6005;phone-context=+64", RegionCode::NZ)
2281
        );
2282
        // Test parsing RFC3966 format with optional user-defined parameters. The parameters will appear
2283
        // after the context if present.
2284
        $this->assertEquals(
2285
            self::$nzNumber,
2286
            $this->phoneUtil->parse("tel:03-331-6005;phone-context=+64;a=%A1", RegionCode::NZ)
2287
        );
2288
        // Test parsing RFC3966 with an ISDN subaddress.
2289
        $this->assertEquals(
2290
            self::$nzNumber,
2291
            $this->phoneUtil->parse("tel:03-331-6005;isub=12345;phone-context=+64", RegionCode::NZ)
2292
        );
2293
        $this->assertEquals(self::$nzNumber, $this->phoneUtil->parse("tel:+64-3-331-6005;isub=12345", RegionCode::NZ));
2294
2295
        // Test parsing RFC3966 with "tel:" missing
2296
        $this->assertEquals(self::$nzNumber, $this->phoneUtil->parse("03-331-6005;phone-context=+64", RegionCode::NZ));
2297
2298
        // Testing international prefixes.
2299
        // Should strip country calling code.
2300
        $this->assertEquals(self::$nzNumber, $this->phoneUtil->parse("0064 3 331 6005", RegionCode::NZ));
2301
        // Try again, but this time we have an international number with Region Code US. It should
2302
        // recognise the country calling code and parse accordingly.
2303
        $this->assertEquals(self::$nzNumber, $this->phoneUtil->parse("01164 3 331 6005", RegionCode::US));
2304
        $this->assertEquals(self::$nzNumber, $this->phoneUtil->parse("+64 3 331 6005", RegionCode::US));
2305
        // We should ignore the leading plus here, since it is not followed by a valid country code but
2306
        // instead is followed by the IDD for the US.
2307
        $this->assertEquals(self::$nzNumber, $this->phoneUtil->parse("+01164 3 331 6005", RegionCode::US));
2308
        $this->assertEquals(self::$nzNumber, $this->phoneUtil->parse("+0064 3 331 6005", RegionCode::NZ));
2309
        $this->assertEquals(self::$nzNumber, $this->phoneUtil->parse("+ 00 64 3 331 6005", RegionCode::NZ));
2310
2311
        $this->assertEquals(
2312
            self::$usLocalNumber,
2313
            $this->phoneUtil->parse("tel:253-0000;phone-context=www.google.com", RegionCode::US)
2314
        );
2315
        $this->assertEquals(
2316
            self::$usLocalNumber,
2317
            $this->phoneUtil->parse("tel:253-0000;isub=12345;phone-context=www.google.com", RegionCode::US)
2318
        );
2319
        // This is invalid because no "+" sign is present as part of phone-context. The phone context
2320
        // is simply ignored in this case just as if it contains a domain.
2321
        $this->assertEquals(
2322
            self::$usLocalNumber,
2323
            $this->phoneUtil->parse("tel:2530000;isub=12345;phone-context=1-650", RegionCode::US)
2324
        );
2325
        $this->assertEquals(
2326
            self::$usLocalNumber,
2327
            $this->phoneUtil->parse("tel:2530000;isub=12345;phone-context=1234.com", RegionCode::US)
2328
        );
2329
2330
        $nzNumber = new PhoneNumber();
2331
        $nzNumber->setCountryCode(64)->setNationalNumber(64123456);
2332
        $this->assertEquals($nzNumber, $this->phoneUtil->parse("64(0)64123456", RegionCode::NZ));
2333
        // Check that using a "/" is fine in a phone number.
2334
        $this->assertEquals(self::$deNumber, $this->phoneUtil->parse("301/23456", RegionCode::DE));
2335
2336
        $usNumber = new PhoneNumber();
2337
        // Check it doesn't use the '1' as a country calling code when parsing if the phone number was
2338
        // already possible.
2339
        $usNumber->setCountryCode(1)->setNationalNumber(1234567890);
2340
        $this->assertEquals($usNumber, $this->phoneUtil->parse("123-456-7890", RegionCode::US));
2341
2342
        // Test star numbers. Although this is not strictly valid, we would like to make sure we can
2343
        // parse the output we produce when formatting the number.
2344
        $this->assertEquals(self::$jpStarNumber, $this->phoneUtil->parse("+81 *2345", RegionCode::JP));
2345
2346
        $shortNumber = new PhoneNumber();
2347
        $shortNumber->setCountryCode(64)->setNationalNumber(12);
2348
        $this->assertEquals($shortNumber, $this->phoneUtil->parse("12", RegionCode::NZ));
2349
    }
2350
2351
    public function testParseNumberWithAlphaCharacters()
2352
    {
2353
        // Test case with alpha characters.
2354
        $tollFreeNumber = new PhoneNumber();
2355
        $tollFreeNumber->setCountryCode(64)->setNationalNumber(800332005);
2356
        $this->assertEquals($tollFreeNumber, $this->phoneUtil->parse("0800 DDA 005", RegionCode::NZ));
2357
2358
        $premiumNumber = new PhoneNumber();
2359
        $premiumNumber->setCountryCode(64)->setNationalNumber(9003326005);
2360
        $this->assertEquals($premiumNumber, $this->phoneUtil->parse("0900 DDA 6005", RegionCode::NZ));
2361
2362
        // Not enough alpha characters for them to be considered intentional, so they are stripped.
2363
        $this->assertEquals($premiumNumber, $this->phoneUtil->parse("0900 332 6005a", RegionCode::NZ));
2364
        $this->assertEquals($premiumNumber, $this->phoneUtil->parse("0900 332 600a5", RegionCode::NZ));
2365
        $this->assertEquals($premiumNumber, $this->phoneUtil->parse("0900 332 600A5", RegionCode::NZ));
2366
        $this->assertEquals($premiumNumber, $this->phoneUtil->parse("0900 a332 600A5", RegionCode::NZ));
2367
    }
2368
2369
    public function testParseMaliciousInput()
2370
    {
2371
        // Lots of leading + signs before the possible number.
2372
        $maliciousNumber = str_repeat("+", 6000);
2373
        $maliciousNumber .= "12222-33-244 extensioB 343+";
2374
2375
        try {
2376
            $this->phoneUtil->parse($maliciousNumber, RegionCode::US);
2377
            $this->fail("This should not parse without throwing an exception " . $maliciousNumber);
2378
        } catch (NumberParseException $e) {
2379
            // Expected this exception.
2380
            $this->assertEquals(
2381
                NumberParseException::TOO_LONG,
2382
                $e->getErrorType(),
2383
                "Wrong error type stored in exception."
2384
            );
2385
        }
2386
2387
        $maliciousNumberWithAlmostExt = str_repeat("200", 350);
2388
        $maliciousNumberWithAlmostExt .= " extensiOB 345";
2389
        try {
2390
            $this->phoneUtil->parse($maliciousNumberWithAlmostExt, RegionCode::US);
2391
            $this->fail("This should not parse without throwing an exception " . $maliciousNumberWithAlmostExt);
2392
        } catch (NumberParseException $e) {
2393
            // Expected this exception.
2394
            $this->assertEquals(
2395
                NumberParseException::TOO_LONG,
2396
                $e->getErrorType(),
2397
                "Wrong error type stored in exception."
2398
            );
2399
        }
2400
    }
2401
2402
    public function testParseWithInternationalPrefixes()
2403
    {
2404
        $this->assertEquals(self::$usNumber, $this->phoneUtil->parse("+1 (650) 253-0000", RegionCode::NZ));
2405
        $this->assertEquals(self::$internationalTollFree, $this->phoneUtil->parse("011 800 1234 5678", RegionCode::US));
2406
        $this->assertEquals(self::$usNumber, $this->phoneUtil->parse("1-650-253-0000", RegionCode::US));
2407
        // Calling the US number from Singapore by using different service providers
2408
        // 1st test: calling using SingTel IDD service (IDD is 001)
2409
        $this->assertEquals(self::$usNumber, $this->phoneUtil->parse("0011-650-253-0000", RegionCode::SG));
2410
        // 2nd test: calling using StarHub IDD service (IDD is 008)
2411
        $this->assertEquals(self::$usNumber, $this->phoneUtil->parse("0081-650-253-0000", RegionCode::SG));
2412
        // 3rd test: calling using SingTel V019 service (IDD is 019)
2413
        $this->assertEquals(self::$usNumber, $this->phoneUtil->parse("0191-650-253-0000", RegionCode::SG));
2414
        // Calling the US number from Poland
2415
        $this->assertEquals(self::$usNumber, $this->phoneUtil->parse("0~01-650-253-0000", RegionCode::PL));
2416
        // Using "++" at the start.
2417
        $this->assertEquals(self::$usNumber, $this->phoneUtil->parse("++1 (650) 253-0000", RegionCode::PL));
2418
    }
2419
2420
    public function testParseNonAscii()
2421
    {
2422
        // Using a full-width plus sign.
2423
        $this->assertEquals(
2424
            self::$usNumber,
2425
            $this->phoneUtil->parse(pack("H*", 'efbc8b') . "1 (650) 253-0000", RegionCode::SG)
2426
        );
2427
        // Using a soft hyphen U+00AD.
2428
        $this->assertEquals(
2429
            self::$usNumber,
2430
            $this->phoneUtil->parse("1 (650) 253" . pack("H*", 'c2ad') . "-0000", RegionCode::US)
2431
        );
2432
        // The whole number, including punctuation, is here represented in full-width form.
2433
        $this->assertEquals(
2434
            self::$usNumber,
2435
            $this->phoneUtil->parse(
2436
                pack("H*", 'efbc8b') . pack("H*", 'efbc91') . pack("H*", 'e38080') .
2437
                pack("H*", 'efbc88') . pack("H*", 'efbc96') . pack("H*", 'efbc95') . pack("H*", 'efbc90') . pack(
2438
                    "H*",
2439
                    'efbc89'
2440
                ) .
2441
                pack("H*", 'e38080') . pack("H*", 'efbc92') . pack("H*", 'efbc95') . pack("H*", 'efbc93') . pack(
2442
                    "H*",
2443
                    'efbc8d'
2444
                ) .
2445
                pack("H*", 'efbc90') . pack("H*", 'efbc90') . pack("H*", 'efbc90') . pack("H*", 'efbc90'),
2446
                RegionCode::SG
2447
            )
2448
        );
2449
        // Using U+30FC dash instead.
2450
        $this->assertEquals(
2451
            self::$usNumber,
2452
            $this->phoneUtil->parse(
2453
                pack("H*", 'efbc8b') . pack("H*", 'efbc91') . pack("H*", 'e38080') .
2454
                pack("H*", 'efbc88') . pack("H*", 'efbc96') . pack("H*", 'efbc95') . pack("H*", 'efbc90') . pack(
2455
                    "H*",
2456
                    'efbc89'
2457
                ) .
2458
                pack("H*", 'e38080') . pack("H*", 'efbc92') . pack("H*", 'efbc95') . pack("H*", 'efbc93') . pack(
2459
                    "H*",
2460
                    'e383bc'
2461
                ) .
2462
                pack("H*", 'efbc90') . pack("H*", 'efbc90') . pack("H*", 'efbc90') . pack("H*", 'efbc90'),
2463
                RegionCode::SG
2464
            )
2465
        );
2466
        // Using a very strange decimal digit range (Mongolian digits).
2467
        $this->assertEquals(
2468
            self::$usNumber,
2469
            $this->phoneUtil->parse(
2470
                pack('H*', 'e1a091') . " "
2471
                . pack('H*', 'e1a096') . pack('H*', 'e1a095') . pack('H*', 'e1a090') . " "
2472
                . pack('H*', 'e1a092') . pack('H*', 'e1a095') . pack('H*', 'e1a093') . " "
2473
                . pack('H*', 'e1a090') . pack('H*', 'e1a090') . pack('H*', 'e1a090') . pack('H*', 'e1a090'),
2474
                RegionCode::US
2475
            )
2476
        );
2477
    }
2478
2479
    public function testParseWithLeadingZero()
2480
    {
2481
        $this->assertEquals(self::$itNumber, $this->phoneUtil->parse("+39 02-36618 300", RegionCode::NZ));
2482
        $this->assertEquals(self::$itNumber, $this->phoneUtil->parse("02-36618 300", RegionCode::IT));
2483
2484
        $this->assertEquals(self::$itMobile, $this->phoneUtil->parse("345 678 901", RegionCode::IT));
2485
    }
2486
2487
    public function testParseNationalNumberArgentina()
2488
    {
2489
        // Test parsing mobile numbers of Argentina.
2490
        $arNumber = new PhoneNumber();
2491
        $arNumber->setCountryCode(54)->setNationalNumber(93435551212);
2492
        $this->assertEquals($arNumber, $this->phoneUtil->parse("+54 9 343 555 1212", RegionCode::AR));
2493
        $this->assertEquals($arNumber, $this->phoneUtil->parse("0343 15 555 1212", RegionCode::AR));
2494
2495
        $arNumber->clear();
2496
        $arNumber->setCountryCode(54)->setNationalNumber(93715654320);
2497
        $this->assertEquals($arNumber, $this->phoneUtil->parse("+54 9 3715 65 4320", RegionCode::AR));
2498
        $this->assertEquals($arNumber, $this->phoneUtil->parse("03715 15 65 4320", RegionCode::AR));
2499
        $this->assertEquals(self::$arMobile, $this->phoneUtil->parse("911 876 54321", RegionCode::AR));
2500
2501
        // Test parsing fixed-line numbers of Argentina.
2502
        $this->assertEquals(self::$arNumber, $this->phoneUtil->parse("+54 11 8765 4321", RegionCode::AR));
2503
        $this->assertEquals(self::$arNumber, $this->phoneUtil->parse("011 8765 4321", RegionCode::AR));
2504
2505
        $arNumber->clear();
2506
        $arNumber->setCountryCode(54)->setNationalNumber(3715654321);
2507
        $this->assertEquals($arNumber, $this->phoneUtil->parse("+54 3715 65 4321", RegionCode::AR));
2508
        $this->assertEquals($arNumber, $this->phoneUtil->parse("03715 65 4321", RegionCode::AR));
2509
2510
        $arNumber->clear();
2511
        $arNumber->setCountryCode(54)->setNationalNumber(2312340000);
2512
        $this->assertEquals($arNumber, $this->phoneUtil->parse("+54 23 1234 0000", RegionCode::AR));
2513
        $this->assertEquals($arNumber, $this->phoneUtil->parse("023 1234 0000", RegionCode::AR));
2514
    }
2515
2516
    public function testParseWithXInNumber()
2517
    {
2518
        // Test that having an 'x' in the phone number at the start is ok and that it just gets removed.
2519
        $this->assertEquals(self::$arNumber, $this->phoneUtil->parse("01187654321", RegionCode::AR));
2520
        $this->assertEquals(self::$arNumber, $this->phoneUtil->parse("(0) 1187654321", RegionCode::AR));
2521
        $this->assertEquals(self::$arNumber, $this->phoneUtil->parse("0 1187654321", RegionCode::AR));
2522
        $this->assertEquals(self::$arNumber, $this->phoneUtil->parse("(0xx) 1187654321", RegionCode::AR));
2523
2524
        $arFromUs = new PhoneNumber();
2525
        $arFromUs->setCountryCode(54)->setNationalNumber(81429712);
2526
        // This test is intentionally constructed such that the number of digit after xx is larger than
2527
        // 7, so that the number won't be mistakenly treated as an extension, as we allow extensions up
2528
        // to 7 digits. This assumption is okay for now as all the countries where a carrier selection
2529
        // code is written in the form of xx have a national significant number of length larger than 7.
2530
        $this->assertEquals($arFromUs, $this->phoneUtil->parse("011xx5481429712", RegionCode::US));
2531
    }
2532
2533
    public function testParseNumbersMexico()
2534
    {
2535
        // Test parsing fixed-line numbers of Mexico.
2536
        $mxNumber = new PhoneNumber();
2537
        $mxNumber->setCountryCode(52)->setNationalNumber(4499780001);
2538
        $this->assertEquals($mxNumber, $this->phoneUtil->parse("+52 (449)978-0001", RegionCode::MX));
2539
        $this->assertEquals($mxNumber, $this->phoneUtil->parse("01 (449)978-0001", RegionCode::MX));
2540
        $this->assertEquals($mxNumber, $this->phoneUtil->parse("(449)978-0001", RegionCode::MX));
2541
2542
        // Test parsing mobile numbers of Mexico.
2543
        $mxNumber->clear();
2544
        $mxNumber->setCountryCode(52)->setNationalNumber(13312345678);
2545
        $this->assertEquals($mxNumber, $this->phoneUtil->parse("+52 1 33 1234-5678", RegionCode::MX));
2546
        $this->assertEquals($mxNumber, $this->phoneUtil->parse("044 (33) 1234-5678", RegionCode::MX));
2547
        $this->assertEquals($mxNumber, $this->phoneUtil->parse("045 33 1234-5678", RegionCode::MX));
2548
    }
2549
2550
    public function testFailedParseOnInvalidNumbers()
2551
    {
2552
        try {
2553
            $sentencePhoneNumber = "This is not a phone number";
2554
            $this->phoneUtil->parse($sentencePhoneNumber, RegionCode::NZ);
2555
            $this->fail("This should not parse without throwing an exception " . $sentencePhoneNumber);
2556
        } catch (NumberParseException $e) {
2557
            // Expected this exception.
2558
            $this->assertEquals(
2559
                NumberParseException::NOT_A_NUMBER,
2560
                $e->getErrorType(),
2561
                "Wrong error type stored in exception."
2562
            );
2563
        }
2564
2565
        try {
2566
            $sentencePhoneNumber = "1 Still not a number";
2567
            $this->phoneUtil->parse($sentencePhoneNumber, RegionCode::NZ);
2568
            $this->fail("This should not parse without throwing an exception " . $sentencePhoneNumber);
2569
        } catch (NumberParseException $e) {
2570
            // Expected this exception.
2571
            $this->assertEquals(
2572
                NumberParseException::NOT_A_NUMBER,
2573
                $e->getErrorType(),
2574
                "Wrong error type stored in exception."
2575
            );
2576
        }
2577
2578
        try {
2579
            $sentencePhoneNumber = "1 MICROSOFT";
2580
            $this->phoneUtil->parse($sentencePhoneNumber, RegionCode::NZ);
2581
            $this->fail("This should not parse without throwing an exception " . $sentencePhoneNumber);
2582
        } catch (NumberParseException $e) {
2583
            // Expected this exception.
2584
            $this->assertEquals(
2585
                NumberParseException::NOT_A_NUMBER,
2586
                $e->getErrorType(),
2587
                "Wrong error type stored in exception."
2588
            );
2589
        }
2590
2591
        try {
2592
            $sentencePhoneNumber = "12 MICROSOFT";
2593
            $this->phoneUtil->parse($sentencePhoneNumber, RegionCode::NZ);
2594
            $this->fail("This should not parse without throwing an exception " . $sentencePhoneNumber);
2595
        } catch (NumberParseException $e) {
2596
            // Expected this exception.
2597
            $this->assertEquals(
2598
                NumberParseException::NOT_A_NUMBER,
2599
                $e->getErrorType(),
2600
                "Wrong error type stored in exception."
2601
            );
2602
        }
2603
2604
        try {
2605
            $tooLongPhoneNumber = "01495 72553301873 810104";
2606
            $this->phoneUtil->parse($tooLongPhoneNumber, RegionCode::GB);
2607
            $this->fail("This should not parse without throwing an exception " . $tooLongPhoneNumber);
2608
        } catch (NumberParseException $e) {
2609
            // Expected this exception.
2610
            $this->assertEquals(
2611
                NumberParseException::TOO_LONG,
2612
                $e->getErrorType(),
2613
                "Wrong error type stored in exception."
2614
            );
2615
        }
2616
2617
        try {
2618
            $plusMinusPhoneNumber = "+---";
2619
            $this->phoneUtil->parse($plusMinusPhoneNumber, RegionCode::DE);
2620
            $this->fail("This should not parse without throwing an exception " . $plusMinusPhoneNumber);
2621
        } catch (NumberParseException $e) {
2622
            // Expected this exception.
2623
            $this->assertEquals(
2624
                NumberParseException::NOT_A_NUMBER,
2625
                $e->getErrorType(),
2626
                "Wrong error type stored in exception."
2627
            );
2628
        }
2629
2630
        try {
2631
            $plusStar = "+***";
2632
            $this->phoneUtil->parse($plusStar, RegionCode::DE);
2633
            $this->fail("This should not parse without throwing an exception " . $plusStar);
2634
        } catch (NumberParseException $e) {
2635
            // Expected this exception.
2636
            $this->assertEquals(
2637
                NumberParseException::NOT_A_NUMBER,
2638
                $e->getErrorType(),
2639
                "Wrong error type stored in exception."
2640
            );
2641
        }
2642
2643
        try {
2644
            $plusStarPhoneNumber = "+*******91";
2645
            $this->phoneUtil->parse($plusStarPhoneNumber, RegionCode::DE);
2646
            $this->fail("This should not parse without throwing an exception " . $plusStarPhoneNumber);
2647
        } catch (NumberParseException $e) {
2648
            // Expected this exception.
2649
            $this->assertEquals(
2650
                NumberParseException::NOT_A_NUMBER,
2651
                $e->getErrorType(),
2652
                "Wrong error type stored in exception."
2653
            );
2654
        }
2655
2656
        try {
2657
            $tooShortPhoneNumber = "+49 0";
2658
            $this->phoneUtil->parse($tooShortPhoneNumber, RegionCode::DE);
2659
            $this->fail("This should not parse without throwing an exception " . $tooShortPhoneNumber);
2660
        } catch (NumberParseException $e) {
2661
            // Expected this exception.
2662
            $this->assertEquals(
2663
                NumberParseException::TOO_SHORT_NSN,
2664
                $e->getErrorType(),
2665
                "Wrong error type stored in exception."
2666
            );
2667
        }
2668
2669
        try {
2670
            $invalidCountryCode = "+210 3456 56789";
2671
            $this->phoneUtil->parse($invalidCountryCode, RegionCode::NZ);
2672
            $this->fail("This is not a recognised region code: should fail: " . $invalidCountryCode);
2673
        } catch (NumberParseException $e) {
2674
            // Expected this exception.
2675
            $this->assertEquals(
2676
                NumberParseException::INVALID_COUNTRY_CODE,
2677
                $e->getErrorType(),
2678
                "Wrong error type stored in exception."
2679
            );
2680
        }
2681
2682
        try {
2683
            $plusAndIddAndInvalidCountryCode = "+ 00 210 3 331 6005";
2684
            $this->phoneUtil->parse($plusAndIddAndInvalidCountryCode, RegionCode::NZ);
2685
            $this->fail("This should not parse without throwing an exception " . $plusAndIddAndInvalidCountryCode);
2686
        } catch (NumberParseException $e) {
2687
            // Expected this exception. 00 is a correct IDD, but 210 is not a valid country code.
2688
            $this->assertEquals(
2689
                NumberParseException::INVALID_COUNTRY_CODE,
2690
                $e->getErrorType(),
2691
                "Wrong error type stored in exception."
2692
            );
2693
        }
2694
2695
        try {
2696
            $someNumber = "123 456 7890";
2697
            $this->phoneUtil->parse($someNumber, RegionCode::ZZ);
2698
            $this->fail("'Unknown' region code not allowed: should fail.");
2699
        } catch (NumberParseException $e) {
2700
            // Expected this exception.
2701
            $this->assertEquals(
2702
                NumberParseException::INVALID_COUNTRY_CODE,
2703
                $e->getErrorType(),
2704
                "Wrong error type stored in exception."
2705
            );
2706
        }
2707
2708
        try {
2709
            $someNumber = "123 456 7890";
2710
            $this->phoneUtil->parse($someNumber, RegionCode::CS);
2711
            $this->fail("Deprecated region code not allowed: should fail.");
2712
        } catch (NumberParseException $e) {
2713
            // Expected this exception.
2714
            $this->assertEquals(
2715
                NumberParseException::INVALID_COUNTRY_CODE,
2716
                $e->getErrorType(),
2717
                "Wrong error type stored in exception."
2718
            );
2719
        }
2720
2721
        try {
2722
            $someNumber = "123 456 7890";
2723
            $this->phoneUtil->parse($someNumber, null);
2724
            $this->fail("Null region code not allowed: should fail.");
2725
        } catch (NumberParseException $e) {
2726
            // Expected this exception.
2727
            $this->assertEquals(
2728
                NumberParseException::INVALID_COUNTRY_CODE,
2729
                $e->getErrorType(),
2730
                "Wrong error type stored in exception."
2731
            );
2732
        }
2733
2734
        try {
2735
            $someNumber = "0044------";
2736
            $this->phoneUtil->parse($someNumber, RegionCode::GB);
2737
            $this->fail("No number provided, only region code: should fail");
2738
        } catch (NumberParseException $e) {
2739
            // Expected this exception.
2740
            $this->assertEquals(
2741
                NumberParseException::TOO_SHORT_AFTER_IDD,
2742
                $e->getErrorType(),
2743
                "Wrong error type stored in exception."
2744
            );
2745
        }
2746
2747
        try {
2748
            $someNumber = "0044";
2749
            $this->phoneUtil->parse($someNumber, RegionCode::GB);
2750
            $this->fail("No number provided, only region code: should fail");
2751
        } catch (NumberParseException $e) {
2752
            // Expected this exception.
2753
            $this->assertEquals(
2754
                NumberParseException::TOO_SHORT_AFTER_IDD,
2755
                $e->getErrorType(),
2756
                "Wrong error type stored in exception."
2757
            );
2758
        }
2759
2760
        try {
2761
            $someNumber = "011";
2762
            $this->phoneUtil->parse($someNumber, RegionCode::US);
2763
            $this->fail("Only IDD provided - should fail.");
2764
        } catch (NumberParseException $e) {
2765
            // Expected this exception.
2766
            $this->assertEquals(
2767
                NumberParseException::TOO_SHORT_AFTER_IDD,
2768
                $e->getErrorType(),
2769
                "Wrong error type stored in exception."
2770
            );
2771
        }
2772
2773
        try {
2774
            $someNumber = "0119";
2775
            $this->phoneUtil->parse($someNumber, RegionCode::US);
2776
            $this->fail("Only IDD provided and then 9 - should fail.");
2777
        } catch (NumberParseException $e) {
2778
            // Expected this exception.
2779
            $this->assertEquals(
2780
                NumberParseException::TOO_SHORT_AFTER_IDD,
2781
                $e->getErrorType(),
2782
                "Wrong error type stored in exception."
2783
            );
2784
        }
2785
2786
        try {
2787
            $emptyNumber = "";
2788
            // Invalid region.
2789
            $this->phoneUtil->parse($emptyNumber, RegionCode::ZZ);
2790
            $this->fail("Empty string - should fail.");
2791
        } catch (NumberParseException $e) {
2792
            // Expected this exception.
2793
            $this->assertEquals(
2794
                NumberParseException::NOT_A_NUMBER,
2795
                $e->getErrorType(),
2796
                "Wrong error type stored in exception."
2797
            );
2798
        }
2799
2800
        try {
2801
            $nullNumber = null;
2802
            // Invalid region.
2803
            $this->phoneUtil->parse($nullNumber, RegionCode::ZZ);
2804
            $this->fail("Null string - should fail.");
2805
        } catch (NumberParseException $e) {
2806
            // Expected this exception.
2807
            $this->assertEquals(
2808
                NumberParseException::NOT_A_NUMBER,
2809
                $e->getErrorType(),
2810
                "Wrong error type stored in exception."
2811
            );
2812
        }
2813
2814
        try {
2815
            $nullNumber = null;
2816
            $this->phoneUtil->parse($nullNumber, RegionCode::US);
2817
            $this->fail("Null string - should fail.");
2818
        } catch (NumberParseException $e) {
2819
            // Expected this exception.
2820
            $this->assertEquals(
2821
                NumberParseException::NOT_A_NUMBER,
2822
                $e->getErrorType(),
2823
                "Wrong error type stored in exception."
2824
            );
2825
        }
2826
2827
        try {
2828
            $domainRfcPhoneContext = "tel:555-1234;phone-context=www.google.com";
2829
            $this->phoneUtil->parse($domainRfcPhoneContext, RegionCode::ZZ);
2830
            $this->fail("'Unknown' region code not allowed: should fail.");
2831
        } catch (NumberParseException $e) {
2832
            // Expected this exception.
2833
            $this->assertEquals(
2834
                NumberParseException::INVALID_COUNTRY_CODE,
2835
                $e->getErrorType(),
2836
                "Wrong error type stored in exception."
2837
            );
2838
        }
2839
2840
        try {
2841
            // This is invalid because no "+" sign is present as part of phone-context. This should not
2842
            // succeed in being parsed.
2843
            $invalidRfcPhoneContext = "tel:555-1234;phone-context=1-331";
2844
            $this->phoneUtil->parse($invalidRfcPhoneContext, RegionCode::ZZ);
2845
            $this->fail("'Unknown' region code not allowed: should fail.");
2846
        } catch (NumberParseException $e) {
2847
            // Expected this exception.
2848
            $this->assertEquals(
2849
                NumberParseException::INVALID_COUNTRY_CODE,
2850
                $e->getErrorType(),
2851
                "Wrong error type stored in exception."
2852
            );
2853
        }
2854
    }
2855
2856
    public function testParseNumbersWithPlusWithNoRegion()
2857
    {
2858
        // RegionCode.ZZ is allowed only if the number starts with a '+' - then the country calling code
2859
        // can be calculated.
2860
        $this->assertEquals(self::$nzNumber, $this->phoneUtil->parse("+64 3 331 6005", RegionCode::ZZ));
2861
        // Test with full-width plus.
2862
        $this->assertEquals(self::$nzNumber, $this->phoneUtil->parse("+64 3 331 6005", RegionCode::ZZ));
2863
        // Test with normal plus but leading characters that need to be stripped.
2864
        $this->assertEquals(self::$nzNumber, $this->phoneUtil->parse("Tel: +64 3 331 6005", RegionCode::ZZ));
2865
        $this->assertEquals(self::$nzNumber, $this->phoneUtil->parse("+64 3 331 6005", null));
2866
        $this->assertEquals(self::$internationalTollFree, $this->phoneUtil->parse("+800 1234 5678", null));
2867
        $this->assertEquals(self::$universalPremiumRate, $this->phoneUtil->parse("+979 123 456 789", null));
2868
2869
        // Test parsing RFC3966 format with a phone context.
2870
        $this->assertEquals(
2871
            self::$nzNumber,
2872
            $this->phoneUtil->parse("tel:03-331-6005;phone-context=+64", RegionCode::ZZ)
2873
        );
2874
        $this->assertEquals(
2875
            self::$nzNumber,
2876
            $this->phoneUtil->parse("  tel:03-331-6005;phone-context=+64", RegionCode::ZZ)
2877
        );
2878
        $this->assertEquals(
2879
            self::$nzNumber,
2880
            $this->phoneUtil->parse("tel:03-331-6005;isub=12345;phone-context=+64", RegionCode::ZZ)
2881
        );
2882
2883
        $nzNumberWithRawInput = new PhoneNumber();
2884
        $nzNumberWithRawInput->mergeFrom(self::$nzNumber);
2885
        $nzNumberWithRawInput->setRawInput("+64 3 331 6005");
2886
        $nzNumberWithRawInput->setCountryCodeSource(CountryCodeSource::FROM_NUMBER_WITH_PLUS_SIGN);
2887
        $this->assertEquals(
2888
            $nzNumberWithRawInput,
2889
            $this->phoneUtil->parseAndKeepRawInput("+64 3 331 6005", RegionCode::ZZ)
2890
        );
2891
2892
        // Null is also allowed for the region code in these cases.
2893
        $this->assertEquals($nzNumberWithRawInput, $this->phoneUtil->parseAndKeepRawInput("+64 3 331 6005", null));
2894
    }
2895
2896
    public function testParseNumberTooShortIfNationalPrefixStripped()
2897
    {
2898
        // Test that a number whose first digits happen to coincide with the national prefix does not
2899
        // get them stripped if doing so would result in a number too short to be a possible (regular
2900
        // length) phone number for that region.
2901
        $byNumber = new PhoneNumber();
2902
        $byNumber->setCountryCode(375)->setNationalNumber(8123);
2903
        $this->assertEquals($byNumber, $this->phoneUtil->parse("8123", RegionCode::BY));
2904
        $byNumber->setNationalNumber(81234);
2905
        $this->assertEquals($byNumber, $this->phoneUtil->parse("81234", RegionCode::BY));
2906
2907
        // The prefix doesn't get stripped, since the input is a viable 6-digit number, whereas the
2908
        // result of stripping is only 5 digits.
2909
        $byNumber->setNationalNumber(812345);
2910
        $this->assertEquals($byNumber, $this->phoneUtil->parse("812345", RegionCode::BY));
2911
2912
        // The prefix gets stripped, since only 6-digit numbers are possible.
2913
        $byNumber->setNationalNumber(123456);
2914
        $this->assertEquals($byNumber, $this->phoneUtil->parse("8123456", RegionCode::BY));
2915
    }
2916
2917
    public function testParseExtensions()
2918
    {
2919
        $nzNumber = new PhoneNumber();
2920
        $nzNumber->setCountryCode(64)->setNationalNumber(33316005)->setExtension("3456");
2921
        $this->assertEquals($nzNumber, $this->phoneUtil->parse("03 331 6005 ext 3456", RegionCode::NZ));
2922
        $this->assertEquals($nzNumber, $this->phoneUtil->parse("03-3316005x3456", RegionCode::NZ));
2923
        $this->assertEquals($nzNumber, $this->phoneUtil->parse("03-3316005 int.3456", RegionCode::NZ));
2924
        $this->assertEquals($nzNumber, $this->phoneUtil->parse("03 3316005 #3456", RegionCode::NZ));
2925
        // Test the following do not extract extensions:
2926
        $this->assertEquals(self::$alphaNumericNumber, $this->phoneUtil->parse("1800 six-flags", RegionCode::US));
2927
        $this->assertEquals(self::$alphaNumericNumber, $this->phoneUtil->parse("1800 SIX FLAGS", RegionCode::US));
2928
        $this->assertEquals(self::$alphaNumericNumber, $this->phoneUtil->parse("0~0 1800 7493 5247", RegionCode::PL));
2929
        $this->assertEquals(self::$alphaNumericNumber, $this->phoneUtil->parse("(1800) 7493.5247", RegionCode::US));
2930
        // Check that the last instance of an extension token is matched.
2931
        $extnNumber = new PhoneNumber();
2932
        $extnNumber->mergeFrom(self::$alphaNumericNumber)->setExtension("1234");
2933
        $this->assertEquals($extnNumber, $this->phoneUtil->parse("0~0 1800 7493 5247 ~1234", RegionCode::PL));
2934
        // Verifying bug-fix where the last digit of a number was previously omitted if it was a 0 when
2935
        // extracting the extension. Also verifying a few different cases of extensions.
2936
        $ukNumber = new PhoneNumber();
2937
        $ukNumber->setCountryCode(44)->setNationalNumber(2034567890)->setExtension("456");
2938
        $this->assertEquals($ukNumber, $this->phoneUtil->parse("+44 2034567890x456", RegionCode::NZ));
2939
        $this->assertEquals($ukNumber, $this->phoneUtil->parse("+44 2034567890x456", RegionCode::GB));
2940
        $this->assertEquals($ukNumber, $this->phoneUtil->parse("+44 2034567890 x456", RegionCode::GB));
2941
        $this->assertEquals($ukNumber, $this->phoneUtil->parse("+44 2034567890 X456", RegionCode::GB));
2942
        $this->assertEquals($ukNumber, $this->phoneUtil->parse("+44 2034567890 X 456", RegionCode::GB));
2943
        $this->assertEquals($ukNumber, $this->phoneUtil->parse("+44 2034567890 X  456", RegionCode::GB));
2944
        $this->assertEquals($ukNumber, $this->phoneUtil->parse("+44 2034567890 x 456  ", RegionCode::GB));
2945
        $this->assertEquals($ukNumber, $this->phoneUtil->parse("+44 2034567890  X 456", RegionCode::GB));
2946
        $this->assertEquals($ukNumber, $this->phoneUtil->parse("+44-2034567890;ext=456", RegionCode::GB));
2947
        $this->assertEquals(
2948
            $ukNumber,
2949
            $this->phoneUtil->parse("tel:2034567890;ext=456;phone-context=+44", RegionCode::ZZ)
2950
        );
2951
2952
        // Full-width extension, "extn" only.
2953
        $this->assertEquals($ukNumber, $this->phoneUtil->parse("+442034567890extn456", RegionCode::GB));
2954
        // "xtn" only.
2955
        $this->assertEquals($ukNumber, $this->phoneUtil->parse("+442034567890xtn456", RegionCode::GB));
2956
        // "xt" only.
2957
        $this->assertEquals($ukNumber, $this->phoneUtil->parse("+442034567890xt456", RegionCode::GB));
2958
2959
        $usWithExtension = new PhoneNumber();
2960
        $usWithExtension->setCountryCode(1)->setNationalNumber(8009013355)->setExtension("7246433");
2961
        $this->assertEquals($usWithExtension, $this->phoneUtil->parse("(800) 901-3355 x 7246433", RegionCode::US));
2962
        $this->assertEquals($usWithExtension, $this->phoneUtil->parse("(800) 901-3355 , ext 7246433", RegionCode::US));
2963
        $this->assertEquals($usWithExtension, $this->phoneUtil->parse("(800) 901-3355 ; 7246433", RegionCode::US));
2964
        // To test an extension character without surrounding spaces.
2965
        $this->assertEquals($usWithExtension, $this->phoneUtil->parse("(800) 901-3355;7246433", RegionCode::US));
2966
        $this->assertEquals(
2967
            $usWithExtension,
2968
            $this->phoneUtil->parse("(800) 901-3355 ,extension 7246433", RegionCode::US)
2969
        );
2970
        $this->assertEquals(
2971
            $usWithExtension,
2972
            $this->phoneUtil->parse("(800) 901-3355 ,extensi" . pack("H*", 'c3b3') . "n 7246433", RegionCode::US)
2973
        );
2974
        // Repeat with the small letter o with acute accent created by combining characters.
2975
        $this->assertEquals(
2976
            $usWithExtension,
2977
            $this->phoneUtil->parse("(800) 901-3355 ,extensio" . pack('H*', 'cc81') . "n 7246433", RegionCode::US)
2978
        );
2979
        $this->assertEquals($usWithExtension, $this->phoneUtil->parse("(800) 901-3355 , 7246433", RegionCode::US));
2980
        $this->assertEquals($usWithExtension, $this->phoneUtil->parse("(800) 901-3355 ext: 7246433", RegionCode::US));
2981
2982
        // Test that if a number has two extensions specified, we ignore the second.
2983
        $usWithTwoExtensionsNumber = new PhoneNumber();
2984
        $usWithTwoExtensionsNumber->setCountryCode(1)->setNationalNumber(2121231234)->setExtension("508");
2985
        $this->assertEquals(
2986
            $usWithTwoExtensionsNumber,
2987
            $this->phoneUtil->parse("(212)123-1234 x508/x1234", RegionCode::US)
2988
        );
2989
        $this->assertEquals(
2990
            $usWithTwoExtensionsNumber,
2991
            $this->phoneUtil->parse("(212)123-1234 x508/ x1234", RegionCode::US)
2992
        );
2993
        $this->assertEquals(
2994
            $usWithTwoExtensionsNumber,
2995
            $this->phoneUtil->parse("(212)123-1234 x508\\x1234", RegionCode::US)
2996
        );
2997
2998
        // Test parsing numbers in the form (645) 123-1234-910# works, where the last 3 digits before
2999
        // the # are an extension.
3000
        $usWithExtension->clear();
3001
        $usWithExtension->setCountryCode(1)->setNationalNumber(6451231234)->setExtension("910");
3002
        $this->assertEquals($usWithExtension, $this->phoneUtil->parse("+1 (645) 123 1234-910#", RegionCode::US));
3003
        // Retry with the same number in a slightly different format.
3004
        $this->assertEquals($usWithExtension, $this->phoneUtil->parse("+1 (645) 123 1234 ext. 910#", RegionCode::US));
3005
    }
3006
3007
    public function testParseAndKeepRaw()
3008
    {
3009
        $alphaNumericNumber = new PhoneNumber();
3010
        $alphaNumericNumber->mergeFrom(self::$alphaNumericNumber);
3011
        $alphaNumericNumber->setRawInput("800 six-flags");
3012
        $alphaNumericNumber->setCountryCodeSource(CountryCodeSource::FROM_DEFAULT_COUNTRY);
3013
        $this->assertEquals(
3014
            $alphaNumericNumber,
3015
            $this->phoneUtil->parseAndKeepRawInput("800 six-flags", RegionCode::US)
3016
        );
3017
3018
        $shorterAlphaNumber = new PhoneNumber();
3019
        $shorterAlphaNumber->setCountryCode(1)->setNationalNumber(8007493524);
3020
        $shorterAlphaNumber
3021
            ->setRawInput("1800 six-flag")
3022
            ->setCountryCodeSource(CountryCodeSource::FROM_NUMBER_WITHOUT_PLUS_SIGN);
3023
        $this->assertEquals(
3024
            $shorterAlphaNumber,
3025
            $this->phoneUtil->parseAndKeepRawInput("1800 six-flag", RegionCode::US)
3026
        );
3027
3028
        $shorterAlphaNumber->setRawInput("+1800 six-flag")->setCountryCodeSource(
3029
            CountryCodeSource::FROM_NUMBER_WITH_PLUS_SIGN
3030
        );
3031
        $this->assertEquals(
3032
            $shorterAlphaNumber,
3033
            $this->phoneUtil->parseAndKeepRawInput("+1800 six-flag", RegionCode::NZ)
3034
        );
3035
3036
        $shorterAlphaNumber->setRawInput("001800 six-flag")->setCountryCodeSource(
3037
            CountryCodeSource::FROM_NUMBER_WITH_IDD
3038
        );
3039
        $this->assertEquals(
3040
            $shorterAlphaNumber,
3041
            $this->phoneUtil->parseAndKeepRawInput("001800 six-flag", RegionCode::NZ)
3042
        );
3043
3044
        // Invalid region code supplied.
3045
        try {
3046
            $this->phoneUtil->parseAndKeepRawInput("123 456 7890", RegionCode::CS);
3047
            $this->fail("Deprecated region code not allowed: should fail.");
3048
        } catch (NumberParseException $e) {
3049
            // Expected this exception.
3050
            $this->assertEquals(
3051
                NumberParseException::INVALID_COUNTRY_CODE,
3052
                $e->getErrorType(),
3053
                "Wrong error type stored in exception."
3054
            );
3055
        }
3056
3057
        $koreanNumber = new PhoneNumber();
3058
        $koreanNumber->setCountryCode(82)->setNationalNumber(22123456)->setRawInput(
3059
            "08122123456"
3060
        )->setCountryCodeSource(CountryCodeSource::FROM_DEFAULT_COUNTRY)->setPreferredDomesticCarrierCode("81");
3061
        $this->assertEquals($koreanNumber, $this->phoneUtil->parseAndKeepRawInput("08122123456", RegionCode::KR));
3062
    }
3063
3064
    public function testParseItalianLeadingZeros()
3065
    {
3066
        // Test the number "011".
3067
        $oneZero = new PhoneNumber();
3068
        $oneZero->setCountryCode(61)->setNationalNumber(11)->setItalianLeadingZero(true);
3069
        $this->assertEquals($oneZero, $this->phoneUtil->parse("011", RegionCode::AU));
3070
3071
        // Test the number "001".
3072
        $twoZeros = new PhoneNumber();
3073
        $twoZeros->setCountryCode(61)->setNationalNumber(1)->setItalianLeadingZero(true)->setNumberOfLeadingZeros(2);
3074
        $this->assertEquals($twoZeros, $this->phoneUtil->parse("001", RegionCode::AU));
3075
3076
        // Test the number "000". This number has 2 leading zeros.
3077
        $stillTwoZeros = new PhoneNumber();
3078
        $stillTwoZeros->setCountryCode(61)->setNationalNumber(0)->setItalianLeadingZero(true)->setNumberOfLeadingZeros(
3079
            2
3080
        );
3081
        $this->assertEquals($stillTwoZeros, $this->phoneUtil->parse("000", RegionCode::AU));
3082
3083
        // Test the number "0000". This number has 3 leading zeros.
3084
        $threeZeros = new PhoneNumber();
3085
        $threeZeros->setCountryCode(61)->setNationalNumber(0)->setItalianLeadingZero(true)->setNumberOfLeadingZeros(3);
3086
        $this->assertEquals($threeZeros, $this->phoneUtil->parse("0000", RegionCode::AU));
3087
    }
3088
3089
    public function testCountryWithNoNumberDesc()
3090
    {
3091
        // Andorra is a country where we don't have PhoneNumberDesc info in the metadata.
3092
        $adNumber = new PhoneNumber();
3093
        $adNumber->setCountryCode(376)->setNationalNumber(12345);
3094
3095
        $this->assertEquals("+376 12345", $this->phoneUtil->format($adNumber, PhoneNumberFormat::INTERNATIONAL));
3096
        $this->assertEquals("+37612345", $this->phoneUtil->format($adNumber, PhoneNumberFormat::E164));
3097
        $this->assertEquals("12345", $this->phoneUtil->format($adNumber, PhoneNumberFormat::NATIONAL));
3098
        $this->assertEquals(PhoneNumberType::UNKNOWN, $this->phoneUtil->getNumberType($adNumber));
3099
        $this->assertFalse($this->phoneUtil->isValidNumber($adNumber));
3100
3101
        // Test dialing a US number from within Andorra.
3102
        $this->assertEquals(
3103
            "00 1 650 253 0000",
3104
            $this->phoneUtil->formatOutOfCountryCallingNumber(self::$usNumber, RegionCode::AD)
3105
        );
3106
    }
3107
3108
    public function testUnknownCountryCallingCode()
3109
    {
3110
        $this->assertFalse($this->phoneUtil->isValidNumber(self::$unknownCountryCodeNoRawInput));
3111
        // It's not very well defined as to what the E164 representation for a number with an invalid
3112
        // country calling code is, but just prefixing the country code and national number is about
3113
        // the best we can do.
3114
        $this->assertEquals(
3115
            "+212345",
3116
            $this->phoneUtil->format(self::$unknownCountryCodeNoRawInput, PhoneNumberFormat::E164)
3117
        );
3118
    }
3119
3120
    public function testIsNumberMatchMatches()
3121
    {
3122
        // Test simple matches where formatting is different, or leading zeros, or country calling code
3123
        // has been specified.
3124
        $this->assertEquals(
3125
            MatchType::EXACT_MATCH,
3126
            $this->phoneUtil->isNumberMatch("+64 3 331 6005", "+64 03 331 6005")
3127
        );
3128
        $this->assertEquals(MatchType::EXACT_MATCH, $this->phoneUtil->isNumberMatch("+800 1234 5678", "+80012345678"));
3129
        $this->assertEquals(
3130
            MatchType::EXACT_MATCH,
3131
            $this->phoneUtil->isNumberMatch("+64 03 331-6005", "+64 03331 6005")
3132
        );
3133
        $this->assertEquals(MatchType::EXACT_MATCH, $this->phoneUtil->isNumberMatch("+643 331-6005", "+64033316005"));
3134
        $this->assertEquals(MatchType::EXACT_MATCH, $this->phoneUtil->isNumberMatch("+643 331-6005", "+6433316005"));
3135
        $this->assertEquals(MatchType::EXACT_MATCH, $this->phoneUtil->isNumberMatch("+64 3 331-6005", "+6433316005"));
3136
        $this->assertEquals(
3137
            MatchType::EXACT_MATCH,
3138
            $this->phoneUtil->isNumberMatch("+64 3 331-6005", "tel:+64-3-331-6005;isub=123")
3139
        );
3140
        // Test alpha numbers.
3141
        $this->assertEquals(
3142
            MatchType::EXACT_MATCH,
3143
            $this->phoneUtil->isNumberMatch("+1800 siX-Flags", "+1 800 7493 5247")
3144
        );
3145
        // Test numbers with extensions.
3146
        $this->assertEquals(
3147
            MatchType::EXACT_MATCH,
3148
            $this->phoneUtil->isNumberMatch("+64 3 331-6005 extn 1234", "+6433316005#1234")
3149
        );
3150
        $this->assertEquals(
3151
            MatchType::EXACT_MATCH,
3152
            $this->phoneUtil->isNumberMatch("+64 3 331-6005 ext. 1234", "+6433316005;1234")
3153
        );
3154
        // Test proto buffers.
3155
        $this->assertEquals(MatchType::EXACT_MATCH, $this->phoneUtil->isNumberMatch(self::$nzNumber, "+6403 331 6005"));
3156
3157
        $nzNumber = new PhoneNumber();
3158
        $nzNumber->mergeFrom(self::$nzNumber)->setExtension("3456");
3159
        $this->assertEquals(
3160
            MatchType::EXACT_MATCH,
3161
            $this->phoneUtil->isNumberMatch($nzNumber, "+643 331 6005 ext 3456")
3162
        );
3163
3164
        // Check empty extensions are ignored.
3165
        $nzNumber->setExtension("");
3166
        $this->assertEquals(MatchType::EXACT_MATCH, $this->phoneUtil->isNumberMatch($nzNumber, "+6403 331 6005"));
3167
        // Check variant with two proto buffers.
3168
        $this->assertEquals(
3169
            MatchType::EXACT_MATCH,
3170
            $this->phoneUtil->isNumberMatch($nzNumber, self::$nzNumber),
3171
            "Number " . (string)$nzNumber . " did not match " . (string)self::$nzNumber
3172
        );
3173
    }
3174
3175
    public function testIsNumberMatchShortMatchIfDiffNumLeadingZeros()
3176
    {
3177
        $nzNumberOne = new PhoneNumber();
3178
        $nzNumberTwo = new PhoneNumber();
3179
        $nzNumberOne->setCountryCode(64)->setNationalNumber(33316005)->setItalianLeadingZero(true);
3180
        $nzNumberTwo->setCountryCode(64)->setNationalNumber(33316005)->setItalianLeadingZero(true)->setNumberOfLeadingZeros(2);
3181
3182
        $this->assertEquals(MatchType::SHORT_NSN_MATCH, $this->phoneUtil->isNumberMatch($nzNumberOne, $nzNumberTwo));
3183
3184
        $nzNumberOne->setItalianLeadingZero(false)->setNumberOfLeadingZeros(1);
3185
        $nzNumberTwo->setItalianLeadingZero(true)->setNumberOfLeadingZeros(1);
3186
3187
        // Since one doesn't have the Italian leading zero set to true, we ignore the number of leading zeros present
3188
        // (1 is in any case the default value)
3189
        $this->assertEquals(MatchType::SHORT_NSN_MATCH, $this->phoneUtil->isNumberMatch($nzNumberOne, $nzNumberTwo));
3190
    }
3191
3192
    public function testIsNumberMatchAcceptsProtoDefaultsAsMatch()
3193
    {
3194
        $nzNumberOne = new PhoneNumber();
3195
        $nzNumberTwo = new PhoneNumber();
3196
3197
        $nzNumberOne->setCountryCode(64)->setNationalNumber(33316005)->setItalianLeadingZero(true);
3198
        // The default for number of leading zeros is 1, so it shouldn't normally be set, however if it
3199
        // is it should be considered equivalent.
3200
        $nzNumberTwo->setCountryCode(64)->setNationalNumber(33316005)->setItalianLeadingZero(true)->setNumberOfLeadingZeros(1);
3201
3202
        $this->assertEquals(MatchType::EXACT_MATCH, $this->phoneUtil->isNumberMatch($nzNumberOne, $nzNumberTwo));
3203
    }
3204
3205
    public function testIsNumberMatchMatchesDiffLeadingZerosIfItalianLeadingZeroFalse()
3206
    {
3207
        $nzNumberOne = new PhoneNumber();
3208
        $nzNumberTwo = new PhoneNumber();
3209
3210
        $nzNumberOne->setCountryCode(64)->setNationalNumber(33316005);
3211
        // The default for number of leading zeros is 1, so it shouldn't normally be set, however if it
3212
        // is it should be considered equivalent
3213
        $nzNumberTwo->setCountryCode(64)->setNationalNumber(33316005)->setNumberOfLeadingZeros(1);
3214
3215
        $this->assertEquals(MatchType::EXACT_MATCH, $this->phoneUtil->isNumberMatch($nzNumberOne, $nzNumberTwo));
3216
3217
        // Even if it is set to ten, it is still equivalent because in both cases
3218
        // italian leading zero is not true
3219
        $nzNumberTwo->setNumberOfLeadingZeros(10);
3220
        $this->assertEquals(MatchType::EXACT_MATCH, $this->phoneUtil->isNumberMatch($nzNumberOne, $nzNumberTwo));
3221
    }
3222
3223
    public function testIsNumberMatchIgnoresSomeFields()
3224
    {
3225
        // Check raw_input, country_code_source and preferred_domestic_carrier_code are ignored.
3226
        $brNumberOne = new PhoneNumber();
3227
        $brNumberTwo = new PhoneNumber();
3228
        $brNumberOne->setCountryCode(55)->setNationalNumber(3121286979)
3229
            ->setCountryCodeSource(CountryCodeSource::FROM_NUMBER_WITH_PLUS_SIGN)
3230
            ->setPreferredDomesticCarrierCode("12")->setRawInput("012 3121286979");
3231
        $brNumberTwo->setCountryCode(55)->setNationalNumber(3121286979)
3232
            ->setCountryCodeSource(CountryCodeSource::FROM_DEFAULT_COUNTRY)
3233
            ->setPreferredDomesticCarrierCode("14")->setRawInput("143121286979");
3234
3235
        $this->assertEquals(MatchType::EXACT_MATCH, $this->phoneUtil->isNumberMatch($brNumberOne, $brNumberTwo));
3236
    }
3237
3238
    public function testIsNumberMatchNonMatches()
3239
    {
3240
        // Non-matches.
3241
        $this->assertEquals(MatchType::NO_MATCH, $this->phoneUtil->isNumberMatch("03 331 6005", "03 331 6006"));
3242
        $this->assertEquals(MatchType::NO_MATCH, $this->phoneUtil->isNumberMatch("+800 1234 5678", "+1 800 1234 5678"));
3243
        // Different country calling code, partial number match.
3244
        $this->assertEquals(MatchType::NO_MATCH, $this->phoneUtil->isNumberMatch("+64 3 331-6005", "+16433316005"));
3245
        // Different country calling code, same number.
3246
        $this->assertEquals(MatchType::NO_MATCH, $this->phoneUtil->isNumberMatch("+64 3 331-6005", "+6133316005"));
3247
        // Extension different, all else the same.
3248
        $this->assertEquals(
3249
            MatchType::NO_MATCH,
3250
            $this->phoneUtil->isNumberMatch("+64 3 331-6005 extn 1234", "0116433316005#1235")
3251
        );
3252
        $this->assertEquals(
3253
            MatchType::NO_MATCH,
3254
            $this->phoneUtil->isNumberMatch("+64 3 331-6005 extn 1234", "tel:+64-3-331-6005;ext=1235")
3255
        );
3256
        // NSN matches, but extension is different - not the same number.
3257
        $this->assertEquals(
3258
            MatchType::NO_MATCH,
3259
            $this->phoneUtil->isNumberMatch("+64 3 331-6005 ext.1235", "3 331 6005#1234")
3260
        );
3261
3262
        // Invalid numbers that can't be parsed.
3263
        $this->assertEquals(MatchType::NOT_A_NUMBER, $this->phoneUtil->isNumberMatch("4", "3 331 6043"));
3264
        $this->assertEquals(MatchType::NOT_A_NUMBER, $this->phoneUtil->isNumberMatch("+43", "+64 3 331 6005"));
3265
        $this->assertEquals(MatchType::NOT_A_NUMBER, $this->phoneUtil->isNumberMatch("+43", "64 3 331 6005"));
3266
        $this->assertEquals(MatchType::NOT_A_NUMBER, $this->phoneUtil->isNumberMatch("Dog", "64 3 331 6005"));
3267
    }
3268
3269
    public function testIsNumberMatchNsnMatches()
3270
    {
3271
        // NSN matches.
3272
        $this->assertEquals(MatchType::NSN_MATCH, $this->phoneUtil->isNumberMatch("+64 3 331-6005", "03 331 6005"));
3273
        $this->assertEquals(
3274
            MatchType::NSN_MATCH,
3275
            $this->phoneUtil->isNumberMatch("+64 3 331-6005", "tel:03-331-6005;isub=1234;phone-context=abc.nz")
3276
        );
3277
        $this->assertEquals(MatchType::NSN_MATCH, $this->phoneUtil->isNumberMatch(self::$nzNumber, "03 331 6005"));
3278
        // Here the second number possibly starts with the country calling code for New Zealand,
3279
        // although we are unsure.
3280
        $unchangedNzNumber = new PhoneNumber();
3281
        $unchangedNzNumber->mergeFrom(self::$nzNumber);
3282
        $this->assertEquals(
3283
            MatchType::NSN_MATCH,
3284
            $this->phoneUtil->isNumberMatch($unchangedNzNumber, "(64-3) 331 6005")
3285
        );
3286
        // Check the phone number proto was not edited during the method call.
3287
        $this->assertEquals(self::$nzNumber, $unchangedNzNumber);
3288
3289
        // Here, the 1 might be a national prefix, if we compare it to the US number, so the resultant
3290
        // match is an NSN match.
3291
        $this->assertEquals(MatchType::NSN_MATCH, $this->phoneUtil->isNumberMatch(self::$usNumber, "1-650-253-0000"));
3292
        $this->assertEquals(MatchType::NSN_MATCH, $this->phoneUtil->isNumberMatch(self::$usNumber, "6502530000"));
3293
        $this->assertEquals(MatchType::NSN_MATCH, $this->phoneUtil->isNumberMatch("+1 650-253 0000", "1 650 253 0000"));
3294
        $this->assertEquals(MatchType::NSN_MATCH, $this->phoneUtil->isNumberMatch("1 650-253 0000", "1 650 253 0000"));
3295
        $this->assertEquals(MatchType::NSN_MATCH, $this->phoneUtil->isNumberMatch("1 650-253 0000", "+1 650 253 0000"));
3296
        // For this case, the match will be a short NSN match, because we cannot assume that the 1 might
3297
        // be a national prefix, so don't remove it when parsing.
3298
        $randomNumber = new PhoneNumber();
3299
        $randomNumber->setCountryCode(41)->setNationalNumber(6502530000);
3300
        $this->assertEquals(
3301
            MatchType::SHORT_NSN_MATCH,
3302
            $this->phoneUtil->isNumberMatch($randomNumber, "1-650-253-0000")
3303
        );
3304
    }
3305
3306
    public function testIsNumberMatchShortNsnMatches()
3307
    {
3308
        // Short NSN matches with the country not specified for either one or both numbers.
3309
        $this->assertEquals(MatchType::SHORT_NSN_MATCH, $this->phoneUtil->isNumberMatch("+64 3 331-6005", "331 6005"));
3310
        $this->assertEquals(
3311
            MatchType::SHORT_NSN_MATCH,
3312
            $this->phoneUtil->isNumberMatch("+64 3 331-6005", "tel:331-6005;phone-context=abc.nz")
3313
        );
3314
        $this->assertEquals(
3315
            MatchType::SHORT_NSN_MATCH,
3316
            $this->phoneUtil->isNumberMatch("+64 3 331-6005", "tel:331-6005;isub=1234;phone-context=abc.nz")
3317
        );
3318
        $this->assertEquals(
3319
            MatchType::SHORT_NSN_MATCH,
3320
            $this->phoneUtil->isNumberMatch("+64 3 331-6005", "tel:331-6005;isub=1234;phone-context=abc.nz;a=%A1")
3321
        );
3322
3323
        // We did not know that the "0" was a national prefix since neither number has a country code,
3324
        // so this is considered a SHORT_NSN_MATCH.
3325
        $this->assertEquals(MatchType::SHORT_NSN_MATCH, $this->phoneUtil->isNumberMatch("3 331-6005", "03 331 6005"));
3326
        $this->assertEquals(MatchType::SHORT_NSN_MATCH, $this->phoneUtil->isNumberMatch("3 331-6005", "331 6005"));
3327
        $this->assertEquals(
3328
            MatchType::SHORT_NSN_MATCH,
3329
            $this->phoneUtil->isNumberMatch("3 331-6005", "tel:331-6005;phone-context=abc.nz")
3330
        );
3331
        $this->assertEquals(MatchType::SHORT_NSN_MATCH, $this->phoneUtil->isNumberMatch("3 331-6005", "+64 331 6005"));
3332
3333
        // Short NSN match with the country specified.
3334
        $this->assertEquals(MatchType::SHORT_NSN_MATCH, $this->phoneUtil->isNumberMatch("03 331-6005", "331 6005"));
3335
        $this->assertEquals(MatchType::SHORT_NSN_MATCH, $this->phoneUtil->isNumberMatch("1 234 345 6789", "345 6789"));
3336
        $this->assertEquals(
3337
            MatchType::SHORT_NSN_MATCH,
3338
            $this->phoneUtil->isNumberMatch("+1 (234) 345 6789", "345 6789")
3339
        );
3340
        // NSN matches, country calling code omitted for one number, extension missing for one.
3341
        $this->assertEquals(
3342
            MatchType::SHORT_NSN_MATCH,
3343
            $this->phoneUtil->isNumberMatch("+64 3 331-6005", "3 331 6005#1234")
3344
        );
3345
        // One has Italian leading zero, one does not.
3346
        $italianNumberOne = new PhoneNumber();
3347
        $italianNumberOne->setCountryCode(39)->setNationalNumber(1234)->setItalianLeadingZero(true);
3348
        $italianNumberTwo = new PhoneNumber();
3349
        $italianNumberTwo->setCountryCode(39)->setNationalNumber(1234);
3350
        $this->assertEquals(
3351
            MatchType::SHORT_NSN_MATCH,
3352
            $this->phoneUtil->isNumberMatch($italianNumberOne, $italianNumberTwo)
3353
        );
3354
        // One has an extension, the other has an extension of "".
3355
        $italianNumberOne->setExtension("1234")->clearItalianLeadingZero();
3356
        $italianNumberTwo->setExtension("");
3357
        $this->assertEquals(
3358
            MatchType::SHORT_NSN_MATCH,
3359
            $this->phoneUtil->isNumberMatch($italianNumberOne, $italianNumberTwo)
3360
        );
3361
    }
3362
3363
    public function testCanBeInternationallyDialled()
3364
    {
3365
        // We have no-international-dialling rules for the US in our test metadata that say that
3366
        // toll-free numbers cannot be dialled internationally.
3367
        $this->assertFalse($this->phoneUtil->canBeInternationallyDialled(self::$usTollFree));
3368
        // Normal US numbers can be internationally dialled.
3369
        $this->assertTrue($this->phoneUtil->canBeInternationallyDialled(self::$usNumber));
3370
3371
        // Invalid number.
3372
        $this->assertTrue($this->phoneUtil->canBeInternationallyDialled(self::$usLocalNumber));
3373
3374
        // We have no data for NZ - should return true.
3375
        $this->assertTrue($this->phoneUtil->canBeInternationallyDialled(self::$nzNumber));
3376
        $this->assertTrue($this->phoneUtil->canBeInternationallyDialled(self::$internationalTollFree));
3377
    }
3378
3379
    public function testIsAlphaNumber()
3380
    {
3381
        $this->assertTrue($this->phoneUtil->isAlphaNumber("1800 six-flags"));
3382
        $this->assertTrue($this->phoneUtil->isAlphaNumber("1800 six-flags ext. 1234"));
3383
        $this->assertTrue($this->phoneUtil->isAlphaNumber("+800 six-flags"));
3384
        $this->assertTrue($this->phoneUtil->isAlphaNumber("180 six-flags"));
3385
        $this->assertFalse($this->phoneUtil->isAlphaNumber("1800 123-1234"));
3386
        $this->assertFalse($this->phoneUtil->isAlphaNumber("1 six-flags"));
3387
        $this->assertFalse($this->phoneUtil->isAlphaNumber("18 six-flags"));
3388
        $this->assertFalse($this->phoneUtil->isAlphaNumber("1800 123-1234 extension: 1234"));
3389
        $this->assertFalse($this->phoneUtil->isAlphaNumber("+800 1234-1234"));
3390
    }
3391
3392
    public function testIsMobileNumberPortableRegion()
3393
    {
3394
        $this->assertTrue($this->phoneUtil->isMobileNumberPortableRegion(RegionCode::US));
3395
        $this->assertTrue($this->phoneUtil->isMobileNumberPortableRegion(RegionCode::GB));
3396
        $this->assertFalse($this->phoneUtil->isMobileNumberPortableRegion(RegionCode::AE));
3397
        $this->assertFalse($this->phoneUtil->isMobileNumberPortableRegion(RegionCode::BS));
3398
    }
3399
}
3400