Permalink
Browse files

+ Strategy Pattern for FixedSplitter to handle Special Services numbers

  • Loading branch information...
1 parent 96d156a commit 147ea5f874a29c15c611331de245b5d832a49751 @andi andi committed with Aug 20, 2009
Showing with 114 additions and 9 deletions.
  1. +1 −1 lib/e164.rb
  2. +1 −1 lib/ndc/austria.rb
  3. +82 −6 lib/ndc/fixed_size.rb
  4. +2 −1 lib/ndc/splitter.rb
  5. +28 −0 spec/lib/e164_spec.rb
View
@@ -48,7 +48,7 @@ def self.fixed national_code_length = 2, options = {}
'39' => fixed(3), # Italy
'40' => fixed(2), # Romania
- '41' => fixed(2, :local => [3, 2, 2]), # Switzerland (Confederation of)
+ '41' => fixed(2, :local => [3, 2, 2], :special_ndcs => ['800', '840', '842', '844', '848']), # Switzerland (Confederation of)
'43' => Austria,
'44' => fixed(2), # United Kingdom of Great Britain and Northern Ireland
'45' => fixed(2), # Denmark
View
@@ -7,7 +7,7 @@ class Austria < Prefix
length 1..4
local 10
- ndcs '1',# Wien
+ ndcs '1',# Wient
'57', # -
'59', # -
'67', # Mobile Services
View
@@ -5,33 +5,109 @@ module NDC
def self.fixed(national_code_length = 2, options = {})
klass = Class.new FixedSize
- klass.national_code_length = national_code_length
+ split_sizes, special_ndcs = klass.extract options
+ klass.special_ndc_strategy E164::NDC::SpecialNdcStrategy.new(national_code_length, special_ndcs)
+ klass.fixed_ndc_strategy E164::NDC::FixedNdcStrategy.new(national_code_length, split_sizes)
klass.format options[:format] || '%s %s %s'
- klass.local options[:local] || [3, 2, 2]
+ klass.local split_sizes
klass
end
class FixedSize < Splitter
- def self.national_code_length= length
- @national_code_length = length
+ def self.extract options
+ [options[:local] || [3, 2, 2], options[:special_ndcs] || []]
+ end
+
+ # Sets the strategy object to handle special services numbers
+ def self.special_ndc_strategy strategy
+ @special_ndc_strategy = strategy
+ end
+
+ # Sets the strategy object to handle normal numbers (non special services)
+ def self.fixed_ndc_strategy strategy
+ @fixed_ndc_strategy = strategy
+ @ndc_strategy = @fixed_ndc_strategy
+ end
+
+ # Returns true if the number is a special services number
+ def self.special_ndc? number
+ @special_ndc_strategy.special_ndc? number
end
# Define a format for the country's national format.
#
# Default is NN followed by a space.
#
def self.ndc_format
- @ndc_format || @ndc_format = '%s' + (@national_code_length == 0 ? '' : ' ')
+ @ndc_format || @ndc_format = @ndc_strategy.ndc_format
end
# A faster split method than the prefix splitter offers.
#
- def self.split_ndc(number)
+ def self.split_ndc number
number = number.dup
+ if special_ndc? number
+ @ndc_strategy = @special_ndc_strategy
+ else
+ @ndc_strategy = @fixed_ndc_strategy
+ end
+ @ndc_strategy.split_ndc number
+ end
+
+ def self.split_local number
+ @ndc_strategy.split_local number
+ end
+
+ end
+
+ # Base class for all Strategies
+ class NdcStrategy
+ attr_reader :split_sizes
+
+ def initialize national_code_length, split_sizes
+ @national_code_length = national_code_length
+ @split_sizes = split_sizes
+ end
+
+ def split_local number
+ local = []
+ split_sizes.each do |size|
+ local << number.slice!(0..size-1)
+ break if number.empty?
+ end
+ local
+ end
+
+ def ndc_format
+ '%s' + (@national_code_length == 0 ? '' : ' ')
+ end
+
+ end
+
+ class SpecialNdcStrategy < NdcStrategy
+ def initialize national_code_length, special_ndcs
+ super national_code_length, [2, 2, 2]
+ @special_ndcs = special_ndcs.flatten
+ @special_ndc_regexp = Regexp.compile "^(#{@special_ndcs.join('|')})"
+ end
+
+ def special_ndc? number
+ @special_ndcs && !@special_ndcs.empty? && @match = @special_ndc_regexp.match(number)
+ end
+
+ def split_ndc number
+ [number.slice!(0..@match[0].length-1), number]
+ end
+ end
+
+ class FixedNdcStrategy < NdcStrategy
+
+ def split_ndc number
@national_code_length.zero? ? ['', number] : [number.slice!(0..@national_code_length-1), number]
end
end
+
end
end
View
@@ -3,7 +3,7 @@
module E164
module NDC
class Splitter
-
+
# Sets the local grouping format.
#
# Examples
@@ -71,5 +71,6 @@ def self.locally_formatted number
end
end
+
end
end
View
@@ -13,6 +13,9 @@
it "should normalize a formatted number" do
E164.normalize('+41 44 364 35 33').should == '41443643533'
end
+ it "should normalize a special service number" do
+ E164.normalize('+41 800 11 22 33').should == '41800112233'
+ end
it "should remove characters from the number" do
E164.normalize('John: +41 44 364 35 33').should == '41443643533'
end
@@ -66,13 +69,23 @@
formatted_cc_ndc('41', '44', :international_relative).should == '0041 44 '
end
end
+ it "should return an internationally formatted cc-ndc combo (for special service number)" do
+ in_the E164 do
+ formatted_cc_ndc('41', '800', :international_absolute).should == '+41 800 '
+ end
+ end
end
describe "national" do
it "should return a nationally formatted cc-ndc combo" do
in_the E164 do
formatted_cc_ndc('41', '44', :national).should == '044 '
end
end
+ it "should return a nationally formatted cc-ndc combo (for special service number)" do
+ in_the E164 do
+ formatted_cc_ndc('41', '800', :national).should == '0800 '
+ end
+ end
end
describe "local" do
it "should return a locally formatted cc-ndc combo" do
@@ -105,6 +118,9 @@
it "should handle new zealand numbers" do
E164.split('6491234567').should == ['64', '9', '123', '4567']
end
+ it "should handle swiss special services numbers" do
+ E164.split('41800334455').should == ['41', '800', '33', '44', '55']
+ end
end
describe "split_cc" do
@@ -145,6 +161,9 @@
it "should handle swiss numbers" do
E164.split_cc('41443643532').should == ['41', '443643532']
end
+ it "should handle swiss special services numbers" do
+ E164.split_cc('41800223344').should == ['41', '800223344']
+ end
it "should handle US numbers" do
E164.split_cc('15551115511').should == ['1', '5551115511']
end
@@ -191,6 +210,9 @@
it "should handle swiss numbers" do
E164.split_cc_ndc('41443643532').should == ['41', '44', '3643532']
end
+ it "should handle swiss special services numbers" do
+ E164.split_cc_ndc('41800112233').should == ['41', '800', '112233']
+ end
it "should handle US numbers" do
E164.split_cc_ndc('15551115511').should == ['1', '555', '1115511']
end
@@ -204,6 +226,9 @@
it "should format swiss numbers" do
E164.formatted('41443643532').should == '+41 44 364 35 32'
end
+ it "should format swiss special services numbers" do
+ E164.formatted('41800112233').should == '+41 800 11 22 33'
+ end
it "should format austrian numbers" do
E164.formatted('43198110').should == '+43 1 98110'
end
@@ -235,6 +260,9 @@
it "should format swiss numbers" do
E164.formatted('41443643532', :format => :national).should == '044 364 35 32'
end
+ it "should format swiss special services numbers" do
+ E164.formatted('41800112233', :format => :national).should == '0800 11 22 33'
+ end
it "should format austrian numbers" do
E164.formatted('43198110', :format => :national).should == '01 98110'
end

0 comments on commit 147ea5f

Please sign in to comment.