Completed
Push — master ( dd9cf2...939550 )
by Joshua
13s
created

testSetRelevantDescPatternsSetsAllDescriptionsForShortNumbers()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 25
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 25
rs 8.8571
c 0
b 0
f 0
cc 1
eloc 22
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
            . "  <smsServices>"
642
            . "    <nationalNumberPattern>\\d{6}</nationalNumberPattern>"
643
            . "  </smsServices>"
644
            . "</territory>";
645
646
        $territoryElement = $this->parseXMLString($xmlInput);
647
        $metadata = new PhoneMetadata();
648
        BuildMetadataFromXml::setRelevantDescPatterns($metadata, $territoryElement, true /* isShortNumberMetadata */);
649
        $this->assertEquals("\\d{1}", $metadata->getTollFree()->getNationalNumberPattern());
650
        $this->assertEquals("\\d{2}", $metadata->getStandardRate()->getNationalNumberPattern());
651
        $this->assertEquals("\\d{3}", $metadata->getPremiumRate()->getNationalNumberPattern());
652
        $this->assertEquals("\\d{4}", $metadata->getShortCode()->getNationalNumberPattern());
653
        $this->assertEquals("\\d{5}", $metadata->getCarrierSpecific()->getNationalNumberPattern());
654
        $this->assertEquals("\\d{6}", $metadata->getSmsServices()->getNationalNumberPattern());
655
    }
656
657
    /**
658
     * @expectedException \RuntimeException
659
     * @expectedExceptionMessage Multiple elements with type fixedLine found.
660
     */
661
    public function testSetRelevantDescPatternsThrowsErrorIfTypePresentMultipleTimes()
662
    {
663
        $xmlInput = "<territory countryCode=\"33\">"
664
            . "  <fixedLine><nationalNumberPattern>\\d{6}</nationalNumberPattern></fixedLine>"
665
            . "  <fixedLine><nationalNumberPattern>\\d{6}</nationalNumberPattern></fixedLine>"
666
            . "</territory>";
667
668
        $territoryElement = $this->parseXMLString($xmlInput);
669
        $metadata = new PhoneMetadata();
670
        BuildMetadataFromXml::setRelevantDescPatterns($metadata, $territoryElement, false /* isShortNumberMetadata */);
671
    }
672
673
    public function testAlternateFormatsOmitsDescPatterns()
