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