Completed
Push — upstream-8.5.2 ( a7fcfc )
by Joshua
11:38
created

testSetPossibleLengthsGeneralDesc_ShortNumberMetadata()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 24
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 24
rs 8.9713
c 0
b 0
f 0
cc 1
eloc 19
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->isLeadingZeroPossible());
116
        $this->assertTrue($phoneMetadata->isMobileNumberPortableRegion());
117
    }
118
119
    public function testLoadTerritoryTagMetadataSetsBooleanFieldsToFalseByDefault()
120
    {
121
        $xmlInput = "<territory countryCode='33'/>";
122
        $territoryElement = $this->parseXMLString($xmlInput);
123
        $phoneMetadata = BuildMetadataFromXml::loadTerritoryTagMetadata('33', $territoryElement, '');
124
        $this->assertFalse($phoneMetadata->isMainCountryForCode());
125
        $this->assertFalse($phoneMetadata->isLeadingZeroPossible());
126
        $this->assertFalse($phoneMetadata->isMobileNumberPortableRegion());
127
    }
128
129
    public function testLoadTerritoryTagMetadataSetsNationalPrefixForParsingByDefault()
130
    {
131
        $xmlInput = "<territory countryCode='33'/>";
132
        $territoryElement = $this->parseXMLString($xmlInput);
133
        $phoneMetadata = BuildMetadataFromXml::loadTerritoryTagMetadata('33', $territoryElement, '00');
134
        // When unspecified, nationalPrefixForParsing defaults to nationalPrefix.
135
        $this->assertEquals("00", $phoneMetadata->getNationalPrefix());
136
        $this->assertEquals($phoneMetadata->getNationalPrefix(), $phoneMetadata->getNationalPrefixForParsing());
137
    }
138
139
    public function testLoadTerritoryTagMetadataWithRequiredAttributesOnly()
140
    {
141
        $xmlInput = "<territory countryCode='33' internationalPrefix='00'/>";
142
        $territoryElement = $this->parseXMLString($xmlInput);
143
        // Should not throw any exception
144
        BuildMetadataFromXml::loadTerritoryTagMetadata('33', $territoryElement, '');
145
    }
146
147
    public function testLoadInternationalFormat()
148
    {
149
        $intlFormat = '$1 $2';
150
        $xmlInput = "<numberFormat><intlFormat>" . $intlFormat . "</intlFormat></numberFormat>";
151
        $numberFormatElement = $this->parseXMLString($xmlInput);
152
        $metadata = new PhoneMetadata();
153
        $nationalFormat = new NumberFormat();
154
155
        $this->assertTrue(BuildMetadataFromXml::loadInternationalFormat($metadata, $numberFormatElement,
156
            $nationalFormat));
157
        $this->assertEquals($intlFormat, $metadata->getIntlNumberFormat(0)->getFormat());
158
    }
159
160
    public function testLoadInternationalFormatWithBothNationalAndIntlFormatsDefined()
161
    {
162
        $intlFormat = '$1 $2';
163
        $xmlInput = "<numberFormat><intlFormat>" . $intlFormat . "</intlFormat></numberFormat>";
164
        $numberFormatElement = $this->parseXMLString($xmlInput);
165
        $metadata = new PhoneMetadata();
166
        $nationalFormat = new NumberFormat();
167
        $nationalFormat->setFormat('$1');
168
169
        $this->assertTrue(BuildMetadataFromXml::loadInternationalFormat($metadata, $numberFormatElement,
170
            $nationalFormat));
171
        $this->assertEquals($intlFormat, $metadata->getIntlNumberFormat(0)->getFormat());
172
    }
173
174
    /**
175
     * @expectedException \RuntimeException
176
     */
177
    public function testLoadInternationalFormatExpectsOnlyOnePattern()
178
    {
179
        $xmlInput = '<numberFormat><intlFormat/><intlFormat/></numberFormat>';
180
        $numberFormatElement = $this->parseXMLString($xmlInput);
181
        $metadata = new PhoneMetadata();
182
183
        // Should throw an exception as multiple intlFormats are provided
184
        BuildMetadataFromXml::loadInternationalFormat($metadata, $numberFormatElement, new NumberFormat());
185
    }
186
187
    public function testLoadInternationalFormatUsesNationalFormatByDefault()
188
    {
189
        $xmlInput = '<numberFormat></numberFormat>';
190
        $numberFormatElement = $this->parseXMLString($xmlInput);
191
        $metadata = new PhoneMetadata();
192
        $nationalFormat = new NumberFormat();
193
        $nationPattern = '$1 $2 $3';
194
        $nationalFormat->setFormat($nationPattern);
195
196
        $this->assertFalse(BuildMetadataFromXml::loadInternationalFormat($metadata, $numberFormatElement,
197
            $nationalFormat));
198
        $this->assertEquals($nationPattern, $metadata->getIntlNumberFormat(0)->getFormat());
199
    }
200
201
    public function testLoadInternationalFormatCopiesNationalFormatData()
202
    {
203
        $xmlInput = '<numberFormat></numberFormat>';
204
        $numberFormatElement = $this->parseXMLString($xmlInput);
205
        $metadata = new PhoneMetadata();
206
        $nationalFormat = new NumberFormat();
207
        $nationalFormat->setFormat('$1-$2');
208
        $nationalFormat->setNationalPrefixOptionalWhenFormatting(true);
209
210
        $this->assertFalse(BuildMetadataFromXml::loadInternationalFormat($metadata, $numberFormatElement,
211
            $nationalFormat));
212
        $this->assertTrue($metadata->getIntlNumberFormat(0)->getNationalPrefixOptionalWhenFormatting());
213
    }
214
215
    public function testLoadNationalFormat()
216
    {
217
        $nationalFormat = '$1 $2';
218
        $xmlInput = '<numberFormat><format>' . $nationalFormat . '</format></numberFormat>';
219
        $numberFormatElement = $this->parseXMLString($xmlInput);
220
        $metadata = new PhoneMetadata();
221
        $numberFormat = new NumberFormat();
222
        BuildMetadataFromXml::loadNationalFormat($metadata, $numberFormatElement, $numberFormat);
223
        $this->assertEquals($nationalFormat, $numberFormat->getFormat());
224
    }