674
    {
675
        $xmlInput = "<territory countryCode=\"33\">"
676
            . "  <availableFormats>"
677
            . "    <numberFormat pattern=\"(1)(\\d{3})\">"
678
            . "      <leadingDigits>1</leadingDigits>"
679
            . '      <format>$1</format>'
680
            . "    </numberFormat>"
681
            . "  </availableFormats>"
682
            . "  <fixedLine><nationalNumberPattern>\\d{1}</nationalNumberPattern></fixedLine>"
683
            . "  <shortCode><nationalNumberPattern>\\d{2}</nationalNumberPattern></shortCode>"
684
            . "</territory>";
685
686
        $territoryElement = $this->parseXMLString($xmlInput);
687
        $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...
688
            /* 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...
689
        $this->assertEquals('(1)(\\d{3})', $metadata->getNumberFormat(0)->getPattern());
690
        $this->assertEquals('1', $metadata->getNumberFormat(0)->getLeadingDigitsPattern(0));
691
        $this->assertEquals('$1', $metadata->getNumberFormat(0)->getFormat());
692
        $this->assertNull($metadata->getFixedLine());
693
        $this->assertNull($metadata->getShortCode());
694
    }
695
696
    public function testNationalPrefixRulesSetCorrectly()
697
    {
698
        $xmlInput = "<territory countryCode=\"33\" nationalPrefix=\"0\""
699
            . ' nationalPrefixFormattingRule="$NP$FG">'
700
            . "  <availableFormats>"
701
            . "    <numberFormat pattern=\"(1)(\\d{3})\" nationalPrefixOptionalWhenFormatting=\"true\">"
702
            . "      <leadingDigits>1</leadingDigits>"
703
            . '      <format>$1</format>'
704
            . "    </numberFormat>"
705
            . "    <numberFormat pattern=\"(\\d{3})\" nationalPrefixOptionalWhenFormatting=\"false\">"
706
            . "      <leadingDigits>2</leadingDigits>"
707
            . '      <format>$1</format>'
708
            . "    </numberFormat>"
709
            . "  </availableFormats>"
710
            . "  <fixedLine><nationalNumberPattern>\\d{1}</nationalNumberPattern></fixedLine>"
711
            . "</territory>";
712
        $territoryElement = $this->parseXMLString($xmlInput);
713
        $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...
714
            /* 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...
715
        $this->assertTrue($metadata->getNumberFormat(0)->getNationalPrefixOptionalWhenFormatting());
716
        // This is inherited from the territory, with $NP replaced by the actual national prefix, and
717
        // $FG replaced with $1.
718
        $this->assertEquals("0$1", $metadata->getNumberFormat(0)->getNationalPrefixFormattingRule());
719
        // Here it is explicitly set to false.
720
        $this->assertFalse($metadata->getNumberFormat(1)->getNationalPrefixOptionalWhenFormatting());
721
    }
722
723
    public function testProcessPhoneNumberDescElement_PossibleLengthsSetCorrectly()
724
    {
725
        $generalDesc = new PhoneNumberDesc();
726
        // The number lengths set for the general description must be a super-set of those in the
727
        // element being parsed.
728
        $generalDesc->setPossibleLength(array(4, 6, 7, 13));
729
        $territoryElement = $this->parseXMLString("<territory>"
730
            . "<fixedLine>"
731
            // Sorting will be done when parsing.
732
            . "  <possibleLengths national=\"13,4\" localOnly=\"6\"/>"
733
            . "</fixedLine>"
734
            . "</territory>");
735
736
        $fixedLine = BuildMetadataFromXml::processPhoneNumberDescElement($generalDesc, $territoryElement,
737
            'fixedLine');
738
        $mobile = BuildMetadataFromXml::processPhoneNumberDescElement($generalDesc, $territoryElement,
739
            'mobile');
740
741
        $possibleLength = $fixedLine->getPossibleLength();
742
        $this->assertCount(2, $possibleLength);
743
        $this->assertEquals(4, $possibleLength[0]);
744
        $this->assertEquals(13, $possibleLength[1]);
745
        $this->assertCount(1, $fixedLine->getPossibleLengthLocalOnly());
746
747
        // We use [-1] to denote that there are no possible lengths; we don't leave it empty, since for
748
        // compression reasons, we use the empty list to mean that the generalDesc possible lengths
749
        // apply.
750
        $mobileLength = $mobile->getPossibleLength();
751
        $this->assertCount(1, $mobileLength);
752
        $this->assertEquals(-1, $mobileLength[0]);
753
        $this->assertCount(0, $mobile->getPossibleLengthLocalOnly());
754
    }
755
756
    public function testSetPossibleLengthsGeneralDesc_BuiltFromChildElements()
757
    {
758
        $territoryElement = $this->parseXMLString("<territory>"
759
            . "<fixedLine>"
760
            . "  <possibleLengths national=\"13\" localOnly=\"6\"/>"
761
            . "</fixedLine>"
762
            . "<mobile>"
763
            . "  <possibleLengths national=\"15\" localOnly=\"7,13\"/>"
764
            . "</mobile>"
765
            . "<tollFree>"
766
            . "  <possibleLengths national=\"15\"/>"
767
            . "</tollFree>"
768
            . "</territory>");
769
770
        $generalDesc = new PhoneNumberDesc();
771
        BuildMetadataFromXml::setPossibleLengthsGeneralDesc($generalDesc, 'someId', $territoryElement,
772
            false /* not short-number metadata */);
773
774
        $possibleLength = $generalDesc->getPossibleLength();
775
        $this->assertCount(2, $possibleLength);
776
        $this->assertEquals(13, $possibleLength[0]);
777
        // 15 is present twice in the input in different sections, but only once in the output.
778
        $this->assertEquals(15, $possibleLength[1]);
779
        $possibleLengthLocalOnly = $generalDesc->getPossibleLengthLocalOnly();
780
        $this->assertCount(2, $possibleLengthLocalOnly);
781
        $this->assertEquals(6, $possibleLengthLocalOnly[0]);
782
        $this->assertEquals(7, $possibleLengthLocalOnly[1]);
783
        // 13 is skipped as a "local only" length, since it is also present as a normal length.
784
    }
785
786
    public function testSetPossibleLengthsGeneralDesc_IgnoresNoIntlDialling()
