cuporter 0.2.9 → 0.3.0

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 CHANGED
@@ -2,13 +2,13 @@ h1. Cuporter
2
2
 
3
3
  Scrapes your feature files and shows 2 possible reports:
4
4
 
5
- # scenarios and examples per tag
5
+ # Tag Report: scenarios and examples per tag
6
6
  ** in Feature and Scenario Outline context, as appropriate
7
- ** sorted alphbetically
7
+ ** sorted alphbetically by file path, scenario name, scenario outline name, example name
8
8
  ** optionally numbered*, counting scenarios and outline examples per tag
9
- # feature, scenario and example names
9
+ # Inventory Report: feature, scenario and example names
10
10
  ** may be filtered by tags, using same CLI syntax as Cucumber
11
- ** sorted alphbetically
11
+ ** sorted alphbetically by file path, scenario name, scenario outline name, example name
12
12
  ** optionally numbered*, using 1 count of all scenarios and outline examples for the report
13
13
 
14
14
  <notextile>*</notextile> _HTML reports are always numbered._
@@ -106,20 +106,12 @@ h4. run script directly
106
106
  # pretty-print demo report to stdout
107
107
  $ ./bin/cuporter -i fixtures/self_text
108
108
 
109
- # default input features/**/*.feature to named output file
110
- $ ./bin/cuporter -f html -o feature_tag_report.html
111
-
112
109
  # same, but number the scenarios and example rows
113
- $ ./bin/cuporter -f html --numbers -o feature_tag_report.html
114
-
115
- # filtered html name report, with non-default title
116
- $ ./bin/cuporter -f html -o active_customer.html -r name -n -T "Active Customer Test Inventory" -t ~@wip -t @customer,@client
117
- </pre>
110
+ $ ./bin/cuporter -i fixtures/self_text -n
118
111
 
119
- h4. run via rake
120
-
121
- <pre>
122
- $ rake cuporter:run["-i fixtures/self_text"]
112
+ # default input features/**/*.feature to named html output file
113
+ $ ./bin/cuporter -f html -o feature_tag_report.html
123
114
 
124
- $ rake cuporter:run["-f html -o feature_tag_report.html"]
115
+ # filtered html name report, with non-default title
116
+ $ ./bin/cuporter -f html -o active_customer.html -r name -T "Active Customer Test Inventory" -t ~@wip -t @customer,@client
125
117
  </pre>
data/Rakefile CHANGED
@@ -56,7 +56,7 @@ namespace :cuporter do
56
56
 
57
57
  spec = Gem::Specification.new do |s|
58
58
  s.name = 'cuporter'
59
- s.version = '0.2.9'
59
+ s.version = '0.3.0'
60
60
  s.rubyforge_project = s.name
61
61
 
62
62
  s.platform = Gem::Platform::RUBY
@@ -1,7 +1,7 @@
1
1
  # Copyright 2010 ThoughtWorks, Inc. Licensed under the MIT License
2
2
 
3
3
  module Cuporter
