cuporter 0.3.2 → 0.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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)
|