225
226
    /**
227
     * @expectedException \RuntimeException
228
     */
229
    public function testLoadNationalFormatRequiresFormat()
230
    {
231
        $xmlInput = '<numberFormat></numberFormat>';
232
        $numberFormatElement = $this->parseXMLString($xmlInput);
233
        $metadata = new PhoneMetadata();
234
        $numberFormat = new NumberFormat();
235
236
        BuildMetadataFromXml::loadNationalFormat($metadata, $numberFormatElement, $numberFormat);
237
    }
238
239
    /**
240
     * @expectedException \RuntimeException
241
     */
242
    public function testLoadNationalFormatExpectsExactlyOneFormat()
243
    {
244
        $xmlInput = "<numberFormat><format/><format/></numberFormat>";
245
        $numberFormatElement = $this->parseXMLString($xmlInput);
246
        $metadata = new PhoneMetadata();
247
        $numberFormat = new NumberFormat();
248
249
        BuildMetadataFromXml::loadNationalFormat($metadata, $numberFormatElement, $numberFormat);
250
    }
251
252
    public function testLoadAvailableFormats()
253
    {
254
        $xmlInput = '<territory>'
255
            . '  <availableFormats>'
256
            . '    <numberFormat nationalPrefixFormattingRule=\'($FG)\''
257
            . '                  carrierCodeFormattingRule=\'$NP $CC ($FG)\'>'
258
            . '      <format>$1 $2 $3</format>'
259
            . '    </numberFormat>'
260
            . '  </availableFormats>'
261
            . '</territory>';
262
263
        $element = $this->parseXMLString($xmlInput);
264
        $metadata = new PhoneMetadata();
265
        BuildMetadataFromXml::loadAvailableFormats($metadata, $element, '0', '', false /* NP not optional */);
266
        $this->assertEquals('($1)', $metadata->getNumberFormat(0)->getNationalPrefixFormattingRule());
267
        $this->assertEquals('0 $CC ($1)', $metadata->getNumberFormat(0)->getDomesticCarrierCodeFormattingRule());
268
        $this->assertEquals('$1 $2 $3', $metadata->getNumberFormat(0)->getFormat());
269
    }
270
271
    public function testLoadAvailableFormatsPropagatesCarrierCodeFormattingRule()
272
    {
273
        $xmlInput =
274
            '<territory carrierCodeFormattingRule=\'$NP $CC ($FG)\'>'
275
            . '  <availableFormats>'
276
            . '    <numberFormat nationalPrefixFormattingRule=\'($FG)\'>'
277
            . '      <format>$1 $2 $3</format>'
278
            . '    </numberFormat>'
279
            . '  </availableFormats>'
280
            . '</territory>';
281
282
        $element = $this->parseXMLString($xmlInput);
283
        $metadata = new PhoneMetadata();
284
        BuildMetadataFromXml::loadAvailableFormats($metadata, $element, '0', '', false /* NP not optional */);
285
        $this->assertEquals('($1)', $metadata->getNumberFormat(0)->getNationalPrefixFormattingRule());
286
        $this->assertEquals('0 $CC ($1)', $metadata->getNumberFormat(0)->getDomesticCarrierCodeFormattingRule());
287
        $this->assertEquals('$1 $2 $3', $metadata->getNumberFormat(0)->getFormat());
288
    }
289
290
    public function testLoadAvailableFormatsSetsProvidedNationalPrefixFormattingRule()
291
    {
292
        $xmlInput = "<territory>"
293
            . "  <availableFormats>"
294
            . '    <numberFormat><format>$1 $2 $3</format></numberFormat>'
295
            . "  </availableFormats>"
296
            . "</territory>";
297
298
        $element = $this->parseXMLString($xmlInput);
299
        $metadata = new PhoneMetadata();
300
        BuildMetadataFromXml::loadAvailableFormats($metadata, $element, '', '($1)', false /* NP not optional */);
301
        $this->assertEquals('($1)', $metadata->getNumberFormat(0)->getNationalPrefixFormattingRule());
302
    }
303
304
    public function testLoadAvailableFormatsClearsIntlFormat()
305
    {
306
        $xmlInput = "<territory>"
307
            . "  <availableFormats>"
308
            . '    <numberFormat><format>$1 $2 $3</format></numberFormat>'
309
            . "  </availableFormats>"
310
            . "</territory>";
311
312
        $element = $this->parseXMLString($xmlInput);
313
        $metadata = new PhoneMetadata();
314
        BuildMetadataFromXml::loadAvailableFormats($metadata, $element, '0', '($1)', false /* NP not optional */);
315
        $this->assertCount(0, $metadata->intlNumberFormats());
316
    }
317
318
    public function testLoadAvailableFormatsHandlesMultipleNumberFormats()
319
    {
320
        $xmlInput = "<territory>"
321
            . "  <availableFormats>"
322
            . '    <numberFormat><format>$1 $2 $3</format></numberFormat>'
323
            . '    <numberFormat><format>$1-$2</format></numberFormat>'
324
            . "  </availableFormats>"
325
            . "</territory>";
326
327
        $element = $this->parseXMLString($xmlInput);
328
        $metadata = new PhoneMetadata();
329
        BuildMetadataFromXml::loadAvailableFormats($metadata, $element, '0', '($1)', false /* NP not optional */);
330
        $this->assertEquals('$1 $2 $3', $metadata->getNumberFormat(0)->getFormat());
331
        $this->assertEquals('$1-$2', $metadata->getNumberFormat(1)->getFormat());
332
    }
333
334
    public function testLoadInternationalFormatDoesNotSetIntlFormatWhenNA()
335
    {
336
        $xmlInput = '<numberFormat><intlFormat>NA</intlFormat></numberFormat>';
337
        $numberFormatElement = $this->parseXMLString($xmlInput);
338
        $metadata = new PhoneMetadata();
339
        $nationalFormat = new NumberFormat();
340
        $nationalFormat->setFormat('$1 $2');
341
342
        BuildMetadataFromXml::loadInternationalFormat($metadata, $numberFormatElement, $nationalFormat);
343
        $this->assertCount(0, $metadata->intlNumberFormats());
344
    }
345
346
    public function testSetLeadingDigitsPatterns()
