Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add 8xx ranges #114

Merged
merged 13 commits into from Jan 20, 2023
2 changes: 1 addition & 1 deletion .gitignore
Expand Up @@ -8,7 +8,7 @@ blib/
lib/Number/Phone/NANP/Data.pm
share/
lib/Number/Phone/Country/
lib/Number/Phone/StubCountry/
lib/Number/Phone/StubCountry/*.pm
libphonenumber/
data-files/
pm_to_blib
Expand Down
11 changes: 10 additions & 1 deletion CHANGELOG
@@ -1,4 +1,13 @@
X.XXXX XXXX-XX-XX
3.8099_02 2023-01-13

- Bugfix for non-geo country codes - instantiate objects like:
Number::Phone->new('GMSS::Iridium' => ...)

3.8099_01 2023-01-12

- Add validation using libphonenumber's data for non-geographic country
codes like +800 (International free phone) and +870 (Inmarsat). See
https://github.com/DrHyde/perl-modules-Number-Phone/issues/17

- Bug fix: NANP toll-free numbers corrected. 833 area code now supported,
and regex fixed to only match when the B and C digits are the same, so
Expand Down
16 changes: 16 additions & 0 deletions MANIFEST
Expand Up @@ -97,6 +97,13 @@ t/manifest-contains-all-modules.t
t/only-use-blib-under-make-test.t
t/deprecations.t
t/constructor.t
lib/Number/Phone/StubCountry/GMSS/Globalstar.pm
lib/Number/Phone/StubCountry/GMSS/ICO.pm
lib/Number/Phone/StubCountry/GMSS/Iridium.pm
lib/Number/Phone/StubCountry/InternationalNetworks882/Telespazio.pm
lib/Number/Phone/StubCountry/InternationalNetworks882/Thuraya.pm
lib/Number/Phone/StubCountry/InternationalNetworks883/MTTGlobalNetworks.pm
lib/Number/Phone/StubCountry/InternationalNetworks883/Mobistar.pm
lib/Number/Phone/StubCountry/AC.pm
lib/Number/Phone/StubCountry/AD.pm
lib/Number/Phone/StubCountry/AE.pm
Expand Down Expand Up @@ -342,3 +349,12 @@ lib/Number/Phone/StubCountry/YT.pm
lib/Number/Phone/StubCountry/ZA.pm
lib/Number/Phone/StubCountry/ZM.pm
lib/Number/Phone/StubCountry/ZW.pm
lib/Number/Phone/StubCountry/InternationalFreephone.pm
lib/Number/Phone/StubCountry/SharedCostServices.pm
lib/Number/Phone/StubCountry/Inmarsat.pm
lib/Number/Phone/StubCountry/UniversalPersonalTelecoms.pm
lib/Number/Phone/StubCountry/GMSS.pm
lib/Number/Phone/StubCountry/InternationalNetworks882.pm
lib/Number/Phone/StubCountry/InternationalNetworks883.pm
lib/Number/Phone/StubCountry/TelecomsForDisasterRelief.pm
lib/Number/Phone/StubCountry/InternationalPremiumRate.pm
10 changes: 9 additions & 1 deletion build-data.country-mapping
Expand Up @@ -12,6 +12,8 @@ use warnings;
use lib 'buildtools';
use Number::Phone::BuildHelpers;

my %known_non_country_codes = known_non_country_codes();

$| = 1;

use XML::XPath;
Expand Down Expand Up @@ -243,7 +245,6 @@ foreach my $tuple (
# [ 38649 => 'XK' ],

do {
my %known_non_country_codes = known_non_country_codes();
map {
[ $_ => $known_non_country_codes{$_} ]
} keys %known_non_country_codes
Expand All @@ -260,6 +261,13 @@ foreach my $tuple (
";\n";
}

foreach my $IDD (keys %known_non_country_codes) {
my $name = $known_non_country_codes{$IDD};
print $module_fh qq{
\$Number::Phone::Country::prefix_codes{'$name'} = ['$IDD'];
};
}

# countries that don't exist in libphonenumber
# FIXME unchecked
print $module_fh q{
Expand Down
5 changes: 5 additions & 0 deletions build-data.sh
Expand Up @@ -161,6 +161,7 @@ fi
# if share/Number-Phone-UK-Data.db doesn't exist, or OFCOM's stuff or
# libphonenumber's list of area codes is newer ...
if test ! -e share/Number-Phone-UK-Data.db -o \
buildtools/Number/Phone/BuildHelpers.pm -nt share/Number-Phone-UK-Data.db -o \
libphonenumber/resources/geocoding/en/44.txt -nt share/Number-Phone-UK-Data.db -o \
data-files/sabcde11_12.xlsx -nt share/Number-Phone-UK-Data.db -o \
data-files/sabcde13.xlsx -nt share/Number-Phone-UK-Data.db -o \
Expand Down Expand Up @@ -189,6 +190,7 @@ fi

# lib/Number/Phone/Country/Data.pm doesn't exist, or if libphonenumber/resources/PhoneNumberMetadata.xml is newer ...
if test ! -e lib/Number/Phone/Country/Data.pm -o \
buildtools/Number/Phone/BuildHelpers.pm -nt lib/Number/Phone/Country/Data.pm -o \
build-data.country-mapping -nt lib/Number/Phone/Country/Data.pm -o \
libphonenumber/resources/PhoneNumberMetadata.xml -nt lib/Number/Phone/Country/Data.pm;
then
Expand All @@ -204,6 +206,7 @@ fi
# lib/Number/Phone/NANP/Data.pm doesn't exist, or if libphonenumber/resources/geocoding/en/1.txt or PhoneNumberMetadata.xml is newer ...
if test ! -e lib/Number/Phone/NANP/Data.pm -o \
! -e share/Number-Phone-NANP-Data.db -o \
buildtools/Number/Phone/BuildHelpers.pm -nt lib/Number/Phone/NANP/Data.pm -o \
build-data.nanp -nt lib/Number/Phone/NANP/Data.pm -o \
libphonenumber/resources/geocoding/en/1.txt -nt lib/Number/Phone/NANP/Data.pm -o \
libphonenumber/resources/PhoneNumberMetadata.xml -nt lib/Number/Phone/NANP/Data.pm -o \
Expand All @@ -227,6 +230,7 @@ NANPDATETIME=$(perl -e 'print +(stat(shift))[9]' $(ls -rt data-files/[0-9][0-9][
# lib/Number/Phone/StubCountry/KZ.pm doesn't exist, or if libphonenumber/resources/PhoneNumberMetadata.xml is newer,
# or if lib/Number/Phone/NANP/Data.pm is newer ...
if test ! -e lib/Number/Phone/StubCountry/KZ.pm -o \
buildtools/Number/Phone/BuildHelpers.pm -nt lib/Number/Phone/StubCountry/KZ.pm -o \
build-data.stubs -nt lib/Number/Phone/StubCountry/KZ.pm -o \
libphonenumber/resources/geocoding/en/1.txt -nt lib/Number/Phone/StubCountry/KZ.pm -o \
libphonenumber/resources/PhoneNumberMetadata.xml -nt lib/Number/Phone/StubCountry/KZ.pm -o \
Expand All @@ -243,6 +247,7 @@ fi

# t/example-phone-numbers.t doesn't exist, or if libphonenumber/resources/PhoneNumberMetadata.xml is newer
if test ! -e t/example-phone-numbers.t -o \
buildtools/Number/Phone/BuildHelpers.pm -nt t/example-phone-numbers.t -o \
build-tests.pl -nt t/example-phone-numbers.t -o \
libphonenumber/resources/PhoneNumberMetadata.xml -nt t/example-phone-numbers.t;
then
Expand Down
23 changes: 13 additions & 10 deletions build-data.stubs
Expand Up @@ -28,7 +28,7 @@ open(my $manifest_fh, 'MANIFEST') || die("Can't read MANIFEST\n");
my @manifest_files = grep { /./ } <$manifest_fh>;
close($manifest_fh);
open($manifest_fh, '>', 'MANIFEST') || die("Can't write MANIFEST\n");
print $manifest_fh "$_" foreach( grep { $_ !~ m{^lib/Number/Phone/StubCountry/} } @manifest_files);
print $manifest_fh "$_" foreach( grep { $_ !~ m{^lib/Number/Phone/StubCountry/\w+\.pm} } @manifest_files);

mkdir('lib/Number/Phone/StubCountry');
mkdir('t/lib');
Expand All @@ -44,6 +44,8 @@ my @gb_formats = formats_for($xml->find(
'/phoneNumberMetadata/territories/territory[@id="GB"]')->get_node(1)
);

unlink(glob('lib/Number/Phone/StubCountry/*pm'));

TERRITORY: foreach my $territory (@territories) {
my $IDD_country_code = ''.$territory->find('@countryCode');
my $national_code = ''.$territory->find('@nationalPrefixForParsing') || ''.$territory->find('@nationalPrefix');
Expand All @@ -58,12 +60,13 @@ TERRITORY: foreach my $territory (@territories) {
next TERRITORY;
}

unlink "$dir/$ISO_country_code.pm"; # to clear out countries that no longer exist
my $final_class_part = get_final_class_part($ISO_country_code, $IDD_country_code);
my $filename = "$dir/$final_class_part.pm";

open(my $module_fh, '>:encoding(UTF-8)', "$dir/$ISO_country_code.pm")
|| die("Can't write $dir/$ISO_country_code.pm: $!\n");
print $manifest_fh "$dir/$ISO_country_code.pm\n";
print $module_fh preamble($ISO_country_code);
open(my $module_fh, '>:encoding(UTF-8)', $filename)
|| die("Can't write $filename: $!\n");
print $manifest_fh "$filename\n";
print $module_fh preamble($final_class_part);

my @formatters = formats_for($territory, $ISO_country_code);
print $module_fh 'my '.Data::Dumper->new([\@formatters], [qw(formatters)])->Dump()."\n";
Expand Down Expand Up @@ -143,7 +146,7 @@ TERRITORY: foreach my $territory (@territories) {
my \$class = shift;
my \$number = shift;
\$number =~ s/(^\\+$IDD_country_code|\\D)//g;
my \$self = bless({ number => \$number, formatters => \$formatters, validators => \$validators, ".
my \$self = bless({ country_code => '$IDD_country_code', number => \$number, formatters => \$formatters, validators => \$validators, ".
(($IDD_country_code != 1 && $got_area_names) ? 'areanames => \\%areanames' : '')
."}, \$class);
";
Expand Down Expand Up @@ -179,7 +182,7 @@ TERRITORY: foreach my $territory (@territories) {
}

push @code,
" \$self = bless({ number => \$number, formatters => \$formatters, validators => \$validators, ".
" \$self = bless({ country_code => '$IDD_country_code', number => \$number, formatters => \$formatters, validators => \$validators, ".
(($IDD_country_code != 1 && $got_area_names) ? 'areanames => \\%areanames' : '')
."}, \$class);";

Expand All @@ -192,7 +195,7 @@ TERRITORY: foreach my $territory (@territories) {
}

sub preamble {
my $iso_code = shift;
my $final_class_part = shift;
"# automatically generated file, don't edit\n\n".
q{

Expand All @@ -210,7 +213,7 @@ sub preamble {
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
package Number::Phone::StubCountry::}.$iso_code.q{;
package Number::Phone::StubCountry::}.$final_class_part.q{;
use base qw(Number::Phone::StubCountry);

use strict;
Expand Down
75 changes: 66 additions & 9 deletions build-tests.pl
Expand Up @@ -29,6 +29,9 @@
warn("skipping 'country' $ISO_country_code (+$IDD_country_code)\n");
next TERRITORY;
}

my $final_class_part = get_final_class_part($ISO_country_code, $IDD_country_code);

my @example_numbers = $territory->find('*/exampleNumber')->get_nodelist();
NUMBER: foreach my $example_number (@example_numbers) {
my $number = $example_number->string_value();
Expand All @@ -44,7 +47,7 @@
($_->[0] eq 'GB') ? ($_, ['UK', $_->[1]]) : $_
} (
[$ISO_country_code, "+$IDD_country_code$number"],
[$ISO_country_code, $number],
[$ISO_country_code, "$number"],
[ "+$IDD_country_code$number"]
);
TUPLE: foreach my $test_tuple (@test_tuples) {
Expand Down Expand Up @@ -108,6 +111,9 @@
warnonce("$ISO_country_code number +$IDD_country_code $number in libphonenumber's example data needs to be treated as IT");
$test_tuple->[0] = 'IT';
}
if($test_tuple->[0] eq '001') {
$test_tuple->[0] = get_final_class_part($ISO_country_code, $IDD_country_code);
}
if($IDD_country_code eq '44' && $number =~ /
^
800 123 4567 |
Expand All @@ -122,31 +128,66 @@
# warn("$ISO_country_code number +$IDD_country_code $number in libphonenumber's example data is wrong\n");
next NUMBER;
}
my $constructor_args = [map { "'$_'" } @{$test_tuple}];
my $constructor_args = [@{$test_tuple}];
my @classes = $IDD_country_code eq '44' ? qw(Number::Phone Number::Phone::Lib) :
$IDD_country_code eq '1' ? qw(Number::Phone Number::Phone::Lib) :
$IDD_country_code =~ /$non_geo_IDD_codes_regex/
? qw(Number::Phone Number::Phone::Lib) :
qw(Number::Phone::Lib);

