xamplr 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (142) hide show
  1. data/CHANGES.txt +13 -0
  2. data/LICENSE +3 -0
  3. data/README.rdoc +26 -0
  4. data/README.rdoc.orig +118 -0
  5. data/Rakefile +85 -0
  6. data/VERSION.yml +4 -0
  7. data/examples/random-people-shared-addresses/Makefile +16 -0
  8. data/examples/random-people-shared-addresses/batch-load-users.rb +83 -0
  9. data/examples/random-people-shared-addresses/find-mentions.rb +47 -0
  10. data/examples/random-people-shared-addresses/find-people-by-address.rb +104 -0
  11. data/examples/random-people-shared-addresses/optimise.rb +16 -0
  12. data/examples/random-people-shared-addresses/people.rb +35 -0
  13. data/examples/random-people-shared-addresses/query.rb +75 -0
  14. data/examples/random-people-shared-addresses/query2.rb +73 -0
  15. data/examples/random-people-shared-addresses/random-names.csv +10000 -0
  16. data/examples/random-people-shared-addresses/settings.rb +3 -0
  17. data/examples/random-people-shared-addresses/what-to-query-on.rb +82 -0
  18. data/examples/random-people-shared-addresses/xampl-gen.rb +36 -0
  19. data/examples/random-people-shared-addresses/xml/people.xml +14 -0
  20. data/examples/random-people/Makefile +16 -0
  21. data/examples/random-people/batch-load-users.rb +61 -0
  22. data/examples/random-people/optimise.rb +16 -0
  23. data/examples/random-people/people.rb +22 -0
  24. data/examples/random-people/query.rb +73 -0
  25. data/examples/random-people/query2.rb +73 -0
  26. data/examples/random-people/random-names.csv +10000 -0
  27. data/examples/random-people/rawtc.rb +91 -0
  28. data/examples/random-people/settings.rb +3 -0
  29. data/examples/random-people/what-to-query-on.rb +80 -0
  30. data/examples/random-people/xampl-gen.rb +36 -0
  31. data/examples/random-people/xml/people.xml +11 -0
  32. data/examples/read-testing/Makefile +10 -0
  33. data/examples/read-testing/load.rb +65 -0
  34. data/examples/read-testing/read.rb +51 -0
  35. data/examples/read-testing/rrr.rb +87 -0
  36. data/examples/read-testing/settings.rb +2 -0
  37. data/examples/read-testing/xampl-gen.rb +36 -0
  38. data/examples/read-testing/xml/text.xml +8 -0
  39. data/examples/tokyo-cabinet-experimental/expt-query.rb +42 -0
  40. data/examples/tokyo-cabinet-experimental/expt-query2.rb +42 -0
  41. data/examples/tokyo-cabinet-experimental/expt-query3.rb +41 -0
  42. data/examples/tokyo-cabinet-experimental/expt-reader.rb +32 -0
  43. data/examples/tokyo-cabinet-experimental/expt.rb +61 -0
  44. data/examples/tokyo-cabinet-experimental/xampl-gen.rb +36 -0
  45. data/examples/tokyo-cabinet-experimental/xml/tcx.xml +6 -0
  46. data/lib/xampl-generator.rb +3 -0
  47. data/lib/xampl.rb +3 -0
  48. data/lib/xamplr-generator.rb +10 -0
  49. data/lib/xamplr.rb +37 -0
  50. data/lib/xamplr/README-POSSIBLE-PROBLEMS +5 -0
  51. data/lib/xamplr/TODO +1 -0
  52. data/lib/xamplr/exceptions.rb +97 -0
  53. data/lib/xamplr/from-xml-orig.rb +350 -0
  54. data/lib/xamplr/from-xml.rb +439 -0
  55. data/lib/xamplr/gen-elements.xml +6230 -0
  56. data/lib/xamplr/gen.elements.xml +108 -0
  57. data/lib/xamplr/generate-elements.rb +15 -0
  58. data/lib/xamplr/generator.rb +5 -0
  59. data/lib/xamplr/graphml-out.rb +470 -0
  60. data/lib/xamplr/handwritten/example.rb +698 -0
  61. data/lib/xamplr/handwritten/hand-example.rb +533 -0
  62. data/lib/xamplr/handwritten/test-handwritten.rb +873 -0
  63. data/lib/xamplr/indexed-array.rb +115 -0
  64. data/lib/xamplr/mixins.rb +397 -0
  65. data/lib/xamplr/my.gen.elements.xml +461 -0
  66. data/lib/xamplr/notifications.rb +57 -0
  67. data/lib/xamplr/obsolete/fsdb.rb +62 -0
  68. data/lib/xamplr/persist-to-xml.rb +249 -0
  69. data/lib/xamplr/persistence.rb +522 -0
  70. data/lib/xamplr/persistence.rb.more_thread_safe +771 -0
  71. data/lib/xamplr/persistence.rb.partially_thread_safe +763 -0
  72. data/lib/xamplr/persister.rb +310 -0
  73. data/lib/xamplr/persisters/caches.rb +186 -0
  74. data/lib/xamplr/persisters/caching.rb +172 -0
  75. data/lib/xamplr/persisters/filesystem.rb +60 -0
  76. data/lib/xamplr/persisters/in-memory.rb +180 -0
  77. data/lib/xamplr/persisters/simple.rb +59 -0
  78. data/lib/xamplr/persisters/tokyo-cabinet.rb +641 -0
  79. data/lib/xamplr/simpleTemplate/danger.rx +4 -0
  80. data/lib/xamplr/simpleTemplate/obsolete/input-c.r4 +35 -0
  81. data/lib/xamplr/simpleTemplate/obsolete/play.r6.txt +12 -0
  82. data/lib/xamplr/simpleTemplate/obsolete/play_more.r6.txt +20 -0
  83. data/lib/xamplr/simpleTemplate/obsolete/test001.r5 +8 -0
  84. data/lib/xamplr/simpleTemplate/obsolete/test002.r5 +13 -0
  85. data/lib/xamplr/simpleTemplate/obsolete/test003.r5 +37 -0
  86. data/lib/xamplr/simpleTemplate/old/r6.000.rb +122 -0
  87. data/lib/xamplr/simpleTemplate/old/r6.001.rb +145 -0
  88. data/lib/xamplr/simpleTemplate/play.r6 +12 -0
  89. data/lib/xamplr/simpleTemplate/play_more.r6 +20 -0
  90. data/lib/xamplr/simpleTemplate/play_noblanks.r6 +21 -0
  91. data/lib/xamplr/simpleTemplate/playq.r6 +16 -0
  92. data/lib/xamplr/simpleTemplate/r6.rb +87 -0
  93. data/lib/xamplr/simpleTemplate/simple-template.rb +75 -0
  94. data/lib/xamplr/templates/child.template +47 -0
  95. data/lib/xamplr/templates/child_indexed.template +89 -0
  96. data/lib/xamplr/templates/child_modules.template +5 -0
  97. data/lib/xamplr/templates/element_classes.template +11 -0
  98. data/lib/xamplr/templates/element_data.template +282 -0
  99. data/lib/xamplr/templates/element_empty.template +285 -0
  100. data/lib/xamplr/templates/element_mixed.template +277 -0
  101. data/lib/xamplr/templates/element_simple.template +276 -0
  102. data/lib/xamplr/templates/package.template +26 -0
  103. data/lib/xamplr/test-support/Makefile +47 -0
  104. data/lib/xamplr/test-support/bench-cache.rb +80 -0
  105. data/lib/xamplr/test-support/bench-script.rb +21 -0
  106. data/lib/xamplr/test-support/bench.rb +116 -0
  107. data/lib/xamplr/test-support/bench2.rb +132 -0
  108. data/lib/xamplr/test-support/test-cache.rb +147 -0
  109. data/lib/xamplr/test-support/test-data/binding.xml +7 -0
  110. data/lib/xamplr/test-support/test-data/example.xml +14 -0
  111. data/lib/xamplr/test-support/test-data/internationalization-utf8.txt +1 -0
  112. data/lib/xamplr/test-support/test-data/labels.xml +37 -0
  113. data/lib/xamplr/test-support/test-data/labels001.xml +38 -0
  114. data/lib/xamplr/test-support/test-deep-change.rb +135 -0
  115. data/lib/xamplr/test-support/test-elements.rb +109 -0
  116. data/lib/xamplr/test-support/test-indexed-array.rb +169 -0
  117. data/lib/xamplr/test-support/test-misc.rb +73 -0
  118. data/lib/xamplr/test-support/test-names.rb +67 -0
  119. data/lib/xamplr/test-support/test-rollback.rb +106 -0
  120. data/lib/xamplr/test-support/test.rb +1504 -0
  121. data/lib/xamplr/to-ruby.rb +220 -0
  122. data/lib/xamplr/to-xml.rb +158 -0
  123. data/lib/xamplr/version.rb +67 -0
  124. data/lib/xamplr/visitor.rb +140 -0
  125. data/lib/xamplr/visitors.rb +573 -0
  126. data/lib/xamplr/xampl-generator.rb +533 -0
  127. data/lib/xamplr/xampl-hand-generated.rb +1535 -0
  128. data/lib/xamplr/xampl-module.rb +36 -0
  129. data/lib/xamplr/xampl-object-internals.rb +6 -0
  130. data/lib/xamplr/xampl-object.rb +202 -0
  131. data/lib/xamplr/xampl-persisted-object.rb +122 -0
  132. data/lib/xamplr/xml-text.rb +117 -0
  133. data/lib/xamplr/xml/document.xml +7 -0
  134. data/lib/xamplr/xml/elements.xml +101 -0
  135. data/lib/xamplr/xml/elements000.xml +73 -0
  136. data/lib/xamplr/xml/example.xml +23 -0
  137. data/lib/xamplr/xml/options.xml +12 -0
  138. data/lib/xamplr/xml/uche.xml +38 -0
  139. data/lib/xamplr/yEd-sample.graphml +300 -0
  140. data/test/test_helper.rb +10 -0
  141. data/test/xamplr_test.rb +7 -0
  142. metadata +245 -0
