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 ADDED
@@ -0,0 +1,2 @@
1
+ rvm use ruby-1.8.7-p334@addressable_record
2
+ rvm info
data/History.txt CHANGED
@@ -1,3 +1,8 @@
1
+ == 1.3.0 2010-09-22
2
+
3
+ * Made string parsing of addresses more adaptable.
4
+
5
+
1
6
  == 1.2.0 2010-09-21
2
7
 
3
8
  * Make able to parse a string of address elements.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.2.0
1
+ 1.3.0
@@ -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 the gemspec command
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.2.0"
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{2010-09-21}
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
- "README.rdoc"
17
+ "README.rdoc"
18
18
  ]
19
19
  s.files = [
20
20
  ".document",
21
- ".gitignore",
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"
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.3.7}
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
- raise 'Cannot parse address array. Failed to find a state.' if state_pos.nil?
125
- raise 'Cannot parse address array. No zip code found.' unless address_elements.size >= (state_pos + 1)
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 = address.split( ',' )
142
- parts = parts.map { |p| p.strip }
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: 31
5
- prerelease: false
4
+ hash: 27
5
+ prerelease:
6
6
  segments:
7
7
  - 1
8
- - 2
8
+ - 3
9
9
  - 0
10
- version: 1.2.0
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: 2010-09-21 00:00:00 -05:00
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
- - .gitignore
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
- - --charset=UTF-8
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.3.7
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
- - spec/addressable_record/address_parsing_shared_spec.rb
137
- - spec/addressable_record/address_spec.rb
138
- - spec/addressable_record_spec.rb
139
- - spec/spec_helper.rb
135
+ test_files: []
136
+
data/.gitignore DELETED
@@ -1,22 +0,0 @@
1
- ## MAC OS
2
- .DS_Store
3
-
4
- ## TEXTMATE
5
- *.tmproj
6
- tmtags
7
-
8
- ## EMACS
9
- *~
10
- \#*
11
- .\#*
12
-
13
- ## VIM
14
- *.swp
15
-
16
- ## PROJECT::GENERAL
17
- coverage
18
- rdoc
19
- pkg
20
-
21
- ## PROJECT::SPECIFIC
22
- .idea/*