cuporter 0.3.2 → 0.3.3
Sign up to get free protection for your applications and to get access to all the features.
- data/README.textile +123 -44
- data/Rakefile +5 -5
- data/bin/cuporter +19 -11
- data/lib/cuporter.rb +15 -26
- data/lib/cuporter/cli/options.rb +95 -22
- data/lib/cuporter/document.rb +23 -0
- data/lib/cuporter/document/html_document.rb +82 -0
- data/lib/cuporter/extensions/nokogiri.rb +46 -0
- data/lib/cuporter/feature_parser.rb +38 -19
- data/lib/cuporter/filter.rb +1 -0
- data/lib/cuporter/formatters/csv.rb +69 -0
- data/lib/cuporter/formatters/text.rb +166 -0
- data/lib/cuporter/formatters/xml_to_html.xslt +315 -0
- data/lib/cuporter/node.rb +7 -83
- data/lib/cuporter/node/node_base.rb +114 -0
- data/lib/cuporter/node/numbering.rb +32 -0
- data/lib/cuporter/node/sorting.rb +27 -0
- data/lib/cuporter/node/tagged_node.rb +22 -0
- data/lib/cuporter/node/totalling.rb +19 -0
- data/lib/cuporter/node/types.rb +158 -0
- data/lib/cuporter/node_parser.rb +62 -0
- data/lib/cuporter/report/feature_report.rb +23 -0
- data/lib/cuporter/report/report_base.rb +69 -0
- data/lib/cuporter/report/tag_report.rb +27 -7
- data/lib/cuporter/report/tree_report.rb +24 -0
- data/lib/cuporter/tag_nodes_parser.rb +94 -0
- data/public/images/ajax-loader.gif +0 -0
- data/public/images/file.gif +0 -0
- data/public/images/folder-closed.gif +0 -0
- data/public/images/folder.gif +0 -0
- data/public/images/minus.gif +0 -0
- data/public/images/plus.gif +0 -0
- data/public/images/treeview-black-line.gif +0 -0
- data/public/images/treeview-black.gif +0 -0
- data/public/images/treeview-default-line.gif +0 -0
- data/public/images/treeview-default.gif +0 -0
- data/public/images/treeview-famfamfam-line.gif +0 -0
- data/public/images/treeview-famfamfam.gif +0 -0
- data/public/images/treeview-gray-line.gif +0 -0
- data/public/images/treeview-gray.gif +0 -0
- data/public/images/treeview-red-line.gif +0 -0
- data/public/images/treeview-red.gif +0 -0
- data/public/javascripts/expand-collapse.js +47 -0
- data/public/javascripts/jquery-min.js +167 -0
- data/public/javascripts/jquery.treeview.js +267 -0
- data/public/javascripts/treeview-loader.js +11 -0
- data/public/stylesheets/cuporter.css +101 -0
- data/{lib/cuporter/formatter/name_report/style.css → public/stylesheets/feature_style.css} +17 -18
- data/public/stylesheets/jquery.treeview.css +75 -0
- data/{lib/cuporter/formatter/tag_report/style.css → public/stylesheets/tag_style.css} +17 -22
- data/public/stylesheets/tree_style.css +104 -0
- metadata +52 -37
- data/lib/cuporter/example_set_node.rb +0 -15
- data/lib/cuporter/formatter/csv_text_methods.rb +0 -20
- data/lib/cuporter/formatter/cuporter.css +0 -64
- data/lib/cuporter/formatter/html_methods.rb +0 -122
- data/lib/cuporter/formatter/html_node_writer.rb +0 -104
- data/lib/cuporter/formatter/jquery-min.js +0 -154
- data/lib/cuporter/formatter/name_report/csv.rb +0 -12
- data/lib/cuporter/formatter/name_report/html.rb +0 -48
- data/lib/cuporter/formatter/name_report/html_node_writer.rb +0 -18
- data/lib/cuporter/formatter/name_report/text.rb +0 -16
- data/lib/cuporter/formatter/name_report/text_node_writer.rb +0 -16
- data/lib/cuporter/formatter/pretty_text_methods.rb +0 -22
- data/lib/cuporter/formatter/tag_report/csv.rb +0 -12
- data/lib/cuporter/formatter/tag_report/html.rb +0 -35
- data/lib/cuporter/formatter/tag_report/html_node_writer.rb +0 -19
- data/lib/cuporter/formatter/tag_report/text.rb +0 -14
- data/lib/cuporter/formatter/tag_report/text_node_writer.rb +0 -17
- data/lib/cuporter/formatter/text_methods.rb +0 -19
- data/lib/cuporter/formatter/writer.rb +0 -33
- data/lib/cuporter/name_list_parser.rb +0 -44
- data/lib/cuporter/node_numberer.rb +0 -18
- data/lib/cuporter/report/name_report.rb +0 -19
- data/lib/cuporter/report/report.rb +0 -22
- data/lib/cuporter/tag_list_node.rb +0 -54
- data/lib/cuporter/tag_list_parser.rb +0 -39
@@ -0,0 +1,315 @@
|
|
1
|
+
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
|
2
|
+
<xsl:output method="xml" indent="yes" />
|
3
|
+
|
4
|
+
<xsl:template match="/">
|
5
|
+
<xsl:apply-templates select="//report"/>
|
6
|
+
</xsl:template>
|
7
|
+
|
8
|
+
<xsl:template match="report">
|
9
|
+
<xsl:element name="div">
|
10
|
+
<xsl:attribute name="class">report</xsl:attribute>
|
11
|
+
<xsl:attribute name="title"><xsl:value-of select="@title"/></xsl:attribute>
|
12
|
+
<xsl:call-template name="cuporter_header"/>
|
13
|
+
<xsl:element name="ul">
|
14
|
+
<xsl:attribute name="class">children</xsl:attribute>
|
15
|
+
<xsl:apply-templates select="./tag | ./dir | ./feature"/>
|
16
|
+
</xsl:element>
|
17
|
+
</xsl:element>
|
18
|
+
</xsl:template>
|
19
|
+
|
20
|
+
<xsl:template name="cuporter_header">
|
21
|
+
<xsl:element name="div">
|
22
|
+
<xsl:attribute name="class">cuporter_header</xsl:attribute>
|
23
|
+
|
24
|
+
<xsl:apply-templates select="../filter_summary"/>
|
25
|
+
|
26
|
+
<xsl:element name="div">
|
27
|
+
<xsl:attribute name="id">summary</xsl:attribute>
|
28
|
+
<xsl:choose>
|
29
|
+
<xsl:when test="@view='tag'">
|
30
|
+
<xsl:element name="div">
|
31
|
+
<xsl:attribute name="id">expand-collapse</xsl:attribute>
|
32
|
+
<xsl:element name="p">
|
33
|
+
<xsl:attribute name="id">expand_tags</xsl:attribute>
|
34
|
+
<xsl:text>Expand Tags</xsl:text>
|
35
|
+
</xsl:element>
|
36
|
+
<xsl:element name="p">
|
37
|
+
<xsl:attribute name="id">expand_all</xsl:attribute>
|
38
|
+
<xsl:text>Expand Features</xsl:text>
|
39
|
+
</xsl:element>
|
40
|
+
<xsl:element name="p">
|
41
|
+
<xsl:attribute name="id">collapser</xsl:attribute>
|
42
|
+
<xsl:text>Collapse All</xsl:text>
|
43
|
+
</xsl:element>
|
44
|
+
</xsl:element>
|
45
|
+
</xsl:when>
|
46
|
+
<xsl:when test="@view='tree'">
|
47
|
+
<xsl:element name="p">
|
48
|
+
<xsl:attribute name="id">total</xsl:attribute>
|
49
|
+
<xsl:value-of select="@total"/>
|
50
|
+
<xsl:text> Scenarios</xsl:text>
|
51
|
+
</xsl:element>
|
52
|
+
<xsl:element name="div">
|
53
|
+
<xsl:attribute name="id">expand-collapse</xsl:attribute>
|
54
|
+
<xsl:element name="a">
|
55
|
+
<xsl:attribute name="href">?#</xsl:attribute>
|
56
|
+
<xsl:attribute name="id">collapse_features</xsl:attribute>
|
57
|
+
<xsl:text>Collapse All</xsl:text>
|
58
|
+
</xsl:element>
|
59
|
+
<xsl:element name="a">
|
60
|
+
<xsl:attribute name="href">?#</xsl:attribute>
|
61
|
+
<xsl:attribute name="id">expand_features</xsl:attribute>
|
62
|
+
<xsl:text>Expand All</xsl:text>
|
63
|
+
</xsl:element>
|
64
|
+
</xsl:element>
|
65
|
+
</xsl:when>
|
66
|
+
<xsl:otherwise>
|
67
|
+
<xsl:element name="p">
|
68
|
+
<xsl:attribute name="id">total</xsl:attribute>
|
69
|
+
<xsl:value-of select="@total"/>
|
70
|
+
<xsl:text> Scenarios</xsl:text>
|
71
|
+
</xsl:element>
|
72
|
+
<xsl:element name="div">
|
73
|
+
<xsl:attribute name="id">expand-collapse</xsl:attribute>
|
74
|
+
<xsl:element name="p">
|
75
|
+
<xsl:attribute name="id">collapse_features</xsl:attribute>
|
76
|
+
<xsl:text>Collapse All</xsl:text>
|
77
|
+
</xsl:element>
|
78
|
+
<xsl:element name="p">
|
79
|
+
<xsl:attribute name="id">expand_features</xsl:attribute>
|
80
|
+
<xsl:text>Expand All</xsl:text>
|
81
|
+
</xsl:element>
|
82
|
+
</xsl:element>
|
83
|
+
</xsl:otherwise>
|
84
|
+
</xsl:choose>
|
85
|
+
</xsl:element>
|
86
|
+
|
87
|
+
<xsl:element name="div">
|
88
|
+
<xsl:attribute name="id">label</xsl:attribute>
|
89
|
+
<xsl:element name="h1">
|
90
|
+
<xsl:value-of select="@title"/>
|
91
|
+
</xsl:element>
|
92
|
+
</xsl:element>
|
93
|
+
</xsl:element>
|
94
|
+
</xsl:template>
|
95
|
+
|
96
|
+
<xsl:template match="filter_summary">
|
97
|
+
<xsl:element name="div">
|
98
|
+
<xsl:attribute name="id">filter_summary</xsl:attribute>
|
99
|
+
<xsl:element name="span">Filtering:</xsl:element>
|
100
|
+
<xsl:apply-templates select="all | any | none"/>
|
101
|
+
</xsl:element>
|
102
|
+
</xsl:template>
|
103
|
+
|
104
|
+
<xsl:template match="all">
|
105
|
+
<xsl:element name="p">
|
106
|
+
<xsl:attribute name="class">all</xsl:attribute>
|
107
|
+
<xsl:text>Include: </xsl:text>
|
108
|
+
<xsl:value-of select="@tags"/>
|
109
|
+
</xsl:element>
|
110
|
+
</xsl:template>
|
111
|
+
|
112
|
+
<xsl:template match="any">
|
113
|
+
<xsl:element name="p">
|
114
|
+
<xsl:attribute name="class">any</xsl:attribute>
|
115
|
+
<xsl:text>Include: </xsl:text>
|
116
|
+
<xsl:value-of select="@tags"/>
|
117
|
+
</xsl:element>
|
118
|
+
</xsl:template>
|
119
|
+
|
120
|
+
<xsl:template match="none">
|
121
|
+
<xsl:element name="p">
|
122
|
+
<xsl:attribute name="class">none</xsl:attribute>
|
123
|
+
<xsl:text>Exclude: </xsl:text>
|
124
|
+
<xsl:value-of select="@tags"/>
|
125
|
+
</xsl:element>
|
126
|
+
</xsl:template>
|
127
|
+
|
128
|
+
<xsl:template match="tag">
|
129
|
+
<xsl:element name="li">
|
130
|
+
<xsl:attribute name="class">tag</xsl:attribute>
|
131
|
+
<xsl:element name="div">
|
132
|
+
<xsl:attribute name="class">properties</xsl:attribute>
|
133
|
+
<xsl:apply-templates select="@cuke_name"/>
|
134
|
+
<xsl:apply-templates select="@total"/>
|
135
|
+
</xsl:element>
|
136
|
+
|
137
|
+
<xsl:element name="ul">
|
138
|
+
<xsl:attribute name="class">children</xsl:attribute>
|
139
|
+
<xsl:apply-templates select="feature"/>
|
140
|
+
</xsl:element>
|
141
|
+
</xsl:element>
|
142
|
+
</xsl:template>
|
143
|
+
|
144
|
+
<xsl:template match="dir">
|
145
|
+
<xsl:element name="li">
|
146
|
+
<xsl:attribute name="class">dir</xsl:attribute>
|
147
|
+
<xsl:element name="span">
|
148
|
+
<xsl:attribute name="class">properties</xsl:attribute>
|
149
|
+
<xsl:apply-templates select="@total"/>
|
150
|
+
<xsl:apply-templates select="@fs_name"/>
|
151
|
+
</xsl:element>
|
152
|
+
|
153
|
+
<xsl:element name="ul">
|
154
|
+
<xsl:attribute name="class">children</xsl:attribute>
|
155
|
+
<xsl:apply-templates select="./dir | ./file | ./feature"/>
|
156
|
+
</xsl:element>
|
157
|
+
</xsl:element>
|
158
|
+
</xsl:template>
|
159
|
+
|
160
|
+
<xsl:template match="file">
|
161
|
+
<xsl:element name="li">
|
162
|
+
<xsl:attribute name="class">file</xsl:attribute>
|
163
|
+
<xsl:element name="span">
|
164
|
+
<xsl:attribute name="class">properties</xsl:attribute>
|
165
|
+
<xsl:apply-templates select="@total"/>
|
166
|
+
<xsl:apply-templates select="@fs_name"/>
|
167
|
+
</xsl:element>
|
168
|
+
|
169
|
+
<xsl:element name="ul">
|
170
|
+
<xsl:apply-templates select="./feature"/>
|
171
|
+
</xsl:element>
|
172
|
+
</xsl:element>
|
173
|
+
</xsl:template>
|
174
|
+
|
175
|
+
<xsl:template match="feature">
|
176
|
+
<xsl:element name="li">
|
177
|
+
<xsl:attribute name="class">feature</xsl:attribute>
|
178
|
+
<xsl:element name="div">
|
179
|
+
<xsl:attribute name="class">properties</xsl:attribute>
|
180
|
+
<xsl:apply-templates select="@cuke_name"/>
|
181
|
+
<xsl:apply-templates select="@tags"/>
|
182
|
+
<xsl:apply-templates select="@file_path"/>
|
183
|
+
<xsl:apply-templates select="@total"/>
|
184
|
+
</xsl:element>
|
185
|
+
|
186
|
+
<xsl:if test="scenario | scenario_outline"> <!-- TODO: remove this test if possible. seems redundant since we'll always have at least 1 child -->
|
187
|
+
<xsl:element name="ul">
|
188
|
+
<xsl:attribute name="class">children</xsl:attribute>
|
189
|
+
<xsl:apply-templates select="scenario | scenario_outline"/>
|
190
|
+
</xsl:element>
|
191
|
+
</xsl:if>
|
192
|
+
</xsl:element>
|
193
|
+
</xsl:template>
|
194
|
+
|
195
|
+
<xsl:template match="scenario">
|
196
|
+
<xsl:element name="li">
|
197
|
+
<xsl:attribute name="class">scenario</xsl:attribute>
|
198
|
+
<xsl:element name="div">
|
199
|
+
<xsl:attribute name="class">properties</xsl:attribute>
|
200
|
+
<xsl:apply-templates select="@number"/>
|
201
|
+
<xsl:apply-templates select="@cuke_name"/>
|
202
|
+
<xsl:apply-templates select="@tags"/>
|
203
|
+
</xsl:element>
|
204
|
+
</xsl:element>
|
205
|
+
</xsl:template>
|
206
|
+
|
207
|
+
<xsl:template match="scenario_outline">
|
208
|
+
<xsl:element name="li">
|
209
|
+
<xsl:attribute name="class">scenario_outline</xsl:attribute>
|
210
|
+
<xsl:element name="div">
|
211
|
+
<xsl:attribute name="class">properties</xsl:attribute>
|
212
|
+
<xsl:apply-templates select="@cuke_name"/>
|
213
|
+
<xsl:apply-templates select="@tags"/>
|
214
|
+
</xsl:element>
|
215
|
+
<xsl:element name="ul">
|
216
|
+
<xsl:attribute name="class">children</xsl:attribute>
|
217
|
+
<xsl:apply-templates select="examples"/>
|
218
|
+
</xsl:element>
|
219
|
+
</xsl:element>
|
220
|
+
</xsl:template>
|
221
|
+
|
222
|
+
<xsl:template match="examples">
|
223
|
+
<xsl:element name="li">
|
224
|
+
<xsl:attribute name="class">examples</xsl:attribute>
|
225
|
+
<xsl:element name="div">
|
226
|
+
<xsl:attribute name="class">properties</xsl:attribute>
|
227
|
+
<xsl:apply-templates select="@cuke_name"/>
|
228
|
+
<xsl:apply-templates select="@tags"/>
|
229
|
+
</xsl:element>
|
230
|
+
<xsl:element name="table">
|
231
|
+
<xsl:attribute name="class">children</xsl:attribute>
|
232
|
+
<xsl:element name="thead">
|
233
|
+
<xsl:apply-templates select="example_header"/>
|
234
|
+
</xsl:element>
|
235
|
+
<xsl:element name="tbody">
|
236
|
+
<xsl:apply-templates select="example"/>
|
237
|
+
</xsl:element>
|
238
|
+
</xsl:element>
|
239
|
+
</xsl:element>
|
240
|
+
</xsl:template>
|
241
|
+
|
242
|
+
<xsl:template match="@cuke_name">
|
243
|
+
<xsl:element name="span">
|
244
|
+
<xsl:attribute name="class">cuke_name</xsl:attribute>
|
245
|
+
<xsl:value-of select="."/>
|
246
|
+
</xsl:element>
|
247
|
+
</xsl:template>
|
248
|
+
|
249
|
+
<xsl:template match="@fs_name">
|
250
|
+
<xsl:element name="span">
|
251
|
+
<xsl:attribute name="class">fs_name</xsl:attribute>
|
252
|
+
<xsl:value-of select="."/>
|
253
|
+
</xsl:element>
|
254
|
+
</xsl:template>
|
255
|
+
|
256
|
+
<xsl:template match="@tags">
|
257
|
+
<xsl:element name="span">
|
258
|
+
<xsl:attribute name="class">tags</xsl:attribute>
|
259
|
+
<xsl:value-of select="."/>
|
260
|
+
</xsl:element>
|
261
|
+
</xsl:template>
|
262
|
+
|
263
|
+
<xsl:template match="@file_path">
|
264
|
+
<xsl:element name="span">
|
265
|
+
<xsl:attribute name="class">file_path</xsl:attribute>
|
266
|
+
<xsl:value-of select="."/>
|
267
|
+
</xsl:element>
|
268
|
+
</xsl:template>
|
269
|
+
|
270
|
+
<xsl:template match="@total">
|
271
|
+
<xsl:element name="span">
|
272
|
+
<xsl:attribute name="class">total</xsl:attribute>
|
273
|
+
<xsl:text>[</xsl:text>
|
274
|
+
<xsl:value-of select="format-number(.,'00')"/>
|
275
|
+
<xsl:text>]</xsl:text>
|
276
|
+
</xsl:element>
|
277
|
+
</xsl:template>
|
278
|
+
|
279
|
+
<xsl:template match="@number">
|
280
|
+
<xsl:element name="span">
|
281
|
+
<xsl:attribute name="class">number</xsl:attribute>
|
282
|
+
<xsl:value-of select="."/>
|
283
|
+
</xsl:element>
|
284
|
+
</xsl:template>
|
285
|
+
|
286
|
+
<xsl:template match="example_header">
|
287
|
+
<xsl:element name="tr">
|
288
|
+
<xsl:attribute name="class">example</xsl:attribute>
|
289
|
+
<xsl:element name="th"> <xsl:attribute name="class">number</xsl:attribute> </xsl:element>
|
290
|
+
<xsl:apply-templates select="span"/>
|
291
|
+
</xsl:element>
|
292
|
+
</xsl:template>
|
293
|
+
|
294
|
+
<xsl:template match="example">
|
295
|
+
<xsl:element name="tr">
|
296
|
+
<xsl:attribute name="class">example</xsl:attribute>
|
297
|
+
<xsl:element name="td"> <xsl:attribute name="class">number</xsl:attribute> <xsl:value-of select="@number"/> </xsl:element>
|
298
|
+
<xsl:apply-templates select="span"/>
|
299
|
+
</xsl:element>
|
300
|
+
</xsl:template>
|
301
|
+
|
302
|
+
<xsl:template match="example_header/span">
|
303
|
+
<xsl:element name="th">
|
304
|
+
<xsl:value-of select="."/>
|
305
|
+
</xsl:element>
|
306
|
+
</xsl:template>
|
307
|
+
|
308
|
+
<xsl:template match="example/span">
|
309
|
+
<xsl:element name="td">
|
310
|
+
<xsl:value-of select="."/>
|
311
|
+
</xsl:element>
|
312
|
+
</xsl:template>
|
313
|
+
|
314
|
+
</xsl:stylesheet>
|
315
|
+
|
data/lib/cuporter/node.rb
CHANGED
@@ -1,83 +1,7 @@
|
|
1
|
-
# Copyright
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
def initialize(name)
|
11
|
-
@name = name.to_s.strip
|
12
|
-
@children = []
|
13
|
-
end
|
14
|
-
|
15
|
-
def has_children?
|
16
|
-
@children.size > 0
|
17
|
-
end
|
18
|
-
|
19
|
-
# will not add duplicate
|
20
|
-
def add_child(node)
|
21
|
-
@children << node unless has_child?(node)
|
22
|
-
end
|
23
|
-
|
24
|
-
def names
|
25
|
-
children.collect {|c| c.name }
|
26
|
-
end
|
27
|
-
|
28
|
-
def find_by_name(name)
|
29
|
-
children.find {|c| c.name == name.to_s}
|
30
|
-
end
|
31
|
-
alias :[] :find_by_name
|
32
|
-
|
33
|
-
def find(node)
|
34
|
-
children.find {|c| c == node}
|
35
|
-
end
|
36
|
-
alias :has_child? :find
|
37
|
-
|
38
|
-
def name_without_title
|
39
|
-
@name_without_title ||= name.split(/:\s+/).last
|
40
|
-
end
|
41
|
-
|
42
|
-
def sort_all_descendants!
|
43
|
-
sort!
|
44
|
-
children.each {|child| child.sort_all_descendants! }
|
45
|
-
end
|
46
|
-
|
47
|
-
def sort!
|
48
|
-
children.sort!
|
49
|
-
end
|
50
|
-
|
51
|
-
# sort on: file path, name, substring of name after any ':'
|
52
|
-
def <=>(other)
|
53
|
-
if file
|
54
|
-
file <=> other.file
|
55
|
-
else
|
56
|
-
name_without_title <=> other.name_without_title
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
# value equivalence
|
61
|
-
def eql?(other)
|
62
|
-
name == other.name && children == other.children
|
63
|
-
end
|
64
|
-
alias :== :eql?
|
65
|
-
|
66
|
-
|
67
|
-
def total
|
68
|
-
number_all_descendants unless @numberer
|
69
|
-
@numberer.total
|
70
|
-
end
|
71
|
-
|
72
|
-
def number_all_descendants
|
73
|
-
@numberer = NodeNumberer.new
|
74
|
-
@numberer.number(self)
|
75
|
-
end
|
76
|
-
|
77
|
-
def numerable?
|
78
|
-
@numerable.nil? ? !has_children? : @numerable
|
79
|
-
end
|
80
|
-
attr_writer :numerable
|
81
|
-
|
82
|
-
end
|
83
|
-
end
|
1
|
+
# Copyright 2011 ThoughtWorks, Inc. Licensed under the MIT License
|
2
|
+
require 'lib/cuporter/node/sorting'
|
3
|
+
require 'lib/cuporter/node/totalling'
|
4
|
+
require 'lib/cuporter/node/numbering'
|
5
|
+
require 'lib/cuporter/node/node_base'
|
6
|
+
require 'lib/cuporter/node/tagged_node'
|
7
|
+
require 'lib/cuporter/node/types'
|
@@ -0,0 +1,114 @@
|
|
1
|
+
# Copyright 2011 ThoughtWorks, Inc. Licensed under the MIT License
|
2
|
+
module Cuporter
|
3
|
+
module Node
|
4
|
+
|
5
|
+
module BaseMethods
|
6
|
+
include Sorting
|
7
|
+
include Totalling
|
8
|
+
include Numbering
|
9
|
+
|
10
|
+
def has_children?
|
11
|
+
children.size > 0
|
12
|
+
end
|
13
|
+
|
14
|
+
def names
|
15
|
+
children.collect {|c| c.name }
|
16
|
+
end
|
17
|
+
|
18
|
+
def cuke_names
|
19
|
+
children.collect {|c| c.cuke_name }
|
20
|
+
end
|
21
|
+
|
22
|
+
def cuke_name
|
23
|
+
@cuke_name ||= self['cuke_name'].to_s
|
24
|
+
end
|
25
|
+
|
26
|
+
def find(node)
|
27
|
+
children.find {|c| c.eql? node}
|
28
|
+
end
|
29
|
+
alias :has_child? :find
|
30
|
+
|
31
|
+
def add_leaf(node, *path)
|
32
|
+
file_node = Node.new_node("file", document, "fs_name" => path.pop)
|
33
|
+
file_node << node
|
34
|
+
parent = node_at(*path)
|
35
|
+
parent.add_child(file_node)
|
36
|
+
end
|
37
|
+
alias :add_to_end :add_leaf
|
38
|
+
|
39
|
+
# *path is a list of nodes forming a path to the last one.
|
40
|
+
def node_at(*path)
|
41
|
+
return self if path.empty?
|
42
|
+
|
43
|
+
# recursive loop ends when last path_node is shifted off the array
|
44
|
+
attributes = {'fs_name' => path.shift}
|
45
|
+
|
46
|
+
# create and add the child node if it's not found among the immediate
|
47
|
+
# children of self
|
48
|
+
child = children.find do |c|
|
49
|
+
c.node_name == 'dir' && c.fs_name == attributes['fs_name']
|
50
|
+
end
|
51
|
+
unless child
|
52
|
+
child = Node.new_node('dir', document, attributes)
|
53
|
+
add_child(child)
|
54
|
+
end
|
55
|
+
|
56
|
+
child.node_at(*path)
|
57
|
+
end
|
58
|
+
|
59
|
+
def short_cuke_name
|
60
|
+
@short_cuke_name ||= (cn = cuke_name) ? cn.split(/:\s*/).last : ""
|
61
|
+
end
|
62
|
+
|
63
|
+
# value equivalence
|
64
|
+
def eql?(other)
|
65
|
+
node_name == other.node_name && cuke_name == other.cuke_name && children.eql?(other.children)
|
66
|
+
end
|
67
|
+
|
68
|
+
def to_text
|
69
|
+
s = Cuporter::Formatters::Text.build_line(self)
|
70
|
+
s += children.map {|n| n.to_text}.to_s
|
71
|
+
s
|
72
|
+
end
|
73
|
+
alias :to_pretty :to_text
|
74
|
+
|
75
|
+
def to_csv
|
76
|
+
s = Cuporter::Formatters::Csv.build_line(self)
|
77
|
+
s += children.map {|n| n.to_csv}.to_s
|
78
|
+
s
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
82
|
+
# this will vary when json comes
|
83
|
+
NodeBase = Nokogiri::XML::Node
|
84
|
+
|
85
|
+
# common methods for building either html or xml nodes
|
86
|
+
module InitializeNode
|
87
|
+
|
88
|
+
def format_name(name)
|
89
|
+
node_name = name.to_s.gsub(/([a-z])([A-Z])/,'\1_\2').downcase
|
90
|
+
class_name = name.to_s.to_class_name.to_sym
|
91
|
+
return node_name, class_name
|
92
|
+
end
|
93
|
+
|
94
|
+
def copy_attrs(node, attributes)
|
95
|
+
attributes.each do |attr, value|
|
96
|
+
next if attr.to_s.downcase == 'type'
|
97
|
+
value = value.is_a?(Array) ? value.join(", ") : value.to_s.strip
|
98
|
+
node[attr.to_s] = value unless value.empty?
|
99
|
+
end
|
100
|
+
node
|
101
|
+
end
|
102
|
+
|
103
|
+
def new_node(name, doc, attributes = {})
|
104
|
+
node_name, class_name = format_name(name)
|
105
|
+
n = Cuporter::Node::Types.const_get(class_name).new(node_name, doc)
|
106
|
+
copy_attrs(n, attributes)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
Cuporter::Node.send(:extend, Cuporter::Node::InitializeNode)
|
114
|
+
Cuporter::Node::NodeBase.send(:include, Cuporter::Node::BaseMethods)
|