347
    {
348
        $xmlInput = "<numberFormat>"
349
            . "<leadingDigits>1</leadingDigits><leadingDigits>2</leadingDigits>"
350
            . "</numberFormat>";
351
352
        $numberFormatElement = $this->parseXMLString($xmlInput);
353
        $numberFormat = new NumberFormat();
354
        BuildMetadataFromXml::setLeadingDigitsPatterns($numberFormatElement, $numberFormat);
355
356
        $this->assertEquals('1', $numberFormat->getLeadingDigitsPattern(0));
357
        $this->assertEquals('2', $numberFormat->getLeadingDigitsPattern(1));
358
    }
359
360
    /**
361
     * Tests setLeadingDigitsPatterns() in the case of international and national formatting rules
362
     * being present but not both defined for this numberFormat - we don't want to add them twice.
363
     */
364
    public function testSetLeadingDigitsPatternsNotAddedTwiceWhenInternationalFormatsPresent()
365
    {
366
        $xmlInput = "<availableFormats>"
367
            . "  <numberFormat pattern=\"(1)(\\d{3})\">"
368
            . "    <leadingDigits>1</leadingDigits>"
369
            . '    <format>$1</format>'
370
            . "  </numberFormat>"
371
            . "  <numberFormat pattern=\"(2)(\\d{3})\">"
372
            . "    <leadingDigits>2</leadingDigits>"
373
            . '    <format>$1</format>'
374
            . '    <intlFormat>9-$1</intlFormat>'
375
            . "  </numberFormat>"
376
            . "</availableFormats>";
377
378
        $element = $this->parseXMLString($xmlInput);
379
        $metadata = new PhoneMetadata();
380
        BuildMetadataFromXml::loadAvailableFormats($metadata, $element, '0', '', false /* NP not optional */);
381
        $this->assertCount(1, $metadata->getNumberFormat(0)->leadingDigitPatterns());
382
        $this->assertCount(1, $metadata->getNumberFormat(1)->leadingDigitPatterns());
383
        // When we merge the national format rules into the international format rules, we shouldn't add
384
        // the leading digit patterns multiple times.
385
        $this->assertCount(1, $metadata->getIntlNumberFormat(0)->leadingDigitPatterns());
386
        $this->assertCount(1, $metadata->getIntlNumberFormat(1)->leadingDigitPatterns());
387
    }
388
389
    public function testGetNationalPrefixFormattingRuleFromElement()
390
    {
391
        $xmlInput = '<territory nationalPrefixFormattingRule="$NP$FG" />';
392
        $element = $this->parseXMLString($xmlInput);
393
        $this->assertEquals('0$1', BuildMetadataFromXml::getNationalPrefixFormattingRuleFromElement($element, '0'));
394
    }
395
396
    public function testGetDomesticCarrierCodeFormattingRuleFromElement()
397
    {
398
        $xmlInput = '<territory carrierCodeFormattingRule=\'$NP$CC $FG\'/>';
399
        $element = $this->parseXMLString($xmlInput);
400
        $this->assertEquals('0$CC $1',
401
            BuildMetadataFromXml::getDomesticCarrierCodeFormattingRuleFromElement($element, '0'));
402
    }
403
404
    public function testProcessPhoneNumberDescElementWithInvalidInputWithRegex()
405
    {
406
        $generalDesc = new PhoneNumberDesc();
407
        $territoryElement = $this->parseXMLString("<territory/>");
408
409
        $phoneNumberDesc = BuildMetadataFromXml::processPhoneNumberDescElement($generalDesc, $territoryElement,
410
            'invalidType');
411
        $this->assertFalse($phoneNumberDesc->hasNationalNumberPattern());
412
    }
413
414
    public function testProcessPhoneNumberDescElementOverridesGeneralDesc()
415
    {
416
        $generalDesc = new PhoneNumberDesc();
417
        $generalDesc->setNationalNumberPattern('\\d{8}');
418
        $xmlInput = "<territory><fixedLine>"
419
            . "  <nationalNumberPattern>\\d{6}</nationalNumberPattern>"
420
            . "</fixedLine></territory>";
421
422
        $territoryElement = $this->parseXMLString($xmlInput);
423
424
        $phoneNumberDesc = BuildMetadataFromXml::processPhoneNumberDescElement($generalDesc, $territoryElement,
425
            'fixedLine');
426
        $this->assertEquals('\\d{6}', $phoneNumberDesc->getNationalNumberPattern());
427
    }
428
429
    public function testFilterMetadata_liteBuild()
430
    {
431
        $xmlInput = "<phoneNumberMetadata>"
432
            . "  <territories>"
433
            . "    <territory id=\"AM\" countryCode=\"374\" internationalPrefix=\"00\">"
434
            . "      <generalDesc>"
435
            . "        <nationalNumberPattern>[1-9]\\d{7}</nationalNumberPattern>"
436
            . "      </generalDesc>"
437
            . "      <fixedLine>"
438
            . "        <nationalNumberPattern>[1-9]\\d{7}</nationalNumberPattern>"
439
            . "        <possibleLengths national=\"8\" localOnly=\"5,6\"/>"
440
            . "        <exampleNumber>10123456</exampleNumber>"
441
            . "      </fixedLine>"
442
            . "      <mobile>"
443
            . "        <nationalNumberPattern>[1-9]\\d{7}</nationalNumberPattern>"
444
            . "        <possibleLengths national=\"8\" localOnly=\"5,6\"/>"
445
            . "        <exampleNumber>10123456</exampleNumber>"
446
            . "      </mobile>"
447
            . "    </territory>"
448
            . "  </territories>"
449
            . "</phoneNumberMetadata>";
450
451
        $document = $this->parseXMLString($xmlInput);
452
453
        $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...
454
            true, // liteBuild
455
            false, // specialBuild
456
            false, // isShortNumberMetadata
457
            false // isAlternateFormatsMetadata
458
        );
459
460
        $this->assertCount(1, $metadataCollection);
461
        $metadata = $metadataCollection[0];
462
463
        $this->assertTrue($metadata->hasGeneralDesc());
464
        $this->assertFalse($metadata->getGeneralDesc()->hasExampleNumber());
465
        $this->assertEquals("", $metadata->getGeneralDesc()->getExampleNumber());
466
        $this->assertTrue($metadata->hasFixedLine());
