jschairb-rets4r 1.1.18
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/.document +5 -0
 - data/CHANGELOG +566 -0
 - data/CONTRIBUTORS +7 -0
 - data/Gemfile +10 -0
 - data/LICENSE +29 -0
 - data/MANIFEST +62 -0
 - data/NEWS +186 -0
 - data/README.rdoc +43 -0
 - data/RUBYS +56 -0
 - data/Rakefile +50 -0
 - data/TODO +35 -0
 - data/examples/client_get_object.rb +49 -0
 - data/examples/client_login.rb +39 -0
 - data/examples/client_mapper.rb +17 -0
 - data/examples/client_metadata.rb +42 -0
 - data/examples/client_parser.rb +9 -0
 - data/examples/client_search.rb +49 -0
 - data/examples/settings.yml +114 -0
 - data/lib/rets4r.rb +14 -0
 - data/lib/rets4r/auth.rb +73 -0
 - data/lib/rets4r/client.rb +487 -0
 - data/lib/rets4r/client/data.rb +14 -0
 - data/lib/rets4r/client/dataobject.rb +28 -0
 - data/lib/rets4r/client/exceptions.rb +116 -0
 - data/lib/rets4r/client/links.rb +32 -0
 - data/lib/rets4r/client/metadata.rb +15 -0
 - data/lib/rets4r/client/parsers/compact.rb +42 -0
 - data/lib/rets4r/client/parsers/compact_nokogiri.rb +91 -0
 - data/lib/rets4r/client/parsers/metadata.rb +92 -0
 - data/lib/rets4r/client/parsers/response_parser.rb +100 -0
 - data/lib/rets4r/client/requester.rb +143 -0
 - data/lib/rets4r/client/transaction.rb +31 -0
 - data/lib/rets4r/core_ext/array/extract_options.rb +15 -0
 - data/lib/rets4r/core_ext/class/attribute_accessors.rb +58 -0
 - data/lib/rets4r/core_ext/hash/keys.rb +46 -0
 - data/lib/rets4r/core_ext/hash/slice.rb +39 -0
 - data/lib/rets4r/listing_mapper.rb +17 -0
 - data/lib/rets4r/listing_service.rb +35 -0
 - data/lib/rets4r/loader.rb +8 -0
 - data/lib/tasks/annotations.rake +121 -0
 - data/lib/tasks/coverage.rake +13 -0
 - data/rets4r.gemspec +24 -0
 - data/spec/rets4r_compact_data_parser_spec.rb +7 -0
 - data/test/data/1.5/bad_compact.xml +7 -0
 - data/test/data/1.5/count_only_compact.xml +3 -0
 - data/test/data/1.5/error.xml +1 -0
 - data/test/data/1.5/invalid_compact.xml +4 -0
 - data/test/data/1.5/login.xml +16 -0
 - data/test/data/1.5/metadata.xml +0 -0
 - data/test/data/1.5/search_compact.xml +8 -0
 - data/test/data/1.5/search_compact_big.xml +136 -0
 - data/test/data/1.5/search_unescaped_compact.xml +8 -0
 - data/test/data/listing_service.yml +36 -0
 - data/test/test_auth.rb +68 -0
 - data/test/test_client.rb +342 -0
 - data/test/test_client_links.rb +39 -0
 - data/test/test_compact_nokogiri.rb +64 -0
 - data/test/test_helper.rb +12 -0
 - data/test/test_listing_mapper.rb +112 -0
 - data/test/test_loader.rb +24 -0
 - data/test/test_parser.rb +96 -0
 - data/test/test_quality.rb +57 -0
 - metadata +211 -0
 
| 
         @@ -0,0 +1,39 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            $:.unshift File.expand_path(File.join(File.dirname(__FILE__), "..", "lib"))
         
     | 
| 
      
 2 
     | 
    
         
            +
            $:.unshift File.expand_path(File.join(File.dirname(__FILE__), "..", "test"))
         
     | 
| 
      
 3 
     | 
    
         
            +
            require 'test_helper'
         
     | 
| 
      
 4 
     | 
    
         
            +
            require 'rets4r/client/links'
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            class TestClientLinks < Test::Unit::TestCase
         
     | 
| 
      
 7 
     | 
    
         
            +
              def setup
         
     | 
| 
      
 8 
     | 
    
         
            +
                @links = RETS4R::Client::Links.from_login_url('http://example.com/login')
         
     | 
| 
      
 9 
     | 
    
         
            +
                @links['Logout'] = URI.parse('http://example.com/logout')
         
     | 
| 
      
 10 
     | 
    
         
            +
                @links['GetMetadata'] = URI.parse('http://example.com/metadata')
         
     | 
| 
      
 11 
     | 
    
         
            +
                @links['GetObject'] = URI.parse('http://example.com/objects')
         
     | 
| 
      
 12 
     | 
    
         
            +
                @links['Search'] = URI.parse('http://example.com/search')
         
     | 
| 
      
 13 
     | 
    
         
            +
                @links['Action'] = URI.parse('http://example.com/action')
         
     | 
| 
      
 14 
     | 
    
         
            +
              end
         
     | 
| 
      
 15 
     | 
    
         
            +
              def test_should_build_from_login_url
         
     | 
| 
      
 16 
     | 
    
         
            +
                assert_equal normalize_url('http://example.com/login'), @links['Login'].to_s
         
     | 
| 
      
 17 
     | 
    
         
            +
              end
         
     | 
| 
      
 18 
     | 
    
         
            +
              def test_should_access_login
         
     | 
| 
      
 19 
     | 
    
         
            +
                assert_equal normalize_url('http://example.com/login'), @links.login.to_s
         
     | 
| 
      
 20 
     | 
    
         
            +
              end
         
     | 
| 
      
 21 
     | 
    
         
            +
              def test_should_access_logout
         
     | 
| 
      
 22 
     | 
    
         
            +
                assert_equal normalize_url('http://example.com/logout'), @links.logout.to_s
         
     | 
| 
      
 23 
     | 
    
         
            +
              end
         
     | 
| 
      
 24 
     | 
    
         
            +
              def test_should_access_metadata
         
     | 
| 
      
 25 
     | 
    
         
            +
                assert_equal normalize_url('http://example.com/metadata'), @links.metadata.to_s
         
     | 
| 
      
 26 
     | 
    
         
            +
              end
         
     | 
| 
      
 27 
     | 
    
         
            +
              def test_should_access_object
         
     | 
| 
      
 28 
     | 
    
         
            +
                assert_equal normalize_url('http://example.com/objects'), @links.objects.to_s
         
     | 
| 
      
 29 
     | 
    
         
            +
              end
         
     | 
| 
      
 30 
     | 
    
         
            +
              def test_should_access_search
         
     | 
| 
      
 31 
     | 
    
         
            +
                assert_equal normalize_url('http://example.com/search'), @links.search.to_s
         
     | 
| 
      
 32 
     | 
    
         
            +
              end
         
     | 
| 
      
 33 
     | 
    
         
            +
              def test_should_access_action
         
     | 
| 
      
 34 
     | 
    
         
            +
                assert_equal normalize_url('http://example.com/action'), @links.action.to_s
         
     | 
| 
      
 35 
     | 
    
         
            +
              end
         
     | 
| 
      
 36 
     | 
    
         
            +
              def normalize_url(url)
         
     | 
| 
      
 37 
     | 
    
         
            +
                URI.parse(url).to_s
         
     | 
| 
      
 38 
     | 
    
         
            +
              end
         
     | 
| 
      
 39 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,64 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            #!/usr/bin/env ruby
         
     | 