4
- module FeatureParser
4
+ class FeatureParser
5
5
  FEATURE_LINE = /^\s*(Feature:[^#]+)/
6
6
  TAG_LINE = /^\s*(@\w.+)/
7
7
  SCENARIO_LINE = /^\s*(Scenario:[^#]+)$/
@@ -11,11 +11,55 @@ module Cuporter
11
11
  EXAMPLE_LINE = /^\s*(\|.*\|)\s*$/
12
12
 
13
13
  def self.tag_list(file)
14
- TagList.new(file).parse_feature
14
+ TagListParser.new(file).parse_feature
15
15
  end
16
16
 
17
17
  def self.name_list(file, filter)
18
- NameList.new(file, filter).parse_feature
18
+ NameListParser.new(file, filter).parse_feature
19
+ end
20
+
21
+ def initialize(file)
22
+ @file = file
23
+ @current_tags = []
24
+ @lines = File.read(@file).split(/\n/)
25
+ end
26
+
27
+ def parse_feature
28
+ @lines.each do |line|
29
+ case line
30
+ when FeatureParser::TAG_LINE
31
+ # may be more than one tag line
32
+ @current_tags |= $1.strip.split(/\s+/)
33
+ when FeatureParser::FEATURE_LINE
34
+ @feature = new_feature_node($1)
35
+ @feature.file = @file.sub(/^.*features\//,"features/")
36
+ @current_tags = []
37
+ when FeatureParser::SCENARIO_LINE
38
+ # How do we know when we have read all the lines from a "Scenario Outline:"?
39
+ # One way is when we encounter a "Scenario:"
40
+ close_scenario_outline
41
+
42
+ handle_scenario_line($1)
43
+ @current_tags = []
44
+ when FeatureParser::SCENARIO_OUTLINE_LINE
45
+ # ... another is when we hit a subsequent "Scenario Outline:"
46
+ close_scenario_outline
47
+
48
+ @scenario_outline = new_scenario_outline_node($1)
49
+ @current_tags = []
50
+ when FeatureParser::EXAMPLE_SET_LINE, FeatureParser::SCENARIO_SET_LINE
51
+ handle_example_set_line if @example_set
52
+
53
+ @example_set = new_example_set_node($1)
54
+ @current_tags = []
55
+ when @example_set && FeatureParser::EXAMPLE_LINE
56
+ @example_set.add_child(Node.new($1))
57
+ end
58
+ end
59
+
60
+ # EOF is the final way that we know we are finished with a "Scenario Outline"
61
+ close_scenario_outline
62
+ return @feature
19
63
  end
20
64
 
21
65
  end
@@ -7,7 +7,6 @@ body {
7
7
  padding-left: 2em;
8
8
  padding-bottom: 0.3em;
9
9
  padding-top: 0.05em;
10
- background-color: #24A6C1;
11
10
  color: white;
12
11
  height: 7em;
13
12
  }
@@ -15,12 +14,6 @@ body {
15
14
  padding-right: 2em;
16
15
  float: left;
17
16
  }
18
- #filter_summary {
19
- width: 60em;
20
- float: right;
21
- padding-top: 1.2em;
22
- }
23
-
24
17
  #summary {
25
18
  position: absolute;
26
19
  right: 1em;
@@ -28,87 +21,40 @@ body {
28
21
  top: 1.2em;
29
22
  }
30
23
 
31
- #summary p, #filter_summary p {
24
+ #summary p {
32
25
  margin: 0px 0px 0px 2px;
33
26
  }
34
27
 
35
- .tag_report #expand-collapse {
36
- position: absolute;
37
- right: 1em;
38
- text-align: right;
39
- top: 0.5em;
40
- }
41
28
  ul {
42
29
  list-style-type: none;
43
30
  }
44
- .tag_list {
31
+ .main_list {
45
32
  padding-left: 0.5em;
46
33
  }
47
- .tag_name {
48
- height: 2em;
49
- font-weight: bold;
50
- font-size: 1.5em;
51
- }
52
- .total {
53
- margin-left: 0.5em;
54
- font-weight: normal;
55
- font-size: 0.8em;
56
- }
57
- .tag {
58
- margin-bottom: 1em;
59
- }
60
-
61
34
  .feature {
62
35
  margin-bottom: 0.5em;
63
36
  margin-right: 1em;
64
37
  }
65
38
  .feature_name {
66
- margin-left: -2em;
67
- padding-left: 2em;
68
39
  padding-top: 0.3em;
69
40
  padding-bottom: 0.3em;
70
41
  font-weight: bold;
71
- background-color: #24A6C1;
72
- color: white;
73
- }
74
- .example_rows {
75
- background-color: lightblue;
76
- margin-left: -7.2em;
77
- padding-left: 7.2em;
78
42
  }
79
43
 
80
- .example_set_name {
81
- margin-left: -2em;
82
- }
83
- .example {
84
- background-color: #26A6C0;
44
+ .file {
45
+ float: right;
46
+ padding-right: 0.5em;
47
+ font-weight: normal;
48
+ color: black;
85
49
  }
86
50
 
87
51
  .example td.val {
88
52
  padding-left: 0.5em;
89
53
  }
90
- .scenario_name {
91
- margin-left: -3.8em;
92
- padding-left: 3.8em;
93
- background-color: lightblue;
94
-
95
- }
96
54
 
97
55
  .number {
98
56
  position: absolute;
99
- left: 4.5em;
100
57
  font-weight: bold;
101
58
  }
102
59
 
103
- .name_report .number {
104
- left: 4em;
105
- }
106
- .file {
107
- float: right;
108
- padding-right: 0.5em;
109
- font-weight: normal;
110
- font-size: 1.1em;
111
- color: black;
112
-
113
- }
114
60
 
@@ -6,24 +6,63 @@ module Cuporter
6
6
  module Formatter
7
7
  module HtmlMethods
8
8
 
9
- def inline_style
10
- File.read(File.dirname(__FILE__) + "/cuporter.css")
9
+ def document
10
+ builder = Builder::XmlMarkup.new
11
+ builder.declare!(:DOCTYPE, :html,
12
+ :PUBLIC, "-//W3C//DTD XHTML 1.0 Transitional//EN",
13
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"
14
+ )
15
+ builder
11
16
  end
12
17
 
13
- def get_binding
14
- binding
18
+ def html
19
+ document.html(:xmlns => "http://www.w3.org/1999/xhtml") do |html|
20
+ head(html)
21
+ body(html)
22
+ end.to_s.sub("<to_s/>",'')
15
23
  end
16
24
 
17
- def rhtml
18
- ERB.new(self.class::RHTML)
25
+ def head(html)
26
+ html.head do |head|
27
+ head.title(title)
28
+ head.style(inline_file("cuporter.css"))
29
+ head.style(inline_file(inline_style))
30
+ head.script(:type => "text/javascript") do
31
+ head << inline_jquery # jquery is corrupted if it isn't handled this way
32
+ head << inline_js_content
33
+ end
34
+ end
35
+ end
36
+
37
+ def body(html)
38
+ html.body do |body|
39
+ header(body)
40
+ body.ul(:class => :main_list) do |ul|
41
+ write_report_node(body)
42
+ end
43
+ end
44
+ end
45
+
46
+ def label(header)
47
+ header.div(:id => :label) do |div|
48
+ div.h1(title)
49
+ end
50
+ end
51
+
52
+ def inline_file(file_name)
53
+ File.read("#{File.dirname(__FILE__)}/#{file_name}")
54
+ end
55
+
56
+ def write_report_node(body)
57
+ report_node_writer.new(@report, body).write_report_node
19
58
  end
20
59
 
21
60
  def write
22
- @output.puts rhtml.result(get_binding).reject {|line| /^\s+$/ =~ line}
61
+ @output.puts html
23
62
  end
24
63
 
25
64
  def inline_jquery
26
- File.read(File.dirname(__FILE__) + '/jquery-min.js')
65
+ inline_file('/jquery-min.js')
27
66
  end
28
67
 
29
68
  def inline_js_content
@@ -72,7 +111,7 @@ module Cuporter
72
111
  });
73
112
 
74
113
  // load page with features collapsed
75
- $("#expand_tags, #collapse_features").click();
114
+ $("#collapser, #collapse_features").click();
76
115
  })