if(!ref($test_method)) { $test_method = [$test_method] }
my $test_methods = [map { "'$_'" } @{$test_method}];
my $test_methods = [@{$test_method}];

foreach my $class (@classes) {
push @tests, {
class => $class,
args => $constructor_args,
methods => $test_methods
methods => $test_methods,
test_country => 0 + !($IDD_country_code eq '1' && grep { /^is_(specialrate|tollfree|personal)$/ } @{$test_methods})
};
}
}
}
}

foreach my $class (qw(Number::Phone Number::Phone::Lib)) {
foreach my $test (
[qw(GMSS::Iridium 612345678 +881612345678)],
[qw(GMSS::ICO 012345678 +881012345678)],
[qw(GMSS::Globalstar 812345678 +881812345678)],
[qw(InternationalNetworks882::Telespazio 13201234 +88213201234)],
[qw(InternationalNetworks882::Thuraya 1610100 +8821610100 )],
[qw(InternationalNetworks883::MTTGlobalNetworks 14000000 +88314000000)],
) {
my @is = $test->[0] =~ /^GMSS/ ? 'is_mobile' :
$test->[0] =~ /^InternationalNetworks88[23]/ ? 'is_ipphone' :
();
push @tests, {
class => $class,
args => [$test->[2]],
methods => \@is,
test_country => 0,
};
push @tests, {
class => $class,
args => [$test->[0], $test->[$_]],
methods => \@is,
test_country => 1,
} foreach(1, 2);
}
}

