Giter Club home page Giter Club logo

phony's Introduction


Coverage Status

Phony

Disclaimer: Phony works with international numbers only, such as 61 412 345 678!

The (admittedly crazy) goal of this Gem is to be able to normalize/format/split all phone numbers in the world.

Used in: airbnb.com, socialcam.com, zendesk.com (and many, many others).

Runtime Memory Usage

According to memory_profiler, the Phony gem uses roughly 1MB of memory per Ruby process.
Usage was generated using (look for Total retained): ruby -e 'require "memory_profiler"; MemoryProfiler.report(allow_files: "phony"){ require "phony" }.pretty_print'

Description

This gem normalizes, formats and splits E164 phone numbers. A valid E164 phone number must include a country code.

E164 numbers are international numbers with a country dial prefix, usually an area code and a subscriber number. For example, the Australian number +61 412 345 678 can be broken down into the following components:

  • Country Code (CC): a country code of 61
  • National Destination Code (NDC): a mobile number denoted by the 4 (specific to Australia)
  • Local Number Part: a subscriber number of 12 345 678

It currently handles the countries listed at the end of this README.

It is covered by roughly 2,250 tests that run in 2 seconds (April 2019).
If it doesn’t work, please enter an issue or better, fork and send a pull request.

Installation

With Rails? Check out: https://github.com/joost/phony_rails.

With Bundler: Append gem 'phony' to your Gemfile and bundle install it.

Without Bundler: Run gem install phony from your command line.

Usage docs

Phony uses qed as docs and to run its functional tests. Start here for usage docs: Usage index.

Phony.normalize(number)

Normalize intelligently removes all non-numeric characters of a number. Do it before storing a number in a DB.

Phony.normalize docs

Phony.normalize('1-888-407-4747').assert == '18884074747'

Phony.format(number, options = {})

Format formats a normalized number according to a country’s predominant formatting. Lots of options for int’l, national, local formatting.

Phony.format docs

Phony.format('41443643532').assert == '+41 44 364 35 32'

Phony.plausible?(number, options = {})

Is a number plausible?

Phony.plausible? docs

Phony.assert.plausible?('+41 44 111 22 33')

Phony.split(number)

Split a number into its parts: CC, NDC, local.

Phony.split docs

Phony.split('3928061371').assert == ['39', '2', '806', '1371']

NB If a country does not have an NDC, #split will return false in the NDC position, for example for Denmark:

Phony.split('4512121212').assert == ['45', false, '12', '12', '12', '12']

Loading only a country subset (Phony 2.18.0+).

Use this in case you’d like to save memory that is used by Phony’s CC rules.

Phony::Config.load docs

First, require 'phony/config'.
Then, one of the following, which will load the rest of Phony.

Load only these CCs:
Phony::Config.load(only: ['41', '44'])

Loads everything except these CCs:
Phony::Config.load(except: ['41', '44'])

Convenience form of only:
Phony::Config.load('41', '44')

Each of these loads the rest of Phony.

Memory usage can be checked using (look for Total retained):
ruby -e 'require "memory_profiler"; MemoryProfiler.report(allow_files: "phony"){ require "phony/config"; Phony::Config.load("1") }.pretty_print'
For example, when just loading the NANP CC, the retained memory usage is ~63kB.

List of Handled Countries

Mildly unmaintained list: Abhas, Afghan, Algerian, Argentina, Austrian, Australian, Azerbaijani, Belgian, Brazilian, Cambodian, Chilean, Chinese, Croatian, Cuban, Cypriot, Czech, Danish, Dutch, Egyptian, El Salvadorian, Estonian, French, German, Ghanan, Gibraltar, Greek, Haiti, Hong Kong, Hungarian, Indian, Iran, Irish, Israel, Italian, Japanese, Kazakh, Liberian, Lithuanian, Luxembourgian, Malaysian, Malta, Mauritian, Mexican, Monaco, Morocco, New Zealand, Nigerian, Norwegian, Peruvian, Polish, Romanian, Russian, Rwandan, Seychelles, Singapore, Slovakian, South African, South Korean, South Osetian, Spanish, Sri Lankan, Sudan, Swedish, Swiss, Thailand, Tunisian, Turkish, Liechtenstein, UK, US, Venezuelan, Vietnamese, and Zambian numbers.

