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