addressable_record 1.2.0 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
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/*