| 
      
 2 
     | 
    
         
            +
            $:.unshift File.expand_path(File.join(File.dirname(__FILE__), "."))
         
     | 
| 
      
 3 
     | 
    
         
            +
            require 'test_helper'
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            class CompactNokogiriTest < Test::Unit::TestCase
         
     | 
| 
      
 6 
     | 
    
         
            +
              def test_should_do_stuff
         
     | 
| 
      
 7 
     | 
    
         
            +
                file = File.expand_path(File.join('test', 'data', '1.5', 'search_compact.xml'))
         
     | 
| 
      
 8 
     | 
    
         
            +
                listings = RETS4R::Client::CompactNokogiriParser.new(open(file)).to_a
         
     | 
| 
      
 9 
     | 
    
         
            +
                assert_equal({"Third"=>"Datum3", "Second"=>"Datum2", "First"=>"Datum1"}, listings[0])
         
     | 
| 
      
 10 
     | 
    
         
            +
                assert_equal({"Third"=>"Datum6", "Second"=>"Datum5", "First"=>"Datum4"}, listings[1])
         
     | 
| 
      
 11 
     | 
    
         
            +
              end
         
     | 
| 
      
 12 
     | 
    
         
            +
              def test_should_handle_big_data
         
     | 
| 
      
 13 
     | 
    
         
            +
                file = File.expand_path(File.join('test', 'data', '1.5', 'bad_compact.xml'))
         
     | 
| 
      
 14 
     | 
    
         
            +
                listings = RETS4R::Client::CompactNokogiriParser.new(open(file)).to_a
         
     | 
| 
      
 15 
     | 
    
         
            +
                assert_equal 1, listings.length
         
     | 
| 
      
 16 
     | 
    
         
            +
                assert_equal 79, listings.first.keys.length
         
     | 
| 
      
 17 
     | 
    
         
            +
              end
         
     | 
| 
      
 18 
     | 
    
         
            +
              def test_each_should_yield_between_results
         
     | 
| 
      
 19 
     | 
    
         
            +
                file = File.expand_path(
         
     | 
| 
      
 20 
     | 
    
         
            +
                  File.join('test', 'data', '1.5', 'search_compact_big.xml'))
         
     | 
| 
      
 21 
     | 
    
         
            +
                stat = File::Stat.new(file)
         
     | 
| 
      
 22 
     | 
    
         
            +
                unless stat.size > stat.blksize
         
     | 
| 
      
 23 
     | 
    
         
            +
                  flunk "This test probably won't work on this machine.
         
     | 
| 
      
 24 
     | 
    
         
            +
                    It needs a test input file larger than the native block size."
         
     | 
| 
      
 25 
     | 
    
         
            +
                end
         
     | 
| 
      
 26 
     | 
    
         
            +
                stream = open(file)
         
     | 
| 
      
 27 
     | 
    
         
            +
                positions = []
         
     | 
| 
      
 28 
     | 
    
         
            +
                listings = RETS4R::Client::CompactNokogiriParser.new(stream).each do |row|
         
     | 
| 
      
 29 
     | 
    
         
            +
                  positions << stream.pos
         
     | 
| 
      
 30 
     | 
    
         
            +
                end
         
     | 
| 
      
 31 
     | 
    
         
            +
                assert positions.first < positions.last,
         
     | 
| 
      
 32 
     | 
    
         
            +
                  "data was yielded durring the reading of the stream"
         
     | 
| 
      
 33 
     | 
    
         
            +
              end
         
     | 
| 
      
 34 
     | 
    
         
            +
              def test_should_not_include_column_elements_in_keys
         
     | 
| 
      
 35 
     | 
    
         
            +
                response = "<RETS ReplyCode=\"0\" ReplyText=\"Operation Successful\">\r\n<DELIMITER value=\"09\" />\r\n<COLUMNS>\tDISPLAYORDER\tINPUTDATE\tMEDIADESCR\tMEDIANAME\tMEDIASOURCE\tMEDIATYPE\tMODIFIED\tPICCOUNT\tPRIMARYPIC\tTABLEUID\tUID\t</COLUMNS>\r\n<DATA>\t7\t2009-09-17 07:08:19 \t\tNew 023.jpg\t3155895-11.jpg\tpic\t2009-09-17 07:09:32 \t11\tn\t3155895\t9601458\t</DATA>\r\n<MAXROWS />\r\n</RETS>\r\n"
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
                assert RETS4R::Client::CompactNokogiriParser.new(StringIO.new(response)).map.first.keys.grep( /COLUMN/ ).empty?
         
     | 
| 
      
 38 
     | 
    
         
            +
              end
         
     | 
| 
      
 39 
     | 
    
         
            +
              context 'non-zero reply code' do
         
     | 
| 
      
 40 
     | 
    
         
            +
                setup do
         
     | 
| 
      
 41 
     | 
    
         
            +
                  @response = <<-BODY
         
     | 
| 
      
 42 
     | 
    
         
            +
            <?xml version="1.0"?>
         
     | 
| 
      
 43 
     | 
    
         
            +
            <RETS ReplyCode="20203" ReplyText="User does not have access to Class named RES. Reference ID: 3fe82558-8015-4d9d-ab0c-776d9e4b5943" />
         
     | 
| 
      
 44 
     | 
    
         
            +
                  BODY
         
     | 
| 
      
 45 
     | 
    
         
            +
                  @parser = RETS4R::Client::CompactNokogiriParser.new(StringIO.new(@response))
         
     | 
| 
      
 46 
     | 
    
         
            +
                end
         
     | 
| 
      
 47 
     | 
    
         
            +
                should "raise the execption" do
         
     | 
| 
      
 48 
     | 
    
         
            +
                  assert_raise RETS4R::Client::MiscellaneousSearchErrorException do
         
     | 
| 
      
 49 
     | 
    
         
            +
                    @parser.to_a
         
     | 
| 
      
 50 
     | 
    
         
            +
                  end
         
     | 
| 
      
 51 
     | 
    
         
            +
                end
         
     | 
| 
      
 52 
     | 
    
         
            +
                context 'when i parse' do
         
     | 
| 
      
 53 
     | 
    
         
            +
                  should "contain the reply text in the exception message" do
         
     | 
| 
      
 54 
     | 
    
         
            +
                    message = ''
         
     | 
| 
      
 55 
     | 
    
         
            +
                    begin
         
     | 
| 
      
 56 
     | 
    
         
            +
                      @parser.to_a
         
     | 
| 
      
 57 
     | 
    
         
            +
                    rescue Exception => e
         
     | 
| 
      
 58 
     | 
    
         
            +
                      message = e.message
         
     | 
| 
      
 59 
     | 
    
         
            +
                    end
         
     | 
| 
      
 60 
     | 
    
         
            +
                    assert_equal "User does not have access to Class named RES. Reference ID: 3fe82558-8015-4d9d-ab0c-776d9e4b5943", message
         
     | 
| 
      
 61 
     | 
    
         
            +
                  end
         
     | 
| 
      
 62 
     | 
    
         
            +
                end
         
     | 
| 
      
 63 
     | 
    
         
            +
              end
         
     | 
| 
      
 64 
     | 
    
         
            +
            end
         
     | 
    
        data/test/test_helper.rb
    ADDED
    
    | 
         @@ -0,0 +1,12 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            $:.unshift File.expand_path(File.join(File.dirname(__FILE__), "..", "lib"))
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            require 'test/unit'
         
     | 
| 
      
 4 
     | 
    
         
            +
            require 'rets4r'
         
     | 
| 
      
 5 
     | 
    
         
            +
            require 'mocha'
         
     | 
| 
      
 6 
     | 
    
         
            +
            require 'shoulda'
         
     | 
