@@ -676,3 +676,199 @@ def test_service_parse_to_dict(self) -> None:
676676 result = service .parse_to_dict ("123 Main St, Austin TX 78749" )
677677 assert result ["AddressNumber" ] == "123"
678678 assert result ["ZipCode" ] == "78749"
679+
680+
681+ # =============================================================================
682+ # Address Formatting Tests (Address1, Address2, FullAddress Properties)
683+ # =============================================================================
684+
685+
686+ class TestAddressFormatting :
687+ """Test the Address formatting properties (Address1, Address2, FullAddress)."""
688+
689+ def test_simple_street_address_to_address1 (self ) -> None :
690+ """Simple street address should format to Address1 correctly."""
691+ result = parse ("123 Main St, Austin TX 78749" , validate = False )
692+ assert result .address is not None
693+ address1 = result .address .Address1
694+ assert address1 is not None
695+ assert "123" in address1
696+ assert "Main" in address1
697+ assert "St" in address1
698+
699+ def test_address1_with_directionals (self ) -> None :
700+ """Address1 should include directionals."""
701+ result = parse ("100 N Main St S, Austin TX 78749" , validate = False )
702+ assert result .address is not None
703+ address1 = result .address .Address1
704+ assert address1 is not None
705+ # Should contain both pre and post directionals
706+ assert "100" in address1
707+ assert "Main" in address1
708+ assert "St" in address1
709+
710+ def test_address1_po_box (self ) -> None :
711+ """PO Box addresses should format to Address1."""
712+ result = parse ("PO Box 1234, Austin TX 78749" , validate = False )
713+ assert result .address is not None
714+ address1 = result .address .Address1
715+ assert address1 is not None
716+ assert "PO Box" in address1 or "P.O." in address1
717+ assert "1234" in address1
718+
719+ def test_address1_none_when_no_components (self ) -> None :
720+ """Address1 should be None when no street components present."""
721+ from ryandata_address_utils .models import AddressBuilder
722+
723+ address = AddressBuilder ().with_city ("Austin" ).with_state ("TX" ).with_zip ("78749" ).build ()
724+ assert address .Address1 is None
725+
726+ def test_address2_with_apartment (self ) -> None :
727+ """Address2 should include apartment/unit information."""
728+ result = parse ("400 Main St Apt 5, Austin TX 78749" , validate = False )
729+ assert result .address is not None
730+ address2 = result .address .Address2
731+ # Address2 may or may not be populated depending on parser
732+ if address2 :
733+ assert "Apt" in address2 or "5" in address2
734+
735+ def test_address2_none_when_no_subaddress (self ) -> None :
736+ """Address2 should be None when no subaddress components present."""
737+ result = parse ("123 Main St, Austin TX 78749" , validate = False )
738+ assert result .address is not None
739+ assert result .address .Address2 is None
740+
741+ def test_address2_with_suite (self ) -> None :
742+ """Address2 should include suite information."""
743+ result = parse ("500 Main St Suite 100, Austin TX 78749" , validate = False )
744+ assert result .address is not None
745+ address2 = result .address .Address2
746+ if address2 :
747+ # May contain suite info depending on parser
748+ assert len (address2 ) > 0
749+
750+ def test_full_address_basic (self ) -> None :
751+ """FullAddress should format correctly for basic address."""
752+ result = parse ("123 Main St, Austin TX 78749" , validate = False )
753+ assert result .address is not None
754+ full_address = result .address .FullAddress
755+ assert "123" in full_address
756+ assert "Main" in full_address
757+ assert "Austin" in full_address
758+ assert "TX" in full_address
759+ assert "78749" in full_address
760+
761+ def test_full_address_with_po_box (self ) -> None :
762+ """FullAddress should format correctly for PO Box."""
763+ result = parse ("PO Box 1234, Austin TX 78749" , validate = False )
764+ assert result .address is not None
765+ full_address = result .address .FullAddress
766+ assert "1234" in full_address
767+ assert "Austin" in full_address
768+ assert "TX" in full_address
769+ assert "78749" in full_address
770+
771+ def test_full_address_only_city_state_zip (self ) -> None :
772+ """FullAddress should work with only city, state, zip."""
773+ from ryandata_address_utils .models import AddressBuilder
774+
775+ address = (
776+ AddressBuilder ().with_city ("Austin" ).with_state ("TX" ).with_zip ("78749" ).build ()
777+ )
778+ full_address = address .FullAddress
779+ assert "Austin" in full_address
780+ assert "TX" in full_address
781+ assert "78749" in full_address
782+
783+ def test_full_address_no_components (self ) -> None :
784+ """FullAddress should return empty string when all components None."""
785+ from ryandata_address_utils .models import Address
786+
787+ address = Address ()
788+ assert address .FullAddress == ""
789+
790+ def test_full_address_only_address1 (self ) -> None :
791+ """FullAddress should work with only Address1."""
792+ from ryandata_address_utils .models import AddressBuilder
793+
794+ address = (
795+ AddressBuilder ()
796+ .with_street_number ("123" )
797+ .with_street_name ("Main" )
798+ .with_street_type ("St" )
799+ .build ()
800+ )
801+ full_address = address .FullAddress
802+ assert "123" in full_address
803+ assert "Main" in full_address
804+ assert "St" in full_address
805+
806+ def test_address1_with_number_suffix (self ) -> None :
807+ """Address1 should include address number suffix."""
808+ from ryandata_address_utils .models import AddressBuilder
809+
810+ address = (
811+ AddressBuilder ()
812+ .with_street_number ("123" )
813+ .with_address_number_suffix ("1/2" )
814+ .with_street_name ("Main" )
815+ .with_street_type ("St" )
816+ .build ()
817+ )
818+ address1 = address .Address1
819+ assert address1 is not None
820+ assert "123" in address1
821+ assert "1/2" in address1
822+
823+ def test_address2_building_name (self ) -> None :
824+ """Address2 should include building name."""
825+ from ryandata_address_utils .models import AddressBuilder
826+
827+ address = (
828+ AddressBuilder ()
829+ .with_street_number ("456" )
830+ .with_street_name ("Oak" )
831+ .with_street_type ("Ave" )
832+ .with_building_name ("The Towers" )
833+ .build ()
834+ )
835+ address1 = address .Address1
836+ address2 = address .Address2
837+ assert address1 is not None
838+ assert "456" in address1
839+ assert address2 is not None
840+ assert "The Towers" in address2
841+
842+ def test_address_formatting_after_parsing (self ) -> None :
843+ """Address properties should be available after parsing."""
844+ result = parse ("123 Main St, Austin TX 78749" )
845+ assert result .address is not None
846+ # All three properties should be available regardless of validation result
847+ assert result .address .Address1 is not None
848+ assert result .address .Address2 is None # No unit info
849+ assert result .address .FullAddress is not None
850+
851+ def test_full_address_format_consistency (self ) -> None :
852+ """FullAddress format should be consistent across different address types."""
853+ from ryandata_address_utils .models import AddressBuilder
854+
855+ # Address without Address2
856+ addr1 = (
857+ AddressBuilder ()
858+ .with_street_number ("100" )
859+ .with_street_name ("First" )
860+ .with_street_type ("Ave" )
861+ .with_city ("Dallas" )
862+ .with_state ("TX" )
863+ .with_zip ("75201" )
864+ .build ()
865+ )
866+ full = addr1 .FullAddress
867+ # Should be: "100 First Ave, Dallas, TX 75201"
868+ assert "100" in full
869+ assert "First" in full
870+ assert "Dallas" in full
871+ assert "TX" in full
872+ assert "75201" in full
873+ # Should contain exactly 3 commas (addr1, city/state/zip)
874+ assert full .count ("," ) >= 1
0 commit comments