467
        $this->assertFalse($metadata->getFixedLine()->hasExampleNumber());
468
        $this->assertEquals("", $metadata->getFixedLine()->getExampleNumber());
469
        $this->assertTrue($metadata->hasMobile());
470
        $this->assertFalse($metadata->getMobile()->hasExampleNumber());
471
        $this->assertEquals("", $metadata->getMobile()->getExampleNumber());
472
    }
473
474
    public function testFilterMetadata_specialBuild()
475
    {
476
        $xmlInput = "<phoneNumberMetadata>"
477
            . "  <territories>"
478
            . "    <territory id=\"AM\" countryCode=\"374\" internationalPrefix=\"00\">"
479
            . "      <generalDesc>"
480
            . "        <nationalNumberPattern>[1-9]\\d{7}</nationalNumberPattern>"
481
            . "      </generalDesc>"
482
            . "      <fixedLine>"
483
            . "        <nationalNumberPattern>[1-9]\\d{7}</nationalNumberPattern>"
484
            . "        <possibleLengths national=\"8\" localOnly=\"5,6\"/>"
485
            . "        <exampleNumber>10123456</exampleNumber>"
486
            . "      </fixedLine>"
487
            . "      <mobile>"
488
            . "        <nationalNumberPattern>[1-9]\\d{7}</nationalNumberPattern>"
489
            . "        <possibleLengths national=\"8\" localOnly=\"5,6\"/>"
490
            . "        <exampleNumber>10123456</exampleNumber>"
491
            . "      </mobile>"
492
            . "    </territory>"
493
            . "  </territories>"
494
            . "</phoneNumberMetadata>";
495
496
        $document = $this->parseXMLString($xmlInput);
497
498
        $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...
499
            false, // liteBuild
500
            true, // specialBuild
501
            false, // isShortNumberMetadata
502
            false // isAlternateFormatsMetadata
503
        );
504
505
        $this->assertCount(1, $metadataCollection);
506
        $metadata = $metadataCollection[0];
507
        $this->assertTrue($metadata->hasGeneralDesc());
508
        $this->assertFalse($metadata->getGeneralDesc()->hasExampleNumber());
509
        $this->assertEquals("", $metadata->getGeneralDesc()->getExampleNumber());
510
        // Consider clearing fixed-line if empty after being filtered.
511
        $this->assertTrue($metadata->hasFixedLine());
512
        $this->assertFalse($metadata->getFixedLine()->hasExampleNumber());
513
        $this->assertEquals("", $metadata->getFixedLine()->getExampleNumber());
514
        $this->assertTrue($metadata->hasMobile());
515
        $this->assertTrue($metadata->getMobile()->hasExampleNumber());
516
        $this->assertEquals("10123456", $metadata->getMobile()->getExampleNumber());
517
    }
518
519
    public function testFilterMetadata_fullBuild()
520
    {
521
        $xmlInput = "<phoneNumberMetadata>"
522
            . "  <territories>"
523
            . "    <territory id=\"AM\" countryCode=\"374\" internationalPrefix=\"00\">"
524
            . "      <generalDesc>"
525
            . "        <nationalNumberPattern>[1-9]\\d{7}</nationalNumberPattern>"
526
            . "      </generalDesc>"
527
            . "      <fixedLine>"
528
            . "        <nationalNumberPattern>[1-9]\\d{7}</nationalNumberPattern>"
529
            . "        <possibleLengths national=\"8\" localOnly=\"5,6\"/>"
530
            . "        <exampleNumber>10123456</exampleNumber>"
531
            . "      </fixedLine>"
532
            . "      <mobile>"
533
            . "        <nationalNumberPattern>[1-9]\\d{7}</nationalNumberPattern>"
534
            . "        <possibleLengths national=\"8\" localOnly=\"5,6\"/>"
535
            . "        <exampleNumber>10123456</exampleNumber>"
536
            . "      </mobile>"
537
            . "    </territory>"
538
            . "  </territories>"
539
            . "</phoneNumberMetadata>";
540
541
        $document = $this->parseXMLString($xmlInput);
542
543
        $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...
544
            false, // liteBuild
545
            false, // specialBuild
546
            false, // isShortNumberMetadata
547
            false // isAlternateFormatsMetadata
548
        );
549
550
        $this->assertCount(1, $metadataCollection);
551
        $metadata = $metadataCollection[0];
552
        $this->assertTrue($metadata->hasGeneralDesc());
553
        $this->assertFalse($metadata->getGeneralDesc()->hasExampleNumber());
554
        $this->assertEquals("", $metadata->getGeneralDesc()->getExampleNumber());
555
        $this->assertTrue($metadata->hasFixedLine());
556
        $this->assertTrue($metadata->getFixedLine()->hasExampleNumber());
557
        $this->assertEquals("10123456", $metadata->getFixedLine()->getExampleNumber());
558
        $this->assertTrue($metadata->hasMobile());
559
        $this->assertTrue($metadata->getMobile()->hasExampleNumber());
560
        $this->assertEquals("10123456", $metadata->getMobile()->getExampleNumber());
561
    }
562
563
    public function testProcessPhoneNumberDescOutputsExampleNumberByDefault()
564
    {
565
        $generalDesc = new PhoneNumberDesc();
566
        $xmlInput = "<territory><fixedLine>"
567
            . "  <exampleNumber>01 01 01 01</exampleNumber>"
568
            . "</fixedLine></territory>";
569
570
        $territoryElement = $this->parseXMLString($xmlInput);
571
572
        $phoneNumberDesc = BuildMetadataFromXml::processPhoneNumberDescElement($generalDesc, $territoryElement,
573
            'fixedLine');
574
        $this->assertEquals('01 01 01 01', $phoneNumberDesc->getExampleNumber());
575
    }
576
577
    public function testProcessPhoneNumberDescRemovesWhiteSpacesInPatterns()
578
    {
579
        $generalDesc = new PhoneNumberDesc();
580
        $xmlInput = "<territory><fixedLine>"
581
            . "  <nationalNumberPattern>\t \\d { 6 } </nationalNumberPattern>"
582
            . "</fixedLine></territory>";
583
584
        $countryElement = $this->parseXMLString($xmlInput);
585
586
        $phoneNumberDesc = BuildMetadataFromXml::processPhoneNumberDescElement($generalDesc, $countryElement,
587
            'fixedLine');
588
        $this->assertEquals('\\d{6}', $phoneNumberDesc->getNationalNumberPattern());
589
    }