| 
      
 7 
     | 
    
         
            +
            require 'rubygems'
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            # Configure ListingService
         
     | 
| 
      
 10 
     | 
    
         
            +
            listing_service_config_file = File.expand_path(File.join('test', 'data', 'listing_service.yml'))
         
     | 
| 
      
 11 
     | 
    
         
            +
            RETS4R::ListingService.configurations = YAML.load_file(listing_service_config_file)
         
     | 
| 
      
 12 
     | 
    
         
            +
            RETS4R::ListingService.env = 'test'
         
     | 
| 
         @@ -0,0 +1,112 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            $:.unshift File.expand_path(File.join(File.dirname(__FILE__)))
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'test_helper'
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            class ListingMapperTest < Test::Unit::TestCase
         
     | 
| 
      
 5 
     | 
    
         
            +
              context "ListingMapper" do
         
     | 
| 
      
 6 
     | 
    
         
            +
                should "access select" do
         
     | 
| 
      
 7 
     | 
    
         
            +
                  config = RETS4R::ListingService.connection
         
     | 
| 
      
 8 
     | 
    
         
            +
                  mapper = RETS4R::ListingMapper.new(config)
         
     | 
| 
      
 9 
     | 
    
         
            +
                  assert_equal config[:select], mapper.select
         
     | 
| 
      
 10 
     | 
    
         
            +
                end
         
     | 
| 
      
 11 
     | 
    
         
            +
                should "map from rets keys to record keys" do
         
     | 
| 
      
 12 
     | 
    
         
            +
                  original = {
         
     | 
| 
      
 13 
     | 
    
         
            +
                    "ListingID"=>"11322886",
         
     | 
| 
      
 14 
     | 
    
         
            +
                    "AgentID"=>"000533246",
         
     | 
| 
      
 15 
     | 
    
         
            +
                    "Status"=>"act",
         
     | 
| 
      
 16 
     | 
    
         
            +
                    "ListPrice"=>"239000",
         
     | 
| 
      
 17 
     | 
    
         
            +
                    "StreetNumber"=>"8317",
         
     | 
| 
      
 18 
     | 
    
         
            +
                    "StreetName"=>"Thompson",
         
     | 
| 
      
 19 
     | 
    
         
            +
                    "StreetDirection"=>"",
         
     | 
| 
      
 20 
     | 
    
         
            +
                    "Unit"=>"",
         
     | 
| 
      
 21 
     | 
    
         
            +
                    "ZipCode"=>"79606-6652",
         
     | 
| 
      
 22 
     | 
    
         
            +
                    "City"=>"Abilene",
         
     | 
| 
      
 23 
     | 
    
         
            +
                    "County"=>"Taylor",
         
     | 
| 
      
 24 
     | 
    
         
            +
                    "State"=>"TX",
         
     | 
| 
      
 25 
     | 
    
         
            +
                    "LotSize"=>"LTS.5-.99A",
         
     | 
| 
      
 26 
     | 
    
         
            +
                    "SqFt"=>"2825",
         
     | 
| 
      
 27 
     | 
    
         
            +
                    "LivingArea"=>"2",
         
     | 
| 
      
 28 
     | 
    
         
            +
                    "Bedrooms"=>"4",
         
     | 
| 
      
 29 
     | 
    
         
            +
                    "Garage"=>"PARATTACHE,PAROPENER,PARREAR,PARSIDE",
         
     | 
| 
      
 30 
     | 
    
         
            +
                    "YearBuilt"=>"2005",
         
     | 
| 
      
 31 
     | 
    
         
            +
                    "AgentName"=>"CD Boyd, II",
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
                    "GARAGECAP"=>"2",
         
     | 
| 
      
 34 
     | 
    
         
            +
                    "BATHSFULLBASEMENT"=>"",
         
     | 
| 
      
 35 
     | 
    
         
            +
                    "BATHSFULLLEVEL1"=>"",
         
     | 
| 
      
 36 
     | 
    
         
            +
                    "BATHSFULLLEVEL2"=>"",
         
     | 
| 
      
 37 
     | 
    
         
            +
                    "BATHSFULLLEVEL3"=>"",
         
     | 
| 
      
 38 
     | 
    
         
            +
                    "STORIES"=>"2",
         
     | 
| 
      
 39 
     | 
    
         
            +
                    "INTERIOR"=>"INFBAY-WIN,INFCABLE-A,INFDECLTNG,INFHIGHSPD,INFLOFT,INFSOUND-W,INFVAUL-CL,INFWIND-CO",
         
     | 
| 
      
 40 
     | 
    
         
            +
                    "ACRESCULTIVATED"=>"",
         
     | 
| 
      
 41 
     | 
    
         
            +
                    "CARPORTCAP"=>"0",
         
     | 
| 
      
 42 
     | 
    
         
            +
                    "TAXUNEXEMPT"=>"5876",
         
     | 
| 
      
 43 
     | 
    
         
            +
                    "STREETDIRSUFFIX"=>"",
         
     | 
| 
      
 44 
     | 
    
         
            +
                    "NUMSTOCKTANKS"=>"",
         
     | 
| 
      
 45 
     | 
    
         
            +
                    "LOTDIM"=>"87X182",
         
     | 
| 
      
 46 
     | 
    
         
            +
                    "ACRESPRICE"=>"662049",
         
     | 
| 
      
 47 
     | 
    
         
            +
                    "FIREPLACES"=>"1",
         
     | 
| 
      
 48 
     | 
    
         
            +
                    "SUBDIVISION"=>"Belle Vista Estates",
         
     | 
| 
      
 49 
     | 
    
         
            +
                    "UTILITIES"=>"STUASPHALT,UTLCITY-SE,UTLCITY-WA,STUCONCRET",
         
     | 
| 
      
 50 
     | 
    
         
            +
                    "LISTSTATUSFLAG"=>"",
         
     | 
| 
      
 51 
     | 
    
         
            +
                    "NUMDININGAREAS"=>"2",
         
     | 
| 
      
 52 
     | 
    
         
            +
                    "SQFTPRICE"=>"84.6",
         
     | 
| 
      
 53 
     | 
    
         
            +
                    "MAPPAGE"=>"9999",
         
     | 
| 
      
 54 
     | 
    
         
            +
                    "NUMBARNS"=>"",
         
     | 
| 
      
 55 
     | 
    
         
            +
                    "UIDPRP"=>"3211078",
         
     | 
| 
      
 56 
     | 
    
         
            +
                    "NUMRESIDENCE"=>"",
         
     | 
| 
      
 57 
     | 
    
         
            +
                    "LISTPRICELOW"=>"0",
         
     | 
| 
      
 58 
     | 
    
         
            +
                    "MAPBOOK"=>"OT",
         
     | 
| 
      
 59 
     | 
    
         
            +
                    "LOTNUM"=>"",
         
     | 
| 
      
 60 
     | 
    
         
            +
                    "OFFICELIST_OFFICENAM1"=>"McClure, REALTORS",
         
     | 
| 
      
 61 
     | 
    
         
            +
                    "ACRES"=>"0.361",
         
     | 
| 
      
 62 
     | 
    
         
            +
                    "AGENTSELL_FULLNAME"=>"",
         
     | 
| 
      
 63 
     | 
    
         
            +
                    "BATHSHALFLEVEL1"=>"",
         
     | 
| 
      
 64 
     | 
    
         
            +
                    "PROPSUBTYPE"=>"S",
         
     | 
| 
      
 65 
     | 
    
         
            +
                    "ROOMBEDBATHDESC"=>"BBFJET-TUB,BBFLIN-CLO,BBFSEP-SHO,BBFW+I-CLO",
         
     | 
| 
      
 66 
     | 
    
         
            +
                    "BATHSHALFLEVEL2"=>"",
         
     | 
| 
      
 67 
     | 
    
         
            +
                    "LISTPRICEORIG"=>"239000",
         
     | 
| 
      
 68 
     | 
    
         
            +
                    "BATHSHALFLEVEL3"=>"",
         
     | 
| 
      
 69 
     | 
    
         
            +
                    "UID"=>"3211078",
         
     | 
| 
      
 70 
     | 
    
         
            +
                    "OFFICELIST"=>"FMAB",
         
     | 
| 
      
 71 
     | 
    
         
            +
                    "BATHSHALFBASEMENT"=>"",
         
     | 
| 
      
 72 
     | 
    
         
            +
                    "STORIESBLDG"=>"",
         
     | 
| 
      
 73 
     | 
    
         
            +
                    "REMARKS"=>"Custom home built in 05'.  Growing neighborhood convienient to Wylie schools. Abundant living areas and and open space floor plan.Could be 5th BDRM, or upstair BDRM & Bath could be another living area.  Perfect office next to Master. Gourmet sized kitchen, granite countertops, barell ceilings, wonderful storage space!!!!",
         
     | 
| 
      
 74 
     | 
    
         
            +
                    "STREETNUMDISPLAY"=>"8317",
         
     | 
| 
      
 75 
     | 
    
         
            +
                    "PROPSUBTYPEDISPLAY"=>"RES-S",
         
     | 
| 
      
 76 
     | 
    
         
            +
                    "BATHSHALF"=>"0",
         
     | 
| 
      
 77 
     | 
    
         
            +
                    "STYLE"=>"STYRANCH",
         
     | 
| 
      
 78 
     | 
    
         
            +
                    "COMMONFEATURES"=>"",
         
     | 
| 
      
 79 
     | 
    
         
            +
                    "OFFICESELL_OFFICENAM2"=>"",
         
     | 
| 
      
 80 
     | 
    
         
            +
                    "BATHSFULL"=>"3",
         
     | 
| 
      
 81 
     | 
    
         
            +
                    "MAPCOORD"=>"none",
         
     | 
| 
      
 82 
     | 
    
         
            +
                    "SQFTSOURCE"=>"TAX",
         
     | 
| 
      
 83 
     | 
    
         
            +
                    "NUMLAKES"=>"",
         
     | 
| 
      
 84 
     | 
    
         
            +
                    "NUMWELLS"=>"",
         
     | 
| 
      
 85 
     | 
    
         
            +
                    "NUMPONDS"=>"",
         
     | 
| 
      
 86 
     | 
    
         
            +
                    "LOTDESC"=>"LTDSUBDIV"}
         
     | 
