Completed
Push — upstream-8.6.0 ( 7fd1b5 )
by Joshua
14:50
created

PhoneNumberUtilTest::testIsLeadingZeroPossible()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

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

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

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

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

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