stepdown 0.2.1 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/bin/stepdown +1 -1
- data/lib/html_reporter.rb +9 -61
- data/lib/options.rb +13 -1
- data/lib/reporter.rb +62 -0
- data/lib/step_down.rb +17 -2
- data/lib/step_instance.rb +5 -1
- data/lib/text_reporter.rb +36 -0
- data/spec/lib/step_instance_spec.rb +26 -0
- data/stepdown.gemspec +4 -4
- metadata +11 -8
data/.gitignore
CHANGED
data/bin/stepdown
CHANGED
data/lib/html_reporter.rb
CHANGED
@@ -1,61 +1,28 @@
|
|
1
1
|
require 'fileutils'
|
2
|
-
|
3
|
-
|
4
|
-
attr_reader :scenarios, :usages, :steps, :grouping
|
5
|
-
|
6
|
-
def initialize(scenarios, usages, grouping, steps)
|
7
|
-
@scenarios = scenarios
|
8
|
-
@usages = usages
|
9
|
-
@steps = steps
|
10
|
-
@grouping = grouping
|
11
|
-
end
|
12
|
-
|
13
|
-
def groupings
|
14
|
-
@grouping
|
15
|
-
end
|
16
|
-
|
17
|
-
def total_scenarios
|
18
|
-
@scenarios.length
|
19
|
-
end
|
20
|
-
|
21
|
-
def total_steps
|
22
|
-
@steps.length
|
23
|
-
end
|
24
|
-
|
25
|
-
def steps_per_scenario
|
26
|
-
steps_scenario(@scenarios)
|
27
|
-
end
|
28
|
-
|
29
|
-
def unique_steps
|
30
|
-
uniq_steps_per_scenario(@scenarios)
|
31
|
-
end
|
32
|
-
|
33
|
-
def usages
|
34
|
-
@usages.select{|use| use.total_usage > 0 }
|
35
|
-
end
|
36
|
-
|
37
|
-
def unused_steps
|
38
|
-
@usages.select{|use| use.total_usage == 0}
|
39
|
-
end
|
2
|
+
require 'reporter'
|
3
|
+
class HTMLReporter < Reporter
|
40
4
|
|
41
5
|
def output_overview()
|
42
|
-
|
6
|
+
puts "Generating report..."
|
7
|
+
FileUtils.mkdir_p(Reporter::OUTPUT_DIR)
|
43
8
|
copy_files
|
44
9
|
|
45
10
|
template = File.open(File.expand_path(File.dirname(__FILE__)) + '/../templates/main.html.haml').read()
|
46
11
|
engine = Haml::Engine.new(template)
|
47
12
|
|
48
|
-
out = File.new(OUTPUT_DIR + '/analysis.html','w+')
|
13
|
+
out = File.new(Reporter::OUTPUT_DIR + '/analysis.html','w+')
|
49
14
|
out.puts engine.render(self)
|
50
15
|
out.close
|
51
16
|
|
52
17
|
template = File.open(File.expand_path(File.dirname(__FILE__)) + '/../templates/style.sass').read
|
53
18
|
sass_engine = Sass::Engine.new(template)
|
54
19
|
|
55
|
-
out = File.new(OUTPUT_DIR + '/style.css', 'w+')
|
20
|
+
out = File.new(Reporter::OUTPUT_DIR + '/style.css', 'w+')
|
56
21
|
out.puts sass_engine.render
|
57
22
|
|
58
23
|
out.close
|
24
|
+
|
25
|
+
$stdout.puts "\nReport output to #{Reporter::OUTPUT_DIR}/analysis.html"
|
59
26
|
end
|
60
27
|
|
61
28
|
protected
|
@@ -67,23 +34,4 @@ class HTMLReporter
|
|
67
34
|
end
|
68
35
|
end
|
69
36
|
|
70
|
-
|
71
|
-
scen_count = scenarios.length
|
72
|
-
step_count = 0.0
|
73
|
-
scenarios.each do |scenario|
|
74
|
-
step_count += scenario.steps.length
|
75
|
-
end
|
76
|
-
step_count / scen_count
|
77
|
-
end
|
78
|
-
|
79
|
-
def uniq_steps_per_scenario(scenarios)
|
80
|
-
total_steps = 0.0
|
81
|
-
uniq_steps = 0.0
|
82
|
-
scenarios.each do |scen|
|
83
|
-
total_steps += scen.steps.length
|
84
|
-
uniq_steps += scen.uniq_steps.length
|
85
|
-
end
|
86
|
-
total_steps / uniq_steps
|
87
|
-
end
|
88
|
-
|
89
|
-
end
|
37
|
+
end
|
data/lib/options.rb
CHANGED
@@ -2,15 +2,23 @@ require 'optparse'
|
|
2
2
|
|
3
3
|
class Options
|
4
4
|
|
5
|
+
OUTPUT_FORMATS = ["html", "text"]
|
6
|
+
|
5
7
|
def self.parse(params)
|
6
8
|
@@steps_dir = "features/step_definitions"
|
7
9
|
@@features_dir = "features"
|
10
|
+
@@reporter = "html"
|
11
|
+
|
8
12
|
|
9
13
|
parser = OptionParser.new do |opts|
|
10
14
|
opts.banner = "Usage: stepdown step_definition_dir feature_file_directory"
|
11
15
|
|
12
16
|
opts.separator("")
|
13
17
|
|
18
|
+
opts.on("--output TYPE", OUTPUT_FORMATS, "Select ouput format (#{OUTPUT_FORMATS.join(',')})") do |o|
|
19
|
+
@@reporter = o
|
20
|
+
end
|
21
|
+
|
14
22
|
opts.on("--steps=directory", "Step definition directory") do |o|
|
15
23
|
@@steps_dir = o
|
16
24
|
end
|
@@ -61,4 +69,8 @@ class Options
|
|
61
69
|
@@features_dir
|
62
70
|
end
|
63
71
|
|
64
|
-
|
72
|
+
def self.reporter
|
73
|
+
@@reporter
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
data/lib/reporter.rb
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
|
2
|
+
class Reporter
|
3
|
+
OUTPUT_DIR = "./stepdown"
|
4
|
+
|
5
|
+
attr_reader :scenarios, :usages, :steps, :grouping
|
6
|
+
|
7
|
+
def initialize(scenarios, usages, grouping, steps)
|
8
|
+
@scenarios = scenarios
|
9
|
+
@usages = usages
|
10
|
+
@steps = steps
|
11
|
+
@grouping = grouping
|
12
|
+
end
|
13
|
+
|
14
|
+
def groupings
|
15
|
+
@grouping
|
16
|
+
end
|
17
|
+
|
18
|
+
def total_scenarios
|
19
|
+
@scenarios.length
|
20
|
+
end
|
21
|
+
|
22
|
+
def total_steps
|
23
|
+
@steps.length
|
24
|
+
end
|
25
|
+
|
26
|
+
def steps_per_scenario
|
27
|
+
steps_scenario(@scenarios)
|
28
|
+
end
|
29
|
+
|
30
|
+
def unique_steps
|
31
|
+
uniq_steps_per_scenario(@scenarios)
|
32
|
+
end
|
33
|
+
|
34
|
+
def usages
|
35
|
+
@usages.select{|use| use.total_usage > 0 }
|
36
|
+
end
|
37
|
+
|
38
|
+
def unused_steps
|
39
|
+
@usages.select{|use| use.total_usage == 0}
|
40
|
+
end
|
41
|
+
|
42
|
+
def uniq_steps_per_scenario(scenarios)
|
43
|
+
total_steps = 0.0
|
44
|
+
uniq_steps = 0.0
|
45
|
+
scenarios.each do |scen|
|
46
|
+
total_steps += scen.steps.length
|
47
|
+
uniq_steps += scen.uniq_steps.length
|
48
|
+
end
|
49
|
+
total_steps / uniq_steps
|
50
|
+
end
|
51
|
+
|
52
|
+
def steps_scenario(scenarios)
|
53
|
+
scen_count = scenarios.length
|
54
|
+
step_count = 0.0
|
55
|
+
scenarios.each do |scenario|
|
56
|
+
step_count += scenario.steps.length
|
57
|
+
end
|
58
|
+
step_count / scen_count
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
|
data/lib/step_down.rb
CHANGED
@@ -7,14 +7,18 @@ require 'step_instance'
|
|
7
7
|
require 'step_group'
|
8
8
|
require 'step_usage'
|
9
9
|
require 'html_reporter'
|
10
|
+
require 'yaml_reporter'
|
11
|
+
require 'text_reporter'
|
10
12
|
class StepDown
|
11
13
|
|
12
|
-
def initialize(steps_dir, feature_dir)
|
14
|
+
def initialize(steps_dir, feature_dir, reporter)
|
13
15
|
@feature_files = Dir.glob(feature_dir + '/**/*.feature')
|
14
16
|
@step_files = Dir.glob(steps_dir + '/**/*.rb')
|
17
|
+
@reporter = reporter
|
15
18
|
end
|
16
19
|
|
17
20
|
def analyse
|
21
|
+
puts "Parsing feature files..."
|
18
22
|
parser = FeatureParser.new
|
19
23
|
|
20
24
|
scenarios = []
|
@@ -23,17 +27,28 @@ class StepDown
|
|
23
27
|
end
|
24
28
|
scenarios.flatten!
|
25
29
|
|
30
|
+
puts "Performing analysis..."
|
26
31
|
usages = step_usage(scenarios)
|
27
32
|
usages = usages.sort{|a,b| b.total_usage <=> a.total_usage }
|
28
33
|
grouping = grouping(scenarios).sort{|a,b| b.use_count <=> a.use_count}
|
29
34
|
|
30
|
-
reporter =
|
35
|
+
reporter = reporter(@reporter, scenarios, usages, grouping, instance.steps)
|
31
36
|
reporter.output_overview
|
32
37
|
|
33
38
|
# #pp grouping(@scenarios)
|
34
39
|
# puts YAML::dump(scenario) if scenario.use_count > 100 && scenario.use_count < 500
|
35
40
|
# end
|
36
41
|
end
|
42
|
+
|
43
|
+
# don't want a factory just yet
|
44
|
+
def reporter(type, scenarios, usages, grouping, steps)
|
45
|
+
case type
|
46
|
+
when "html"
|
47
|
+
HTMLReporter.new(scenarios, usages, grouping, steps)
|
48
|
+
when "text"
|
49
|
+
TextReporter.new(scenarios, usages, grouping, steps)
|
50
|
+
end
|
51
|
+
end
|
37
52
|
|
38
53
|
def step_usage(scenarios)
|
39
54
|
usages = instance.steps.collect{|step| StepUsage.new(step) }
|
data/lib/step_instance.rb
CHANGED
@@ -22,6 +22,10 @@ class StepInstance
|
|
22
22
|
def method_missing(*args)
|
23
23
|
#nothing
|
24
24
|
end
|
25
|
+
|
26
|
+
def self.const_missing(*args)
|
27
|
+
#nothing
|
28
|
+
end
|
25
29
|
|
26
30
|
def require(*args)
|
27
31
|
# do nothing
|
@@ -49,4 +53,4 @@ class StepInstance
|
|
49
53
|
@step_definitions
|
50
54
|
end
|
51
55
|
|
52
|
-
end
|
56
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'reporter'
|
2
|
+
|
3
|
+
class TextReporter < Reporter
|
4
|
+
|
5
|
+
def output_overview
|
6
|
+
puts "Generating report..."
|
7
|
+
output = File.new(Reporter::OUTPUT_DIR + '/analysis.txt', "w+")
|
8
|
+
|
9
|
+
output.puts "Total number of scenarios: #{total_scenarios}"
|
10
|
+
output.puts "Total numer of steps: #{total_steps}"
|
11
|
+
output.puts "Steps per scenario: #{steps_per_scenario}"
|
12
|
+
output.puts "Unique steps per scenario: #{unique_steps}"
|
13
|
+
|
14
|
+
output.puts "Step usages"
|
15
|
+
usages.each{|use| output.puts used_step_line(use) }
|
16
|
+
|
17
|
+
output.puts "Unused steps"
|
18
|
+
unused_steps.each{|use| output.puts unused_step_line(use) }
|
19
|
+
|
20
|
+
output.close
|
21
|
+
|
22
|
+
puts "Report output to #{Reporter::OUTPUT_DIR}/analysis.txt"
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
def used_step_line(use)
|
27
|
+
line = [use.step.regex.inspect, use.total_usage, use.number_scenarios, use.use_scenario]
|
28
|
+
line.join("|")
|
29
|
+
end
|
30
|
+
|
31
|
+
def unused_step_line(use)
|
32
|
+
use.step.regex
|
33
|
+
end
|
34
|
+
|
35
|
+
|
36
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'rspec'
|
2
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../lib/step_instance')
|
3
|
+
|
4
|
+
|
5
|
+
describe StepInstance do
|
6
|
+
|
7
|
+
before :each do
|
8
|
+
@step_instance = StepInstance.new
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should deal with missing constants" do
|
12
|
+
lambda{ @step_instance.instance_eval("MissingConst") }.should_not raise_error
|
13
|
+
end
|
14
|
+
it "should deal with missing methods" do
|
15
|
+
lambda{ @step_instance.doesnt_exist }.should_not raise_error
|
16
|
+
end
|
17
|
+
|
18
|
+
describe "steps" do
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
describe "line matches" do
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
data/stepdown.gemspec
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
|
2
2
|
Gem::Specification.new do |s|
|
3
3
|
s.name = "stepdown"
|
4
|
-
s.version = "0.
|
4
|
+
s.version = "0.3.0"
|
5
5
|
s.platform = Gem::Platform::RUBY
|
6
6
|
s.authors = "Sean Caffery"
|
7
7
|
s.email = "sean@lineonpoint.com"
|
8
|
-
s.summary = "
|
9
|
-
s.homepage = "
|
10
|
-
s.description = "
|
8
|
+
s.summary = "Static analysis tool for Cucumber features"
|
9
|
+
s.homepage = "http://stepdown.lineonpoint.com"
|
10
|
+
s.description = "Stepdown allows you to see where your most used Cucumber steps are, your unused steps and how they are clustered"
|
11
11
|
|
12
12
|
s.required_rubygems_version = ">= 1.3.6"
|
13
13
|
s.rubyforge_project = "stepdown"
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: stepdown
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 19
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
-
|
10
|
-
version: 0.
|
8
|
+
- 3
|
9
|
+
- 0
|
10
|
+
version: 0.3.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Sean Caffery
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-02-
|
18
|
+
date: 2011-02-27 00:00:00 +11:00
|
19
19
|
default_executable: stepdown
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -50,7 +50,7 @@ dependencies:
|
|
50
50
|
version: 2.0.0
|
51
51
|
type: :development
|
52
52
|
version_requirements: *id002
|
53
|
-
description:
|
53
|
+
description: Stepdown allows you to see where your most used Cucumber steps are, your unused steps and how they are clustered
|
54
54
|
email: sean@lineonpoint.com
|
55
55
|
executables:
|
56
56
|
- stepdown
|
@@ -69,20 +69,23 @@ files:
|
|
69
69
|
- lib/feature_parser.rb
|
70
70
|
- lib/html_reporter.rb
|
71
71
|
- lib/options.rb
|
72
|
+
- lib/reporter.rb
|
72
73
|
- lib/scenario.rb
|
73
74
|
- lib/step.rb
|
74
75
|
- lib/step_down.rb
|
75
76
|
- lib/step_group.rb
|
76
77
|
- lib/step_instance.rb
|
77
78
|
- lib/step_usage.rb
|
79
|
+
- lib/text_reporter.rb
|
78
80
|
- public/jquery-1.4.3.min.js
|
79
81
|
- public/step_down.js
|
80
82
|
- spec/lib/step_group_spec.rb
|
83
|
+
- spec/lib/step_instance_spec.rb
|
81
84
|
- stepdown.gemspec
|
82
85
|
- templates/main.html.haml
|
83
86
|
- templates/style.sass
|
84
87
|
has_rdoc: true
|
85
|
-
homepage:
|
88
|
+
homepage: http://stepdown.lineonpoint.com
|
86
89
|
licenses: []
|
87
90
|
|
88
91
|
post_install_message:
|
@@ -116,6 +119,6 @@ rubyforge_project: stepdown
|
|
116
119
|
rubygems_version: 1.4.2
|
117
120
|
signing_key:
|
118
121
|
specification_version: 3
|
119
|
-
summary:
|
122
|
+
summary: Static analysis tool for Cucumber features
|
120
123
|
test_files: []
|
121
124
|
|