| 
      
 87 
     | 
    
         
            +
                  mapper = RETS4R::ListingMapper.new
         
     | 
| 
      
 88 
     | 
    
         
            +
                  actual = mapper.map(original)
         
     | 
| 
      
 89 
     | 
    
         
            +
                  expected = {
         
     | 
| 
      
 90 
     | 
    
         
            +
                    :mls => "11322886",
         
     | 
| 
      
 91 
     | 
    
         
            +
                    :agent_id =>"000533246",
         
     | 
| 
      
 92 
     | 
    
         
            +
                    :rets_updated_at => nil,
         
     | 
| 
      
 93 
     | 
    
         
            +
                    :status=>"act",
         
     | 
| 
      
 94 
     | 
    
         
            +
                    :list_price =>"239000",
         
     | 
| 
      
 95 
     | 
    
         
            +
                    :street_number =>"8317",
         
     | 
| 
      
 96 
     | 
    
         
            +
                    :street_direction => "",
         
     | 
| 
      
 97 
     | 
    
         
            +
                    :street_name=>"Thompson",
         
     | 
| 
      
 98 
     | 
    
         
            +
                    :unit_number =>"",
         
     | 
| 
      
 99 
     | 
    
         
            +
                    :zip_code =>"79606-6652",
         
     | 
| 
      
 100 
     | 
    
         
            +
                    :city => "Abilene",
         
     | 
| 
      
 101 
     | 
    
         
            +
                    :county =>"Taylor",
         
     | 
| 
      
 102 
     | 
    
         
            +
                    :square_feet =>"2825",
         
     | 
| 
      
 103 
     | 
    
         
            +
                    :living_area => "2",
         
     | 
| 
      
 104 
     | 
    
         
            +
                    :baths =>nil,
         
     | 
| 
      
 105 
     | 
    
         
            +
                    :beds => "4",
         
     | 
| 
      
 106 
     | 
    
         
            +
                    :garage => "PARATTACHE,PAROPENER,PARREAR,PARSIDE",
         
     | 
| 
      
 107 
     | 
    
         
            +
                    :year_built => "2005",
         
     | 
| 
      
 108 
     | 
    
         
            +
                  }
         
     | 
| 
      
 109 
     | 
    
         
            +
                  expected.merge(actual).keys.each{|k| assert_equal expected[k], actual[k], "mismatched on key #{k}"}
         
     | 
| 
      
 110 
     | 
    
         
            +
                end
         
     | 
| 
      
 111 
     | 
    
         
            +
              end
         
     | 
| 
      
 112 
     | 
    
         
            +
            end
         
     | 
    
        data/test/test_loader.rb
    ADDED
    
    | 
         @@ -0,0 +1,24 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            $:.unshift File.expand_path(File.join(File.dirname(__FILE__), "..", "lib"))
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            require 'rets4r'
         
     | 
| 
      
 4 
     | 
    
         
            +
            require 'test/unit'
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            class LoaderTest < Test::Unit::TestCase
         
     | 
| 
      
 7 
     | 
    
         
            +
              def test_should_pass_records_to_block
         
     | 
| 
      
 8 
     | 
    
         
            +
                file = File.expand_path(File.join('test', 'data', '1.5', 'search_compact.xml'))
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
                listings = []
         
     | 
| 
      
 11 
     | 
    
         
            +
                RETS4R::Loader.load(open(file)) do |record|
         
     | 
| 
      
 12 
     | 
    
         
            +
                  listings << record
         
     | 
| 
      
 13 
     | 
    
         
            +
                end
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
                assert_equal 2, listings.length
         
     | 
| 
      
 16 
     | 
    
         
            +
                assert_equal "Datum1", listings[0]['First']
         
     | 
| 
      
 17 
     | 
    
         
            +
                assert_equal "Datum2", listings[0]['Second']
         
     | 
| 
      
 18 
     | 
    
         
            +
                assert_equal "Datum3", listings[0]['Third']
         
     | 
| 
      
 19 
     | 
    
         
            +
                assert_equal "Datum4", listings[1]['First']
         
     | 
| 
      
 20 
     | 
    
         
            +
                assert_equal "Datum5", listings[1]['Second']
         
     | 
| 
      
 21 
     | 
    
         
            +
                assert_equal "Datum6", listings[1]['Third']
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
              end
         
     | 
| 
      
 24 
     | 
    
         
            +
            end
         
     | 
    
        data/test/test_parser.rb
    ADDED
    
    | 
         @@ -0,0 +1,96 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            $:.unshift File.expand_path(File.join(File.dirname(__FILE__), "..", "lib"))
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            require 'test/unit'
         
     | 
| 
      
 4 
     | 
    
         
            +
            require 'rets4r'
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            module RETS4R
         
     | 
| 
      
 7 
     | 
    
         
            +
                class Client
         
     | 
| 
      
 8 
     | 
    
         
            +
                    class TestParser < Test::Unit::TestCase
         
     | 
