glyph 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (114) hide show
  1. data/AUTHORS.textile +1 -1
  2. data/CHANGELOG.textile +119 -222
  3. data/LICENSE.textile +1 -1
  4. data/README.textile +42 -23
  5. data/Rakefile +1 -3
  6. data/VERSION +1 -1
  7. data/benchmark.rb +72 -0
  8. data/book/config.yml +4 -4
  9. data/book/document.glyph +90 -57
  10. data/book/images/document_generation.png +0 -0
  11. data/book/lib/macros/reference.rb +75 -22
  12. data/book/output/html/glyph.html +3183 -2121
  13. data/book/output/html/images/document_generation.png +0 -0
  14. data/book/output/pdf/glyph.pdf +7370 -4913
  15. data/book/resources/document_generation.txt +34 -0
  16. data/book/snippets.yml +6 -0
  17. data/book/text/changelog.glyph +45 -34
  18. data/book/text/compiling/compiling.glyph +23 -0
  19. data/book/text/compiling/lite_mode.glyph +23 -0
  20. data/book/text/compiling/programmatic_usage.glyph +77 -0
  21. data/book/text/extending/bookmarks_headers.glyph +21 -0
  22. data/book/text/extending/further_reading.glyph +13 -0
  23. data/book/text/extending/internals.glyph +79 -0
  24. data/book/text/extending/interpreting.glyph +51 -0
  25. data/book/text/extending/macro_def.glyph +64 -0
  26. data/book/text/extending/params_attrs.glyph +70 -0
  27. data/book/text/extending/placeholders.glyph +34 -0
  28. data/book/text/extending/validators.glyph +16 -0
  29. data/book/text/getting_started/configuration.glyph +49 -0
  30. data/book/text/getting_started/create_project.glyph +41 -0
  31. data/book/text/getting_started/structure.glyph +55 -0
  32. data/book/text/introduction.glyph +49 -26
  33. data/book/text/license.glyph +1 -1
  34. data/book/text/macros/macros_block.glyph +99 -0
  35. data/book/text/macros/macros_core.glyph +208 -0
  36. data/book/text/macros/macros_filters.glyph +40 -0
  37. data/book/text/macros/macros_inline.glyph +50 -0
  38. data/book/text/macros/macros_structure.glyph +100 -0
  39. data/book/text/ref_commands.glyph +94 -73
  40. data/book/text/ref_config.glyph +34 -42
  41. data/book/text/ref_macros.glyph +1 -373
  42. data/book/text/text_editing/code.glyph +51 -0
  43. data/book/text/text_editing/conditionals.glyph +49 -0
  44. data/book/text/text_editing/evaluation.glyph +13 -0
  45. data/book/text/text_editing/glyph_files.glyph +7 -0
  46. data/book/text/text_editing/images.glyph +29 -0
  47. data/book/text/text_editing/inclusions.glyph +44 -0
  48. data/book/text/text_editing/links.glyph +53 -0
  49. data/book/text/text_editing/macro_intro.glyph +111 -0
  50. data/book/text/text_editing/raw_html.glyph +112 -0
  51. data/book/text/text_editing/sections.glyph +63 -0
  52. data/book/text/text_editing/stylesheets.glyph +36 -0
  53. data/book/text/troubleshooting/errors_command.glyph +39 -0
  54. data/book/text/troubleshooting/errors_generic.glyph +29 -0
  55. data/book/text/troubleshooting/errors_intro.glyph +3 -0
  56. data/book/text/troubleshooting/errors_macro.glyph +98 -0
  57. data/book/text/troubleshooting/errors_parser.glyph +29 -0
  58. data/config.yml +77 -58
  59. data/document.glyph +25 -25
  60. data/glyph.gemspec +57 -22
  61. data/lib/glyph.rb +54 -13
  62. data/lib/glyph/commands.rb +84 -17
  63. data/lib/glyph/config.rb +3 -3
  64. data/lib/glyph/document.rb +14 -8
  65. data/lib/glyph/interpreter.rb +18 -58
  66. data/lib/glyph/macro.rb +160 -55
  67. data/lib/glyph/macro_validators.rb +104 -12
  68. data/lib/glyph/node.rb +24 -0
  69. data/lib/glyph/parser.rb +278 -0
  70. data/lib/glyph/syntax_node.rb +225 -0
  71. data/macros/core.rb +212 -0
  72. data/macros/filters.rb +66 -15
  73. data/macros/html/block.rb +43 -105
  74. data/macros/html/inline.rb +11 -12
  75. data/macros/html/structure.rb +123 -58
  76. data/macros/xml.rb +33 -0
  77. data/spec/files/container.textile +2 -2
  78. data/spec/files/document.glyph +2 -2
  79. data/spec/files/document_with_toc.glyph +3 -3
  80. data/spec/files/included.textile +1 -1
  81. data/spec/files/ligature.jpg +0 -0
  82. data/spec/files/markdown.markdown +2 -1
  83. data/spec/lib/commands_spec.rb +46 -3
  84. data/spec/lib/document_spec.rb +4 -4
  85. data/spec/lib/glyph_spec.rb +17 -46
  86. data/spec/lib/interpreter_spec.rb +6 -25
  87. data/spec/lib/macro_spec.rb +141 -43
  88. data/spec/lib/macro_validators_spec.rb +27 -5
  89. data/spec/lib/node_spec.rb +26 -1
  90. data/spec/lib/parser_spec.rb +246 -0
  91. data/spec/lib/syntax_node_spec.rb +111 -0
  92. data/spec/macros/core_spec.rb +195 -0
  93. data/spec/macros/filters_spec.rb +38 -4
  94. data/spec/macros/macros_spec.rb +20 -176
  95. data/spec/macros/textile_spec.rb +13 -71
  96. data/spec/macros/xml_spec.rb +77 -0
  97. data/spec/spec_helper.rb +50 -10
  98. data/spec/tasks/load_spec.rb +13 -2
  99. data/styles/default.css +18 -6
  100. data/styles/pagination.css +1 -19
  101. data/tasks/generate.rake +2 -2
  102. data/tasks/load.rake +27 -17
  103. data/tasks/project.rake +1 -1
  104. metadata +75 -62
  105. data/book/script/compile.rb +0 -8
  106. data/book/script/prof +0 -1
  107. data/book/script/prof_results.htm +0 -21079
  108. data/book/text/authoring.glyph +0 -548
  109. data/book/text/extending.glyph +0 -224
  110. data/book/text/getting_started.glyph +0 -158
  111. data/book/text/troubleshooting.glyph +0 -179
  112. data/lib/glyph/glyph_language.rb +0 -538
  113. data/lib/glyph/glyph_language.treetop +0 -27
  114. data/macros/common.rb +0 -160
