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

testBuildPhoneMetadataCollection_specialBuild()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 44
Code Lines 37

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 44
rs 8.8571
c 0
b 0
f 0
cc 1
eloc 37
nc 1
nop 0
1
<?php
2
/**
3
 *
4
 * @author giggsey
5
 * @package libphonenumber-for-php
6
 */
7
8
namespace libphonenumber\Tests\buildtools;
9
10
use libphonenumber\buildtools\BuildMetadataFromXml;
11
use libphonenumber\buildtools\MetadataFilter;
12
use libphonenumber\NumberFormat;
13
use libphonenumber\PhoneMetadata;
14
use libphonenumber\PhoneNumberDesc;
15
16
class BuildMetadataFromXmlTest extends \PHPUnit_Framework_TestCase
17
{
18
    public function testValidateRERemovesWhiteSpaces()
19
    {
20
        $input = " hello world ";
21
        // Should remove all the white spaces contained in the provided string.
22
        $this->assertEquals("helloworld", BuildMetadataFromXml::validateRE($input, true));
23
        // Make sure it only happens when the last parameter is set to true.
24
        $this->assertEquals(" hello world ", BuildMetadataFromXml::validateRE($input, false));
25
    }
26
27
    public function testValidateREThrowsException()
28
    {
29
        $invalidPattern = '[';
30
        // Should throw an exception when an invalid pattern is provided independently of the last
31
        // parameter (remove white spaces).
32
        try {
33
            BuildMetadataFromXml::validateRE($invalidPattern, false);
34
            $this->fail();
35
        } catch (\Exception $e) {
36
            // Test passed.
37
            $this->addToAssertionCount(1);
38
        }
39
40
        try {
41
            BuildMetadataFromXml::validateRE($invalidPattern, true);
42
            $this->fail();
43
        } catch (\Exception $e) {
44
            // Test passed.
45
            $this->addToAssertionCount(1);
46
        }
47
48
        // We don't allow | to be followed by ) because it introduces bugs, since we typically use it at
49
        // the end of each line and when a line is deleted, if the pipe from the previous line is not
50
        // removed, we end up erroneously accepting an empty group as well.
51
        $patternWithPipeFollowedByClosingParentheses = '|)';
52
        try {
53
            BuildMetadataFromXml::validateRE($patternWithPipeFollowedByClosingParentheses, true);
54
            $this->fail();
55
        } catch (\Exception $e) {
56
            // Test passed.
57
            $this->addToAssertionCount(1);
58
        }
59
        $patternWithPipeFollowedByNewLineAndClosingParentheses = "|\n)";
60
        try {
61
            BuildMetadataFromXml::validateRE($patternWithPipeFollowedByNewLineAndClosingParentheses, true);
62
            $this->fail();
63
        } catch (\Exception $e) {
64
            // Test passed.
65
            $this->addToAssertionCount(1);
66
        }
67
    }
68
69
    public function testValidateRE()
70
    {
71
        $validPattern = "[a-zA-Z]d{1,9}";
72
        // The provided pattern should be left unchanged.
73
        $this->assertEquals($validPattern, BuildMetadataFromXml::validateRE($validPattern, false));
74
    }
75
76
    public function testGetNationalPrefix()
77
    {
78
        $xmlInput = "<territory nationalPrefix='00'/>";
79
        $territoryElement = $this->parseXMLString($xmlInput);
80
        $this->assertEquals('00', BuildMetadataFromXml::getNationalPrefix($territoryElement));
81
    }
82
83
    /**
84
     * @param $xmlString
85
     * @return \DOMElement
86
     */
87
    private function parseXMLString($xmlString)
88
    {
89
        $domDocument = new \DOMDocument();
90
        $domDocument->loadXML($xmlString);
91
92
        return $domDocument->documentElement;
93
    }
94
95
    public function testLoadTerritoryTagMetadata()
96
    {
97
        $xmlInput = "<territory"
98
            . "  countryCode='33' leadingDigits='2' internationalPrefix='00'"
99
            . "  preferredInternationalPrefix='0011' nationalPrefixForParsing='0'"
100
            . "  nationalPrefixTransformRule='9$1'"  // nationalPrefix manually injected.
101
            . "  preferredExtnPrefix=' x' mainCountryForCode='true'"
102
            . "  leadingZeroPossible='true' mobileNumberPortableRegion='true'>"
103
            . "</territory>";
104
        $territoryElement = $this->parseXMLString($xmlInput);
105
        $phoneMetadata = BuildMetadataFromXml::loadTerritoryTagMetadata('33', $territoryElement, '0');
106
        $this->assertEquals(33, $phoneMetadata->getCountryCode());
107
        $this->assertEquals("2", $phoneMetadata->getLeadingDigits());
108
        $this->assertEquals("00", $phoneMetadata->getInternationalPrefix());
109
        $this->assertEquals("0011", $phoneMetadata->getPreferredInternationalPrefix());
110
        $this->assertEquals("0", $phoneMetadata->getNationalPrefixForParsing());
111
        $this->assertEquals("9$1", $phoneMetadata->getNationalPrefixTransformRule());
112
        $this->assertEquals("0", $phoneMetadata->getNationalPrefix());
113
        $this->assertEquals(" x", $phoneMetadata->getPreferredExtnPrefix());
114
        $this->assertTrue($phoneMetadata->isMainCountryForCode());
115
        $this->assertTrue($phoneMetadata->isMobileNumberPortableRegion());
116
    }
117
118
    public function testLoadTerritoryTagMetadataSetsBooleanFieldsToFalseByDefault()
119
    {
120
        $xmlInput = "<territory countryCode='33'/>";
121
        $territoryElement = $this->parseXMLString($xmlInput);
122
        $phoneMetadata = BuildMetadataFromXml::loadTerritoryTagMetadata('33', $territoryElement, '');
123
        $this->assertFalse($phoneMetadata->isMainCountryForCode());
124
        $this->assertFalse($phoneMetadata->isMobileNumberPortableRegion());
125
    }
126
127
    public function testLoadTerritoryTagMetadataSetsNationalPrefixForParsingByDefault()
128
    {
129
        $xmlInput = "<territory countryCode='33'/>";
130
        $territoryElement = $this->parseXMLString($xmlInput);
131
        $phoneMetadata = BuildMetadataFromXml::loadTerritoryTagMetadata('33', $territoryElement, '00');
132
        // When unspecified, nationalPrefixForParsing defaults to nationalPrefix.
133
        $this->assertEquals("00", $phoneMetadata->getNationalPrefix());
134
        $this->assertEquals($phoneMetadata->getNationalPrefix(), $phoneMetadata->getNationalPrefixForParsing());
135
    }
136
137
    public function testLoadTerritoryTagMetadataWithRequiredAttributesOnly()
138
    {
139
        $xmlInput = "<territory countryCode='33' internationalPrefix='00'/>";
140
        $territoryElement = $this->parseXMLString($xmlInput);
141
        // Should not throw any exception
142
        BuildMetadataFromXml::loadTerritoryTagMetadata('33', $territoryElement, '');
143
    }
144
145
    public function testLoadInternationalFormat()
146
    {
147
        $intlFormat = '$1 $2';
148
        $xmlInput = "<numberFormat><intlFormat>" . $intlFormat . "</intlFormat></numberFormat>";
149
        $numberFormatElement = $this->parseXMLString($xmlInput);
150
        $metadata = new PhoneMetadata();
151
        $nationalFormat = new NumberFormat();
152
153
        $this->assertTrue(BuildMetadataFromXml::loadInternationalFormat($metadata, $numberFormatElement,
154
            $nationalFormat));
155
        $this->assertEquals($intlFormat, $metadata->getIntlNumberFormat(0)->getFormat());
156
    }
157
158
    public function testLoadInternationalFormatWithBothNationalAndIntlFormatsDefined()
159
    {
160
        $intlFormat = '$1 $2';
161
        $xmlInput = "<numberFormat><intlFormat>" . $intlFormat . "</intlFormat></numberFormat>";
162
        $numberFormatElement = $this->parseXMLString($xmlInput);
163
        $metadata = new PhoneMetadata();
164
        $nationalFormat = new NumberFormat();
165
        $nationalFormat->setFormat('$1');
166
167
        $this->assertTrue(BuildMetadataFromXml::loadInternationalFormat($metadata, $numberFormatElement,
168
            $nationalFormat));
169
        $this->assertEquals($intlFormat, $metadata->getIntlNumberFormat(0)->getFormat());
170
    }
171
172
    /**
173
     * @expectedException \RuntimeException
174
     */
175
    public function testLoadInternationalFormatExpectsOnlyOnePattern()
176
    {
177
        $xmlInput = '<numberFormat><intlFormat/><intlFormat/></numberFormat>';
178
        $numberFormatElement = $this->parseXMLString($xmlInput);
179
        $metadata = new PhoneMetadata();
180
181
        // Should throw an exception as multiple intlFormats are provided
182
        BuildMetadataFromXml::loadInternationalFormat($metadata, $numberFormatElement, new NumberFormat());
183
    }
184
185
    public function testLoadInternationalFormatUsesNationalFormatByDefault()
186
    {
187
        $xmlInput = '<numberFormat></numberFormat>';
188
        $numberFormatElement = $this->parseXMLString($xmlInput);
189
        $metadata = new PhoneMetadata();
190
        $nationalFormat = new NumberFormat();
191
        $nationPattern = '$1 $2 $3';
192
        $nationalFormat->setFormat($nationPattern);
193
194
        $this->assertFalse(BuildMetadataFromXml::loadInternationalFormat($metadata, $numberFormatElement,
195
            $nationalFormat));
196
        $this->assertEquals($nationPattern, $metadata->getIntlNumberFormat(0)->getFormat());
197
    }
198
199
    public function testLoadInternationalFormatCopiesNationalFormatData()
200
    {
201
        $xmlInput = '<numberFormat></numberFormat>';
202
        $numberFormatElement = $this->parseXMLString($xmlInput);
203
        $metadata = new PhoneMetadata();
204
        $nationalFormat = new NumberFormat();
205
        $nationalFormat->setFormat('$1-$2');
206
        $nationalFormat->setNationalPrefixOptionalWhenFormatting(true);
207
208
        $this->assertFalse(BuildMetadataFromXml::loadInternationalFormat($metadata, $numberFormatElement,
209
            $nationalFormat));
210
        $this->assertTrue($metadata->getIntlNumberFormat(0)->getNationalPrefixOptionalWhenFormatting());
211
    }
212
213
    public function testLoadNationalFormat()
214
    {
215
        $nationalFormat = '$1 $2';
216
        $xmlInput = '<numberFormat><format>' . $nationalFormat . '</format></numberFormat>';
217
        $numberFormatElement = $this->parseXMLString($xmlInput);
218
        $metadata = new PhoneMetadata();
219
        $numberFormat = new NumberFormat();
220
        BuildMetadataFromXml::loadNationalFormat($metadata, $numberFormatElement, $numberFormat);
221
        $this->assertEquals($nationalFormat, $numberFormat->getFormat());
222
    }
223
224
    /**
225
     * @expectedException \RuntimeException
226
     */
227
    public function testLoadNationalFormatRequiresFormat()
228
    {
229
        $xmlInput = '<numberFormat></numberFormat>';
230
        $numberFormatElement = $this->parseXMLString($xmlInput);
231
        $metadata = new PhoneMetadata();
232
        $numberFormat = new NumberFormat();
233
234
        BuildMetadataFromXml::loadNationalFormat($metadata, $numberFormatElement, $numberFormat);
235
    }
236
237
    /**
238
     * @expectedException \RuntimeException
239
     */
240
    public function testLoadNationalFormatExpectsExactlyOneFormat()
241
    {
242
        $xmlInput = "<numberFormat><format/><format/></numberFormat>";
243
        $numberFormatElement = $this->parseXMLString($xmlInput);
244
        $metadata = new PhoneMetadata();
245
        $numberFormat = new NumberFormat();
246
247
        BuildMetadataFromXml::loadNationalFormat($metadata, $numberFormatElement, $numberFormat);
248
    }
249
250
    public function testLoadAvailableFormats()
251
    {
252
        $xmlInput = '<territory>'
253
            . '  <availableFormats>'
254
            . '    <numberFormat nationalPrefixFormattingRule=\'($FG)\''
255
            . '                  carrierCodeFormattingRule=\'$NP $CC ($FG)\'>'
256
            . '      <format>$1 $2 $3</format>'
257
            . '    </numberFormat>'
258
            . '  </availableFormats>'
259
            . '</territory>';
260
261
        $element = $this->parseXMLString($xmlInput);
262
        $metadata = new PhoneMetadata();
263
        BuildMetadataFromXml::loadAvailableFormats($metadata, $element, '0', '', false /* NP not optional */);
264
        $this->assertEquals('($1)', $metadata->getNumberFormat(0)->getNationalPrefixFormattingRule());
265
        $this->assertEquals('0 $CC ($1)', $metadata->getNumberFormat(0)->getDomesticCarrierCodeFormattingRule());
266
        $this->assertEquals('$1 $2 $3', $metadata->getNumberFormat(0)->getFormat());
267
    }
268
269
    public function testLoadAvailableFormatsPropagatesCarrierCodeFormattingRule()
270
    {
271
        $xmlInput =
272
            '<territory carrierCodeFormattingRule=\'$NP $CC ($FG)\'>'
273
            . '  <availableFormats>'
274
            . '    <numberFormat nationalPrefixFormattingRule=\'($FG)\'>'
275
            . '      <format>$1 $2 $3</format>'
276
            . '    </numberFormat>'
277
            . '  </availableFormats>'
278
            . '</territory>';
279
280
        $element = $this->parseXMLString($xmlInput);
281
        $metadata = new PhoneMetadata();
282
        BuildMetadataFromXml::loadAvailableFormats($metadata, $element, '0', '', false /* NP not optional */);
283
        $this->assertEquals('($1)', $metadata->getNumberFormat(0)->getNationalPrefixFormattingRule());
284
        $this->assertEquals('0 $CC ($1)', $metadata->getNumberFormat(0)->getDomesticCarrierCodeFormattingRule());
285
        $this->assertEquals('$1 $2 $3', $metadata->getNumberFormat(0)->getFormat());
286
    }
287
288
    public function testLoadAvailableFormatsSetsProvidedNationalPrefixFormattingRule()
289
    {
290
        $xmlInput = "<territory>"
291
            . "  <availableFormats>"
292
            . '    <numberFormat><format>$1 $2 $3</format></numberFormat>'
293
            . "  </availableFormats>"
294
            . "</territory>";
295
296
        $element = $this->parseXMLString($xmlInput);
297
        $metadata = new PhoneMetadata();
298
        BuildMetadataFromXml::loadAvailableFormats($metadata, $element, '', '($1)', false /* NP not optional */);
299
        $this->assertEquals('($1)', $metadata->getNumberFormat(0)->getNationalPrefixFormattingRule());
300
    }
301
302
    public function testLoadAvailableFormatsClearsIntlFormat()
303
    {
304
        $xmlInput = "<territory>"
305
            . "  <availableFormats>"
306
            . '    <numberFormat><format>$1 $2 $3</format></numberFormat>'
307
            . "  </availableFormats>"
308
            . "</territory>";
309
310
        $element = $this->parseXMLString($xmlInput);
311
        $metadata = new PhoneMetadata();
312
        BuildMetadataFromXml::loadAvailableFormats($metadata, $element, '0', '($1)', false /* NP not optional */);
313
        $this->assertCount(0, $metadata->intlNumberFormats());
314
    }
315
316
    public function testLoadAvailableFormatsHandlesMultipleNumberFormats()
317
    {
318
        $xmlInput = "<territory>"
319
            . "  <availableFormats>"
320
            . '    <numberFormat><format>$1 $2 $3</format></numberFormat>'
321
            . '    <numberFormat><format>$1-$2</format></numberFormat>'
322
            . "  </availableFormats>"
323
            . "</territory>";
324
325
        $element = $this->parseXMLString($xmlInput);
326
        $metadata = new PhoneMetadata();
327
        BuildMetadataFromXml::loadAvailableFormats($metadata, $element, '0', '($1)', false /* NP not optional */);
328
        $this->assertEquals('$1 $2 $3', $metadata->getNumberFormat(0)->getFormat());
329
        $this->assertEquals('$1-$2', $metadata->getNumberFormat(1)->getFormat());
330
    }
331
332
    public function testLoadInternationalFormatDoesNotSetIntlFormatWhenNA()
333
    {
334
        $xmlInput = '<numberFormat><intlFormat>NA</intlFormat></numberFormat>';
335
        $numberFormatElement = $this->parseXMLString($xmlInput);
336
        $metadata = new PhoneMetadata();
337
        $nationalFormat = new NumberFormat();
338
        $nationalFormat->setFormat('$1 $2');
339
340
        BuildMetadataFromXml::loadInternationalFormat($metadata, $numberFormatElement, $nationalFormat);
341
        $this->assertCount(0, $metadata->intlNumberFormats());
342
    }
343
344
    public function testSetLeadingDigitsPatterns()
345
    {
346
        $xmlInput = "<numberFormat>"
347
            . "<leadingDigits>1</leadingDigits><leadingDigits>2</leadingDigits>"
348
            . "</numberFormat>";
349
350
        $numberFormatElement = $this->parseXMLString($xmlInput);
351
        $numberFormat = new NumberFormat();
352
        BuildMetadataFromXml::setLeadingDigitsPatterns($numberFormatElement, $numberFormat);
353
354
        $this->assertEquals('1', $numberFormat->getLeadingDigitsPattern(0));
355
        $this->assertEquals('2', $numberFormat->getLeadingDigitsPattern(1));
356
    }
357
358
    /**
359
     * Tests setLeadingDigitsPatterns() in the case of international and national formatting rules
360
     * being present but not both defined for this numberFormat - we don't want to add them twice.
361
     */
362
    public function testSetLeadingDigitsPatternsNotAddedTwiceWhenInternationalFormatsPresent()
363
    {
364
        $xmlInput = "<availableFormats>"
365
            . "  <numberFormat pattern=\"(1)(\\d{3})\">"
366
            . "    <leadingDigits>1</leadingDigits>"
367
            . '    <format>$1</format>'
368
            . "  </numberFormat>"
369
            . "  <numberFormat pattern=\"(2)(\\d{3})\">"
370
            . "    <leadingDigits>2</leadingDigits>"
371
            . '    <format>$1</format>'
372
            . '    <intlFormat>9-$1</intlFormat>'
373
            . "  </numberFormat>"
374
            . "</availableFormats>";
375
376
        $element = $this->parseXMLString($xmlInput);
377
        $metadata = new PhoneMetadata();
378
        BuildMetadataFromXml::loadAvailableFormats($metadata, $element, '0', '', false /* NP not optional */);
379
        $this->assertCount(1, $metadata->getNumberFormat(0)->leadingDigitPatterns());
380
        $this->assertCount(1, $metadata->getNumberFormat(1)->leadingDigitPatterns());
381
        // When we merge the national format rules into the international format rules, we shouldn't add
382
        // the leading digit patterns multiple times.
383
        $this->assertCount(1, $metadata->getIntlNumberFormat(0)->leadingDigitPatterns());
384
        $this->assertCount(1, $metadata->getIntlNumberFormat(1)->leadingDigitPatterns());
385
    }
386
387
    public function testGetNationalPrefixFormattingRuleFromElement()
388
    {
389
        $xmlInput = '<territory nationalPrefixFormattingRule="$NP$FG" />';
390
        $element = $this->parseXMLString($xmlInput);
391
        $this->assertEquals('0$1', BuildMetadataFromXml::getNationalPrefixFormattingRuleFromElement($element, '0'));
392
    }
393
394
    public function testGetDomesticCarrierCodeFormattingRuleFromElement()
395
    {
396
        $xmlInput = '<territory carrierCodeFormattingRule=\'$NP$CC $FG\'/>';
397
        $element = $this->parseXMLString($xmlInput);
398
        $this->assertEquals('0$CC $1',
399
            BuildMetadataFromXml::getDomesticCarrierCodeFormattingRuleFromElement($element, '0'));
400
    }
401
402
    public function testProcessPhoneNumberDescElementWithInvalidInput()
403
    {
404
        $generalDesc = new PhoneNumberDesc();
405
        $territoryElement = $this->parseXMLString("<territory/>");
406
407
        $phoneNumberDesc = BuildMetadataFromXml::processPhoneNumberDescElement($generalDesc, $territoryElement,
408
            'invalidType');
409
        $this->assertFalse($phoneNumberDesc->hasNationalNumberPattern());
410
    }
411
412
    public function testProcessPhoneNumberDescElementOverridesGeneralDesc()
413
    {
414
        $generalDesc = new PhoneNumberDesc();
415
        $generalDesc->setNationalNumberPattern('\\d{8}');
416
        $xmlInput = "<territory><fixedLine>"
417
            . "  <nationalNumberPattern>\\d{6}</nationalNumberPattern>"
418
            . "</fixedLine></territory>";
419
420
        $territoryElement = $this->parseXMLString($xmlInput);
421
422
        $phoneNumberDesc = BuildMetadataFromXml::processPhoneNumberDescElement($generalDesc, $territoryElement,
423
            'fixedLine');
424
        $this->assertEquals('\\d{6}', $phoneNumberDesc->getNationalNumberPattern());
425
    }
426
427
    public function testBuildPhoneMetadataCollection_liteBuild()
428
    {
429
        $xmlInput = "<phoneNumberMetadata>"
430
            . "  <territories>"
431
            . "    <territory id=\"AM\" countryCode=\"374\" internationalPrefix=\"00\">"
432
            . "      <generalDesc>"
433
            . "        <nationalNumberPattern>[1-9]\\d{7}</nationalNumberPattern>"
434
            . "      </generalDesc>"
435
            . "      <fixedLine>"
436
            . "        <nationalNumberPattern>[1-9]\\d{7}</nationalNumberPattern>"
437
            . "        <possibleLengths national=\"8\" localOnly=\"5,6\"/>"
438
            . "        <exampleNumber>10123456</exampleNumber>"
439
            . "      </fixedLine>"
440
            . "      <mobile>"
441
            . "        <nationalNumberPattern>[1-9]\\d{7}</nationalNumberPattern>"
442
            . "        <possibleLengths national=\"8\" localOnly=\"5,6\"/>"
443
            . "        <exampleNumber>10123456</exampleNumber>"
444
            . "      </mobile>"
445
            . "    </territory>"
446
            . "  </territories>"
447
            . "</phoneNumberMetadata>";
448
449
        $document = $this->parseXMLString($xmlInput);
450
451
        $metadataCollection = BuildMetadataFromXml::buildPhoneMetadataCollection($document,
0 ignored issues
show
Documentation introduced by
$document is of type object<DOMElement>, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
452
            true, // liteBuild
453
            false, // specialBuild
454
            false, // isShortNumberMetadata
455
            false // isAlternateFormatsMetadata
456
        );
457
458
        $this->assertCount(1, $metadataCollection);
459
        $metadata = $metadataCollection[0];
460
461
        $this->assertTrue($metadata->hasGeneralDesc());
462
        $this->assertFalse($metadata->getGeneralDesc()->hasExampleNumber());
463
        $this->assertEquals("", $metadata->getGeneralDesc()->getExampleNumber());
464
        $this->assertTrue($metadata->hasFixedLine());
465
        $this->assertFalse($metadata->getFixedLine()->hasExampleNumber());
466
        $this->assertEquals("", $metadata->getFixedLine()->getExampleNumber());
467
        $this->assertTrue($metadata->hasMobile());
468
        $this->assertFalse($metadata->getMobile()->hasExampleNumber());
469
        $this->assertEquals("", $metadata->getMobile()->getExampleNumber());
470
    }
471
472
    public function testBuildPhoneMetadataCollection_specialBuild()
473
    {
474
        $xmlInput = "<phoneNumberMetadata>"
475
            . "  <territories>"
476
            . "    <territory id=\"AM\" countryCode=\"374\" internationalPrefix=\"00\">"
477
            . "      <generalDesc>"
478
            . "        <nationalNumberPattern>[1-9]\\d{7}</nationalNumberPattern>"
479
            . "      </generalDesc>"
480
            . "      <fixedLine>"
481
            . "        <nationalNumberPattern>[1-9]\\d{7}</nationalNumberPattern>"
482
            . "        <possibleLengths national=\"8\" localOnly=\"5,6\"/>"
483
            . "        <exampleNumber>10123456</exampleNumber>"
484
            . "      </fixedLine>"
485
            . "      <mobile>"
486
            . "        <nationalNumberPattern>[1-9]\\d{7}</nationalNumberPattern>"
487
            . "        <possibleLengths national=\"8\" localOnly=\"5,6\"/>"
488
            . "        <exampleNumber>10123456</exampleNumber>"
489
            . "      </mobile>"
490
            . "    </territory>"
491
            . "  </territories>"
492
            . "</phoneNumberMetadata>";
493
494
        $document = $this->parseXMLString($xmlInput);
495
496
        $metadataCollection = BuildMetadataFromXml::buildPhoneMetadataCollection($document,
0 ignored issues
show
Documentation introduced by
$document is of type object<DOMElement>, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
497
            false, // liteBuild
498
            true, // specialBuild
499
            false, // isShortNumberMetadata
500
            false // isAlternateFormatsMetadata
501
        );
502
503
        $this->assertCount(1, $metadataCollection);
504
        $metadata = $metadataCollection[0];
505
        $this->assertTrue($metadata->hasGeneralDesc());
506
        $this->assertFalse($metadata->getGeneralDesc()->hasExampleNumber());
507
        $this->assertEquals("", $metadata->getGeneralDesc()->getExampleNumber());
508
        // Consider clearing fixed-line if empty after being filtered.
509
        $this->assertTrue($metadata->hasFixedLine());
510
        $this->assertFalse($metadata->getFixedLine()->hasExampleNumber());
511
        $this->assertEquals("", $metadata->getFixedLine()->getExampleNumber());
512
        $this->assertTrue($metadata->hasMobile());
513
        $this->assertTrue($metadata->getMobile()->hasExampleNumber());
514
        $this->assertEquals("10123456", $metadata->getMobile()->getExampleNumber());
515
    }
516
517
    public function testBuildPhoneMetadataCollection_fullBuild()
518
    {
519
        $xmlInput = "<phoneNumberMetadata>"
520
            . "  <territories>"
521
            . "    <territory id=\"AM\" countryCode=\"374\" internationalPrefix=\"00\">"
522
            . "      <generalDesc>"
523
            . "        <nationalNumberPattern>[1-9]\\d{7}</nationalNumberPattern>"
524
            . "      </generalDesc>"
525
            . "      <fixedLine>"
526
            . "        <nationalNumberPattern>[1-9]\\d{7}</nationalNumberPattern>"
527
            . "        <possibleLengths national=\"8\" localOnly=\"5,6\"/>"
528
            . "        <exampleNumber>10123456</exampleNumber>"
529
            . "      </fixedLine>"
530
            . "      <mobile>"
531
            . "        <nationalNumberPattern>[1-9]\\d{7}</nationalNumberPattern>"
532
            . "        <possibleLengths national=\"8\" localOnly=\"5,6\"/>"
533
            . "        <exampleNumber>10123456</exampleNumber>"
534
            . "      </mobile>"
535
            . "    </territory>"
536
            . "  </territories>"
537
            . "</phoneNumberMetadata>";
538
539
        $document = $this->parseXMLString($xmlInput);
540
541
        $metadataCollection = BuildMetadataFromXml::buildPhoneMetadataCollection($document,
0 ignored issues
show
Documentation introduced by
$document is of type object<DOMElement>, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
542
            false, // liteBuild
543
            false, // specialBuild
544
            false, // isShortNumberMetadata
545
            false // isAlternateFormatsMetadata
546
        );
547
548
        $this->assertCount(1, $metadataCollection);
549
        $metadata = $metadataCollection[0];
550
        $this->assertTrue($metadata->hasGeneralDesc());
551
        $this->assertFalse($metadata->getGeneralDesc()->hasExampleNumber());
552
        $this->assertEquals("", $metadata->getGeneralDesc()->getExampleNumber());
553
        $this->assertTrue($metadata->hasFixedLine());
554
        $this->assertTrue($metadata->getFixedLine()->hasExampleNumber());
555
        $this->assertEquals("10123456", $metadata->getFixedLine()->getExampleNumber());
556
        $this->assertTrue($metadata->hasMobile());
557
        $this->assertTrue($metadata->getMobile()->hasExampleNumber());
558
        $this->assertEquals("10123456", $metadata->getMobile()->getExampleNumber());
559
    }
560
561
    public function testProcessPhoneNumberDescOutputsExampleNumberByDefault()
562
    {
563
        $generalDesc = new PhoneNumberDesc();
564
        $xmlInput = "<territory><fixedLine>"
565
            . "  <exampleNumber>01 01 01 01</exampleNumber>"
566
            . "</fixedLine></territory>";
567
568
        $territoryElement = $this->parseXMLString($xmlInput);
569
570
        $phoneNumberDesc = BuildMetadataFromXml::processPhoneNumberDescElement($generalDesc, $territoryElement,
571
            'fixedLine');
572
        $this->assertEquals('01 01 01 01', $phoneNumberDesc->getExampleNumber());
573
    }
574
575
    public function testProcessPhoneNumberDescRemovesWhiteSpacesInPatterns()
576
    {
577
        $generalDesc = new PhoneNumberDesc();
578
        $xmlInput = "<territory><fixedLine>"
579
            . "  <nationalNumberPattern>\t \\d { 6 } </nationalNumberPattern>"
580
            . "</fixedLine></territory>";
581
582
        $countryElement = $this->parseXMLString($xmlInput);
583
584
        $phoneNumberDesc = BuildMetadataFromXml::processPhoneNumberDescElement($generalDesc, $countryElement,
585
            'fixedLine');
586
        $this->assertEquals('\\d{6}', $phoneNumberDesc->getNationalNumberPattern());
587
    }
588
589
    public function testSetRelevantDescPatternsSetsSameMobileAndFixedLinePattern()
590
    {
591
        $xmlInput = "<territory countryCode=\"33\">"
592
            . "  <fixedLine><nationalNumberPattern>\\d{6}</nationalNumberPattern></fixedLine>"
593
            . "  <mobile><nationalNumberPattern>\\d{6}</nationalNumberPattern></mobile>"
594
            . "</territory>";
595
596
        $territoryElement = $this->parseXMLString($xmlInput);
597
        $metadata = new PhoneMetadata();
598
        // Should set sameMobileAndFixedPattern to true.
599
        BuildMetadataFromXml::setRelevantDescPatterns($metadata, $territoryElement, false /* isShortNumberMetadata */);
600
        $this->assertTrue($metadata->getSameMobileAndFixedLinePattern());
601
    }
602
603
    public function testSetRelevantDescPatternsSetsAllDescriptionsForRegularLengthNumbers()
604
    {
605
        $xmlInput = "<territory countryCode=\"33\">"
606
            . "  <fixedLine><nationalNumberPattern>\\d{1}</nationalNumberPattern></fixedLine>"
607
            . "  <mobile><nationalNumberPattern>\\d{2}</nationalNumberPattern></mobile>"
608
            . "  <pager><nationalNumberPattern>\\d{3}</nationalNumberPattern></pager>"
609
            . "  <tollFree><nationalNumberPattern>\\d{4}</nationalNumberPattern></tollFree>"
610
            . "  <premiumRate><nationalNumberPattern>\\d{5}</nationalNumberPattern></premiumRate>"
611
            . "  <sharedCost><nationalNumberPattern>\\d{6}</nationalNumberPattern></sharedCost>"
612
            . "  <personalNumber><nationalNumberPattern>\\d{7}</nationalNumberPattern></personalNumber>"
613
            . "  <voip><nationalNumberPattern>\\d{8}</nationalNumberPattern></voip>"
614
            . "  <uan><nationalNumberPattern>\\d{9}</nationalNumberPattern></uan>"
615
            . "</territory>";
616
617
        $territoryElement = $this->parseXMLString($xmlInput);
618
        $metadata = new PhoneMetadata();
619
        BuildMetadataFromXml::setRelevantDescPatterns($metadata, $territoryElement, false /* isShortNumberMetadata */);
620
        $this->assertEquals("\\d{1}", $metadata->getFixedLine()->getNationalNumberPattern());
621
        $this->assertEquals("\\d{2}", $metadata->getMobile()->getNationalNumberPattern());
622
        $this->assertEquals("\\d{3}", $metadata->getPager()->getNationalNumberPattern());
623
        $this->assertEquals("\\d{4}", $metadata->getTollFree()->getNationalNumberPattern());
624
        $this->assertEquals("\\d{5}", $metadata->getPremiumRate()->getNationalNumberPattern());
625
        $this->assertEquals("\\d{6}", $metadata->getSharedCost()->getNationalNumberPattern());
626
        $this->assertEquals("\\d{7}", $metadata->getPersonalNumber()->getNationalNumberPattern());
627
        $this->assertEquals("\\d{8}", $metadata->getVoip()->getNationalNumberPattern());
628
        $this->assertEquals("\\d{9}", $metadata->getUan()->getNationalNumberPattern());
629
    }
630
631
    public function testSetRelevantDescPatternsSetsAllDescriptionsForShortNumbers()
632
    {
633
        $xmlInput = "<territory ID=\"FR\">"
634
            . "  <tollFree><nationalNumberPattern>\\d{1}</nationalNumberPattern></tollFree>"
635
            . "  <standardRate><nationalNumberPattern>\\d{2}</nationalNumberPattern></standardRate>"
636
            . "  <premiumRate><nationalNumberPattern>\\d{3}</nationalNumberPattern></premiumRate>"
637
            . "  <shortCode><nationalNumberPattern>\\d{4}</nationalNumberPattern></shortCode>"
638
            . "  <carrierSpecific>"
639
            . "    <nationalNumberPattern>\\d{5}</nationalNumberPattern>"
640
            . "  </carrierSpecific>"
641
            . "</territory>";
642
643
        $territoryElement = $this->parseXMLString($xmlInput);
644
        $metadata = new PhoneMetadata();
645
        BuildMetadataFromXml::setRelevantDescPatterns($metadata, $territoryElement, true /* isShortNumberMetadata */);
646
        $this->assertEquals("\\d{1}", $metadata->getTollFree()->getNationalNumberPattern());
647
        $this->assertEquals("\\d{2}", $metadata->getStandardRate()->getNationalNumberPattern());
648
        $this->assertEquals("\\d{3}", $metadata->getPremiumRate()->getNationalNumberPattern());
649
        $this->assertEquals("\\d{4}", $metadata->getShortCode()->getNationalNumberPattern());
650
        $this->assertEquals("\\d{5}", $metadata->getCarrierSpecific()->getNationalNumberPattern());
651
    }
652
653
    /**
654
     * @expectedException \RuntimeException
655
     * @expectedExceptionMessage Multiple elements with type fixedLine found.
656
     */
657
    public function testSetRelevantDescPatternsThrowsErrorIfTypePresentMultipleTimes()
658
    {
659
        $xmlInput = "<territory countryCode=\"33\">"
660
            . "  <fixedLine><nationalNumberPattern>\\d{6}</nationalNumberPattern></fixedLine>"
661
            . "  <fixedLine><nationalNumberPattern>\\d{6}</nationalNumberPattern></fixedLine>"
662
            . "</territory>";
663
664
        $territoryElement = $this->parseXMLString($xmlInput);
665
        $metadata = new PhoneMetadata();
666
        BuildMetadataFromXml::setRelevantDescPatterns($metadata, $territoryElement, false /* isShortNumberMetadata */);
667
    }
668
669
    public function testAlternateFormatsOmitsDescPatterns()
670
    {
671
        $xmlInput = "<territory countryCode=\"33\">"
672
            . "  <availableFormats>"
673
            . "    <numberFormat pattern=\"(1)(\\d{3})\">"
674
            . "      <leadingDigits>1</leadingDigits>"
675
            . '      <format>$1</format>'
676
            . "    </numberFormat>"
677
            . "  </availableFormats>"
678
            . "  <fixedLine><nationalNumberPattern>\\d{1}</nationalNumberPattern></fixedLine>"
679
            . "  <shortCode><nationalNumberPattern>\\d{2}</nationalNumberPattern></shortCode>"
680
            . "</territory>";
681
682
        $territoryElement = $this->parseXMLString($xmlInput);
683
        $metadata = BuildMetadataFromXml::loadCountryMetadata('FR', $territoryElement, false
0 ignored issues
show
Documentation introduced by
false is of type boolean, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
684
            /* isShortNumberMetadata */, true /* isAlternateFormatsMetadata */);
0 ignored issues
show
Documentation introduced by
true is of type boolean, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
685
        $this->assertEquals('(1)(\\d{3})', $metadata->getNumberFormat(0)->getPattern());
686
        $this->assertEquals('1', $metadata->getNumberFormat(0)->getLeadingDigitsPattern(0));
687
        $this->assertEquals('$1', $metadata->getNumberFormat(0)->getFormat());
688
        $this->assertNull($metadata->getFixedLine());
689
        $this->assertNull($metadata->getShortCode());
690
    }
691
692
    public function testNationalPrefixRulesSetCorrectly()
693
    {
694
        $xmlInput = "<territory countryCode=\"33\" nationalPrefix=\"0\""
695
            . ' nationalPrefixFormattingRule="$NP$FG">'
696
            . "  <availableFormats>"
697
            . "    <numberFormat pattern=\"(1)(\\d{3})\" nationalPrefixOptionalWhenFormatting=\"true\">"
698
            . "      <leadingDigits>1</leadingDigits>"
699
            . '      <format>$1</format>'
700
            . "    </numberFormat>"
701
            . "    <numberFormat pattern=\"(\\d{3})\" nationalPrefixOptionalWhenFormatting=\"false\">"
702
            . "      <leadingDigits>2</leadingDigits>"
703
            . '      <format>$1</format>'
704
            . "    </numberFormat>"
705
            . "  </availableFormats>"
706
            . "  <fixedLine><nationalNumberPattern>\\d{1}</nationalNumberPattern></fixedLine>"
707
            . "</territory>";
708
        $territoryElement = $this->parseXMLString($xmlInput);
709
        $metadata = BuildMetadataFromXml::loadCountryMetadata('FR', $territoryElement, false
0 ignored issues
show
Documentation introduced by
false is of type boolean, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
710
            /* isShortNumberMetadata */, true /* isAlternateFormatsMetadata */);
0 ignored issues
show
Documentation introduced by
true is of type boolean, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
711
        $this->assertTrue($metadata->getNumberFormat(0)->getNationalPrefixOptionalWhenFormatting());
712
        // This is inherited from the territory, with $NP replaced by the actual national prefix, and
713
        // $FG replaced with $1.
714
        $this->assertEquals("0$1", $metadata->getNumberFormat(0)->getNationalPrefixFormattingRule());
715
        // Here it is explicitly set to false.
716
        $this->assertFalse($metadata->getNumberFormat(1)->getNationalPrefixOptionalWhenFormatting());
717
    }
718
719
    public function testProcessPhoneNumberDescElement_PossibleLengthsSetCorrectly()
720
    {
721
        $generalDesc = new PhoneNumberDesc();
722
        // The number lengths set for the general description must be a super-set of those in the
723
        // element being parsed.
724
        $generalDesc->setPossibleLength(array(4, 6, 7, 13));
725
        $territoryElement = $this->parseXMLString("<territory>"
726
            . "<fixedLine>"
727
            // Sorting will be done when parsing.
728
            . "  <possibleLengths national=\"13,4\" localOnly=\"6\"/>"
729
            . "</fixedLine>"
730
            . "</territory>");
731
732
        $fixedLine = BuildMetadataFromXml::processPhoneNumberDescElement($generalDesc, $territoryElement,
733
            'fixedLine');
734
        $mobile = BuildMetadataFromXml::processPhoneNumberDescElement($generalDesc, $territoryElement,
735
            'mobile');
736
737
        $possibleLength = $fixedLine->getPossibleLength();
738
        $this->assertCount(2, $possibleLength);
739
        $this->assertEquals(4, $possibleLength[0]);
740
        $this->assertEquals(13, $possibleLength[1]);
741
        $this->assertCount(1, $fixedLine->getPossibleLengthLocalOnly());
742
743
        // We use [-1] to denote that there are no possible lengths; we don't leave it empty, since for
744
        // compression reasons, we use the empty list to mean that the generalDesc possible lengths
745
        // apply.
746
        $mobileLength = $mobile->getPossibleLength();
747
        $this->assertCount(1, $mobileLength);
748
        $this->assertEquals(-1, $mobileLength[0]);
749
        $this->assertCount(0, $mobile->getPossibleLengthLocalOnly());
750
    }
751
752
    public function testSetPossibleLengthsGeneralDesc_BuiltFromChildElements()
753
    {
754
        $territoryElement = $this->parseXMLString("<territory>"
755
            . "<fixedLine>"
756
            . "  <possibleLengths national=\"13\" localOnly=\"6\"/>"
757
            . "</fixedLine>"
758
            . "<mobile>"
759
            . "  <possibleLengths national=\"15\" localOnly=\"7,13\"/>"
760
            . "</mobile>"
761
            . "<tollFree>"
762
            . "  <possibleLengths national=\"15\"/>"
763
            . "</tollFree>"
764
            . "</territory>");
765
766
        $generalDesc = new PhoneNumberDesc();
767
        BuildMetadataFromXml::setPossibleLengthsGeneralDesc($generalDesc, 'someId', $territoryElement,
768
            false /* not short-number metadata */);
769
770
        $possibleLength = $generalDesc->getPossibleLength();
771
        $this->assertCount(2, $possibleLength);
772
        $this->assertEquals(13, $possibleLength[0]);
773
        // 15 is present twice in the input in different sections, but only once in the output.
774
        $this->assertEquals(15, $possibleLength[1]);
775
        $possibleLengthLocalOnly = $generalDesc->getPossibleLengthLocalOnly();
776
        $this->assertCount(2, $possibleLengthLocalOnly);
777
        $this->assertEquals(6, $possibleLengthLocalOnly[0]);
778
        $this->assertEquals(7, $possibleLengthLocalOnly[1]);
779
        // 13 is skipped as a "local only" length, since it is also present as a normal length.
780
    }
781
782
    public function testSetPossibleLengthsGeneralDesc_IgnoresNoIntlDialling()
783
    {
784
        $territoryElement = $this->parseXMLString("<territory>"
785
            . "<fixedLine>"
786
            . "  <possibleLengths national=\"13\"/>"
787
            . "</fixedLine>"
788
            . "<noInternationalDialling>"
789
            . "  <possibleLengths national=\"15\"/>"
790
            . "</noInternationalDialling>"
791
            . "</territory>");
792
793
        $generalDesc = new PhoneNumberDesc();
794
        BuildMetadataFromXml::setPossibleLengthsGeneralDesc($generalDesc, 'someId', $territoryElement,
795
            false /* not short-number metadata */);
796
797
        $possibleLength = $generalDesc->getPossibleLength();
798
        $this->assertCount(1, $possibleLength);
799
        $this->assertEquals(13, $possibleLength[0]);
800
        // 15 is skipped because noInternationalDialling should not contribute to the general lengths;
801
        // it isn't a particular "type" of number per se, it is a property that different types may
802
        // have.
803
    }
804
805
    public function testSetPossibleLengthsGeneralDesc_ShortNumberMetadata()
806
    {
807
        $territoryElement = $this->parseXMLString("<territory>"
808
            . "<shortCode>"
809
            . "  <possibleLengths national=\"6,13\"/>"
810
            . "</shortCode>"
811
            . "<carrierSpecific>"
812
            . "  <possibleLengths national=\"7,13,15\"/>"
813
            . "</carrierSpecific>"
814
            . "<tollFree>"
815
            . "  <possibleLengths national=\"15\"/>"
816
            . "</tollFree>"
817
            . "</territory>");
818
819
        $generalDesc = new PhoneNumberDesc();
820
        BuildMetadataFromXml::setPossibleLengthsGeneralDesc($generalDesc, 'someId', $territoryElement,
821
            true /* short-number metadata */);
822
823
        // All elements other than shortCode are ignored when creating the general desc.
824
        $possibleLength = $generalDesc->getPossibleLength();
825
        $this->assertCount(2, $possibleLength);
826
        $this->assertEquals(6, $possibleLength[0]);
827
        $this->assertEquals(13, $possibleLength[1]);
828
    }
829
830
    /**
831
     * @expectedException \RuntimeException
832
     * @expectedExceptionMessage Found local-only lengths in short-number metadata
833
     */
834
    public function testSetPossibleLengthsGeneralDesc_ShortNumberMetadataErrorsOnLocalLengths()
835
    {
836
        $territoryElement = $this->parseXMLString("<territory>"
837
            . "<shortCode>"
838
            . "  <possibleLengths national=\"13\" localOnly=\"6\"/>"
839
            . "</shortCode>"
840
            . "</territory>");
841
842
        $generalDesc = new PhoneNumberDesc();
843
        BuildMetadataFromXml::setPossibleLengthsGeneralDesc($generalDesc, 'someId', $territoryElement,
844
            true /* short-number metadata */);
845
    }
846
847
    /**
848
     * @expectedException \RuntimeException
849
     * @expectedExceptionMessage Duplicate length element found (6) in possibleLength string 6,6
850
     */
851
    public function testProcessPhoneNumberDescElement_ErrorDuplicates()
852
    {
853
        $generalDesc = new PhoneNumberDesc();
854
        $generalDesc->setPossibleLength(array(6));
855
856
        $territoryElement = $this->parseXMLString("<territory>"
857
            . "<mobile>"
858
            . "  <possibleLengths national=\"6,6\"/>"
859
            . "</mobile>"
860
            . "</territory>");
861
862
        BuildMetadataFromXml::processPhoneNumberDescElement($generalDesc, $territoryElement, 'mobile');
863
    }
864
865
    /**
866
     * @expectedException \RuntimeException
867
     * @expectedExceptionMessage Possible length(s) found specified as a normal and local-only length: [6]
868
     */
869
    public function testProcessPhoneNumberDescElement_ErrorDuplicatesOneLocal()
870
    {
871
        $generalDesc = new PhoneNumberDesc();
872
        $generalDesc->setPossibleLength(array(6));
873
874
        $territoryElement = $this->parseXMLString("<territory>"
875
            . "<mobile>"
876
            . "  <possibleLengths national=\"6\" localOnly=\"6\"/>"
877
            . "</mobile>"
878
            . "</territory>");
879
880
        BuildMetadataFromXml::processPhoneNumberDescElement($generalDesc, $territoryElement, 'mobile');
881
    }
882
883
    /**
884
     * @expectedException \RuntimeException
885
     * @expectedExceptionMessage Out-of-range possible length
886
     */
887
    public function testProcessPhoneNumberDescElement_ErrorUncoveredLengths()
888
    {
889
        $generalDesc = new PhoneNumberDesc();
890
        $generalDesc->setPossibleLength(array(4));
891
892
        $territoryElement = $this->parseXMLString("<territory>"
893
            . "<noInternationalDialling>"
894
            // Sorting will be done when parsing.
895
            . "  <possibleLengths national=\"6,7,4\"/>"
896
            . "</noInternationalDialling>"
897
            . "</territory>");
898
899
        BuildMetadataFromXml::processPhoneNumberDescElement($generalDesc, $territoryElement, 'noInternationalDialling');
900
    }
901
902
    public function testProcessPhoneNumberDescElement_SameAsParent()
903
    {
904
        $generalDesc = new PhoneNumberDesc();
905
        // The number lengths set for the general description must be a super-set of those in the
906
        // element being parsed.
907
        $generalDesc->setPossibleLength(array(4, 6, 7));
908
        $generalDesc->setPossibleLengthLocalOnly(array(2));
909
        $territoryElement = $this->parseXMLString("<territory>"
910
            . "<fixedLine>"
911
            // Sorting will be done when parsing.
912
            . "  <possibleLengths national=\"6,7,4\" localOnly=\"2\"/>"
913
            . "</fixedLine>"
914
            . "</territory>");
915
916
        $phoneNumberDesc = BuildMetadataFromXml::processPhoneNumberDescElement($generalDesc, $territoryElement,
917
            'fixedLine');
918
919
        // No possible lengths should be present, because they match the general description.
920
        $this->assertCount(0, $phoneNumberDesc->getPossibleLength());
921
        // Local-only lengths should be present for child elements such as fixed-line
922
        $this->assertCount(1, $phoneNumberDesc->getPossibleLengthLocalOnly());
923
    }
924
925
    /**
926
     * @expectedException \RuntimeException
927
     * @expectedExceptionMessage For input string "4d"
928
     */
929
    public function testProcessPhoneNumberDescElement_InvalidNumber()
930
    {
931
        $generalDesc = new PhoneNumberDesc();
932
        $generalDesc->setPossibleLength(array(4));
933
        $territoryElement = $this->parseXMLString("<territory>"
934
            . "<fixedLine>"
935
            . "  <possibleLengths national=\"4d\"/>"
936
            . "</fixedLine>"
937
            . "</territory>");
938
939
        BuildMetadataFromXml::processPhoneNumberDescElement($generalDesc, $territoryElement, 'fixedLine');
940
    }
941
942
    /**
943
     * @expectedException \RuntimeException
944
     * @expectedExceptionMessage Found possible lengths specified at general desc: this should be derived from child elements. Affected country: FR
945
     */
946
    public function testLoadCountryMetadata_GeneralDescHasNumberLengthsSet()
947
    {
948
        $territoryElement = $this->parseXMLString("<territory>"
949
            . "<generalDesc>"
950
            // This shouldn't be set, the possible lengths should be derived for generalDesc.
951
            . "  <possibleLengths national=\"4\"/>"
952
            . "</generalDesc>"
953
            . "<fixedLine>"
954
            . "  <possibleLengths national=\"4\"/>"
955
            . "</fixedLine>"
956
            . "</territory>");
957
958
        BuildMetadataFromXml::loadCountryMetadata('FR', $territoryElement, false /* isShortNumberMetadata */,
0 ignored issues
show
Documentation introduced by
false is of type boolean, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
959
            false /* isAlternateFormatsMetadata */);
0 ignored issues
show
Documentation introduced by
false is of type boolean, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
960
    }
961
962
    /**
963
     * @expectedException \RuntimeException
964
     * @expectedExceptionMessage Empty possibleLength string found.
965
     */
966
    public function testProcessPhoneNumberDescElement_ErrorEmptyPossibleLengthStringAttribute()
967
    {
968
        $generalDesc = new PhoneNumberDesc();
969
        $generalDesc->setPossibleLength(array(4));
970
        $territoryElement = $this->parseXMLString("<territory>"
971
            . "<fixedLine>"
972
            . "  <possibleLengths national=\"\"/>"
973
            . "</fixedLine>"
974
            . "</territory>");
975
976
        BuildMetadataFromXml::processPhoneNumberDescElement($generalDesc, $territoryElement, 'fixedLine');
977
    }
978
979
    /**
980
     * @expectedException \RuntimeException
981
     * @expectedExceptionMessage Missing end of range character in possible length string [4,7].
982
     */
983
    public function testProcessPhoneNumberDescElement_ErrorRangeSpecifiedWithComma()
984
    {
985
        $generalDesc = new PhoneNumberDesc();
986
        $generalDesc->setPossibleLength(array(4));
987
        $territoryElement = $this->parseXMLString("<territory>"
988
            . "<fixedLine>"
989
            . "  <possibleLengths national=\"[4,7]\"/>"
990
            . "</fixedLine>"
991
            . "</territory>");
992
993
        BuildMetadataFromXml::processPhoneNumberDescElement($generalDesc, $territoryElement, 'fixedLine');
994
    }
995
996
    /**
997
     * @expectedException \RuntimeException
998
     * @expectedExceptionMessage Missing end of range character in possible length string [4-.
999
     */
1000
    public function testProcessPhoneNumberDescElement_ErrorIncompleteRange()
1001
    {
1002
        $generalDesc = new PhoneNumberDesc();
1003
        $generalDesc->setPossibleLength(array(4));
1004
1005
        $territoryElement = $this->parseXMLString("<territory>"
1006
            . "<fixedLine>"
1007
            . "  <possibleLengths national=\"[4-\"/>"
1008
            . "</fixedLine>"
1009
            . "</territory>");
1010
1011
        BuildMetadataFromXml::processPhoneNumberDescElement($generalDesc, $territoryElement, 'fixedLine');
1012
    }
1013
1014
    /**
1015
     * @expectedException \RuntimeException
1016
     * @expectedExceptionMessage Ranges must have exactly one - character: missing for [4:10].
1017
     */
1018
    public function testProcessPhoneNumberDescElement_ErrorNoDashInRange()
1019
    {
1020
        $generalDesc = new PhoneNumberDesc();
1021
        $generalDesc->setPossibleLength(array(4));
1022
        $territoryElement = $this->parseXMLString("<territory>"
1023
            . "<fixedLine>"
1024
            . "  <possibleLengths national=\"[4:10]\"/>"
1025
            . "</fixedLine>"
1026
            . "</territory>");
1027
1028
        BuildMetadataFromXml::processPhoneNumberDescElement($generalDesc, $territoryElement, 'fixedLine');
1029
    }
1030
1031
    /**
1032
     * @expectedException \RuntimeException
1033
     * @expectedExceptionMessage The first number in a range should be two or more digits lower than the second. Culprit possibleLength string: [10-10]
1034
     */
1035
    public function testProcessPhoneNumberDescElement_ErrorRangeIsNotFromMinToMax()
1036
    {
1037
        $generalDesc = new PhoneNumberDesc();
1038
        $generalDesc->setPossibleLength(array(4));
1039
        $territoryElement = $this->parseXMLString("<territory>"
1040
            . "<fixedLine>"
1041
            . "  <possibleLengths national=\"[10-10]\"/>"
1042
            . "</fixedLine>"
1043
            . "</territory>");
1044
1045
        BuildMetadataFromXml::processPhoneNumberDescElement($generalDesc, $territoryElement, 'fixedLine');
1046
    }
1047
1048
    public function testGetMetadataFilter()
1049
    {
1050
        $this->assertEquals(BuildMetadataFromXml::getMetadataFilter(false, false), MetadataFilter::emptyFilter());
1051
        $this->assertEquals(BuildMetadataFromXml::getMetadataFilter(true, false), MetadataFilter::forLiteBuild());
1052
        $this->assertEquals(BuildMetadataFromXml::getMetadataFilter(false, true), MetadataFilter::forSpecialBuild());
1053
1054
        try {
1055
            BuildMetadataFromXml::getMetadataFilter(true, true);
1056
            $this->fail("getMetadataFilter should fail when liteBuild and specialBuild are both set");
1057
        } catch (\RuntimeException $e) {
1058
            $this->assertEquals("liteBuild and specialBuild may not both be set", $e->getMessage());
1059
        }
1060
    }
1061
}
1062