| 
      
 9 
     | 
    
         
            +
                        def setup
         
     | 
| 
      
 10 
     | 
    
         
            +
                            @parser = ResponseParser.new
         
     | 
| 
      
 11 
     | 
    
         
            +
                        end
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
                        DATA_DIR = 'test/data/1.5/'
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
                        def load_xml_from_file(file_name)
         
     | 
| 
      
 16 
     | 
    
         
            +
                            xml = ''
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                            File.open(file_name) do |file|
         
     | 
| 
      
 19 
     | 
    
         
            +
                                file.each do |line|
         
     | 
| 
      
 20 
     | 
    
         
            +
                                    xml << line
         
     | 
| 
      
 21 
     | 
    
         
            +
                                end
         
     | 
| 
      
 22 
     | 
    
         
            +
                            end
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
                            xml
         
     | 
| 
      
 25 
     | 
    
         
            +
                        end
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
                        def parse_to_transaction(xml_file_name)
         
     | 
| 
      
 28 
     | 
    
         
            +
                            @parser.parse_key_value(load_xml_from_file(xml_file_name))
         
     | 
| 
      
 29 
     | 
    
         
            +
                        end
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
                        # Test Cases
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
            #           TODO: verify test_search_compact header, metadata
         
     | 
| 
      
 34 
     | 
    
         
            +
                        def test_search_compact
         
     | 
| 
      
 35 
     | 
    
         
            +
                            xml = load_xml_from_file("#{DATA_DIR}search_compact.xml")
         
     | 
| 
      
 36 
     | 
    
         
            +
                            transaction = @parser.parse_results(xml, 'COMPACT')
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
                            assert_equal true, transaction.success?, "transaction should be successful"
         
     | 
| 
      
 39 
     | 
    
         
            +
                            assert_equal '0', transaction.reply_code
         
     | 
| 
      
 40 
     | 
    
         
            +
                            assert_equal 'SUCCESS', transaction.reply_text
         
     | 
| 
      
 41 
     | 
    
         
            +
                            assert_equal [], transaction.header
         
     | 
| 
      
 42 
     | 
    
         
            +
                            # XXX: this used to say, why?
         
     | 
| 
      
 43 
     | 
    
         
            +
            #                assert_equal false, transaction.header.empty?
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
                            assert_equal nil, transaction.metadata
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
                            assert_equal ?\t, transaction.delimiter
         
     | 
| 
      
 48 
     | 
    
         
            +
                            assert_equal "\t", transaction.ascii_delimiter
         
     | 
| 
      
 49 
     | 
    
         
            +
                            assert_equal true, transaction.maxrows?
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
                            assert_equal 2, transaction.response.length, 'response length should be 2'
         
     | 
| 
      
 52 
     | 
    
         
            +
                            assert_equal "Datum1", transaction.response[0]['First']
         
     | 
| 
      
 53 
     | 
    
         
            +
                            assert_equal "Datum2", transaction.response[0]['Second']
         
     | 
| 
      
 54 
     | 
    
         
            +
                            assert_equal "Datum3", transaction.response[0]['Third']
         
     | 
| 
      
 55 
     | 
    
         
            +
                            assert_equal "Datum4", transaction.response[1]['First']
         
     | 
| 
      
 56 
     | 
    
         
            +
                            assert_equal "Datum5", transaction.response[1]['Second']
         
     | 
| 
      
 57 
     | 
    
         
            +
                            assert_equal "Datum6", transaction.response[1]['Third']
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
                            # Check for compatibility
         
     | 
| 
      
 60 
     | 
    
         
            +
                            assert_equal transaction.data, transaction.response
         
     | 
| 
      
 61 
     | 
    
         
            +
             
     | 
| 
      
 62 
     | 
    
         
            +
                            assert_equal nil, transaction.secondary_response
         
     | 
| 
      
 63 
     | 
    
         
            +
                        end
         
     | 
| 
      
 64 
     | 
    
         
            +
             
     | 
| 
      
 65 
     | 
    
         
            +
                        def test_unescaped_search_compact
         
     | 
| 
      
 66 
     | 
    
         
            +
                          assert_raise(REXML::ParseException) do
         
     | 
| 
      
 67 
     | 
    
         
            +
                            @parser.parse_key_value(load_xml_from_file("#{DATA_DIR}search_unescaped_compact.xml"))
         
     | 
| 
      
 68 
     | 
    
         
            +
                          end
         
     | 
| 
      
 69 
     | 
    
         
            +
                        end
         
     | 
| 
      
 70 
     | 
    
         
            +
             
     | 
| 
      
 71 
     | 
    
         
            +
                        def test_invalid_search_compact
         
     | 
| 
      
 72 
     | 
    
         
            +
                            assert_raise(REXML::ParseException) do
         
     | 
| 
      
 73 
     | 
    
         
            +
                              @parser.parse_key_value(load_xml_from_file("#{DATA_DIR}search_unescaped_compact.xml"))
         
     | 
| 
      
 74 
     | 
    
         
            +
                            end
         
     | 
| 
      
 75 
     | 
    
         
            +
                        end
         
     | 
| 
      
 76 
     | 
    
         
            +
             
     | 
| 
      
 77 
     | 
    
         
            +
                        def test_login_results
         
     | 
| 
      
 78 
     | 
    
         
            +
                            transaction = parse_to_transaction("#{DATA_DIR}login.xml")
         
     | 
| 
      
 79 
     | 
    
         
            +
             
     | 
| 
      
 80 
     | 
    
         
            +
                            assert_equal(true, transaction.success?)
         
     | 
| 
      
 81 
     | 
    
         
            +
                            assert_equal('srealtor,1,11,11111', transaction.response['User'])
         
     | 
| 
      
 82 
     | 
    
         
            +
                            assert_equal('/rets/Login', transaction.response['Login'])
         
     | 
| 
      
 83 
     | 
    
         
            +
                        end
         
     | 
| 
      
 84 
     | 
    
         
            +
             
     | 
| 
      
 85 
     | 
    
         
            +
                        def test_error_results
         
     | 
| 
      
 86 
     | 
    
         
            +
                            xml = load_xml_from_file("#{DATA_DIR}error.xml")
         
     | 
| 
      
 87 
     | 
    
         
            +
             
     | 
| 
      
 88 
     | 
    
         
            +
                            exception = assert_raise(InvalidResourceException) do
         
     | 
| 
      
 89 
     | 
    
         
            +
                              @parser.parse_object_response(xml)
         
     | 
| 
      
 90 
     | 
    
         
            +
                            end
         
     | 
| 
      
 91 
     | 
    
         
            +
             
     | 
| 
      
 92 
     | 
    
         
            +
                            assert_equal('20400 - Invalid Invalidness.', exception.message)
         
     | 
| 
      
 93 
     | 
    
         
            +
                        end
         
     | 
| 
      
 94 
     | 
    
         
            +
                    end
         
     | 
| 
      
 95 
     | 
    
         
            +
                end
         
     | 
| 
      
 96 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,57 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            #!/usr/bin/env ruby -w
         
     | 
| 
      
 2 
     | 
    
         
            +
            libdir = File.expand_path('../../lib', __FILE__)
         
     | 
| 
      
 3 
     | 
    
         
            +
            $LOAD_PATH.unshift(libdir) unless $LOAD_PATH.include?(libdir)
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            require "test/unit"
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            class TestQuality < Test::Unit::TestCase
         
     | 
| 
      
 8 
     | 
    
         
            +
              def test_can_still_be_built
         
     | 
| 
      
 9 
     | 
    
         
            +
                Dir.chdir(root) do
         
     | 