77
116
 
78
117
  EOF
@@ -8,17 +8,11 @@ module Cuporter
8
8
 
9
9
  attr_reader :builder
10
10
 
11
- def initialize
12
- @builder = Builder::XmlMarkup.new
11
+ def initialize(report, builder)
12
+ @report = report
13
+ @builder = builder
13
14
  end
14
15
 
15
- def write_nodes(report, number_scenarios)
16
- report.report_node.number_all_descendants if number_scenarios
17
- report.report_node.children.each do |child_node|
18
- write_node(child_node)
19
- end
20
- builder
21
- end
22
16
  def write_node(node)
23
17
  builder.li(:class => node_class(node.name)) do
24
18
  write_node_name(node)
@@ -79,18 +73,18 @@ module Cuporter
79
73
 
80
74
  def node_class(name)
81
75
  case name
82
- when FeatureParser::TAG_LINE
83
- :tag
84
- when FeatureParser::FEATURE_LINE
85
- :feature
86
- when FeatureParser::SCENARIO_LINE
87
- :scenario
88
- when FeatureParser::SCENARIO_OUTLINE_LINE
89
- :scenario_outline
90
- when FeatureParser::SCENARIO_SET_LINE, FeatureParser::EXAMPLE_SET_LINE
91
- :example_set
92
- else
93
- :example
76
+ when FeatureParser::TAG_LINE
77
+ :tag
78
+ when FeatureParser::FEATURE_LINE
79
+ :feature
80
+ when FeatureParser::SCENARIO_LINE
81
+ :scenario
82
+ when FeatureParser::SCENARIO_OUTLINE_LINE
83
+ :scenario_outline
84
+ when FeatureParser::SCENARIO_SET_LINE, FeatureParser::EXAMPLE_SET_LINE
85
+ :example_set
86
+ else
87
+ :example
94
88
  end