@@ -0,0 +1,73 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "test/unit"
4
+
5
+ require "xamplr-generator"
6
+
7
+ include XamplGenerator
8
+ include Xampl
9
+
10
+ class TestXampl < Test::Unit::TestCase
11
+
12
+ def setup
13
+ Xampl.disable_all_persisters
14
+ FromXML.reset_registry
15
+ end
16
+
17
+ def test_tokenise
18
+ assert_equal(nil, FromXML.tokenise_string(nil))
19
+ assert_equal("", FromXML.tokenise_string(""))
20
+ assert_equal("abc", FromXML.tokenise_string("abc"))
21
+ assert_equal("abc def ghi", FromXML.tokenise_string("abc def ghi"))
22
+ assert_equal("a b c", FromXML.tokenise_string("a b c"))
23
+ assert_equal("a b c", FromXML.tokenise_string(" a b c"))
24
+ assert_equal("a b c", FromXML.tokenise_string("a b c "))
25
+ assert_equal("a b c", FromXML.tokenise_string(" a b c "))
26
+ assert_equal("a b c", FromXML.tokenise_string("a b c"))
27
+ assert_equal("a b c", FromXML.tokenise_string("a\nb\tc"))
28
+ assert_equal("a b c", FromXML.tokenise_string("a\n\t\n\tb\t\n\t\nc"))
29
+ assert_equal("a b c", FromXML.tokenise_string("\n\n\t\ta\n\t\n\tb\t\n\t\nc\n\n"))
30
+ assert_equal("abc", FromXML.tokenise_string("\n abc"))
31
+
32
+ str = "\n\n\t\ta\n\t\n\tb\t\n\t\nc\n\n"
33
+ FromXML.tokenise_string str
34
+ assert_equal("a b c", str)
35
+
36
+ #assert_equal(" a b c", FromXML.tokenise_string(" a b c", false))
37
+ #assert_equal(" a b c", FromXML.tokenise_string(" a b c", false))
38
+ #assert_equal(" a b c", FromXML.tokenise_string("\n\n\t a b c", false))
39
+ end
40
+
41
+ def test_xml_text
42
+ xml=%Q{
43
+ <unknown a='1'
44
+ b='2'
45
+ xmlns='dummy.ns'
46
+ xmlns:ns='another-dummy.ns'
47
+ xmlns:ns1='never-used.ns'
48
+ xmlns:ns2='used-only-by-attr.ns'>
49
+ hello <ns:strong ns2:c='3'
50
+ ns3:d='4'
51
+ xmlns:ns3='also-used-only-by-attr.ns'>there</ns:strong>
52
+ hello <strong ns2:c='3'
53
+ ns3:d='4'
54
+ xmlns='another-dummy.ns'
55
+ xmlns:ns3='also-used-only-by-attr.ns'>there</strong>
56
+ </unknown>
57
+ }
58
+ xml_expected=%Q{<unknown a='1' b='2' xmlns:ns='another-dummy.ns' xmlns:ns2='used-only-by-attr.ns' xmlns:ns3='also-used-only-by-attr.ns' xmlns='dummy.ns'>
59
+ hello <ns:strong ns2:c='3' ns3:d='4' xmlns='another-dummy.ns'>there</ns:strong>
60
+ hello <strong ns2:c='3' ns3:d='4' xmlns='another-dummy.ns'>there</strong>
61
+ </unknown>}
62
+ pp = FromXML.new
63
+ pp.setup_parse_string(xml)
64
+ while !pp.startElement?
65
+ pp.nextEvent
66
+ end
67
+ xml_text = XMLText.new
68
+ xml_text.build(pp)
69
+
70
+ assert_equal(xml_expected, xml_text.text)
71
+ end
72
+ end
73
+
@@ -0,0 +1,67 @@
1
+ #!/usr/bin/env ruby -w
2
+
3
+ require "test/unit"
4
+ require "xamplr-generator"
5
+
6
+ include XamplGenerator
7
+ include Xampl
8
+
9
+ class TestXampl < Test::Unit::TestCase
10
+
11
+ def setup
12
+ Xampl.disable_all_persisters
13
+ end
14
+
15
+ def test_same_names
16
+ options = Xampl.make(Options) { | options |
17
+ options.new_index_attribute("name")
18
+ options.new_resolve{ | resolver |
19
+ resolver.pkg = "XamplExampleNames"
20
+ resolver.namespace="http://xampl.com/example"
21
+ }
22
+ }
23
+ generator = Generator.new(options)
24
+ xml = %Q{
25
+ <conflict name="hansel" xmlns='http://xampl.com/example'>
26
+ <xname name='blah'>
27
+ <conflict name='nested'/>
28
+ </xname>
29
+ <name name='blah'>
30
+ <conflict name='nested'/>
31
+ </name>
32
+ </conflict>
33
+ }
34
+ generator.comprehend_from_strings([ xml ])
35
+ generator.generate_and_eval() { | module_definition, name |
36
+ eval(module_definition, nil, name, 1)
37
+ }
38
+
39
+ parser = FromXML.new
40
+ conflict = parser.parse_string(xml)
41
+
42
+ assert(conflict)
43
+ assert_equal("hansel", conflict.name)
44
+ assert_equal("hansel"[0], conflict.name[0])
45
+ assert_equal("blah", conflict.xname_child[0].name)
46
+ assert_equal("blah", conflict.name_child[0].name)
47
+ assert_nil(conflict.name['blah'])
48
+ end
49
+
50
+ def check_parents(xampl, parent=nil)
51
+ if (nil != parent) then
52
+ found = false
53
+ xampl.parents.each{ | p |
54
+ found = true if (parent == p)
55
+ }
56
+ assert(found)
57
+ else
58
+ if (xampl.kind_of? XamplObject)
59
+ assert((nil == xampl.parents) || (0 == xampl.parents.size))
60
+ end
61
+ end
62
+ xampl.children.each{ | child |
63
+ check_parents(child, xampl) if (child.kind_of? XamplObject)
64
+ }
65
+ end
66
+ end
67
+
@@ -0,0 +1,106 @@
1
+ #!/usr/bin/env ruby -w -I..
2
+
3
+ require "test/unit"
4
+ require "xamplr-generator"
5
+
6
+ include XamplGenerator
7
+ include Xampl
8
+
9
+ class TestRollback < Test::Unit::TestCase
10
+
11
+ xml = %Q{
12
+ <sack pid='white'>
13
+ <bag mark='one'>
14
+ <thing info='something'>hello</thing>
15
+ <stuff id='my stuff'>blah</stuff>
16
+ <bag/>
17
+ </bag>
18
+ <sack pid='black'/>
19
+ </sack>
20
+ }
21
+
22
+ Generator.new.go(:strings => [ xml ],
23
+ :directory => "step7")
24
+
25
+ require "step7/XamplAdHoc"
26
+ include XamplAdHoc
27
+
28
+ def test_rollback
29
+ #sack1 = sack2 = nil
30
+
31
+ Xampl.transaction("step7-persister", :in_memory){
32
+ sack1 = Sack.new
33
+ sack1.pid = "sack1"
34
+
35
+ sack2 = sack1.new_sack("sack2"){ | sack |
36
+ sack.new_bag{ | bag |
37
+ bag.new_thing{ | thing |
38
+ thing.info = "thing in sack2"
39
+ }
40
+ }
41
+ }
42
+ }
43
+
44
+ #assert_equal(0, Xampl.count_changed)
45
+ begin
46
+ Xampl.transaction("step7-persister"){
47
+ sack2 = Sack["sack2"]
48
+
49
+ assert_equal(0, Xampl.count_changed)
50
+
51
+ sack2.bag[0].thing[0].info = "this is a mistake"
52
+
53
+ assert_equal(1, Xampl.count_changed)
54
+
55
+ raise
56
+ }
57
+ rescue Exception
58
+ end
59
+
60
+ #assert_equal(0, Xampl.count_changed)
61
+
62
+ Xampl.transaction("step7-persister"){
63
+ sack1 = Sack["sack1"]
64
+ assert_equal("thing in sack2", sack1.sack[0].bag[0].thing[0].info)
65
+ }
66
+
67
+ end
68
+
69
+ def test_rollback_in_fs
70
+ #sack1 = sack2 = nil
71
+
72
+ pname = "test_rollback_in_fs" << Time.now.strftime("%Y%m%d-%H%M-%S") << rand.to_s
73
+ Xampl.transaction(pname, :filesystem){
74
+ sack1 = Sack.new
75
+ sack1.pid = "sack1"
76
+
77
+ sack2 = sack1.new_sack("sack2"){ | sack |
78
+ sack.new_bag{ | bag |
79
+ bag.new_thing{ | thing |
80
+ thing.info = "thing in sack2"
81
+ }
82
+ }
83
+ }
84
+ }
85
+
86
+ #assert_equal(0, Xampl.count_changed)
87
+ begin
88
+ Xampl.transaction(pname, :filesystem){
89
+ sack2 = Sack["sack2"]
90
+
91
+ sack2.bag[0].thing[0].info = "this is a mistake"
92
+
93
+ raise
94
+ }
95
+ rescue Exception
96
+ end
97
+
98
+ #assert_equal(0, Xampl.count_changed)
99
+
100
+ Xampl.transaction(pname, :filesystem){
101
+ sack1 = Sack["sack1"]
102
+ assert_equal("thing in sack2", sack1.sack[0].bag[0].thing[0].info)
103
+ }
104
+
105
+ end
106
+ end
@@ -0,0 +1,1504 @@
1
+ #!/usr/bin/env ruby -w
2
+
3
+ require "test/unit"
4
+ require "xamplr-generator"
5
+
6
+ include XamplGenerator
7
+ include Xampl
8
+
9
+ def assert_xampl_exception(name)
10
+ xampl_exception = assert_raise(XamplException){
11
+ yield
12
+ }
13
+ assert_equal(name, xampl_exception.name)
14
+ end
15
+
16
+ options = Xampl.make(Options) { | options |
17
+ options.new_index_attribute("name")
18
+ options.new_index_attribute("id")
19
+ options.new_index_attribute("pid").persisted = true
20
+
21
+ options.resolve("http://xampl.com/example", "XamplExample", "ex")
22
+ options.resolve("http://xampl.com/example/special", "XamplExampleSpecial", "exs")
23
+ }
24
+ generator = Generator.new(options)
25
+
26
+ the_xml_file = File.join(".", "xml", "example.xml")
27
+ if (0 < ARGV.size) then
28
+ File.open(the_xml_file){ | f |
29
+ s = f.read
30
+ generator.comprehend_from_strings([s])
31
+ generator.generate_and_eval() { | module_definition, name |
32
+ eval(module_definition, nil, name, 1)
33
+ }
34
+
35
+ #generator.print_stats
36
+ }
37
+ include XamplExample
38
+ else
39
+ generator.comprehend_from_files([the_xml_file])
40
+ generator.generate_to_directory(File.join(".", "tmp"))
41
+ #generator.print_stats
42
+
43
+ require "tmp/XamplExample"
44
+ include XamplExample
45
+ end
46
+
47
+ #generator.report_elements
48
+
49
+ class TestXampl < Test::Unit::TestCase
50
+
51
+ def setup
52
+ Xampl.disable_all_persisters
53
+ #FromXML.reset_registry
54
+ end
55
+
56
+ def test_simple_xampl
57
+ emph1 = Emph.new
58
+ assert_not_nil(emph1.is_changed)
59
+ emph2 = Emph.new
60
+ assert_not_nil(emph2.is_changed)
61
+ emph3 = Emph.new
62
+ assert_not_nil(emph3.is_changed)
63
+
64
+ emph1.content = "emph 1"
65
+ assert_not_nil(emph1.is_changed)
66
+ emph2.content = "emph 2"
67
+ assert_not_nil(emph2.is_changed)
68
+
69
+ assert_equal("emph 1", emph1.content)
70
+ assert_equal("emph 2", emph2.content)
71
+
72
+ assert_equal("<ex:emph xmlns:ex='http://xampl.com/example'>emph 1</ex:emph>", emph1.test_to_xml)
73
+ assert_equal("<ex:emph xmlns:ex='http://xampl.com/example'>emph 2</ex:emph>", emph2.test_to_xml)
74
+ assert_equal("<ex:emph xmlns:ex='http://xampl.com/example'/>", emph3.test_to_xml)
75
+
76
+ fakeRules = XMLPrinter.new("fake...")
77
+ emph1.test_to_xml_internal(fakeRules)
78
+ r = fakeRules.done
79
+
80
+ assert_equal("fake... xmlns:ex='http://xampl.com/example'<ex:emph>emph 1</ex:emph>", r)
81
+
82
+ assert_not_nil(emph1.is_changed)
83
+ assert_not_nil(emph2.is_changed)
84
+ assert_not_nil(emph3.is_changed)
85
+
86
+ check_parents(emph1)
87
+ check_parents(emph2)
88
+ check_parents(emph3)
89
+ end
90
+
91
+ def test_empty_xampl
92
+ stuff1 = Stuff.new
93
+ assert_not_nil(stuff1.is_changed)
94
+ stuff1.kind = 'test'
95
+ assert_not_nil(stuff1.is_changed)
96
+
97
+ stuff2 = Stuff.new
98
+ assert_not_nil(stuff2.is_changed)
99
+
100
+ stuff3 = Stuff.new
101
+ assert_not_nil(stuff3.is_changed)
102
+ stuff3.kind = 'test'
103
+ assert_not_nil(stuff3.is_changed)
104
+ stuff3.special = 'test'
105
+ assert_not_nil(stuff3.is_changed)
106
+
107
+ assert_equal("<ex:stuff kind='test' xmlns:ex='http://xampl.com/example' xmlns:exs='http://xampl.com/example/special'/>",
108
+ stuff1.test_to_xml)
109
+ assert_equal("<ex:stuff xmlns:ex='http://xampl.com/example' xmlns:exs='http://xampl.com/example/special'/>",
110
+ stuff2.test_to_xml)
111
+ assert_equal("<ex:stuff kind='test' exs:special='test' xmlns:ex='http://xampl.com/example' xmlns:exs='http://xampl.com/example/special'/>",
112
+ stuff3.test_to_xml)
113
+
114
+ fakeRules = XMLPrinter.new("fake...")
115
+ stuff1.test_to_xml_internal(fakeRules)
116
+ r = fakeRules.done
117
+ assert_equal("fake... xmlns:ex='http://xampl.com/example' xmlns:exs='http://xampl.com/example/special'<ex:stuff kind='test'/>", r)
118
+
119
+ check_parents(stuff1)
120
+ check_parents(stuff2)
121
+ check_parents(stuff3)
122
+ end
123
+
124
+ def test_mixed_xampl
125
+ desc1 = Description.new
126
+ assert_not_nil(desc1.is_changed)
127
+ desc1.kind = "desc1"
128
+ assert_not_nil(desc1.is_changed)
129
+ assert_equal("<ex:description kind='desc1' xmlns:ex='http://xampl.com/example'/>",
130
+ desc1.test_to_xml)
131
+
132
+ desc1.add_content("hello ")
133
+ emph_content_1 = "there"
134
+ desc1.new_emph.content = emph_content_1
135
+ desc1.add_content("! How ")
136
+ emph_content_2 = "are"
137
+ desc1.new_emph.content = emph_content_2
138
+ desc1.add_content(" you?")
139
+
140
+ assert_not_nil(desc1.is_changed)
141
+ assert_equal("<ex:description kind='desc1' xmlns:ex='http://xampl.com/example'>hello <ex:emph>there</ex:emph>! How <ex:emph>are</ex:emph> you?</ex:description>",
142
+ desc1.test_to_xml)
143
+ assert_equal(desc1.emph_child.length, 2)
144
+ assert_equal(emph_content_1, desc1.emph_child[0].content, emph_content_1)
145
+ assert_equal(emph_content_2, desc1.emph_child[1].content, emph_content_2)
146
+
147
+ check_parents(desc1)
148
+ end
149
+
150
+ def test_data_xampl
151
+ emph_content_1 = "there"
152
+ emph_content_2 = "are"
153
+ big_thing = Xampl.make(Thing){ | big_thing |
154
+ big_thing.pid = "big_thing"
155
+ big_thing.new_thing("thing"){ | thing |
156
+ thing.new_stuff.kind = "stuff1"
157
+
158
+ thing.new_description{ | desc |
159
+ desc.kind = "desc1"
160
+
161
+ desc.add_content("hello ")
162
+ desc.new_emph.content = emph_content_1
163
+ desc.add_content("! How ")
164
+ desc.new_emph.content = emph_content_2
165
+ desc.add_content(" you?")
166
+ }
167
+ }
168
+ }
169
+
170
+ ### desc1 = Description.new
171
+ ### desc1.kind = "desc1"
172
+ ###
173
+ ### desc1.add_content("hello ")
174
+ ### emph_content_1 = "there"
175
+ ### desc1.new_emph.content = emph_content_1
176
+ ### desc1.add_content("! How ")
177
+ ### emph_content_2 = "are"
178
+ ### desc1.new_emph.content = emph_content_2
179
+ ### desc1.add_content(" you?")
180
+ ###
181
+ ### thing = Thing.new
182
+ ### thing.pid = "thing"
183
+ ### assert(thing.is_changed)
184
+ ### thing.new_stuff.kind = "stuff1"
185
+ ### assert_not_nil(thing.is_changed)
186
+ ### thing.is_changed = nil
187
+ ### thing.add_description(desc1)
188
+ ### assert_not_nil(thing.is_changed)
189
+ ###
190
+ ### big_thing = Thing.new
191
+ ### big_thing.add_thing(thing)
192
+ assert_equal("<ex:thing pid='big_thing' xmlns:ex='http://xampl.com/example' xmlns:exs='http://xampl.com/example/special'><ex:thing pid='thing'><ex:stuff kind='stuff1'/><ex:description kind='desc1'>hello <ex:emph>there</ex:emph>! How <ex:emph>are</ex:emph> you?</ex:description></ex:thing></ex:thing>",
193
+ big_thing.test_to_xml)
194
+
195
+ assert_equal(1, big_thing.children.length)
196
+ assert_equal(2, big_thing.thing_child[0].children.length)
197
+ assert_equal(big_thing.thing_child[0].description_child[0].emph_child.length, 2)
198
+ assert_equal(emph_content_1, big_thing.thing_child[0].description_child[0].emph_child[0].content, emph_content_1)
199
+ assert_equal(emph_content_2, big_thing.thing_child[0].description_child[0].emph_child[1].content, emph_content_2)
200
+
201
+ check_parents(big_thing)
202
+ end
203
+
204
+ def test_ensure
205
+ big_thing = Xampl.make(Thing){ | big_thing |
206
+ big_thing.pid = "big_thing"
207
+ big_thing.ensure_thing("thing"){ | thing |
208
+ thing.info = "first";
209
+ }
210
+ big_thing.ensure_thing("thing"){ | thing |
211
+ flunk "What are you doing in here?"
212
+ thing.info = "second";
213
+ }
214
+ }
215
+
216
+ assert_equal(1, big_thing.thing.length)
217
+ assert_equal("first", big_thing.thing[0].info)
218
+
219
+ desc = Description.new
220
+ desc.ensure_emph
221
+ assert_equal(1, desc.emph.length)
222
+ #NOTE -- ensure_emph used to be aliased to new_emph, now it just makes
223
+ # sure that there is at least one emph
224
+ end
225
+
226
+ def test_data_xampl_using_append
227
+ emph_content_1 = "there"
228
+ emph1 = Emph.new
229
+ emph1 << emph_content_1
230
+
231
+ emph_content_2 = "are"
232
+ emph2 = Emph.new
233
+ emph2.content = emph_content_2
234
+
235
+ desc1 = Description.new
236
+ desc1.kind = "desc1"
237
+
238
+ desc1.is_changed = nil
239
+ desc1 << "hello " << emph1 << "! How " << emph2 << " you?"
240
+ assert_not_nil(desc1.is_changed)
241
+
242
+ thing = Thing.new
243
+ thing.pid = "thing"
244
+ thing.new_stuff.kind = "stuff1"
245
+ thing << desc1
246
+
247
+ big_thing = Thing.new
248
+ big_thing << thing
249
+
250
+ assert_equal("<ex:thing xmlns:ex='http://xampl.com/example' xmlns:exs='http://xampl.com/example/special'><ex:thing pid='thing'><ex:stuff kind='stuff1'/><ex:description kind='desc1'>hello <ex:emph>there</ex:emph>! How <ex:emph>are</ex:emph> you?</ex:description></ex:thing></ex:thing>",
251
+ big_thing.test_to_xml)
252
+
253
+ assert_equal(2, big_thing.thing_child[0].description_child[0].emph_child.length)
254
+ assert_equal(emph_content_1, big_thing.thing_child[0].description_child[0].emph_child[0].content)
255
+ assert_equal(emph_content_2, big_thing.thing_child[0].description_child[0].emph_child[1].content)
256
+
257
+ check_parents(big_thing)
258
+ end
259
+
260
+ def test_from_xml
261
+ emph_content_1 = "there"
262
+ emph1 = Emph.new
263
+ emph1 << emph_content_1
264
+
265
+ emph_content_2 = "are"
266
+ emph2 = Emph.new
267
+ emph2.content = emph_content_2
268
+
269
+ desc1 = Description.new
270
+ desc1.kind = "desc1"
271
+
272
+ desc1.is_changed = nil
273
+ desc1 << "hello " << emph1 << "! How " << emph2 << " you?"
274
+
275
+ thing = Thing.new
276
+ thing.pid = "thing"
277
+ thing.new_stuff.kind = "stuff1"
278
+ thing << desc1
279
+
280
+ big_thing = Thing.new
281
+ big_thing << "leading content" << thing << "trailing content"
282
+
283
+ #puts big_thing.test_to_xml
284
+ #pp = FromXML.new
285
+ #pp.setup_parse_string(big_thing.test_to_xml)
286
+ #while not pp.endDocument?
287
+ #event = pp.next_interesting_event
288
+ #puts event
289
+ #if (event == Xampl_PP::TEXT) then
290
+ #puts "TEXT [[[" << pp.text << "]]]"
291
+ #end
292
+ #end
293
+
294
+ pp = FromXML.new
295
+ pp.setup_parse_string(big_thing.test_to_xml)
296
+ assert_equal(pp.next_interesting_event, Xampl_PP::START_ELEMENT)
297
+ assert_equal(pp.next_interesting_event, Xampl_PP::TEXT)
298
+ assert_equal(pp.next_interesting_event, Xampl_PP::START_ELEMENT)
299
+ assert_equal(pp.next_interesting_event, Xampl_PP::START_ELEMENT)
300
+
301
+ assert_equal(pp.next_interesting_event, Xampl_PP::END_ELEMENT)
302
+ assert_equal(pp.next_interesting_event, Xampl_PP::START_ELEMENT)
303
+ assert_equal(pp.next_interesting_event, Xampl_PP::TEXT)
304
+ assert_equal(pp.next_interesting_event, Xampl_PP::START_ELEMENT)
305
+ assert_equal(pp.next_interesting_event, Xampl_PP::TEXT)
306
+ assert_equal(pp.next_interesting_event, Xampl_PP::END_ELEMENT)
307
+ assert_equal(pp.next_interesting_event, Xampl_PP::TEXT)
308
+ assert_equal(pp.next_interesting_event, Xampl_PP::START_ELEMENT)
309
+ assert_equal(pp.next_interesting_event, Xampl_PP::TEXT)
310
+ assert_equal(pp.next_interesting_event, Xampl_PP::END_ELEMENT)
311
+ assert_equal(pp.next_interesting_event, Xampl_PP::TEXT)
312
+ assert_equal(pp.next_interesting_event, Xampl_PP::END_ELEMENT)
313
+ assert_equal(pp.next_interesting_event, Xampl_PP::END_ELEMENT)
314
+ assert_equal(pp.next_interesting_event, Xampl_PP::END_ELEMENT)
315
+ assert_equal(pp.next_interesting_event, Xampl_PP::END_DOCUMENT)
316
+ assert(pp.endDocument?)
317
+
318
+ pp = FromXML.new
319
+ #another_big_thing = pp.parse_string(big_thing.test_to_xml)
320
+ another_big_thing = pp.parse_string(big_thing.pp_xml)
321
+
322
+ #assert_equal(big_thing.test_to_xml, another_big_thing.test_to_xml)
323
+ assert_equal(big_thing.pp_xml.gsub(/\s/, ''), another_big_thing.pp_xml.gsub(/\s/, ''))
324
+ assert_not_same(big_thing, another_big_thing)
325
+ end
326
+
327
+ def test_index
328
+ thing = Thing.new
329
+ thing.new_key_value("one").value = "1"
330
+ thing.new_key_value("two").value = "2"
331
+
332
+ assert_same(thing.key_value_child[0], thing.key_value_child["one"])
333
+ assert_same(thing.key_value_child[1], thing.key_value_child["two"])
334
+
335
+ thing.new_key_value("one").value = "1a"
336
+
337
+ assert_same(thing.key_value_child[0], thing.key_value_child["two"])
338
+ assert_same(thing.key_value_child[1], thing.key_value_child["one"])
339
+
340
+ check_parents(thing)
341
+ end
342
+
343
+ def test_indexed_remove
344
+ thing = Thing.new
345
+ thing.new_key_value("one").value = "1"
346
+ thing.remove_key_value(thing.key_value["one"])
347
+
348
+ assert_equal(0, thing.children.size)
349
+ assert_equal(0, thing.key_value_child.size)
350
+
351
+ thing = Thing.new
352
+ thing.new_key_value("one").value = "1"
353
+ thing.new_key_value("two").value = "2"
354
+ thing.remove_key_value(thing.key_value["one"])
355
+
356
+ assert_equal(1, thing.children.size)
357
+ assert_equal(1, thing.key_value_child.size)
358
+ assert_not_nil(thing.key_value["two"])
359
+ assert_equal("2", thing.key_value["two"].value)
360
+
361
+ end
362
+
363
+ def test_parents
364
+ thing = Thing.new
365
+ (kv1 = thing.new_key_value("one")).value = "1"
366
+ (kv2 = thing.new_key_value("two")).value = "2"
367
+
368
+ assert_same(thing, thing.key_value_child[0].parents[0])
369
+ assert_same(thing, thing.key_value_child[1].parents[0])
370
+
371
+ another_thing = Thing.new
372
+ another_thing << kv1 << kv2
373
+
374
+ assert_equal(2, kv1.parents.size)
375
+ assert_equal(2, kv2.parents.size)
376
+
377
+ check_parents(thing)
378
+ check_parents(another_thing)
379
+ end
380
+
381
+ def test_non_string_attributes
382
+ stuff1 = Stuff.new
383
+
384
+ stuff1.kind = 123.456
385
+ assert_equal("<ex:stuff kind='123.456' xmlns:ex='http://xampl.com/example' xmlns:exs='http://xampl.com/example/special'/>",
386
+ stuff1.test_to_xml)
387
+
388
+ stuff1.kind = nil
389
+ assert_equal("<ex:stuff xmlns:ex='http://xampl.com/example' xmlns:exs='http://xampl.com/example/special'/>",
390
+ stuff1.test_to_xml)
391
+
392
+ stuff1.kind = [1, 2, 3]
393
+ assert_equal("<ex:stuff kind='123' xmlns:ex='http://xampl.com/example' xmlns:exs='http://xampl.com/example/special'/>",
394
+ stuff1.test_to_xml)
395
+
396
+ stuff2 = Stuff.new
397
+ stuff2.kind = 123
398
+ stuff1.kind = stuff2
399
+ assert_equal("<ex:stuff kind='&lt;ex:stuff kind=&apos;123&apos; xmlns:ex=&apos;http://xampl.com/example&apos; xmlns:exs=&apos;http://xampl.com/example/special&apos;/&gt;' xmlns:ex='http://xampl.com/example' xmlns:exs='http://xampl.com/example/special'/>",
400
+ stuff1.test_to_xml)
401
+
402
+ thing = Thing.new
403
+ thing.pid = "thing"
404
+ thing << stuff2
405
+ stuff1.kind = thing
406
+ assert_equal("<ex:stuff kind='&lt;ex:thing pid=&apos;thing&apos; xmlns:ex=&apos;http://xampl.com/example&apos; xmlns:exs=&apos;http://xampl.com/example/special&apos;&gt;&lt;ex:stuff kind=&apos;123&apos;/&gt;&lt;/ex:thing&gt;' xmlns:ex='http://xampl.com/example' xmlns:exs='http://xampl.com/example/special'/>",
407
+ stuff1.test_to_xml)
408
+
409
+ check_parents(stuff1)
410
+ end
411
+
412
+ def test_registry
413
+ assert_equal([ Emph ], FromXML::registered(Emph::ns_tag))
414
+ assert_equal([ Emph ], FromXML::registered(Emph::tag))
415
+ assert_equal([ Stuff ], FromXML::registered(Stuff::ns_tag))
416
+ assert_equal([ Stuff ], FromXML::registered(Stuff::tag))
417
+
418
+ FromXML::register(Emph::tag, Emph::ns_tag, Emph)
419
+ assert_equal([ Emph ], FromXML::registered(Emph::ns_tag))
420
+ assert_equal([ Emph ], FromXML::registered(Emph::tag))
421
+
422
+ FromXML::register(Emph::tag, Thing::ns_tag, Thing)
423
+ assert_equal([ Emph ], FromXML::registered(Emph::ns_tag))
424
+ assert_equal([ Emph, Thing ], FromXML::registered(Emph::tag))
425
+ end
426
+
427
+ def test_in_memory_persistence_basics
428
+ stuff = Stuff.new
429
+ thing = Thing.new
430
+ thing << stuff
431
+
432
+ assert(!stuff.persist_required)
433
+ assert(thing.persist_required)
434
+ assert(nil == thing.persister)
435
+
436
+ persister = InMemoryPersister.new
437
+
438
+ assert_xampl_exception(:no_index_so_no_persist){
439
+ persister.write(thing)
440
+ }
441
+
442
+ thing.pid = "thing"
443
+
444
+ assert(persister.write(thing))
445
+
446
+ saved_thing = persister.read(Thing, "thing")
447
+ assert(saved_thing)
448
+
449
+ assert_equal(thing.test_to_xml, saved_thing.test_to_xml)
450
+ assert_not_same(thing, saved_thing)
451
+
452
+ pname = "first" << Time.now.strftime("%Y%m%d-%H%M-%S") << rand.to_s
453
+ Xampl.enable_persister(pname, :in_memory)
454
+ persister1 = Xampl.persister
455
+
456
+ #check that the naming and kind checking is working
457
+ assert_raise(IncompatiblePersisterRequest){
458
+ Xampl.enable_persister(pname, :filesystem)
459
+ }
460
+ #okay, carry on
461
+
462
+ Xampl.enable_persister(pname, :in_memory)
463
+ persister2 = Xampl.persister
464
+
465
+ assert_equal(persister1, persister2)
466
+
467
+ stuff = Stuff.new
468
+ thing = Thing.new
469
+ thing.pid = "thing"
470
+ thing << stuff
471
+
472
+ assert_nil(Xampl.lookup(Thing, "thing"))
473
+
474
+ assert(nil == thing.persister)
475
+ assert(thing.is_changed)
476
+ assert(0 == Xampl.count_changed)
477
+ Xampl.introduce_to_persister(thing)
478
+ assert(thing.persister)
479
+ assert_equal(1, Xampl.count_changed)
480
+ assert_same(thing, Xampl.lookup(Thing, "thing"), "cannot lookup new stuff")
481
+ assert_same(thing, Thing.lookup("thing"), "cannot lookup new stuff")
482
+ assert_same(thing, Thing["thing"], "cannot lookup new stuff")
483
+
484
+ #Xampl.print_stats
485
+
486
+ assert_equal(1, Xampl.count_changed)
487
+ writes = Xampl.sync
488
+ assert_equal(1, writes)
489
+ assert_equal(0, Xampl.count_changed)
490
+ assert(Xampl.lookup(Thing, "thing"))
491
+
492
+ assert_same(thing, Xampl.lookup(Thing, "thing"), "cannot lookup cached stuff")
493
+
494
+ Xampl.clear_cache
495
+
496
+ found = Xampl.lookup(Thing, "thing")
497
+ assert_not_equal(thing, found)
498
+ assert(thing === found)
499
+
500
+ #Xampl.print_stats
501
+ end
502
+
503
+ def test_in_memory_persistence_ruby
504
+ pname = "test_in_memory_persistence_ruby" << Time.now.strftime("%Y%m%d-%H%M-%S") << rand.to_s
505
+ Xampl.enable_persister(pname, :in_memory, :ruby_format)
506
+ persister2 = Xampl.persister
507
+
508
+ stuff = Stuff.new
509
+ thing = Thing.new
510
+ thing.pid = "thing"
511
+ thing << stuff
512
+
513
+ Xampl.introduce_to_persister(thing)
514
+ Xampl.sync
515
+ Xampl.clear_cache
516
+ found = Xampl.lookup(Thing, "thing")
517
+
518
+ assert_not_equal(thing, found)
519
+ assert(thing === found)
520
+ end
521
+
522
+ def test_in_memory_persistence_rollback
523
+ pname = "first" << Time.now.strftime("%Y%m%d-%H%M-%S") << rand.to_s
524
+ original_persister = Xampl.enable_persister(pname, :in_memory)
525
+
526
+ stuff = Stuff.new
527
+ thing = Thing.new
528
+ thing.pid = "thing"
529
+ thing << stuff
530
+
531
+ Xampl.introduce_to_persister(thing)
532
+
533
+ Xampl.rollback
534
+
535
+ current_persister = Xampl.persister
536
+
537
+ #assert_not_equal(original_persister, current_persister)
538
+ assert_equal(original_persister, current_persister)
539
+
540
+ # no sync after thing's creation, so thing should NOT exist after rollback
541
+ found = Xampl.lookup(Thing, "thing")
542
+ assert_nil(found)
543
+
544
+ assert_equal(original_persister, thing.persister)
545
+
546
+ #assert_xampl_exception(:live_across_rollback){
547
+ # thing.new_stuff
548
+ #}
549
+ assert_raise(XamplIsInvalid){
550
+ thing.new_stuff
551
+ }
552
+
553
+ writes = Xampl.sync
554
+
555
+ assert_equal(0, writes)
556
+ end
557
+
558
+ def test_in_memory_persistence_rollback_survival
559
+ pname = "first" << Time.now.strftime("%Y%m%d-%H%M-%S") << rand.to_s
560
+ original_persister = Xampl.enable_persister(pname, :in_memory)
561
+
562
+ stuff = Stuff.new
563
+ thing = Thing.new
564
+ thing.pid = "thing"
565
+ thing << stuff
566
+
567
+ Xampl.introduce_to_persister(thing)
568
+
569
+ Xampl.sync
570
+
571
+ thing.new_stuff
572
+ thing.info = "something"
573
+
574
+ Xampl.rollback
575
+
576
+ assert(thing.load_needed)
577
+ assert(!thing.is_changed)
578
+
579
+ assert_nil(thing.info, "attributes not cleared by the rollback")
580
+
581
+ current_persister = Xampl.persister
582
+
583
+ #assert_not_equal(original_persister, current_persister)
584
+ assert_equal(original_persister, current_persister) # stomp
585
+
586
+ # a sync done BEFORE the second 'stuff' was added to thing
587
+ found = Xampl.lookup(Thing, "thing")
588
+ assert_equal(thing, found)
589
+
590
+ assert_equal(original_persister, current_persister)
591
+ assert_equal(original_persister, thing.persister)
592
+ assert_equal(current_persister, found.persister)
593
+
594
+ assert_equal(1, thing.stuff.size)
595
+ assert_equal(1, found.stuff.size)
596
+
597
+ # assert_xampl_exception(:live_across_rollback){
598
+ # thing.new_stuff
599
+ # }
600
+
601
+ writes = Xampl.sync
602
+
603
+ assert_equal(0, writes)
604
+
605
+ new_thing = found.new_thing("new_thing")
606
+ new_thing.new_stuff
607
+
608
+ writes = Xampl.sync
609
+
610
+ assert_equal(2, writes)
611
+
612
+ new_thing.new_stuff
613
+ writes = Xampl.sync
614
+ assert_equal(1, writes)
615
+ end
616
+
617
+ def test_filesystem_persistence_basics
618
+ stuff = Stuff.new
619
+ thing = Thing.new
620
+ thing << stuff
621
+
622
+ thing.pid = "thing"
623
+
624
+ assert_xampl_exception(:name_required){
625
+ Xampl.enable_persister(nil, :filesystem)
626
+ }
627
+
628
+ pname = "test_filesystem_persistence_basics_ut" << Time.now.strftime("%Y%m%d-%H%M-%S") << rand.to_s
629
+ Xampl.enable_persister(pname, :filesystem)
630
+
631
+ stuff = Stuff.new
632
+ thing = Thing.new
633
+ thing.pid = "thing"
634
+ thing << stuff
635
+
636
+ assert_nil(Xampl.lookup(Thing, "thing"))
637
+
638
+ assert(nil == thing.persister)
639
+ assert(thing.is_changed)
640
+ assert_equal(0, Xampl.count_changed)
641
+
642
+ Xampl.introduce_to_persister(thing)
643
+
644
+ assert(thing.persister)
645
+ assert_equal(1, Xampl.count_changed)
646
+ assert_same(thing, Xampl.lookup(Thing, "thing"), "cannot lookup new stuff")
647
+
648
+ #Xampl.print_stats
649
+
650
+ assert_equal(1, Xampl.count_changed)
651
+ writes = Xampl.sync
652
+ assert_equal(1, writes)
653
+ assert_equal(0, Xampl.count_changed)
654
+ assert(Xampl.lookup(Thing, "thing"))
655
+
656
+ assert_same(thing, Xampl.lookup(Thing, "thing"), "cannot lookup cached stuff")
657
+
658
+ Xampl.clear_cache
659
+
660
+ found = Xampl.lookup(Thing, "thing")
661
+ assert_not_same(thing, found)
662
+ assert(thing === found)
663
+
664
+ Xampl.clear_cache
665
+
666
+ # now, changing thing will affect the DB -- VERY SUBTLE POSSIBLIITY OF BUG!
667
+ thing.new_stuff
668
+ assert_equal(2, thing.stuff.size)
669
+ assert_equal(1, found.stuff.size)
670
+
671
+ writes = Xampl.sync
672
+
673
+ assert_equal(2, thing.stuff.size)
674
+ assert_equal(1, found.stuff.size)
675
+
676
+ found2 = Xampl.lookup(Thing, "thing")
677
+
678
+ assert_equal(2, thing.stuff.size)
679
+ assert_equal(1, found.stuff.size)
680
+ assert_equal(2, found2.stuff.size)
681
+
682
+ assert(!(found === found2))
683
+ assert(thing === found2)
684
+
685
+ assert_not_equal(found, found2)
686
+
687
+ #Xampl.print_stats
688
+ end
689
+
690
+ def test_filesystem_persistence_very_many
691
+ name = "test_filesystem_persistence_very_many_ut" << Time.now.strftime("%Y%m%d-%H%M-%S") << rand.to_s
692
+ holder = nil
693
+
694
+ Xampl.transaction(name, :filesystem, automatic=true) do
695
+ holder = Thing.new("root")
696
+ end
697
+
698
+ 1.upto(200) do |i|
699
+ Xampl.transaction(name, :filesystem, automatic=true) do
700
+ child = holder.new_thing("child#{i}")
701
+ end
702
+ end
703
+
704
+ #Xampl.transaction(name, :filesystem, automatic=true) do
705
+ #Xampl.print_stats
706
+ #end
707
+
708
+ Xampl.transaction(name, :filesystem, automatic=true) do
709
+ holder.thing.each{ | child |
710
+ found = Xampl.lookup(Thing, child.pid)
711
+ assert_equal(child, found)
712
+ }
713
+ #Xampl.print_stats
714
+ end
715
+ end
716
+
717
+ def test_filesystem_persistence_over_write_on_parse
718
+ name = "test_filesystem_persistence_over_write_on_parse_ut" << Time.now.strftime("%Y%m%d-%H%M-%S") << rand.to_s
719
+ holder = nil
720
+ Xampl.transaction(name, :filesystem, automatic=true) do
721
+ holder = Thing.new("root")
722
+ end
723
+
724
+ Xampl.transaction(name, :filesystem, automatic=true) do
725
+ 1.upto(10) do |i|
726
+ cname = "child#{i}"
727
+ child = holder.new_thing(cname)
728
+ child.new_key_value('index').value = cname
729
+ end
730
+ end
731
+
732
+ Xampl.transaction(name, :filesystem, automatic=true) do
733
+ Xampl.print_stats
734
+ end
735
+
736
+ xml = holder.pp_xml
737
+
738
+ Xampl.transaction(name, :filesystem, automatic=true) do
739
+ 1.upto(11) do |i|
740
+ cname = "child#{i}"
741
+ child = holder.ensure_thing(cname)
742
+ child.ensure_key_value('index').value = "changed#{i}"
743
+ end
744
+ holder.remove_thing("child1")
745
+ end
746
+
747
+ assert_equal(10, holder.thing.size)
748
+ assert_equal(holder.children.size, holder.thing.size)
749
+
750
+ parsed_holder = nil
751
+ Xampl.transaction(name, :filesystem, automatic=true) do
752
+ parsed_holder = XamplObject.from_xml_string(xml)
753
+ end
754
+
755
+ assert_equal(10, holder.thing.size)
756
+ assert_equal(holder.children.size, holder.thing.size)
757
+
758
+ assert_equal(parsed_holder, holder)
759
+
760
+ Xampl.transaction(name, :filesystem, automatic=true) do
761
+ holder.thing.each{ | child |
762
+ found = Xampl.lookup(Thing, child.pid)
763
+ assert_equal(child, found)
764
+ assert_equal(child, parsed_holder.thing[child.pid])
765
+ }
766
+ Xampl.print_stats
767
+ end
768
+ end
769
+
770
+ def test_filesystem_persistence_ruby
771
+ pname = "test_filesystem_persistence_ruby" << Time.now.strftime("%Y%m%d-%H%M-%S") << rand.to_s
772
+ Xampl.enable_persister(pname, :filesystem, :ruby_format)
773
+ persister2 = Xampl.persister
774
+
775
+ stuff = Stuff.new
776
+ thing = Thing.new
777
+ thing.pid = "thing"
778
+ thing << stuff
779
+
780
+ Xampl.introduce_to_persister(thing)
781
+ Xampl.sync
782
+
783
+ thing.info = "force emptying"
784
+
785
+ Xampl.rollback
786
+
787
+ assert(thing.load_needed)
788
+
789
+ found = Xampl.lookup(Thing, "thing")
790
+
791
+ assert_equal(thing.object_id, found.object_id)
792
+ end
793
+
794
+ def test_filesystem_persistence_automatic
795
+ stuff = Stuff.new
796
+ thing = Thing.new
797
+ thing << stuff
798
+
799
+ thing.pid = "thing"
800
+
801
+ pname = "test_filesystem_persistence_automatic_ut" << Time.now.strftime("%Y%m%d-%H%M-%S") << rand.to_s
802
+ Xampl.enable_persister(pname, :filesystem)
803
+ Xampl.auto_persistence
804
+
805
+ stuff = Stuff.new
806
+ thing = Thing.new
807
+ thing.pid = "thing"
808
+ thing << stuff
809
+
810
+ assert_equal(thing, Xampl.lookup(Thing, "thing"))
811
+
812
+ assert(thing.persister)
813
+ assert(thing.is_changed)
814
+ assert_equal(1, Xampl.count_changed)
815
+
816
+ assert_equal(thing, Xampl.lookup(Thing, "thing"), "cannot lookup new stuff")
817
+
818
+ writes = Xampl.sync
819
+
820
+ assert_equal(1, writes)
821
+ assert_equal(0, Xampl.count_changed)
822
+
823
+ assert(Xampl.lookup(Thing, "thing"))
824
+ assert_equal(thing, Xampl.lookup(Thing, "thing"), "cannot lookup cached stuff")
825
+ assert_same(thing, Xampl.lookup(Thing, "thing"), "cannot lookup cached stuff")
826
+
827
+ Xampl.clear_cache
828
+
829
+ found = Xampl.lookup(Thing, "thing")
830
+ assert_not_equal(thing, found)
831
+ assert_not_same(thing, found)
832
+
833
+ root = Thing.new
834
+ root.pid = "root"
835
+ found2 = root.new_thing("thing")
836
+
837
+ assert_equal(found, found2, "in automatic persistence mode, supposed to look stuff up")
838
+
839
+ #Xampl.print_stats
840
+ end
841
+
842
+ def test_filesystem_persistence_rollback
843
+ pname = "test_filesystem_persistence_rollback_ut" << Time.now.strftime("%Y%m%d-%H%M-%S") << rand.to_s
844
+ original_persister = Xampl.enable_persister(pname, :filesystem)
845
+
846
+ stuff = Stuff.new
847
+ thing = Thing.new
848
+ thing.pid = "thing"
849
+ thing << stuff
850
+
851
+ Xampl.introduce_to_persister(thing)
852
+
853
+ Xampl.rollback
854
+
855
+ current_persister = Xampl.persister
856
+
857
+ assert_equal(original_persister, current_persister)
858
+ #assert_not_equal(original_persister, current_persister)
859
+
860
+ # no sync after thing's creation, so thing should NOT exist after rollback
861
+ found = Xampl.lookup(Thing, "thing")
862
+ assert_nil(found)
863
+
864
+ assert_equal(original_persister, thing.persister)
865
+
866
+ #assert_xampl_exception(:live_across_rollback){
867
+ # thing.new_stuff
868
+ #}
869
+ thing.stuff.size
870
+
871
+ writes = Xampl.sync
872
+
873
+ assert_equal(0, writes)
874
+ end
875
+
876
+ def test_filesystem_persistence_rollback_survival
877
+ pname = "test_filesystem_persistence_rollback_survival_ut" << Time.now.strftime("%Y%m%d-%H%M-%S") << rand.to_s
878
+ original_persister = Xampl.enable_persister(pname, :filesystem)
879
+
880
+ stuff = Stuff.new
881
+ thing = Thing.new
882
+ thing.pid = "thing"
883
+ thing << stuff
884
+
885
+ Xampl.introduce_to_persister(thing)
886
+
887
+ assert_equal(1, thing.stuff.size)
888
+ Xampl.sync
889
+ assert_equal(1, thing.stuff.size)
890
+
891
+ thing.new_stuff
892
+ thing.info = "something"
893
+
894
+ assert_equal(2, thing.stuff.size)
895
+
896
+ Xampl.rollback
897
+
898
+ assert(thing.load_needed)
899
+ assert_nil(thing.info, "attributes not cleared by the rollback")
900
+ assert(!thing.load_needed)
901
+ assert_equal(1, thing.stuff.size)
902
+
903
+ current_persister = Xampl.persister
904
+
905
+ assert_equal(original_persister, current_persister)
906
+
907
+ # a sync done BEFORE the second 'stuff' was added to thing
908
+ found = Xampl.lookup(Thing, "thing")
909
+ assert_equal(found.object_id, thing.object_id)
910
+
911
+ assert_equal(original_persister, current_persister)
912
+ assert_equal(current_persister, thing.persister)
913
+ assert_equal(current_persister, found.persister)
914
+
915
+ assert(!thing.load_needed)
916
+ assert(!thing.is_changed)
917
+
918
+ thing.stuff.size
919
+
920
+ assert(!thing.load_needed)
921
+ assert(!thing.is_changed)
922
+
923
+ assert_equal(found.object_id, thing.object_id)
924
+ assert_equal(1, thing.stuff.size)
925
+ assert_equal(1, found.stuff.size)
926
+
927
+ #assert_xampl_exception(:live_across_rollback){
928
+ # thing.new_stuff
929
+ #}
930
+
931
+ assert(!thing.is_changed)
932
+ writes = Xampl.sync
933
+
934
+ assert_equal(0, writes)
935
+
936
+ new_thing = found.new_thing("new_thing")
937
+ new_thing.new_stuff
938
+
939
+ writes = Xampl.sync
940
+
941
+ assert_equal(2, writes)
942
+
943
+ new_thing.new_stuff
944
+ writes = Xampl.sync
945
+ assert_equal(1, writes)
946
+
947
+ Xampl.rollback
948
+
949
+ assert_equal(0, Xampl.persister.read_count)
950
+
951
+ thing = Thing.lookup("thing")
952
+ assert_not_nil(thing)
953
+ assert_equal(0, Xampl.persister.read_count, "not in the cache")
954
+
955
+ new_thing = thing.thing["new_thing"]
956
+ assert_not_nil(new_thing)
957
+ assert_equal(0, Xampl.persister.read_count, "not in the cache")
958
+
959
+ keep_new_thing = new_thing
960
+
961
+ # these (to xml, ruby) will NOT suck the child thing into memory
962
+ xml = thing.test_to_xml
963
+
964
+ ruby = thing.to_ruby
965
+ ruby_thing = XamplObject.from_ruby(ruby)
966
+
967
+ assert_equal(0, Xampl.persister.read_count, "not in the cache")
968
+
969
+ # this will trigger the lazy load of new_thing
970
+ size = new_thing.stuff.size
971
+
972
+ assert_equal(0, Xampl.persister.read_count, "not in the cache")
973
+ assert_equal(keep_new_thing, new_thing)
974
+ assert_equal(new_thing, thing.thing["new_thing"])
975
+
976
+ Xampl.rollback
977
+
978
+ # another way to get stuff into memory
979
+ # ACTUALLY, this is not legal, there is a cache conflict problem
980
+ illegal_lazy_thing = Thing.new
981
+ illegal_lazy_thing.pid = "thing"
982
+ illegal_lazy_thing.load_needed = true
983
+ #assert_xampl_exception(:cache_conflict){
984
+ # assert(thing === illegal_lazy_thing)
985
+ #}
986
+ #assert_raise(XamplIsInvalid){
987
+ # # due to a change in xampl this is OK (it isn't invalid yet)
988
+ #illegal_lazy_thing.info = "oops"
989
+ #}
990
+
991
+ okay_thing = Thing.lookup("thing")
992
+ assert(okay_thing)
993
+ okay_thing.info = "okay"
994
+ end
995
+
996
+
997
+ def test_escaping
998
+ description = Description.new
999
+ description.kind = "<>&'\""
1000
+ description << "<>&'\""
1001
+
1002
+ expect = "<ex:description kind='&lt;&gt;&amp;&apos;&quot;' xmlns:ex='http://xampl.com/example'>&lt;>&amp;'\"</ex:description>"
1003
+
1004
+ assert_equal(expect, description.test_to_xml)
1005
+ end
1006
+
1007
+ def choose_name_test_helper(name, expected_class_name, expected_attribute_name)
1008
+ original_name = name.dup
1009
+ class_name, attribute_name = Generator.choose_names(name, "", "")
1010
+ assert_equal(original_name, name, "changed the original name")
1011
+ assert_equal(expected_class_name, class_name, "CLASS name wrong")
1012
+ assert_equal(expected_attribute_name, attribute_name, "ATTRIBUTE name wrong")
1013
+ end
1014
+
1015
+ def test_generator_with_no_namespace
1016
+ generator = Generator.new
1017
+ generator.comprehend_from_strings([
1018
+ %Q{
1019
+ <things xmlns:xampl='http://xampl.com/example/special'>
1020
+ <thing pid=''>
1021
+ <description kind=''>blah <emph>blah</emph> blah</description>
1022
+ <keyValue id='' value=''/>
1023
+ <stuff kind='' xampl:special=''/>
1024
+ <thing pid=''/>
1025
+ <things/>
1026
+ </thing>
1027
+ </things>
1028
+ }
1029
+ ])
1030
+
1031
+ ns = ""
1032
+ #ns = nil
1033
+ emap = generator.elements_map
1034
+ assert_equal(1, emap.size)
1035
+ elements = emap[ns]
1036
+ assert_not_nil(elements)
1037
+ assert_equal(6, elements.element_child.size)
1038
+
1039
+ ename = "emph"
1040
+ element = elements.element_child[ename]
1041
+ assert_not_nil(element)
1042
+ assert_equal(ns, element.namespace)
1043
+ assert_equal("{#{ns}}#{ename}", element.nstag)
1044
+ assert(!element.empty)
1045
+ assert(element.has_content)
1046
+
1047
+ ename = "description"
1048
+ element = elements.element_child[ename]
1049
+ assert_not_nil(element)
1050
+ assert_equal(ns, element.namespace)
1051
+ assert_equal("{#{ns}}#{ename}", element.nstag)
1052
+ assert(!element.empty)
1053
+ assert(element.has_content)
1054
+
1055
+ assert_equal(1, element.attribute_child.size)
1056
+ assert_not_nil(element.attribute_child["kind"])
1057
+ assert_nil(element.attribute_child["kind"].namespace)
1058
+
1059
+ assert_equal(1, element.child_element_child.size)
1060
+ cname = "{#{ns}}emph"
1061
+ assert_not_nil(element.child_element_child[cname])
1062
+ assert_equal(ns, element.child_element_child[cname].namespace)
1063
+ assert_equal("emph", element.child_element_child[cname].element_name)
1064
+
1065
+ ename = "stuff"
1066
+ element = elements.element_child[ename]
1067
+ assert_not_nil(element)
1068
+ assert_equal(ns, element.namespace)
1069
+ assert_equal("{#{ns}}#{ename}", element.nstag)
1070
+ assert(element.empty)
1071
+ assert(!element.has_content)
1072
+
1073
+ assert_equal(2, element.attribute_child.size)
1074
+ assert_not_nil(element.attribute_child["kind"])
1075
+ assert_nil(element.attribute_child["kind"].namespace)
1076
+ assert_not_nil(element.attribute_child["special"])
1077
+ assert_equal('http://xampl.com/example/special', element.attribute_child["special"].namespace)
1078
+
1079
+ assert_equal(0, element.child_element_child.size)
1080
+
1081
+ ename = "keyValue"
1082
+ element = elements.element_child[ename]
1083
+ assert_not_nil(element)
1084
+ assert_equal(ns, element.namespace)
1085
+ assert_equal("{#{ns}}#{ename}", element.nstag)
1086
+ assert(element.empty)
1087
+ assert(!element.has_content)
1088
+
1089
+ assert_equal(2, element.attribute_child.size)
1090
+ assert_not_nil(element.attribute_child["id"])
1091
+ assert_nil(element.attribute_child["id"].namespace)
1092
+ assert_not_nil(element.attribute_child["value"])
1093
+ assert_nil(element.attribute_child["value"].namespace)
1094
+
1095
+ assert_equal(0, element.child_element_child.size)
1096
+
1097
+ ename = "thing"
1098
+ element = elements.element_child[ename]
1099
+ assert_not_nil(element)
1100
+ assert_equal(ns, element.namespace)
1101
+ assert_equal("{#{ns}}#{ename}", element.nstag)
1102
+ assert(element.empty)
1103
+ assert(!element.has_content)
1104
+
1105
+ assert_equal(1, element.attribute_child.size)
1106
+ assert_equal(1, element.attribute_child.size)
1107
+ assert_not_nil(element.attribute_child["pid"])
1108
+ assert_nil(element.attribute_child["pid"].namespace)
1109
+
1110
+ assert_equal(5, element.child_element_child.size)
1111
+
1112
+ cname = "{#{ns}}description"
1113
+ assert_not_nil(element.child_element_child[cname])
1114
+ assert_equal(ns, element.child_element_child[cname].namespace)
1115
+ assert_equal("description", element.child_element_child[cname].element_name)
1116
+
1117
+ cname = "{#{ns}}keyValue"
1118
+ assert_not_nil(element.child_element_child[cname])
1119
+ assert_equal(ns, element.child_element_child[cname].namespace)
1120
+ assert_equal("keyValue", element.child_element_child[cname].element_name)
1121
+
1122
+ cname = "{#{ns}}stuff"
1123
+ assert_not_nil(element.child_element_child[cname])
1124
+ assert_equal(ns, element.child_element_child[cname].namespace)
1125
+ assert_equal("stuff", element.child_element_child[cname].element_name)
1126
+
1127
+ cname = "{#{ns}}thing"
1128
+ assert_not_nil(element.child_element_child[cname])
1129
+ assert_equal(ns, element.child_element_child[cname].namespace)
1130
+ assert_equal("thing", element.child_element_child[cname].element_name)
1131
+
1132
+ cname = "{#{ns}}things"
1133
+ assert_not_nil(element.child_element_child[cname])
1134
+ assert_equal(ns, element.child_element_child[cname].namespace)
1135
+ assert_equal("things", element.child_element_child[cname].element_name)
1136
+
1137
+ ename = "things"
1138
+ element = elements.element_child[ename]
1139
+ assert_not_nil(element)
1140
+ assert_equal(ns, element.namespace)
1141
+ assert_equal("{#{ns}}#{ename}", element.nstag)
1142
+ assert(element.empty)
1143
+ assert(!element.has_content)
1144
+
1145
+ assert_equal(0, element.attribute_child.size)
1146
+ assert_equal(1, element.child_element_child.size)
1147
+
1148
+ cname = "{#{ns}}thing"
1149
+ assert_not_nil(element.child_element_child[cname])
1150
+ assert_equal(ns, element.child_element_child[cname].namespace)
1151
+ assert_equal("thing", element.child_element_child[cname].element_name)
1152
+
1153
+ #generator.print_stats
1154
+ generator.analyse
1155
+
1156
+ ename = "emph"
1157
+ element = elements.element_child[ename]
1158
+ assert_equal("simple", element.kind, "emph is wrong kind")
1159
+ assert_nil(element.indexed_by_attr)
1160
+ assert_nil(element.persisted)
1161
+ assert_equal("XamplAdHoc", element.package)
1162
+ assert_equal("Emph", element.class_name)
1163
+ assert_equal("emph", element.attribute_name)
1164
+
1165
+ ename = "description"
1166
+ element = elements.element_child[ename]
1167
+ assert_equal("mixed", element.kind, "description is wrong kind")
1168
+ assert_nil(element.indexed_by_attr)
1169
+ assert_nil(element.persisted)
1170
+ assert_equal("XamplAdHoc", element.package)
1171
+ assert_equal("Description", element.class_name)
1172
+ assert_equal("description", element.attribute_name)
1173
+
1174
+ ename = "stuff"
1175
+ element = elements.element_child[ename]
1176
+ assert_equal("empty", element.kind, "stuff is wrong kind")
1177
+ assert_nil(element.indexed_by_attr)
1178
+ assert_nil(element.persisted)
1179
+ assert_equal("XamplAdHoc", element.package)
1180
+ assert_equal("Stuff", element.class_name)
1181
+ assert_equal("stuff", element.attribute_name)
1182
+
1183
+ ename = "keyValue"
1184
+ element = elements.element_child[ename]
1185
+ assert_equal("empty", element.kind, "keyValue is wrong kind")
1186
+ assert_equal("id", element.indexed_by_attr)
1187
+ assert_nil(element.persisted)
1188
+ assert_equal("XamplAdHoc", element.package)
1189
+ assert_equal("KeyValue", element.class_name)
1190
+ assert_equal("key_value", element.attribute_name)
1191
+
1192
+ ename = "thing"
1193
+ element = elements.element_child[ename]
1194
+ assert_equal("data", element.kind, "thing is wrong kind")
1195
+ assert_equal("pid", element.indexed_by_attr)
1196
+ assert_not_nil(element.persisted)
1197
+ assert_equal("XamplAdHoc", element.package)
1198
+ assert_equal("Thing", element.class_name)
1199
+ assert_equal("thing", element.attribute_name)
1200
+
1201
+ #generator.generate_to_directory(nil)
1202
+ end
1203
+
1204
+
1205
+ def test_choose_names
1206
+ choose_name_test_helper("abcd", "Abcd", "abcd")
1207
+ choose_name_test_helper("Abcd", "Abcd", "abcd")
1208
+ choose_name_test_helper("abCd", "AbCd", "ab_cd")
1209
+ choose_name_test_helper("AbCd", "AbCd", "ab_cd")
1210
+ choose_name_test_helper("ABcd", "ABcd", "abcd")
1211
+
1212
+ choose_name_test_helper("ABcdefABCdef", "ABcdefABCdef", "abcdef_abcdef")
1213
+
1214
+ choose_name_test_helper("ab-cd", "AbCd", "ab_cd")
1215
+ choose_name_test_helper("Ab-Cd", "AbCd", "ab_cd")
1216
+
1217
+ choose_name_test_helper("ab--cd", "AbCd", "ab_cd")
1218
+ choose_name_test_helper("Ab--Cd", "AbCd", "ab_cd")
1219
+
1220
+ choose_name_test_helper("ab_-cd", "AbCd", "ab_cd")
1221
+ choose_name_test_helper("Ab_-Cd", "AbCd", "ab_cd")
1222
+
1223
+ choose_name_test_helper("ab__cd", "AbCd", "ab_cd")
1224
+ choose_name_test_helper("Ab__Cd", "AbCd", "ab_cd")
1225
+
1226
+ choose_name_test_helper("ab:cd", "AbCd", "ab_cd")
1227
+ choose_name_test_helper("Ab:Cd", "AbCd", "ab_cd")
1228
+
1229
+ choose_name_test_helper("ab.cd", "AbCd", "ab_cd")
1230
+
1231
+ choose_name_test_helper("ab9cd", "AbCd", "ab_cd")
1232
+ choose_name_test_helper("ab9Cd", "AbCd", "ab_cd")
1233
+ end
1234
+
1235
+ # TODO -- test no namespace
1236
+
1237
+ def test_bug_indexed_child_same_pid_added_twice
1238
+ element = Element.new
1239
+ attr0 = element.new_attribute("repeated")
1240
+
1241
+ assert_equal(1, element.attribute_child.size)
1242
+ assert_equal(1, element.attribute_child.size)
1243
+ assert_equal(1, element.children.size)
1244
+ assert_equal(attr0, element.children[0])
1245
+
1246
+ ce1 = element.new_child_element("something")
1247
+
1248
+ assert_equal(1, element.attribute_child.size)
1249
+ assert_equal(1, element.attribute_child.size)
1250
+ assert_equal(2, element.children.size)
1251
+ assert_equal(attr0, element.children[0])
1252
+ assert_equal(ce1, element.children[1])
1253
+
1254
+ attr2 = element.new_attribute("repeated")
1255
+
1256
+ assert_equal(1, element.attribute_child.size)
1257
+ assert_equal(1, element.attribute_child.size)
1258
+ assert_equal(2, element.children.size)
1259
+ assert_equal(ce1, element.children[0])
1260
+ assert_equal(attr2, element.children[1])
1261
+ end
1262
+
1263
+ def test_cycles_and_bushy_lookup
1264
+ pname = "test_cycles_and_bushy" << Time.now.strftime("%Y%m%d-%H%M-%S") << rand.to_s
1265
+ #Xampl.enable_persister(pname, :filesystem)
1266
+ Xampl.enable_persister(pname, :in_memory)
1267
+ Xampl.auto_persistence
1268
+
1269
+ root = Thing.new("root")
1270
+ root.info = "one"
1271
+
1272
+ root.new_thing("branch1").new_thing("leaf").info = "two"
1273
+ root.new_thing("branch2").new_thing("leaf").info = "three"
1274
+ root.new_thing("branch3").new_thing("leaf").info = "four"
1275
+
1276
+ root.new_thing("cycle0").info = "five"
1277
+ Thing.lookup("cycle0").new_thing("cycle1").new_thing("cycle2").info = "six"
1278
+ Thing.lookup("cycle2").new_thing("cycle0")
1279
+
1280
+ assert(Thing.lookup("cycle2").thing["cycle0"] == Thing.lookup("cycle0"))
1281
+ assert(Thing.lookup("root").thing["cycle0"] == Thing.lookup("cycle0"))
1282
+
1283
+ Xampl.sync
1284
+
1285
+ assert_equal(8, CountingVisitor.new.start(root).count)
1286
+
1287
+ pp_xml = root.pp_xml
1288
+ #puts root.pp_xml
1289
+ end
1290
+
1291
+ def test_cycles_and_bushy2_locals
1292
+ pname = "test_cycles_and_bushy" << Time.now.strftime("%Y%m%d-%H%M-%S") << rand.to_s
1293
+ #Xampl.enable_persister(pname, :filesystem)
1294
+ Xampl.enable_persister(pname, :in_memory)
1295
+ Xampl.auto_persistence
1296
+
1297
+ root = Thing.new("root")
1298
+
1299
+ root.new_thing("branch1").new_thing("leaf")
1300
+ root.new_thing("branch2").new_thing("leaf")
1301
+ root.new_thing("branch3").new_thing("leaf")
1302
+
1303
+ cycle0 = root.new_thing("cycle0")
1304
+ cycle0.new_thing("cycle1").new_thing("cycle2").new_thing("cycle0")
1305
+
1306
+ assert_equal(Thing.lookup("cycle2").thing["cycle0"],
1307
+ Thing.lookup("root").thing["cycle0"])
1308
+
1309
+ Xampl.sync
1310
+
1311
+ assert_equal(8, CountingVisitor.new.start(root).count)
1312
+
1313
+ #puts root.pp_xml
1314
+ end
1315
+
1316
+ def test_internal_cycles_and_bushy
1317
+ pname = "test_internal_cycles_and_bushy" << Time.now.strftime("%Y%m%d-%H%M-%S") << rand.to_s
1318
+ #Xampl.enable_persister(pname, :filesystem)
1319
+ Xampl.enable_persister(pname, :in_memory)
1320
+ Xampl.auto_persistence
1321
+
1322
+ root = Thing.new("root")
1323
+ root.info = "root"
1324
+
1325
+ (branch1 = Branch.new).info='one'
1326
+ (branch2 = Branch.new).info='two'
1327
+ (branch3 = Branch.new).info='three'
1328
+ (branch4 = Branch.new).info='four'
1329
+ (branch5 = Branch.new).info='five'
1330
+
1331
+ #puts branch1.pp_xml
1332
+
1333
+ #
1334
+ # 1
1335
+ # 2 3
1336
+ # 4
1337
+ # 1
1338
+ # and 5 is a child of 1, 2, 3, and 4
1339
+
1340
+ root << branch1
1341
+
1342
+ branch1 << branch2
1343
+ branch1 << branch3
1344
+
1345
+ branch2 << branch4
1346
+ branch3 << branch4
1347
+
1348
+ branch4 << branch1
1349
+
1350
+ branch1 << branch5
1351
+ branch2 << branch5
1352
+ branch3 << branch5
1353
+ branch4 << branch5
1354
+
1355
+ #assert_xampl_exception(:cycle_detected_in_xampl_cluster){
1356
+ assert_xampl_exception(:cycle_detected_in_xampl_cluster){
1357
+ xml = PersistXML.new("").start(root).done
1358
+ }
1359
+
1360
+ assert_xampl_exception(:cycle_detected_in_xampl_cluster){
1361
+ Xampl.sync
1362
+ }
1363
+
1364
+ #there is one thing and 5 branches, so 6 different things
1365
+ assert_equal(6, CountingVisitor.new.start(root).count)
1366
+
1367
+ pp_xml = root.pp_xml
1368
+ end
1369
+
1370
+ # def test_fsdb_extension_persistence_basics
1371
+ # require 'persister/fsdb'
1372
+ # stuff = Stuff.new
1373
+ # thing = Thing.new
1374
+ # thing << stuff
1375
+ #
1376
+ # thing.pid = "thing"
1377
+ #
1378
+ # assert_xampl_exception(:name_required){
1379
+ # Xampl.enable_persister(nil, :fsdb)
1380
+ # }
1381
+ #
1382
+ # pname = "test_fsdb_extension_persistence_basics" << Time.now.strftime("%Y%m%d-%H%M-%S") << rand.to_s
1383
+ # Xampl.enable_persister(pname, :fsdb)
1384
+ #
1385
+ # stuff = Stuff.new
1386
+ # thing = Thing.new
1387
+ # thing.pid = "thing"
1388
+ # thing << stuff
1389
+ #
1390
+ # assert_nil(Xampl.lookup(Thing, "thing"))
1391
+ #
1392
+ # assert(nil == thing.persister)
1393
+ # assert(thing.is_changed)
1394
+ # assert_equal(0, Xampl.count_changed)
1395
+ #
1396
+ # Xampl.introduce_to_persister(thing)
1397
+ #
1398
+ # assert(thing.persister)
1399
+ # assert_equal(1, Xampl.count_changed)
1400
+ # assert_same(thing, Xampl.lookup(Thing, "thing"), "cannot lookup new stuff")
1401
+ #
1402
+ # #Xampl.print_stats
1403
+ #
1404
+ # assert_equal(1, Xampl.count_changed)
1405
+ # writes = Xampl.sync
1406
+ # assert_equal(1, writes)
1407
+ # assert_equal(0, Xampl.count_changed)
1408
+ # assert(Xampl.lookup(Thing, "thing"))
1409
+ #
1410
+ # thing2 = Xampl.lookup(Thing, "thing")
1411
+ # assert_same(thing, thing2, "cannot lookup cached stuff")
1412
+ #
1413
+ # Xampl.clear_cache
1414
+ #
1415
+ # found = Xampl.lookup(Thing, "thing")
1416
+ # assert_not_same(thing, found)
1417
+ # assert(thing === found)
1418
+ #
1419
+ # Xampl.clear_cache
1420
+ #
1421
+ # # now, changing thing will affect the DB -- VERY SUBTLE POSSIBLIITY OF BUG!
1422
+ # thing.new_stuff
1423
+ # assert_equal(2, thing.stuff.size)
1424
+ # assert_equal(1, found.stuff.size)
1425
+ #
1426
+ # writes = Xampl.sync
1427
+ #
1428
+ # assert_equal(2, thing.stuff.size)
1429
+ # assert_equal(1, found.stuff.size)
1430
+ #
1431
+ # found2 = Xampl.lookup(Thing, "thing")
1432
+ #
1433
+ # assert_equal(2, thing.stuff.size)
1434
+ # assert_equal(1, found.stuff.size)
1435
+ # assert_equal(2, found2.stuff.size)
1436
+ #
1437
+ # assert(!(found === found2))
1438
+ # assert(thing === found2)
1439
+ #
1440
+ # assert_not_equal(found, found2)
1441
+ #
1442
+ # #Xampl.print_stats
1443
+ # end
1444
+
1445
+ def test_simple_extension_persistence_basics
1446
+ stuff = Stuff.new
1447
+ thing = Thing.new
1448
+ thing << stuff
1449
+
1450
+ thing.pid = "thing"
1451
+
1452
+ Xampl.enable_persister(nil, :simple)
1453
+
1454
+ stuff = Stuff.new
1455
+ thing = Thing.new
1456
+ thing.pid = "thing"
1457
+ thing << stuff
1458
+
1459
+ assert_nil(Xampl.lookup(Thing, "thing"))
1460
+
1461
+ assert(nil == thing.persister)
1462
+ assert(thing.is_changed)
1463
+ assert_equal(0, Xampl.count_changed)
1464
+
1465
+ Xampl.introduce_to_persister(thing)
1466
+
1467
+ assert(thing.persister)
1468
+ assert_equal(0, Xampl.count_changed)
1469
+ assert_same(thing, Xampl.lookup(Thing, "thing"), "cannot lookup new stuff")
1470
+
1471
+ #Xampl.print_stats
1472
+
1473
+ assert_equal(0, Xampl.count_changed)
1474
+ writes = Xampl.sync
1475
+ assert_equal(0, Xampl.count_changed)
1476
+ assert(Xampl.lookup(Thing, "thing"))
1477
+
1478
+ thing2 = Xampl.lookup(Thing, "thing")
1479
+ assert_same(thing, thing2, "cannot lookup cached stuff")
1480
+
1481
+ found = Xampl.lookup(Thing, "thing")
1482
+ assert_equal(thing.object_id, found.object_id)
1483
+
1484
+ #Xampl.print_stats
1485
+ end
1486
+
1487
+ def check_parents(xampl, parent=nil)
1488
+ if (nil != parent) then
1489
+ found = false
1490
+ xampl.parents.each{ | p |
1491
+ found = true if (parent == p)
1492
+ }
1493
+ assert(found)
1494
+ else
1495
+ if (xampl.kind_of? XamplObject)
1496
+ assert((nil == xampl.parents) || (0 == xampl.parents.size))
1497
+ end
1498
+ end
1499
+ xampl.children.each{ | child |
1500
+ check_parents(child, xampl) if (child.kind_of? XamplObject)
1501
+ }
1502
+ end
1503
+ end
1504
+