Passed
Push — upstream-8.9.2 ( 6a22e8 )
by Joshua
25:34 queued 09:29
created

ExampleNumbersTest   B

Complexity

Total Complexity 53

Size/Duplication

Total Lines 392
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 4

Importance

Changes 0
Metric Value
wmc 53
lcom 1
cbo 4
dl 0
loc 392
rs 7.4757
c 0
b 0
f 0

How to fix   Complexity   

Complex Class

Complex classes like ExampleNumbersTest often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use ExampleNumbersTest, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace libphonenumber\Tests\core;
4
5
use libphonenumber\NumberParseException;
6
use libphonenumber\PhoneNumberFormat;
7
use libphonenumber\PhoneNumberType;
8
use libphonenumber\PhoneNumberUtil;
9
use libphonenumber\ShortNumberCost;
10
use libphonenumber\ShortNumberInfo;
11
12
/**
13
 * Verifies all of the example numbers in the metadata are valid and of the correct type. If no
14
 * example number exists for a particular type, the test still passes since not all types are
15
 * relevant for all regions. Tests that check the XML schema will ensure that an exampleNumber
16
 * node is present for every phone number description.
17
 */
18
class ExampleNumbersTest extends \PHPUnit_Framework_TestCase
19
{
20
21
    /**
22
     * @var PhoneNumberUtil
23
     */
24
    private $phoneNumberUtil;
25
    /**
26
     * @var ShortNumberInfo
27
     */
28
    private $shortNumberInfo;
29
30
    public static function setUpBeforeClass()
31
    {
32
        PhoneNumberUtil::resetInstance();
33
        PhoneNumberUtil::getInstance();
34
        ShortNumberInfo::resetInstance();
35
    }
36
37
    public function setUp()
38
    {
39
        $this->phoneNumberUtil = PhoneNumberUtil::getInstance();
40
        $this->shortNumberInfo = ShortNumberInfo::getInstance();
41
    }
42
43
    public function regionList()
44
    {
45
        $returnList = array();
46
47
        PhoneNumberUtil::resetInstance();
48
        $phoneUtil = PhoneNumberUtil::getInstance();
49
        foreach ($phoneUtil->getSupportedRegions() as $regionCode) {
50
            $returnList[] = array($regionCode);
51
        }
52
53
        return $returnList;
54
    }
55
56
    public function numberTypes()
57
    {
58
        return array(
59
            array(PhoneNumberType::FIXED_LINE),
60
            array(PhoneNumberType::MOBILE),
61
            array(PhoneNumberType::FIXED_LINE_OR_MOBILE),
62
            array(PhoneNumberType::TOLL_FREE),
63
            array(PhoneNumberType::PREMIUM_RATE),
64
            array(PhoneNumberType::SHARED_COST),
65
            array(PhoneNumberType::VOIP),
66
            array(PhoneNumberType::PERSONAL_NUMBER),
67
            array(PhoneNumberType::PAGER),
68
            array(PhoneNumberType::UAN),
69
            array(PhoneNumberType::VOICEMAIL),
70
        );
71
    }
72
73
    /**
74
     * @dataProvider regionList
75
     */
76
    public function testFixedLine($region)
77
    {
78
        $fixedLineTypes = array(PhoneNumberType::FIXED_LINE, PhoneNumberType::FIXED_LINE_OR_MOBILE);
79
        $this->checkNumbersValidAndCorrectType(PhoneNumberType::FIXED_LINE, $fixedLineTypes, $region);
80
    }
81
82
    /**
83
     * @dataProvider regionList
84
     */
85
    public function testFixedLineOrMobile($region)
86
    {
87
        $numberTypes = array(PhoneNumberType::FIXED_LINE, PhoneNumberType::FIXED_LINE_OR_MOBILE);
88
        $this->checkNumbersValidAndCorrectType(PhoneNumberType::FIXED_LINE_OR_MOBILE, $numberTypes, $region);
89
    }
90
91
    private function checkNumbersValidAndCorrectType($exampleNumberRequestedType, $possibleExpectedTypes, $regionCode)
92
    {
93
        $exampleNumber = $this->phoneNumberUtil->getExampleNumberForType($regionCode, $exampleNumberRequestedType);
94
        if ($exampleNumber !== null) {
95
            $this->assertTrue(
96
                $this->phoneNumberUtil->isValidNumber($exampleNumber),
97
                "Failed validation for {$exampleNumber}"
98
            );
99
100
            // We know the number is valid, now we check the type.
101
            $exampleNumberType = $this->phoneNumberUtil->getNumberType($exampleNumber);
102
            $this->assertContains($exampleNumberType, $possibleExpectedTypes, "Wrong type for {$exampleNumber}");
103
        }
104
    }
105
106
    /**
107
     * @dataProvider regionList
108
     */
109
    public function testMobile($region)
110
    {
111
        $mobileTypes = array(PhoneNumberType::MOBILE, PhoneNumberType::FIXED_LINE_OR_MOBILE);
112
        $this->checkNumbersValidAndCorrectType(PhoneNumberType::MOBILE, $mobileTypes, $region);
113
    }
114
115
    /**
116
     * @dataProvider regionList
117
     */
118
    public function testTollFree($region)
119
    {
120
        $tollFreeTypes = array(PhoneNumberType::TOLL_FREE);
121
        $this->checkNumbersValidAndCorrectType(PhoneNumberType::TOLL_FREE, $tollFreeTypes, $region);
122
    }
123
124
    /**
125
     * @dataProvider regionList
126
     */
127
    public function testPremiumRate($region)
128
    {
129
        $premiumRateTypes = array(PhoneNumberType::PREMIUM_RATE);
130
        $this->checkNumbersValidAndCorrectType(PhoneNumberType::PREMIUM_RATE, $premiumRateTypes, $region);
131
    }
132
133
    /**
134
     * @dataProvider regionList
135
     */
136
    public function testVoip($region)
137
    {
138
        $voipTypes = array(PhoneNumberType::VOIP);
139
        $this->checkNumbersValidAndCorrectType(PhoneNumberType::VOIP, $voipTypes, $region);
140
    }
141
142
    /**
143
     * @dataProvider regionList
144
     */
145
    public function testPager($region)
146
    {
147
        $pagerTypes = array(PhoneNumberType::PAGER);
148
        $this->checkNumbersValidAndCorrectType(PhoneNumberType::PAGER, $pagerTypes, $region);
149
    }
150
151
    /**
152
     * @dataProvider regionList
153
     */
154
    public function testUan($region)
155
    {
156
        $uanTypes = array(PhoneNumberType::UAN);
157
        $this->checkNumbersValidAndCorrectType(PhoneNumberType::UAN, $uanTypes, $region);
158
    }
159
160
    /**
161
     * @dataProvider regionList
162
     */
163
    public function testVoicemail($region)
164
    {
165
        $voicemailTypes = array(PhoneNumberType::VOICEMAIL);
166
        $this->checkNumbersValidAndCorrectType(PhoneNumberType::VOICEMAIL, $voicemailTypes, $region);
167
    }
168
169
    /**
170
     * @dataProvider regionList
171
     */
172
    public function testPersonalNumber($region)
173
    {
174
        $numberTypes = array(PhoneNumberType::PERSONAL_NUMBER);
175
        $this->checkNumbersValidAndCorrectType(PhoneNumberType::PERSONAL_NUMBER, $numberTypes, $region);
176
    }
177
178
    /**
179
     * @dataProvider regionList
180
     */
181
    public function testSharedCost($region)
182
    {
183
        $sharedCostTypes = array(PhoneNumberType::SHARED_COST);
184
        $this->checkNumbersValidAndCorrectType(PhoneNumberType::SHARED_COST, $sharedCostTypes, $region);
185
    }
186
187
    /**
188
     * @dataProvider regionList
189
     */
190
    public function testCanBeInternationallyDialled($regionCode)
191
    {
192
        $exampleNumber = null;
193
        /** @var \libphonenumber\PhoneNumberDesc $desc */
194
        $desc = $this->phoneNumberUtil->getMetadataForRegion($regionCode)->getNoInternationalDialling();
195
        try {
196
            if ($desc->hasExampleNumber()) {
197
                $exampleNumber = $this->phoneNumberUtil->parse($desc->getExampleNumber(), $regionCode);
198
            }
199
        } catch (NumberParseException $e) {
200
        }
201
202
        if ($exampleNumber !== null && $this->phoneNumberUtil->canBeInternationallyDialled($exampleNumber)) {
203
            $this->fail("Number {$exampleNumber} should not be internationally diallable");
204
        }
205
    }
206
207
    public function shortNumberRegionList()
208
    {
209
        $returnList = array();
210
211
        PhoneNumberUtil::resetInstance();
212
        ShortNumberInfo::resetInstance();
213
        $shortNumberInfo = ShortNumberInfo::getInstance();
214
        foreach ($shortNumberInfo->getSupportedRegions() as $regionCode) {
215
            $returnList[] = array($regionCode);
216
        }
217
218
        return $returnList;
219
    }
220
221
    public function supportedGlobalNetworkCallingCodes()
222
    {
223
        $returnList = array();
224
225
        PhoneNumberUtil::resetInstance();
226
        $phoneUtil = PhoneNumberUtil::getInstance();
227
        foreach ($phoneUtil->getSupportedGlobalNetworkCallingCodes() as $callingCode) {
228
            $returnList[] = array($callingCode);
229
        }
230
231
        return $returnList;
232
    }
233
234
    /**
235
     * @dataProvider supportedGlobalNetworkCallingCodes
236
     */
237
    public function testGlobalNetworkNumbers($callingCode)
238
    {
239
        $exampleNumber = $this->phoneNumberUtil->getExampleNumberForNonGeoEntity($callingCode);
240
        $this->assertNotNull($exampleNumber, "No example phone number for calling code " . $callingCode);
241
        if (!$this->phoneNumberUtil->isValidNumber($exampleNumber)) {
242
            $this->fail("Failed validation for " . $exampleNumber);
243
        }
244
    }
245
246
    /**
247
     * @dataProvider regionList
248
     * @param string $regionCode
249
     */
250
    public function testEveryRegionHasAnExampleNumber($regionCode)
251
    {
252
        $exampleNumber = $this->phoneNumberUtil->getExampleNumber($regionCode);
253
        $this->assertNotNull($exampleNumber, "No example number found for region " . $regionCode);
254
255
        /*
256
         * Check the number is valid
257
         */
258
259
        $e164 = $this->phoneNumberUtil->format($exampleNumber, PhoneNumberFormat::E164);
260
261
        $phoneObject = $this->phoneNumberUtil->parse($e164, 'ZZ');
262
263
        $this->assertEquals($phoneObject, $exampleNumber);
264
265
        $this->assertTrue($this->phoneNumberUtil->isValidNumber($phoneObject));
266
        $this->assertTrue($this->phoneNumberUtil->isValidNumberForRegion($phoneObject, $regionCode));
267
    }
268
269
    /**
270
     * @dataProvider regionList
271
     * @param string $regionCode
272
     */
273
    public function testEveryRegionHasAnInvalidExampleNumber($regionCode)
274
    {
275
        $exampleNumber = $this->phoneNumberUtil->getInvalidExampleNumber($regionCode);
276
        $this->assertNotNull($exampleNumber, 'No invalid example number found for region ' . $regionCode);
277
    }
278
279
    /**
280
     * @dataProvider numberTypes
281
     * @param string $numberType
282
     */
283
    public function testEveryTypeHasAnExampleNumber($numberType)
284
    {
285
        $exampleNumber = $this->phoneNumberUtil->getExampleNumberForType($numberType);
286
        $this->assertNotNull($exampleNumber, 'No example number found for type ' . $numberType);
287
    }
288
289
    /**
290
     * @dataProvider shortNumberRegionList
291
     */
292
    public function testShortNumbersValidAndCorrectCost($regionCode)
293
    {
294
        $exampleShortNumber = $this->shortNumberInfo->getExampleShortNumber($regionCode);
295
        if (!$this->shortNumberInfo->isValidShortNumberForRegion(
296
            $this->phoneNumberUtil->parse($exampleShortNumber, $regionCode),
297
            $regionCode
298
        )
299
        ) {
300
            $this->fail(
301
                "Failed validation for string region_code: {$regionCode}, national_number: {$exampleShortNumber}"
302
            );
303
        }
304
        $phoneNumber = $this->phoneNumberUtil->parse($exampleShortNumber, $regionCode);
305
        if (!$this->shortNumberInfo->isValidShortNumber($phoneNumber)) {
306
            $this->fail("Failed validation for " . (string)$phoneNumber);
307
        }
308
    }
309
310
    public function shortRegionListAndNumberCost()
311
    {
312
        $costArray = array(
313
            ShortNumberCost::PREMIUM_RATE,
314
            ShortNumberCost::STANDARD_RATE,
315
            ShortNumberCost::TOLL_FREE,
316
            ShortNumberCost::UNKNOWN_COST
317
        );
318
319
        $output = array();
320
321
        foreach ($this->shortNumberRegionList() as $region) {
322
            foreach ($costArray as $cost) {
323
                $output[] = array($region[0], $cost);
324
            }
325
        }
326
327
        return $output;
328
    }
329
330
    /**
331
     * @dataProvider shortRegionListAndNumberCost
332
     * @param $regionCode
333
     * @param $cost
334
     */
335
    public function testShortNumberHasCorrectCost($regionCode, $cost)
336
    {
337
        $exampleShortNumber = $this->shortNumberInfo->getExampleShortNumberForCost($regionCode, $cost);
338
        if ($exampleShortNumber != '') {
339
            $phoneNumber = $this->phoneNumberUtil->parse($exampleShortNumber, $regionCode);
340
            $exampleShortNumberCost = $this->shortNumberInfo->getExpectedCostForRegion($phoneNumber, $regionCode);
341
342
            $this->assertEquals($cost, $exampleShortNumberCost, 'Wrong cost for ' . (string)$phoneNumber);
343
        }
344
    }
345
346
    /**
347
     * @dataProvider shortNumberRegionList
348
     */
349
    public function testEmergency($regionCode)
350
    {
351
        $desc = $this->shortNumberInfo->getMetadataForRegion($regionCode)->getEmergency();
352
        if ($desc->hasExampleNumber()) {
353
            $exampleNumber = $desc->getExampleNumber();
354
            $phoneNumber = $this->phoneNumberUtil->parse($exampleNumber, $regionCode);
355
356
            if (!$this->shortNumberInfo->isPossibleShortNumberForRegion(
357
                    $phoneNumber,
358
                    $regionCode
359
                ) || !$this->shortNumberInfo->isEmergencyNumber($exampleNumber, $regionCode)
360
            ) {
361
                $this->fail("Emergency example number test failed for " . $regionCode);
362
            } elseif ($this->shortNumberInfo->getExpectedCostForRegion(
363
                    $phoneNumber,
364
                    $regionCode
365
                ) !== ShortNumberCost::TOLL_FREE
366
            ) {
367
                $this->fail("Emergency example number not toll free for " . $regionCode);
368
            }
369
        }
370
    }
371
372
    /**
373
     * @dataProvider shortNumberRegionList
374
     * @param string $regionCode
375
     */
376
    public function testCarrierSpecificShortNumbers($regionCode)
377
    {
378
        // Test the carrier-specific tag.
379
        $desc = $this->shortNumberInfo->getMetadataForRegion($regionCode)->getCarrierSpecific();
380
        if ($desc->hasExampleNumber()) {
381
            $exampleNumber = $desc->getExampleNumber();
382
            $carrierSpecificNumber = $this->phoneNumberUtil->parse($exampleNumber, $regionCode);
383
384
            if (!$this->shortNumberInfo->isPossibleShortNumberForRegion($carrierSpecificNumber, $regionCode)
385
                || !$this->shortNumberInfo->isCarrierSpecificForRegion($carrierSpecificNumber, $regionCode)
386
            ) {
387
                $this->fail("Carrier-specific test failed for " . $regionCode);
388
            }
389
        }
390
    }
391
392
    /**
393
     * @dataProvider shortNumberRegionList
394
     * @param string $regionCode
395
     */
396
    public function testSmsServiceShortNumbers($regionCode)
397
    {
398
        $desc = $this->shortNumberInfo->getMetadataForRegion($regionCode)->getSmsServices();
399
400
        if ($desc->hasExampleNumber()) {
401
            $exampleNumber = $desc->getExampleNumber();
402
            $smsServiceNumber = $this->phoneNumberUtil->parse($exampleNumber, $regionCode);
403
            if (!$this->shortNumberInfo->isPossibleShortNumberForRegion($smsServiceNumber, $regionCode)
404
                || !$this->shortNumberInfo->isSmsServiceForRegion($smsServiceNumber, $regionCode)) {
405
                $this->fail('SMS service test failed for ' . $regionCode);
406
            }
407
        }
408
    }
409
}
410