addressable_record 1.2.0 → 1.3.0
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.
- data/.rvmrc +2 -0
- data/History.txt +5 -0
- data/VERSION +1 -1
- data/addressable_record.gemspec +27 -35
- data/lib/addressable_record/address.rb +68 -6
- data/spec/addressable_record/address_spec.rb +63 -1
- metadata +11 -14
- data/.gitignore +0 -22
data/.rvmrc
ADDED
data/History.txt
CHANGED
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.
|
1
|
+
1.3.0
|
data/addressable_record.gemspec
CHANGED
@@ -1,60 +1,52 @@
|
|
1
1
|
# Generated by jeweler
|
2
2
|
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
-
# Instead, edit Jeweler::Tasks in Rakefile, and run
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{addressable_record}
|
8
|
-
s.version = "1.
|
8
|
+
s.version = "1.3.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["C. Jason Harrelson (midas)"]
|
12
|
-
s.date = %q{
|
12
|
+
s.date = %q{2011-11-17}
|
13
13
|
s.description = %q{Encapsulates the composed of pattern for addresses into any easy to use library. Provides convenience methods for formatting, parsing, etc.}
|
14
14
|
s.email = %q{jason@lookforwardenterprises.com}
|
15
15
|
s.extra_rdoc_files = [
|
16
16
|
"LICENSE",
|
17
|
-
|
17
|
+
"README.rdoc"
|
18
18
|
]
|
19
19
|
s.files = [
|
20
20
|
".document",
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
21
|
+
".rvmrc",
|
22
|
+
"History.txt",
|
23
|
+
"LICENSE",
|
24
|
+
"README.rdoc",
|
25
|
+
"Rakefile",
|
26
|
+
"VERSION",
|
27
|
+
"addressable_record.gemspec",
|
28
|
+
"lib/addressable_record.rb",
|
29
|
+
"lib/addressable_record/active_record_extesions.rb",
|
30
|
+
"lib/addressable_record/address.rb",
|
31
|
+
"lib/addressable_record/states.rb",
|
32
|
+
"rails_generators/addressable_record_migration_generator/addressable_record_migration_generator.rb",
|
33
|
+
"rails_generators/addressable_record_migration_generator/templates/migration.rb",
|
34
|
+
"script/console",
|
35
|
+
"script/environment.rb",
|
36
|
+
"script/seed.rb",
|
37
|
+
"spec/addressable_record/address_parsing_shared_spec.rb",
|
38
|
+
"spec/addressable_record/address_spec.rb",
|
39
|
+
"spec/addressable_record_spec.rb",
|
40
|
+
"spec/database.yml",
|
41
|
+
"spec/spec.opts",
|
42
|
+
"spec/spec_helper.rb"
|
43
43
|
]
|
44
44
|
s.homepage = %q{http://github.com/midas/addressable_record}
|
45
|
-
s.rdoc_options = ["--charset=UTF-8"]
|
46
45
|
s.require_paths = ["lib"]
|
47
|
-
s.rubygems_version = %q{1.
|
46
|
+
s.rubygems_version = %q{1.6.0}
|
48
47
|
s.summary = %q{Encapsulates the composed of pattern for addresses into any easy to use library.}
|
49
|
-
s.test_files = [
|
50
|
-
"spec/addressable_record/address_parsing_shared_spec.rb",
|
51
|
-
"spec/addressable_record/address_spec.rb",
|
52
|
-
"spec/addressable_record_spec.rb",
|
53
|
-
"spec/spec_helper.rb"
|
54
|
-
]
|
55
48
|
|
56
49
|
if s.respond_to? :specification_version then
|
57
|
-
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
58
50
|
s.specification_version = 3
|
59
51
|
|
60
52
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
@@ -2,6 +2,11 @@ require File.dirname(__FILE__) + '/states'
|
|
2
2
|
|
3
3
|
module AddressableRecord
|
4
4
|
class Address
|
5
|
+
NATURAL_OR_CSV_STRING_REGEX = /^\s*?(?:([^,]+?)),\s*?(?:([^,]+?)),\s*?(?:(?:([^,]+?)),\s*?)??([A-Z]{2}),??\s*?(\d{5}(?:-\d{4})?)\s*$/ # /^(.+),\s*(.+),\s*(.+),\s*(.{2}),?\s*(\d{5})-?(\d{4})?\s*$/
|
6
|
+
NATURAL_OR_CSV_STRING_INVALID_MESSAGE = "invalid format, try something like: 123 Some Street, Suite 123, Some City, AL 11111-1111"
|
7
|
+
NATURAL_STRING_REGEX = /^(.+),\s*(.+),\s*(.+),\s*(.{2})\s*(\d{5})-?(\d{4})?\s*$/
|
8
|
+
CSV_STRING_REGEX = /^(.+),\s*(.+),\s*(.+),\s*(.{2}),\s*(\d{5})-?(\d{4})?\s*$/
|
9
|
+
|
5
10
|
attr_reader :raw_street, :streets, :city, :state_or_province, :zip_code, :country
|
6
11
|
|
7
12
|
@@street_delimiter ||= '###'
|
@@ -76,12 +81,28 @@ module AddressableRecord
|
|
76
81
|
# %C - country
|
77
82
|
#
|
78
83
|
def to_s( pattern=nil )
|
84
|
+
return '' if is_blank?
|
79
85
|
to_return = pattern.is_a?( Symbol ) ? @@patterns[pattern] : pattern
|
80
86
|
to_return = @@patterns[:us] if to_return.nil? || to_return.empty?
|
81
87
|
@pattern_map.each { |pat, replacement| to_return = to_return.gsub( pat, replacement ) }
|
82
88
|
to_return.strip
|
83
89
|
end
|
84
90
|
|
91
|
+
def is_blank?
|
92
|
+
raw_street.blank? && city.blank? && state_or_province.blank? && raw_zip_code.blank? && country.blank?
|
93
|
+
end
|
94
|
+
|
95
|
+
def ==( other )
|
96
|
+
return false unless other.instance_of?( self.class )
|
97
|
+
return false unless other.raw_street.upcase == raw_street.upcase
|
98
|
+
return false unless other.city.upcase == city.upcase
|
99
|
+
return false unless other.state_or_province.upcase == state_or_province.upcase
|
100
|
+
return false unless other.raw_zip_code == raw_zip_code
|
101
|
+
return false unless other.country.upcase == country.upcase
|
102
|
+
|
103
|
+
true
|
104
|
+
end
|
105
|
+
|
85
106
|
# Outputs the parts of teh address delimited by specified delimiter(s).
|
86
107
|
#
|
87
108
|
# *parameters*
|
@@ -121,14 +142,17 @@ module AddressableRecord
|
|
121
142
|
|
122
143
|
def parse_array( address_elements ) #:nodoc:
|
123
144
|
state_pos = find_state_position( address_elements )
|
124
|
-
|
125
|
-
raise 'Cannot parse address array.
|
145
|
+
# puts address_elements.class.name, address_elements, state_pos
|
146
|
+
# raise 'Cannot parse address array. Failed to find a state.' if state_pos.nil?
|
147
|
+
# raise 'Cannot parse address array. No zip code found.' unless address_elements.size >= (state_pos + 1)
|
148
|
+
return nil if state_pos.nil?
|
149
|
+
return nil unless address_elements.size >= (state_pos + 1)
|
126
150
|
state = States.by_abbreviation.has_key?( address_elements[state_pos] ) ? address_elements[state_pos] : States.by_name[address_elements[state_pos]]
|
127
151
|
zip_code = address_elements[state_pos+1].gsub( /#{@@zip_code_delimiter}/, '' )
|
128
152
|
country = address_elements.size >= (state_pos + 3) ? address_elements[state_pos+2] : 'U.S.A.'
|
129
153
|
city = address_elements[state_pos-1]
|
130
154
|
streets = []
|
131
|
-
(0..state_pos-2).each { |i| streets << address_elements[i] }
|
155
|
+
(0..state_pos-2).each { |i| streets << address_elements[i].strip }
|
132
156
|
street = streets.join( @@street_delimiter )
|
133
157
|
return AddressableRecord::Address.new( :raw_street => street, :city => city, :state_or_province => state, :raw_zip_code => zip_code, :country => country )
|
134
158
|
end
|
@@ -138,12 +162,35 @@ module AddressableRecord
|
|
138
162
|
end
|
139
163
|
|
140
164
|
def parse_string( address )
|
141
|
-
parts =
|
142
|
-
|
165
|
+
parts = nil
|
166
|
+
pos = find_state_position_in_string( address )
|
167
|
+
return blank_address if pos.nil?
|
168
|
+
|
169
|
+
if !pos.nil? && address[pos+2,1] == ','
|
170
|
+
parts = address.split( ',' )
|
171
|
+
parts = parts.map { |p| p.strip }
|
172
|
+
else
|
173
|
+
pre_state_string = address[0,pos]
|
174
|
+
parts = pre_state_string.split( ',' ).reject { |p| p.blank? }
|
175
|
+
state_on_string = address[pos,address.size-pos]
|
176
|
+
parts += state_on_string.split( /\s+/ ).reject { |p| p.blank? }
|
177
|
+
end
|
178
|
+
|
143
179
|
parse_array( parts )
|
144
180
|
end
|
145
181
|
|
182
|
+
def blank_address
|
183
|
+
self.new( {} )
|
184
|
+
end
|
185
|
+
|
146
186
|
def find_state_position( address_elements )
|
187
|
+
unless [Array,String].include?( address_elements.class )
|
188
|
+
raise "Cannot search for state position in a #{address_elements.class.name}"
|
189
|
+
end
|
190
|
+
self.send( :"find_state_position_in_#{address_elements.class.to_s.downcase}", address_elements )
|
191
|
+
end
|
192
|
+
|
193
|
+
def find_state_position_in_array( address_elements )
|
147
194
|
# Look for state abbreviation
|
148
195
|
possible_abbreviation_positions = find_possible_state_abbrev_positions( address_elements )
|
149
196
|
state_index = possible_abbreviation_positions.detect { |i| States.by_abbreviation.has_key?( address_elements[i] ) }
|
@@ -153,6 +200,21 @@ module AddressableRecord
|
|
153
200
|
(0..address_elements.size-1).detect { |i| States.by_name.has_key?( address_elements[i] ) }
|
154
201
|
end
|
155
202
|
|
203
|
+
def find_state_position_in_string( address_elements )
|
204
|
+
idx = nil
|
205
|
+
States.abbreviations.each do |abbreviation|
|
206
|
+
idx = address_elements.rindex( abbreviation )
|
207
|
+
return idx unless idx.nil?
|
208
|
+
end
|
209
|
+
|
210
|
+
States.names.each do |name|
|
211
|
+
idx = address_elements.rindex( name )
|
212
|
+
return idx unless idx.nil?
|
213
|
+
end
|
214
|
+
|
215
|
+
nil
|
216
|
+
end
|
217
|
+
|
156
218
|
def find_possible_state_abbrev_positions( address_array )
|
157
219
|
positions = []
|
158
220
|
address_array.each_with_index { |str, i| positions << i if str.size == 2 }
|
@@ -160,4 +222,4 @@ module AddressableRecord
|
|
160
222
|
end
|
161
223
|
end
|
162
224
|
end
|
163
|
-
end
|
225
|
+
end
|
@@ -64,7 +64,31 @@ describe "AddressableRecord::Address" do
|
|
64
64
|
@klass.send( :find_state_position, ['123 Jones St.', 'Atlanta', '33333' ] ).should be_nil
|
65
65
|
end
|
66
66
|
|
67
|
-
describe "when parsng a string of address elements" do
|
67
|
+
describe "when parsng a naturally puncuated string of address elements" do
|
68
|
+
before :each do
|
69
|
+
@address_elements_without_country = "123 Jones Street, Suite 540, Atlanta, GA 33333-1111"
|
70
|
+
@address_elements = "123 Jones Street, Suite 540, Atlanta, GA 33333-1111 U.S.A."
|
71
|
+
end
|
72
|
+
|
73
|
+
# ^(.*),(.*),(.*),(.*),?(\d{5})-?(\d{4})?$
|
74
|
+
# describe "with a country" do
|
75
|
+
# before :each do
|
76
|
+
# @address = @address_elements
|
77
|
+
# end
|
78
|
+
#
|
79
|
+
# it_should_behave_like "The address 123 Jones Street, Suite 540, Atlanta, GA 33333-1111 U.S.A."
|
80
|
+
# end
|
81
|
+
|
82
|
+
# describe "without a country" do
|
83
|
+
# before :each do
|
84
|
+
# @address = @address_elements_without_country
|
85
|
+
# end
|
86
|
+
#
|
87
|
+
# it_should_behave_like "The address 123 Jones Street, Suite 540, Atlanta, GA 33333-1111 U.S.A."
|
88
|
+
# end
|
89
|
+
end
|
90
|
+
|
91
|
+
describe "when parsng a comma separated string of address elements" do
|
68
92
|
before :each do
|
69
93
|
@address_elements_without_country = ['123 Jones Street', 'Suite 540', 'Atlanta', 'GA', '33333-1111']
|
70
94
|
end
|
@@ -317,5 +341,43 @@ describe "AddressableRecord::Address" do
|
|
317
341
|
@address.to_s( '%C' ).should eql( 'U.S.A.' )
|
318
342
|
end
|
319
343
|
end
|
344
|
+
|
345
|
+
describe "having a regular expression for a string address" do
|
346
|
+
describe "that is naturally formatted" do
|
347
|
+
describe "without a contry"do
|
348
|
+
it "should match" do
|
349
|
+
# "123 Jones Street, Suite 111, Atlanta, GA 31555"
|
350
|
+
end
|
351
|
+
|
352
|
+
it "should ignore white space" do
|
353
|
+
|
354
|
+
end
|
355
|
+
end
|
356
|
+
|
357
|
+
describe "with a country" do
|
358
|
+
it "should match" do
|
359
|
+
# "123 Jones Street, Suite 111, Atlanta, GA 31555, United States"
|
360
|
+
end
|
361
|
+
|
362
|
+
it "should ignore white space" do
|
363
|
+
|
364
|
+
end
|
365
|
+
end
|
366
|
+
end
|
367
|
+
|
368
|
+
describe "that is comma separated formatted" do
|
369
|
+
it "should match" do
|
370
|
+
|
371
|
+
end
|
372
|
+
|
373
|
+
it "should ignore white space" do
|
374
|
+
|
375
|
+
end
|
376
|
+
end
|
377
|
+
|
378
|
+
describe "similar strings" do
|
379
|
+
|
380
|
+
end
|
381
|
+
end
|
320
382
|
end
|
321
383
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: addressable_record
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
5
|
-
prerelease:
|
4
|
+
hash: 27
|
5
|
+
prerelease:
|
6
6
|
segments:
|
7
7
|
- 1
|
8
|
-
-
|
8
|
+
- 3
|
9
9
|
- 0
|
10
|
-
version: 1.
|
10
|
+
version: 1.3.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- C. Jason Harrelson (midas)
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date:
|
18
|
+
date: 2011-11-17 00:00:00 -06:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -76,7 +76,7 @@ extra_rdoc_files:
|
|
76
76
|
- README.rdoc
|
77
77
|
files:
|
78
78
|
- .document
|
79
|
-
- .
|
79
|
+
- .rvmrc
|
80
80
|
- History.txt
|
81
81
|
- LICENSE
|
82
82
|
- README.rdoc
|
@@ -103,8 +103,8 @@ homepage: http://github.com/midas/addressable_record
|
|
103
103
|
licenses: []
|
104
104
|
|
105
105
|
post_install_message:
|
106
|
-
rdoc_options:
|
107
|
-
|
106
|
+
rdoc_options: []
|
107
|
+
|
108
108
|
require_paths:
|
109
109
|
- lib
|
110
110
|
required_ruby_version: !ruby/object:Gem::Requirement
|
@@ -128,12 +128,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
128
128
|
requirements: []
|
129
129
|
|
130
130
|
rubyforge_project:
|
131
|
-
rubygems_version: 1.
|
131
|
+
rubygems_version: 1.6.0
|
132
132
|
signing_key:
|
133
133
|
specification_version: 3
|
134
134
|
summary: Encapsulates the composed of pattern for addresses into any easy to use library.
|
135
|
-
test_files:
|
136
|
-
|
137
|
-
- spec/addressable_record/address_spec.rb
|
138
|
-
- spec/addressable_record_spec.rb
|
139
|
-
- spec/spec_helper.rb
|
135
|
+
test_files: []
|
136
|
+
|