95
89
  end
96
90
 
@@ -1,20 +1,34 @@
1
1
  # Copyright 2010 ThoughtWorks, Inc. Licensed under the MIT License
2
- require 'rubygems'
3
- require 'erb'
4
-
5
2
  module Cuporter
6
3
  module Formatter
7
4
  module NameReport
8
5
  class Html < Writer
9
6
  include HtmlMethods
10
7
 
8
+ def report_node_writer
9
+ Cuporter::Formatter::NameReport::HtmlNodeWriter
10
+ end
11
+
11
12
  def title
12
13
  @report.title
13
14
  end
14
15
 
15
- def filter_summary
16
+ def header(body)
17
+ body.div(:class => :cuporter_header) do |header|
18
+ label(header)
19
+ filter_summary(header)
20
+ header.div(:id => :summary) do |div|
21
+ div.p("#{@report.report_node.total} Scenarios", :id => :total)
22
+ div.div(:id => "expand-collapse") do |exp_col|
23
+ exp_col.p("Expand All", :id => :expand_features)
24
+ exp_col.p("Collapse All", :id => :collapse_features)
25
+ end
26
+ end
27
+ end
28
+ end
29
+
30
+ def filter_summary(builder)
16
31
  return if @report.filter.empty?
17
- builder = Builder::XmlMarkup.new
18
32
  builder.div(:id => :filter_summary) do |div|
19
33
  div.p("Filtering:")
20
34
  div.p("Include: #{@report.filter.all.join(' AND ')}") unless @report.filter.all.empty?
@@ -23,40 +37,10 @@ module Cuporter
23
37
  end
24
38
  end
25
39
 
26
- RHTML = %{
27
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
28
- <html xmlns="http://www.w3.org/1999/xhtml">
29
- <head>
30
- <title><%= title %></title>
31
- <style type="text/css">
32
- <%= inline_style%>
33
- </style>
34
- <script type="text/javascript">
35
- <%= inline_jquery%>
36
- <%= inline_js_content%>
37
- </script>
38
- </head>
39
- <body class="name_report">
40
- <div class="cuporter_header">
41
- <div id="label">
42
- <h1><%= title %></h1>
43
- </div>
44
- <%= filter_summary %>
45
- <div id="summary">
46
- <p id="total"><%= @report.report_node.total%> Scenarios </p>
47
- <div id="expand-collapse">
48
- <p id="expand_features">Expand All</p>
49
- <p id="collapse_features">Collapse All</p>
50
- </div>
51
- </div>
52
- </div>
53
- <ul class="tag_list, name_report">
54
- <%= Cuporter::Formatter::NameReport::HtmlNodeWriter.new.write_nodes(@report)%>
55
- </ul>
56
- </body>
57
- </html>
58
- }
59
-
40
+ def inline_style
41
+ "name_report/style.css"
42
+ end
43
+
60
44
 
61
45
  end
62
46
  end
@@ -5,8 +5,8 @@ module Cuporter
5
5
  module NameReport
6
6
  class HtmlNodeWriter < Cuporter::Formatter::HtmlNodeWriter
7
7
 
8
- def write_nodes(report)
9
- report.report_node.children.each do |child_node|
8
+ def write_report_node
9
+ @report.report_node.children.each do |child_node|
10
10
  write_node(child_node)
11
11
  end
12
12
  builder