Proud Sponsors

License

MIT.
See LICENSE file.

phony's People

Contributors

andi avatar baxter avatar bibendi avatar dwilkie avatar eduardofiorezi avatar emily avatar floere avatar francesmcmullin avatar franckverrot avatar g1smd avatar gerard76 avatar hsgfan avatar htech9 avatar jcfischer avatar jip1080 avatar kbingman avatar marcboquet avatar marshall-lee avatar mrchucho avatar nabetaro avatar pmor avatar samda avatar sconstantinides avatar sergeydgr8 avatar slike9 avatar toxix avatar tpena avatar uelb avatar weppos avatar yoshih avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

phony's Issues

Countries with none splitter are not plausible?

I'm having issues validating (plausiblating?? haha) number for countries such as Denmark

Phony.plausible?('45 44 11 22 33') # => false

It is weird (I would expect it to return true) because I can see the country definition in the countries.rb file. And it also matches what wikipedia says

I tried the same thing with with others using the none matcher like Liechtenstein and those don't work either.

Ideas?

Thanks!

format vs formatted

Why not just Phony.format() instead of Phone.formatted()?

BTW, love the "Brrringggg! " at the bottom of the webpage :-)

Move lib/countries.rb to phony/

Just a project organization issue. Technically it's not good to put a file directly under lib that doesn't share the name of your project. So specifically in Phony's case, the countries.rb file should be moved to the phony/ directory. The reason being, if someone else wanted to create a project called countries then there would be a naming conflict.

Normalize drops 0 from middle of number

# Phony 1.8.4
> Phony.normalize('3109999999')
=> "319999999"
> Phony.normalize('13109999999')
=> "13109999999"

Not sure why the number is being dropped in the former case. The plausible? method returns true for both (whether or not country code is specified), but there's no way to specify country code to normalize in an attempt to fix this.

Thoughts? Thanks!

Leave initial zero when normalizing in some cases

Calls to Italy do not remove the initial zero on area codes (zero denotes a geographic landine area code), as is done in most countries, e.g. Switzerland:
Phony.normalize('+41 (044) 364 35 33').should == '41443643533'
(Removes the 0 in the 044 area code (Kanton Zürich)).

Phony.normalize would remove the zero even for Italy. Thus: Rework the normalizer to be country specific. Normalizing up to and including the country code, then deferring the rest of the number to the country handler.

Like that, Italy can normalize without removing the initial zero.

can I use on Rails 2.3.8?

I tried installing this and it said it needed activesupport >3.0?

Is there a way to work in my Rails 2.3.x installation, it's exactly what I need

Argentina phone number formatting is quite broken

I'd implement this fix myself, but don't truly understand enough about how the gem works to make the changes.

Right now, we format all Argentina numbers as +54 xx xxx xxx. They should be formatted as:

A) Local numbers. Many area codes, 2-4 digits. Different area codes result in the remainder of the number being formatted differently.

+54 11 1234 5678
+54 291 123 4567
+54 2965 12 3456

B) Mobile numbers. Follows above convention, but "9" is prepended to all numbers.

+54 9 11 1234 5678
+54 9 220 123 3457
+54 9 2221 12 3455

Full of list of area codes, as scraped from http://www.cnc.gov.ar/infotecnica/numeracion/indicativosinter.asp?offset=0 (using http://sak.to/0612291C3x1U1S0B1g0G):

