cuporter 0.3.2 → 0.3.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (77) hide show
  1. data/README.textile +123 -44
  2. data/Rakefile +5 -5
  3. data/bin/cuporter +19 -11
  4. data/lib/cuporter.rb +15 -26
  5. data/lib/cuporter/cli/options.rb +95 -22
  6. data/lib/cuporter/document.rb +23 -0
  7. data/lib/cuporter/document/html_document.rb +82 -0
  8. data/lib/cuporter/extensions/nokogiri.rb +46 -0
  9. data/lib/cuporter/feature_parser.rb +38 -19
  10. data/lib/cuporter/filter.rb +1 -0
  11. data/lib/cuporter/formatters/csv.rb +69 -0
  12. data/lib/cuporter/formatters/text.rb +166 -0
  13. data/lib/cuporter/formatters/xml_to_html.xslt +315 -0
  14. data/lib/cuporter/node.rb +7 -83
  15. data/lib/cuporter/node/node_base.rb +114 -0
  16. data/lib/cuporter/node/numbering.rb +32 -0
  17. data/lib/cuporter/node/sorting.rb +27 -0
  18. data/lib/cuporter/node/tagged_node.rb +22 -0
  19. data/lib/cuporter/node/totalling.rb +19 -0
  20. data/lib/cuporter/node/types.rb +158 -0
  21. data/lib/cuporter/node_parser.rb +62 -0
  22. data/lib/cuporter/report/feature_report.rb +23 -0
  23. data/lib/cuporter/report/report_base.rb +69 -0
  24. data/lib/cuporter/report/tag_report.rb +27 -7
  25. data/lib/cuporter/report/tree_report.rb +24 -0
  26. data/lib/cuporter/tag_nodes_parser.rb +94 -0
  27. data/public/images/ajax-loader.gif +0 -0
  28. data/public/images/file.gif +0 -0
  29. data/public/images/folder-closed.gif +0 -0
  30. data/public/images/folder.gif +0 -0
  31. data/public/images/minus.gif +0 -0
  32. data/public/images/plus.gif +0 -0
  33. data/public/images/treeview-black-line.gif +0 -0
  34. data/public/images/treeview-black.gif +0 -0
  35. data/public/images/treeview-default-line.gif +0 -0
  36. data/public/images/treeview-default.gif +0 -0
  37. data/public/images/treeview-famfamfam-line.gif +0 -0
  38. data/public/images/treeview-famfamfam.gif +0 -0
  39. data/public/images/treeview-gray-line.gif +0 -0
  40. data/public/images/treeview-gray.gif +0 -0
  41. data/public/images/treeview-red-line.gif +0 -0
  42. data/public/images/treeview-red.gif +0 -0
  43. data/public/javascripts/expand-collapse.js +47 -0
  44. data/public/javascripts/jquery-min.js +167 -0
  45. data/public/javascripts/jquery.treeview.js +267 -0
  46. data/public/javascripts/treeview-loader.js +11 -0
  47. data/public/stylesheets/cuporter.css +101 -0
  48. data/{lib/cuporter/formatter/name_report/style.css → public/stylesheets/feature_style.css} +17 -18
  49. data/public/stylesheets/jquery.treeview.css +75 -0
  50. data/{lib/cuporter/formatter/tag_report/style.css → public/stylesheets/tag_style.css} +17 -22
  51. data/public/stylesheets/tree_style.css +104 -0
  52. metadata +52 -37
  53. data/lib/cuporter/example_set_node.rb +0 -15
  54. data/lib/cuporter/formatter/csv_text_methods.rb +0 -20
  55. data/lib/cuporter/formatter/cuporter.css +0 -64
  56. data/lib/cuporter/formatter/html_methods.rb +0 -122
  57. data/lib/cuporter/formatter/html_node_writer.rb +0 -104
  58. data/lib/cuporter/formatter/jquery-min.js +0 -154
  59. data/lib/cuporter/formatter/name_report/csv.rb +0 -12
  60. data/lib/cuporter/formatter/name_report/html.rb +0 -48
  61. data/lib/cuporter/formatter/name_report/html_node_writer.rb +0 -18
  62. data/lib/cuporter/formatter/name_report/text.rb +0 -16
  63. data/lib/cuporter/formatter/name_report/text_node_writer.rb +0 -16
  64. data/lib/cuporter/formatter/pretty_text_methods.rb +0 -22
  65. data/lib/cuporter/formatter/tag_report/csv.rb +0 -12
  66. data/lib/cuporter/formatter/tag_report/html.rb +0 -35
  67. data/lib/cuporter/formatter/tag_report/html_node_writer.rb +0 -19
  68. data/lib/cuporter/formatter/tag_report/text.rb +0 -14
  69. data/lib/cuporter/formatter/tag_report/text_node_writer.rb +0 -17
  70. data/lib/cuporter/formatter/text_methods.rb +0 -19
  71. data/lib/cuporter/formatter/writer.rb +0 -33
  72. data/lib/cuporter/name_list_parser.rb +0 -44
  73. data/lib/cuporter/node_numberer.rb +0 -18
  74. data/lib/cuporter/report/name_report.rb +0 -19
  75. data/lib/cuporter/report/report.rb +0 -22
  76. data/lib/cuporter/tag_list_node.rb +0 -54
  77. 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 2010 ThoughtWorks, Inc. Licensed under the MIT License
2
- module Cuporter
3
- class Node
4
- include Comparable
5
-
6
- attr_reader :name
7
- attr_accessor :children, :number, :file
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)