@@ -0,0 +1,58 @@
1
+ /* Name Report */
2
+ .number {
3
+ left: 3.0em;
4
+ }
5
+
6
+ #filter_summary {
7
+ width: 60em;
8
+ float: right;
9
+ padding-top: 1.2em;
10
+ }
11
+
12
+ #filter_summary p {
13
+ margin: 0px 0px 0px 2px;
14
+ }
15
+
16
+ .cuporter_header {
17
+ background-color: #65C400;
18
+ }
19
+
20
+ .feature_name {
21
+ margin-left: 0.5em;
22
+ font-size: 1.5em;
23
+ }
24
+
25
+ .file {
26
+ font-size: 0.8em;
27
+ }
28
+
29
+ .scenario_name {
30
+ margin-left: -2.4em;
31
+ padding-left: 4.0em;
32
+ padding-top: 0.1em;
33
+ padding-bottom: 0.2em;
34
+ }
35
+ .scenario_outline_name {
36
+ margin-left: -2.4em;
37
+ padding-left: 4.5em;
38
+ padding-top: 0.1em;
39
+ padding-bottom: 0.2em;
40
+
41
+ }
42
+
43
+ .example {
44
+ background-color: #65C400;
45
+ }
46
+
47
+ .example_rows {
48
+ margin-left: -6.0em;
49
+ padding-left: 7.6em;
50
+ }
51
+
52
+ .scenario_name, .example_rows {
53
+ margin-top: 0.2em;
54
+ margin-bottom: 0.2em;
55
+ background-color: #DBFFB4;
56
+ border-left: 0.5em solid #65c400;
57
+ border-bottom: 1px solid #65c400;
58
+ }
@@ -1,48 +1,33 @@
1
1
  # Copyright 2010 ThoughtWorks, Inc. Licensed under the MIT License
2
- require 'rubygems'
3
- require 'erb'
4
-
5
2
  module Cuporter
6
3
  module Formatter
7
4
  module TagReport
8
5
  class Html < Writer
9
6
  include HtmlMethods
10
7
 
8
+ def report_node_writer
9
+ Cuporter::Formatter::TagReport::HtmlNodeWriter
10
+ end
11
+
11
12
  def title
12
13
  "Cucumber Tags"
13
14
  end
14
15
 
15
- RHTML = %{
16
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
17
- <html xmlns="http://www.w3.org/1999/xhtml">
18
- <head>
19
- <title><%= title %></title>
20
- <style type="text/css">
21
- <%= inline_style%>
22
- </style>
23
- <script type="text/javascript">
24
- <%= inline_jquery%>
25
- <%= inline_js_content%>
26
- </script>
27
- </head>
28
- <body class="tag_report">
29
- <div class="cuporter_header">
30
- <div id="label">
31
- <h1><%= title %></h1>
32
- </div>
33
- <div id="expand-collapse">
34
- <p id="expand_tags">Expand Tags</p>
35
- <p id="expand_all">Expand All</p>
36
- <p id="collapser">Collapse All</p>
37
- </div>
38
- </div>
39
- <ul class="tag_list">
40
- <%= Cuporter::Formatter::TagReport::HtmlNodeWriter.new.write_nodes(@report)%>
41
- </ul>
42
- </body>
43
- </html>
44
- }
16
+ def inline_style
17
+ "tag_report/style.css"
18
+ end
19
+
20
+ def header(body)
21
+ body.div(:class => :cuporter_header) do |header|
22
+ label(header)
45
23
 
24
+ body.div(:id => "expand-collapse") do |div|
25
+ div.p("Expand Tags", :id => :expand_tags)
26
+ div.p("Expand All", :id => :expand_all)
27
+ div.p("Collapse All", :id => :collapser)
28
+ end
29
+ end
30
+ end
46
31
 
47
32
  end
48
33
  end
@@ -5,8 +5,8 @@ module Cuporter
5
5
  module TagReport
6
6
  class HtmlNodeWriter < Cuporter::Formatter::HtmlNodeWriter
7
7
 
8
- def write_nodes(report)
9
- report.report_node.children.each do |tag_node|
8
+ def write_report_node
9
+ @report.report_node.children.each do |tag_node|
10
10
  tag_node.number_all_descendants
11
11
  write_node(tag_node)
12
12
  end