@@ -4,13 +4,19 @@ require File.join(File.dirname(__FILE__), "..", "spec_helper")
4
4
  describe Glyph::Macro::Validators do
5
5
 
6
6
  before do
7
+ create_project
7
8
  Glyph.run! 'load:all'
8
9
  Glyph.macro :validated_test do
9
- validate("Invalid Macro"){ @value == "valid" }
10
- "Validated Test: #{@value}"
10
+ validate("Invalid Macro"){ value == "valid" }
11
+ "Validated Test: #{value}"
11
12
  end
12
13
  end
13
14
 
15
+ after do
16
+ reset_quiet
17
+ delete_project
18
+ end
19
+
14
20
  it "should provide custom validation" do
15
21
  lambda { interpret("section[validated_test[invalid]]").document.output }.should raise_error Glyph::MacroError
16
22
  lambda { interpret("chapter[validated_test[valid]]").document.output }.should_not raise_error
@@ -18,16 +24,32 @@ describe Glyph::Macro::Validators do
18
24
 
19
25
  it "should validate the number of parameters" do
20
26
  # exact
21
- lambda { interpret("table[]").document.output }.should raise_error Glyph::MacroError
27
+ lambda { interpret("section[sfsdg|saf]").document.output }.should raise_error Glyph::MacroError
22
28
  # none
23
- lambda { interpret("toc[test]").document.output }.should raise_error Glyph::MacroError
29
+ lambda { interpret("title[test]").document.output }.should raise_error Glyph::MacroError
24
30
  # min
25
- lambda { interpret("img[]").document.output }.should raise_error Glyph::MacroError
31
+ lambda { interpret("?[]").document.output }.should raise_error Glyph::MacroError
26
32
  # max
27
33
  lambda { interpret("not[a|b|c]").document.output }.should raise_error Glyph::MacroError
28
34
  # correct
29
35
  lambda { interpret("chapter[fmi[something|#something]]").document.output }.should_not raise_error Glyph::MacroError
30
36
  end
31
37
 
