rets 0.9.0 → 0.10.0

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