@@ -0,0 +1,78 @@
1
+ /* Tag Report */
2
+ .number {
3
+ left: 4.5em;
4
+ }
5
+
6
+ #expand-collapse {
7
+ position: absolute;
8
+ right: 1em;
9
+ text-align: right;
10
+ top: 0.5em;
11
+ }
12
+
13
+ .cuporter_header {
14
+ background-color: #24A6C1;
15
+ }
16
+
17
+ .tag_name {
18
+ font-weight: bold;
19
+ font-size: 1.5em;
20
+ }
21
+ .total {
22
+ margin-left: 0.5em;
23
+ font-weight: normal;
24
+ font-size: 0.8em;
25
+ }
26
+
27
+ .tag {
28
+ margin-top: 0.5em;
29
+ margin-bottom: 0.5em;
30
+ }
31
+
32
+ .tag ul {
33
+ margin-top: 1.0em;
34
+ margin-bottom: 0.5em;
35
+ }
36
+ .feature_name {
37
+ margin-left: -2em;
38
+ padding-left: 1.5em;
39
+ background-color: #24A6C1;
40
+ color: white;
41
+ }
42
+
43
+ .file {
44
+ font-size: 1.1em;
45
+ }
46
+
47
+ .scenario_name {
48
+ margin-left: -4.0em;
49
+ padding-left: 4.0em;
50
+ background-color: lightblue;
51
+ }
52
+
53
+ .scenario_outline_name {
54
+ margin-left: -4.0em;
55
+ padding-left: 4.5em;
56
+ }
57
+
58
+ .example_rows {
59
+ margin-left: -7.7em;
60
+ padding-left: 7.7em;
61
+ background-color: lightblue;
62
+ }
63
+
64
+ .example {
65
+ background-color: #26A6C0;
66
+ }
67
+
68
+ .example_set_name {
69
+ margin-left: -2em;
70
+ }
71
+
72
+ .scenario_name, .example_rows {
73
+ margin-top: 0.2em;
74
+ margin-bottom: 0.2em;
75
+ background-color: #lightblue;
76
+ border-left: 0.5em solid #26A6C0;
77
+ border-bottom: 1px solid #26A6C0;
78
+ }
@@ -0,0 +1,44 @@
1
+ # Copyright 2010 ThoughtWorks, Inc. Licensed under the MIT License
2
+
3
+ module Cuporter
4
+ class NameListParser < FeatureParser
5
+
6
+ # ++sub_expression++ is the paren group in the regex, dereferenced with $1 in the caller
7
+ def new_feature_node(sub_expression)
8
+ TagListNode.new(sub_expression, @current_tags, @filter)
9
+ end
10
+
11
+ def handle_scenario_line(sub_expression)
12
+ @feature.filter_child(Node.new(sub_expression), @current_tags)
13
+ end
14
+
15
+ def new_scenario_outline_node(sub_expression)
16
+ TagListNode.new(sub_expression, @current_tags, @filter)
17
+ end
18
+
19
+ def handle_example_set_line
20
+ @scenario_outline.filter_child(@example_set, @example_set.tags)
21
+ end
22
+
23
+ def new_example_set_node(sub_expression)
24
+ ExampleSetNode.new(sub_expression, @feature.tags | @current_tags, @filter)
25
+ end
26
+
27
+ def close_scenario_outline
28
+ if @scenario_outline
29
+ if @example_set
30
+ @scenario_outline.filter_child(@example_set, @example_set.tags) if @example_set
31
+ @example_set = nil
32
+ end
33
+ @feature.add_child(@scenario_outline) if @scenario_outline.has_children?
34
+ @scenario_outline = nil
35
+ end
36
+ end
37
+
38
+ def initialize(file, filter)
39
+ super(file)
40
+ @filter = filter
41
+ end
42
+
43
+ end
44
+ end
data/lib/cuporter/node.rb CHANGED
@@ -48,9 +48,13 @@ module Cuporter
48
48
  children.sort!
49
49
  end
50
50
 
51
- # sort on name or substring of name after any ':'
51
+ # sort on: file path, name, substring of name after any ':'
52
52
  def <=>(other)
53
- name_without_title <=> other.name_without_title
53
+ if file
54
+ file <=> other.file
55
+ else
56
+ name_without_title <=> other.name_without_title
57
+ end
54
58
  end
55
59
 
56
60
  # value equivalence