787
    {
788
        $territoryElement = $this->parseXMLString("<territory>"
789
            . "<fixedLine>"
790
            . "  <possibleLengths national=\"13\"/>"
791
            . "</fixedLine>"
792
            . "<noInternationalDialling>"
793
            . "  <possibleLengths national=\"15\"/>"
794
            . "</noInternationalDialling>"
795
            . "</territory>");
796
797
        $generalDesc = new PhoneNumberDesc();
798
        BuildMetadataFromXml::setPossibleLengthsGeneralDesc($generalDesc, 'someId', $territoryElement,
799
            false /* not short-number metadata */);
800
801
        $possibleLength = $generalDesc->getPossibleLength();
802
        $this->assertCount(1, $possibleLength);
803
        $this->assertEquals(13, $possibleLength[0]);
804
        // 15 is skipped because noInternationalDialling should not contribute to the general lengths;
805
        // it isn't a particular "type" of number per se, it is a property that different types may
806
        // have.
807
    }
808
809
    public function testSetPossibleLengthsGeneralDesc_ShortNumberMetadata()
810
    {
811
        $territoryElement = $this->parseXMLString("<territory>"
812
            . "<shortCode>"
813
            . "  <possibleLengths national=\"6,13\"/>"
814
            . "</shortCode>"
815
            . "<carrierSpecific>"
816
            . "  <possibleLengths national=\"7,13,15\"/>"
817
            . "</carrierSpecific>"
818
            . "<tollFree>"
819
            . "  <possibleLengths national=\"15\"/>"
820
            . "</tollFree>"
821
            . "<smsServices>"
822
            . "  <possibleLengths national=\"5\"/>"
823
            . "</smsServices>"
824
            . "</territory>");
825
826
        $generalDesc = new PhoneNumberDesc();
827
        BuildMetadataFromXml::setPossibleLengthsGeneralDesc($generalDesc, 'someId', $territoryElement,
828
            true /* short-number metadata */);
829
830
        // All elements other than shortCode are ignored when creating the general desc.
831
        $possibleLength = $generalDesc->getPossibleLength();
832
        $this->assertCount(2, $possibleLength);
833
        $this->assertEquals(6, $possibleLength[0]);
834
        $this->assertEquals(13, $possibleLength[1]);
835
    }
836
837
    /**
838
     * @expectedException \RuntimeException
839
     * @expectedExceptionMessage Found local-only lengths in short-number metadata
840
     */
841
    public function testSetPossibleLengthsGeneralDesc_ShortNumberMetadataErrorsOnLocalLengths()
842
    {
843
        $territoryElement = $this->parseXMLString("<territory>"
844
            . "<shortCode>"
845
            . "  <possibleLengths national=\"13\" localOnly=\"6\"/>"
846
            . "</shortCode>"
847
            . "</territory>");
848
849
        $generalDesc = new PhoneNumberDesc();
850
        BuildMetadataFromXml::setPossibleLengthsGeneralDesc($generalDesc, 'someId', $territoryElement,
851
            true /* short-number metadata */);
852
    }
853
854
    /**
855
     * @expectedException \RuntimeException
856
     * @expectedExceptionMessage Duplicate length element found (6) in possibleLength string 6,6
857
     */
858
    public function testProcessPhoneNumberDescElement_ErrorDuplicates()
859
    {
860
        $generalDesc = new PhoneNumberDesc();
861
        $generalDesc->setPossibleLength(array(6));
862
863
        $territoryElement = $this->parseXMLString("<territory>"
864
            . "<mobile>"
865
            . "  <possibleLengths national=\"6,6\"/>"
866
            . "</mobile>"
867
            . "</territory>");
868
869
        BuildMetadataFromXml::processPhoneNumberDescElement($generalDesc, $territoryElement, 'mobile');
870
    }
871
872
    /**
873
     * @expectedException \RuntimeException
874
     * @expectedExceptionMessage Possible length(s) found specified as a normal and local-only length: [6]
875
     */
876
    public function testProcessPhoneNumberDescElement_ErrorDuplicatesOneLocal()