590
591
    public function testSetRelevantDescPatternsSetsSameMobileAndFixedLinePattern()
592
    {
593
        $xmlInput = "<territory countryCode=\"33\">"
594
            . "  <fixedLine><nationalNumberPattern>\\d{6}</nationalNumberPattern></fixedLine>"
595
            . "  <mobile><nationalNumberPattern>\\d{6}</nationalNumberPattern></mobile>"
596
            . "</territory>";
597
598
        $territoryElement = $this->parseXMLString($xmlInput);
599
        $metadata = new PhoneMetadata();
600
        // Should set sameMobileAndFixedPattern to true.
601
        BuildMetadataFromXml::setRelevantDescPatterns($metadata, $territoryElement, false /* isShortNumberMetadata */);
602
        $this->assertTrue($metadata->getSameMobileAndFixedLinePattern());
603
    }
604
605
    public function testSetRelevantDescPatternsSetsAllDescriptionsForRegularLengthNumbers()
606
    {
607
        $xmlInput = "<territory countryCode=\"33\">"
608
            . "  <fixedLine><nationalNumberPattern>\\d{1}</nationalNumberPattern></fixedLine>"
609
            . "  <mobile><nationalNumberPattern>\\d{2}</nationalNumberPattern></mobile>"
610
            . "  <pager><nationalNumberPattern>\\d{3}</nationalNumberPattern></pager>"
611
            . "  <tollFree><nationalNumberPattern>\\d{4}</nationalNumberPattern></tollFree>"
612
            . "  <premiumRate><nationalNumberPattern>\\d{5}</nationalNumberPattern></premiumRate>"
613
            . "  <sharedCost><nationalNumberPattern>\\d{6}</nationalNumberPattern></sharedCost>"
614
            . "  <personalNumber><nationalNumberPattern>\\d{7}</nationalNumberPattern></personalNumber>"
615
            . "  <voip><nationalNumberPattern>\\d{8}</nationalNumberPattern></voip>"
616
            . "  <uan><nationalNumberPattern>\\d{9}</nationalNumberPattern></uan>"
617
            . "</territory>";
618
619
        $territoryElement = $this->parseXMLString($xmlInput);
620
        $metadata = new PhoneMetadata();
621
        BuildMetadataFromXml::setRelevantDescPatterns($metadata, $territoryElement, false /* isShortNumberMetadata */);
622
        $this->assertEquals("\\d{1}", $metadata->getFixedLine()->getNationalNumberPattern());
623
        $this->assertEquals("\\d{2}", $metadata->getMobile()->getNationalNumberPattern());
624
        $this->assertEquals("\\d{3}", $metadata->getPager()->getNationalNumberPattern());
625
        $this->assertEquals("\\d{4}", $metadata->getTollFree()->getNationalNumberPattern());
626
        $this->assertEquals("\\d{5}", $metadata->getPremiumRate()->getNationalNumberPattern());
627
        $this->assertEquals("\\d{6}", $metadata->getSharedCost()->getNationalNumberPattern());
628
        $this->assertEquals("\\d{7}", $metadata->getPersonalNumber()->getNationalNumberPattern());
629
        $this->assertEquals("\\d{8}", $metadata->getVoip()->getNationalNumberPattern());
630
        $this->assertEquals("\\d{9}", $metadata->getUan()->getNationalNumberPattern());
631
    }
632
633
    public function testSetRelevantDescPatternsSetsAllDescriptionsForShortNumbers()
634
    {
635
        $xmlInput = "<territory ID=\"FR\">"
636
            . "  <tollFree><nationalNumberPattern>\\d{1}</nationalNumberPattern></tollFree>"
637
            . "  <standardRate><nationalNumberPattern>\\d{2}</nationalNumberPattern></standardRate>"
638
            . "  <premiumRate><nationalNumberPattern>\\d{3}</nationalNumberPattern></premiumRate>"
639
            . "  <shortCode><nationalNumberPattern>\\d{4}</nationalNumberPattern></shortCode>"
640
            . "  <carrierSpecific>"
641
            . "    <nationalNumberPattern>\\d{5}</nationalNumberPattern>"
642
            . "  </carrierSpecific>"
643
            . "</territory>";
644
645
        $territoryElement = $this->parseXMLString($xmlInput);
646
        $metadata = new PhoneMetadata();
647
        BuildMetadataFromXml::setRelevantDescPatterns($metadata, $territoryElement, true /* isShortNumberMetadata */);
648
        $this->assertEquals("\\d{1}", $metadata->getTollFree()->getNationalNumberPattern());
649
        $this->assertEquals("\\d{2}", $metadata->getStandardRate()->getNationalNumberPattern());
650
        $this->assertEquals("\\d{3}", $metadata->getPremiumRate()->getNationalNumberPattern());
651
        $this->assertEquals("\\d{4}", $metadata->getShortCode()->getNationalNumberPattern());
652
        $this->assertEquals("\\d{5}", $metadata->getCarrierSpecific()->getNationalNumberPattern());
653
    }
654
655
    /**
656
     * @expectedException \RuntimeException
657
     * @expectedExceptionMessage Multiple elements with type fixedLine found.
658
     */
659
    public function testSetRelevantDescPatternsThrowsErrorIfTypePresentMultipleTimes()
660
    {
661
        $xmlInput = "<territory countryCode=\"33\">"
662
            . "  <fixedLine><nationalNumberPattern>\\d{6}</nationalNumberPattern></fixedLine>"
663
            . "  <fixedLine><nationalNumberPattern>\\d{6}</nationalNumberPattern></fixedLine>"
664
            . "</territory>";
665
666
        $territoryElement = $this->parseXMLString($xmlInput);
667
        $metadata = new PhoneMetadata();
668
        BuildMetadataFromXml::setRelevantDescPatterns($metadata, $territoryElement, false /* isShortNumberMetadata */);
669
    }
670
671
    public function testAlternateFormatsOmitsDescPatterns()