| 
      
 10 
     | 
    
         
            +
                  `gem build rets4r.gemspec`
         
     | 
| 
      
 11 
     | 
    
         
            +
                  assert_equal 0, $?
         
     | 
| 
      
 12 
     | 
    
         
            +
                end
         
     | 
| 
      
 13 
     | 
    
         
            +
              end
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
              def test_has_no_malformed_whitespace
         
     | 
| 
      
 16 
     | 
    
         
            +
                error_messages = []
         
     | 
| 
      
 17 
     | 
    
         
            +
                Dir.chdir(root) do
         
     | 
| 
      
 18 
     | 
    
         
            +
                  File.read("MANIFEST").split("\n").each do |filename|
         
     | 
| 
      
 19 
     | 
    
         
            +
                    next if filename =~ /data/
         
     | 
| 
      
 20 
     | 
    
         
            +
                    error_messages << check_for_tab_characters(filename)
         
     | 
| 
      
 21 
     | 
    
         
            +
                    error_messages << check_for_extra_spaces(filename)
         
     | 
| 
      
 22 
     | 
    
         
            +
                  end
         
     | 
| 
      
 23 
     | 
    
         
            +
                end
         
     | 
| 
      
 24 
     | 
    
         
            +
                assert_well_formed error_messages.compact
         
     | 
| 
      
 25 
     | 
    
         
            +
              end
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
              def assert_well_formed(actual)
         
     | 
| 
      
 28 
     | 
    
         
            +
                assert actual.empty?, actual.join("\n")
         
     | 
| 
      
 29 
     | 
    
         
            +
              end
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
              def check_for_tab_characters(filename)
         
     | 
| 
      
 32 
     | 
    
         
            +
                failing_lines = []
         
     | 
| 
      
 33 
     | 
    
         
            +
                File.readlines(filename).each_with_index do |line,number|
         
     | 
| 
      
 34 
     | 
    
         
            +
                  failing_lines << number + 1 if line =~ /\t/
         
     | 
| 
      
 35 
     | 
    
         
            +
                end
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
                unless failing_lines.empty?
         
     | 
| 
      
 38 
     | 
    
         
            +
                  "#{filename} has tab characters on lines #{failing_lines.join(', ')}"
         
     | 
| 
      
 39 
     | 
    
         
            +
                end
         
     | 
| 
      
 40 
     | 
    
         
            +
              end
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
              def check_for_extra_spaces(filename)
         
     | 
| 
      
 43 
     | 
    
         
            +
                failing_lines = []
         
     | 
| 
      
 44 
     | 
    
         
            +
                File.readlines(filename).each_with_index do |line,number|
         
     | 
| 
      
 45 
     | 
    
         
            +
                  next if line =~ /^\s+#.*\s+\n$/
         
     | 
| 
      
 46 
     | 
    
         
            +
                  failing_lines << number + 1 if line =~ /\s+\n$/
         
     | 
| 
      
 47 
     | 
    
         
            +
                end
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
                unless failing_lines.empty?
         
     | 
| 
      
 50 
     | 
    
         
            +
                  "#{filename} has spaces on the EOL on lines #{failing_lines.join(', ')}"
         
     | 
| 
      
 51 
     | 
    
         
            +
                end
         
     | 
| 
      
 52 
     | 
    
         
            +
              end
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
      
 54 
     | 
    
         
            +
              def root
         
     | 
| 
      
 55 
     | 
    
         
            +
                File.expand_path("../..", __FILE__)
         
     | 
| 
      
 56 
     | 
    
         
            +
              end
         
     | 
| 
      
 57 
     | 
    
         
            +
            end
         
     | 
    
        metadata
    ADDED
    
    | 
         @@ -0,0 +1,211 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            --- !ruby/object:Gem::Specification 
         
     | 
| 
      
 2 
     | 
    
         
            +
            name: jschairb-rets4r
         
     | 
| 
      
 3 
     | 
    
         
            +
            version: !ruby/object:Gem::Version 
         
     | 
| 
      
 4 
     | 
    
         
            +
              hash: 55
         
     | 
| 
      
 5 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 6 
     | 
    
         
            +
              segments: 
         
     | 
| 
      
 7 
     | 
    
         
            +
              - 1
         
     | 
| 
      
 8 
     | 
    
         
            +
              - 1
         
     | 
| 
      
 9 
     | 
    
         
            +
              - 18
         
     | 
| 
      
 10 
     | 
    
         
            +
              version: 1.1.18
         
     | 
| 
      
 11 
     | 
    
         
            +
            platform: ruby
         
     | 
| 
      
 12 
     | 
    
         
            +
            authors: 
         
     | 
| 
      
 13 
     | 
    
         
            +
            - Scott Patterson
         
     | 
| 
      
 14 
     | 
    
         
            +
            - John Wulff
         
     | 
| 
      
 15 
     | 
    
         
            +
            - bgetting
         
     | 
| 
      
 16 
     | 
    
         
            +
            - Jacob Basham
         
     | 
| 
      
 17 
     | 
    
         
            +
            - Joseph Holsten
         
     | 
| 
      
 18 
     | 
    
         
            +
            autorequire: 
         
     | 
| 
      
 19 
     | 
    
         
            +
            bindir: bin
         
     | 
| 
      
 20 
     | 
    
         
            +
            cert_chain: []
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
            date: 2011-01-05 00:00:00 -06:00
         
     | 
| 
      
 23 
     | 
    
         
            +
            default_executable: 
         
     | 
| 
      
 24 
     | 
    
         
            +
            dependencies: 
         
     | 
| 
      
 25 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency 
         
     | 
| 
      
 26 
     | 
    
         
            +
              name: nokogiri
         
     | 
| 
      
 27 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 28 
     | 
    
         
            +
              requirement: &id001 !ruby/object:Gem::Requirement 
         
     | 
| 
      
 29 
     | 
    
         
            +
                none: false
         
     | 
| 
      
 30 
     | 
    
         
            +
                requirements: 
         
     | 
| 
      
 31 
     | 
    
         
            +
                - - ~>
         
     | 
| 
      
 32 
     | 
    
         
            +
                  - !ruby/object:Gem::Version 
         
     | 
| 
      
 33 
     | 
    
         
            +
                    hash: 7
         
     | 
| 
      
 34 
     | 
    
         
            +
                    segments: 
         
     | 
| 
      
 35 
     | 
    
         
            +
                    - 1
         
     | 
| 
      
 36 
     | 
    
         
            +
                    - 4
         
     | 
| 
      
 37 
     | 
    
         
            +
                    - 0
         
     | 
| 
      
 38 
     | 
    
         
            +
                    version: 1.4.0
         
     | 
| 
      
 39 
     | 
    
         
            +
              type: :runtime
         
     | 
| 
      
 40 
     | 
    
         
            +
              version_requirements: *id001
         
     | 
| 
      
 41 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency 
         
     | 
| 
      
 42 
     | 
    
         
            +
              name: mocha
         
     | 
| 
      
 43 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 44 
     | 
    
         
            +
              requirement: &id002 !ruby/object:Gem::Requirement 
         
     | 
| 
      
 45 
     | 
    
         
            +
                none: false
         
     | 
| 
      
 46 
     | 
    
         
            +
                requirements: 
         
     | 
| 
      
 47 
     | 
    
         
            +
                - - ">="
         
     | 
| 
      
 48 
     | 
    
         
            +
                  - !ruby/object:Gem::Version 
         
     | 
| 
      
 49 
     | 
    
         
            +
                    hash: 3
         
     | 
| 
      
 50 
     | 
    
         
            +
                    segments: 
         
     | 
| 
      
 51 
     | 
    
         
            +
                    - 0
         
     | 