11, 220, 2202, 221, 2221, 2223, 2224, 2225, 2226, 2227, 2229, 223, 2241, 2242, 2243, 2244, 2245, 2246, 2252, 2254, 2255, 2257, 2261, 2262, 2264, 2265, 2266, 2271, 2272, 2273, 2274, 2281, 2283, 2284, 2285, 2286, 2291, 2292, 2293, 2314, 2316, 2317, 2320, 2322, 2323, 2324, 2325, 2326, 2337, 2342, 2343, 2344, 2345, 2346, 2352, 2353, 2354, 2355, 2356, 2357, 2358, 2268, 2296, 2297, 2362, 2267, 237, 2392, 2393, 2394, 2395, 2396, 2473, 2474, 2475, 2477, 2478, 291, 2921, 2922, 2923, 2924, 2925, 2926, 2927, 2928, 2929, 2932, 2933, 2935, 2936, 2982, 2983, 3327, 3329, 3382, 3388, 3407, 3461, 3487, 3488, 3489, 3832, 3833, 3835, 3837, 3838, 3711, 3715, 3721, 3722, 3725, 3731, 3732, 3734, 3735, 3877, 297, 2965, 2945, 2903, 3385, 3387, 2336, 3472, 3463, 3467, 3468, 351, 3521, 3522, 3524, 3525, 353, 3532, 3533, 3534, 3541, 3542, 3543, 3544, 3546, 3547, 3548, 3549, 3562, 3563, 3564, 3571, 3572, 3573, 3574, 3575, 3576, 358, 3582, 3583, 3585, 3584, 3756, 3772, 3773, 3774, 3775, 3777, 3781, 3782, 3783, 3786, 345, 3454, 3455, 3456, 3458, 343, 3435, 3436, 3437, 3438, 3442, 3444, 3445, 3446, 3447, 3716, 3718, 3717, 388, 3884, 3885, 3886, 3887, 2941, 2338, 2333, 2334, 2335, 2331, 2302, 2952, 2953, 2954, 3821, 3822, 3825, 3826, 3827, 261, 2622, 2623, 2624, 2625, 2626, 2627, 3741, 3743, 3758, 3757, 3755, 3754, 3751, 3752, 2942, 2948, 299, 2972, 2944, 2946, 2940, 2934, 2931, 2920, 3878, 3876, 3868, 387, 3875, 264, 2646, 2647, 2648, 2651, 2652, 2658, 2655, 2656, 2657, 2902, 2962, 2963, 2966, 342, 3408, 3406, 3409, 341, 3400, 3401, 3402, 3404, 3405, 3462, 3460, 3469, 3471, 3464, 3465, 3466, 3476, 3482, 3483, 3491, 3492, 3493, 3498, 3496, 3497, 3857, 3858, 3861, 3844, 3845, 3846, 385, 3854, 3855, 3856, 3841, 3843, 2964, 2901, 381, 3862, 3863, 3865, 3867, 3869, 3894, 3891, 3892

Make number formatting more forgiving so that a number is displayed

If phony incorrectly detects a wrong prefix, then e.g. formats it using split(3,3), instead of e.g. split(4,4) it will format it incorrectly.

However, much worse, it will lose 2 digits. This will usually only be detected at (phone) call time, with very bad results.

I suggest making the split method more forgiving. Hackish way: Adding X to the last number passed in, where X is an arbitrary number, e.g. 5.

Ruby 1.8 compatibility

Expression ['1', *('3200'..'3209').to_a, 1] is not compatible with Ruby 1.8 (invalid syntax, due to 1.8 parsing restrictions). (see /lib/phony/countries/italy.rb)

Cheers,
Gleb

Phony format() throws error if area code is invalid

Steps to reproduce

This example shows an Irish phone number...
Phony.plausible?('353345435') # => true
Phony.format('353345435', :format => :national)

Error

NoMethodError Exception: You have a nil object when you didn't expect it!
You might have expected an instance of Array.
The error occurred while evaluating nil.empty?

Workaround

You can get the national version of the number from the international number using ...
Phony.format('353345435').split(' ')[1..-1]

Normalizing given a country hint?

In some countries phone numbers are prefixed with a 0 and provide no country code. I'd like a way, given a ISO-3166 2-letter country code as a hint, to have the numeric E164 country code prepended and the 0 removed.

Is there any way to do this right now with phony? If not, any thoughts on how to go about doing it?

Thanks!

Sincerely,
Anthony Eden

Germany: Does not recognize 5-digit NDC's

NDC's with 5 digits are not recognized. Example:

it "should handle Geithain" do
  Phony.split('493434144602').should == ['49', '34341', '446', '02']
end

Wrong result: ['49', '3434', '144', '602']

Hm, found this comment in https://github.com/floere/phony/blob/master/lib/phony/countries/germany.rb:

#  Note: Germany uses a variable ndc format from length 2 to 5.
#       To save space, we only use ndcs up to length 4.

Maybe you wannt to use the data from a similar (but more simple) gem created by me:
https://github.com/ledermann/dialy/blob/master/lib/dialy/data/de.rb