877
    {
878
        $generalDesc = new PhoneNumberDesc();
879
        $generalDesc->setPossibleLength(array(6));
880
881
        $territoryElement = $this->parseXMLString("<territory>"
882
            . "<mobile>"
883
            . "  <possibleLengths national=\"6\" localOnly=\"6\"/>"
884
            . "</mobile>"
885
            . "</territory>");
886
887
        BuildMetadataFromXml::processPhoneNumberDescElement($generalDesc, $territoryElement, 'mobile');
888
    }
889
890
    /**
891
     * @expectedException \RuntimeException
892
     * @expectedExceptionMessage Out-of-range possible length
893
     */
894
    public function testProcessPhoneNumberDescElement_ErrorUncoveredLengths()
895
    {
896
        $generalDesc = new PhoneNumberDesc();
897
        $generalDesc->setPossibleLength(array(4));
898
899
        $territoryElement = $this->parseXMLString("<territory>"
900
            . "<noInternationalDialling>"
901
            // Sorting will be done when parsing.
902
            . "  <possibleLengths national=\"6,7,4\"/>"
903
            . "</noInternationalDialling>"
904
            . "</territory>");
905
906
        BuildMetadataFromXml::processPhoneNumberDescElement($generalDesc, $territoryElement, 'noInternationalDialling');
907
    }
908
909
    public function testProcessPhoneNumberDescElement_SameAsParent()
910
    {
911
        $generalDesc = new PhoneNumberDesc();
912
        // The number lengths set for the general description must be a super-set of those in the
913
        // element being parsed.
914
        $generalDesc->setPossibleLength(array(4, 6, 7));
915
        $generalDesc->setPossibleLengthLocalOnly(array(2));
916
        $territoryElement = $this->parseXMLString("<territory>"
917
            . "<fixedLine>"
918
            // Sorting will be done when parsing.
919
            . "  <possibleLengths national=\"6,7,4\" localOnly=\"2\"/>"
920
            . "</fixedLine>"
921
            . "</territory>");
922
923
        $phoneNumberDesc = BuildMetadataFromXml::processPhoneNumberDescElement($generalDesc, $territoryElement,
924
            'fixedLine');
925
926
        // No possible lengths should be present, because they match the general description.
927
        $this->assertCount(0, $phoneNumberDesc->getPossibleLength());
928
        // Local-only lengths should be present for child elements such as fixed-line
929
        $this->assertCount(1, $phoneNumberDesc->getPossibleLengthLocalOnly());
930
    }
931
932
    /**
933
     * @expectedException \RuntimeException
934
     * @expectedExceptionMessage For input string "4d"
935
     */
936
    public function testProcessPhoneNumberDescElement_InvalidNumber()
937
    {
938
        $generalDesc = new PhoneNumberDesc();
939
        $generalDesc->setPossibleLength(array(4));
940
        $territoryElement = $this->parseXMLString("<territory>"
941
            . "<fixedLine>"
942
            . "  <possibleLengths national=\"4d\"/>"
943
            . "</fixedLine>"
944
            . "</territory>");
945
946
        BuildMetadataFromXml::processPhoneNumberDescElement($generalDesc, $territoryElement, 'fixedLine');
947
    }
948
949
    /**
950
     * @expectedException \RuntimeException
951
     * @expectedExceptionMessage Found possible lengths specified at general desc: this should be derived from child elements. Affected country: FR
952
     */
953
    public function testLoadCountryMetadata_GeneralDescHasNumberLengthsSet()
954
    {
955
        $territoryElement = $this->parseXMLString("<territory>"
956
            . "<generalDesc>"
957
            // This shouldn't be set, the possible lengths should be derived for generalDesc.
958
            . "  <possibleLengths national=\"4\"/>"
959
            . "</generalDesc>"
960
            . "<fixedLine>"
961
            . "  <possibleLengths national=\"4\"/>"
962
            . "</fixedLine>"
963
            . "</territory>");
964
965
        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...
966
            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...
967
    }
968
969
    /**
970
     * @expectedException \RuntimeException
971
     * @expectedExceptionMessage Empty possibleLength string found.
972
     */
973
    public function testProcessPhoneNumberDescElement_ErrorEmptyPossibleLengthStringAttribute()
974
    {
975
        $generalDesc = new PhoneNumberDesc();
976
        $generalDesc->setPossibleLength(array(4));
977
        $territoryElement = $this->parseXMLString("<territory>"
978
            . "<fixedLine>"
979
            . "  <possibleLengths national=\"\"/>"
980
            . "</fixedLine>"
981
            . "</territory>");
982
983
        BuildMetadataFromXml::processPhoneNumberDescElement($generalDesc, $territoryElement, 'fixedLine');
984
    }
