mobme_support 2.2.2

Sign up to get free protection for your applications and to get access to all the features.
data/.autotest ADDED
@@ -0,0 +1,5 @@
1
+ require 'autotest/bundler'
2
+
3
+ Autotest.add_hook(:initialize) do |at|
4
+ at.add_exception %r{^./(.git|coverage)}
5
+ end
data/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ vendor/
2
+ .bundle/
3
+ coverage/
4
+ spec/reports
5
+ *.log
6
+ .yardoc
7
+ *.gem
8
+ Gemfile.lock
9
+ yardoc
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --profile
data/Gemfile ADDED
@@ -0,0 +1,14 @@
1
+ source :rubygems
2
+
3
+ gemspec
4
+
5
+ group :osx do
6
+ gem "growl"
7
+ gem 'rb-fsevent'
8
+ end
9
+
10
+ group :linux do
11
+ gem "rb-inotify"
12
+ gem "libnotify"
13
+ end
14
+
data/Guardfile ADDED
@@ -0,0 +1,7 @@
1
+
2
+ guard 'rspec', :version => 2 do
3
+ watch(%r{^spec/.+_spec\.rb$})
4
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
5
+ watch('spec/spec_helper.rb') { "spec" }
6
+ watch(%r{\.yml$}) { "spec" }
7
+ end
data/README.md ADDED
@@ -0,0 +1,12 @@
1
+ ## Description
2
+
3
+ MobME Support is a collection of classes and standard library extensions extracted from across MobME projects & for great good. Ala ActiveSupport!
4
+
5
+ ## Install
6
+
7
+ $ gem install mobme_support
8
+
9
+ ## Documentation
10
+
11
+ $ rake yardoc:generate
12
+ $ ls yardoc/
data/Rakefile ADDED
@@ -0,0 +1,32 @@
1
+ require 'rspec/core/rake_task'
2
+ require "rake/tasklib"
3
+ require "flog"
4
+ require 'yard'
5
+ require 'yard/rake/yardoc_task'
6
+
7
+ RSpec::Core::RakeTask.new(:spec)
8
+
9
+ task :default => :spec
10
+
11
+ desc "Analyze for code complexity"
12
+ task :flog do
13
+ flog = Flog.new
14
+ flog.flog [ "lib" ]
15
+ threshold = 10
16
+
17
+ bad_methods = flog.totals.select do | name, score |
18
+ name != "main#none" && score > threshold
19
+ end
20
+ bad_methods.sort do | a, b |
21
+ a[ 1 ] <=> b[ 1 ]
22
+ end.reverse.each do | name, score |
23
+ puts "%8.1f: %s" % [ score, name ]
24
+ end
25
+ unless bad_methods.empty?
26
+ raise "#{ bad_methods.size } methods have a flog complexity > #{ threshold }"
27
+ end
28
+ end
29
+
30
+ YARD::Rake::YardocTask.new(:yard) do |y|
31
+ y.options = ["--output-dir", "yardoc"]
32
+ end
data/TODO.md ADDED
@@ -0,0 +1,14 @@
1
+
2
+ ## TODO
3
+ * Finish all countries from Zone 9: http://en.wikipedia.org/wiki/List_of_country_calling_codes#Zone_9_.E2.80.93_Central.2C_South_and_Western_Asia
4
+
5
+ ## CHANGES
6
+
7
+ ### 20120224 (vishnu@mobme.in)
8
+ * MobMESupport, & not retaining older versions.
9
+
10
+ ### 20120122 (vishnu@mobme.in)
11
+ * Tweaks to cache YML data
12
+
13
+ ### Not Known (hari@mobme.in)
14
+ * Much work!
@@ -0,0 +1,40 @@
1
+ # Gems
2
+ require 'active_support/core_ext/hash/keys'
3
+
4
+ # Local
5
+ require_relative '../../version'
6
+
7
+ module MobME::Infrastructure::Utilities::CoreExtensions
8
+ # Hash extension, allowing recursive Hash key symbolization
9
+ module Keys
10
+ # Recursively symbolize all keys in the hash.
11
+ def recursively_symbolize_keys!(modify_nested_arrays = false)
12
+ case self
13
+ when Hash
14
+ symbolize_keys!
15
+
16
+ each do |key, value|
17
+ if value.is_a?(Hash) || (modify_nested_arrays && value.is_a?(Array))
18
+ self[key] = value.dup.recursively_symbolize_keys!(modify_nested_arrays)
19
+ end
20
+ end
21
+ when Array
22
+ each_with_index do |value, index|
23
+ self[index] = value.dup.recursively_symbolize_keys!(true) if (value.is_a?(Hash) || value.is_a?(Array))
24
+ end
25
+ end
26
+
27
+ self
28
+ end
29
+
30
+ alias_method :recursive_symbolize_keys!, :recursively_symbolize_keys!
31
+ end
32
+ end
33
+
34
+ class Hash
35
+ include MobME::Infrastructure::Utilities::CoreExtensions::Keys
36
+ end
37
+
38
+ class Array
39
+ include MobME::Infrastructure::Utilities::CoreExtensions::Keys
40
+ end
@@ -0,0 +1,2 @@
1
+ # Local
2
+ require_relative 'hash/keys'
@@ -0,0 +1,75 @@
1
+ # Standard
2
+ require 'yaml'
3
+
4
+ # Gems
5
+ require 'active_support/core_ext/hash/keys'
6
+ require 'active_support/core_ext/hash/reverse_merge'
7
+
8
+ # Local
9
+ require_relative '../../version'
10
+
11
+ module MobME::Infrastructure::Utilities::CoreExtensions
12
+ # String extension, which allows MSISDN validation.
13
+ module MSISDN
14
+
15
+ # Validates and converts an MSISDN in the string to the required format.
16
+ #
17
+ # @param [Hash] options_hash Options to pass into the function
18
+ # @option options_hash [String] :country ('IN') The ISO 3166 code for the MSISDN's country.
19
+ # @option options_hash [String] :format ('local') Either 'local', 'international', 'country', 'plus_country'.
20
+ # @return [String, nil] Validated MSISDN, or nil.
21
+ # @example Convert to an international format.
22
+ # "31234567".msisdn(:country => "BH", :format => 'international')
23
+ # "0097331234567"
24
+ # @example Convert to a 10 digit mobile number.
25
+ # "+919846819033".msisdn(:format => 'local')
26
+ # "9846819033"
27
+ def msisdn(options_hash = {})
28
+ default_options = {
29
+ :country => 'IN',
30
+ :format => 'local'
31
+ }
32
+
33
+ options_hash = options_hash.symbolize_keys.reverse_merge(default_options)
34
+
35
+ @@msdn_format_data ||= YAML.load_file(File.dirname(__FILE__) + "/msisdn_formats.yml")
36
+ msisdn_format = @@msdn_format_data[options_hash[:country]]
37
+
38
+ msisdn = self.strip
39
+ if msisdn.match(msisdn_format['regexp'])
40
+ local_segment = msisdn[-(msisdn_format['local_digits'])..-1]
41
+ case options_hash[:format]
42
+ when 'local'
43
+ local_segment
44
+ when 'country'
45
+ "#{msisdn_format['country_code']}#{local_segment}"
46
+ when 'plus_country'
47
+ "+#{msisdn_format['country_code']}#{local_segment}"
48
+ when "international"
49
+ "#{msisdn_format['international_prefix']}#{msisdn_format['country_code']}#{local_segment}"
50
+ end
51
+ else
52
+ nil
53
+ end
54
+ end
55
+
56
+ # Validates an MSISDN.
57
+ #
58
+ # @param [Hash] options_hash Options to pass into the function.
59
+ # @option options_hash [String] :country ('IN') The ISO 3166 code for the MSISDN's country.
60
+ # @return [Boolean] True if string is a valid MSISDN. False, otherwise.
61
+ # @example Validate an Indian MSISDN.
62
+ # "9846819033".msisdn?
63
+ # true
64
+ # @example Validate an non-Indian MSISDN.
65
+ # "+919846819033".msisdn?(:country => 'CA')
66
+ # false
67
+ def msisdn?(options_hash = {})
68
+ msisdn(options_hash) ? true : false
69
+ end
70
+ end
71
+ end
72
+
73
+ class String
74
+ include MobME::Infrastructure::Utilities::CoreExtensions::MSISDN
75
+ end
@@ -0,0 +1,41 @@
1
+ # ISO 3116 code:
2
+ # regexp: !ruby/regexp '/Regular expression to match phone numbers/'
3
+ # country_code: "International Country Code"
4
+ # local_digits: "Number of digits after country code"
5
+ # international_prefix: "International Prefix"
6
+
7
+ TR:
8
+ regexp: !ruby/regexp '/^(\+|00)?(90)?((2|3|4|5|8|9)[0-9]{10})$/'
9
+ country_code: "90"
10
+ local_digits: 10
11
+ international_prefix: "00"
12
+ IN:
13
+ regexp: !ruby/regexp '/^(\+|00)?(91)?((9|8|7)[0-9]{9})$/'
14
+ country_code: "91"
15
+ local_digits: 10
16
+ international_prefix: "00"
17
+ PK:
18
+ regexp: !ruby/regexp '/^(\+|00)?(91)?((3)[0-9]{8})$/'
19
+ country_code: "92"
20
+ local_digits: 8
21
+ international_prefix: "00"
22
+ AF:
23
+ regexp: !ruby/regexp '/^(\+|00)?(93)?((7)[0-9]{8})$/'
24
+ country_code: "92"
25
+ local_digits: 9
26
+ international_prefix: "00"
27
+ LK:
28
+ regexp: !ruby/regexp '/^(\+|00)?(94)?0?((7)[0-9]{8})$/'
29
+ country_code: "94"
30
+ local_digits: 10
31
+ international_prefix: "00"
32
+ BH:
33
+ regexp: !ruby/regexp '/^(\+|00)?(973)?((3|6)[0-9]{7})$/'
34
+ country_code: "973"
35
+ local_digits: 8
36
+ international_prefix: "00"
37
+ CA:
38
+ regexp: !ruby/regexp '/^(\+|011)?(1)?(([2-9][0-9]{2}){2}[0-9]{4})$/'
39
+ country_code: "1"
40
+ local_digits: 10
41
+ international_prefix: "011"
@@ -0,0 +1,90 @@
1
+ # Local
2
+ require_relative '../../version'
3
+
4
+ module MobME::Infrastructure::Utilities::CoreExtensions
5
+ # String extension, which allows URL validation
6
+ module URL
7
+ # Validates and converts a URL to standard format (if applicable)
8
+ #
9
+ # @return [String, nil] Validated MSISDN, or nil
10
+ # @example Validate a URL without scheme
11
+ # "google.com".url
12
+ # "http://google.com"
13
+ # @example Validate a URL with server IP
14
+ # "https://123.234.123.234/path/to/item".url
15
+ # "https://123.234.123.234/path/to/item"
16
+ # @example Validate a file:// URL
17
+ # "file:///absolute/path/to/file".url
18
+ # "file:///absolute/path/to/file"
19
+ # @example Validate a scp:// URL
20
+ # "scp://user@server:/path/to/resource".url
21
+ # "scp://user@server:/path/to/resource"
22
+ def url
23
+ possible_url = self.strip
24
+ reg = /^(http|https):\/\/[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}(:[0-9]{1,5})?(\/.*)?$/ix
25
+ first_match = reg.match(possible_url) ? possible_url : nil
26
+ unless first_match
27
+ reg = /^[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}(:[0-9]{1,5})?(\/.*)?$/ix
28
+ second_match = reg.match(possible_url) ? "http://" + possible_url : nil
29
+ unless second_match
30
+ reg = /^(http|https):\/\/[12]?[0-9]?[0-9]\.[12]?[0-9]?[0-9]\.[12]?[0-9]?[0-9]\.[12]?[0-9]?[0-9](\/.*)?$/ix
31
+ third_match = reg.match(possible_url) ? possible_url : nil
32
+ unless third_match
33
+ reg = /^[12]?[0-9]?[0-9]\.[12]?[0-9]?[0-9]\.[12]?[0-9]?[0-9]\.[12]?[0-9]?[0-9](\/.*)?$/ix
34
+ fourth_match = reg.match(possible_url) ? "http://" + possible_url : nil
35
+ unless fourth_match
36
+ reg = /^file:\/\/(\/[a-z0-9_-]+)*\/([a-z0-9_-]+)+(\.([a-z0-9]+)+)?$/ix
37
+ fifth_match = reg.match(possible_url) ? possible_url : nil
38
+ unless fifth_match
39
+ reg = /^scp:\/\/[a-z0-9_-]+@[a-z0-9_-]+:(\/[a-z0-9_-]+)*\/([a-z0-9_-]+)+(\.([a-z0-9]+)+)?$/ix
40
+ sixth_match = reg.match(possible_url) ? possible_url : nil
41
+ unless sixth_match
42
+ reg = /^scp:\/\/[a-z0-9_-]+@[12]?[0-9]?[0-9]\.[12]?[0-9]?[0-9]\.[12]?[0-9]?[0-9]\.[12]?[0-9]?[0-9]:(\/[a-z0-9_-]+)*\/([a-z0-9_-]+)+(\.([a-z0-9]+)+)?$/ix
43
+ seventh_match = reg.match(possible_url) ? possible_url : nil
44
+ unless seventh_match
45
+ reg = /^scp:\/\/[a-z0-9_-]+@[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}:(\/[a-z0-9_-]+)*\/([a-z0-9_-]+)+(\.([a-z0-9]+)+)?$/ix
46
+ reg.match(possible_url) ? possible_url : nil
47
+ else
48
+ seventh_match
49
+ end
50
+ else
51
+ sixth_match
52
+ end
53
+ else
54
+ fifth_match
55
+ end
56
+ else
57
+ fourth_match
58
+ end
59
+ else
60
+ third_match
61
+ end
62
+ else
63
+ second_match
64
+ end
65
+ else
66
+ first_match
67
+ end
68
+ end
69
+
70
+ # Validates a URL
71
+ #
72
+ # @return [Boolean] True if string is a valid URL. False, otherwise
73
+ # @example URL without scheme
74
+ # "google.com".url?
75
+ # true
76
+ # @example URL with invalid scheme
77
+ # "foobar://123.234.123.234/path/to/item".url
78
+ # false
79
+ # @example file:// path with invalid characters
80
+ # "file:///p@th/w!th/!nval!d/ch@r@cters".url
81
+ # false
82
+ def url?
83
+ url ? true : false
84
+ end
85
+ end
86
+ end
87
+
88
+ class String
89
+ include MobME::Infrastructure::Utilities::CoreExtensions::URL
90
+ end
@@ -0,0 +1,3 @@
1
+ # Local
2
+ require_relative 'string/msisdn'
3
+ require_relative 'string/url'
@@ -0,0 +1,3 @@
1
+ # Local
2
+ require_relative 'core_ext/hash'
3
+ require_relative 'core_ext/string'
@@ -0,0 +1,74 @@
1
+ require_relative '../version'
2
+ require_relative '../core_ext/hash/keys'
3
+ require 'active_support/core_ext/hash/reverse_merge'
4
+
5
+ module MobME::Infrastructure::Utilities::FileOperations
6
+ # Filters for MSISDN-s in files.
7
+ class MSISDNFilter
8
+ class << self
9
+
10
+ # Filters input file for valid MSISDN-s.
11
+ #
12
+ # @param [String] file_path Path to file containing line-separated MSISDN-s.
13
+ # @param [Hash] options_hash Options with which to evaluate MSISDN-s.
14
+ # @option options_hash [String] :country ('IN') The ISO 3166 code for the MSISDN's country.
15
+ # @option options_hash [String] :format ('local') Either 'local', 'international', 'country', 'plus_country'.
16
+ # @return [Array] Array of valid MSISDN-s in requested format.
17
+ # @example MSISDN filtration on a file.
18
+ # MobME::Infrastructure::Utilities::FileOperations::MSISDNFilter.filter('/absolute/path/to/file')
19
+ # >> ["9876543210", "9876543211", "9876543212", ... ]
20
+ # MobME::Infrastructure::Utilities::FileOperations::MSISDNFilter.filter('/absolute/path/to/file', :format => "plus_country")
21
+ # >> ["+919876543210", "+919876543211", "+919876543212", ... ]
22
+ def filter(file_path, options_hash={})
23
+ options_hash.recursively_symbolize_keys!
24
+ options_hash.reverse_merge!({
25
+ :country => "IN",
26
+ :format => "local"
27
+ })
28
+
29
+ input_file_contents = get_file_contents(file_path)
30
+ input_file_contents.scan(pattern(options_hash)).map do |match|
31
+ case options_hash[:format]
32
+ when "local"
33
+ match[2]
34
+ when "country"
35
+ settings[options_hash[:country]]['country_code'] + match[2]
36
+ when "plus_country"
37
+ "+#{settings[options_hash[:country]]['country_code']}#{match[2]}"
38
+ when "international"
39
+ settings[options_hash[:country]]['international_prefix'] + settings[options_hash[:country]]['country_code'] + match[2]
40
+ else
41
+ raise "Invalid :format value - must be one of 'local', 'country', 'plus_country', or 'international'."
42
+ end
43
+
44
+ end
45
+ end
46
+
47
+ private
48
+
49
+ # Retrieves contents of a file at specified path.
50
+ def get_file_contents(file_path)
51
+ input_file = File.open(file_path, 'r')
52
+ input_file_contents = input_file.read
53
+ input_file.close
54
+ input_file_contents
55
+ end
56
+
57
+ # Returns cached settings, if possible. Otherwise loads them from file.
58
+ def settings
59
+ return @settings_hash unless @settings_hash.nil?
60
+
61
+ settings_file = File.open(File.dirname(File.expand_path(__FILE__)) + "/../core_ext/string/msisdn_formats.yml", 'r')
62
+ settings_hash = YAML.load(settings_file)
63
+ settings_file.close
64
+ @settings_hash = settings_hash
65
+ settings_hash
66
+ end
67
+
68
+ # Returns regular expression for MSISDN in specified country.
69
+ def pattern(options_hash)
70
+ settings[options_hash[:country]]['regexp']
71
+ end
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,2 @@
1
+ # Local
2
+ require_relative 'file/msisdn_filter'
@@ -0,0 +1,21 @@
1
+ module MobME
2
+ module Infrastructure
3
+ # Collection of classes and standard library extensions extracted from across MobME projects, which serves to avoid re-writing often-used
4
+ # code.
5
+ module Utilities
6
+ # Version string.
7
+ VERSION = '2.2.2'
8
+
9
+ # Extensions to core Ruby classes.
10
+ module CoreExtensions
11
+ end
12
+
13
+ # Operations on files.
14
+ module FileOperations
15
+ end
16
+ end
17
+ end
18
+ end
19
+
20
+ # Alias it!
21
+ MobMESupport = MobME::Infrastructure::Utilities
@@ -0,0 +1 @@
1
+ require_relative "mobme/infrastructure/utilities"
@@ -0,0 +1,35 @@
1
+ lib = File.expand_path('../lib/', __FILE__)
2
+ $:.unshift lib unless $:.include?(lib)
3
+
4
+ require 'mobme_support/version'
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = "mobme_support"
8
+ s.version = MobME::Infrastructure::Utilities::VERSION
9
+ s.platform = Gem::Platform::RUBY
10
+ s.authors = ["MobME"]
11
+ s.email = ["engineering@mobme.in"]
12
+ s.homepage = "http://42.mobme.in/"
13
+ s.summary = %q{MobME Support are classes and standard library extensions shared across projects, brought under one roof.}
14
+ s.description = %q{MobME Support is a collection of classes and standard library extensions extracted from across MobME projects & for great good. Ala ActiveSupport!}
15
+
16
+ s.required_rubygems_version = ">= 1.3.6"
17
+
18
+ s.add_dependency "i18n"
19
+ s.add_dependency "activesupport"
20
+
21
+ s.add_development_dependency "rspec"
22
+ s.add_development_dependency "rake"
23
+ s.add_development_dependency "guard"
24
+ s.add_development_dependency "guard-rspec"
25
+ s.add_development_dependency "simplecov"
26
+ s.add_development_dependency "flog"
27
+ s.add_development_dependency "yard"
28
+ s.add_development_dependency "ci_reporter"
29
+ s.add_development_dependency "simplecov-rcov"
30
+ s.add_development_dependency "rdiscount"
31
+
32
+ s.files = `git ls-files`.split("\n") - ["Gemfile.lock", ".rvmrc"]
33
+ s.test_files = `git ls-files -- {spec}/*`.split("\n")
34
+ s.require_paths = ["lib"]
35
+ end
@@ -0,0 +1,64 @@
1
+ require 'spec_helper'
2
+
3
+ require 'mobme_support/core_ext/hash'
4
+
5
+ module MobMESupport::CoreExtensions
6
+ describe "Hash" do
7
+ subject { {"foo" => {"bar" => "baz"}, :already_symbol => "far", 123 => "faz"} }
8
+
9
+ describe "#recursively_symbolize_keys!" do
10
+ before(:each) { subject.recursively_symbolize_keys! }
11
+
12
+ it { should == {:foo => {:bar => "baz"}, :already_symbol => "far", 123 => "faz"} }
13
+
14
+ it "returns the recursively symbolized hash" do
15
+ {"foo" => "bar"}.recursively_symbolize_keys!.should == {:foo => "bar"}
16
+ end
17
+
18
+ context "when the modify_nested_arrays flag is set to true" do
19
+ it "recursively symbolizes nested Hashes if they are nested inside an Array" do
20
+ with_hash_inside_array = {"foo" => {"bar" => [{"baz" => [{"qux" => "qar"}, "string"]}]}}
21
+ with_hash_inside_array.recursively_symbolize_keys!(true)
22
+ with_hash_inside_array.should == {:foo => {:bar => [{:baz => [{:qux => "qar"}, "string"]}]}}
23
+ end
24
+ end
25
+
26
+ context "when the modify_nested_arrays flag is not set" do
27
+ it "does not recursively symbolize nested Hashes if they are nested inside an Array" do
28
+ with_hash_inside_array = {"foo" => {"bar" => [{"baz" => "qux"}]}}
29
+ with_hash_inside_array.recursively_symbolize_keys!
30
+ with_hash_inside_array.should == {:foo => {:bar => [{"baz" => "qux"}]}}
31
+ end
32
+ end
33
+
34
+ context "when a Hash or array contains other hashes or arrays" do
35
+ it "does not modify original hashes or arrays" do
36
+ sample_array = [{"foo" => "bar"}]
37
+ sample_hash = {"far" => "bar"}
38
+ hash_to_symbolize = {"array" => sample_array, "hash" => sample_hash}
39
+
40
+ hash_to_symbolize.recursively_symbolize_keys!(true)
41
+
42
+ sample_array.should == [{"foo" => "bar"}]
43
+ sample_hash.should == {"far" => "bar"}
44
+ end
45
+ end
46
+ end
47
+
48
+ describe "#recursive_symbolize_keys!" do
49
+ it "is an alias for #recursively_symbolize_keys!" do
50
+ subject.method(:recursive_symbolize_keys!).should == subject.method(:recursively_symbolize_keys!)
51
+ end
52
+ end
53
+ end
54
+
55
+ describe "Array" do
56
+ describe "#recursively_symbolize_keys!" do
57
+ it "recursively symbolizes Hash values in the array" do
58
+ array_with_hash_values = [{"foo" => "bar"}, {"baz" => "qux"}]
59
+ array_with_hash_values.recursively_symbolize_keys!
60
+ array_with_hash_values.should == [{:foo => "bar"}, {:baz => "qux"}]
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,84 @@
1
+ require 'spec_helper'
2
+
3
+ require 'mobme_support/core_ext/string/msisdn'
4
+
5
+ module MobMESupport
6
+
7
+ describe 'MSISDN' do
8
+ subject { '9946759680' }
9
+
10
+ it { should respond_to(:msisdn).with(1).argument }
11
+ it { should respond_to(:msisdn?).with(1).argument }
12
+
13
+ describe "#msisdn" do
14
+
15
+ it "removes whitespace from self" do
16
+ msisdn_with_whitespace = ' 9846819066 '
17
+ msisdn_with_whitespace.msisdn.should == '9846819066'
18
+ end
19
+
20
+ context "when a valid MSISDN is passed" do
21
+ it "returns the MSISDN in 10-digit form" do
22
+ '9946759680'.msisdn.should == '9946759680'
23
+ '919946759680'.msisdn.should == '9946759680'
24
+ '+919946759680'.msisdn.should == '9946759680'
25
+ '00919946759680'.msisdn.should == '9946759680'
26
+ end
27
+ end
28
+
29
+ context "when an invalid MSISDN is passed" do
30
+ it "returns nil" do
31
+ '994675680'.msisdn.should == nil
32
+ '+00919946759680'.msisdn.should == nil
33
+ end
34
+ end
35
+
36
+ context "when a custom country is passed" do
37
+ it "returns the MSISDN in that country's local form" do
38
+ '33280686'.msisdn("country" => "BH").should == '33280686'
39
+ '97333280686'.msisdn(:country => "BH").should == '33280686'
40
+ '+97333280686'.msisdn(:country => "BH").should == '33280686'
41
+ '0097333280686'.msisdn(:country => "BH").should == '33280686'
42
+ end
43
+ end
44
+
45
+ context "when a custom format is passed" do
46
+ it "returns the MSISDN in the requested format" do
47
+ '9946759680'.msisdn(:format => "plus_country").should == '+919946759680'
48
+ '33280686'.msisdn("country" => "BH", "format" => "international").should == '0097333280686'
49
+ '0097333280686'.msisdn("country" => "BH", "format" => "country").should == '97333280686'
50
+ '919946759680'.msisdn(:format => 'local').should == '9946759680'
51
+ end
52
+ end
53
+ end
54
+
55
+ describe "#msisdn?" do
56
+ it "calls #msisdn" do
57
+ subject.should_receive(:msisdn)
58
+ subject.msisdn?
59
+ end
60
+
61
+ context "if #msisdn returns anything" do
62
+ it "returns true" do
63
+ subject.stub(:msisdn).and_return('9946759680')
64
+ subject.msisdn?.should == true
65
+ end
66
+ end
67
+
68
+ context "if #msisdn returns nothing" do
69
+ it "returns false" do
70
+ subject.stub(:msisdn).and_return(nil)
71
+ subject.msisdn?.should == false
72
+ end
73
+ end
74
+
75
+ context "when passed custom options" do
76
+ it "passes them onto msisdn" do
77
+ mock_options = double("Options Hash")
78
+ subject.should_receive(:msisdn).with(mock_options)
79
+ subject.msisdn?(mock_options)
80
+ end
81
+ end
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,64 @@
1
+ require 'spec_helper'
2
+
3
+ require 'mobme_support/core_ext/string/url'
4
+
5
+ module MobMESupport
6
+
7
+ describe 'URL' do
8
+ subject { 'http://www.google.com' }
9
+
10
+ it { should respond_to(:url) }
11
+ it { should respond_to(:url?) }
12
+
13
+ describe "#url" do
14
+ it "removes whitespace from self" do
15
+ " http://google.com ".url.should == "http://google.com"
16
+ end
17
+
18
+ context "when a valid URL is passed" do
19
+ it "returns a properly formatted URL" do
20
+ "google.com".url.should == "http://google.com"
21
+ "https://www.facebook.com".url.should == "https://www.facebook.com"
22
+ "127.0.0.12".url.should == "http://127.0.0.12"
23
+ "file:///home/mobme/test".url.should == "file:///home/mobme/test"
24
+ "scp://mobme@localhost:/home/mobme/test".url.should == "scp://mobme@localhost:/home/mobme/test"
25
+ "scp://mobme@127.0.0.1:/home/mobme/test".url.should == "scp://mobme@127.0.0.1:/home/mobme/test"
26
+ "scp://mobme@somewhere.ca:/home/mobme/test".url.should == "scp://mobme@somewhere.ca:/home/mobme/test"
27
+ end
28
+ end
29
+
30
+ context "when an invalid URL is passed" do
31
+ it "returns nil" do
32
+ "google.c".url.should == nil
33
+ "http//www.facebook.com".url.should == nil
34
+ "127.0.0.1234".url.should == nil
35
+ "file:/home/mobme/test".url.should == nil
36
+ "scp//mobme@localhost/test".url.should == nil
37
+ "scp://mobme:/test".url.should == nil
38
+ "scp://mobme@somewhere.c:/test".url.should == nil
39
+ "scp://mobme@somewhere.com:~/test".url.should == nil
40
+ end
41
+ end
42
+ end
43
+
44
+ describe "#url?" do
45
+ it "calls #url" do
46
+ subject.should_receive(:url)
47
+ subject.url?
48
+ end
49
+
50
+ context "if #url returns anything" do
51
+ it "returns true" do
52
+ subject.url?.should == true
53
+ end
54
+ end
55
+
56
+ context "if #url returns nil" do
57
+ it "returns false" do
58
+ subject.stub(:url).and_return(nil)
59
+ subject.url?.should == false
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,64 @@
1
+ require 'spec_helper'
2
+
3
+ require 'mobme_support/file/msisdn_filter'
4
+
5
+ module MobMESupport::FileOperations
6
+ describe "MSISDNFilter" do
7
+ subject { MSISDNFilter }
8
+
9
+ it { should respond_to(:filter).with(1).argument }
10
+ it { should respond_to(:filter).with(2).arguments }
11
+
12
+ describe ".filter" do
13
+ before :each do
14
+ MSISDNFilter.stub(:get_file_contents)
15
+ end
16
+
17
+ context "when passed valid path to a file" do
18
+ it "returns array of filtered numbers" do
19
+ MSISDNFilter.stub(:get_file_contents).and_return("9876543210\n+919876543210\n00919876543211\n876543210")
20
+ expected_output = ["9876543210", "9876543210", "9876543211"]
21
+ MSISDNFilter.filter("/a/file/that/doesnt/exist").should == expected_output
22
+ end
23
+
24
+ context "when custom country and format are specified" do
25
+ before :each do
26
+ MSISDNFilter.stub(:get_file_contents).and_return("36543210\n97336543211\n+97336543212\n876543210")
27
+ end
28
+
29
+ it "returns array of filtered numbers" do
30
+ expected_output_plus_country = ["+97336543210", "+97336543211", "+97336543212"]
31
+ expected_output_international = ["0097336543210", "0097336543211", "0097336543212"]
32
+ options = {
33
+ :country => "BH",
34
+ :format => "plus_country"
35
+ }
36
+ MSISDNFilter.filter("/a/file/that/doesnt/exist", options).should == expected_output_plus_country
37
+ options[:format] = "international"
38
+ MSISDNFilter.filter("/a/file/that/doesnt/exist", options).should == expected_output_international
39
+ end
40
+
41
+ context "when an invalid format is specified" do
42
+ it "raises an error" do
43
+ options = {
44
+ :country => "BH",
45
+ :format => "invalid_format"
46
+ }
47
+ expect {
48
+ MSISDNFilter.filter("/a/file/that/doesnt/exist", options)
49
+ }.to raise_error
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
55
+
56
+ describe ".get_file_contents" do
57
+ it "returns contents of file at specified path" do
58
+ mock_file_contents = double("File contents")
59
+ File.stub(:open).and_return(double(File, :read => mock_file_contents, :close => nil))
60
+ MSISDNFilter.send(:get_file_contents, "/path/to/non-existent/sample/file").should == mock_file_contents
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,8 @@
1
+ require "simplecov"
2
+ require "simplecov-rcov"
3
+
4
+ SimpleCov.formatter = SimpleCov::Formatter::RcovFormatter
5
+ SimpleCov.start do
6
+ add_filter "vendor"
7
+ add_filter "spec"
8
+ end if ENV["COVERAGE"]
metadata ADDED
@@ -0,0 +1,204 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mobme_support
3
+ version: !ruby/object:Gem::Version
4
+ version: 2.2.2
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - MobME
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-02-24 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: i18n
16
+ requirement: &70149437295620 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *70149437295620
25
+ - !ruby/object:Gem::Dependency
26
+ name: activesupport
27
+ requirement: &70149437295120 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *70149437295120
36
+ - !ruby/object:Gem::Dependency
37
+ name: rspec
38
+ requirement: &70149437294640 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *70149437294640
47
+ - !ruby/object:Gem::Dependency
48
+ name: rake
49
+ requirement: &70149437294200 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: *70149437294200
58
+ - !ruby/object:Gem::Dependency
59
+ name: guard
60
+ requirement: &70149437293720 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ type: :development
67
+ prerelease: false
68
+ version_requirements: *70149437293720
69
+ - !ruby/object:Gem::Dependency
70
+ name: guard-rspec
71
+ requirement: &70149437293280 !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ! '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: *70149437293280
80
+ - !ruby/object:Gem::Dependency
81
+ name: simplecov
82
+ requirement: &70149437292720 !ruby/object:Gem::Requirement
83
+ none: false
84
+ requirements:
85
+ - - ! '>='
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ type: :development
89
+ prerelease: false
90
+ version_requirements: *70149437292720
91
+ - !ruby/object:Gem::Dependency
92
+ name: flog
93
+ requirement: &70149437292060 !ruby/object:Gem::Requirement
94
+ none: false
95
+ requirements:
96
+ - - ! '>='
97
+ - !ruby/object:Gem::Version
98
+ version: '0'
99
+ type: :development
100
+ prerelease: false
101
+ version_requirements: *70149437292060
102
+ - !ruby/object:Gem::Dependency
103
+ name: yard
104
+ requirement: &70149437291540 !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ type: :development
111
+ prerelease: false
112
+ version_requirements: *70149437291540
113
+ - !ruby/object:Gem::Dependency
114
+ name: ci_reporter
115
+ requirement: &70149437290920 !ruby/object:Gem::Requirement
116
+ none: false
117
+ requirements:
118
+ - - ! '>='
119
+ - !ruby/object:Gem::Version
120
+ version: '0'
121
+ type: :development
122
+ prerelease: false
123
+ version_requirements: *70149437290920
124
+ - !ruby/object:Gem::Dependency
125
+ name: simplecov-rcov
126
+ requirement: &70149437290360 !ruby/object:Gem::Requirement
127
+ none: false
128
+ requirements:
129
+ - - ! '>='
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: *70149437290360
135
+ - !ruby/object:Gem::Dependency
136
+ name: rdiscount
137
+ requirement: &70149437289660 !ruby/object:Gem::Requirement
138
+ none: false
139
+ requirements:
140
+ - - ! '>='
141
+ - !ruby/object:Gem::Version
142
+ version: '0'
143
+ type: :development
144
+ prerelease: false
145
+ version_requirements: *70149437289660
146
+ description: MobME Support is a collection of classes and standard library extensions
147
+ extracted from across MobME projects & for great good. Ala ActiveSupport!
148
+ email:
149
+ - engineering@mobme.in
150
+ executables: []
151
+ extensions: []
152
+ extra_rdoc_files: []
153
+ files:
154
+ - .autotest
155
+ - .gitignore
156
+ - .rspec
157
+ - Gemfile
158
+ - Guardfile
159
+ - README.md
160
+ - Rakefile
161
+ - TODO.md
162
+ - lib/mobme_support.rb
163
+ - lib/mobme_support/core_ext.rb
164
+ - lib/mobme_support/core_ext/hash.rb
165
+ - lib/mobme_support/core_ext/hash/keys.rb
166
+ - lib/mobme_support/core_ext/string.rb
167
+ - lib/mobme_support/core_ext/string/msisdn.rb
168
+ - lib/mobme_support/core_ext/string/msisdn_formats.yml
169
+ - lib/mobme_support/core_ext/string/url.rb
170
+ - lib/mobme_support/file.rb
171
+ - lib/mobme_support/file/msisdn_filter.rb
172
+ - lib/mobme_support/version.rb
173
+ - mobme_support.gemspec
174
+ - spec/mobme/infrastructure/utilities/core_ext/hash/keys_spec.rb
175
+ - spec/mobme/infrastructure/utilities/core_ext/string/msisdn_spec.rb
176
+ - spec/mobme/infrastructure/utilities/core_ext/string/url_spec.rb
177
+ - spec/mobme/infrastructure/utilities/file/msisdn_filter_spec.rb
178
+ - spec/spec_helper.rb
179
+ homepage: http://42.mobme.in/
180
+ licenses: []
181
+ post_install_message:
182
+ rdoc_options: []
183
+ require_paths:
184
+ - lib
185
+ required_ruby_version: !ruby/object:Gem::Requirement
186
+ none: false
187
+ requirements:
188
+ - - ! '>='
189
+ - !ruby/object:Gem::Version
190
+ version: '0'
191
+ required_rubygems_version: !ruby/object:Gem::Requirement
192
+ none: false
193
+ requirements:
194
+ - - ! '>='
195
+ - !ruby/object:Gem::Version
196
+ version: 1.3.6
197
+ requirements: []
198
+ rubyforge_project:
199
+ rubygems_version: 1.8.10
200
+ signing_key:
201
+ specification_version: 3
202
+ summary: MobME Support are classes and standard library extensions shared across projects,
203
+ brought under one roof.
204
+ test_files: []