672
    {
673
        $xmlInput = "<territory countryCode=\"33\">"
674
            . "  <availableFormats>"
675
            . "    <numberFormat pattern=\"(1)(\\d{3})\">"
676
            . "      <leadingDigits>1</leadingDigits>"
677
            . '      <format>$1</format>'
678
            . "    </numberFormat>"
679
            . "  </availableFormats>"
680
            . "  <fixedLine><nationalNumberPattern>\\d{1}</nationalNumberPattern></fixedLine>"
681
            . "  <shortCode><nationalNumberPattern>\\d{2}</nationalNumberPattern></shortCode>"
682
            . "</territory>";
683
684
        $territoryElement = $this->parseXMLString($xmlInput);
685
        $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...
686
            /* 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...
687
        $this->assertEquals('(1)(\\d{3})', $metadata->getNumberFormat(0)->getPattern());
688
        $this->assertEquals('1', $metadata->getNumberFormat(0)->getLeadingDigitsPattern(0));
689
        $this->assertEquals('$1', $metadata->getNumberFormat(0)->getFormat());
690
        $this->assertNull($metadata->getFixedLine());
691
        $this->assertNull($metadata->getShortCode());
692
    }
693
694
    public function testNationalPrefixRulesSetCorrectly()
695
    {
696
        $xmlInput = "<territory countryCode=\"33\" nationalPrefix=\"0\""
697
            . ' nationalPrefixFormattingRule="$NP$FG">'
698
            . "  <availableFormats>"
699
            . "    <numberFormat pattern=\"(1)(\\d{3})\" nationalPrefixOptionalWhenFormatting=\"true\">"
700
            . "      <leadingDigits>1</leadingDigits>"
701
            . '      <format>$1</format>'
702
            . "    </numberFormat>"
703
            . "    <numberFormat pattern=\"(\\d{3})\" nationalPrefixOptionalWhenFormatting=\"false\">"
704
            . "      <leadingDigits>2</leadingDigits>"
705
            . '      <format>$1</format>'
706
            . "    </numberFormat>"
707
            . "  </availableFormats>"
708
            . "  <fixedLine><nationalNumberPattern>\\d{1}</nationalNumberPattern></fixedLine>"
709
            . "</territory>";
710
        $territoryElement = $this->parseXMLString($xmlInput);
711
        $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...
712
            /* 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...
713
        $this->assertTrue($metadata->getNumberFormat(0)->getNationalPrefixOptionalWhenFormatting());
714
        // This is inherited from the territory, with $NP replaced by the actual national prefix, and
715
        // $FG replaced with $1.
716
        $this->assertEquals("0$1", $metadata->getNumberFormat(0)->getNationalPrefixFormattingRule());
717
        // Here it is explicitly set to false.
718
        $this->assertFalse($metadata->getNumberFormat(1)->getNationalPrefixOptionalWhenFormatting());
719
    }
720
721
    public function testProcessPhoneNumberDescElement_PossibleLengthsSetCorrectly()
722
    {
723
        $generalDesc = new PhoneNumberDesc();
724
        // The number lengths set for the general description must be a super-set of those in the
725
        // element being parsed.
726
        $generalDesc->setPossibleLength(array(4, 6, 7, 13));
727
        $territoryElement = $this->parseXMLString("<territory>"
728
            . "<fixedLine>"
729
            // Sorting will be done when parsing.
730
            . "  <possibleLengths national=\"13,4\" localOnly=\"6\"/>"
731
            . "</fixedLine>"
732
            . "</territory>");
733
734
        $fixedLine = BuildMetadataFromXml::processPhoneNumberDescElement($generalDesc, $territoryElement,
735
            'fixedLine');
736
        $mobile = BuildMetadataFromXml::processPhoneNumberDescElement($generalDesc, $territoryElement,
737
            'mobile');
738
739
        $possibleLength = $fixedLine->getPossibleLength();
740
        $this->assertCount(2, $possibleLength);
741
        $this->assertEquals(4, $possibleLength[0]);
742
        $this->assertEquals(13, $possibleLength[1]);
743
        $this->assertCount(1, $fixedLine->getPossibleLengthLocalOnly());
744
745
        // We use [-1] to denote that there are no possible lengths; we don't leave it empty, since for
746
        // compression reasons, we use the empty list to mean that the generalDesc possible lengths
747
        // apply.
748
        $mobileLength = $mobile->getPossibleLength();
749
        $this->assertCount(1, $mobileLength);
750
        $this->assertEquals(-1, $mobileLength[0]);
751
        $this->assertCount(0, $mobile->getPossibleLengthLocalOnly());
752
    }
753
754
    public function testSetPossibleLengthsGeneralDesc_BuiltFromChildElements()
755
    {
756
        $territoryElement = $this->parseXMLString("<territory>"
757
            . "<fixedLine>"
758
            . "  <possibleLengths national=\"13\" localOnly=\"6\"/>"
759
            . "</fixedLine>"
760
            . "<mobile>"
761
            . "  <possibleLengths national=\"15\" localOnly=\"7,13\"/>"
762
            . "</mobile>"
763
            . "<tollFree>"
764
            . "  <possibleLengths national=\"15\"/>"
765
            . "</tollFree>"
766
            . "</territory>");
767
768
        $generalDesc = new PhoneNumberDesc();
769
        BuildMetadataFromXml::setPossibleLengthsGeneralDesc($generalDesc, 'someId', $territoryElement,
770
            false /* not short-number metadata */);
771
772
        $possibleLength = $generalDesc->getPossibleLength();
773
        $this->assertCount(2, $possibleLength);
774
        $this->assertEquals(13, $possibleLength[0]);
775
        // 15 is present twice in the input in different sections, but only once in the output.
776
        $this->assertEquals(15, $possibleLength[1]);
777
        $possibleLengthLocalOnly = $generalDesc->getPossibleLengthLocalOnly();
778
        $this->assertCount(2, $possibleLengthLocalOnly);
779
        $this->assertEquals(6, $possibleLengthLocalOnly[0]);
780
        $this->assertEquals(7, $possibleLengthLocalOnly[1]);
781
        // 13 is skipped as a "local only" length, since it is also present as a normal length.
782
    }
783
784
    public function testSetPossibleLengthsGeneralDesc_IgnoresNoIntlDialling()