| 
      
 52 
     | 
    
         
            +
                    version: "0"
         
     | 
| 
      
 53 
     | 
    
         
            +
              type: :development
         
     | 
| 
      
 54 
     | 
    
         
            +
              version_requirements: *id002
         
     | 
| 
      
 55 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency 
         
     | 
| 
      
 56 
     | 
    
         
            +
              name: shoulda
         
     | 
| 
      
 57 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 58 
     | 
    
         
            +
              requirement: &id003 !ruby/object:Gem::Requirement 
         
     | 
| 
      
 59 
     | 
    
         
            +
                none: false
         
     | 
| 
      
 60 
     | 
    
         
            +
                requirements: 
         
     | 
| 
      
 61 
     | 
    
         
            +
                - - ">="
         
     | 
| 
      
 62 
     | 
    
         
            +
                  - !ruby/object:Gem::Version 
         
     | 
| 
      
 63 
     | 
    
         
            +
                    hash: 3
         
     | 
| 
      
 64 
     | 
    
         
            +
                    segments: 
         
     | 
| 
      
 65 
     | 
    
         
            +
                    - 0
         
     | 
| 
      
 66 
     | 
    
         
            +
                    version: "0"
         
     | 
| 
      
 67 
     | 
    
         
            +
              type: :development
         
     | 
| 
      
 68 
     | 
    
         
            +
              version_requirements: *id003
         
     | 
| 
      
 69 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency 
         
     | 
| 
      
 70 
     | 
    
         
            +
              name: activesupport
         
     | 
| 
      
 71 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 72 
     | 
    
         
            +
              requirement: &id004 !ruby/object:Gem::Requirement 
         
     | 
| 
      
 73 
     | 
    
         
            +
                none: false
         
     | 
| 
      
 74 
     | 
    
         
            +
                requirements: 
         
     | 
| 
      
 75 
     | 
    
         
            +
                - - ">="
         
     | 
| 
      
 76 
     | 
    
         
            +
                  - !ruby/object:Gem::Version 
         
     | 
| 
      
 77 
     | 
    
         
            +
                    hash: 3
         
     | 
| 
      
 78 
     | 
    
         
            +
                    segments: 
         
     | 
| 
      
 79 
     | 
    
         
            +
                    - 0
         
     | 
| 
      
 80 
     | 
    
         
            +
                    version: "0"
         
     | 
| 
      
 81 
     | 
    
         
            +
              type: :development
         
     | 
| 
      
 82 
     | 
    
         
            +
              version_requirements: *id004
         
     | 
| 
      
 83 
     | 
    
         
            +
            description: RETS4R is a native Ruby interface to the RETS (Real Estate Transaction Standard). It currently is built for the 1.5 specification, but support for 1.7 and 2.0 are planned. It does not currently implement all of the specification, but the most commonly used portions. Specifically, there is no support for Update transactions.
         
     | 
| 
      
 84 
     | 
    
         
            +
            email: 
         
     | 
| 
      
 85 
     | 
    
         
            +
            - scott.patterson@digitalaun.com
         
     | 
| 
      
 86 
     | 
    
         
            +
            - john@johnwulff.com
         
     | 
| 
      
 87 
     | 
    
         
            +
            - brian@terra-firma-design.com
         
     | 
| 
      
 88 
     | 
    
         
            +
            - jacob@paperpigeons.net
         
     | 
| 
      
 89 
     | 
    
         
            +
            - joseph@josephholsten.com
         
     | 
| 
      
 90 
     | 
    
         
            +
            executables: []
         
     | 
| 
      
 91 
     | 
    
         
            +
             
     | 
| 
      
 92 
     | 
    
         
            +
            extensions: []
         
     | 
| 
      
 93 
     | 
    
         
            +
             
     | 
| 
      
 94 
     | 
    
         
            +
            extra_rdoc_files: 
         
     | 
| 
      
 95 
     | 
    
         
            +
            - CHANGELOG
         
     | 
| 
      
 96 
     | 
    
         
            +
            - CONTRIBUTORS
         
     | 
| 
      
 97 
     | 
    
         
            +
            - LICENSE
         
     | 
| 
      
 98 
     | 
    
         
            +
            - MANIFEST
         
     | 
| 
      
 99 
     | 
    
         
            +
            - NEWS
         
     | 
| 
      
 100 
     | 
    
         
            +
            - README.rdoc
         
     | 
| 
      
 101 
     | 
    
         
            +
            - RUBYS
         
     | 
| 
      
 102 
     | 
    
         
            +
            - TODO
         
     | 
| 
      
 103 
     | 
    
         
            +
            files: 
         
     | 
| 
      
 104 
     | 
    
         
            +
            - .document
         
     | 
| 
      
 105 
     | 
    
         
            +
            - CHANGELOG
         
     | 
| 
      
 106 
     | 
    
         
            +
            - CONTRIBUTORS
         
     | 
| 
      
 107 
     | 
    
         
            +
            - Gemfile
         
     | 
| 
      
 108 
     | 
    
         
            +
            - LICENSE
         
     | 
| 
      
 109 
     | 
    
         
            +
            - MANIFEST
         
     | 
| 
      
 110 
     | 
    
         
            +
            - NEWS
         
     | 
| 
      
 111 
     | 
    
         
            +
            - README.rdoc
         
     | 
| 
      
 112 
     | 
    
         
            +
            - RUBYS
         
     | 
| 
      
 113 
     | 
    
         
            +
            - Rakefile
         
     | 
| 
      
 114 
     | 
    
         
            +
            - TODO
         
     | 
| 
      
 115 
     | 
    
         
            +
            - examples/client_get_object.rb
         
     | 
| 
      
 116 
     | 
    
         
            +
            - examples/client_login.rb
         
     | 
| 
      
 117 
     | 
    
         
            +
            - examples/client_mapper.rb
         
     | 
| 
      
 118 
     | 
    
         
            +
            - examples/client_metadata.rb
         
     | 
| 
      
 119 
     | 
    
         
            +
            - examples/client_parser.rb
         
     | 
| 
      
 120 
     | 
    
         
            +
            - examples/client_search.rb
         
     | 
| 
      
 121 
     | 
    
         
            +
            - examples/settings.yml
         
     | 
| 
      
 122 
     | 
    
         
            +
            - lib/rets4r.rb
         
     | 
| 
      
 123 
     | 
    
         
            +
            - lib/rets4r/auth.rb
         
     | 
| 
      
 124 
     | 
    
         
            +
            - lib/rets4r/client.rb
         
     | 
| 
      
 125 
     | 
    
         
            +
            - lib/rets4r/client/data.rb
         
     | 
| 
      
 126 
     | 
    
         
            +
            - lib/rets4r/client/dataobject.rb
         
     | 
| 
      
 127 
     | 
    
         
            +
            - lib/rets4r/client/exceptions.rb
         
     | 
| 
      
 128 
     | 
    
         
            +
            - lib/rets4r/client/links.rb
         
     | 
| 
      
 129 
     | 
    
         
            +
            - lib/rets4r/client/metadata.rb
         
     | 
| 
      
 130 
     | 
    
         
            +
            - lib/rets4r/client/parsers/compact.rb
         
     | 
| 
      
 131 
     | 
    
         
            +
            - lib/rets4r/client/parsers/compact_nokogiri.rb
         
     | 
| 
      
 132 
     | 
    
         
            +
            - lib/rets4r/client/parsers/metadata.rb
         
     | 
| 
      
 133 
     | 
    
         
            +
            - lib/rets4r/client/parsers/response_parser.rb
         
     | 