@@ -0,0 +1,39 @@
1
+ # Copyright 2010 ThoughtWorks, Inc. Licensed under the MIT License
2
+
3
+ module Cuporter
4
+ class TagListParser < FeatureParser
5
+
6
+ # ++sub_expression++ is the paren group in the regex, dereferenced with $1 in the caller
7
+ def new_feature_node(sub_expression)
8
+ TagListNode.new(sub_expression, @current_tags)
9
+ end
10
+
11
+ def handle_scenario_line(sub_expression)
12
+ @feature.add_to_tag_nodes(TagListNode.new(sub_expression, @current_tags))
13
+ end
14
+
15
+ def new_scenario_outline_node(sub_expression)
16
+ TagListNode.new(sub_expression, @current_tags)
17
+ end
18
+
19
+ def handle_example_set_line
20
+ @scenario_outline.add_to_tag_nodes(@example_set)
21
+ end
22
+
23
+ def new_example_set_node(sub_expression)
24
+ ExampleSetNode.new(sub_expression, @feature.tags | @current_tags)
25
+ end
26
+
27
+ def close_scenario_outline
28
+ if @scenario_outline
29
+ if @example_set
30
+ @scenario_outline.add_to_tag_nodes(@example_set) if @example_set
31
+ @example_set = nil
32
+ end
33
+ @feature.merge_tag_nodes(@scenario_outline)
34
+ @scenario_outline = nil
35
+ end
36
+ end
37
+
38
+ end
39
+ end
data/lib/cuporter.rb CHANGED
@@ -1,12 +1,12 @@
1
1
  # Copyright 2010 ThoughtWorks, Inc. Licensed under the MIT License
2
2
  require 'cuporter/node'
3
3
  require 'cuporter/filter'
4
- require 'cuporter/tag_list'
5
- require 'cuporter/name_list'
6
4
  require 'cuporter/tag_list_node'
7
5
  require 'cuporter/example_set_node'
8
6
  require 'cuporter/node_numberer'
9
7
  require 'cuporter/feature_parser'
8
+ require 'cuporter/tag_list_parser'
9
+ require 'cuporter/name_list_parser'
10
10
  require 'cuporter/extensions/string'
11
11
  require 'cuporter/cli/options'
12
12
  require 'cuporter/cli/filter_args_builder'
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cuporter
3
3
  version: !ruby/object:Gem::Version
4
- hash: 5
4
+ hash: 19
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
- - 2
9
- - 9
10
- version: 0.2.9
8
+ - 3
9
+ - 0
10
+ version: 0.3.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Tim Camper
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-09-28 00:00:00 -04:00
18
+ date: 2010-10-04 00:00:00 -04:00
19
19
  default_executable: cuporter
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -47,7 +47,7 @@ files:
47
47
  - LICENSE
48
48
  - README.textile
49
49
  - Rakefile
50
- - lib/cuporter/name_list.rb
50
+ - lib/cuporter/tag_list_parser.rb
51
51
  - lib/cuporter/example_set_node.rb
52
52
  - lib/cuporter/formatter/tag_report/csv.rb
53
53
  - lib/cuporter/formatter/tag_report/text_node_writer.rb
@@ -65,7 +65,6 @@ files:
65
65
  - lib/cuporter/formatter/name_report/text.rb
66
66
  - lib/cuporter/formatter/name_report/html_node_writer.rb
67
67
  - lib/cuporter/formatter/name_report/html.rb
68
- - lib/cuporter/tag_list.rb
69
68
  - lib/cuporter/report/report.rb
70
69
  - lib/cuporter/report/name_report.rb
71
70
  - lib/cuporter/report/tag_report.rb
@@ -75,9 +74,12 @@ files:
75
74
  - lib/cuporter/extensions/string.rb
76
75
  - lib/cuporter/feature_parser.rb
77
76
  - lib/cuporter/node.rb
77
+ - lib/cuporter/name_list_parser.rb
78
78
  - lib/cuporter/filter.rb
79
79
  - lib/cuporter/node_numberer.rb
80
80
  - lib/cuporter.rb
81
+ - lib/cuporter/formatter/tag_report/style.css
82
+ - lib/cuporter/formatter/name_report/style.css
81
83
  - lib/cuporter/formatter/cuporter.css
82
84
  - lib/cuporter/formatter/jquery-min.js
83
85
  - bin/cuporter