38
+ it "should check for mutual inclusion" do
39
+ Glyph::SNIPPETS[:inc] = "Test &[inc]"
40
+ lambda {interpret("&[inc] test").document}.should raise_error(Glyph::MutualInclusionError)
41
+ end
42
+
43
+ it "should validate XML elements" do
44
+ language 'xml'
45
+ lambda { interpret("<test[test]").document}.should raise_error
46
+ lambda { interpret("_test[test]").document}.should_not raise_error
47
+ end
48
+
49
+ it "should validate XML attributes" do
50
+ language 'xml'
51
+ output_for("test[test @.test[test]]").should == "<test>test</test>"
52
+ end
53
+
32
54
  end
33
55
 
@@ -74,11 +74,36 @@ describe Node do
74
74
  result = @ht.find_child do |node|
75
75
  node[:d] == 4
76
76
  end
77
- result.should == {:c => 3, :d => 4}
77
+ result.to_hash.should == {:c => 3, :d => 4}
78
78
  result2 = @ht.find_child do |node|
79
79
  node[:q] == 7
80
80
  end
81
81
  result2.should == nil
82
82
  end
83
83
 
84
+ it "should expose a dedicated inspect method" do
85
+ create_node
86
+ @ht << {:c => 3, :d => 4}
87
+ @ht << {:e => 5, :f => 6}
88
+ @ht.inspect.should == "#{@ht.to_hash.inspect}\n #{(@ht&0).to_hash.inspect}\n #{(@ht&1).to_hash.inspect}"
89
+ end
90
+
91
+ it "should be convertable into a hash" do
92
+ create_node
93
+ @ht.to_hash.should == {:a => 1, :b => 2}
94
+ lambda { @ht.to_hash.children }.should raise_error
95
+ end
96
+
97
+ it "should check equality of children as well" do
98
+ create_node
99
+ @ht << {:c => 3, :d => 4}
100
+ @ht << {:e => 5, :f => 6}
101
+ @ht2 = {:a => 1, :b => 2}.to_node
102
+ @ht2 << {:c => 3, :d => 4}
103
+ @ht2 << {:e => 5, :f => 6}
104
+ (@ht==@ht2).should == true
105
+ (@ht&1)[:c] = 47
106
+ (@ht==@ht2).should == false
107
+ end
108
+
84
109
  end