| 
      
 134 
     | 
    
         
            +
            - lib/rets4r/client/requester.rb
         
     | 
| 
      
 135 
     | 
    
         
            +
            - lib/rets4r/client/transaction.rb
         
     | 
| 
      
 136 
     | 
    
         
            +
            - lib/rets4r/core_ext/array/extract_options.rb
         
     | 
| 
      
 137 
     | 
    
         
            +
            - lib/rets4r/core_ext/class/attribute_accessors.rb
         
     | 
| 
      
 138 
     | 
    
         
            +
            - lib/rets4r/core_ext/hash/keys.rb
         
     | 
| 
      
 139 
     | 
    
         
            +
            - lib/rets4r/core_ext/hash/slice.rb
         
     | 
| 
      
 140 
     | 
    
         
            +
            - lib/rets4r/listing_mapper.rb
         
     | 
| 
      
 141 
     | 
    
         
            +
            - lib/rets4r/listing_service.rb
         
     | 
| 
      
 142 
     | 
    
         
            +
            - lib/rets4r/loader.rb
         
     | 
| 
      
 143 
     | 
    
         
            +
            - lib/tasks/annotations.rake
         
     | 
| 
      
 144 
     | 
    
         
            +
            - lib/tasks/coverage.rake
         
     | 
| 
      
 145 
     | 
    
         
            +
            - rets4r.gemspec
         
     | 
| 
      
 146 
     | 
    
         
            +
            - spec/rets4r_compact_data_parser_spec.rb
         
     | 
| 
      
 147 
     | 
    
         
            +
            - test/data/1.5/bad_compact.xml
         
     | 
| 
      
 148 
     | 
    
         
            +
            - test/data/1.5/count_only_compact.xml
         
     | 
| 
      
 149 
     | 
    
         
            +
            - test/data/1.5/error.xml
         
     | 
| 
      
 150 
     | 
    
         
            +
            - test/data/1.5/invalid_compact.xml
         
     | 
| 
      
 151 
     | 
    
         
            +
            - test/data/1.5/login.xml
         
     | 
| 
      
 152 
     | 
    
         
            +
            - test/data/1.5/metadata.xml
         
     | 
| 
      
 153 
     | 
    
         
            +
            - test/data/1.5/search_compact.xml
         
     | 
| 
      
 154 
     | 
    
         
            +
            - test/data/1.5/search_compact_big.xml
         
     | 
| 
      
 155 
     | 
    
         
            +
            - test/data/1.5/search_unescaped_compact.xml
         
     | 
| 
      
 156 
     | 
    
         
            +
            - test/data/listing_service.yml
         
     | 
| 
      
 157 
     | 
    
         
            +
            - test/test_auth.rb
         
     | 
| 
      
 158 
     | 
    
         
            +
            - test/test_client.rb
         
     | 
| 
      
 159 
     | 
    
         
            +
            - test/test_client_links.rb
         
     | 
| 
      
 160 
     | 
    
         
            +
            - test/test_compact_nokogiri.rb
         
     | 
| 
      
 161 
     | 
    
         
            +
            - test/test_helper.rb
         
     | 
| 
      
 162 
     | 
    
         
            +
            - test/test_listing_mapper.rb
         
     | 
| 
      
 163 
     | 
    
         
            +
            - test/test_loader.rb
         
     | 
| 
      
 164 
     | 
    
         
            +
            - test/test_parser.rb
         
     | 
| 
      
 165 
     | 
    
         
            +
            - test/test_quality.rb
         
     | 
| 
      
 166 
     | 
    
         
            +
            has_rdoc: true
         
     | 
| 
      
 167 
     | 
    
         
            +
            homepage: http://rets4r.rubyforge.org/
         
     | 
| 
      
 168 
     | 
    
         
            +
            licenses: []
         
     | 
| 
      
 169 
     | 
    
         
            +
             
     | 
| 
      
 170 
     | 
    
         
            +
            post_install_message: 
         
     | 
| 
      
 171 
     | 
    
         
            +
            rdoc_options: 
         
     | 
| 
      
 172 
     | 
    
         
            +
            - --charset=UTF-8
         
     | 
| 
      
 173 
     | 
    
         
            +
            - --main
         
     | 
| 
      
 174 
     | 
    
         
            +
            - README.rdoc
         
     | 
| 
      
 175 
     | 
    
         
            +
            require_paths: 
         
     | 
| 
      
 176 
     | 
    
         
            +
            - lib
         
     | 
| 
      
 177 
     | 
    
         
            +
            required_ruby_version: !ruby/object:Gem::Requirement 
         
     | 
| 
      
 178 
     | 
    
         
            +
              none: false
         
     | 
| 
      
 179 
     | 
    
         
            +
              requirements: 
         
     | 
| 
      
 180 
     | 
    
         
            +
              - - ">="
         
     | 
| 
      
 181 
     | 
    
         
            +
                - !ruby/object:Gem::Version 
         
     | 
| 
      
 182 
     | 
    
         
            +
                  hash: 3
         
     | 
| 
      
 183 
     | 
    
         
            +
                  segments: 
         
     | 
| 
      
 184 
     | 
    
         
            +
                  - 0
         
     | 
| 
      
 185 
     | 
    
         
            +
                  version: "0"
         
     | 
| 
      
 186 
     | 
    
         
            +
            required_rubygems_version: !ruby/object:Gem::Requirement 
         
     | 
| 
      
 187 
     | 
    
         
            +
              none: false
         
     | 
| 
      
 188 
     | 
    
         
            +
              requirements: 
         
     | 
| 
      
 189 
     | 
    
         
            +
              - - ">="
         
     | 
| 
      
 190 
     | 
    
         
            +
                - !ruby/object:Gem::Version 
         
     | 
| 
      
 191 
     | 
    
         
            +
                  hash: 3
         
     | 
| 
      
 192 
     | 
    
         
            +
                  segments: 
         
     | 
| 
      
 193 
     | 
    
         
            +
                  - 0
         
     | 
| 
      
 194 
     | 
    
         
            +
                  version: "0"
         
     | 
| 
      
 195 
     | 
    
         
            +
            requirements: []
         
     | 
| 
      
 196 
     | 
    
         
            +
             
     | 
| 
      
 197 
     | 
    
         
            +
            rubyforge_project: rets4r
         
     | 
| 
      
 198 
     | 
    
         
            +
            rubygems_version: 1.3.7
         
     | 
| 
      
 199 
     | 
    
         
            +
            signing_key: 
         
     | 
| 
      
 200 
     | 
    
         
            +
            specification_version: 3
         
     | 
| 
      
 201 
     | 
    
         
            +
            summary: RETS4R is a native Ruby interface to the RETS (Real Estate Transaction Standard)
         
     | 
| 
      
 202 
     | 
    
         
            +
            test_files: 
         
     | 
| 
      
 203 
     | 
    
         
            +
            - test/test_auth.rb
         
     | 
| 
      
 204 
     | 
    
         
            +
            - test/test_client.rb
         
     | 
| 
      
 205 
     | 
    
         
            +
            - test/test_client_links.rb
         
     | 
| 
      
 206 
     | 
    
         
            +
            - test/test_compact_nokogiri.rb
         
     | 
| 
      
 207 
     | 
    
         
            +
            - test/test_helper.rb
         
     | 
| 
      
 208 
     | 
    
         
            +
            - test/test_listing_mapper.rb
         
     | 
| 
      
 209 
     | 
    
         
            +
            - test/test_loader.rb
         
     | 
| 
      
 210 
     | 
    
         
            +
            - test/test_parser.rb
         
     | 
| 
      
 211 
     | 
    
         
            +
            - test/test_quality.rb
         
     |