print $testfh 'foreach my $test (';
foreach my $test (@tests) {
print $testfh "{ class => '".$test->{class}."', args => [".join(',',@{$test->{args}})."], methods => [".join(',',@{$test->{methods}})."] },\n";
print $testfh "{
class => '".$test->{class}."',
args => [".join(',', map { "'$_'" } @{$test->{args}})."],
methods => [".join(',', map { "'$_'" } @{$test->{methods}})."],
test_country => ".$test->{test_country}.",
},\n";
}
print $testfh ') {
my($class, $args, $methods) = map { $test->{$_} } qw(class args methods);
my($class, $args, $methods, $test_country) = map { $test->{$_} } qw(class args methods test_country);
SKIP: {
skip("built --without_uk so not testing that full-fat implementation today", 1)
if(
Expand All @@ -155,12 +196,28 @@
);
my $object = $class->new(@{$args});
my $obj_class = $object ? blessed($object) : "[undef]";
ok(defined($object), "$class->new(".join(", ", @{$args}).") returns an object: $obj_class") &&
ok(defined($object), "$class->new(".join(", ", @{$args}).") returns an object: $obj_class") &&
ok(
# grep is because a number might need to be checked as is_geographic *or* is_fixed_line
(grep { $class->new(@{$args})->$_() } @{$methods}),
(grep { $object->$_() } @{$methods}),
"$class->new(".join(", ", @{$args}).")->".join(", ", @{$methods})."() does the right thing"
);
if($test_country && scalar(@{$args}) > 1) {
my $got_country = $object->country();
(my $expected_country = $args->[0]) =~ s/.*:://;
if(
($got_country =~ /^(UK|GB)$/ && $expected_country =~ /^(UK|GB)$/) ||
($got_country eq "VA" && $expected_country eq "IT" ) ||
($got_country eq "Iridium" && $expected_country eq "GMSS" )
) {
pass "$class->new(".join(", ", @{$args}).")->country() does the right thing"
} else {
is(
$object->country(), $expected_country,
"$class->new(".join(", ", @{$args}).")->country() does the right thing"
);
}
}
}
}
done_testing();
Expand Down Expand Up @@ -191,7 +248,7 @@ sub preamble {
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

use strict;
use warnings;
use lib 't/inc';
Expand Down