sms_validation 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: d771ba3b06bfaf38dd03b4422c54ca14904d0d0f
4
+ data.tar.gz: f81fa7011d95d86d6b2ea2a60d91a871b4461cea
5
+ SHA512:
6
+ metadata.gz: 55ef04ab2258fe6af54ace53155e4fc207617e4092a14995152cc72b8303beae6d6c920443917a7c383dd87991e743b8100ed948362060b2c5c273ae548a342b
7
+ data.tar.gz: 8fcd241178d77fbcc4af945307ff897a11f33313e4100e3f81137d71c9bc1a9ba59695d472965618edf91a546d0c2b1e6e3aa26e28e8ac0fa8391394560c3786
@@ -0,0 +1,14 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in sms_validation.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2015 Isaac Betesh
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,87 @@
1
+ # SmsValidation
2
+
3
+ This gem does not send SMS messages. It just makes sure the arguments are valid.
4
+
5
+ ## What are valid arguments for an SMS message?
6
+
7
+ - Phone number: 10 digits, does not begin with 0 or 1
8
+ - Message: Not longer than 160 characters.
9
+
10
+ ## What if my message is longer than 160 characters?
11
+
12
+ You have 3 choices:
13
+ - Truncate the message to the first 160 characters
14
+ - Split it into multiple messages
15
+ - Raise a SmsValidation::Sms::MessageTooLongError error
16
+
17
+ You can configure at any time using:
18
+
19
+ SmsValidation.configuration.on_message_too_long = :truncate # or :split or :raise_error
20
+
21
+ It defaults to :raise_error
22
+
23
+ ## Installation
24
+
25
+ Add this line to your application's Gemfile:
26
+
27
+ ```ruby
28
+ gem 'sms_validation'
29
+ ```
30
+
31
+ And then execute:
32
+
33
+ $ bundle
34
+
35
+ Or install it yourself as:
36
+
37
+ $ gem install sms_validation
38
+
39
+ ## Usage
40
+
41
+ ### Configuration
42
+
43
+ SmsValidation.configure do |config|
44
+ config.on_message_too_long = :truncate # or :split or :raise_error
45
+ config.logger = ::Logger.new(STDOUT) # Defaults to ::Rails.logger if ::Rails.logger is defined
46
+
47
+ # This DOES NOT change the log_level of the logger--use `config.logger.level = :debug` for that
48
+ # This DOES determine the log level at which messages should be logged.
49
+ # This provides a convenient way to toggle whether this gem should log without interfering with the log level of others processes sharing the logger.
50
+ # For instance, if you're using Rails, you probably don't want to set the log_level to DEBUG, because then ActiveRecord will log every query.
51
+ # But you may still want SmsValidation to log everything it does.
52
+ config.log_at :info
53
+
54
+ # OR you may want SmsValidation to log only when you're logging all other DEBUG messages.
55
+ config.log_at :debug
56
+ end
57
+
58
+ ### Validation
59
+
60
+ sms = SmsValidation::Sms.new(8889999999, "The quick brown fox jumps over the lazy dog")
61
+ puts sms.phone # => 8889999999
62
+ puts sms.message # => "The quick brown fox jumps over the lazy dog"
63
+
64
+ sms = SmsValidation::Sms.new(889999999, "The quick brown fox jumps over the lazy dog")
65
+ # => SmsValidation::Sms::InvalidPhoneNumberError: "Phone number must be ten digits"
66
+
67
+ SmsValidation.configuration.on_message_too_long = :split
68
+ sms = SmsValidation::Sms.new(8889999999, "The quick brown fox jumps over the lazy dog" * 4)
69
+ puts sms.phone # => 8889999999
70
+ puts sms.messages # => ["(MSG 1/2): The quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown ", "(MSG 2/2): fox jumps over the lazy dog"]
71
+
72
+ SmsValidation.configuration.on_message_too_long = :truncate
73
+ sms = SmsValidation::Sms.new(8889999999, "The quick brown fox jumps over the lazy dog" * 4)
74
+ puts sms.phone # => 8889999999
75
+ puts sms.message # => ["The quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown fox jumps over "]
76
+
77
+ SmsValidation.configuration.on_message_too_long = :raise_error
78
+ sms = SmsValidation::Sms.new(8889999999, "The quick brown fox jumps over the lazy dog" * 4)
79
+ # => SmsValidation::Sms::MessageTooLongError, "Message cannot be longer than 160 characters"
80
+
81
+ ## Contributing
82
+
83
+ 1. Fork it ( https://github.com/[my-github-username]/sms_validation/fork )
84
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
85
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
86
+ 4. Push to the branch (`git push origin my-new-feature`)
87
+ 5. Create a new Pull Request
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+
@@ -0,0 +1,5 @@
1
+ require "sms_validation/version"
2
+ require "sms_validation/sms"
3
+
4
+ module SmsValidation
5
+ end
@@ -0,0 +1,48 @@
1
+ module SmsValidation
2
+ class << self
3
+ def configuration
4
+ @configuration ||= Configuration.new
5
+ end
6
+
7
+ def configure
8
+ yield configuration
9
+ end
10
+ end
11
+
12
+ class Configuration
13
+ ON_MESSAGE_TOO_LONG_OPTIONS = [:truncate, :raise_error, :split]
14
+ LOG_LEVEL_OPTIONS = [:fatal, :error, :warn, :info, :debug]
15
+
16
+ attr_reader :logger, :log_level, :on_message_too_long
17
+ def initialize
18
+ @logger = Rails.logger if defined?(::Rails.logger)
19
+ @log_level = :debug
20
+ @on_message_too_long = :raise_error
21
+ end
22
+
23
+ def on_message_too_long=(action)
24
+ raise ArgumentError, "SmsValidation.configuration.on_message_too_long must be included in: #{options_string(ON_MESSAGE_TOO_LONG_OPTIONS)}. It cannot be \"#{action}\"" unless ON_MESSAGE_TOO_LONG_OPTIONS.include?(action)
25
+ @on_message_too_long = action
26
+ end
27
+
28
+ def log_at(level)
29
+ validate_logger(@logger, level)
30
+ @log_level = level
31
+ end
32
+
33
+ def logger=(_logger)
34
+ validate_logger(_logger, @log_level)
35
+ @logger = _logger
36
+ end
37
+
38
+ private
39
+ def validate_logger(_logger, level)
40
+ raise ArgumentError, "SmsValidation.configuration.log_at argument must be included in: #{options_string(LOG_LEVEL_OPTIONS)}. It cannot be \"#{level}\"" unless LOG_LEVEL_OPTIONS.include?(level)
41
+ raise ArgumentError, "SmsValidation.configuration.logger must respond to \"#{level}\"" if _logger && !_logger.respond_to?(level)
42
+ end
43
+
44
+ def options_string(array)
45
+ "[:#{array.join(", :")}]"
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,9 @@
1
+ require "sms_validation/configuration"
2
+
3
+ module SmsValidation
4
+ class << self
5
+ def log(*args, &block)
6
+ configuration.logger.__send__(configuration.log_level, *args, &block) if configuration.logger
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,61 @@
1
+ require "sms_validation/log"
2
+
3
+ module SmsValidation
4
+ class Sms
5
+ class InvalidPhoneNumberError < ::ArgumentError; end
6
+ class InvalidMessageError < ::ArgumentError; end
7
+ class MessageTooLongError < ::ArgumentError; end
8
+
9
+ MAX_LENGTH = 160
10
+ MAX_SECTION_LENGTH = MAX_LENGTH - "(MSG XXX/XXX): ".size
11
+ MESSAGE_WHEN_SPLIT_MESSAGE = "This message was split because it is too long to fit into a single SMS. Instead of #message, use #messages or change SmsValidation.configuration.on_message_too_long to something other than :split"
12
+
13
+ attr_reader :phone, :messages
14
+
15
+ def initialize(phone, message)
16
+ phone = phone.to_s
17
+ raise InvalidPhoneNumberError, "Phone number must be ten digits" unless /\A[0-9]{10}\z/.match(phone)
18
+ raise InvalidPhoneNumberError, "Phone number cannot begin with a \"#{phone[0]}\"" if ['0','1'].include?(phone[0].to_s)
19
+ raise InvalidMessageError, "Message cannot be blank" if message.empty?
20
+ SmsValidation.configuration.logger.warn { "WARNING: Some characters may be lost because the message must be broken into at least 1000 sections" } if message.size > (999 * MAX_SECTION_LENGTH)
21
+ @messages = (message.size > MAX_LENGTH) ? SmsValidation::Sms.__send__(SmsValidation.configuration.on_message_too_long, message) : [message.dup]
22
+ @phone = "1#{phone}"
23
+ end
24
+
25
+ def message
26
+ @message ||= begin
27
+ raise StandardError, MESSAGE_WHEN_SPLIT_MESSAGE unless 1 == messages.size
28
+ messages.first
29
+ end
30
+ end
31
+
32
+ class << self
33
+ def raise_error(message)
34
+ raise MessageTooLongError, "Message cannot be longer than #{MAX_LENGTH} characters"
35
+ end
36
+
37
+ def truncate(message)
38
+ truncated_message = message[0,MAX_LENGTH]
39
+ SmsValidation.log { "Truncating message due to length. Message was: \"#{message}\" but will now be \"#{truncated_message}\"" }
40
+ [truncated_message]
41
+ end
42
+
43
+ def section_counter(size)
44
+ size / MAX_SECTION_LENGTH + ((size % MAX_SECTION_LENGTH).zero? ? 0 : 1)
45
+ end
46
+
47
+ def split(message)
48
+ sections = section_counter(message.size)
49
+ SmsValidation.log { "Splitting message into #{sections} messages due to length." }
50
+ split_message = (sections - 1).times.collect do |i|
51
+ first_char = i * MAX_SECTION_LENGTH
52
+ SmsValidation.log { "Section ##{i + 1} of ##{sections} contains characters #{first_char + 1} thru #{first_char + MAX_SECTION_LENGTH} of #{message.size}" }
53
+ "(MSG #{i+1}/#{sections}): #{message[first_char, MAX_SECTION_LENGTH]}"
54
+ end
55
+ first_char = (sections-1)*MAX_SECTION_LENGTH
56
+ SmsValidation.log { "Section ##{sections} of ##{sections} contains characters #{first_char + 1} thru #{message.size} of #{message.size}" }
57
+ split_message << "(MSG #{sections}/#{sections}): #{message[first_char..-1]}"
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,3 @@
1
+ module SmsValidation
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,24 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'sms_validation/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "sms_validation"
8
+ spec.version = SmsValidation::VERSION
9
+ spec.authors = ["Isaac Betesh"]
10
+ spec.email = ["iybetesh@gmail.com"]
11
+ spec.description = "Validate the phone number and content of an SMS Message. This gem does not send SMS messages. It just makes sure the arguments are valid."
12
+ spec.summary = `cat README.md`
13
+ spec.homepage = "https://github.com/betesh/sms_validation/"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.7"
22
+ spec.add_development_dependency "rake", "~> 10.0"
23
+ spec.add_development_dependency "rspec"
24
+ end
@@ -0,0 +1,114 @@
1
+ require "sms_validation/configuration"
2
+ require "sms_validation/log"
3
+ require "logger"
4
+
5
+ describe SmsValidation::Configuration do
6
+ before(:each) do
7
+ SmsValidation.instance_variable_set("@configuration", nil)
8
+ end
9
+
10
+ describe "logger" do
11
+ let(:logger) { ::Logger.new('/dev/null') }
12
+
13
+ def it_should_not_log
14
+ text = "Some info"
15
+ described_class::LOG_LEVEL_OPTIONS.each do |log_level|
16
+ expect(logger).not_to receive(log_level)
17
+ end
18
+ expect{SmsValidation.log { text } }.to_not raise_error
19
+ end
20
+
21
+ def it_should_log_at(log_level)
22
+ text = "Some info"
23
+ expect(logger).to receive(log_level) do |&arg|
24
+ expect(arg.call).to eq(text)
25
+ end
26
+ expect{SmsValidation.log { text } }.to_not raise_error
27
+ end
28
+
29
+ def when_the_logger_is_configured
30
+ SmsValidation.configuration.logger = logger
31
+ end
32
+
33
+ [:fatal, :error, :warn, :info, :debug].each do |log_level|
34
+ describe "can log at #{log_level}" do
35
+ let(:log_level) { log_level }
36
+ it "should allow log level ':#{log_level}'" do
37
+ SmsValidation.configuration.log_at(log_level)
38
+ when_the_logger_is_configured
39
+ it_should_log_at(log_level)
40
+ end
41
+ end
42
+ end
43
+
44
+ it "should default to log level debug" do
45
+ when_the_logger_is_configured
46
+ it_should_log_at(:debug)
47
+ end
48
+
49
+ it "should default to Rails.logger when Rails.logger is defined" do
50
+ stub_const("Rails", double)
51
+ allow(Rails).to receive(:logger).and_return(logger)
52
+ it_should_log_at(:debug)
53
+ end
54
+
55
+ it "should not attempt to default to Rails.logger when Rails is defined but Rails.logger is defined" do
56
+ stub_const("Rails", double)
57
+ it_should_not_log
58
+ end
59
+
60
+ it "can be nil" do
61
+ SmsValidation.configuration.logger = nil
62
+ it_should_not_log
63
+ end
64
+
65
+ it "should not allow log level news and should remain in a valid state" do
66
+ expect{SmsValidation.configuration.log_at(:news)}.to raise_error(ArgumentError, "SmsValidation.configuration.log_at argument must be included in: [:fatal, :error, :warn, :info, :debug]. It cannot be \"news\"")
67
+ SmsValidation.configuration.logger = logger
68
+ it_should_log_at(:debug)
69
+ end
70
+
71
+ it "should not allow log level that the logger does not respond_to when the logger is created before log level is set and should remain in a valid state" do
72
+ SmsValidation.configuration.logger = logger
73
+ allow(logger).to receive(:respond_to?).with(:warn).and_return(false)
74
+ expect{SmsValidation.configuration.log_at(:warn)}.to raise_error(ArgumentError, "SmsValidation.configuration.logger must respond to \"warn\"")
75
+ it_should_log_at(:debug)
76
+ end
77
+
78
+ it "should not allow log level that the logger does not respond_to when the logger is created after log level is set and should remain in a valid state" do
79
+ allow(logger).to receive(:respond_to?).with(:warn).and_return(false)
80
+ SmsValidation.configuration.log_at(:warn)
81
+ expect{SmsValidation.configuration.logger = logger}.to raise_error(ArgumentError, "SmsValidation.configuration.logger must respond to \"warn\"")
82
+ it_should_not_log
83
+ end
84
+ end
85
+
86
+ describe "on_message_too_long" do
87
+ it "should default to :raise_error" do
88
+ expect(SmsValidation.configuration.on_message_too_long).to eq(:raise_error)
89
+ end
90
+
91
+ [:raise_error, :split, :truncate].each do |value|
92
+ describe value.to_s do
93
+ let(:value) { value }
94
+ it "should be an allowed value" do
95
+ expect{SmsValidation.configuration.on_message_too_long = value}.to_not raise_error
96
+ expect(SmsValidation.configuration.on_message_too_long).to eq(value)
97
+ end
98
+
99
+ it "should not allow other values and should remain in a valid state" do
100
+ SmsValidation.configuration.on_message_too_long = value
101
+ expect{SmsValidation.configuration.on_message_too_long = :do_nothing}.to raise_error(ArgumentError, "SmsValidation.configuration.on_message_too_long must be included in: [:truncate, :raise_error, :split]. It cannot be \"do_nothing\"")
102
+ expect(SmsValidation.configuration.on_message_too_long).to eq(value)
103
+ end
104
+ end
105
+ end
106
+ end
107
+
108
+ it "can yield" do
109
+ SmsValidation.configure do |config|
110
+ config.on_message_too_long = :split
111
+ end
112
+ expect(SmsValidation.configuration.on_message_too_long).to eq(:split)
113
+ end
114
+ end
@@ -0,0 +1,174 @@
1
+ require "sms_validation/sms"
2
+ require "sms_validation/log"
3
+ require "logger"
4
+
5
+ describe SmsValidation::Sms do
6
+ let(:phone_number_length) { 10 }
7
+ let(:phone_number) { "8" * phone_number_length }
8
+ let(:message) { "TEXT MESSAGE FROM ME TO YOU" }
9
+ let(:on_message_too_long) { :raise_error }
10
+
11
+ before(:each) do
12
+ SmsValidation.instance_variable_set("@configuration", nil)
13
+ SmsValidation.configure do |config|
14
+ config.log_at(:info)
15
+ config.logger = logger
16
+ config.on_message_too_long = on_message_too_long
17
+ end
18
+ end
19
+
20
+ def it_should_not_log
21
+ described_class::LOG_LEVEL_OPTIONS.each do |log_level|
22
+ expect(logger).not_to receive(log_level)
23
+ end
24
+ end
25
+
26
+ def it_should_log(text, options={})
27
+ expect(logger).to receive(options[:at] || :info) do |&arg|
28
+ expect(arg.call).to eq(text)
29
+ end
30
+ end
31
+
32
+ subject { described_class.new(phone_number, message) }
33
+
34
+ shared_examples_for :all_specs do
35
+ describe "phone number" do
36
+ describe "when 9 digits" do
37
+ let(:phone_number_length) { 9 }
38
+
39
+ it "should raise an error" do
40
+ expect{subject}.to raise_error(described_class::InvalidPhoneNumberError, "Phone number must be ten digits")
41
+ end
42
+ end
43
+
44
+ describe "when 11 digits" do
45
+ let(:phone_number_length) { 11 }
46
+
47
+ it "should raise an error" do
48
+ expect{subject}.to raise_error(described_class::InvalidPhoneNumberError, "Phone number must be ten digits")
49
+ end
50
+ end
51
+
52
+ describe "when it starts with a 0" do
53
+ let(:phone_number) { "0" + "8" * (phone_number_length - 1) }
54
+
55
+ it "should raise an error" do
56
+ expect{subject}.to raise_error(described_class::InvalidPhoneNumberError, "Phone number cannot begin with a \"0\"")
57
+ end
58
+ end
59
+
60
+ describe "when it starts with a 1" do
61
+ let(:phone_number) { "1" + "8" * (phone_number_length - 1) }
62
+
63
+ it "should raise an error" do
64
+ expect{subject}.to raise_error(described_class::InvalidPhoneNumberError, "Phone number cannot begin with a \"1\"")
65
+ end
66
+ end
67
+
68
+ it "should prepend a '1' and be safe from changes" do
69
+ expected_phone_number = "1#{phone_number}"
70
+ subject
71
+ phone_number[1..3] = ''
72
+ expect(subject.phone).to eq(expected_phone_number)
73
+ end
74
+ end
75
+
76
+ describe "message" do
77
+ describe "when blank" do
78
+ let(:message) { "" }
79
+
80
+ it "raises an error" do
81
+ expect{subject}.to raise_error(described_class::InvalidMessageError, "Message cannot be blank")
82
+ end
83
+ end
84
+
85
+ describe "when longer than 160 characters" do
86
+ describe "when on_message_too_long = :truncate" do
87
+ let(:on_message_too_long) { :truncate }
88
+ let(:message) { "A"+"ABCDEFGHIJ"*16 }
89
+
90
+ it "is truncated to the first 160 characters" do
91
+ expect(subject.message).to eq(message[0,160])
92
+ expect(subject.messages).to eq([message[0,160]])
93
+ end
94
+
95
+ it "should be safe from changing" do
96
+ expected_message = "#{message[0,160]}"
97
+ subject
98
+ message[1..3] = ''
99
+ expect(subject.message).to eq(expected_message)
100
+ expect(subject.messages).to eq([expected_message])
101
+ end
102
+ end
103
+
104
+ describe "when on_message_too_long = :raise_error" do
105
+ let(:on_message_too_long) { :raise_error }
106
+ let(:message) { "A"*161 }
107
+
108
+ it "raises an error" do
109
+ expect{subject}.to raise_error(described_class::MessageTooLongError, "Message cannot be longer than 160 characters")
110
+ end
111
+ end
112
+
113
+ describe "when on_message_too_long = :split" do
114
+ let(:on_message_too_long) { :split }
115
+
116
+ describe "when it's an even split" do
117
+ let(:message) { "ABCDEFGHIJ"*58 }
118
+
119
+ it "should be split into multiple messages" do
120
+ expect(subject.messages).to eq(["(MSG 1/4): #{message[0,145]}", "(MSG 2/4): #{message[145,145]}", "(MSG 3/4): #{message[290,145]}", "(MSG 4/4): #{message[435,145]}"])
121
+ expect{subject.message}.to raise_error(StandardError, "This message was split because it is too long to fit into a single SMS. Instead of #message, use #messages or change SmsValidation.configuration.on_message_too_long to something other than :split")
122
+ end
123
+ end
124
+
125
+ describe "when it's not an even split" do
126
+ let(:message) { "ABCDEFGHIJ"*32 }
127
+
128
+ it "should be split into multiple messages" do
129
+ expect(subject.messages).to eq(["(MSG 1/3): #{message[0,145]}", "(MSG 2/3): #{message[145,145]}", "(MSG 3/3): #{message[290..-1]}"])
130
+ expect{subject.message}.to raise_error(StandardError, "This message was split because it is too long to fit into a single SMS. Instead of #message, use #messages or change SmsValidation.configuration.on_message_too_long to something other than :split")
131
+ end
132
+
133
+ it "should be safe from changing" do
134
+ expected_messages = ["(MSG 1/3): #{message[0,145]}", "(MSG 2/3): #{message[145,145]}", "(MSG 3/3): #{message[290..-1]}"]
135
+ subject
136
+ message[1..3] = ''
137
+ expect(subject.messages).to eq(expected_messages)
138
+ end
139
+ end
140
+ end
141
+ end
142
+
143
+ [:raise_error, :split, :truncate].each do |value|
144
+ describe "when on_message_too_long = :#{value}" do
145
+ let(:on_message_too_long) { value }
146
+
147
+ it "should be safe from changing the message" do
148
+ expected_message = "#{message}"
149
+ subject
150
+ message[1..3] = ''
151
+ expect(subject.message).to eq(expected_message)
152
+ end
153
+
154
+ describe "when the initial message is 160 characters" do
155
+ let(:message) { "A"*160 }
156
+
157
+ it "does not change" do
158
+ expect(subject.message).to eq(message)
159
+ expect(subject.messages).to eq([message])
160
+ end
161
+ end
162
+ end
163
+ end
164
+ end
165
+ end
166
+
167
+ it_behaves_like :all_specs do
168
+ let(:logger) { ::Logger.new('/dev/null') }
169
+ end
170
+
171
+ it_behaves_like :all_specs do
172
+ let(:logger) { nil }
173
+ end
174
+ end
metadata ADDED
@@ -0,0 +1,141 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sms_validation
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Isaac Betesh
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-03-11 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.7'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.7'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description: Validate the phone number and content of an SMS Message. This gem does
56
+ not send SMS messages. It just makes sure the arguments are valid.
57
+ email:
58
+ - iybetesh@gmail.com
59
+ executables: []
60
+ extensions: []
61
+ extra_rdoc_files: []
62
+ files:
63
+ - ".gitignore"
64
+ - ".rspec"
65
+ - Gemfile
66
+ - LICENSE.txt
67
+ - README.md
68
+ - Rakefile
69
+ - lib/sms_validation.rb
70
+ - lib/sms_validation/configuration.rb
71
+ - lib/sms_validation/log.rb
72
+ - lib/sms_validation/sms.rb
73
+ - lib/sms_validation/version.rb
74
+ - sms_validation.gemspec
75
+ - spec/configuration_spec.rb
76
+ - spec/sms_spec.rb
77
+ homepage: https://github.com/betesh/sms_validation/
78
+ licenses:
79
+ - MIT
80
+ metadata: {}
81
+ post_install_message:
82
+ rdoc_options: []
83
+ require_paths:
84
+ - lib
85
+ required_ruby_version: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ required_rubygems_version: !ruby/object:Gem::Requirement
91
+ requirements:
92
+ - - ">="
93
+ - !ruby/object:Gem::Version
94
+ version: '0'
95
+ requirements: []
96
+ rubyforge_project:
97
+ rubygems_version: 2.4.3
98
+ signing_key:
99
+ specification_version: 4
100
+ summary: '# SmsValidation This gem does not send SMS messages. It just makes sure
101
+ the arguments are valid. ## What are valid arguments for an SMS message? - Phone
102
+ number: 10 digits, does not begin with 0 or 1 - Message: Not longer than 160 characters. ##
103
+ What if my message is longer than 160 characters? You have 3 choices: - Truncate
104
+ the message to the first 160 characters - Split it into multiple messages - Raise
105
+ a SmsValidation::Sms::MessageTooLongError error You can configure at any time using: SmsValidation.configuration.on_message_too_long
106
+ = :truncate # or :split or :raise_error It defaults to :raise_error ## Installation Add
107
+ this line to your application''s Gemfile: ```ruby gem ''sms_validation'' ``` And
108
+ then execute: $ bundle Or install it yourself as: $ gem install sms_validation ##
109
+ Usage ### Configuration SmsValidation.configure do |config| config.on_message_too_long
110
+ = :truncate # or :split or :raise_error config.logger = ::Logger.new(STDOUT) # Defaults
111
+ to ::Rails.logger if ::Rails.logger is defined # This DOES NOT change the log_level
112
+ of the logger--use `config.logger.level = :debug` for that # This DOES determine
113
+ the log level at which messages should be logged. # This provides a convenient way
114
+ to toggle whether this gem should log without interfering with the log level of
115
+ others processes sharing the logger. # For instance, if you''re using Rails, you
116
+ probably don''t want to set the log_level to DEBUG, because then ActiveRecord will
117
+ log every query. # But you may still want SmsValidation to log everything it does.
118
+ config.log_at :info # OR you may want SmsValidation to log only when you''re logging
119
+ all other DEBUG messages. config.log_at :debug end ### Validation sms = SmsValidation::Sms.new(8889999999,
120
+ "The quick brown fox jumps over the lazy dog") puts sms.phone # => 8889999999 puts
121
+ sms.message # => "The quick brown fox jumps over the lazy dog" sms = SmsValidation::Sms.new(889999999,
122
+ "The quick brown fox jumps over the lazy dog") # => SmsValidation::Sms::InvalidPhoneNumberError:
123
+ "Phone number must be ten digits" SmsValidation.configuration.on_message_too_long
124
+ = :split sms = SmsValidation::Sms.new(8889999999, "The quick brown fox jumps over
125
+ the lazy dog" * 4) puts sms.phone # => 8889999999 puts sms.messages # => ["(MSG
126
+ 1/2): The quick brown fox jumps over the lazy dogThe quick brown fox jumps over
127
+ the lazy dogThe quick brown fox jumps over the lazy dogThe quick brown ", "(MSG
128
+ 2/2): fox jumps over the lazy dog"] SmsValidation.configuration.on_message_too_long
129
+ = :truncate sms = SmsValidation::Sms.new(8889999999, "The quick brown fox jumps
130
+ over the lazy dog" * 4) puts sms.phone # => 8889999999 puts sms.message # => ["The
131
+ quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy dogThe
132
+ quick brown fox jumps over the lazy dogThe quick brown fox jumps over "] SmsValidation.configuration.on_message_too_long
133
+ = :raise_error sms = SmsValidation::Sms.new(8889999999, "The quick brown fox jumps
134
+ over the lazy dog" * 4) # => SmsValidation::Sms::MessageTooLongError, "Message cannot
135
+ be longer than 160 characters" ## Contributing 1. Fork it ( https://github.com/[my-github-username]/sms_validation/fork
136
+ ) 2. Create your feature branch (`git checkout -b my-new-feature`) 3. Commit your
137
+ changes (`git commit -am ''Add some feature''`) 4. Push to the branch (`git push
138
+ origin my-new-feature`) 5. Create a new Pull Request'
139
+ test_files:
140
+ - spec/configuration_spec.rb
141
+ - spec/sms_spec.rb