rets 0.1.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.
- data/.gemtest +0 -0
- data/CHANGELOG.md +9 -0
- data/Manifest.txt +23 -0
- data/README.md +42 -0
- data/Rakefile +18 -0
- data/bin/rets +194 -0
- data/lib/rets.rb +24 -0
- data/lib/rets/authentication.rb +59 -0
- data/lib/rets/client.rb +473 -0
- data/lib/rets/metadata.rb +6 -0
- data/lib/rets/metadata/containers.rb +84 -0
- data/lib/rets/metadata/lookup_type.rb +17 -0
- data/lib/rets/metadata/resource.rb +73 -0
- data/lib/rets/metadata/rets_class.rb +42 -0
- data/lib/rets/metadata/root.rb +155 -0
- data/lib/rets/metadata/table.rb +98 -0
- data/lib/rets/parser/compact.rb +46 -0
- data/lib/rets/parser/multipart.rb +36 -0
- data/test/fixtures.rb +142 -0
- data/test/helper.rb +6 -0
- data/test/test_client.rb +571 -0
- data/test/test_metadata.rb +452 -0
- data/test/test_parser_compact.rb +71 -0
- data/test/test_parser_multipart.rb +21 -0
- metadata +162 -0
@@ -0,0 +1,452 @@
|
|
1
|
+
require "helper"
|
2
|
+
|
3
|
+
class TestMetadata < Test::Unit::TestCase
|
4
|
+
def setup
|
5
|
+
@root = Rets::Metadata::Root.new
|
6
|
+
end
|
7
|
+
|
8
|
+
def test_metadata_root_fetch_sources_returns_hash_of_metadata_types
|
9
|
+
types = []
|
10
|
+
fake_fetcher = lambda do |type|
|
11
|
+
types << type
|
12
|
+
end
|
13
|
+
|
14
|
+
@root.fetch_sources(&fake_fetcher)
|
15
|
+
|
16
|
+
assert_equal(Rets::Metadata::METADATA_TYPES, types)
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_metadata_root_intialized_with_block
|
20
|
+
external = false
|
21
|
+
Rets::Metadata::Root.new { |source| external = true }
|
22
|
+
assert external
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_metadata_root_build_tree
|
26
|
+
resource = stub(:id => "X")
|
27
|
+
Rets::Metadata::Resource.stubs(:build => resource)
|
28
|
+
resource_fragment = stub(:resource_fragment)
|
29
|
+
resource_container = stub(:rows => [resource_fragment])
|
30
|
+
@root.stubs(:metadata_types => { :resource => [resource_container] })
|
31
|
+
assert_equal({"x" => resource}, @root.build_tree)
|
32
|
+
assert_equal(resource, @root.build_tree["X"])
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_metadata_root_version
|
36
|
+
@root.instance_variable_set("@metadata_types", {:system => [stub(:version => "1")]})
|
37
|
+
assert_equal "1", @root.version
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_metadata_root_date
|
41
|
+
@root.instance_variable_set("@metadata_types", {:system => [stub(:date => "1")]})
|
42
|
+
assert_equal "1", @root.date
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_metadata_root_different_version
|
46
|
+
@root.stubs(:version).returns("1.2.2")
|
47
|
+
@root.stubs(:date).returns("1")
|
48
|
+
|
49
|
+
current_version = "1.2.3"
|
50
|
+
current_timestamp = "1"
|
51
|
+
|
52
|
+
assert !@root.current?(current_timestamp, current_version)
|
53
|
+
end
|
54
|
+
|
55
|
+
def test_metadata_root_same_version
|
56
|
+
@root.stubs(:version).returns("1.2.2")
|
57
|
+
@root.stubs(:date).returns("1")
|
58
|
+
|
59
|
+
current_version = "1.2.2"
|
60
|
+
current_timestamp = "2"
|
61
|
+
|
62
|
+
assert @root.current?(current_timestamp, current_version)
|
63
|
+
end
|
64
|
+
|
65
|
+
def test_metadata_root_no_version_same_timestamp
|
66
|
+
@root.stubs(:version).returns("")
|
67
|
+
@root.stubs(:date).returns("1")
|
68
|
+
|
69
|
+
current_version = "1.2.3"
|
70
|
+
current_timestamp = "1"
|
71
|
+
|
72
|
+
assert @root.current?(current_timestamp, current_version)
|
73
|
+
end
|
74
|
+
|
75
|
+
def test_metadata_root_current
|
76
|
+
@root.stubs(:version).returns("1.2.2")
|
77
|
+
@root.stubs(:date).returns("1")
|
78
|
+
|
79
|
+
current_timestamp = "1"
|
80
|
+
current_version = "1.2.2"
|
81
|
+
|
82
|
+
assert @root.current?(current_timestamp, current_version)
|
83
|
+
end
|
84
|
+
|
85
|
+
# missing timestamp - this happens in violation of the spec.
|
86
|
+
def test_metadata_root_current_ignores_missing_timestamp
|
87
|
+
@root.stubs(:version).returns("1.2.2")
|
88
|
+
@root.stubs(:date).returns("1")
|
89
|
+
|
90
|
+
current_timestamp = nil
|
91
|
+
current_version = "1.2.2"
|
92
|
+
|
93
|
+
assert @root.current?(current_timestamp, current_version)
|
94
|
+
end
|
95
|
+
|
96
|
+
# missing version - this happens in violation of the spec.
|
97
|
+
def test_metadata_root_current_ignores_missing_version
|
98
|
+
@root.stubs(:version).returns("1.2.2")
|
99
|
+
@root.stubs(:date).returns("1")
|
100
|
+
|
101
|
+
current_timestamp = "1"
|
102
|
+
current_version = nil
|
103
|
+
|
104
|
+
assert @root.current?(current_timestamp, current_version)
|
105
|
+
end
|
106
|
+
|
107
|
+
def test_metadata_root_metadata_types_constructs_a_hash_of_metadata_types_from_sources
|
108
|
+
test_sources = { "X" => "Y", "Z" => "W" }
|
109
|
+
@root.stubs(:sources => test_sources, :build_containers => "Y--")
|
110
|
+
@root.metadata_types = nil
|
111
|
+
Nokogiri.stubs(:parse => "Y-")
|
112
|
+
assert_equal({:x => "Y--", :z => "Y--"}, @root.metadata_types)
|
113
|
+
end
|
114
|
+
|
115
|
+
def test_metadata_root_build_containers_selects_correct_tags
|
116
|
+
doc = "<RETS><METADATA-FOO></METADATA-FOO><MET-FOO></MET-FOO><METADATA-BAR /></RETS>"
|
117
|
+
|
118
|
+
@root.expects(:build_container).with { |fragment| fragment.name == "METADATA-FOO" }
|
119
|
+
@root.expects(:build_container).with { |fragment| fragment.name == "METADATA-BAR" }
|
120
|
+
|
121
|
+
@root.build_containers(Nokogiri.parse(doc))
|
122
|
+
end
|
123
|
+
|
124
|
+
def test_metadata_root_build_container_uses_row_containers_for_resource
|
125
|
+
doc = Nokogiri.parse(METADATA_RESOURCE).xpath("//METADATA-RESOURCE").first
|
126
|
+
|
127
|
+
container = @root.build_container(doc)
|
128
|
+
|
129
|
+
assert_instance_of Rets::Metadata::Containers::ResourceContainer, container
|
130
|
+
|
131
|
+
assert_equal 13, container.resources.size
|
132
|
+
|
133
|
+
resource = container.resources.first
|
134
|
+
|
135
|
+
assert_equal "ActiveAgent", resource["StandardName"]
|
136
|
+
end
|
137
|
+
|
138
|
+
def test_metadata_root_build_container_uses_system_container_for_system
|
139
|
+
doc = Nokogiri.parse(METADATA_SYSTEM).xpath("//METADATA-SYSTEM").first
|
140
|
+
|
141
|
+
container = @root.build_container(doc)
|
142
|
+
assert_instance_of Rets::Metadata::Containers::SystemContainer, container
|
143
|
+
end
|
144
|
+
|
145
|
+
def test_metadata_root_build_container_uses_base_container_for_unknown_metadata_types
|
146
|
+
doc = Nokogiri.parse(METADATA_UNKNOWN).xpath("//METADATA-FOO").first
|
147
|
+
|
148
|
+
container = @root.build_container(doc)
|
149
|
+
assert_instance_of Rets::Metadata::Containers::Container, container
|
150
|
+
end
|
151
|
+
|
152
|
+
def test_metadata_uses
|
153
|
+
#TODO
|
154
|
+
end
|
155
|
+
|
156
|
+
def test_resource_initialize
|
157
|
+
fragment = { "ResourceID" => 'r' }
|
158
|
+
resource = Rets::Metadata::Resource.new(fragment)
|
159
|
+
assert_equal('r', resource.id)
|
160
|
+
assert_equal([], resource.rets_classes)
|
161
|
+
end
|
162
|
+
|
163
|
+
def test_resource_build_lookup_tree
|
164
|
+
metadata = stub(:metadata)
|
165
|
+
resource = stub(:resource)
|
166
|
+
|
167
|
+
Rets::Metadata::Resource.expects(:find_lookup_containers).
|
168
|
+
with(metadata, resource).
|
169
|
+
returns([stub(:lookups => [{"LookupName" => "Foo"}])])
|
170
|
+
|
171
|
+
Rets::Metadata::Resource.expects(:find_lookup_type_containers).
|
172
|
+
with(metadata, resource, "Foo").
|
173
|
+
returns([stub(:lookup_types => [{"Value" => "111", "LongValue" => "Bar"}])])
|
174
|
+
|
175
|
+
tree = Rets::Metadata::Resource.build_lookup_tree(resource, metadata)
|
176
|
+
|
177
|
+
assert_equal ["Foo"], tree.keys
|
178
|
+
assert_equal 1, tree["Foo"].size
|
179
|
+
|
180
|
+
lookup_type = tree["Foo"].first
|
181
|
+
|
182
|
+
assert_equal "111", lookup_type.value
|
183
|
+
assert_equal "Bar", lookup_type.long_value
|
184
|
+
end
|
185
|
+
|
186
|
+
def test_resource_build_classes
|
187
|
+
resource = stub(:resource)
|
188
|
+
metadata = stub(:metadata)
|
189
|
+
rets_class = stub(:rets_class)
|
190
|
+
rets_class_fragment = stub(:rets_class_fragment)
|
191
|
+
|
192
|
+
Rets::Metadata::RetsClass.expects(:build).with(rets_class_fragment, resource, metadata).returns(rets_class)
|
193
|
+
Rets::Metadata::Resource.expects(:find_rets_classes).with(metadata, resource).returns([rets_class_fragment])
|
194
|
+
|
195
|
+
classes = Rets::Metadata::Resource.build_classes(resource, metadata)
|
196
|
+
assert([rets_class], classes)
|
197
|
+
end
|
198
|
+
|
199
|
+
def test_resource_build
|
200
|
+
fragment = { "ResourceID" => "test" }
|
201
|
+
|
202
|
+
lookup_types = stub(:lookup_types)
|
203
|
+
classes = stub(:classes)
|
204
|
+
metadata = stub(:metadata)
|
205
|
+
|
206
|
+
Rets::Metadata::Resource.stubs(:build_lookup_tree => lookup_types)
|
207
|
+
Rets::Metadata::Resource.stubs(:build_classes => classes)
|
208
|
+
|
209
|
+
resource = Rets::Metadata::Resource.build(fragment, metadata)
|
210
|
+
|
211
|
+
assert_equal(lookup_types, resource.lookup_types)
|
212
|
+
assert_equal(classes, resource.rets_classes)
|
213
|
+
end
|
214
|
+
|
215
|
+
def test_resource_find_lookup_containers
|
216
|
+
resource = stub(:id => "id")
|
217
|
+
metadata = { :lookup => [stub(:resource => "id"), stub(:resource => "id"), stub(:resource => "a")] }
|
218
|
+
|
219
|
+
lookup_containers = Rets::Metadata::Resource.find_lookup_containers(metadata, resource)
|
220
|
+
|
221
|
+
assert_equal(2, lookup_containers.size)
|
222
|
+
assert_equal(["id", "id"], lookup_containers.map(&:resource))
|
223
|
+
end
|
224
|
+
|
225
|
+
def test_resource_find_lookup_type_containers
|
226
|
+
resource = stub(:id => "id")
|
227
|
+
metadata = { :lookup_type => [stub(:resource => "id", :lookup => "look"),
|
228
|
+
stub(:resource => "id", :lookup => "look"),
|
229
|
+
stub(:resource => "id", :lookup => "not_look"),
|
230
|
+
stub(:resource => "a", :lookup => "look"),
|
231
|
+
stub(:resource => "a", :lookup => "not_look")
|
232
|
+
]}
|
233
|
+
|
234
|
+
lookup_type_containers = Rets::Metadata::Resource.find_lookup_type_containers(metadata, resource, "look")
|
235
|
+
|
236
|
+
assert_equal(2, lookup_type_containers.size)
|
237
|
+
assert_equal(["id", "id"], lookup_type_containers.map(&:resource))
|
238
|
+
end
|
239
|
+
|
240
|
+
def test_resource_find_rets_classes
|
241
|
+
resource = stub(:id => "id")
|
242
|
+
rets_classes = stub(:rets_classes)
|
243
|
+
|
244
|
+
metadata = { :class => [stub(:resource => "id", :classes => rets_classes),
|
245
|
+
stub(:resource => "id", :classes => rets_classes),
|
246
|
+
stub(:resource => "a")]}
|
247
|
+
|
248
|
+
assert_equal(rets_classes, Rets::Metadata::Resource.find_rets_classes(metadata, resource))
|
249
|
+
end
|
250
|
+
|
251
|
+
def test_resource_find_rets_class
|
252
|
+
resource = Rets::Metadata::Resource.new({})
|
253
|
+
value = mock(:name => "test")
|
254
|
+
|
255
|
+
resource.expects(:rets_classes).returns([value])
|
256
|
+
assert_equal(value, resource.find_rets_class("test"))
|
257
|
+
end
|
258
|
+
|
259
|
+
def test_lookup_type_initialize
|
260
|
+
fragment = { "Value" => 'a', "ShortValue" => 'b', "LongValue" => 'c' }
|
261
|
+
|
262
|
+
lookup_type = Rets::Metadata::LookupType.new(fragment)
|
263
|
+
|
264
|
+
assert_equal('a', lookup_type.value)
|
265
|
+
assert_equal('b', lookup_type.short_value)
|
266
|
+
assert_equal('c', lookup_type.long_value)
|
267
|
+
end
|
268
|
+
def test_rets_class_find_table
|
269
|
+
rets_class = Rets::Metadata::RetsClass.new({}, "resource")
|
270
|
+
value = mock(:name => "test")
|
271
|
+
|
272
|
+
rets_class.expects(:tables).returns([value])
|
273
|
+
assert_equal(value, rets_class.find_table("test"))
|
274
|
+
end
|
275
|
+
|
276
|
+
def test_rets_class_find_table_container
|
277
|
+
resource = mock(:id => "a")
|
278
|
+
rets_class = mock(:name => "b")
|
279
|
+
table = mock(:resource => "a", :class => "b")
|
280
|
+
|
281
|
+
metadata = { :table => [table] }
|
282
|
+
|
283
|
+
assert_equal(table, Rets::Metadata::RetsClass.find_table_container(metadata, resource, rets_class))
|
284
|
+
end
|
285
|
+
|
286
|
+
def test_rets_class_build
|
287
|
+
resource = stub(:resource)
|
288
|
+
table_fragment = stub(:fragment)
|
289
|
+
table_container = stub(:tables => [table_fragment])
|
290
|
+
table = stub(:table)
|
291
|
+
|
292
|
+
Rets::Metadata::TableFactory.expects(:build).with(table_fragment, resource).returns(table)
|
293
|
+
Rets::Metadata::RetsClass.expects(:find_table_container).returns(table_container)
|
294
|
+
|
295
|
+
rets_class = Rets::Metadata::RetsClass.build({}, resource, "")
|
296
|
+
|
297
|
+
assert_equal(rets_class.tables, [table])
|
298
|
+
end
|
299
|
+
|
300
|
+
def test_rets_class_build_when_find_table_container_returns_nil
|
301
|
+
new_rets_class = stub(:new_rets_class)
|
302
|
+
Rets::Metadata::RetsClass.stubs(:new => new_rets_class)
|
303
|
+
Rets::Metadata::RetsClass.stubs(:find_table_container => nil)
|
304
|
+
Rets::Metadata::RetsClass.build({}, "", "")
|
305
|
+
end
|
306
|
+
|
307
|
+
|
308
|
+
def test_rets_class_initialize
|
309
|
+
fragment = { "ClassName" => "A" }
|
310
|
+
rets_class = Rets::Metadata::RetsClass.new(fragment, "resource")
|
311
|
+
|
312
|
+
assert_equal("A", rets_class.name)
|
313
|
+
assert_equal("resource", rets_class.resource)
|
314
|
+
assert_equal([], rets_class.tables)
|
315
|
+
end
|
316
|
+
|
317
|
+
def test_table_factory_creates_lookup_table
|
318
|
+
assert_instance_of Rets::Metadata::LookupTable, Rets::Metadata::TableFactory.build({"LookupName" => "Foo", "Interpretation" => "Lookup"}, nil)
|
319
|
+
end
|
320
|
+
|
321
|
+
def test_table_factory_creates_table
|
322
|
+
assert_instance_of Rets::Metadata::Table, Rets::Metadata::TableFactory.build({"LookupName" => "", "Interpretation" => ""}, nil)
|
323
|
+
end
|
324
|
+
|
325
|
+
def test_table_factory_enum
|
326
|
+
assert Rets::Metadata::TableFactory.enum?("LookupName" => "Foo", "Interpretation" => "Lookup")
|
327
|
+
assert !Rets::Metadata::TableFactory.enum?("LookupName" => "", "Interpretation" => "SomethingElse")
|
328
|
+
assert !Rets::Metadata::TableFactory.enum?("LookupName" => "Foo", "Interpretation" => "")
|
329
|
+
assert !Rets::Metadata::TableFactory.enum?("LookupName" => "", "Interpretation" => "SomethingElse")
|
330
|
+
end
|
331
|
+
|
332
|
+
def test_lookup_table_initialize
|
333
|
+
fragment = { "SystemName" => "A", "Interpretation" => "B", "LookupName" => "C" }
|
334
|
+
|
335
|
+
lookup_table = Rets::Metadata::LookupTable.new(fragment, "Foo")
|
336
|
+
|
337
|
+
assert_equal("Foo", lookup_table.resource)
|
338
|
+
assert_equal("A", lookup_table.name)
|
339
|
+
assert_equal("C", lookup_table.lookup_name)
|
340
|
+
assert_equal("B", lookup_table.interpretation)
|
341
|
+
end
|
342
|
+
|
343
|
+
def test_lookup_table_resolve_returns_empty_array_when_value_is_empty_and_is_multi?
|
344
|
+
|
345
|
+
lookup_table = Rets::Metadata::LookupTable.new({}, nil)
|
346
|
+
lookup_table.stubs(:multi? => true)
|
347
|
+
|
348
|
+
assert_equal [], lookup_table.resolve("")
|
349
|
+
end
|
350
|
+
|
351
|
+
def test_lookup_table_resolve_returns_single_value_if_not_multi
|
352
|
+
lookup_table = Rets::Metadata::LookupTable.new({}, nil)
|
353
|
+
lookup_table.stubs(:multi? => false)
|
354
|
+
|
355
|
+
lookup_table.expects(:lookup_type).with("A,B").returns(mock(:long_value => "AaaBbb"))
|
356
|
+
|
357
|
+
assert_equal "AaaBbb", lookup_table.resolve("A,B")
|
358
|
+
end
|
359
|
+
|
360
|
+
def test_lookup_table_resolve_returns_multi_value_array_when_multi
|
361
|
+
fragment = { "Interpretation" => "LookupMulti" }
|
362
|
+
|
363
|
+
lookup_table = Rets::Metadata::LookupTable.new(fragment, nil)
|
364
|
+
|
365
|
+
lookup_table.expects(:lookup_type).with("A").returns(mock(:long_value => "Aaa"))
|
366
|
+
lookup_table.expects(:lookup_type).with("B").returns(mock(:long_value => "Bbb"))
|
367
|
+
|
368
|
+
assert_equal ["Aaa", "Bbb"], lookup_table.resolve("A,B")
|
369
|
+
end
|
370
|
+
|
371
|
+
#Sandicor does this :|
|
372
|
+
def test_lookup_table_resolve_returns_multi_value_array_when_multi_with_quoted_values
|
373
|
+
fragment = { "Interpretation" => "LookupMulti" }
|
374
|
+
|
375
|
+
lookup_table = Rets::Metadata::LookupTable.new(fragment, nil)
|
376
|
+
|
377
|
+
lookup_table.expects(:lookup_type).with("A").returns(mock(:long_value => "Aaa"))
|
378
|
+
lookup_table.expects(:lookup_type).with("B").returns(mock(:long_value => "Bbb"))
|
379
|
+
|
380
|
+
assert_equal ["Aaa", "Bbb"], lookup_table.resolve(%q["A","B"])
|
381
|
+
end
|
382
|
+
|
383
|
+
# This scenario is unfortunately common.
|
384
|
+
def test_lookup_table_resolve_returns_nil_when_lookup_type_is_not_present_for_multi_value
|
385
|
+
fragment = { "Interpretation" => "LookupMulti" }
|
386
|
+
|
387
|
+
lookup_table = Rets::Metadata::LookupTable.new(fragment, nil)
|
388
|
+
|
389
|
+
lookup_table.expects(:lookup_type).with("A").returns(mock(:long_value => "Aaa"))
|
390
|
+
lookup_table.expects(:lookup_type).with("B").returns(nil)
|
391
|
+
|
392
|
+
lookup_table.expects(:warn).with("Discarding unmappable value of #{"B".inspect}")
|
393
|
+
|
394
|
+
assert_equal ["Aaa", ""], lookup_table.resolve("A,B")
|
395
|
+
end
|
396
|
+
|
397
|
+
# This scenario is unfortunately common.
|
398
|
+
def test_lookup_table_resolve_returns_nil_when_lookup_type_is_not_present_for_single_value
|
399
|
+
|
400
|
+
lookup_table = Rets::Metadata::LookupTable.new({}, nil)
|
401
|
+
lookup_table.stubs(:multi? => true)
|
402
|
+
|
403
|
+
lookup_table.expects(:lookup_type).with("A").returns(nil)
|
404
|
+
|
405
|
+
lookup_table.expects(:warn).with("Discarding unmappable value of #{"A".inspect}")
|
406
|
+
|
407
|
+
assert_equal [""], lookup_table.resolve("A")
|
408
|
+
end
|
409
|
+
|
410
|
+
def test_table_initialize
|
411
|
+
fragment = { "DataType" => "A", "SystemName" => "B" }
|
412
|
+
|
413
|
+
table = Rets::Metadata::Table.new(fragment)
|
414
|
+
assert_equal("A", table.type)
|
415
|
+
assert_equal("B", table.name)
|
416
|
+
end
|
417
|
+
|
418
|
+
def test_table_resolve_returns_empty_string_when_value_nil
|
419
|
+
table = Rets::Metadata::Table.new({})
|
420
|
+
|
421
|
+
assert_equal "", table.resolve(nil)
|
422
|
+
end
|
423
|
+
|
424
|
+
def test_table_resolve_passes_values_straight_through
|
425
|
+
table = Rets::Metadata::Table.new({})
|
426
|
+
|
427
|
+
assert_equal "Foo", table.resolve("Foo")
|
428
|
+
end
|
429
|
+
|
430
|
+
def test_table_resolve_passes_values_strips_extra_whitspace
|
431
|
+
table = Rets::Metadata::Table.new({})
|
432
|
+
|
433
|
+
assert_equal "Foo", table.resolve(" Foo ")
|
434
|
+
end
|
435
|
+
|
436
|
+
def test_root_can_be_serialized
|
437
|
+
sources = { :x => "a" }
|
438
|
+
|
439
|
+
@root.sources = sources
|
440
|
+
|
441
|
+
assert_equal sources, @root.marshal_dump
|
442
|
+
end
|
443
|
+
|
444
|
+
def test_root_can_be_unserialized
|
445
|
+
sources = { :x => "a" }
|
446
|
+
|
447
|
+
@root.marshal_load(sources)
|
448
|
+
|
449
|
+
assert_equal sources, @root.sources
|
450
|
+
end
|
451
|
+
|
452
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
require "helper"
|
2
|
+
|
3
|
+
class TestParserCompact < Test::Unit::TestCase
|
4
|
+
def test_parse_document_raises_on_invalid_delimiter
|
5
|
+
assert_raise 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_example
|
60
|
+
rows = Rets::Parser::Compact.parse_document(Nokogiri.parse(SAMPLE_COMPACT))
|
61
|
+
|
62
|
+
assert_equal "7", rows.first["MetadataEntryID"]
|
63
|
+
end
|
64
|
+
|
65
|
+
def test_parse_example_2
|
66
|
+
rows = Rets::Parser::Compact.parse_document(Nokogiri.parse(SAMPLE_COMPACT_2))
|
67
|
+
|
68
|
+
assert_equal "", rows.first["ModTimeStamp"]
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|