In my gem I have included all NDC's (not only 2 to 4), so a validation check is possible, too.

Errors and weird results on bad input

Phony.normalize('3')
NoMethodError: undefined method `normalize' for 1:Fixnum

Phony.normalize('ewrg')
NoMethodError: undefined method `normalize' for 1:Fixnum

 Phony.normalize('1ewrg')
 => "1[#<Phony::NationalCode:0x007fbb06bfdab0 @national_splitter=#<Phony::NationalSplitters::Fixed:0x007fbb06bfdb00 @size=3, @zero=nil>, @local_splitter=#<Phony::LocalSplitters::Fixed:0x007fbb06cde470 @format=[3, 14]>, @normalize=true>]" 

Perhaps it should throw its own error class, or simply return the input back again

Estonia numbers

There is no phone check for Estonia.

Estonian code is 372
mobile's regexp is ^(5|81|82), others are fixed. We have number portability this means, that we cannot separate numbers by region.
Finally, as we are located in European Union, then 112 and 110 are the numbers if something happens to you

new DSL clashes with Machinist in tests

We have a Machinist blueprint that reads:

Address.blueprint do
  address_1 { Faker::Address.street_address }
  ...
  country { %w{ DE FR IT AT }.rand }
  state { "new" }
end

The line with "country" clashes with Phony's own country DSL. Not sure who is to blame though :)

Phony.format truncates numbers from unsupported countries

Given a number from an "unsupported" country like Bangladesh, Phony will drop digits when calling format.

Phony.normalize("+8801552405452")
=> "8801552405452"

Phony.format("8801552405452") # the normalized number
=> "+880 15 524 05 45" # Note the missing 2

Identifying an unsupported country

Is it possible to identify unsupported countries, so that I could use Phony-based validations for those that are supported and fall back to some basic validations for those that are not?

Italy phone numbers with 2 digit NDCs will not format correctly

A number like "390612345678" will not format correctly. The last digit will be dropped and the formatted number will end up looking like this: "+39 06 123 4567"

The problem is in the last handler defined in phony/countries/italy.rb. The local splitter there will split the number into three digits and then four, dropping off the last digit. This works just fine for 3 or more digit NDCs obviously. :)

Phony.normalize('020') returns 'weird' string

Phony.normalize('020')
 => "20[#<Phony::NationalCode:0x007f92abd88c28 @national_splitter=#<Phony::NationalSplitters::Variable:0x007f92abd88db8 @size=nil, @zero=\"0\", @mapped_ndc_min_length=3, @mapped_ndc_max_length=3, @ndcs={3=>[\"800\"]}>, @local_splitter=#<Phony::LocalSplitters::Fixed:0x007f92abd88c50 @format=[17]>, @normalize=true>, #<Phony::NationalCode:0x007f92abd889a8 @national_splitter=#<Phony::NationalSplitters::Variable:0x007f92abd88b10 @size=nil, @zero=\"0\", @mapped_ndc_min_length=1, @mapped_ndc_max_length=1, @ndcs={1=>[\"2\", \"3\"]}>, @local_splitter=#<Phony::LocalSplitters::Fixed:0x007f92ac2e7e58 @format=[18]>, @normalize=true>, #<Phony::NationalCode:0x007f92abd88890 @national_splitter=#<Phony::NationalSplitters::Fixed:0x007f92abcea960 @size=2, @zero=\"0\">, @local_splitter=#<Phony::LocalSplitters::Fixed:0x007f92ac2e7e58 @format=[18]>, @normalize=true>]"