985
986
    /**
987
     * @expectedException \RuntimeException
988
     * @expectedExceptionMessage Missing end of range character in possible length string [4,7].
989
     */
990
    public function testProcessPhoneNumberDescElement_ErrorRangeSpecifiedWithComma()
991
    {
992
        $generalDesc = new PhoneNumberDesc();
993
        $generalDesc->setPossibleLength(array(4));
994
        $territoryElement = $this->parseXMLString("<territory>"
995
            . "<fixedLine>"
996
            . "  <possibleLengths national=\"[4,7]\"/>"
997
            . "</fixedLine>"
998
            . "</territory>");
999
1000
        BuildMetadataFromXml::processPhoneNumberDescElement($generalDesc, $territoryElement, 'fixedLine');
1001
    }
1002
1003
    /**
1004
     * @expectedException \RuntimeException
1005
     * @expectedExceptionMessage Missing end of range character in possible length string [4-.
1006
     */
1007
    public function testProcessPhoneNumberDescElement_ErrorIncompleteRange()
1008
    {
1009
        $generalDesc = new PhoneNumberDesc();
1010
        $generalDesc->setPossibleLength(array(4));
1011
1012
        $territoryElement = $this->parseXMLString("<territory>"
1013
            . "<fixedLine>"
1014
            . "  <possibleLengths national=\"[4-\"/>"
1015
            . "</fixedLine>"
1016
            . "</territory>");
1017
1018
        BuildMetadataFromXml::processPhoneNumberDescElement($generalDesc, $territoryElement, 'fixedLine');
1019
    }
1020
1021
    /**
1022
     * @expectedException \RuntimeException
1023
     * @expectedExceptionMessage Ranges must have exactly one - character: missing for [4:10].
1024
     */
1025
    public function testProcessPhoneNumberDescElement_ErrorNoDashInRange()
1026
    {
1027
        $generalDesc = new PhoneNumberDesc();
1028
        $generalDesc->setPossibleLength(array(4));
1029
        $territoryElement = $this->parseXMLString("<territory>"
1030
            . "<fixedLine>"
1031
            . "  <possibleLengths national=\"[4:10]\"/>"
1032
            . "</fixedLine>"
1033
            . "</territory>");
1034
1035
        BuildMetadataFromXml::processPhoneNumberDescElement($generalDesc, $territoryElement, 'fixedLine');
1036
    }
1037
1038
    /**
1039
     * @expectedException \RuntimeException
1040
     * @expectedExceptionMessage The first number in a range should be two or more digits lower than the second. Culprit possibleLength string: [10-10]
1041
     */
1042
    public function testProcessPhoneNumberDescElement_ErrorRangeIsNotFromMinToMax()
1043
    {
1044
        $generalDesc = new PhoneNumberDesc();
1045
        $generalDesc->setPossibleLength(array(4));
1046
        $territoryElement = $this->parseXMLString("<territory>"
1047
            . "<fixedLine>"
1048
            . "  <possibleLengths national=\"[10-10]\"/>"
1049
            . "</fixedLine>"
1050
            . "</territory>");
1051
1052
        BuildMetadataFromXml::processPhoneNumberDescElement($generalDesc, $territoryElement, 'fixedLine');
1053
    }
1054
1055
    public function testGetMetadataFilter()
1056
    {
1057
        $this->assertEquals(BuildMetadataFromXml::getMetadataFilter(false, false), MetadataFilter::emptyFilter());
1058
        $this->assertEquals(BuildMetadataFromXml::getMetadataFilter(true, false), MetadataFilter::forLiteBuild());
1059
        $this->assertEquals(BuildMetadataFromXml::getMetadataFilter(false, true), MetadataFilter::forSpecialBuild());
1060
1061
        try {
1062
            BuildMetadataFromXml::getMetadataFilter(true, true);
1063
            $this->fail("getMetadataFilter should fail when liteBuild and specialBuild are both set");
1064
        } catch (\RuntimeException $e) {
1065
            $this->assertEquals("liteBuild and specialBuild may not both be set", $e->getMessage());
1066
        }
1067
    }
1068
}
1069