sean-rets 0.6.0

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.
@@ -0,0 +1,86 @@
1
+ require_relative "helper"
2
+
3
+ class TestParserCompact < MiniTest::Test
4
+ def test_parse_document_raises_on_invalid_delimiter
5
+ assert_raises Rets::Parser::Compact::InvalidDelimiter do
6
+ Rets::Parser::Compact.parse_document(INVALID_DELIMETER)
7
+ end
8
+ end
9
+
10
+ def test_parse_document_uses_default_delimiter_when_none_provided
11
+ # we assert that the delimeter character getting to parse is a tab
12
+ # even though COMPACT defines no delimiter tag
13
+ Rets::Parser::Compact.expects(:parse).with("A\tB", "1\t2", /\t/)
14
+ Rets::Parser::Compact.expects(:parse).with("A\tB", "4\t5", /\t/)
15
+ Rets::Parser::Compact.parse_document(COMPACT)
16
+ end
17
+
18
+ def test_parse_document_delegates_to_parse
19
+ result = Rets::Parser::Compact.parse_document(COMPACT)
20
+
21
+ assert_equal([{"A" => "1", "B" => "2"}, {"A" => "4", "B" => "5"}], result)
22
+ end
23
+
24
+ def test_parser_rejects_empty_key_value_pairs
25
+ result = Rets::Parser::Compact.parse_document(METADATA_OBJECT)
26
+
27
+ result.each do |row|
28
+ assert !row.any? { |k,v| k.to_s.size == 0 }, "Should not contain empty keys"
29
+ end
30
+ end
31
+
32
+ def test_parse_returns_key_value_pairs
33
+ result = Rets::Parser::Compact.parse("A\tB", "1\t2")
34
+
35
+ assert_equal({"A" => "1", "B" => "2"}, result)
36
+ end
37
+
38
+ # RMLS does this. :|
39
+ def test_remaining_columns_produce_empty_string_values
40
+ columns = "A B C D"
41
+ data = "1 2"
42
+
43
+ assert_equal({"A" => "1", "B" => "2", "C" => "", "D" => ""}, Rets::Parser::Compact.parse(columns, data, / /))
44
+ end
45
+
46
+ def test_leading_empty_columns_are_preserved_with_delimiter
47
+ columns = "A\tB\tC\tD"
48
+ data = "\t\t3\t4" # first two columns are empty data.
49
+
50
+ assert_equal({"A" => "", "B" => "", "C" => "3", "D" => "4"}, Rets::Parser::Compact.parse(columns, data, /\t/))
51
+ end
52
+
53
+ def test_parse_only_accepts_regexp
54
+ assert_raises ArgumentError do
55
+ Rets::Parser::Compact.parse("a", "b", " ")
56
+ end
57
+ end
58
+
59
+ def test_parse_empty_document
60
+ rows = Rets::Parser::Compact.parse_document(EMPTY_COMPACT)
61
+ assert_equal [], rows
62
+ end
63
+
64
+ def test_get_count
65
+ count = Rets::Parser::Compact.get_count(COUNT_ONLY)
66
+ assert_equal 1234, count
67
+ end
68
+
69
+ def test_get_count_with_no_matching_records
70
+ count = Rets::Parser::Compact.get_count(RETS_STATUS_NO_MATCHING_RECORDS)
71
+ assert_equal 0, count
72
+ end
73
+
74
+ def test_parse_example
75
+ rows = Rets::Parser::Compact.parse_document(Nokogiri.parse(SAMPLE_COMPACT))
76
+
77
+ assert_equal "7", rows.first["MetadataEntryID"]
78
+ end
79
+
80
+ def test_parse_example_2
81
+ rows = Rets::Parser::Compact.parse_document(Nokogiri.parse(SAMPLE_COMPACT_2))
82
+
83
+ assert_equal "", rows.first["ModTimeStamp"]
84
+ end
85
+
86
+ end
@@ -0,0 +1,39 @@
1
+ require_relative "helper"
2
+
3
+ class TestParserMultipart < MiniTest::Test
4
+ def test_parse_returns_multiple_parts
5
+ headers = {"content-type"=>"image/jpeg", "content-id"=>"90020062739", "content-length"=>"10"}
6
+
7
+ parts = Rets::Parser::Multipart.parse(MULITPART_RESPONSE, "simple boundary")
8
+
9
+ assert_equal 2, parts.size
10
+
11
+ part = parts[0]
12
+
13
+ assert_equal headers.merge("object-id" => "1"), part.headers
14
+ assert_equal "xxxxxxxx", part.body.strip
15
+
16
+ part = parts[1]
17
+
18
+ assert_equal headers.merge("object-id" => "2"), part.headers
19
+ assert_equal "yyyyyyyy", part.body.strip
20
+ end
21
+
22
+ def test_parse_real_mls_data
23
+ parts = Rets::Parser::Multipart.parse(MULTIPART_RESPONSE_URLS, "rets.object.content.boundary.1330546052739")
24
+ assert_equal 5, parts.size
25
+ end
26
+
27
+ def test_parse_values_with_colon_data
28
+ parts = Rets::Parser::Multipart.parse(MULTIPART_RESPONSE_URLS, "rets.object.content.boundary.1330546052739")
29
+ assert_equal 'http://foobarmls.com/RETS//MediaDisplay/98/hr2890998-1.jpg', parts[0].headers['location']
30
+ end
31
+
32
+ def test_parse_with_error
33
+ raw = "\r\n--89467f8e0c6b48158c8f1883910212ec\r\nContent-Type: text/xml\r\nContent-ID: foo\r\nObject-ID: *\r\n\r\n<RETS ReplyCode=\"20403\" ReplyText=\"No Object Found\" />\r\n\r\n--89467f8e0c6b48158c8f1883910212ec--\r\n"
34
+ boundary = "89467f8e0c6b48158c8f1883910212ec"
35
+ assert_raises Rets::InvalidRequest do
36
+ Rets::Parser::Multipart.parse(raw, boundary)
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,262 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: post
5
+ uri: http://rets.example.com/GetObject.asmx/GetObject
6
+ body:
7
+ encoding: US-ASCII
8
+ string: Resource=Property&Type=Photo&ID=2661580%3A1&Location=0
9
+ headers:
10
+ User-Agent:
11
+ - Estately/1.0
12
+ Host:
13
+ - rets.example.com:80
14
+ Rets-Version:
15
+ - RETS/1.7.2
16
+ Authorization:
17
+ - Digest username="login", realm="fake_realm", qop="auth",
18
+ uri="/Login.asmx/Login", nonce="a8f4bc805062602c8ba7a87b2109f808", nc=00000001,
19
+ cnonce="6e2dd038eea6cbacf0b956fd11f914b6", response="fake_digest",
20
+ opaque="96eda461-41d0-4624-b7fe-b59e966035f3"
21
+ Cookie:
22
+ - ASP.NET_SessionId=mapij045k3bphj3gqqgpmmrx
23
+ Accept:
24
+ - image/jpeg, image/png;q=0.5, image/gif;q=0.1
25
+ Content-Type:
26
+ - application/x-www-form-urlencoded
27
+ Content-Length:
28
+ - '54'
29
+ response:
30
+ status:
31
+ code: 401
32
+ message: Unauthorized
33
+ headers:
34
+ Connection:
35
+ - close
36
+ Date:
37
+ - Thu, 26 Jul 2012 00:11:02 GMT
38
+ Server:
39
+ - Microsoft-IIS/6.0
40
+ Cache-Control:
41
+ - private
42
+ - private
43
+ X-Aspnet-Version:
44
+ - 2.0.50727
45
+ Www-Authenticate:
46
+ - Digest realm="fake_realm",nonce="dfd74deac03147e1a4fff598679f1a80",opaque="8e5029c6-bb9c-4562-b440-e7c2b8960743",qop="auth"
47
+ Content-Type:
48
+ - text/plain
49
+ body:
50
+ encoding: US-ASCII
51
+ string: ! "Unauthorized Request. Digest Session Invalid Reauthenticate\r\nReference:
52
+ e0ff89c0-2d64-4287-a6b7-6be27c7d3ade"
53
+ http_version:
54
+ recorded_at: Thu, 26 Jul 2012 00:11:13 GMT
55
+ - request:
56
+ method: post
57
+ uri: http://rets.example.com/Login.asmx/Login
58
+ body:
59
+ encoding: US-ASCII
60
+ string: ''
61
+ headers:
62
+ User-Agent:
63
+ - Estately/1.0
64
+ Host:
65
+ - rets.example.com:80
66
+ Rets-Version:
67
+ - RETS/1.7.2
68
+ Accept:
69
+ - ! '*/*'
70
+ response:
71
+ status:
72
+ code: 401
73
+ message: Unauthorized
74
+ headers:
75
+ Connection:
76
+ - close
77
+ Date:
78
+ - Thu, 26 Jul 2012 00:11:03 GMT
79
+ Server:
80
+ - Microsoft-IIS/6.0
81
+ Cache-Control:
82
+ - private
83
+ - private
84
+ X-Aspnet-Version:
85
+ - 2.0.50727
86
+ Www-Authenticate:
87
+ - Digest realm="fake_realm",nonce="17fdfe2c6125296bd93bb81bd88dc4be",opaque="aee1e7da-60eb-41b3-b704-8eb3969645fd",qop="auth"
88
+ Content-Type:
89
+ - text/plain
90
+ body:
91
+ encoding: US-ASCII
92
+ string: ! "Unauthorized Request. Authentication needed\r\nReference: c2c5ab9f-8c12-42bb-94ce-5b6ebf156da4"
93
+ http_version:
94
+ recorded_at: Thu, 26 Jul 2012 00:11:13 GMT
95
+ - request:
96
+ method: post
97
+ uri: http://rets.example.com/Login.asmx/Login
98
+ body:
99
+ encoding: US-ASCII
100
+ string: ''
101
+ headers:
102
+ User-Agent:
103
+ - Estately/1.0
104
+ Host:
105
+ - rets.example.com:80
106
+ Rets-Version:
107
+ - RETS/1.7.2
108
+ Authorization:
109
+ - Digest username="login", realm="fake_realm", qop="auth",
110
+ uri="/Login.asmx/Login", nonce="17fdfe2c6125296bd93bb81bd88dc4be", nc=00000001,
111
+ cnonce="ad805b9e2d6f08ad82175085e5febd8d", response="7402076f53663602f052e1aa343d3dab",
112
+ opaque="aee1e7da-60eb-41b3-b704-8eb3969645fd"
113
+ Accept:
114
+ - ! '*/*'
115
+ response:
116
+ status:
117
+ code: 200
118
+ message: OK
119
+ headers:
120
+ Date:
121
+ - Thu, 26 Jul 2012 00:11:03 GMT
122
+ Server:
123
+ - Microsoft-IIS/6.0
124
+ Cache-Control:
125
+ - private
126
+ - private, max-age=0
127
+ X-Aspnet-Version:
128
+ - 2.0.50727
129
+ Rets-Version:
130
+ - RETS/1.7.2
131
+ Rets-Server:
132
+ - Interealty-RETS/1.5.247.0
133
+ Transfer-Encoding:
134
+ - chunked
135
+ Set-Cookie:
136
+ - ASP.NET_SessionId=vuesmq55l0cpjy45zyn0e555; path=/; HttpOnly
137
+ - RETS-Session-ID=vuesmq55l0cpjy45zyn0e555; path=/
138
+ Content-Type:
139
+ - text/xml
140
+ body:
141
+ encoding: US-ASCII
142
+ string: ! "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<RETS ReplyCode=\"0\"
143
+ ReplyText=\"Success. Reference ID: a3073726-a011-4391-b22e-900adae5184b\">\r\n
144
+ \ <RETS-RESPONSE>\r\nMemberName=John Wolff\r\nUser=23756,60,RH,login\r\nBroker=BRDA,BRDA01\r\nMetadataVersion=31.76.69587\r\nMetadataTimeStamp=2012-07-24T17:33:07Z\r\nMinMetadataTimeStamp=2012-07-24T17:33:07Z\r\nTimeoutSeconds=7200\r\nChangePassword=/ChangePassword.asmx/ChangePassword\r\nGetObject=/GetObject.asmx/GetObject\r\nLogin=/Login.asmx/Login\r\nLogout=/Logout.asmx/Logout\r\nSearch=/Search.asmx/Search\r\nGetMetadata=/GetMetadata.asmx/GetMetadata\r\n</RETS-RESPONSE>\r\n</RETS>"
145
+ http_version:
146
+ recorded_at: Thu, 26 Jul 2012 00:11:14 GMT
147
+ - request:
148
+ method: post
149
+ uri: http://rets.example.com/Login.asmx/Login
150
+ body:
151
+ encoding: US-ASCII
152
+ string: ''
153
+ headers:
154
+ User-Agent:
155
+ - Estately/1.0
156
+ Host:
157
+ - rets.example.com:80
158
+ Rets-Version:
159
+ - RETS/1.7.2
160
+ Authorization:
161
+ - Digest username="login", realm="fake_realm", qop="auth",
162
+ uri="/Login.asmx/Login", nonce="17fdfe2c6125296bd93bb81bd88dc4be", nc=00000001,
163
+ cnonce="ad805b9e2d6f08ad82175085e5febd8d", response="7402076f53663602f052e1aa343d3dab",
164
+ opaque="aee1e7da-60eb-41b3-b704-8eb3969645fd"
165
+ Cookie:
166
+ - ASP.NET_SessionId=vuesmq55l0cpjy45zyn0e555; RETS-Session-ID=vuesmq55l0cpjy45zyn0e555
167
+ Accept:
168
+ - ! '*/*'
169
+ response:
170
+ status:
171
+ code: 200
172
+ message: OK
173
+ headers:
174
+ Date:
175
+ - Thu, 26 Jul 2012 00:11:03 GMT
176
+ Server:
177
+ - Microsoft-IIS/6.0
178
+ Cache-Control:
179
+ - private
180
+ - private, max-age=0
181
+ X-Aspnet-Version:
182
+ - 2.0.50727
183
+ Rets-Version:
184
+ - RETS/1.7.2
185
+ Rets-Server:
186
+ - Interealty-RETS/1.5.247.0
187
+ Transfer-Encoding:
188
+ - chunked
189
+ Set-Cookie:
190
+ - RETS-Session-ID=vuesmq55l0cpjy45zyn0e555; path=/
191
+ Content-Type:
192
+ - text/xml
193
+ body:
194
+ encoding: US-ASCII
195
+ string: ! "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<RETS ReplyCode=\"0\"
196
+ ReplyText=\"Success. Reference ID: a48b4f59-cb22-41be-8e7b-1cee28fb8644\">\r\n
197
+ \ <RETS-RESPONSE>\r\nMemberName=John Wolff\r\nUser=23756,60,RH,login\r\nBroker=BRDA,BRDA01\r\nMetadataVersion=31.76.69587\r\nMetadataTimeStamp=2012-07-24T17:33:07Z\r\nMinMetadataTimeStamp=2012-07-24T17:33:07Z\r\nTimeoutSeconds=7200\r\nChangePassword=/ChangePassword.asmx/ChangePassword\r\nGetObject=/GetObject.asmx/GetObject\r\nLogin=/Login.asmx/Login\r\nLogout=/Logout.asmx/Logout\r\nSearch=/Search.asmx/Search\r\nGetMetadata=/GetMetadata.asmx/GetMetadata\r\n</RETS-RESPONSE>\r\n</RETS>"
198
+ http_version:
199
+ recorded_at: Thu, 26 Jul 2012 00:11:14 GMT
200
+ - request:
201
+ method: post
202
+ uri: http://rets.example.com/GetObject.asmx/GetObject
203
+ body:
204
+ encoding: US-ASCII
205
+ string: Resource=Property&Type=Photo&ID=2661580%3A1&Location=0
206
+ headers:
207
+ User-Agent:
208
+ - Estately/1.0
209
+ Host:
210
+ - rets.example.com:80
211
+ Rets-Version:
212
+ - RETS/1.7.2
213
+ Authorization:
214
+ - Digest username="login", realm="fake_realm", qop="auth",
215
+ uri="/Login.asmx/Login", nonce="17fdfe2c6125296bd93bb81bd88dc4be", nc=00000001,
216
+ cnonce="ad805b9e2d6f08ad82175085e5febd8d", response="7402076f53663602f052e1aa343d3dab",
217
+ opaque="aee1e7da-60eb-41b3-b704-8eb3969645fd"
218
+ Cookie:
219
+ - ASP.NET_SessionId=vuesmq55l0cpjy45zyn0e555; RETS-Session-ID=vuesmq55l0cpjy45zyn0e555
220
+ Accept:
221
+ - image/jpeg, image/png;q=0.5, image/gif;q=0.1
222
+ Content-Type:
223
+ - application/x-www-form-urlencoded
224
+ Content-Length:
225
+ - '54'
226
+ response:
227
+ status:
228
+ code: 200
229
+ message: OK
230
+ headers:
231
+ Date:
232
+ - Thu, 26 Jul 2012 00:11:04 GMT
233
+ Server:
234
+ - Microsoft-IIS/6.0
235
+ Cache-Control:
236
+ - private
237
+ - private, max-age=0
238
+ X-Aspnet-Version:
239
+ - 2.0.50727
240
+ Mime-Version:
241
+ - '1.0'
242
+ Rets-Version:
243
+ - RETS/1.7.2
244
+ Rets-Server:
245
+ - Interealty-RETS/1.5.247.0
246
+ Content-Id:
247
+ - '2661580'
248
+ Object-Id:
249
+ - '1'
250
+ Transfer-Encoding:
251
+ - chunked
252
+ Set-Cookie:
253
+ - RETS-Session-ID=vuesmq55l0cpjy45zyn0e555; path=/
254
+ Content-Type:
255
+ - image/jpeg
256
+ body:
257
+ encoding: ASCII-8BIT
258
+ string: !binary |-
259
+ /9j/4AAQSkZJRgABAQEAYABgAAD///2Q==
260
+ http_version:
261
+ recorded_at: Thu, 26 Jul 2012 00:11:14 GMT
262
+ recorded_with: VCR 2.2.2
metadata ADDED
@@ -0,0 +1,186 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sean-rets
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.6.0
5
+ platform: ruby
6
+ authors:
7
+ - Estately, Inc. Open Source
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-11-26 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: httpclient
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 2.3.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 2.3.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: nokogiri
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 1.5.2
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 1.5.2
41
+ - !ruby/object:Gem::Dependency
42
+ name: rdoc
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '4.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '4.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: mocha
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 0.11.0
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 0.11.0
69
+ - !ruby/object:Gem::Dependency
70
+ name: vcr
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: 2.2.2
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: 2.2.2
83
+ - !ruby/object:Gem::Dependency
84
+ name: webmock
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: 1.8.0
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: 1.8.0
97
+ - !ruby/object:Gem::Dependency
98
+ name: hoe
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '3.6'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '3.6'
111
+ description: |-
112
+ [![Build Status](https://secure.travis-ci.org/estately/rets.png?branch=master)](http://travis-ci.org/estately/rets)
113
+ A pure-ruby library for fetching data from [RETS] servers.
114
+
115
+ [RETS]: http://www.rets.org
116
+ email:
117
+ - opensource@estately.com
118
+ executables:
119
+ - rets
120
+ extensions: []
121
+ extra_rdoc_files:
122
+ - CHANGELOG.md
123
+ - Manifest.txt
124
+ - README.md
125
+ files:
126
+ - ".gemtest"
127
+ - CHANGELOG.md
128
+ - Manifest.txt
129
+ - README.md
130
+ - Rakefile
131
+ - bin/rets
132
+ - lib/rets.rb
133
+ - lib/rets/client.rb
134
+ - lib/rets/client_progress_reporter.rb
135
+ - lib/rets/http_client.rb
136
+ - lib/rets/locking_http_client.rb
137
+ - lib/rets/measuring_http_client.rb
138
+ - lib/rets/metadata.rb
139
+ - lib/rets/metadata/containers.rb
140
+ - lib/rets/metadata/lookup_type.rb
141
+ - lib/rets/metadata/resource.rb
142
+ - lib/rets/metadata/rets_class.rb
143
+ - lib/rets/metadata/root.rb
144
+ - lib/rets/metadata/table.rb
145
+ - lib/rets/parser/compact.rb
146
+ - lib/rets/parser/multipart.rb
147
+ - test/fixtures.rb
148
+ - test/helper.rb
149
+ - test/test_client.rb
150
+ - test/test_locking_http_client.rb
151
+ - test/test_metadata.rb
152
+ - test/test_parser_compact.rb
153
+ - test/test_parser_multipart.rb
154
+ - test/vcr_cassettes/unauthorized_response.yml
155
+ homepage: http://github.com/estately/rets
156
+ licenses: []
157
+ metadata: {}
158
+ post_install_message:
159
+ rdoc_options:
160
+ - "--main"
161
+ - README.md
162
+ require_paths:
163
+ - lib
164
+ required_ruby_version: !ruby/object:Gem::Requirement
165
+ requirements:
166
+ - - ">="
167
+ - !ruby/object:Gem::Version
168
+ version: '0'
169
+ required_rubygems_version: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - ">="
172
+ - !ruby/object:Gem::Version
173
+ version: '0'
174
+ requirements: []
175
+ rubyforge_project: rets
176
+ rubygems_version: 2.2.2
177
+ signing_key:
178
+ specification_version: 4
179
+ summary: "[![Build Status](https://secure.travis-ci.org/estately/rets.png?branch=master)](http://travis-ci.org/estately/rets)
180
+ A pure-ruby library for fetching data from [RETS] servers"
181
+ test_files:
182
+ - test/test_client.rb
183
+ - test/test_locking_http_client.rb
184
+ - test/test_metadata.rb
185
+ - test/test_parser_compact.rb
186
+ - test/test_parser_multipart.rb