Phony.formatted("7209175276") returns undefined method `size'

Hi,

I'm using the Fabrication gem (http://rubygems.org/gems/fabrication) in combination with the Faker gem (http://rubygems.org/gems/faker) to generate test data for a project I'm working on currently which looks something like this..

Fabricator(:phone_number) do
  phone_number { Faker::PhoneNumber.phone_number }
end

Thru this I landed on the phone number "7209175276" which returns an error. I repeated the same process on the console and got the same error

1.9.3p194 :001 > include Phony
 => Object 
1.9.3p194 :002 > Phony.formatted("7209175276")
NoMethodError: undefined method `size' for nil:NilClass
    from /Users/imoss/.rvm/gems/ruby-1.9.3-p194@admissions/gems/phony-1.7.6/lib/phony/national_splitters/regex.rb:38:in `split'
    from /Users/imoss/.rvm/gems/ruby-1.9.3-p194@admissions/gems/phony-1.7.6/lib/phony/national_code.rb:19:in `split'
    from /Users/imoss/.rvm/gems/ruby-1.9.3-p194@admissions/gems/phony-1.7.6/lib/phony/country.rb:30:in `block in split'
    from /Users/imoss/.rvm/gems/ruby-1.9.3-p194@admissions/gems/phony-1.7.6/lib/phony/country.rb:29:in `each'
    from /Users/imoss/.rvm/gems/ruby-1.9.3-p194@admissions/gems/phony-1.7.6/lib/phony/country.rb:29:in `split'
    from /Users/imoss/.rvm/gems/ruby-1.9.3-p194@admissions/gems/phony-1.7.6/lib/phony/country_codes.rb:44:in `split'
    from /Users/imoss/.rvm/gems/ruby-1.9.3-p194@admissions/gems/phony-1.7.6/lib/phony/country_codes.rb:48:in `formatted'
    from /Users/imoss/.rvm/gems/ruby-1.9.3-p194@admissions/gems/phony-1.7.6/lib/phony.rb:79:in `format!'
    from /Users/imoss/.rvm/gems/ruby-1.9.3-p194@admissions/gems/phony-1.7.6/lib/phony.rb:76:in `format'
    from (irb):2
    from /Users/imoss/.rvm/gems/ruby-1.9.3-p194@admissions/gems/railties-3.2.3/lib/rails/commands/console.rb:47:in `start'
    from /Users/imoss/.rvm/gems/ruby-1.9.3-p194@admissions/gems/railties-3.2.3/lib/rails/commands/console.rb:8:in `start'
    from /Users/imoss/.rvm/gems/ruby-1.9.3-p194@admissions/gems/railties-3.2.3/lib/rails/commands.rb:41:in `<top (required)>'
    from script/rails:6:in `require'
    from script/rails:6:in `<main>'

I'm not sure if this phone number is valid or not (some googling suggested that it is not) but I would suggest that it if it is not valid it should return some more useful error, or better yet just the string that was passed in.

German number are split incorrectly

German service numbers, with the 180 or 181 prefix are incorrectly split:
+49 180 587 8323 should have have 180 as the second block, but splits like this:
["49", "1805", "878", "323"]

Phony.formatted crashing if number starts with '+'

Actual behaviour:
When the string starts with "+" (e.g. "+14152339111") Phony.formatted crashes hard, giving the backtrace below

Expected behaviour:
Phony.formatted('+14152339111', space: '') returns '+14152339111' without crashing

irb(main):001:0> Phony.formatted('+14152339110', space: '')
NoMethodError: undefined method `split' for 1:Fixnum
        from C:/Ruby193/lib/ruby/gems/1.9.1/gems/phony-1.9.0/lib/phony/country_codes.rb:44:in `split'
        from C:/Ruby193/lib/ruby/gems/1.9.1/gems/phony-1.9.0/lib/phony/country_codes.rb:48:in `formatted'
        from C:/Ruby193/lib/ruby/gems/1.9.1/gems/phony-1.9.0/lib/phony.rb:80:in `format!'
        from C:/Ruby193/lib/ruby/gems/1.9.1/gems/phony-1.9.0/lib/phony.rb:77:in `format'
        from (irb):1
        from C:/Ruby193/lib/ruby/gems/1.9.1/gems/railties-3.2.12/lib/rails/commands/console.rb:47:in `start'
        from C:/Ruby193/lib/ruby/gems/1.9.1/gems/railties-3.2.12/lib/rails/commands/console.rb:8:in `start'
        from C:/Ruby193/lib/ruby/gems/1.9.1/gems/railties-3.2.12/lib/rails/commands.rb:41:in `<top (required)>'
        from script/rails:6:in `require'
        from script/rails:6:in `<main>'

Normalize bugs

1.9.3p125 :020 > Phony.plausible?("010")
=> true
1.9.3p125 :021 > Phony.normalize("010")
=> "1[#<Phony::NationalCode:0x007ffc2efc53a0 @national_splitter=#<Phony::NationalSplitters::Fixed:0x007ffc2efc53f0 @SiZe=3, @zero=nil>, @local_splitter=#<Phony::LocalSplitters::Fixed:0x007ffc2d5d3d70 @Format=[3, 14]>, @normalize=true>]"

