From c619f21b0bb8074dab3b2e72b75b26a874cb6b1b Mon Sep 17 00:00:00 2001 From: Thomas Hoen Date: Wed, 17 Aug 2016 13:23:38 -0400 Subject: [PATCH 1/5] Adds street address 1 and 2 so the Suite/Apt ect. can be placed on the second line --- lib/street_address.rb | 23 +++++++++++++++++++++++ test/address_test.rb | 17 +++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/lib/street_address.rb b/lib/street_address.rb index 7e74eb7..a1d76e0 100644 --- a/lib/street_address.rb +++ b/lib/street_address.rb @@ -901,12 +901,35 @@ def to_s(format = :default) s << line1(s) when :line2 s << line2(s) + when :street_address_1 + s << street_address_1 + when :street_address_2 + s << street_address_2 + when :city_state_zip + s << line2(s) else s << [line1, line2].select{ |l| !l.empty? }.join(', ') end s end + def street_address_1 + s = number + s += " " + prefix unless prefix.nil? + s += " " + street unless street.nil? + s += " " + street_type unless street_type.nil? + s + end + + def street_address_2 + s = "" + if( !unit_prefix.nil? && !unit.nil? ) + s += unit_prefix + " " + unit + elsif( unit_prefix.nil? && !unit.nil? ) + s += "#" + unit + end + s + end def to_h self.instance_variables.each_with_object({}) do |var_name, hash| diff --git a/test/address_test.rb b/test/address_test.rb index f38f523..e4b445d 100644 --- a/test/address_test.rb +++ b/test/address_test.rb @@ -311,6 +311,23 @@ def test_to_s_for_line2 assert_equal addr.to_s(:line2), addr.line2 end + def test_to_s_for_street_address_1 + address = "7800 Mill Station Rd, Apt. 7B, Sebastopol CA 95472-1234" + addr = StreetAddress::US.parse(address) + assert_equal addr.to_s(:street_address_1), "7800 Mill Station Rd" + end + + def test_to_s_for_street_address_2 + address = "7800 Mill Station Rd, Apt. 7B, Sebastopol CA 95472-1234" + addr = StreetAddress::US.parse(address) + assert_equal addr.to_s(:street_address_2), "Apt 7B" + end + + def test_to_s_for_city_state_zip + address = "7800 Mill Station Rd Sebastopol CA 95472-1234" + addr = StreetAddress::US.parse(address) + assert_equal addr.to_s(:line2), addr.line2 + end def test_full_postal_code address = "7800 Mill Station Rd Sebastopol CA 95472-1234" From cce40bbed5a0032e6c837b3854b8a74fae936a2e Mon Sep 17 00:00:00 2001 From: Thomas Hoen Date: Tue, 13 Sep 2016 14:07:06 -0400 Subject: [PATCH 2/5] Adds parsing for PO boxes and adds tests for street_address_1 and street_address_2 --- lib/street_address.rb | 33 ++++++++++++++++++----- test/address_test.rb | 52 +++++++++++++++++++++++++++++++++++-- test/street_address_test.rb | 2 -- 3 files changed, 77 insertions(+), 10 deletions(-) diff --git a/lib/street_address.rb b/lib/street_address.rb index a1d76e0..ca879e0 100644 --- a/lib/street_address.rb +++ b/lib/street_address.rb @@ -520,6 +520,8 @@ class US 'state' => STATE_CODES, } + STREET_NUMBER_WORDS = %{one two three four five six seven eight nine ten} + class << self attr_accessor( :street_type_regexp, @@ -533,8 +535,10 @@ class << self :corner_regexp, :unit_regexp, :street_regexp, + :po_street_regexp, :place_regexp, :address_regexp, + :po_address_regexp, :informal_address_regexp, :dircode_regexp, :unit_prefix_numbered_regexp, @@ -602,6 +606,8 @@ class << self ) /ix; + self.po_street_regexp = /^(?p\.?o\.?\s?(?:box|\#)?\s\d\d*[-a-z]*)/ix; + # http://pe.usps.com/text/pub28/pub28c2_003.htm # TODO add support for those that don't require a number # TODO map to standard names/abbreviations @@ -672,6 +678,14 @@ class << self \z # right up to end of string /ix; + self.po_address_regexp = / + \A + #{po_street_regexp} \W* + #{place_regexp} + \W* # require on non-word chars at end + \z # right up to end of string + /ix; + self.sep_regexp = /(?:\W+|\Z)/; self.sep_avoid_unit_regexp = /(?:[^\#\w]+|\Z)/; @@ -705,7 +719,7 @@ def parse(location, args={}) if( corner_regexp.match(location) ) return parse_intersection(location, args) else - return parse_address(location, args) || parse_informal_address(location, args) + return parse_po_address(location, args) || parse_address(location, args) || parse_informal_address(location, args) end end @@ -715,6 +729,12 @@ def parse_address(address, args={}) to_address( match_to_hash(match), args ) end + def parse_po_address(address, args={}) + return unless match = po_address_regexp.match(address) + + to_address(match_to_hash(match), args) + end + def parse_informal_address(address, args={}) return unless match = informal_address_regexp.match(address) @@ -914,11 +934,12 @@ def to_s(format = :default) end def street_address_1 - s = number - s += " " + prefix unless prefix.nil? - s += " " + street unless street.nil? - s += " " + street_type unless street_type.nil? - s + s = "" + s = number + " " unless number.nil? + s += prefix + " " unless prefix.nil? + s += street + " " unless street.nil? + s += street_type unless street_type.nil? + s.strip end def street_address_2 diff --git a/test/address_test.rb b/test/address_test.rb index e4b445d..53d0743 100644 --- a/test/address_test.rb +++ b/test/address_test.rb @@ -21,11 +21,15 @@ class AddressTest < MiniTest::Test }, "1005 N Gravenstein Highway, Sebastopol, CA" => { :line1 => "1005 N Gravenstein Hwy", - :line2 => "Sebastopol, CA" + :line2 => "Sebastopol, CA", + :street_address_1 => "1005 N Gravenstein Hwy", + :street_address_2 => "" }, "1005 N Gravenstein Highway, Suite 500, Sebastopol, CA" => { :line1 => "1005 N Gravenstein Hwy Suite 500", - :line2 => "Sebastopol, CA" + :line2 => "Sebastopol, CA", + :street_address_1 => "1005 N Gravenstein Hwy", + :street_address_2 => "Suite 500" }, "1005 N Gravenstein Hwy Suite 500 Sebastopol, CA" => { :line1 => "1005 N Gravenstein Hwy Suite 500", @@ -134,6 +138,36 @@ class AddressTest < MiniTest::Test "44 Canal Center Plaza Suite 500, Alexandria, VA 22314" => { :line1 => "44 Canal Center Plz Suite 500", :line2 => "Alexandria, VA 22314" + }, + "One East 161st Street, Bronx, NY 10451" => { + :line1 => "One East 161st St", + :line2 => "Bronx, NY 10451", + :street_address_1 => "One East 161st St", + :street_address_2 => "" + }, + "One East 161st Street Suite 10, Bronx, NY 10451" => { + :line1 => "One East 161st St Suite 10", + :line2 => "Bronx, NY 10451", + :street_address_1 => "One East 161st St", + :street_address_2 => "Suite 10" + }, + "P.O. Box 280568 Queens Village, New York 11428" => { + :line1 => "Po Box 280568", + :line2 => "Queens Village, NY 11428" + }, + "PO Box 280568 Queens Village, New York 11428" => { + :line1 => "Po Box 280568", + :line2 => "Queens Village, NY 11428", + :street_address_1 => "Po Box 280568", + :street_address_2 => "" + }, + "PO 280568 Queens Village, New York 11428" => { + :line1 => "Po 280568", + :line2 => "Queens Village, NY 11428" + }, + "Two Pennsylvania Plaza New York, NY 10121-0091" => { + :line1 => "Two Pennsylvania Plz", + :line2 => "New York, NY 10121-0091" } } @@ -213,6 +247,14 @@ def test_line1_with_valid_addresses end end + def test_street_address_1_with_valid_addresses + ADDRESSES.select { |k,v| !v[:street_address_1].nil? }.each_pair do |address, expected| + addr = StreetAddress::US.parse(address) + assert_equal addr.street_address_1, expected[:street_address_1] + assert_equal addr.street_address_2, expected[:street_address_2] + + end + end def test_line1_with_intersections INTERSECTIONS.each_pair do |address, expected| @@ -329,6 +371,12 @@ def test_to_s_for_city_state_zip assert_equal addr.to_s(:line2), addr.line2 end + def test_to_s_for_PO_box + address = "PO 7800 Sebastopol CA 95472-1234" + addr = StreetAddress::US.parse(address) + assert_equal "Po 7800", addr.to_s(:line1) + end + def test_full_postal_code address = "7800 Mill Station Rd Sebastopol CA 95472-1234" addr = StreetAddress::US.parse(address) diff --git a/test/street_address_test.rb b/test/street_address_test.rb index 5611e06..3fcecca 100644 --- a/test/street_address_test.rb +++ b/test/street_address_test.rb @@ -489,8 +489,6 @@ class StreetAddressUsTest < MiniTest::Test "Gravenstein Hwy 95472", "E1005 Gravenstein Hwy 95472", # "1005E Gravenstein Hwy 95472" - ## adding from original ruby test suite - "PO BOX 450, Chicago IL 60657" ] From f30dafa2da6bf4b23e1e6de6851aeeca0c09e2e8 Mon Sep 17 00:00:00 2001 From: Thomas Hoen Date: Mon, 30 Oct 2017 12:07:25 -0400 Subject: [PATCH 3/5] Do not capitalize the street name if it is a PO BOX --- lib/street_address.rb | 3 ++- test/address_test.rb | 10 +++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/lib/street_address.rb b/lib/street_address.rb index ca879e0..c6f2232 100644 --- a/lib/street_address.rb +++ b/lib/street_address.rb @@ -820,7 +820,8 @@ def to_address(input, args) end %w(street street_type street2 street_type2 city unit_prefix).each do |k| - input[k] = input[k].split.map(&:capitalize).join(' ') if input[k] + input[k] = input[k].split.map(&:capitalize).join(' ') if input[k] && !input[k].match(po_street_regexp) + input[k] = input[k].split.map(&:upcase).join(' ') if input[k] && input[k].match(po_street_regexp) end return StreetAddress::US::Address.new( input ) diff --git a/test/address_test.rb b/test/address_test.rb index 53d0743..8155efe 100644 --- a/test/address_test.rb +++ b/test/address_test.rb @@ -152,17 +152,17 @@ class AddressTest < MiniTest::Test :street_address_2 => "Suite 10" }, "P.O. Box 280568 Queens Village, New York 11428" => { - :line1 => "Po Box 280568", + :line1 => "PO BOX 280568", :line2 => "Queens Village, NY 11428" }, "PO Box 280568 Queens Village, New York 11428" => { - :line1 => "Po Box 280568", + :line1 => "PO BOX 280568", :line2 => "Queens Village, NY 11428", - :street_address_1 => "Po Box 280568", + :street_address_1 => "PO BOX 280568", :street_address_2 => "" }, "PO 280568 Queens Village, New York 11428" => { - :line1 => "Po 280568", + :line1 => "PO 280568", :line2 => "Queens Village, NY 11428" }, "Two Pennsylvania Plaza New York, NY 10121-0091" => { @@ -374,7 +374,7 @@ def test_to_s_for_city_state_zip def test_to_s_for_PO_box address = "PO 7800 Sebastopol CA 95472-1234" addr = StreetAddress::US.parse(address) - assert_equal "Po 7800", addr.to_s(:line1) + assert_equal "PO 7800", addr.to_s(:line1) end def test_full_postal_code From 91660d62d49d4e4a1bb00c600c58eddef13f5b53 Mon Sep 17 00:00:00 2001 From: Thomas Hoen Date: Sat, 4 Nov 2017 10:30:45 -0400 Subject: [PATCH 4/5] capitalized the PO and street directions --- lib/street_address.rb | 10 +++++++--- test/address_test.rb | 25 ++++++++++++++----------- test/street_address_test.rb | 19 +++++++++++++++++-- 3 files changed, 38 insertions(+), 16 deletions(-) diff --git a/lib/street_address.rb b/lib/street_address.rb index c6f2232..75a4131 100644 --- a/lib/street_address.rb +++ b/lib/street_address.rb @@ -819,13 +819,17 @@ def to_address(input, args) } end - %w(street street_type street2 street_type2 city unit_prefix).each do |k| - input[k] = input[k].split.map(&:capitalize).join(' ') if input[k] && !input[k].match(po_street_regexp) - input[k] = input[k].split.map(&:upcase).join(' ') if input[k] && input[k].match(po_street_regexp) + %w(street street_type street2 street_type2 city unit_prefix postal_code).each do |k| + input[k] = input[k].split.map { |elem| upcase_or_capitalize(elem) }.join(' ') if input[k] end return StreetAddress::US::Address.new( input ) end + + def upcase_or_capitalize(elem) + return elem.upcase if elem.downcase.match(/^(po|ne|nw|sw|se)$/) + elem.capitalize + end end class Address diff --git a/test/address_test.rb b/test/address_test.rb index 8155efe..acc59e5 100644 --- a/test/address_test.rb +++ b/test/address_test.rb @@ -152,13 +152,13 @@ class AddressTest < MiniTest::Test :street_address_2 => "Suite 10" }, "P.O. Box 280568 Queens Village, New York 11428" => { - :line1 => "PO BOX 280568", + :line1 => "PO Box 280568", :line2 => "Queens Village, NY 11428" }, - "PO Box 280568 Queens Village, New York 11428" => { - :line1 => "PO BOX 280568", + "PO BOX 280568 Queens Village, New York 11428" => { + :line1 => "PO Box 280568", :line2 => "Queens Village, NY 11428", - :street_address_1 => "PO BOX 280568", + :street_address_1 => "PO Box 280568", :street_address_2 => "" }, "PO 280568 Queens Village, New York 11428" => { @@ -168,6 +168,10 @@ class AddressTest < MiniTest::Test "Two Pennsylvania Plaza New York, NY 10121-0091" => { :line1 => "Two Pennsylvania Plz", :line2 => "New York, NY 10121-0091" + }, + "1400 CONNECTICUT AVE NW, WASHINGTON, DC 20036" => { + :line1 => "1400 Connecticut Ave NW", + :line2 => "Washington, DC 20036" } } @@ -233,26 +237,25 @@ class AddressTest < MiniTest::Test :line1 => "233 S Wacker Dr Lobby", :line2 => "60606" } - #FIXME + # FIXME # "(233 S Wacker Dr lobby 60606)" => { # :line1 => "233 S Wacker Dr Lobby", - # :line2 => ""} + # :line2 => ""} } def test_line1_with_valid_addresses ADDRESSES.each_pair do |address, expected| addr = StreetAddress::US.parse(address) - assert_equal addr.line1, expected[:line1] + assert_equal expected[:line1], addr.line1 end end def test_street_address_1_with_valid_addresses ADDRESSES.select { |k,v| !v[:street_address_1].nil? }.each_pair do |address, expected| addr = StreetAddress::US.parse(address) - assert_equal addr.street_address_1, expected[:street_address_1] - assert_equal addr.street_address_2, expected[:street_address_2] - + assert_equal expected[:street_address_1], addr.street_address_1 + assert_equal expected[:street_address_2], addr.street_address_2 end end @@ -301,7 +304,7 @@ def test_to_s_with_valid_addresses addr = StreetAddress::US.parse(address) expected_result = expected[:to_s] expected_result ||= [expected[:line1], expected[:line2]].select{|l| !l.empty?}.join(', ') - assert_equal addr.to_s, expected_result + assert_equal expected_result, addr.to_s end end diff --git a/test/street_address_test.rb b/test/street_address_test.rb index 3fcecca..c7851ed 100644 --- a/test/street_address_test.rb +++ b/test/street_address_test.rb @@ -301,7 +301,7 @@ class StreetAddressUsTest < MiniTest::Test :city => "Alexandria", :street2 => nil }, - "1600 Pennsylvania Ave Washington DC" => { + "1600 Pennsylvania Ave NW Washington DC" => { :number => "1600", :postal_code => nil, :prefix => nil, @@ -311,7 +311,8 @@ class StreetAddressUsTest < MiniTest::Test :unit => nil, :unit_prefix => nil, :city => "Washington", - :street2 => nil + :street2 => nil, + :suffix => "NW" }, "1005 Gravenstein Hwy N, Sebastopol CA 95472" => { :number => "1005", @@ -338,6 +339,20 @@ class StreetAddressUsTest < MiniTest::Test :state=>"VA", :postal_code=>"22206", :postal_code_ext=>nil + }, + + "P.O. BOX 293930, ARLINGTON, VA 22206" => { + :number=>nil, + :street=>"PO Box 293930", + :street_type=>nil, + :unit=>nil, + :unit_prefix=>nil, + :suffix=>nil, + :prefix=>nil, + :city=>"Arlington", + :state=>"VA", + :postal_code=>"22206", + :postal_code_ext=>nil } } From 3fd33fe7a2122c1ad0eb8a91a5b65caade38113c Mon Sep 17 00:00:00 2001 From: Mike Subelsky Date: Thu, 14 Jan 2021 13:06:34 -0500 Subject: [PATCH 5/5] fix minitest assert_nil deprecation warnings --- test/street_address_test.rb | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/test/street_address_test.rb b/test/street_address_test.rb index c7851ed..42849d2 100644 --- a/test/street_address_test.rb +++ b/test/street_address_test.rb @@ -594,8 +594,8 @@ def test_informal_parse_informal_address_trailing_words end def test_parse - assert_equal StreetAddress::US.parse("&"), nil - assert_equal StreetAddress::US.parse(" and "), nil + assert_nil StreetAddress::US.parse("&") + assert_nil StreetAddress::US.parse(" and ") parseable = [ "1600 Pennsylvania Ave Washington DC 20006", @@ -630,7 +630,11 @@ def test_comparison def compare_expected_to_actual_hash(expected, actual, address) expected.each_pair do |expected_key, expected_value| - assert_equal actual[expected_key], expected_value, "For address '#{address}', #{actual[expected_key]} != #{expected_value}" + if expected_value.nil? + assert_nil actual[expected_key], "For address '#{address}', expected nil value for field '#{expected_key}', got: #{actual[expected_key]}" + else + assert_equal actual[expected_key], expected_value, "For address '#{address}', expected value '#{expected[expected_key]}' for field '#{expected_key}', got: #{actual[expected_key]}" + end end end