@@ -0,0 +1,246 @@
1
+ #!/usr/bin/env ruby
2
+ require File.join(File.dirname(__FILE__), "..", "spec_helper")
3
+
4
+ describe Glyph::Parser do
5
+
6
+ def parse_text(text)
7
+ Glyph::Parser.new(text).parse
8
+ end
9
+
10
+ it "should parse macros" do
11
+ text = %{
12
+ test #1
13
+ section[header[Testing...]
14
+ =>[#something]
15
+ Test.
16
+ section[
17
+ header[Another test]
18
+ Contents]
19
+ ]}
20
+ tree = document_node
21
+ tree << text_node("\ntest #1\n")
22
+ tree << macro_node(:section)
23
+ (tree&1) << p_node(0)
24
+ section_0 = tree&1&0
25
+ section_0 << macro_node(:header)
26
+ section_0.children.last << p_node(0)
27
+ header_0 = section_0&0&0
28
+ header_0 << text_node("Testing...")
29
+ section_0 << text_node("\n\t")
30
+ section_0 << macro_node(:"=>")
31
+ section_0.children.last << p_node(0)
32
+ link_0 = section_0.children.last&0
33
+ link_0 << text_node("#something")
34
+ section_0 << text_node("\n\tTest.\n\t")
35
+ section_0 << macro_node(:section)
36
+ section_0.children.last << p_node(0)
37
+ section_1 = section_0.children.last&0
38
+ section_1 << text_node("\n\t\t")
39
+ section_1 << macro_node(:header)
40
+ section_1.children.last << p_node(0)
41
+ header_1 = section_1.children.last&0
42
+ header_1 << text_node("Another test")
43
+ section_1 << text_node("\nContents")
44
+ section_0 << text_node("\n")
45
+ parse_text(text).should == tree
46
+ end
47
+
48
+ it "should recognize escape sequences" do
49
+ text = "section[This is a test test\\[\\]\\]\\[ ]"
50
+ tree = document_node
51
+ tree << macro_node(:section)
52
+ macro_0 = p_node( 0)
53
+ macro_0 << text_node("This is a test test")
54
+ macro_0 << escape_node("\\[")
55
+ macro_0 << escape_node("\\]")
56
+ macro_0 << escape_node("\\]")
57
+ macro_0 << escape_node("\\[")
58
+ macro_0 << text_node(" ")
59
+ (tree&0) << macro_0
60
+ parse_text(text).should == tree
61
+ end
62
+
63
+ it "should raise an error if a standard macro is not closed" do
64
+ text = "test\nsection[test\\]\ntest"
65
+ lambda { puts parse_text(text).inspect }.should raise_error(Glyph::SyntaxError, "-- [3, 4] Macro 'section' not closed")
66
+ end
67
+
68
+ it "should not parse macros within escaping macros" do
69
+ text = "test1[= abc test2[This macro is escaped]\n cde=]"
70
+ tree = document_node
71
+ tree << macro_node(:test1, :escape => true)
72
+ macro_0 = p_node(0)
73
+ macro_0 << text_node(" abc test2[This macro is escaped]\n cde", :escaped => true)
74
+ (tree&0) << macro_0
75
+ parse_text(text).should == tree
76
+ end
77
+
78
+ it "should raise an error if escaped contents are nested" do
79
+ text = "test1[= abc test2[=This macro is escaped=]\n cde=]"
80
+ lambda { puts parse_text(text).inspect }.should raise_error(Glyph::SyntaxError, "-- [1, 41] Cannot nest escaping macro 'test2' within escaping macro 'test1'")
81
+ end
82
+
83
+ it "should raise an error if an escaping macro is not closed" do
84
+ text = "test1[= abc test2[This macro is escaped]\n cde] test"
85
+ lambda { puts parse_text(text).inspect }.should raise_error(Glyph::SyntaxError, "-- [2, 10] Escaping macro 'test1' not closed")
86
+ end
87
+
88
+ it "should raise errors if unescaped brackets are found" do
89
+ lambda { puts parse_text(" ] test[...] dgdsg").inspect}.should raise_error(Glyph::SyntaxError, "-- [1, 2] Macro delimiter ']' not escaped")
90
+ lambda { puts parse_text("[ test[...] dgdsg").inspect}.should raise_error(Glyph::SyntaxError, "-- [1, 1] Macro delimiter '[' not escaped")
91
+ lambda { puts parse_text(" test[...] [dgdsg]").inspect}.should raise_error(Glyph::SyntaxError, "-- [1, 12] Macro delimiter '[' not escaped")
92
+ lambda { puts parse_text(" test[...] dgdsg [").inspect}.should raise_error(Glyph::SyntaxError, "-- [1, 18] Macro delimiter '[' not escaped")
93
+ lambda { puts parse_text(" test[[...]] dgdsg").inspect}.should raise_error(Glyph::SyntaxError, "-- [1, 7] Macro delimiter '[' not escaped")
94
+ end
95
+
96
+ it "should parse positional parameters (parameters)" do
97
+ text = "test[aaa =>[test2[...]|test3[...]].]"
98
+ tree = document_node
99
+ tree << macro_node(:test)
100
+ macro_0 = p_node 0
101
+ macro_0 << text_node('aaa ')
102
+ macro_0 << macro_node("=>")
103
+ (tree&0) << macro_0
104
+ macro_01_p0 = p_node 0
105
+ macro_01_p0 << macro_node(:test2)
106
+ (macro_0&1) << macro_01_p0
107
+ macro_010 = p_node 0
108
+ macro_010 << text_node("...")
109
+ (macro_01_p0&0) << macro_010
110
+ macro_01_p1 = p_node 1
111
+ macro_01_p1 << macro_node(:test3)
112
+ (macro_0&1) << macro_01_p1
113
+ macro_011 = p_node 0
114
+ macro_011 << text_node("...")
115
+ (macro_01_p1&0) << macro_011
116
+ macro_0 << text_node(".")
117
+ parse_text(text).should == tree
118
+ end
119
+
120
+ it "should not allow parameters outside macros" do
121
+ text = "... | test[...]"
122
+ lambda { puts parse_text(text).inspect }.should raise_error(Glyph::SyntaxError, "-- [1, 5] Parameter delimiter '|' not allowed here")
123
+ end
124
+
125
+ it "should recognize escaped pipes" do
126
+ text = "\\| test \\| test[=this \\| is|a \\|test=]"
127
+ tree = document_node
128
+ tree << escape_node("\\|")
129
+ tree << text_node(" test ")
130
+ tree << escape_node("\\|")
131
+ tree << text_node(" ")
132
+ tree << macro_node(:test, :escape => true)
133
+ tree.children.last << p_node(0)
134
+ test_0 = tree.children.last&0
135
+ test_0 << text_node("this ", :escaped => true)
136
+ test_0 << escape_node("\\|")
137
+ test_0 << text_node(" is", :escaped => true)
138
+ tree.children.last << p_node(1)
139
+ test_1 = tree.children.last&1
140
+ test_1 << text_node("a ", :escaped => true)
141
+ test_1 << escape_node("\\|")
142
+ test_1 << text_node("test", :escaped => true)
143
+ parse_text(text).should == tree
144
+ end
145
+
146
+ it "should parse named parameters (attributes)" do
147
+ text = "test[@first[test1] @second[=test2[...]=].]"
148
+ tree = document_node
149
+ tree << macro_node(:test)
150
+ first = a_node :first
151
+ first << text_node("test1")
152
+ macro_0 = p_node(0)
153
+ macro_0 << text_node(" ")
154
+ macro_0 << text_node(".")
155
+ second = a_node :second, :escape=> true
156
+ second << text_node("test2[...]", :escaped => true)
157
+ (tree&0) << macro_0
158
+ (tree&0) << first
159
+ (tree&0) << second
160
+ parse_text(text).should == tree
161
+ end
162
+
163
+ it "should not parse parameters inside attributes" do
164
+ text = "test[@attr[test|...]]"
165
+ lambda { puts parse_text(text).inspect}.should raise_error(Glyph::SyntaxError, "-- [1, 16] Parameter delimiter '|' not allowed here")
166
+ end
167
+
168
+ it "should parse attributes inside parameters" do
169
+ text = "test[parameter 1|@par[...] test]"
170
+ tree = document_node
171
+ tree << macro_node(:test)
172
+ tree.children.last << p_node(0)
173
+ test_0 = tree.children.last&0
174
+ test_0 << text_node("parameter 1")
175
+ tree.children.last << p_node(1)
176
+ tree.children.last << a_node(:par)
177
+ test_1 = tree.children.last&1
178
+ par = tree.children.last&2
179
+ par << text_node("...")
180
+ test_1 << text_node(" test")
181
+ parse_text(text).should == tree
182
+ end
183
+
184
+ it "should not allow attribute nesting" do
185
+ text = "... test[@par1[@par2[...]...]]"
186
+ lambda { puts parse_text(text).inspect}.should raise_error(Glyph::SyntaxError, "-- [1, 22] Attributes cannot be nested")
187
+ end
188
+
189
+ it "should parse macros nested in attributes" do
190
+ text = "test[@a[test1[@b[...]@c[...]]]]"
191
+ tree = document_node
192
+ tree << macro_node(:test)
193
+ a = a_node :a
194
+ a << macro_node(:test1)
195
+ (tree&0) << a
196
+ b = a_node :b
197
+ b << text_node('...')
198
+ (a&0) << b
199
+ c = a_node :c
200
+ c << text_node('...')
201
+ (a&0) << c
202
+ parse_text(text).should == tree
203
+ end
204
+
205
+ it "should parse parameters in nested macros" do
206
+ text = "test[...|test1[a|b]|...]"
207
+ tree = document_node
208
+ tree << macro_node(:test)
209
+ macro_0_p0 = p_node 0
210
+ macro_0_p0 << text_node("...")
211
+ (tree&0) << macro_0_p0
212
+ macro_0_p1 = p_node 1
213
+ macro_0_p1 << macro_node(:test1)
214
+ (tree&0) << macro_0_p1
215
+ macro_01_p0 = p_node 0
216
+ macro_01_p0 << text_node('a')
217
+ (macro_0_p1&0) << macro_01_p0
218
+ macro_01_p1 = p_node 1
219
+ macro_01_p1 << text_node('b')
220
+ (macro_0_p1&0) << macro_01_p1
221
+ macro_0_p2 = p_node 2
222
+ macro_0_p2 << text_node("...")
223
+ (tree&0) << macro_0_p2
224
+ parse_text(text).should == tree
225
+ end
226
+
227
+ it "should handle escaped sequences before macro names" do
228
+ text = "abc\\.test[...]"
229
+ tree = document_node
230
+ tree << text_node("abc")
231
+ tree << escape_node("\\.")
232
+ tree << macro_node(:test)
233
+ macro_0 = p_node(0)
234
+ macro_0 << text_node("...")
235
+ (tree&2) << macro_0
236
+ parse_text(text).should == tree
237
+ end
238
+
239
+ it "should ignore parameters for empty macros" do
240
+ text = "toc[]"
241
+ tree = document_node
242
+ tree << macro_node(:toc)
243
+ parse_text(text).should == tree
244
+ end
245
+
246
+ end
@@ -0,0 +1,111 @@
1
+ #!/usr/bin/env ruby
2
+ require File.join(File.dirname(__FILE__), "..", "spec_helper")
3
+
4
+ describe Glyph::SyntaxNode do
5
+
6
+ it "should evaluate" do
7
+ t = text_node("test")
8
+ t.evaluate({})
9
+ t[:value].should == "test"
10
+ e = escape_node("\\.")
11
+ e.evaluate({})
12
+ e[:value].should == "\\."
13
+ p = p_node(0)
14
+ a = a_node(:a)
15
+ a << e
16
+ p << t
17
+ p.evaluate({}, :params => true)
18
+ p[:value].should == "test"
19
+ a.evaluate({}, :attrs => true)
20
+ a[:value].should == "\\."
21
+ Glyph.macro :test do
22
+ attribute(:a)+param(0)
23
+ end
24
+ m = macro_node(:test)
25
+ m << p
26
+ m << a
27
+ m.evaluate({})
28
+ m[:value].should == "\\.test"
29
+ end
30
+
31
+ it "should return its parent macro" do
32
+ node = Glyph::Parser.new("test[@a[a].|test]").parse
33
+ node.parent_macro.should == nil
34
+ (node&0).parent_macro.should == nil
35
+ (node&0&0).parent_macro.should == node&0
36
+ (node&0&1).parent_macro.should == node&0
37
+ (node&0&0&0).parent_macro.should == node&0
38
+ (node&0&1&0).parent_macro.should == node&0
39
+ end
40
+
41
+ it "should convert to a string implicitly" do
42
+ "#{text_node("test")}".should == "test"
43
+ "#{escape_node("\\.")}".should == "\\."
44
+ "#{document_node}".should == ""
45
+ p0 = p_node(0)
46
+ p0 << text_node("p0")
47
+ p1 = p_node(1)
48
+ p1 << text_node("p1")
49
+ "#{p0}".should == "p0"
50
+ "#{p1}".should == "p1"
51
+ a = a_node(:a)
52
+ a << text_node("a")
53
+ b = a_node(:b)
54
+ b << text_node("b")
55
+ "#{a}".should == "@a[a]"
56
+ "#{b}".should == "@b[b]"
57
+ m = macro_node(:test, :escape => true)
58
+ m << a
59
+ m << b
60
+ m << p0
61
+ m << p1
62
+ "#{m}".should == "test[=@a[a]@b[b]p0|p1=]"
63
+ end
64
+
65
+ end
66
+
67
+ describe Glyph::MacroNode do
68
+
69
+ before do
70
+ @n = macro_node(:test)
71
+ @p = p_node(0)
72
+ @a = a_node(:a)
73
+ @p << text_node("test")
74
+ @a << text_node("test")
75
+ @n << @p
76
+ @n << @a
77
+ Glyph.macro :test do
78
+ "--#{param(0)}:#{attr(:a)}--"
79
+ end
80
+ end
81
+
82
+ it "should expand the corresponding macro" do
83
+ @n.expand({}).should == "--test:test--"
84
+ end
85
+
86
+ it "should resolve to an XML element" do
87
+ reset_quiet
88
+ @n.expand({}) rescue nil # |xml| macro not defined
89
+ @n[:element].should == "test"
90
+ end
91
+
92
+ it "should retrieve parameter nodes easily" do
93
+ @n.parameter(0).should == @p
94
+ @n.parameters.should == [@p]
95
+ end
96
+
97
+ it "should retrieve attribute nodes easily" do
98
+ @n.attribute(:a).should == @a
99
+ @n.attributes.should == [@a]
100
+ end
101
+
102
+ it "should convert escaping attributes and parameters to strings properly" do
103
+ @a[:escape] = true
104
+ @a.to_s.should == "@a[=test=]"
105
+ @a.contents.should == ".[=test=]"
106
+ @p.parent[:escape] = true
107
+ @p.to_s.should == "test"
108
+ @p.contents.should == ".[=test=]"
109
+ end
110
+
111
+ end