1.9.3p125 :022 > Phony.plausible?("+460000")
=> true
1.9.3p125 :023 > Phony.normalize("+460000")
=> "46[#<Phony::NationalCode:0x007ffc2efe2f40 @national_splitter=#<Phony::NationalSplitters::Variable:0x007ffc2efe3120 @SiZe=nil, @zero="0", @mapped_ndc_min_length=2, @mapped_ndc_max_length=5, @ndcs={2=>["99"], 3=>["112", "116", "118", "900", "939", "944"], 4=>["1177"], 5=>["11414"]}>, @local_splitter=#<Phony::LocalSplitters::Fixed:0x007ffc2e97f338 @Format=[3, 13]>, @normalize=true>, #<Phony::NationalCode:0x007ffc2efe2cc0 @national_splitter=#<Phony::NationalSplitters::Variable:0x007ffc2efe2e50 @SiZe=3, @zero="0", @mapped_ndc_min_length=1, @mapped_ndc_max_length=2, @ndcs={1=>["7", "8"], 2=>["10", "11", "13", "16", "18", "19", "20", "21", "23", "26", "31", "33", "35", "36", "40", "42", "44", "46", "54", "60", "63", "90", "70", "71", "72", "73", "74", "76"]}>, @local_splitter=#<Phony::LocalSplitters::Fixed:0x007ffc2d3a6bb0 @Format=[18]>, @normalize=true>]"

Exception: undefined method `normalize' for 1:Fixnum with Phony.normalize "000000"

(rdb:1) e  Phony.normalize "00000001"
"1[#<Phony::NationalCode:0x007fff332edfd0 @national_splitter=#<Phony::NationalSplitters::Fixed:0x007fff332ee020 @size=3>, @local_splitter=#<Phony::LocalSplitters::Fixed:0x007fff3335a298 @format=[3, 14]>, @normalize=true>]"

(rdb:1) e  Phony.normalize "00000000"
NoMethodError Exception: undefined method `normalize' for 1:Fixnum

(rdb:1) e  Phony.normalize "0"
NoMethodError Exception: undefined method `normalize' for 1:Fixnum

(rdb:1) e  Phony.normalize "1"
"1[#<Phony::NationalCode:0x007fff332edfd0 @national_splitter=#<Phony::NationalSplitters::Fixed:0x007fff332ee020 @size=3>, @local_splitter=#<Phony::LocalSplitters::Fixed:0x007fff3335a298 @format=[3, 14]>, @normalize=true>]"

Israel phone number format support

It would be great if there could be more support for Israel number formats. Would be interested in sponsoring the development of this if interested please contact me directly todd dot fisher at gmail dot com

Phony gets crazy, when phone number == nil

This is what I wanted to do in my model:

  def phone_number=(phone_number)
    write_attribute(:phone_number, Phony.normalize(phone_number))
  end

  def phone_number
    Phony.format(read_attribute(:phone_number))
  end

(I know, a representer/decorator would not be bad.)

This is my spec for this feature:

require 'spec_helper'

describe Phone do
  describe "phone number normalization and formation" do
    let(:person) {Fabricate.build(:person)}

    it "using %phone_number=" do
      person.phones = []
      person.phones << Phone.new
      person.phones.first.phone_number = "+491618674135"
      person.phones.first.phone_number.should eq("+49 161 867 4135")
      person.phones.first[:phone_number].should eq("491618674135")
    end

    it "using %attributes" do
      hash = {"phones_attributes"=>[{
                     "_id"=>person.phones.first.id,
                     "phone_number"=>"+491618674135"
                 }]}
      person.attributes = hash
      person.should be_valid
      person.phones.first.phone_number.should eq("+49 161 867 4135")
      person.phones.first[:phone_number].should eq("491618674135")
    end

    it "using %[]=" do
      person.phones.first[:phone_number] = "+491618674135"
      person.should be_valid
      person.phones.first.phone_number.should eq("+49 161 867 4135")
    end

    it "does not fail if phone_number is nil" do
      person.phones.first.phone_number = nil
      person.should be_valid
      person.phones.first.phone_number.should be_nil

      person.phones.first.phone_number = "+491618674135"

      person.phones.first[:phone_number] = nil
      person.should be_valid
      person.phones.first.phone_number.should be_nil
    end
  end
end

when I run this spec, I get the following error messages:

Phone
  phone number normalization and formation
    using %phone_number=
    using %attributes
    using %[]= (FAILED - 1)
    does not fail if phone_number is nil (FAILED - 2)

Failures:

  1) Phone phone number normalization and formation using %[]=
     Failure/Error: person.should be_valid
     NoMethodError:
       undefined method `split' for 1:Fixnum
     # ./app/models/phone.rb:45:in `phone_number'
     # ./spec/models/phone_spec.rb:33:in `block (3 levels) in <top (required)>'

  2) Phone phone number normalization and formation does not fail if phone_number is nil
     Failure/Error: person.phones.first.phone_number = nil
     TypeError:
       can't dup NilClass
     # ./app/models/phone.rb:41:in `phone_number='
     # ./spec/models/phone_spec.rb:38:in `block (3 levels) in <top (required)>'