@@ -1,65 +0,0 @@
1
- # Copyright 2010 ThoughtWorks, Inc. Licensed under the MIT License
2
-
3
- module Cuporter
4
- class NameList
5
-
6
- def initialize(file, filter)
7
- @file = file
8
- @current_tags = []
9
- @filter = filter
10
- end
11
-
12
- def parse_feature
13
- lines = File.read(@file).split(/\n/)
14
-
15
- lines.each do |line|
16
- case line
17
- when FeatureParser::TAG_LINE
18
- # may be more than one tag line
19
- @current_tags |= $1.strip.split(/\s+/)
20
- when FeatureParser::FEATURE_LINE
21
- @feature = TagListNode.new($1, @current_tags, @filter)
22
- @feature.file = @file.sub(/^.*features\//,"features/")
23
- @current_tags = []
24
- when FeatureParser::SCENARIO_LINE
25
- # How do we know when we have read all the lines from a "Scenario Outline:"?
26
- # One way is when we encounter a "Scenario:"
27
- close_scenario_outline
28
-
29
- @feature.filter_child(Node.new($1), @current_tags)
30
- @current_tags = []
31
- when FeatureParser::SCENARIO_OUTLINE_LINE
32
- # ... another is when we hit a subsequent "Scenario Outline:"
33
- close_scenario_outline
34
-
35
- @scenario_outline = TagListNode.new($1, @current_tags, @filter)
36
- @current_tags = []
37
- when FeatureParser::EXAMPLE_SET_LINE, FeatureParser::SCENARIO_SET_LINE
38
- @scenario_outline.filter_child(@example_set, @example_set.tags) if @example_set
39
-
40
- @example_set = ExampleSetNode.new($1, @feature.tags | @current_tags, @filter)
41
- @current_tags = []
42
- when @example_set && FeatureParser::EXAMPLE_LINE
43
- @example_set.add_child(Node.new($1))
44
- end
45
- end
46
-
47
- # EOF is the final way that we know we are finished with a "Scenario Outline"
48
- close_scenario_outline
49
- return @feature
50
- end
51
-
52
- def close_scenario_outline
53
- if @scenario_outline
54
- if @example_set
55
- @scenario_outline.filter_child(@example_set, @example_set.tags) if @example_set
56
- @example_set = nil
57
- end
58
- @feature.add_child(@scenario_outline) if @scenario_outline.has_children?
59
- @scenario_outline = nil
60
- end
61
- end
62
-
63
- end
64
-
65
- end
@@ -1,64 +0,0 @@
1
- # Copyright 2010 ThoughtWorks, Inc. Licensed under the MIT License
2
-
3
- module Cuporter
4
- class TagList
5
-
6
- def initialize(file)
7
- @file = file
8
- @current_tags = []
9
- end
10
-
11
- def parse_feature
12
- lines = File.read(@file).split(/\n/)
13
-
14
- lines.each do |line|
15
- case line
16
- when FeatureParser::TAG_LINE
17
- # may be more than one tag line
18
- @current_tags |= $1.strip.split(/\s+/)
19
- when FeatureParser::FEATURE_LINE
20
- @feature = TagListNode.new($1, @current_tags)
21
- @feature.file = @file.sub(/^.*features\//,"features/")
22
- @current_tags = []
23
- when FeatureParser::SCENARIO_LINE
24
- # How do we know when we have read all the lines from a "Scenario Outline:"?
25
- # One way is when we encounter a "Scenario:"
26
- close_scenario_outline
27
-
28
- @feature.add_to_tag_nodes(TagListNode.new($1, @current_tags))
29
- @current_tags = []
30
- when FeatureParser::SCENARIO_OUTLINE_LINE
31
- # ... another is when we hit a subsequent "Scenario Outline:"
32
- close_scenario_outline
33
-
34
- @scenario_outline = TagListNode.new($1, @current_tags)
35
- @current_tags = []
36
- when FeatureParser::EXAMPLE_SET_LINE, FeatureParser::SCENARIO_SET_LINE
37
- @scenario_outline.add_to_tag_nodes(@example_set) if @example_set
38
-
39
- @example_set = ExampleSetNode.new($1, @feature.tags | @current_tags)
40
- @current_tags = []
41
- when @example_set && FeatureParser::EXAMPLE_LINE
42
- @example_set.add_child(Node.new($1))
43
- end
44
- end
45
-
46
- # EOF is the final way that we know we are finished with a "Scenario Outline"
47
- close_scenario_outline
48
- return @feature
49
- end
50
-
51
- def close_scenario_outline
52
- if @scenario_outline
53
- if @example_set
54
- @scenario_outline.add_to_tag_nodes(@example_set) if @example_set
55
- @example_set = nil
56
- end
57
- @feature.merge_tag_nodes(@scenario_outline)
58
- @scenario_outline = nil
59
- end
60
- end
61
-
62
- end
63
-
64
- end