785
    {
786
        $territoryElement = $this->parseXMLString("<territory>"
787
            . "<fixedLine>"
788
            . "  <possibleLengths national=\"13\"/>"
789
            . "</fixedLine>"
790
            . "<noInternationalDialling>"
791
            . "  <possibleLengths national=\"15\"/>"
792
            . "</noInternationalDialling>"
793
            . "</territory>");
794
795
        $generalDesc = new PhoneNumberDesc();
796
        BuildMetadataFromXml::setPossibleLengthsGeneralDesc($generalDesc, 'someId', $territoryElement,
797
            false /* not short-number metadata */);
798
799
        $possibleLength = $generalDesc->getPossibleLength();
800
        $this->assertCount(1, $possibleLength);
801
        $this->assertEquals(13, $possibleLength[0]);
802
        // 15 is skipped because noInternationalDialling should not contribute to the general lengths;
803
        // it isn't a particular "type" of number per se, it is a property that different types may
804
        // have.
805
    }
806
807
    public function testSetPossibleLengthsGeneralDesc_ShortNumberMetadata()
808
    {
809
        $territoryElement = $this->parseXMLString("<territory>"
810
            . "<shortCode>"
811
            . "  <possibleLengths national=\"6,13\"/>"
812
            . "</shortCode>"
813
            . "<carrierSpecific>"
814
            . "  <possibleLengths national=\"7,13,15\"/>"
815
            . "</carrierSpecific>"
816
            . "<tollFree>"
817
            . "  <possibleLengths national=\"15\"/>"
818
            . "</tollFree>"
819
            . "</territory>");
820
821
        $generalDesc = new PhoneNumberDesc();
822
        BuildMetadataFromXml::setPossibleLengthsGeneralDesc($generalDesc, 'someId', $territoryElement,
823
            true /* short-number metadata */);
824
825
        // All elements other than shortCode are ignored when creating the general desc.
826
        $possibleLength = $generalDesc->getPossibleLength();
827
        $this->assertCount(2, $possibleLength);
828
        $this->assertEquals(6, $possibleLength[0]);
829
        $this->assertEquals(13, $possibleLength[1]);
830
    }
831
832
    /**
833
     * @expectedException \RuntimeException
834
     * @expectedExceptionMessage Found local-only lengths in short-number metadata
835
     */
836
    public function testSetPossibleLengthsGeneralDesc_ShortNumberMetadataErrorsOnLocalLengths()
837
    {
838
        $territoryElement = $this->parseXMLString("<territory>"
839
            . "<shortCode>"
840
            . "  <possibleLengths national=\"13\" localOnly=\"6\"/>"
841
            . "</shortCode>"
842
            . "</territory>");
843
844
        $generalDesc = new PhoneNumberDesc();
845
        BuildMetadataFromXml::setPossibleLengthsGeneralDesc($generalDesc, 'someId', $territoryElement,
846
            true /* short-number metadata */);
847
    }
848
849
    /**
850
     * @expectedException \RuntimeException
851
     * @expectedExceptionMessage Duplicate length element found (6) in possibleLength string 6,6
852
     */
853
    public function testProcessPhoneNumberDescElement_ErrorDuplicates()
854
    {
855
        $generalDesc = new PhoneNumberDesc();
856
        $generalDesc->setPossibleLength(array(6));
857
858
        $territoryElement = $this->parseXMLString("<territory>"
859
            . "<mobile>"
860
            . "  <possibleLengths national=\"6,6\"/>"
861
            . "</mobile>"
862
            . "</territory>");
863
864
        BuildMetadataFromXml::processPhoneNumberDescElement($generalDesc, $territoryElement, 'mobile');
865
    }
866
867
    /**
868
     * @expectedException \RuntimeException
869
     * @expectedExceptionMessage Possible length(s) found specified as a normal and local-only length: [6]
870
     */
871
    public function testProcessPhoneNumberDescElement_ErrorDuplicatesOneLocal()
872
    {
873
        $generalDesc = new PhoneNumberDesc();
874
        $generalDesc->setPossibleLength(array(6));
875
876
        $territoryElement = $this->parseXMLString("<territory>"
877
            . "<mobile>"
878
            . "  <possibleLengths national=\"6\" localOnly=\"6\"/>"
879
            . "</mobile>"
880
            . "</territory>");
881
882
        BuildMetadataFromXml::processPhoneNumberDescElement($generalDesc, $territoryElement, 'mobile');
883
    }
884
885
    /**
886
     * @expectedException \RuntimeException
887
     * @expectedExceptionMessage Out-of-range possible length
888
     */
889
    public function testProcessPhoneNumberDescElement_ErrorUncoveredLengths()
890
    {
891
        $generalDesc = new PhoneNumberDesc();
892
        $generalDesc->setPossibleLength(array(4));
893
894
        $territoryElement = $this->parseXMLString("<territory>"
895
            . "<noInternationalDialling>"
896
            // Sorting will be done when parsing.
897
            . "  <possibleLengths national=\"6,7,4\"/>"
898
            . "</noInternationalDialling>"
899
            . "</territory>");
900
901
        BuildMetadataFromXml::processPhoneNumberDescElement($generalDesc, $territoryElement, 'noInternationalDialling');
902
    }
903
904
    public function testProcessPhoneNumberDescElement_SameAsParent()
905
    {
906
        $generalDesc = new PhoneNumberDesc();
907
        // The number lengths set for the general description must be a super-set of those in the
908
        // element being parsed.
909
        $generalDesc->setPossibleLength(array(4, 6, 7));
910
        $generalDesc->setPossibleLengthLocalOnly(array(2));
911
        $territoryElement = $this->parseXMLString("<territory>"
912
            . "<fixedLine>"
913
            // Sorting will be done when parsing.
914
            . "  <possibleLengths national=\"6,7,4\" localOnly=\"2\"/>"
915
            . "</fixedLine>"
916
            . "</territory>");
917
918
        $phoneNumberDesc = BuildMetadataFromXml::processPhoneNumberDescElement($generalDesc, $territoryElement,
919
            'fixedLine');
920
921
        // No possible lengths should be present, because they match the general description.
922
        $this->assertCount(0, $phoneNumberDesc->getPossibleLength());
923
        // Local-only lengths should be present for child elements such as fixed-line
924
        $this->assertCount(1, $phoneNumberDesc->getPossibleLengthLocalOnly());
925
    }