Finished in 0.23927 seconds
4 examples, 2 failures

Failed examples:

rspec ./spec/models/phone_spec.rb:31 # Phone phone number normalization and formation using %[]=
rspec ./spec/models/phone_spec.rb:37 # Phone phone number normalization and formation does not fail if phone_number is nil

In the end, I came up with the following to get this spec running.

  def phone_number=(phone_number)
    value = Phony.normalize(phone_number) unless phone_number.nil?
    write_attribute(:phone_number, value)
  end

  def phone_number
    @phone_number_loop ||= 0
    Phony.format(read_attribute(:phone_number)) unless read_attribute(:phone_number).nil?
  rescue NoMethodError => error
    @phone_number_loop += 1
    self.phone_number = self[:phone_number]
    if @phone_number_loop == 1
      phone_number
    else
      raise error
    end
  end

It would be nice, if

  • Phony.normalize could handle nil
  • Phony.format could also handle nil
  • Phony.format would run a string through Phony.normalize when the string was not normalized before, instead of failing.
  • Phony would convert anything it gets to String before processing it to avoid failing when it is not necessary.

Thanks!

Tobias

Undefined method `split' for 1:Fixnum

Formatting a real italian number (Rome area)

Phony.formatted('+39 0639 751474', :format => :international)

Raises the following exception:

NoMethodError: undefined method `split' for 1:Fixnum
    from /home/gleb/phony/lib/phony/country_codes.rb:19:in `split'

issue parsing Denmark numbers?

Phony.split("4578775130")
=> ["45", false, "78", "77", "51", "30"]

Not sure if the false value in the return value from split is correct? Should that be a 0? or Is it an error to have a boolean instead of a string?

Thanks!

Phony.normalize should return a custom exception object when it can't parse a value

If you pass normalize a value it can't process, the following exception gets raised:

Phony.normalize('!') # => <NoMethodError: undefined method `normalize' for 1:Fixnum>

It seems like Phony should raise a more useful exception here that downstream code can reasonably deal with:

def normalize_phone_number(num)
  Phony.normalize(num)
rescue Phony::ParseError => ex
  errors.add(:base, "#{num} is not a valid number")
end

Happy to write a patch if you agree with this approach.

splitting leaves objects within split content

Example:

Phony.split(Phony.normalize("+972"))

->

["972", "[#<Phony::NationalCode:0x007ffafe4d9fa8 @national_splitter=#<Phony::NationalSplitters::None:0x007ffafe4be190>, @local_splitter=#<Phony::NationalSplitters::Default:0x007ffafe4c30c8>, @normalize=true>]"]

expected:

["972",nil,nil,nil]

the normalize method removes zeros if there are before

I am using the latest version 1.9.0
I tried to display this number 20000001 (the 20 is for country code and the rest is the phone number)
Phony.plausible? returns true
Phony.normalize returns 201 and if i try to display it like this

Phony.formatted(Phony.normalize("20000001"), :format => :interrnational) this returns +20 1
while
Phony.formatted("20000001", :format => :interrnational) returns +20 00 0001

I would expect that Phony.normalize to return 000001 instead of just 1. But please let me know if i am wrong and what would be the expected behaviour in this case.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.