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