Repository: carr/phone Branch: master Commit: ae4b98a6fe3e Files: 41 Total size: 104.9 KB Directory structure: gitextract_cgkn_9w2/ ├── .document ├── .github/ │ └── workflows/ │ └── ci.yml ├── .gitignore ├── .ruby-version ├── .yardopts ├── ChangeLog.md ├── Gemfile ├── LICENSE.txt ├── README.md ├── Rakefile ├── data/ │ └── phone/ │ └── countries.yml ├── lib/ │ ├── phone/ │ │ ├── country.rb │ │ ├── errors.rb │ │ └── version.rb │ └── phone.rb ├── phone.gemspec ├── test/ │ ├── countries/ │ │ ├── au_test.rb │ │ ├── ba_test.rb │ │ ├── be_test.rb │ │ ├── de_test.rb │ │ ├── es_test.rb │ │ ├── fr_test.rb │ │ ├── gb_test.rb │ │ ├── hr_test.rb │ │ ├── hu_test.rb │ │ ├── ie_test.rb │ │ ├── me_test.rb │ │ ├── nl_test.rb │ │ ├── nz_test.rb │ │ ├── pt_test.rb │ │ ├── rs_test.rb │ │ ├── se_test.rb │ │ ├── si_test.rb │ │ ├── ua_test.rb │ │ ├── us_test.rb │ │ ├── uy_test.rb │ │ └── za_test.rb │ ├── extension_test.rb │ ├── helper.rb │ └── phone_test.rb └── test_usa_phones_with_extensions.csv ================================================ FILE CONTENTS ================================================ ================================================ FILE: .document ================================================ - ChangeLog.md LICENSE.txt ================================================ FILE: .github/workflows/ci.yml ================================================ name: Ruby CI on: push: branches: [ master ] pull_request: branches: [ master ] jobs: test: runs-on: ubuntu-latest strategy: matrix: ruby-version: ["3.4", "3.3", "3.2", "3.1", "3.0", "2.7", "jruby-head", "ruby-head"] steps: - uses: actions/checkout@v4 - name: Set up Ruby ${{ matrix.ruby-version }} uses: ruby/setup-ruby@v1 with: ruby-version: ${{ matrix.ruby-version }} bundler-cache: true # runs 'bundle install' and caches installed gems automatically - name: Run tests run: bundle exec rake ================================================ FILE: .gitignore ================================================ Gemfile.lock doc/ pkg/ tmp/ vendor/cache/*.gem ================================================ FILE: .ruby-version ================================================ 2.0.0 ================================================ FILE: .yardopts ================================================ --markup markdown --title "phone Documentation" --protected ================================================ FILE: ChangeLog.md ================================================ # 1.3.0 / (unreleased) * Update README for yaml name and location (pepe) * Relocate / rename `data/phone_countries.yml` to `data/phone/countries.yml` (elskwid) * [improvement] Add modern gem infrastructure - add bundler, update gemspec, convert to minitest, locate gem files in proper directories, add .ruby-version, update README, update LICENSE.txt, add Changelog.md. (elskwid) * [improvement] Memoize country code regex. (tiegz) * [improvement] Update regex for: ZA, UY, NL, BE, FR, HU, PT, UA, RS, HR, SE, SI, and BA. (g1smd) * [improvement] Add IE support. (dramalho) * [improvement] Update #split_to_parts to provide a format override and handle nil parts. (dramalho) * [improvement] Add NZ support. (jurgens) * [improvement] Add options support to `#valid?`. (soulcutter) * [improvement] Remove need for `cattr_accessor`. (elskwid) * [fix] Incorrect error raised when missing phone number and add missing test. (elskwid) * [fix] Fix extension handling in `::parse`. (elskwid) * [improvement] Remove need for ActiveSupport detection. (elskwid) * [improvement] Remove monkeypatching support library. (elskwid) * [improvement] Add support for Travis CI. (elskwid) * [improvement] Add tests for parameter mutation in `#valid?`. (elskwid) * [fix] Fix parameter mutation in extension extraction. (elskwid) * [fix] ME (Montenegro) area code correction and tests. (bsboris) * [improvement] Add test for parameter mutation in `::parse`. (elskwid) * [improvement] Code style clean up and method refactoring to clarify processing and remove multiple gsub calls. (elskwid) * [doc] README updates. # 1.2.3 / 2013-11-16 * [fix] Bring changes from v1.1 that were mysteriously missing from repo. (elskwid) - README updates - Spain area code updates - Support 3 character codes for countries - Update default area code - Update `::normalize` # 1.2.2 / 2013-11-15 * Add license to gemspec. (bf4) # 1.2.1 / 2013-10-24 * Add errors.rb to gemspec to fix gem. (mtarnovan) # 1.2 / 2013-10-23 (yanked) * Released to capture updates made after version 1.1. (elskwid) * Add specific exception classes. (miloshadzic) # 1.1 / 2011-06-23 * Implement `==`. (haxney and carr) * Update Uraguay area codes and tests. (tiegz) # 1.0 / 2011-04-04 * Namespaced library as `Phoner::Phone` (carr) # Previous versions ... ================================================ FILE: Gemfile ================================================ source "https://rubygems.org" gemspec group :doc do gem "redcarpet" end group :test do gem "rake" end ================================================ FILE: LICENSE.txt ================================================ Copyright (c) 2010-2013 Tomislav Car Modifications copyright (c) 2010 Todd Eichel for Fooala, Inc. Copyright (c) 2013 Don Morrison Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: README.md ================================================ [gem]: https://rubygems.org/gems/phone [stable]: https://github.com/carr/phone/tree/v1.2.3 [gem-beta]: https://rubygems.org/gems/phone/versions/1.3.0.beta1 [beta]: https://github.com/carr/phone/tree/v1.3.0.beta1/ [ci]: https://github.com/carr/phone/actions/workflows/ci.yml # phone [![Beta Gem Version](https://img.shields.io/badge/beta-v1.3.0.beta1-blue.svg)][gem-beta] [![Gem Version](https://img.shields.io/gem/v/phone.svg)][gem] [![Build Status](https://github.com/carr/phone/actions/workflows/ci.yml/badge.svg)][ci] Parsing, validating and creating phone numbers * [Homepage](https://github.com/carr/phone#readme) * [Issues](https://github.com/carr/phone/issues) * [Documentation](http://rubydoc.info/gems/phone/frames) * [Email](mailto:don at elskwid.net) ## Version This documentation is for the unreleased development branch. * Current release: [1.3.0.beta1][beta] * Current stable: [1.2.3][stable] ## Description Ruby library for phone number parsing, validation, and formatting. ## Features ### Automatic country and area code detection Phone does its best to automatically detect the country and area code while parsing. To do this, phone uses data stored in `data/phone/countries.yml`. Each country code can have a regular expression named `area_code` that describes what the area code for that particular country looks like. If an `area_code` regular expression isn't specified, a default value which is considered correct for the US will be used. If your country has phone numbers longer that 8 digits - exluding country and area code - you can specify that within the country's configuration in `data/phone/countries.yml` ### Validating Validating is very relaxed, basically it strips out everything that's not a number or '+' character: ```ruby Phoner::Phone.valid? 'blabla 091/555-4488 blabla' ``` ### Formatting Formating is done via the `#format` method. The method accepts a `Symbol` or a `String`. When given a string, it interpolates the string with the following fields: * %c - country_code (385) * %a - area_code (91) * %A - area_code with leading zero (091) * %n - number (5554488) * %f - first @@n1_length characters of number (configured through Phoner::Phone.n1_length), default is 3 (555) * %l - last characters of number (4488) * %x - the extension number ```ruby pn = Phoner::Phone.parse('+385915554488') pn.to_s # => "+385915554488" pn.format("%A/%f-%l") # => "091/555-4488" pn.format("+ %c (%a) %n") # => "+ 385 (91) 5554488" ``` When given a symbol it is used as a lookup for the format in the Phoner::Phone.named_formats hash. ```ruby pn.format(:europe) # => "+385 (0) 91 555 4488" pn.format(:us) # => "(234) 123-4567" pn.format(:default_with_extension) # => "+3851234567x143" ``` You can add your own custom named formats like so: ```ruby Phoner::Phone.named_formats[:short] = '%A/%n1-%n2' pn.format(:short) # => 091/555-4488 ``` ### Finding countries by their isocode If you don't have the country code, but you know from other sources what country a phone is from, you can retrieve the country using the country isocode (such as 'de', 'es', 'us', ...). Remember to call `Phoner::Country.load` before using this lookup. ```ruby if country = Phoner::Country.find_by_country_isocode(user_country_isocode) phone_number = Phoner::Phone.parse(user_input, :country_code => country.country_code) end ``` ## Examples ```ruby require 'phone' ``` ### Initializing Initialize a new phone object with the number, area code, country code and extension number: ```ruby Phoner::Phone.new('5554488', '91', '385') ``` ```ruby Phoner::Phone.new(:number => '5554488', :area_code => '91', :country_code => '385', :extension => '143') ``` ### Parsing Create a new phone object by parsing from a string. Phoner::Phone does it's best to detect the country and area codes: ```ruby Phoner::Phone.parse '+385915554488' Phoner::Phone.parse '00385915554488' ``` If the country or area code isn't given in the string, you must set it, otherwise it doesn't work: ```ruby Phoner::Phone.parse '091/555-4488', :country_code => '385' Phoner::Phone.parse '(091) 555 4488', :country_code => '385' ``` If you feel that it's tedious, set the default country code once: ```ruby Phoner::Phone.default_country_code = '385' Phoner::Phone.parse '091/555-4488' Phoner::Phone.parse '(091) 555 4488' ``` Same goes for the area code: ```ruby Phoner::Phone.parse '451-588', :country_code => '385', :area_code => '47' ``` or ```ruby Phoner::Phone.default_country_code = '385' Phoner::Phone.default_area_code = '47' Phoner::Phone.parse '451-588' ``` ## Adding and maintaining countries From time to time, the specifics about your countries information may change. You can add or update your countries configuration by editing `data/phone/countries.yml` The following are the available attributes for configuration: * `country_code`: Required. A string representing your country's international dialling code. e.g. "123" * `national_dialing_prefix`: Required. A string representing your default dialling prefix for national calls. e.g. "0" * `char_3_code`: Required. A string representing a country's ISO code. e.g. "US" * `name`: Required. The name of the country. e.g. "Denmark" * `international_dialing_prefix`: Required. The dialling prefix a country typically uses when making international calls. e.g. "0" * `area_code`: Optional. A regular expression detailing valid area codes. Default: "\d{3}" i.e. any 3 digits. * `max_num_length`: Optional. The maximum length of a phone number after country and area codes have been removed. Default: 8 ## Test Countries * [AU] Australia * [BA] Bosnia and Herzegovina * [BE] Belgium * [DE] Germany * [ES] Spain * [FR] France * [GB] United Kingdom * [HR] Croatia * [HU] Hungary * [IE] Ireland * [ME] Montenegro * [NL] Netherlands * [NZ] New Zealand * [PT] Portugal * [RS] Serbia * [SE] Sweden * [SI] Slovenia * [UA] Ukraine * [US] United States * [UY] Uruguay * [ZA] South Africa ## Known issues There's an issue with Germany and Spanish area codes. ## Requirements ## Install $ gem install phone Or as a Rails plugin, in your Gemfile gem 'phone' And then `bundle install` from your command line. ## Copyright Copyright (c) 2010-2013 Tomislav Car, [Infinum](http://www.infinum.co) Copyright (c) 2013 Don Morrison See [LICENSE.txt](LICENSE.txt) for details. ## Contributors Don Morrison, Michael Squires, Todd Eichel (Fooala, Inc.), chipiga, Etienne Samson, Luke Randall, Jakob Hilden, Tieg Zaharia ================================================ FILE: Rakefile ================================================ # encoding: utf-8 require "rubygems" begin require "bundler" rescue LoadError => e warn e.message warn "Run `gem install bundler` to install Bundler." exit -1 end begin Bundler.setup(:development) rescue Bundler::BundlerError => e warn e.message warn "Run `bundle install` to install missing gems." exit e.status_code end require "rake" require "rubygems/tasks" Gem::Tasks.new require "rake/testtask" Rake::TestTask.new do |test| test.libs << "test" test.pattern = "test/**/*_test.rb" test.verbose = true end require "yard" YARD::Rake::YardocTask.new task :doc => :yard task :default => :test ================================================ FILE: data/phone/countries.yml ================================================ --- "676": :country_code: "676" :national_dialing_prefix: None :char_2_code: None :char_3_code: TO :name: Tonga :international_dialing_prefix: "0" "54": :country_code: "54" :national_dialing_prefix: "0" :char_2_code: "0" :char_3_code: AR :name: Argentina :international_dialing_prefix: "0" "506": :country_code: "506" :national_dialing_prefix: None :char_2_code: None :char_3_code: CR :name: Costa Rica :international_dialing_prefix: "0" "251": :country_code: "251" :national_dialing_prefix: "0" :char_2_code: "0" :char_3_code: ET :name: Ethiopia :international_dialing_prefix: "0" "590": :country_code: "590" :national_dialing_prefix: None :char_2_code: None :char_3_code: GP :name: Guadeloupe :international_dialing_prefix: "0" "82": :country_code: "82" :national_dialing_prefix: "0" :char_2_code: "0" :char_3_code: KR :name: Korea, Republic of :international_dialing_prefix: "1" "223": :country_code: "223" :national_dialing_prefix: "0" :char_2_code: "0" :char_3_code: ML :name: Mali :international_dialing_prefix: "0" "420": :country_code: "420" :national_dialing_prefix: None :char_2_code: None :char_3_code: CZ :name: Czech Republic :international_dialing_prefix: "0" "252": :country_code: "252" :national_dialing_prefix: None :char_2_code: None :char_3_code: SO :name: Somalia :international_dialing_prefix: "0" "677": :country_code: "677" :national_dialing_prefix: None :char_2_code: None :char_3_code: SB :name: Solomon Islands :international_dialing_prefix: "0" "421": :country_code: "421" :national_dialing_prefix: "0" :char_2_code: "0" :char_3_code: SK :name: Slovakia :international_dialing_prefix: "0" "507": :country_code: "507" :national_dialing_prefix: None :char_2_code: None :char_3_code: PA :name: Panama :international_dialing_prefix: "0" "591": :country_code: "591" :national_dialing_prefix: "10" :char_2_code: "10" :char_3_code: BO :name: Bolivia :international_dialing_prefix: "10" "224": :country_code: "224" :national_dialing_prefix: None :char_2_code: None :char_3_code: GN :name: Guinea :international_dialing_prefix: "0" "84": :country_code: "84" :national_dialing_prefix: "0" :char_2_code: "0" :char_3_code: VN :name: Viet Nam :international_dialing_prefix: "0" "678": :country_code: "678" :national_dialing_prefix: None :char_2_code: None :char_3_code: VU :name: Vanuatu :international_dialing_prefix: "0" "27": :country_code: "27" :national_dialing_prefix: "0" :char_2_code: "0" :char_3_code: ZA :name: South Africa :international_dialing_prefix: "0" :area_code: "800|86[01]|[1-9]\\d" :max_num_length: 11 "508": :country_code: "508" :national_dialing_prefix: "0" :char_2_code: "0" :char_3_code: PM :name: Saint Pierre And Miquelon :international_dialing_prefix: "0" "55": :country_code: "55" :national_dialing_prefix: "14" :char_2_code: "14" :char_3_code: BR :name: Brazil :international_dialing_prefix: "14" "253": :country_code: "253" :national_dialing_prefix: None :char_2_code: None :char_3_code: DJ :name: Djibouti :international_dialing_prefix: "0" "592": :country_code: "592" :national_dialing_prefix: None :char_2_code: None :char_3_code: GY :name: Guyana :international_dialing_prefix: "0" "225": :country_code: "225" :national_dialing_prefix: "0" :char_2_code: "0" :char_3_code: CI :name: "C\xC3\xB4te D'Ivoire" :international_dialing_prefix: "0" "56": :country_code: "56" :national_dialing_prefix: "0" :char_2_code: "0" :char_3_code: CL :name: Chile :international_dialing_prefix: "0" "679": :country_code: "679" :national_dialing_prefix: None :char_2_code: None :char_3_code: FJ :name: Fiji :international_dialing_prefix: "0" "509": :country_code: "509" :national_dialing_prefix: None :char_2_code: None :char_3_code: HT :name: Haiti :international_dialing_prefix: "0" "593": :country_code: "593" :national_dialing_prefix: "0" :char_2_code: "0" :char_3_code: EC :name: Ecuador :international_dialing_prefix: "0" "254": :country_code: "254" :national_dialing_prefix: "0" :char_2_code: "0" :char_3_code: KE :name: Kenya :international_dialing_prefix: "0" "226": :country_code: "226" :national_dialing_prefix: None :char_2_code: None :char_3_code: BF :name: Burkina Faso :international_dialing_prefix: "0" "423": :country_code: "423" :national_dialing_prefix: None :char_2_code: None :char_3_code: LI :name: Liechtenstein :international_dialing_prefix: "0" "255": :country_code: "255" :national_dialing_prefix: "0" :char_2_code: "0" :char_3_code: TZ :name: Tanzania, United Republic of :international_dialing_prefix: "0" "227": :country_code: "227" :national_dialing_prefix: "0" :char_2_code: "0" :char_3_code: NE :name: Niger :international_dialing_prefix: "0" "594": :country_code: "594" :national_dialing_prefix: None :char_2_code: None :char_3_code: GF :name: French Guiana :international_dialing_prefix: "0" "86": :country_code: "86" :national_dialing_prefix: "0" :char_2_code: "0" :char_3_code: CN :name: China :international_dialing_prefix: "0" "960": :country_code: "960" :national_dialing_prefix: None :char_2_code: None :char_3_code: MV :name: Maldives :international_dialing_prefix: "0" "57": :country_code: "57" :national_dialing_prefix: "5" :char_2_code: "5" :char_3_code: CO :name: Colombia :international_dialing_prefix: "5" "58": :country_code: "58" :national_dialing_prefix: "0" :char_2_code: "0" :char_3_code: VE :name: Venezuela, Bolivarian Republic of :international_dialing_prefix: "0" "256": :country_code: "256" :national_dialing_prefix: "0" :char_2_code: "0" :char_3_code: UG :name: Uganda :international_dialing_prefix: "0" "228": :country_code: "228" :national_dialing_prefix: None :char_2_code: None :char_3_code: TG :name: Togo :international_dialing_prefix: "0" "595": :country_code: "595" :national_dialing_prefix: "0" :char_2_code: "0" :char_3_code: PY :name: Paraguay :international_dialing_prefix: "2" "961": :country_code: "961" :national_dialing_prefix: "0" :char_2_code: "0" :char_3_code: LB :name: Lebanon :international_dialing_prefix: "0" "596": :country_code: "596" :national_dialing_prefix: None :char_2_code: None :char_3_code: MQ :name: Martinique :international_dialing_prefix: "0" "257": :country_code: "257" :national_dialing_prefix: None :char_2_code: None :char_3_code: BI :name: Burundi :international_dialing_prefix: "0" "229": :country_code: "229" :national_dialing_prefix: None :char_2_code: None :char_3_code: BJ :name: Benin :international_dialing_prefix: "0" "962": :country_code: "962" :national_dialing_prefix: "0" :char_2_code: "0" :char_3_code: JO :name: Jordan :international_dialing_prefix: "0" "963": :country_code: "963" :national_dialing_prefix: "0" :char_2_code: "0" :char_3_code: SY :name: Syrian Arab Republic :international_dialing_prefix: "0" "597": :country_code: "597" :national_dialing_prefix: "0" :char_2_code: "0" :char_3_code: SR :name: Suriname :international_dialing_prefix: "0" "680": :country_code: "680" :national_dialing_prefix: None :char_2_code: None :char_3_code: PW :name: Palau :international_dialing_prefix: "0" "258": :country_code: "258" :national_dialing_prefix: "0" :char_2_code: "0" :char_3_code: MZ :name: Mozambique :international_dialing_prefix: "0" "30": :country_code: "30" :national_dialing_prefix: None :char_2_code: None :char_3_code: GR :name: Greece :international_dialing_prefix: "0" "681": :country_code: "681" :national_dialing_prefix: None :char_2_code: None :char_3_code: WF :name: Wallis and Futuna :international_dialing_prefix: "19" "598": :country_code: "598" :national_dialing_prefix: "0" :char_2_code: "0" :char_3_code: UY :name: Uruguay :international_dialing_prefix: "0" :area_code: "2|42|4364|43[34567]|4452|44[3457]|454[24]|4567?|4586|46[234]|4675|47[237]|4779|9[0-9]" "992": :country_code: "992" :national_dialing_prefix: "8" :char_2_code: "8" :char_3_code: TJ :name: Tajikistan :international_dialing_prefix: "810" "31": :country_code: "31" :national_dialing_prefix: "0" :char_2_code: "0" :char_3_code: NL :name: Netherlands :international_dialing_prefix: "0" :area_code: "6760|66|6|800|878|8[4578]|90[069]|1[035]|2[0346]|3[03568]|4[0356]|5[0358]|7\\d|11[134578]|16[124-8]|17[24]|18[0-467]|22[2-46-9]|25[125]|29[479]|31[3-8]|32[01]|34[1-8]|41[12368]|47[58]|48[15-8]|49[23579]|5[129][1-9]|54[134-8]|56[126]|57[0-3578]" "850": :country_code: "850" :national_dialing_prefix: "0" :char_2_code: "0" :char_3_code: KP :name: Korea, Democratic People's Republic Of :international_dialing_prefix: "0" "964": :country_code: "964" :national_dialing_prefix: None :char_2_code: None :char_3_code: IQ :name: Iraq :international_dialing_prefix: "0" "370": :country_code: "370" :national_dialing_prefix: "8" :char_2_code: "8" :char_3_code: LT :name: Lithuania :international_dialing_prefix: "0" "993": :country_code: "993" :national_dialing_prefix: "8" :char_2_code: "8" :char_3_code: TM :name: Turkmenistan :international_dialing_prefix: "810" "599": :country_code: "599" :national_dialing_prefix: "0" :char_2_code: "0" :char_3_code: AN :name: Netherlands Antilles :international_dialing_prefix: "0" "32": :country_code: "32" :national_dialing_prefix: "0" :char_2_code: "0" :char_3_code: BE :name: Belgium :international_dialing_prefix: "0" :area_code: "800|90\\d|2|3|4|9|1[0-69]|5\\d|6[013-9]|7[0178]|8[1-9]" "965": :country_code: "965" :national_dialing_prefix: None :char_2_code: None :char_3_code: KW :name: Kuwait :international_dialing_prefix: "0" "371": :country_code: "371" :national_dialing_prefix: "8" :char_2_code: "8" :char_3_code: LV :name: Latvia :international_dialing_prefix: "0" "682": :country_code: "682" :national_dialing_prefix: "0" :char_2_code: "0" :char_3_code: CK :name: Cook Islands :international_dialing_prefix: "0" "60": :country_code: "60" :national_dialing_prefix: "0" :char_2_code: "0" :char_3_code: MY :name: Malaysia :international_dialing_prefix: "0" "966": :country_code: "966" :national_dialing_prefix: "0" :char_2_code: "0" :char_3_code: SA :name: Saudi Arabia :international_dialing_prefix: "0" "683": :country_code: "683" :national_dialing_prefix: None :char_2_code: None :char_3_code: NU :name: Niue :international_dialing_prefix: "0" "230": :country_code: "230" :national_dialing_prefix: None :char_2_code: None :char_3_code: MU :name: Mauritius :international_dialing_prefix: "20" "994": :country_code: "994" :national_dialing_prefix: "8" :char_2_code: "8" :char_3_code: AZ :name: Azerbaijan :international_dialing_prefix: "810" "852": :country_code: "852" :national_dialing_prefix: None :char_2_code: None :char_3_code: HK :name: Hong Kong :international_dialing_prefix: "1" "372": :country_code: "372" :national_dialing_prefix: None :char_2_code: None :char_3_code: EE :name: Estonia :international_dialing_prefix: "0" "61": :country_code: "61" :national_dialing_prefix: "0" :char_2_code: "0" :char_3_code: AU :name: Australia :international_dialing_prefix: "11" :area_code: "[234578]" "880": :country_code: "880" :national_dialing_prefix: "0" :char_2_code: "0" :char_3_code: BD :name: Bangladesh :international_dialing_prefix: "0" "967": :country_code: "967" :national_dialing_prefix: "0" :char_2_code: "0" :char_3_code: YE :name: Yemen :international_dialing_prefix: "0" "90": :country_code: "90" :national_dialing_prefix: "0" :char_2_code: "0" :char_3_code: TR :name: Turkey :international_dialing_prefix: "0" "373": :country_code: "373" :national_dialing_prefix: "0" :char_2_code: "0" :char_3_code: MD :name: Moldova, Republic of :international_dialing_prefix: "0" "33": :country_code: "33" :national_dialing_prefix: "0" :char_2_code: "0" :char_3_code: FR :name: France :international_dialing_prefix: "0" :area_code: "[1-9]" "995": :country_code: "995" :national_dialing_prefix: 8* :char_2_code: 8* :char_3_code: GE :name: Georgia :international_dialing_prefix: "810" "853": :country_code: "853" :national_dialing_prefix: "0" :char_2_code: "0" :char_3_code: MO :name: Macao :international_dialing_prefix: "0" "231": :country_code: "231" :national_dialing_prefix: "22" :char_2_code: "22" :char_3_code: LR :name: Liberia :international_dialing_prefix: "0" "62": :country_code: "62" :national_dialing_prefix: "0" :char_2_code: "0" :char_3_code: ID :name: Indonesia :international_dialing_prefix: "1" "260": :country_code: "260" :national_dialing_prefix: "0" :char_2_code: "0" :char_3_code: ZM :name: Zambia :international_dialing_prefix: "0" "34": :country_code: "34" :national_dialing_prefix: None :char_2_code: None :char_3_code: ES :name: Spain :international_dialing_prefix: "0" :area_code: "6[0-9][0-9]|7[1-9][0-9]|8[0-9][0-9]|9[0-9][0-9]" "232": :country_code: "232" :national_dialing_prefix: "0" :char_2_code: "0" :char_3_code: SL :name: Sierra Leone :international_dialing_prefix: "0" "685": :country_code: "685" :national_dialing_prefix: None :char_2_code: None :char_3_code: WS :name: Samoa :international_dialing_prefix: "0" "63": :country_code: "63" :national_dialing_prefix: "0" :char_2_code: "0" :char_3_code: PH :name: Philippines :international_dialing_prefix: "0" "968": :country_code: "968" :national_dialing_prefix: None :char_2_code: None :char_3_code: OM :name: Oman :international_dialing_prefix: "0" "996": :country_code: "996" :national_dialing_prefix: "0" :char_2_code: "0" :char_3_code: KG :name: Kyrgyzstan :international_dialing_prefix: "0" "374": :country_code: "374" :national_dialing_prefix: "8" :char_2_code: "8" :char_3_code: AM :name: Armenia :international_dialing_prefix: "0" "91": :country_code: "91" :national_dialing_prefix: "0" :char_2_code: "0" :char_3_code: IN :name: India :international_dialing_prefix: "0" "92": :country_code: "92" :national_dialing_prefix: "0" :char_2_code: "0" :char_3_code: PK :name: Pakistan :international_dialing_prefix: "0" "64": :country_code: "64" :national_dialing_prefix: 0 (None fo :char_2_code: 0 (None fo :char_3_code: NZ :name: New Zealand :international_dialing_prefix: "0" :area_code: "[1-9]" "855": :country_code: "855" :national_dialing_prefix: "0" :char_2_code: "0" :char_3_code: KH :name: Cambodia :international_dialing_prefix: "0" "261": :country_code: "261" :national_dialing_prefix: None :char_2_code: None :char_3_code: MG :name: Madagascar :international_dialing_prefix: "0" "1": :country_code: "1" :national_dialing_prefix: "1" :char_2_code: "1" :char_3_code: US :name: United States :international_dialing_prefix: "11" "375": :country_code: "375" :national_dialing_prefix: "8" :char_2_code: "8" :char_3_code: BY :name: Belarus :international_dialing_prefix: "810" "233": :country_code: "233" :national_dialing_prefix: None :char_2_code: None :char_3_code: GH :name: Ghana :international_dialing_prefix: "0" "686": :country_code: "686" :national_dialing_prefix: None :char_2_code: None :char_3_code: KI :name: Kiribati :international_dialing_prefix: "0" "998": :country_code: "998" :national_dialing_prefix: "8" :char_2_code: "8" :char_3_code: UZ :name: Uzbekistan :international_dialing_prefix: "810" "65": :country_code: "65" :national_dialing_prefix: None :char_2_code: None :char_3_code: SG :name: Singapore :international_dialing_prefix: "1" "290": :country_code: "290" :national_dialing_prefix: None :char_2_code: None :char_3_code: SH :name: Saint Helena :international_dialing_prefix: "0" "262": :country_code: "262" :national_dialing_prefix: None :char_2_code: None :char_3_code: RE :name: "R\xC3\xA9union" :international_dialing_prefix: "0" "234": :country_code: "234" :national_dialing_prefix: "0" :char_2_code: "0" :char_3_code: NG :name: Nigeria :international_dialing_prefix: "9" "687": :country_code: "687" :national_dialing_prefix: None :char_2_code: None :char_3_code: NC :name: New Caledonia :international_dialing_prefix: "0" "856": :country_code: "856" :national_dialing_prefix: "0" :char_2_code: "0" :char_3_code: LA :name: Lao People's Democratic Republic :international_dialing_prefix: "0" "93": :country_code: "93" :national_dialing_prefix: "0" :char_2_code: "0" :char_3_code: AF :name: Afghanistan :international_dialing_prefix: "0" "376": :country_code: "376" :national_dialing_prefix: None :char_2_code: None :char_3_code: AD :name: Andorra :international_dialing_prefix: "0" "36": :country_code: "36" :national_dialing_prefix: "6" :char_2_code: "6" :char_3_code: HU :name: Hungary :international_dialing_prefix: "0" :area_code: "1|[2-9]\\d" "263": :country_code: "263" :national_dialing_prefix: "0" :char_2_code: "0" :char_3_code: ZW :name: Zimbabwe :international_dialing_prefix: "0" "688": :country_code: "688" :national_dialing_prefix: None :char_2_code: None :char_3_code: TV :name: Tuvalu :international_dialing_prefix: "0" "94": :country_code: "94" :national_dialing_prefix: "0" :char_2_code: "0" :char_3_code: LK :name: Sri Lanka :international_dialing_prefix: "0" "377": :country_code: "377" :national_dialing_prefix: "0" :char_2_code: "0" :char_3_code: MC :name: Monaco :international_dialing_prefix: "0" "235": :country_code: "235" :national_dialing_prefix: None :char_2_code: None :char_3_code: TD :name: Chad :international_dialing_prefix: "15" "291": :country_code: "291" :national_dialing_prefix: "0" :char_2_code: "0" :char_3_code: ER :name: Eritrea :international_dialing_prefix: "0" "66": :country_code: "66" :national_dialing_prefix: "0" :char_2_code: "0" :char_3_code: TH :name: Thailand :international_dialing_prefix: "1" "886": :country_code: "886" :national_dialing_prefix: None :char_2_code: None :char_3_code: TW :name: Taiwan, Province Of China :international_dialing_prefix: "2" "378": :country_code: "378" :national_dialing_prefix: None :char_2_code: None :char_3_code: SM :name: San Marino :international_dialing_prefix: "0" "264": :country_code: "264" :national_dialing_prefix: "0" :char_2_code: "0" :char_3_code: NA :name: Namibia :international_dialing_prefix: "0" "95": :country_code: "95" :national_dialing_prefix: None :char_2_code: None :char_3_code: MM :name: Myanmar :international_dialing_prefix: "0" "236": :country_code: "236" :national_dialing_prefix: None :char_2_code: None :char_3_code: CF :name: Central African Republic :international_dialing_prefix: "0" "689": :country_code: "689" :national_dialing_prefix: None :char_2_code: None :char_3_code: PF :name: French Polynesia :international_dialing_prefix: "0" "970": :country_code: "970" :national_dialing_prefix: "0" :char_2_code: "0" :char_3_code: PS :name: Palestinian Territory, Occupied :international_dialing_prefix: "0" "237": :country_code: "237" :national_dialing_prefix: None :char_2_code: None :char_3_code: CM :name: Cameroon :international_dialing_prefix: "0" "39": :country_code: "39" :national_dialing_prefix: None :char_2_code: None :char_3_code: IT :name: Italy :international_dialing_prefix: "0" "265": :country_code: "265" :national_dialing_prefix: None :char_2_code: None :char_3_code: MW :name: Malawi :international_dialing_prefix: "0" "971": :country_code: "971" :national_dialing_prefix: "0" :char_2_code: "0" :char_3_code: AE :name: United Arab Emirates :international_dialing_prefix: "0" "238": :country_code: "238" :national_dialing_prefix: None :char_2_code: None :char_3_code: CV :name: Cape Verde :international_dialing_prefix: "0" "266": :country_code: "266" :national_dialing_prefix: None :char_2_code: None :char_3_code: LS :name: Lesotho :international_dialing_prefix: "0" "239": :country_code: "239" :national_dialing_prefix: "0" :char_2_code: "0" :char_3_code: ST :name: Sao Tome and Principe :international_dialing_prefix: "0" "7": :country_code: "7" :national_dialing_prefix: "8" :char_2_code: "8" :char_3_code: RU :name: Russian Federation :international_dialing_prefix: "810" "98": :country_code: "98" :national_dialing_prefix: "0" :char_2_code: "0" :char_3_code: IR :name: Iran, Islamic Republic Of :international_dialing_prefix: "0" "972": :country_code: "972" :national_dialing_prefix: "0" :char_2_code: "0" :char_3_code: IL :name: Israel :international_dialing_prefix: "0" "350": :country_code: "350" :national_dialing_prefix: None :char_2_code: None :char_3_code: GI :name: Gibraltar :international_dialing_prefix: "0" "267": :country_code: "267" :national_dialing_prefix: None :char_2_code: None :char_3_code: BW :name: Botswana :international_dialing_prefix: "0" "690": :country_code: "690" :national_dialing_prefix: None :char_2_code: None :char_3_code: TK :name: Tokelau :international_dialing_prefix: "0" "268": :country_code: "268" :national_dialing_prefix: None :char_2_code: None :char_3_code: SZ :name: Swaziland :international_dialing_prefix: "0" "40": :country_code: "40" :national_dialing_prefix: "0" :char_2_code: "0" :char_3_code: RO :name: Romania :international_dialing_prefix: "0" "351": :country_code: "351" :national_dialing_prefix: None :char_2_code: None :char_3_code: PT :name: Portugal :international_dialing_prefix: "0" :area_code: "2[12]|2[3-9][1-9]|70[78]|80[089]|9[136]|92[1-9]" "973": :country_code: "973" :national_dialing_prefix: None :char_2_code: None :char_3_code: BH :name: Bahrain :international_dialing_prefix: "0" "380": :country_code: "380" :national_dialing_prefix: "0" :char_2_code: "0" :char_3_code: UA :name: Ukraine :international_dialing_prefix: "00" :area_code: "[1-9]\\d" "41": :country_code: "41" :national_dialing_prefix: "0" :char_2_code: "0" :char_3_code: CH :name: Switzerland :international_dialing_prefix: "0" "974": :country_code: "974" :national_dialing_prefix: None :char_2_code: None :char_3_code: QA :name: Qatar :international_dialing_prefix: "0" "691": :country_code: "691" :national_dialing_prefix: "1" :char_2_code: "1" :char_3_code: FM :name: Micronesia, Federated States Of :international_dialing_prefix: "11" "297": :country_code: "297" :national_dialing_prefix: None :char_2_code: None :char_3_code: AW :name: Aruba :international_dialing_prefix: "0" "352": :country_code: "352" :national_dialing_prefix: None :char_2_code: None :char_3_code: LU :name: Luxembourg :international_dialing_prefix: "0" "269": :country_code: "269" :national_dialing_prefix: None :char_2_code: None :char_3_code: YT :name: Mayotte :international_dialing_prefix: "0" "381": :country_code: "381" :national_dialing_prefix: "0" :char_2_code: "0" :char_3_code: RS :name: Serbia :international_dialing_prefix: "99" :area_code: "[1-9]\\d" "975": :country_code: "975" :national_dialing_prefix: None :char_2_code: None :char_3_code: BT :name: Bhutan :international_dialing_prefix: "0" "298": :country_code: "298" :national_dialing_prefix: None :char_2_code: None :char_3_code: FO :name: Faroe Islands :international_dialing_prefix: "0" "353": :country_code: "353" :national_dialing_prefix: "0" :char_2_code: "0" :char_3_code: IE :name: Ireland :international_dialing_prefix: "0" :area_code: "1|[2,4-7,9][0-9]|8[0,3-9]|822|818" "692": :country_code: "692" :national_dialing_prefix: "1" :char_2_code: "1" :char_3_code: MH :name: Marshall Islands :international_dialing_prefix: "0" "212": :country_code: "212" :national_dialing_prefix: "0" :char_2_code: "0" :char_3_code: MA :name: Morocco :international_dialing_prefix: "0" "382": :country_code: "382" :national_dialing_prefix: "0" :char_2_code: "0" :char_3_code: ME :name: Montenegro :international_dialing_prefix: "99" :area_code: "[2-6][0-9]" "976": :country_code: "976" :national_dialing_prefix: "0" :char_2_code: "0" :char_3_code: MN :name: Mongolia :international_dialing_prefix: "1" "240": :country_code: "240" :national_dialing_prefix: None :char_2_code: None :char_3_code: GQ :name: Equatorial Guinea :international_dialing_prefix: "0" "299": :country_code: "299" :national_dialing_prefix: None :char_2_code: None :char_3_code: GL :name: Greenland :international_dialing_prefix: "9" "354": :country_code: "354" :national_dialing_prefix: "0" :char_2_code: "0" :char_3_code: IS :name: Iceland :international_dialing_prefix: "0" "43": :country_code: "43" :national_dialing_prefix: "0" :char_2_code: "0" :char_3_code: AT :name: Austria :international_dialing_prefix: "0" "977": :country_code: "977" :national_dialing_prefix: "0" :char_2_code: "0" :char_3_code: NP :name: Nepal :international_dialing_prefix: "0" "241": :country_code: "241" :national_dialing_prefix: None :char_2_code: None :char_3_code: GA :name: Gabon :international_dialing_prefix: "0" "355": :country_code: "355" :national_dialing_prefix: "0" :char_2_code: "0" :char_3_code: AL :name: Albania :international_dialing_prefix: "0" "213": :country_code: "213" :national_dialing_prefix: "7" :char_2_code: "7" :char_3_code: DZ :name: Algeria :international_dialing_prefix: "0" "44": :country_code: "44" :national_dialing_prefix: "0" :char_2_code: "0" :char_3_code: GB :name: United Kingdom :international_dialing_prefix: "0" :area_code: "2[03489]|11[3-8]|1[2-69]1|1[2-9][0-9]{2}|70|7[0-9]{3}|[8|9][0-9]{2}|3[0-9]{2}" "242": :country_code: "242" :national_dialing_prefix: None :char_2_code: None :char_3_code: CG :name: Congo :international_dialing_prefix: "0" "356": :country_code: "356" :national_dialing_prefix: "21" :char_2_code: "21" :char_3_code: MT :name: Malta :international_dialing_prefix: "0" "357": :country_code: "357" :national_dialing_prefix: None :char_2_code: None :char_3_code: CY :name: Cyprus :international_dialing_prefix: "0" "45": :country_code: "45" :national_dialing_prefix: None :char_2_code: None :char_3_code: DK :name: Denmark :international_dialing_prefix: "0" "385": :country_code: "385" :national_dialing_prefix: "0" :char_2_code: "0" :char_3_code: HR :name: Croatia :international_dialing_prefix: "0" :area_code: "1|[2-9]\\d" "243": :country_code: "243" :national_dialing_prefix: None :char_2_code: None :char_3_code: CD :name: Congo, The Democratic Republic Of The :international_dialing_prefix: "0" "216": :country_code: "216" :national_dialing_prefix: None :char_2_code: None :char_3_code: TN :name: Tunisia :international_dialing_prefix: "0" "46": :country_code: "46" :national_dialing_prefix: "0" :char_2_code: "0" :char_3_code: SE :name: Sweden :international_dialing_prefix: "0" :area_code: "900|1[013689]|2[0136]|3[1356]|4[0246]|54|6[03]|7[01236]|8|9[09]|1[2457]\\d|2[2457-9]\\d|3[0247-9]\\d|4[1357-9]\\d|5[0-35-9]\\d|6[124-9]\\d|74\\d|9[1-8]\\d" "386": :country_code: "386" :national_dialing_prefix: "0" :char_2_code: "0" :char_3_code: SI :name: Slovenia :international_dialing_prefix: "0" :area_code: "3[01]|4[01]|51|7[01]|64|59|1|2|3|4|5|6|7" "358": :country_code: "358" :national_dialing_prefix: "0" :char_2_code: "0" :char_3_code: FI :name: Finland :international_dialing_prefix: "0" "244": :country_code: "244" :national_dialing_prefix: "0" :char_2_code: "0" :char_3_code: AO :name: Angola :international_dialing_prefix: "0" "47": :country_code: "47" :national_dialing_prefix: None :char_2_code: None :char_3_code: "NO" :name: Norway :international_dialing_prefix: "0" "359": :country_code: "359" :national_dialing_prefix: "0" :char_2_code: "0" :char_3_code: BG :name: Bulgaria :international_dialing_prefix: "0" "387": :country_code: "387" :national_dialing_prefix: "0" :char_2_code: "0" :char_3_code: BA :name: Bosnia and Herzegovina :international_dialing_prefix: "0" :area_code: "6|[0-57-9]\\d" "245": :country_code: "245" :national_dialing_prefix: None :char_2_code: None :char_3_code: GW :name: Guinea-Bissau :international_dialing_prefix: "0" "48": :country_code: "48" :national_dialing_prefix: "0" :char_2_code: "0" :char_3_code: PL :name: Poland :international_dialing_prefix: "0" "218": :country_code: "218" :national_dialing_prefix: "0" :char_2_code: "0" :char_3_code: LY :name: Libyan Arab Jamahiriya :international_dialing_prefix: "0" "49": :country_code: "49" :national_dialing_prefix: "0" :char_2_code: "0" :char_3_code: DE :name: Germany :international_dialing_prefix: "0" :area_code: "[0-9]{3}" "389": :country_code: "389" :national_dialing_prefix: "0" :char_2_code: "0" :char_3_code: MK :name: Macedonia, the Former Yugoslav Republic Of :international_dialing_prefix: "0" "670": :country_code: "670" :national_dialing_prefix: None :char_2_code: None :char_3_code: TL :name: Timor-Leste :international_dialing_prefix: None "248": :country_code: "248" :national_dialing_prefix: None :char_2_code: None :char_3_code: SC :name: Seychelles :international_dialing_prefix: "0" "20": :country_code: "20" :national_dialing_prefix: "0" :char_2_code: "0" :char_3_code: EG :name: Egypt :international_dialing_prefix: "0" "500": :country_code: "500" :national_dialing_prefix: None :char_2_code: None :char_3_code: FK :name: Falkland Islands (Malvinas) :international_dialing_prefix: "0" "249": :country_code: "249" :national_dialing_prefix: "0" :char_2_code: "0" :char_3_code: SD :name: Sudan :international_dialing_prefix: "0" "501": :country_code: "501" :national_dialing_prefix: "0" :char_2_code: "0" :char_3_code: BZ :name: Belize :international_dialing_prefix: "0" "672": :country_code: "672" :national_dialing_prefix: None :char_2_code: None :char_3_code: NF :name: Norfolk Island :international_dialing_prefix: "0" "502": :country_code: "502" :national_dialing_prefix: None :char_2_code: None :char_3_code: GT :name: Guatemala :international_dialing_prefix: "0" "51": :country_code: "51" :national_dialing_prefix: "0" :char_2_code: "0" :char_3_code: PE :name: Peru :international_dialing_prefix: "0" "220": :country_code: "220" :national_dialing_prefix: None :char_2_code: None :char_3_code: GM :name: Gambia :international_dialing_prefix: "0" "673": :country_code: "673" :national_dialing_prefix: "0" :char_2_code: "0" :char_3_code: BN :name: Brunei Darussalam :international_dialing_prefix: "0" "503": :country_code: "503" :national_dialing_prefix: None :char_2_code: None :char_3_code: SV :name: El Salvador :international_dialing_prefix: "0" "221": :country_code: "221" :national_dialing_prefix: None :char_2_code: None :char_3_code: SN :name: Senegal :international_dialing_prefix: "0" "674": :country_code: "674" :national_dialing_prefix: "0" :char_2_code: "0" :char_3_code: NR :name: Nauru :international_dialing_prefix: "0" "52": :country_code: "52" :national_dialing_prefix: "1" :char_2_code: "1" :char_3_code: MX :name: Mexico :international_dialing_prefix: "0" "504": :country_code: "504" :national_dialing_prefix: None :char_2_code: None :char_3_code: HN :name: Honduras :international_dialing_prefix: "0" "250": :country_code: "250" :national_dialing_prefix: "0" :char_2_code: "0" :char_3_code: RW :name: Rwanda :international_dialing_prefix: "0" "872": :country_code: "872" :national_dialing_prefix: "0" :char_2_code: "0" :char_3_code: PN :name: Pitcairn :international_dialing_prefix: "0" "675": :country_code: "675" :national_dialing_prefix: None :char_2_code: None :char_3_code: PG :name: Papua New Guinea :international_dialing_prefix: "5" "505": :country_code: "505" :national_dialing_prefix: None :char_2_code: None :char_3_code: NI :name: Nicaragua :international_dialing_prefix: "0" "222": :country_code: "222" :national_dialing_prefix: "0" :char_2_code: "0" :char_3_code: MR :name: Mauritania :international_dialing_prefix: "0" "53": :country_code: "53" :national_dialing_prefix: "0" :char_2_code: "0" :char_3_code: CU :name: Cuba :international_dialing_prefix: "119" "81": :country_code: "81" :national_dialing_prefix: "0" :char_2_code: "0" :char_3_code: JP :name: Japan :international_dialing_prefix: "10" ================================================ FILE: lib/phone/country.rb ================================================ require "yaml" module Phoner class Country < Struct.new(:name, :country_code, :char_2_code, :char_3_code, :area_code, :max_num_length) module All attr_accessor :all end extend All def all self.class.all end def self.load return self.all if !self.all.nil? && !self.all.empty? data_file = File.join("..","..","data", "phone", "countries.yml") data_path = File.expand_path(data_file, File.dirname(__FILE__)) self.all = {} YAML.load(File.read(data_path)).each_pair do |key, c| self.all[key] = Country.new( c[:name], c[:country_code], c[:char_2_code], c[:char_3_code], c.fetch(:area_code, "[0-9][0-9][0-9]").freeze, c.fetch(:max_num_length, 8) ) end self.all end def self.find_by_country_code(code) self.all[code] end def self.find_by_country_isocode(isocode) if country = self.all.detect{|c|c[1].char_3_code.downcase == isocode} country[1] end end def to_s name end def country_code_regexp @country_code_regexp ||= Regexp.new("^[+]#{country_code}") end end end ================================================ FILE: lib/phone/errors.rb ================================================ module Phoner class PhoneError < RuntimeError;end class BlankNumberError < PhoneError;end class AreaCodeError < PhoneError;end class CountryCodeError < PhoneError;end end ================================================ FILE: lib/phone/version.rb ================================================ module Phone # phone version VERSION = "1.3.0.beta1" end ================================================ FILE: lib/phone.rb ================================================ # An object representing a phone number. # # The phone number is recorded in 3 separate parts: # * country_code - e.g. "385", "386" # * area_code - e.g. "91", "47" # * number - e.g. "5125486", "451588" # # All parts are mandatory, but country code and area code can be set for all phone numbers using # Phone.default_country_code # Phone.default_area_code # require "phone/country" require "phone/errors" module Phoner class Phone module ClassAttributes attr_accessor :default_country_code attr_accessor :default_area_code attr_accessor :named_formats attr_accessor :n1_length end extend ClassAttributes module ClassAttributeAccessors def default_country_code self.class.default_country_code end def default_area_code self.class.default_area_code end def named_formats self.class.named_formats end def n1_length self.class.n1_length end end include ClassAttributeAccessors self.named_formats = { :default => "+%c%a%n", :default_with_extension => "+%c%a%nx%x", :europe => "+%c (0) %a %f %l", :us => "(%a) %f-%l" } # length of first number part (using multi number format) # default length of first number part self.n1_length = 3 # common extension patterns COMMON_EXTENSIONS = /[ ]*(ext|ex|x|xt|#|:)+[^0-9]*\(*([-0-9]{1,})\)*#?$/i # common extra characters and sequences we normalize out COMMON_EXTRAS = /(\(0\)|[^0-9+]|^\+?00?)/ # replacements for extra characters COMMON_EXTRAS_REPLACEMENTS = { "00" => "+", "+00" => "+", "+0" => "+" } # default replacement COMMON_EXTRAS_REPLACEMENTS.default = "" # tokens used in the formatting string: %c, %a, %A, etc FORMAT_TOKENS = /(%[caAnflx])/ # is this string a valid phone number? def self.valid?(string, options = {}) begin !parse(string, options).nil? # if we encountered exceptions (missing country code, missing area code etc) rescue PhoneError return false end end # create a new phone number by parsing a string # the format of the string is detect automatically (from FORMATS) def self.parse(string, options={}) return if string.to_s.empty? Country.load string, extension = extract_extension(string) string = normalize(string) options[:country_code] ||= self.default_country_code options[:area_code] ||= self.default_area_code parts = split_to_parts(string, options) pn = Phone.new(parts.merge(:extension => extension)) if parts return pn end # Returns an array of the number with the extension removed, and the extension. # # Example: # # number, ext = Phoner::Phone.extract_extension("+1 (123) 456-7890 x321") # # [] def self.extract_extension(string) return [nil, nil] if string.nil? if subbed = string.sub(COMMON_EXTENSIONS, "") [subbed, $2] else [string, nil] end end # fix string so it's easier to parse, remove extra characters etc. def self.normalize(string_with_number) # TODO: When we drop 1.8.7 we can pass the hash in as an arg to #gsub string_with_number.gsub(COMMON_EXTRAS) do |match| COMMON_EXTRAS_REPLACEMENTS[match.to_s] end end # split string into hash with keys :country_code, :area_code and :number def self.split_to_parts(string, options = {}) country = detect_country(string) if country options[:country_code] = country.country_code string = string.gsub(country.country_code_regexp, "0") else if options[:country_code] country = Country.find_by_country_code options[:country_code] end end if country.nil? if options[:country_code].nil? raise CountryCodeError, "Must enter country code or set default country code" else raise CountryCodeError, "Could not find country with country code #{options[:country_code]}" end end format = detect_format(string, country) return nil if format.nil? # Override the format IF overriding options are not present format = :short if options[:area_code].nil? parts = string.match formats(country)[format] return nil if parts.nil? case format when :short { :number => parts[2], :area_code => parts[1], :country_code => options[:country_code] } when :really_short { :number => parts[1], :area_code => options[:area_code], :country_code => options[:country_code] } end end # detect country from the string entered def self.detect_country(string) detected_country = nil # find if the number has a country code Country.all.each_pair do |country_code, country| if string =~ country.country_code_regexp detected_country = country end end detected_country end # detect format (from FORMATS) of input string def self.detect_format(string_with_number, country) arr = [] formats(country).each_pair do |format, regexp| arr << format if string_with_number =~ regexp end # raise "Detected more than 1 format for #{string_with_number}" if arr.size > 1 if arr.length > 1 # puts %Q{detect_format: more than one format found - #{arr.inspect}} return :really_short end arr.first end def self.formats(country) area_code_regexp = country.area_code number_regex = "([0-9]{1,#{country.max_num_length}})$".freeze { # 047451588, 013668734 :short => Regexp.new("^0?(#{area_code_regexp})#{number_regex}"), # 451588 :really_short => Regexp.new("^#{number_regex}") } end attr_accessor :country_code, :area_code, :number, :extension # Initialize a new instance with a list or hash of phone number parts # # Example: # Phone.new("5125486", "91", "385") # # # or # # Phone.new( # :number => "5125486", # :area_code => "91", # :country_code => "385", # :extension => "143" # ) def initialize(*args) input = args.first.is_a?(Hash) ? args.first : args_to_hash(args) # set defaults input[:area_code] ||= self.default_area_code input[:country_code] ||= self.default_country_code @number = input[:number].to_s.strip raise BlankNumberError, "Must enter number" if @number.empty? @area_code = input[:area_code].to_s.strip raise AreaCodeError, "Must enter area code or set default" if @area_code.empty? @country_code = input[:country_code].to_s.strip raise CountryCodeError, "Must enter country code or set default" if @country_code.empty? @extension = input[:extension] end # format area_code with trailing zero (e.g. 91 as 091) # format area_code with trailing zero (e.g. 91 as 091) def area_code_long "0#{area_code}" if area_code end # first n characters of :number def number1 number[0...self.class.n1_length] end # everything left from number after the first n characters (see number1) def number2 n2_length = number.size - self.class.n1_length number[-n2_length, n2_length] end # Formats the phone number. # # if the method argument is a String, it is used as a format string, with the following fields being interpolated: # # * %c - country_code (385) # * %a - area_code (91) # * %A - area_code with leading zero (091) # * %n - number (5125486) # * %f - first @@n1_length characters of number (configured through Phone.n1_length), default is 3 (512) # * %l - last characters of number (5486) # * %x - entire extension # # if the method argument is a Symbol, it is used as a lookup key for a format String in Phone.named_formats # pn.format(:europe) def format(fmt) if fmt.is_a?(Symbol) raise "The format #{fmt} doesn't exist" unless named_formats.has_key?(fmt) format_number named_formats[fmt] else format_number(fmt) end end # the default format is "+%c%a%n" def to_s format(:default) end # does this number belong to the default country code? def has_default_country_code? country_code == self.class.default_country_code end # does this number belong to the default area code? def has_default_area_code? area_code == self.class.default_area_code end # comparison of 2 phone objects def ==(other) methods = [:country_code, :area_code, :number, :extension] methods.all? { |method| other.respond_to?(method) && send(method) == other.send(method) } end private # Convert initialize arguments into parameter hash # # Example: # # args_to_hash ["5125486", "91", "385"] # #=> { :number => "5125486", # :area_code => "91", # :country_code => "385", # :extension => nil } def args_to_hash(args) { :number => args[0], :area_code => args[1], :country_code => args[2], :extension => args[3] } end def format_number(fmt) replacements = { "%c" => (country_code || ""), "%a" => (area_code || ""), "%A" => (area_code_long || ""), "%n" => (number || ""), "%f" => (number1 || ""), "%l" => (number2 || ""), "%x" => (extension || "") } # TODO: When we drop 1.8.7 we can pass the hash in as an arg to #gsub fmt.gsub(FORMAT_TOKENS) do |match| replacements[match.to_s] end end end end ================================================ FILE: phone.gemspec ================================================ # -*- encoding: utf-8 -*- require File.expand_path("../lib/phone/version", __FILE__) Gem::Specification.new do |gem| gem.name = "phone" gem.version = Phone::VERSION gem.summary = %q{Phone number parsing, validation and formatting} gem.description = %q{Phone number parsing, validation and formatting in Ruby} gem.license = "MIT" gem.authors = ["Tomislav Carr", "Todd Eichel", "Don Morrison"] gem.email = ["tomislav@infinum.hr", "todd@toddeichel.com", "don@elskwid.net"] gem.homepage = "https://github.com/carr/phone#readme" gem.files = `git ls-files`.split($/) gem.test_files = gem.files.grep(%r{^(test|spec|features)/}) gem.require_paths = ["lib"] gem.add_development_dependency "bundler", ">= 1.2" gem.add_development_dependency "minitest", "~> 5.0" gem.add_development_dependency "rake", "~> 10.0" gem.add_development_dependency "rubygems-tasks", "~> 0.2" gem.add_development_dependency "yard", "~> 0.8" end ================================================ FILE: test/countries/au_test.rb ================================================ require "helper" # 0x 5551 reserved for fictitious use. (not including x=3) # 0x 7010 reserved for fictitious use. ## Australia class AUTest < Minitest::Test # 00 Emergency and International access # 01 Alternate phone services # 014 Satellite phone services # 016 Paging [+3D or +6D] # 018 Analogue (AMPS) mobile phone - few numbers still in use [+6D] # 0198 Data networks [+2D or +6D] - e.g. 0198 379 000 is the Dial-Up POP number for iiNet # 02 Central East region (NSW, ACT) def test_central_east parse_test('+61 2 5551 1234', '61', '2', '55511234') end # 03 South-east region (VIC, TAS) def test_south_east parse_test('+61 3 5551 1234', '61', '3', '55511234') end # 04 Mobile services (Digital - GSM, CDMA, 3G) def test_mobile parse_test('+61 4 5551 1234', '61', '4', '55511234') end # 05 Universal/Personal numberings (uncommon) def test_personal parse_test('+61 5 5551 1234', '61', '5', '55511234') end # 07 North-east region (QLD) def test_north_east parse_test('+61 7 5551 1234', '61', '7', '55511234') end # 08 Central and West region (SA, NT, WA) def test_central parse_test('+61 8 5551 1234', '61', '8', '55511234') end # (Geographical region boundaries do not exactly follow state borders.) # 1 Non-geographic numbers end ================================================ FILE: test/countries/ba_test.rb ================================================ require "helper" ## Bosnia and Herzegovina class BATest < Minitest::Test def test_local parse_test('+387 33 25 02 33', '387', '33', '250233') end end ================================================ FILE: test/countries/be_test.rb ================================================ # -*- coding: utf-8 -*- require "helper" ## Belgium class BETest < Minitest::Test ## single digit # 02: Brussels (Bruxelles/Brussel) def test_brussels parse_test('+32 2 1234567', '32', '2', '1234567') end # 03: Antwerpen (Antwerp), Sint-Niklaas def test_antwerpen parse_test('+32 3 1234567', '32', '3', '1234567') end # 04: Liège (Luik), Voeren (Fourons) def test_liege parse_test('+32 4 1234567', '32', '4', '1234567') end # 09: Gent (Ghent/Gand) def test_gent parse_test('+32 9 1234567', '32', '9', '1234567') end ## two digit # 010: Wavre (Waver) def test_wavre parse_test('+32 10 123456', '32', '10', '123456') end # 011: Hasselt def test_hasselt parse_test('+32 11 123456', '32', '11', '123456') end # 012: Tongeren (Tongres) def test_tongeren parse_test('+32 12 123456', '32', '12', '123456') end # 013: Diest def test_diest parse_test('+32 13 123456', '32', '13', '123456') end # 014: Herentals, Turnhout # 015: Mechelen (Malines) # 016: Leuven (Louvain), Tienen (Tirlemont) # 019: Waremme (Borgworm) def test_waremme parse_test('+32 19 123456', '32', '19', '123456') end # 050: Brugge (Bruges), Zeebrugge def test_brugge parse_test('+32 50 123456', '32', '50', '123456') end # 051: Roeselare (Roulers) def test_roeselare parse_test('+32 51 123456', '32', '51', '123456') end # 052: Dendermonde (Termonde) # 053: Aalst (Alost) # 054: Ninove # 055: Ronse (Renaix) # 056: Kortrijk (Courtrai), Comines-Warneton, Mouscron (Moeskroen) # 057: Ieper (Ypres) # 058: Veurne (Furnes) # 059: Oostende (Ostend) def test_oostende parse_test('+32 59 123456', '32', '59', '123456') end # 060: Chimay def test_chimay parse_test('+32 60 123456', '32', '60', '123456') end # 061: Bastogne, Libramont-Chevigny # 063: Arlon (Aarlen) # 064: La Louviere # 065: Mons (Bergen) # 067: Nivelles (Nijvel) def test_nivelles parse_test('+32 67 123456', '32', '67', '123456') end # 068: Ath (Aat) # 069: Tournai (Doornik) # 070: Specialty Numbers (i.e. bus information or bank information) def test_specialty parse_test('+32 70 123456', '32', '70', '123456') end # 071: Charleroi # 081: Namur (Namen) def test_namur parse_test('+32 81 123456', '32', '81', '123456') end # 082: Dinant # 083: Ciney # 084: Jemelle, Marche-en-Famenne # 085: Huy # 086: Durbuy # 087: Verviers # 089: Genk # 0800: toll free service def test_toll_free parse_test('+32 800 12345', '32', '800', '12345') end # 090x: Premium numbers (0900, 0901, 0902, 0903, 0904, 0905, 0906, 0907, 0908, 0909) def test_premium_900 parse_test('+32 900 12345', '32', '900', '12345') end def test_premium_901 parse_test('+32 901 12345', '32', '901', '12345') end end ================================================ FILE: test/countries/de_test.rb ================================================ require "helper" ## Germany class DETest < Minitest::Test def test_local parse_test('+49 714 1605832', '49', '714', '1605832') end def test_mobile parse_test('+49 162 3499558', '49', '162', '3499558') end # TODO: germany has 2-5 length area codes, that's why this test doesn't go through #def test_country_side # parse_test('+49 (0)6120 59511-23', '49', '6120', '5951123') #end end ================================================ FILE: test/countries/es_test.rb ================================================ require "helper" ## Spain # http://en.wikipedia.org/wiki/Telephone_numbers_in_Spain # http://gospain.about.com/od/practicaltraveltips/f/area_codes.htm # A problem is that landline area codes can be 2 (92) as well as 3 digits (923) # right now the area_code_regexp is only finding 3 digit area_codes class ESTest < Minitest::Test def test_validates Phoner::Phone.default_country_code = nil assert_equal Phoner::Phone.valid?("+34-695-097-612"), true assert_equal Phoner::Phone.valid?("0034 91-3597426"), true assert_equal Phoner::Phone.valid?("+0034 91-3597426"), true assert_equal Phoner::Phone.valid?("+34 92-6563629"), true assert_equal Phoner::Phone.valid?("(+34) 606 275 213"), true assert_equal Phoner::Phone.valid?("+034 937 299 016"), true assert_equal Phoner::Phone.valid?("+34 93 487 32 93"), true Phoner::Phone.default_country_code = '34' assert_equal Phoner::Phone.valid?(" 607 65 05 01 "), true assert_equal Phoner::Phone.valid?(" 971 15 66 33"), true assert_equal Phoner::Phone.valid?(" 93-4559934"), true assert_equal Phoner::Phone.valid?("628 274 908"), true assert_equal Phoner::Phone.valid?("744 486 62 78"), true assert_equal Phoner::Phone.valid?("916754559"), true assert_equal Phoner::Phone.valid?("93.4327119"), true assert_equal Phoner::Phone.valid?("986300257"), true end end ================================================ FILE: test/countries/fr_test.rb ================================================ require "helper" ## France class FRTest < Minitest::Test def test_local parse_test('+33 4 75 06 07 07', '33', '4', '75060707') end def test_mobile parse_test('+33 6 11 22 33 44', '33', '6', '11223344') end def test_mobile_07 parse_test('+33 7 11 22 33 44', '33', '7', '11223344') end def test_voip parse_test('+33 9 11 22 33 44', '33', '9', '11223344') end end ================================================ FILE: test/countries/gb_test.rb ================================================ # -*- coding: utf-8 -*- require "helper" # http://stakeholders.ofcom.org.uk/telecoms/numbering/guidance-tele-no/numbers-for-drama # # Geographic Area Geographic Area Code Telephone Number Range # (1000 numbers in each range) # Leeds 0113 496 0000 to 496 0999 # Sheffield 0114 496 0000 to 496 0999 # Nottingham 0115 496 0000 to 496 0999 # Leicester 0116 496 0000 to 496 0999 # Bristol 0117 496 0000 to 496 0999 # Reading 0118 496 0000 to 496 0999 # Birmingham 0121 496 0000 to 496 0999 # Edinburgh 0131 496 0000 to 496 0999 # Glasgow 0141 496 0000 to 496 0999 # Liverpool 0151 496 0000 to 496 0999 # Manchester 0161 496 0000 to 496 0999 # London 020 7946 0000 to 7946 0999 # Tyneside/Durham #/Sunderland 0191 498 0000 to 498 0999 # Northern Ireland 028 9018 0000 to 9018 0999 # Cardiff 029 2018 0000 to 2018 0999 # No area 01632 960000 to 960999 # # Other Telephone Numbers # # Telephone Number Type Telephone Number Range # (1000 numbers in each range) # Mobile 07700 900000 to 900999 # Freephone 08081 570000 to 570999 # Premium Rate Services 0909 8790000 to 8790999 # UK Wide 03069 990000 to 990999 class GBTest < Minitest::Test ## SHORT CODES # London 020 7946 0000 to 7946 0999 def test_london parse_test('+44 20 7946 0123', '44', '20', '79460123') end # Northern Ireland 028 9018 0000 to 9018 0999 def test_northern_ireland parse_test('+44 28 9018 0123', '44', '28', '90180123') end # Cardiff 029 2018 0000 to 2018 0999 def test_cardiff parse_test('+44 29 2018 0123', '44', '29', '20180123') end # Leeds 0113 496 0000 to 496 0999 def test_leeds parse_test('+44 113 496 0123', '44', '113', '4960123') end # Sheffield 0114 496 0000 to 496 0999 def test_sheffield parse_test('+44 114 496 0123', '44', '114', '4960123') end # Nottingham 0115 496 0000 to 496 0999 def test_nottingham parse_test('+44 115 496 0123', '44', '115', '4960123') end # Leicester 0116 496 0000 to 496 0999 def test_leicester parse_test('+44 116 496 0123', '44', '116', '4960123') end # Bristol 0117 496 0000 to 496 0999 def test_bristol parse_test('+44 117 496 0123', '44', '117', '4960123') end # Reading 0118 496 0000 to 496 0999 def test_reading parse_test('+44 118 496 0123', '44', '118', '4960123') end # Birmingham 0121 496 0000 to 496 0999 def test_birmingham parse_test('+44 121 496 0123', '44', '121', '4960123') end # Edinburgh 0131 496 0000 to 496 0999 def test_edinburgh parse_test('+44 131 496 0123', '44', '131', '4960123') end # Glasgow 0141 496 0000 to 496 0999 def test_glasgow parse_test('+44 141 496 0123', '44', '141', '4960123') end # Liverpool 0151 496 0000 to 496 0999 def test_liverpool parse_test('+44 151 496 0123', '44', '151', '4960123') end # Manchester 0161 496 0000 to 496 0999 def test_manchester parse_test('+44 161 496 0123', '44', '161', '4960123') end # Tyneside/Durham #/Sunderland 0191 498 0000 to 498 0999 def test_tyneside parse_test('+44 191 496 0123', '44', '191', '4960123') end ## LONG CODES # 01202 — Bournemouth (BO) def test_bournemouth parse_test('+44 1202 96 0123', '44', '1202', '960123') end # 01326 — Falmouth (FA) def test_falmouth parse_test('+44 1326 96 0123', '44', '1326', '960123') end # 01420 — Alton (HA) def test_alton parse_test('+44 1420 96 0123', '44', '1420', '960123') end # 01598 — Lynton (LY) def test_lynton parse_test('+44 1598 96 0123', '44', '1598', '960123') end # 01637 — Newquay (NE) def test_newquay parse_test('+44 1637 96 0123', '44', '1637', '960123') end # 01700 — Rothesay (RO) def test_rothesay parse_test('+44 1700 96 0123', '44', '1700', '960123') end # 01951 — Colonsay def test_colonsay parse_test('+44 1951 96 0123', '44', '1951', '960123') end # No area 01632 960000 to 960999 def test_no_area parse_test('+44 1632 96 0123', '44', '1632', '960123') end # Personal numbering 070 xxxx xxxx def test_personal_numbering parse_test('+44 70 00001234', '44', '70', '00001234') end # Mobile 07700 900000 to 900999 def test_mobile parse_test('+44 7700 900345', '44', '7700', '900345') end def test_mobile_2 parse_test('+44 7778 900345', '44', '7778', '900345') end # Freephone 08081 570000 to 570999 def test_freephone parse_test('+44 808 1570123', '44', '808', '1570123') end def test_freephone_2 parse_test('+44 873 1570123', '44', '873', '1570123') end # Premium Rate Services 0909 8790000 to 8790999 def test_premium parse_test('+44 909 8790999', '44', '909', '8790999') end def test_premium2 parse_test('+44 910 8790123', '44', '910', '8790123') end # UK Wide 03069 990000 to 990999 def test_wide parse_test('+44 306 9990123', '44', '306', '9990123') end def test_wide_2 parse_test('+44 339 9990123', '44', '339', '9990123') end end ================================================ FILE: test/countries/hr_test.rb ================================================ require "helper" ## Croatia class HRTest < Minitest::Test def test_zagreb parse_test('+38513668734', '385', '1', '3668734') end def test_mobile parse_test('+385915125486', '385', '91', '5125486') end def test_long_without_special_characters parse_test('+385915125486', '385', '91', '5125486') end def test_long_with_special_characters parse_test('+ 385 (91) 512 / 5486 ', '385', '91', '5125486') end def test_long_with_leading_zeros parse_test('00385915125486', '385', '91', '5125486') end def test_zagreb_long_with_leading_zeros parse_test('0038513668734', '385', '1', '3668734') end def test_short_without_special_characters_with_country Phoner::Phone.default_country_code = '385' parse_test('044885047', '385', '44', '885047') end def test_zagreb_short_without_special_characters_with_country Phoner::Phone.default_country_code = '385' parse_test('013668734', '385', '1', '3668734') end def test_long_with_zero_in_brackets Phoner::Phone.default_country_code = nil parse_test('+385 (0)1 366 8111', '385', '1', '3668111') end def test_has_default_country_code Phoner::Phone.default_country_code = '385' assert_equal Phoner::Phone.parse('+38547451588').has_default_country_code?, true assert_equal Phoner::Phone.parse('+38647451588').has_default_country_code?, false end def test_has_default_area_code Phoner::Phone.default_country_code = '385' Phoner::Phone.default_area_code = '47' assert_equal Phoner::Phone.parse('047/451-588').has_default_area_code?, true assert_equal Phoner::Phone.parse('032/336-1456').has_default_area_code?, false end def test_validates Phoner::Phone.default_country_code = nil assert_equal Phoner::Phone.valid?('00385915125486'), true assert_equal Phoner::Phone.valid?('+385915125486'), true assert_equal Phoner::Phone.valid?('+385 (91) 512 5486'), true assert_equal Phoner::Phone.valid?('+38547451588'), true Phoner::Phone.default_country_code = '385' assert_equal Phoner::Phone.valid?('0915125486'), true assert_equal Phoner::Phone.valid?('091/512-5486'), true assert_equal Phoner::Phone.valid?('091/512-5486'), true assert_equal Phoner::Phone.valid?('091 512 54 86'), true assert_equal Phoner::Phone.valid?('091-512-54-86'), true assert_equal Phoner::Phone.valid?('047/451-588'), true end end ================================================ FILE: test/countries/hu_test.rb ================================================ require "helper" ## Hungary class HUTest < Minitest::Test def test_mobile parse_test('+36 30 5517999', '36', '30', '5517999') end end ================================================ FILE: test/countries/ie_test.rb ================================================ require "helper" ## Ireland class IETest < Minitest::Test def test_short_cork_number parse_test('+353 28 28946', '353', '28', '28946') end def test_short_cork_number_2 parse_test('+353 28 28943', '353', '28', '28943') end def test_short_wrong_area_code pp = Phoner::Phone.parse('+353 33023') assert_nil pp end end ================================================ FILE: test/countries/me_test.rb ================================================ require "helper" ## Montenegro class METest < Minitest::Test def test_mobile parse_test('+382 69 555 5555', '382', '69', '5555555') end def test_local parse_test('+382 20 555 5555', '382', '20', '5555555') end end ================================================ FILE: test/countries/nl_test.rb ================================================ require "helper" ## Netherlands class NETest < Minitest::Test # 06: mobile phone number def test_mobile parse_test('+31 6 12345678', '31', '6', '12345678') end # 066: mobile pagers def test_pagers parse_test('+31 66 1234567', '31', '66', '1234567') end # 06760: internet access number def test_internet_access parse_test('+31 6760 12345', '31', '6760', '12345') end # 0800: toll free number def test_toll_free parse_test('+31 800 123456', '31', '800', '123456') end # 084: location independent (used mostly for fax-to-email and voicemail services) def test_location_independent_84 parse_test('+31 84 1234567', '31', '84', '1234567') end # 085: location independent def test_location_independent_85 parse_test('+31 85 1234567', '31', '85', '1234567') end # 087: location independent def test_location_independent_87 parse_test('+31 87 1234567', '31', '87', '1234567') end # 088: location independent (for companies) def test_location_independent_88 parse_test('+31 88 1234567', '31', '88', '1234567') end # 0878: location independent (voice over IP) def test_location_independent_878 parse_test('+31 878 123456', '31', '878', '123456') end # 0900: premium rate, information def test_premium_900 parse_test('+31 900 123456', '31', '900', '123456') end # 0906: premium rate, erotic def test_premium_906 parse_test('+31 906 123456', '31', '906', '123456') end # 0909: premium rate, entertainment # 112: emergency services number # 14xxx(x): public authorities, where xxxx is the three- or four-digit area-code of the municipality # 18xx: number information # 01x(x) to 05x(x): geographical area codes ## two digit # 010 Rotterdam def test_rotterdam parse_test('+31 10 1234567', '31', '10', '1234567') end # 013 Tilburg def test_tilburg parse_test('+31 13 1234567', '31', '13', '1234567') end # 015 Delft # 020 Amsterdam def test_amsterdam parse_test('+31 20 1234567', '31', '20', '1234567') end # 023 Haarlem # 024 Nijmegen # 026 Arnhem # 030 Utrecht def test_utrecht parse_test('+31 30 1234567', '31', '30', '1234567') end # 033 Amersfoort def test_amersfoort parse_test('+31 33 1234567', '31', '33', '1234567') end # 035 Hilversum # 036 Almere # 038 Zwolle # 040 Eindhoven # 043 Maastricht # 045 Heerlen def test_heerlen parse_test('+31 45 1234567', '31', '45', '1234567') end # 046 Sittard # 050 Groningen def test_groningen parse_test('+31 50 1234567', '31', '50', '1234567') end # 053 Enschede # 055 Apeldoorn # 058 Leeuwarden def test_leeuwarden parse_test('+31 58 1234567', '31', '58', '1234567') end # 07x: geographical area codes (cities all over the country) # 070 The Hague def test_the_hague parse_test('+31 70 1234567', '31', '70', '1234567') end # 071 Leiden def test_leiden parse_test('+31 71 1234567', '31', '71', '1234567') end # 072 Alkmaar # 073 's-Hertogenbosch # 074 Hengelo # 075 Zaandam def test_zaandam parse_test('+31 75 1234567', '31', '75', '1234567') end # 076 Breda # 077 Venlo # 078 Dordrecht # 079 Zoetermeer def test_zoetermeer parse_test('+31 79 1234567', '31', '79', '1234567') end ## three digit # 0111 Zierikzee def test_zierikzee parse_test('+31 111 123456', '31', '111', '123456') end # 0113 Goes def test_goes parse_test('+31 113 123456', '31', '113', '123456') end # 0114 Hulst # 0115 Terneuzen # 0117 Sluis def test_sluis parse_test('+31 117 123456', '31', '117', '123456') end # 0118 Middelburg # 0161 Gilze-Rijen def test_gilze parse_test('+31 161 123456', '31', '161', '123456') end # 0162 Oosterhout # 0164 Bergen op Zoom def test_bergen parse_test('+31 164 123456', '31', '164', '123456') end # 0165 Roosendaal # 0166 Tholen # 0167 Steenbergen # 0168 Zevenbergen # 0172 Alphen aan den Rijn def test_alphen parse_test('+31 172 123456', '31', '172', '123456') end # 0174 Naaldwijk # 0180 Ridderkerk def test_ridderkerk parse_test('+31 180 123456', '31', '180', '123456') end # 0181 Spijkenisse # 0182 Gouda def test_gouda parse_test('+31 182 123456', '31', '182', '123456') end # 0183 Gorinchem # 0184 Sliedrecht # 0186 Oud-Beijerland # 0187 Middelharnis # 0222 Texel def test_texel parse_test('+31 222 123456', '31', '222', '123456') end # 0223 Den Helder # 0224 Schagen def test_shagen parse_test('+31 224 123456', '31', '224', '123456') end # 0226 Harenkarspel # 0227 Medemblik, Middenmeer as well as Heerhugowaard # 0228 Enkhuizen # 0229 Hoorn def test_hoorn parse_test('+31 229 123456', '31', '229', '123456') end # 0251 Beverwijk def test_beverwijk parse_test('+31 251 123456', '31', '251', '123456') end # 0252 Hillegom # 0255 IJmuiden # 0294 Weesp def test_weesp parse_test('+31 294 123456', '31', '294', '123456') end # 0297 Aalsmeer # 0299 Purmerend # 0313 Dieren def test_dieren parse_test('+31 313 123456', '31', '313', '123456') end # 0314 Doetinchem # 0315 Terborg def test_terborg parse_test('+31 315 123456', '31', '315', '123456') end # 0316 Zevenaar # 0317 Wageningen # 0318 Ede / Veenendaal # 0320 Lelystad def test_lelystad parse_test('+31 320 123456', '31', '320', '123456') end # 0321 Dronten # 0341 Harderwijk def test_harderwijk parse_test('+31 341 123456', '31', '341', '123456') end # 0342 Barneveld # 0343 Doorn # 0344 Tiel def test_tiel parse_test('+31 344 123456', '31', '344', '123456') end # 0345 Culemborg # 0346 Maarssen # 0347 Vianen # 0348 Woerden # 0411 Boxtel def test_boxtel parse_test('+31 411 123456', '31', '411', '123456') end # 0412 Oss # 0413 Veghel # 0416 Waalwijk # 0418 Zaltbommel # 0475 Roermond def test_roermond parse_test('+31 475 123456', '31', '475', '123456') end # 0478 Venray # 0481 Bemmel def test_bemmel parse_test('+31 481 123456', '31', '481', '123456') end # 0485 Cuijk # 0486 Grave # 0487 Druten def test_druten parse_test('+31 487 123456', '31', '487', '123456') end # 0488 Zetten # 0492 Helmond def test_helmond parse_test('+31 492 123456', '31', '492', '123456') end # 0493 Deurne # 0495 Weert def test_weert parse_test('+31 495 123456', '31', '495', '123456') end # 0497 Eersel # 0499 Best # 0511 Veenwouden def test_veenwouden parse_test('+31 511 123456', '31', '511', '123456') end # 0512 Drachten # 0513 Heerenveen # 0514 Balk # 0515 Sneek def test_sneek parse_test('+31 515 123456', '31', '515', '123456') end # 0516 Oosterwolde # 0517 Franeker # 0518 St. Annaparochie # 0519 Dokkum # 0521 Steenwijk def test_steenwijk parse_test('+31 521 123456', '31', '521', '123456') end # 0522 Meppel # 0523 Hardenberg # 0524 Coevorden def tst_coevorden parse_test('+31 524 123456', '31', '524', '123456') end # 0525 Elburg # 0527 Emmeloord # 0528 Hoogeveen # 0529 Ommen # 0541 Oldenzaal def test_oldenzaal parse_test('+31 541 123456', '31', '541', '123456') end # 0543 Winterswijk # 0544 Groenlo # 0545 Neede def test_neede parse_test('+31 545 123456', '31', '545', '123456') end # 0546 Almelo # 0547 Goor # 0548 Rijssen # 0561 Wolvega def test_wolvega parse_test('+31 561 123456', '31', '561', '123456') end # 0562 Terschelling/Vlieland # 0566 Irnsum # 0570 Deventer def test_deventer parse_test('+31 570 123456', '31', '570', '123456') end # 0571 Voorst # 0572 Raalte # 0573 Lochem def test_lochem parse_test('+31 573 123456', '31', '573', '123456') end # 0575 Zutphen # 0577 Uddel # 0578 Epe # 0591 Emmen def test_emmen parse_test('+31 591 123456', '31', '591', '123456') end # 0592 Assen # 0593 Beilen def test_beilen parse_test('+31 593 123456', '31', '593', '123456') end # 0594 Zuidhorn # 0595 Warffum # 0596 Appingedam # 0597 Winschoten # 0598 Hoogezand # 0599 Stadskanaal def test_stadskanaal parse_test('+31 599 123456', '31', '599', '123456') end end ================================================ FILE: test/countries/nz_test.rb ================================================ require "helper" ## New Zealand class NZTest < Minitest::Test def test_local parse_test('+6431234567', '64', '3', '1234567') end end ================================================ FILE: test/countries/pt_test.rb ================================================ require "helper" ## Portugal # source 1: http://pt.wikipedia.org/wiki/N%C3%BAmeros_de_telefone_em_Portugal # source 2: http://www.anacom.pt/render.jsp?categoryId=279035 class PTTest < Minitest::Test ### Prefixes followed by corresponding tests ## 01-09: reserved for future use ## 1: Short Numbers ## 2: Landline / fixed numbers ## two digits landlines # 21: Lisbon (Lisboa) def test_lisbon parse_test('+351 21 123 4567', '351', '21', '1234567') end # 22: Oporto (Porto) def test_oporto parse_test('+351 22 123 4567', '351', '22', '1234567') end ## three digits landlines # 231: Mealhada def test_mealhada parse_test('+351 231 123456', '351', '231', '123456') end # 232-295 (Viseu - Angra do Heroismo) def test_viseu parse_test('+351 232 123456', '351', '232', '123456') end def test_angra parse_test('+351 295 123456', '351', '295', '123456') end # 296: Ponta Delgada def test_pontadelgada parse_test('+351 296 123456', '351', '296', '123456') end ## 3: Nomad services ## 4: Not used ## 5: Free ## 6: Audiotext service, data network access... ## 7: Premium numbers ("Universal access numbers") # 707-708: Premium Numbers def test_707 Phoner::Phone.default_country_code = '351' parse_test('707 123 456', '351', '707', '123456') end ## 8: Free toll numbers # 800: Numero verde ("Green Number") def test_800 Phoner::Phone.default_country_code = '351' parse_test('800 123 456', '351', '800', '123456') end # 808: Numero azul ("Blue Number") def test_808 Phoner::Phone.default_country_code = '351' parse_test('808 123 456', '351', '808', '123456') end # 809: Custo partilhado ("Shared cost") def test_809 Phoner::Phone.default_country_code = '351' parse_test('809 123 456', '351', '809', '123456') end ## 9: Mobile networks ## two-digits mobile networks # 91: Vodafone def test_vodafone parse_test('+351 91 1234567', '351', '91', '1234567') end # 93: Optimus def test_optimus parse_test('+351 93 1234567', '351', '93', '1234567') end # 96: TMN two-digits def test_tmn parse_test('+351 96 1234567', '351', '96', '1234567') end ## three-digits mobile networks # 921: TMN three-digits def test_tmn921 parse_test('+351 921 123456', '351', '921', '123456') end # 923-926: TMN three-digits (corporate networks) def test_tmn923 parse_test('+351 925 123456', '351', '925', '123456') end # 922: Phone-ix def test_phoneix parse_test('+351 922 123456', '351', '922', '123456') end # 929: Zon Mobile def test_zonmobile parse_test('+351 929 123456', '351', '929', '123456') end def test_validates Phoner::Phone.default_country_code = nil assert_equal Phoner::Phone.valid?('00351211234567'), true assert_equal Phoner::Phone.valid?('00351911234567'), true assert_equal Phoner::Phone.valid?('+351931234567'), true assert_equal Phoner::Phone.valid?('+351 (911) 123 456'), true assert_equal Phoner::Phone.valid?('+351921123456'), true Phoner::Phone.default_country_code = '351' assert_equal Phoner::Phone.valid?('(931) 234-567'), true assert_equal Phoner::Phone.valid?('(211) 234 567'), true assert_equal Phoner::Phone.valid?('232-123-456'), true assert_equal Phoner::Phone.valid?('232123456'), true assert_equal Phoner::Phone.valid?('92 212 34 56'), true assert_equal Phoner::Phone.valid?('221234567'), true assert_equal Phoner::Phone.valid?('708123456'), true assert_equal Phoner::Phone.valid?('800 123 456'), true end end ================================================ FILE: test/countries/rs_test.rb ================================================ require "helper" ## Serbia class RSTest < Minitest::Test def test_local # Beograd parse_test('+381 11 24 33 836', '381', '11', '2433836') end def test_mobile # mts parse_test('+381 648542987', '381', '64', '8542987') end end ================================================ FILE: test/countries/se_test.rb ================================================ # -*- coding: utf-8 -*- require "helper" ## Sweden class SETest < Minitest::Test # 08 Greater Stockholm def test_stockholm parse_test('+4685555555', '46', '8', '5555555') end ## two digit codes # 010 Geographically Independent Numbers / VOIP services def test_independent_numbers parse_test('+46105555555', '46', '10', '5555555') end # 011 Norrköping def test_norrkoping parse_test('+46115555555', '46', '11', '5555555') end # 013 Linköping def test_linkoping parse_test('+46135555555', '46', '13', '5555555') end # 016 Eskilstuna-Torshälla def test_eskilstuna parse_test('+46165555555', '46', '16', '5555555') end # 018 Uppsala def test_uppsala parse_test('+46185555555', '46', '18', '5555555') end # 019 Örebro-Kumla def test_orebro parse_test('+46195555555', '46', '19', '5555555') end # 020 toll-free def test_toll_free parse_test('+46205555555', '46', '20', '5555555') end # 021 Västerås def test_vasteras parse_test('+46215555555', '46', '21', '5555555') end # 023 Falun def test_falun parse_test('+46235555555', '46', '23', '5555555') end # 026 Gävle-Sandviken def test_gavle parse_test('+46265555555', '46', '26', '5555555') end # 031 Göteborg def test_goteborg parse_test('+46315555555', '46', '31', '5555555') end # 033 Borås def test_boras parse_test('+46335555555', '46', '33', '5555555') end # 035 Halmstad def test_halmstad parse_test('+46355555555', '46', '35', '5555555') end # 036 Jönköping-Huskvarna def test_jonkoping parse_test('+46365555555', '46', '36', '5555555') end # 040 Malmö def test_malmo parse_test('+46405555555', '46', '40', '5555555') end # 042 Helsingborg-Höganäs def test_helsingborg parse_test('+46425555555', '46', '42', '5555555') end # 044 Kristianstad def test_kristianstad parse_test('+46445555555', '46', '44', '5555555') end # 046 Lund def test_lund parse_test('+46465555555', '46', '46', '5555555') end # 054 Karlstad def test_karlstad parse_test('+46545555555', '46', '54', '5555555') end # 060 Sundsvall-Timrå def test_sundsvall parse_test('+46605555555', '46', '60', '5555555') end # 063 Östersund def test_ostersund parse_test('+46635555555', '46', '63', '5555555') end # 070, def test_mobile_70 parse_test('+46705555555', '46', '70', '5555555') end # 071 Telematics in Mobile Networks (used to be Premium rate numbers) def test_telematics parse_test('+46715555555', '46', '71', '5555555') end # 072, def test_mobile_72 parse_test('+46725555555', '46', '72', '5555555') end # 073, def test_mobile_73 parse_test('+46735555555', '46', '73', '5555555') end # 076 Mobile networks def test_mobile_76 parse_test('+46765555555', '46', '76', '5555555') end # 090 Umeå def test_umea parse_test('+46905555555', '46', '90', '5555555') end # 099 Premium rate calls def test_premium_99 parse_test('+46995555555', '46', '99', '5555555') end ## three digit codes # 0120 Åtvidaberg def test_atvidaberg parse_test('+46120555555', '46', '120', '555555') end # 0121 Söderköping # 0122 Finspång # 0123 Valdemarsvik # 0125 Vikbolandet # 0140 Tranås # 0141 Motala # 0142 Mjölby-Skänninge-Boxholm # 0143 Vadstena # 0144 Ödeshög # 0150 Katrineholm # 0151 Vingåker # 0152 Strängnäs # 0155 Nyköping-Oxelösund # 0156 Trosa-Vagnhärad # 0157 Flen-Malmköping # 0158 Gnesta # 0159 Mariefred # 0171 Enköping def test_enkoping parse_test('+461715555555', '46', '171', '5555555') end # 0173 Öregrund-Östhammar # 0174 Alunda # 0175 Hallstavik-Rimbo # 0176 Norrtälje # 0220 Hallstahammar-Surahammar def test_hallstahammar parse_test('+462205555555', '46', '220', '5555555') end # 0221 Köping # 0222 Skinnskatteberg # 0223 Fagersta-Norberg # 0224 Sala-Heby # 0225 Hedemora-Säter # 0226 Avesta-Krylbo # 0227 Kungsör # 0240 Ludvika-Smedjebacken # 0241 Gagnef-Floda # 0243 Borlänge # 0246 Svärdsjö-Enviken # 0247 Leksand-Insjön # 0248 Rättvik def test_rattvik parse_test('+462485555555', '46', '248', '5555555') end # 0250 Mora-Orsa # 0251 Älvdalen # 0253 Idre-Särna # 0258 Furudal # 0270 Söderhamn # 0271 Alfta-Edsbyn # 0278 Bollnäs # 0280 Malung # 0281 Vansbro # 0290 Hofors-Storvik # 0291 Hedesunda-Österfärnebo # 0292 Tärnsjö-Östervåla # 0293 Tierp-Söderfors # 0294 Karlholmsbruk-Skärplinge # 0295 Örbyhus-Dannemora # 0297 Ockelbo-Hamrånge def test_ockelbo parse_test('+462975555555', '46', '297', '5555555') end # 0300 Kungsbacka def test_kungsbacka parse_test('+463005555555', '46', '300', '5555555') end # 0301 Hindås # 0302 Lerum # 0303 Kungälv # 0304 Orust-Tjörn # 0320 Kinna # 0321 Ulricehamn # 0322 Alingsås-Vårgårda # 0325 Svenljunga-Tranemo # 0340 Varberg def test_varberg parse_test('+463405555555', '46', '340', '5555555') end # 0345 Hyltebruk-Torup # 0346 Falkenberg # 0370 Värnamo # 0371 Gislaved-Anderstorp # 0372 Ljungby # 0380 Nässjö # 0381 Eksjö # 0382 Sävsjö # 0383 Vetlanda # 0390 Gränna # 0392 Mullsjö # 0393 Vaggeryd # 0410 Trelleborg def test_trelleborg parse_test('+464105555555', '46', '410', '5555555') end # 0411 Ystad # 0413 Eslöv-Höör # 0414 Simrishamn # 0415 Hörby # 0416 Sjöbo # 0417 Tomelilla # 0418 Landskrona-Svalöv # 0430 Laholm def test_lanholm parse_test('+464305555555', '46', '430', '5555555') end # 0431 Ängelholm-Båstad # 0433 Markaryd-Strömsnäsbruk # 0435 Klippan-Perstorp # 0451 Hässleholm # 0454 Karlshamn-Olofström # 0455 Karlskrona # 0456 Sölvesborg-Bromölla # 0457 Ronneby # 0459 Ryd # 0470 Växjö def test_vaxjo parse_test('+464705555555', '46', '470', '5555555') end # 0471 Emmaboda # 0472 Alvesta-Rydaholm # 0474 Åseda-Lenhovda # 0476 Älmhult # 0477 Tingsryd # 0478 Lessebo # 0479 Osby # 0480 Kalmar # 0481 Nybro # 0485 Öland # 0486 Torsås # 0490 Västervik # 0491 Oskarshamn-Högsby # 0492 Vimmerby # 0493 Gamleby # 0494 Kisa def test_kisa parse_test('+464945555555', '46', '494', '5555555') end # 0495 Hultsfred-Virserum # 0496 Mariannelund # 0498 Gotland # 0499 Mönsterås # 0500 Skövde def test_skovde parse_test('+465005555555', '46', '500', '5555555') end # 0501 Mariestad # 0502 Tidaholm # 0503 Hjo def test_hjo parse_test('+465035555555', '46', '503', '5555555') end # 0504 Tibro # 0505 Karlsborg # 0506 Töreboda-Hova # 0510 Lidköping # 0511 Skara-Götene # 0512 Vara-Nossebro # 0513 Herrljunga # 0514 Grästorp # 0515 Falköping # 0520 Trollhättan # 0521 Vänersborg # 0522 Uddevalla # 0523 Lysekil # 0524 Munkedal # 0525 Grebbestad # 0526 Strömstad # 0528 Färgelanda # 0530 Mellerud # 0531 Bengtsfors # 0532 Åmål # 0533 Säffle # 0534 Ed # 0550 Kristinehamn # 0551 Gullspång # 0552 Deje def test_deje parse_test('+465525555555', '46', '552', '5555555') end # 0553 Molkom # 0554 Kil # 0555 Grums # 0560 Torsby # 0563 Hagfors-Munkfors # 0564 Sysslebäck # 0565 Sunne # 0570 Arvika # 0571 Charlottenberg-Åmotfors # 0573 Årjäng # 0580 Kopparberg # 0581 Lindesberg # 0582 Hallsberg-Pålsboda # 0583 Askersund # 0584 Laxå # 0585 Fjugesta-Svartå # 0586 Karlskoga-Degerfors # 0587 Nora def test_nora parse_test('+465875555555', '46', '587', '5555555') end # 0589 Arboga # 0590 Filipstad # 0591 Hällefors-Grythyttan # 0611 Härnösand def test_harnosand parse_test('+466115555555', '46', '611', '5555555') end # 0612 Kramfors # 0613 Ullånger # 0620 Sollefteå # 0621 Junsele # 0622 Näsåker # 0623 Ramsele # 0624 Backe # 0640 Krokom # 0642 Lit # 0643 Hallen-Oviken # 0644 Hammerdal # 0645 Föllinge # 0647 Åre-Järpen # 0650 Hudiksvall # 0651 Ljusdal # 0652 Bergsjö # 0653 Delsbo # 0657 Los # 0660 Örnsköldsvik # 0661 Bredbyn # 0662 Björna # 0663 Husum def test_husum parse_test('+466635555555', '46', '663', '5555555') end # 0670 Strömsund # 0671 Hoting # 0672 Gäddede # 0680 Sveg # 0682 Rätan # 0684 Hede-Funäsdalen # 0687 Svenstavik # 0690 Ånge # 0691 Torpshammar # 0692 Liden # 0693 Bräcke-Gällö # 0695 Stugun # 0696 Hammarstrand # 07x(x) various non-geographical area codes # ambiguous! # 074(x) Pagers def test_pagers parse_test('+467405555555', '46', '740', '5555555') end # 0900 Premium rate calls def test_premium_900 parse_test('+469005555555', '46', '900', '5555555') end # 0910 Skellefteå # 0911 Piteå # 0912 Byske # 0913 Lövånger # 0914 Burträsk # 0915 Bastuträsk # 0916 Jörn def test_jorn parse_test('+469165555555', '46', '916', '5555555') end # 0918 Norsjö # 0920 Luleå # 0921 Boden # 0922 Haparanda # 0923 Kalix # 0924 Råneå # 0925 Lakaträsk # 0926 Överkalix # 0927 Övertorneå # 0928 Harads # 0929 Älvsbyn # 0930 Nordmaling # 0932 Bjurholm # 0933 Vindeln # 0934 Robertsfors # 0935 Vännäs def test_vannas parse_test('+469355555555', '46', '935', '5555555') end # 0939 Premium rate calls # 0940 Vilhelmina # 0941 Åsele # 0942 Dorotea # 0943 Fredrika # 0944 Premium rate calls # 0950 Lycksele # 0951 Storuman # 0952 Sorsele # 0953 Malå # 0954 Tärnaby # 0960 Arvidsjaur # 0961 Arjeplog # 0970 Gällivare # 0971 Jokkmokk # 0973 Porjus # 0975 Hakkas # 0976 Vuollerim # 0977 Korpilombolo # 0978 Pajala # 0980 Kiruna # 0981 Vittangi def test_vittangi parse_test('+469815555555', '46', '981', '5555555') end end ================================================ FILE: test/countries/si_test.rb ================================================ require "helper" ## Slovenia class SITest < Minitest::Test def test_local #Maribor parse_test('+ 386 2 23 46 611', '386', '2', '2346611') end def test_local_2 # Koper parse_test('+ 386 5 23 46 611', '386', '5', '2346611') end def test_mobile # Mobitel parse_test('+386 51 258999', '386', '51', '258999') end end ================================================ FILE: test/countries/ua_test.rb ================================================ require "helper" ## Ukraine class UATest < Minitest::Test def test_local parse_test('+380 57 711 22 33', '380', '57', '7112233') end def test_mobile parse_test('+380-50-111-22-33', '380', '50', '1112233') end def test_mobile2 parse_test('+380-66-042-22-01', '380', '66', '0422201') end end ================================================ FILE: test/countries/us_test.rb ================================================ require "helper" ## United States class USTest < Minitest::Test def test_local parse_test('+1 555 123 4567', '1', '555', '1234567') end def test_tollfree parse_test('+1 800 555 3456', '1', '800', '5553456') end def test_long_with_default_country_code Phoner::Phone.default_country_code = '1' parse_test('2069735100', '1', '206', '9735100') end def test_short_with_default_country_code_and_area_code Phoner::Phone.default_country_code = '1' Phoner::Phone.default_area_code = '206' parse_test('9735100', '1', '206', '9735100') end end ================================================ FILE: test/countries/uy_test.rb ================================================ require "helper" ## Uruguay # source: http://en.wikipedia.org/wiki/Telephone_numbers_in_Uruguay class UYTest < Minitest::Test # 02 Montevideo def test_montevideo parse_test('+598 2 1234567', '598', '2', '1234567') end # 042 Maldonado def test_maldonado parse_test('+598 42 123456', '598', '42', '123456') end # 09 Mobile phones def test_mobile_phones parse_test('+598 99 570110', '598', '99', '570110') end end ================================================ FILE: test/countries/za_test.rb ================================================ require "helper" ## South Africa class ZATest < Minitest::Test def test_local # Telkom parse_test('+27 11 555 5555', '27', '11', '5555555') end def test_mobile # Vodacom parse_test('+27 82 555 5555', '27', '82', '5555555') # Broader cellular ranges past initial allocation given to telecoms service providers parse_test('+27 62 555 5555', '27', '62', '5555555') parse_test('+27 99 555 5555', '27', '99', '5555555') end def test_tollfree # Telkom parse_test('+27 800 123 321', '27', '800', '123321') end def test_long_msisdns parse_test('+279602007648699', '27', '96', '02007648699') end end ================================================ FILE: test/extension_test.rb ================================================ require "helper" class ExtensionTest < Minitest::Test def test_parse_usa_long_with_simple_extension pn = Phoner::Phone.parse "+1 2069735100 x143" refute_nil pn, %Q{parse should pass} assert_equal '9735100', pn.number assert_equal '206', pn.area_code assert_equal '1', pn.country_code assert_equal '143', pn.extension end def test_to_s_with_extension pn = Phoner::Phone.new '5125486', '91', '385', '143' assert_equal '+385915125486x143', pn.format(:default_with_extension) end def test_format_with_extension pn = Phoner::Phone.new '5125486', '91', '385', '143' assert_equal '(091)/512-5486 x 143', pn.format('(%A)/%f-%l x %x') end def test_extract_extension string = "+1 2069735100 x143" number, ext = Phoner::Phone.extract_extension(string) assert_equal "+1 2069735100 x143", string assert_equal "+1 2069735100", number assert_equal "143", ext end end ================================================ FILE: test/helper.rb ================================================ require "rubygems" begin require "bundler" rescue LoadError => e STDERR.puts e.message STDERR.puts "Run `gem install bundler` to install Bundler." exit e.status_code end begin Bundler.setup(:default, :development, :test) rescue Bundler::BundlerError => e STDERR.puts e.message STDERR.puts "Run `bundle install` to install missing gems." exit e.status_code end require "phone" require "minitest/autorun" class Minitest::Test def setup Phoner::Phone.default_country_code = nil Phoner::Phone.default_area_code = nil end def teardown Phoner::Phone.default_country_code = nil Phoner::Phone.default_area_code = nil end end def parse_test(raw, country_code, area_code, number) pn = Phoner::Phone.parse(raw) refute_nil pn, %Q{parse should pass} assert_equal country_code, pn.country_code assert_equal area_code, pn.area_code assert_equal number, pn.number end ================================================ FILE: test/phone_test.rb ================================================ require "helper" class PhoneTest < Minitest::Test def test_with_nil_number_initialize assert_raises Phoner::BlankNumberError do Phoner::Phone.new nil end end def test_with_empty_number_initialize assert_raises Phoner::BlankNumberError do Phoner::Phone.new "" end end def test_number_without_country_code_initialize Phoner::Phone.default_country_code = nil assert_raises Phoner::CountryCodeError do Phoner::Phone.new '5125486', '91' end end def test_number_without_country_and_area_code_initialize Phoner::Phone.default_country_code = nil Phoner::Phone.default_area_code = nil assert_raises Phoner::AreaCodeError do Phoner::Phone.new '451588' end end def test_number_with_default_area_code_initialize Phoner::Phone.default_country_code = '385' Phoner::Phone.default_area_code = '47' pn = Phoner::Phone.new '451588' assert pn.number == '451588' assert pn.area_code == '47' assert pn.country_code == '385' end def test_number_with_default_country_code_initialize Phoner::Phone.default_country_code = '386' pn = Phoner::Phone.new '5125486', '91' assert pn.number == '5125486' assert pn.area_code == '91' assert pn.country_code == '386' end def test_number_with_country_code_initialize Phoner::Phone.default_country_code = '387' pn = Phoner::Phone.new '5125486', '91', '385' assert pn.number == '5125486' assert pn.area_code == '91' assert pn.country_code == '385' end def test_parse_empty assert_nil Phoner::Phone.parse('') assert_nil Phoner::Phone.parse(nil) end def test_parse_with_special_characters_with_country pn = Phoner::Phone.parse "+1 545-545-5454" assert "1", pn.country_code assert "545", pn.area_code assert "5455454", pn.number end def test_parse_with_extension pn = Phoner::Phone.parse "+1 545-545-5454 ext. 4307" assert "1", pn.country_code assert "545", pn.area_code assert "5455454", pn.number assert "4307", pn.extension end def test_parse_wont_alter_parameter number = "+1 545-545-5454 ext. 4307" _parsed = Phoner::Phone.parse number assert_equal "+1 545-545-5454 ext. 4307", number end def test_parse_short_without_special_characters_without_country Phoner::Phone.default_country_code = nil assert_raises Phoner::CountryCodeError do Phoner::Phone.parse "0915125486" end end def test_parse_short_with_special_characters_without_country Phoner::Phone.default_country_code = nil assert_raises Phoner::CountryCodeError do Phoner::Phone.parse "091/512-5486" end end def test_normalize numbers = [ ["(0)512-5486", "5125486"], ["z512-5486", "5125486"], ["00512-5486", "+5125486"], ["+00512-5486", "+5125486"], ["+0512-5486", "+5125486"], ] numbers.each do |number, expected| assert_equal expected, Phoner::Phone.normalize(number) end end def test_to_s Phoner::Phone.default_country_code = nil pn = Phoner::Phone.new '5125486', '91', '385' assert pn.to_s == '+385915125486' end def test_to_s_without_country_code Phoner::Phone.default_country_code = '385' pn = Phoner::Phone.new '5125486', '91' assert pn.format("0%a%n") == '0915125486' end def test_format_special_with_country_code Phoner::Phone.default_country_code = nil pn = Phoner::Phone.new '5125486', '91', '385' assert pn.format("+ %c (%a) %n") == '+ 385 (91) 5125486' end def test_format_special_without_country_code Phoner::Phone.default_country_code = '385' pn = Phoner::Phone.new '5125486', '91' assert_equal pn.format("%A/%f-%l"), '091/512-5486' end def test_format_with_symbol_specifier Phoner::Phone.default_country_code = nil pn = Phoner::Phone.new '5125486', '91', '385' assert_equal pn.format(:europe), '+385 (0) 91 512 5486' end def test_validity assert true, Phoner::Phone.valid?("+17788827175") end def test_successful_validity_wont_alter_parameter number = "+17755551212" Phoner::Phone.valid?(number) assert_equal "+17755551212", number end def test_failing_validity_wont_alter_parameter number = "ABC123" Phoner::Phone.valid?(number) assert_equal "ABC123", number end def test_validity_with_country_code assert true, Phoner::Phone.valid?("7788827175", :country_code => "1") end def test_doesnt_validate assert_equal Phoner::Phone.valid?('asdas'), false assert_equal Phoner::Phone.valid?('385915125486'), false end def test_valid_wont_strip_the_extension number = '+1 (123) 456-7890 x321' parsed = Phoner::Phone.parse(number) assert_equal "+11234567890", parsed.to_s assert_equal "321", parsed.extension assert Phoner::Phone.valid?(number) parsed = Phoner::Phone.parse(number) assert_equal "+11234567890", parsed.to_s assert_equal"321", parsed.extension end def test_comparison_true pn1 = Phoner::Phone.new '5125486', '91', '385' pn2 = Phoner::Phone.new '5125486', '91', '385' assert pn1 == pn2 end def test_comparison_false pn1 = Phoner::Phone.new '5125486', '91', '385' pn2 = Phoner::Phone.new '1234567', '91', '385' assert pn1 != pn2 end def test_find_by_country_isocode Phoner::Country.load assert_equal Phoner::Country.find_by_country_isocode('de').country_code, "49" assert_nil Phoner::Country.find_by_country_isocode('xx') assert_nil Phoner::Country.find_by_country_isocode('bla') end end ================================================ FILE: test_usa_phones_with_extensions.csv ================================================ 601-867-5000 ext 75292 (334)821-2223 Ext. 107 (863) 983-6171 ext: 0055 601-987-3995 ext 10 (512) 473-3200Ext2396 (727) 558-5010 ext: 0112 (904) 360-5611 ext: 5611 (937) 255-7204Ext337 228-374-5022 ext 5386 (205)987-3500 Ext. 205-32 (607) 273-8588x402 (205)328-3330 Ext. 802-59 (407) 251-2452 ext: 0146 502-564-8110 xt 312 (828) 698-3923x13 (608)836-7433 Ext. 5147 (1-808)935-3222 Ext. 2# (770)420-3179 Ext. x 179 (415) 558-8669x218 (205)879-6330 Ext. 731-50 (205)987-5995 Ext. 802-58 (609) 924-2200Ext10 (312) 440-4373x12 (978) 369-9602x457 1-602-264-1774 # 135 502-564-8890 x4340 502-564-5550 x4569 (480)437-2600 Ext. VM123 (850) 245-4131 ext: 3506 601-354-6161 ext 103 (414)778-5400 Ext. 127 (262)338-4475 Ext. #16 (602) 264-1774 extention # 135 (314) 361-3221x107 (800) 255-5747x46 410-514-7336 TDDTTY + Voice (617) 695-2300x393 1-334-386-8800 Ext. 107 (928)634-9536 Ext. 143 502-573-1555 x266 (978) 927-8000x246 (920) 887-4600Ext340 502-564-1404 x4536 (850) 245-6774 ext: 4774 (718) 852-3000 Ext 269 228-374-5022 ext 5022 502-564-0105 x10260 (850) 000-0000 ext: 00000000 (979) 233-1616x306 (207) 333-3267x224 (561) 625-5122 ext: 687 (386) 961-7414 ext: 7414 (262)549-2249 Ext. 104 (205)322-7500 Ext. BECKYS (303)858-8100 Ext. n.a. (937) 255-7204x337 601-944-4830 ext 104 228-432-1056 ext 104 (209) 586-1495Ext104 502-564-8139 : 4645 (602) 264-1774 ext is 135 (602) 264-1774Ext135 502-564-7822 x4212 (609) 921-8808Ext3 (703) 739-7900x222 (609) 758-2241x144 (970)223-6500 Ext. X6510 (734) 485-2000Ext255 (904) 620-4424 ext: 8614424 (904) 827-2520 ext: 2520 (978) 774-1050x251 (541) 343-0123x2269 (608)277-2752 Ext. 2752 (203) 869-6786x335 502-564-5981 x272 606-878-5908 x6085 502-564-2257 x3464 (205)871-1911 Ext. (205) 502-564-7770 x3965 (608)374-2130 Ext. 28 (850) 410-9660 ext: 9240 601-987-6837 ext 102 (414)529-1101 Ext. 153 (209) 586-1495x104 (520)408-1885 Ext. # 227 601-605-5388 ext 100 (352) 375-8484 ext: 0174 15025645981x225 (602) 264-1774 X 135 (205)803-1499 Ext. 414-03 (651) 459-4121x203 +61 3 9811 2400 (262)681-2020 Ext. 6682 601-944-4845 ext 118 384-1100 VOICE MAIL:3004 (205)251-1267 Ext. 802-09 (410) 280-2038Ext11 502-564-3170 x190 15025646734x4420