926
927
    /**
928
     * @expectedException \RuntimeException
929
     * @expectedExceptionMessage For input string "4d"
930
     */
931
    public function testProcessPhoneNumberDescElement_InvalidNumber()
932
    {
933
        $generalDesc = new PhoneNumberDesc();
934
        $generalDesc->setPossibleLength(array(4));
935
        $territoryElement = $this->parseXMLString("<territory>"
936
            . "<fixedLine>"
937
            . "  <possibleLengths national=\"4d\"/>"
938
            . "</fixedLine>"
939
            . "</territory>");
940
941
        BuildMetadataFromXml::processPhoneNumberDescElement($generalDesc, $territoryElement, 'fixedLine');
942
    }
943
944
    /**
945
     * @expectedException \RuntimeException
946
     * @expectedExceptionMessage Found possible lengths specified at general desc: this should be derived from child elements. Affected country: FR
947
     */
948
    public function testLoadCountryMetadata_GeneralDescHasNumberLengthsSet()
949
    {
950
        $territoryElement = $this->parseXMLString("<territory>"
951
            . "<generalDesc>"
952
            // This shouldn't be set, the possible lengths should be derived for generalDesc.
953
            . "  <possibleLengths national=\"4\"/>"
954
            . "</generalDesc>"
955
            . "<fixedLine>"
956
            . "  <possibleLengths national=\"4\"/>"
957
            . "</fixedLine>"
958
            . "</territory>");
959
960
        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...
961
            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...
962
    }
963
964
    /**
965
     * @expectedException \RuntimeException
966
     * @expectedExceptionMessage Empty possibleLength string found.
967
     */
968
    public function testProcessPhoneNumberDescElement_ErrorEmptyPossibleLengthStringAttribute()
969
    {
970
        $generalDesc = new PhoneNumberDesc();
971
        $generalDesc->setPossibleLength(array(4));
972
        $territoryElement = $this->parseXMLString("<territory>"
973
            . "<fixedLine>"
974
            . "  <possibleLengths national=\"\"/>"
975
            . "</fixedLine>"
976
            . "</territory>");
977
978
        BuildMetadataFromXml::processPhoneNumberDescElement($generalDesc, $territoryElement, 'fixedLine');
979
    }
980
981
    /**
982
     * @expectedException \RuntimeException
983
     * @expectedExceptionMessage Missing end of range character in possible length string [4,7].
984
     */
985
    public function testProcessPhoneNumberDescElement_ErrorRangeSpecifiedWithComma()
986
    {
987
        $generalDesc = new PhoneNumberDesc();
988
        $generalDesc->setPossibleLength(array(4));
989
        $territoryElement = $this->parseXMLString("<territory>"
990
            . "<fixedLine>"
991
            . "  <possibleLengths national=\"[4,7]\"/>"
992
            . "</fixedLine>"
993
            . "</territory>");
994
995
        BuildMetadataFromXml::processPhoneNumberDescElement($generalDesc, $territoryElement, 'fixedLine');
996
    }
997
998
    /**
999
     * @expectedException \RuntimeException
1000
     * @expectedExceptionMessage Missing end of range character in possible length string [4-.
1001
     */
1002
    public function testProcessPhoneNumberDescElement_ErrorIncompleteRange()
1003
    {
1004
        $generalDesc = new PhoneNumberDesc();
1005
        $generalDesc->setPossibleLength(array(4));
1006
1007
        $territoryElement = $this->parseXMLString("<territory>"
1008
            . "<fixedLine>"
1009
            . "  <possibleLengths national=\"[4-\"/>"
1010
            . "</fixedLine>"
1011
            . "</territory>");
1012
1013
        BuildMetadataFromXml::processPhoneNumberDescElement($generalDesc, $territoryElement, 'fixedLine');
1014
    }
1015
1016
    /**
1017
     * @expectedException \RuntimeException
1018
     * @expectedExceptionMessage Ranges must have exactly one - character: missing for [4:10].
1019
     */
1020
    public function testProcessPhoneNumberDescElement_ErrorNoDashInRange()
1021
    {
1022
        $generalDesc = new PhoneNumberDesc();
1023
        $generalDesc->setPossibleLength(array(4));
1024
        $territoryElement = $this->parseXMLString("<territory>"
1025
            . "<fixedLine>"
1026
            . "  <possibleLengths national=\"[4:10]\"/>"
1027
            . "</fixedLine>"
1028
            . "</territory>");
1029
1030
        BuildMetadataFromXml::processPhoneNumberDescElement($generalDesc, $territoryElement, 'fixedLine');
1031
    }
1032
1033
    /**
1034
     * @expectedException \RuntimeException
1035
     * @expectedExceptionMessage The first number in a range should be two or more digits lower than the second. Culprit possibleLength string: [10-10]
1036
     */
1037
    public function testProcessPhoneNumberDescElement_ErrorRangeIsNotFromMinToMax()
1038
    {
1039
        $generalDesc = new PhoneNumberDesc();
1040
        $generalDesc->setPossibleLength(array(4));
1041
        $territoryElement = $this->parseXMLString("<territory>"
1042
            . "<fixedLine>"
1043
            . "  <possibleLengths national=\"[10-10]\"/>"
1044
            . "</fixedLine>"
1045
            . "</territory>");
1046
1047
        BuildMetadataFromXml::processPhoneNumberDescElement($generalDesc, $territoryElement, 'fixedLine');
1048
    }
1049
1050
    public function testGetMetadataFilter()
1051
    {
1052
        $this->assertEquals(BuildMetadataFromXml::getMetadataFilter(false, false), MetadataFilter::emptyFilter());
1053
        $this->assertEquals(BuildMetadataFromXml::getMetadataFilter(true, false), MetadataFilter::forLiteBuild());
1054
        $this->assertEquals(BuildMetadataFromXml::getMetadataFilter(false, true), MetadataFilter::forSpecialBuild());
1055
1056
        try {
1057
            BuildMetadataFromXml::getMetadataFilter(true, true);
1058
            $this->fail("getMetadataFilter should fail when liteBuild and specialBuild are both set");
1059
        } catch (\RuntimeException $e) {
1060
            $this->assertEquals("liteBuild and specialBuild may not both be set", $e->getMessage());
1061
        }
1062
    }
1063
}
1064