stepdown-patched 0.6.3.1patched

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. data/.bundle/config +1 -0
  2. data/.gitignore +7 -0
  3. data/.rspec +1 -0
  4. data/Gemfile +12 -0
  5. data/Gemfile.lock +31 -0
  6. data/History.txt +50 -0
  7. data/README.rdoc +28 -0
  8. data/Rakefile +14 -0
  9. data/bin/stepdown +23 -0
  10. data/lib/stepdown/analyzer.rb +74 -0
  11. data/lib/stepdown/feature_parser.rb +60 -0
  12. data/lib/stepdown/graph.rb +75 -0
  13. data/lib/stepdown/html_reporter.rb +37 -0
  14. data/lib/stepdown/options.rb +68 -0
  15. data/lib/stepdown/reporter.rb +23 -0
  16. data/lib/stepdown/scenario.rb +26 -0
  17. data/lib/stepdown/statistics.rb +162 -0
  18. data/lib/stepdown/step.rb +22 -0
  19. data/lib/stepdown/step_collection.rb +36 -0
  20. data/lib/stepdown/step_group.rb +45 -0
  21. data/lib/stepdown/step_instance.rb +63 -0
  22. data/lib/stepdown/step_usage.rb +15 -0
  23. data/lib/stepdown/text_reporter.rb +39 -0
  24. data/lib/stepdown/version.rb +3 -0
  25. data/lib/stepdown/yaml_writer.rb +14 -0
  26. data/lib/stepdown.rb +17 -0
  27. data/public/bluff-min.js +1 -0
  28. data/public/excanvas.js +35 -0
  29. data/public/jquery-1.6.1.min.js +18 -0
  30. data/public/js-class.js +1 -0
  31. data/public/step_down.js +41 -0
  32. data/public/stepdown.css +24 -0
  33. data/spec/fixtures/20110611.yml +5 -0
  34. data/spec/fixtures/20110612.yml +5 -0
  35. data/spec/lib/stepdown/analyzer_spec.rb +70 -0
  36. data/spec/lib/stepdown/feature_parser_spec.rb +93 -0
  37. data/spec/lib/stepdown/graph_spec.rb +82 -0
  38. data/spec/lib/stepdown/options_spec.rb +98 -0
  39. data/spec/lib/stepdown/scenario_spec.rb +40 -0
  40. data/spec/lib/stepdown/statistics_spec.rb +239 -0
  41. data/spec/lib/stepdown/step_collection_spec.rb +78 -0
  42. data/spec/lib/stepdown/step_group_spec.rb +43 -0
  43. data/spec/lib/stepdown/step_instance_spec.rb +85 -0
  44. data/spec/spec_helper.rb +4 -0
  45. data/stepdown.gemspec +30 -0
  46. data/templates/_empty.html.erb +5 -0
  47. data/templates/_grouping.html.erb +31 -0
  48. data/templates/_unused.html.erb +5 -0
  49. data/templates/_usages.html.erb +8 -0
  50. data/templates/index.html.erb +218 -0
  51. data/templates/style.sass +25 -0
  52. metadata +183 -0
data/.bundle/config ADDED
@@ -0,0 +1 @@
1
+ --- {}
data/.gitignore ADDED
@@ -0,0 +1,7 @@
1
+ .idea/
2
+ .sass-cache
3
+ *.html
4
+ *.rbc
5
+ *.gem
6
+ .rvmrc
7
+ *.swp
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/Gemfile ADDED
@@ -0,0 +1,12 @@
1
+ source 'http://rubygems.org'
2
+
3
+ gem 'gherkin', '> 2.3'
4
+ gem 'bundler', '> 1.0'
5
+
6
+ group :development,:test do
7
+ gem 'rake'
8
+ gem 'rspec', '~> 2.5.0'
9
+ gem 'rcov', '~> 0.9.9'
10
+ gem 'sass', '~> 3.1.0'
11
+ gem 'haml', '~> 3.1.3'
12
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,31 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ diff-lcs (1.1.2)
5
+ gherkin (2.4.6)
6
+ json (>= 1.4.6)
7
+ haml (3.1.3)
8
+ json (1.5.3)
9
+ rake (0.9.2)
10
+ rcov (0.9.10)
11
+ rspec (2.5.0)
12
+ rspec-core (~> 2.5.0)
13
+ rspec-expectations (~> 2.5.0)
14
+ rspec-mocks (~> 2.5.0)
15
+ rspec-core (2.5.2)
16
+ rspec-expectations (2.5.0)
17
+ diff-lcs (~> 1.1.2)
18
+ rspec-mocks (2.5.0)
19
+ sass (3.1.7)
20
+
21
+ PLATFORMS
22
+ ruby
23
+
24
+ DEPENDENCIES
25
+ bundler (> 1.0)
26
+ gherkin (> 2.3)
27
+ haml
28
+ rake
29
+ rcov (~> 0.9.9)
30
+ rspec (~> 2.5.0)
31
+ sass (~> 3.1.0)
data/History.txt ADDED
@@ -0,0 +1,50 @@
1
+ == 0.6.3 2011-08-16
2
+ * update dependant gems, be less restrictive on versions
3
+ * adjust statistics interface to improve metric_fu integration
4
+
5
+ == 0.6.2 2011-06-26
6
+ * Only show top 10 items on page load
7
+
8
+ == 0.6.1 2011-06-23
9
+ * fix issue with Ruby 1.9.2
10
+ * update jQuery
11
+
12
+ == 0.6.0 2011-6-6
13
+ * Graph for overall statistics
14
+
15
+ == 0.5.0 2011-5-17
16
+ * Use gherkin gem to parse features
17
+ * Added empty step detection
18
+ * Added unused step count to summary
19
+ * Added quiet option
20
+
21
+ == 0.4.0 2011-3-29
22
+ * Better HTML output
23
+ * Structured like other gems
24
+ * Maintainability improvements
25
+ * Better test coverage
26
+
27
+ == 0.3.3 2011-03-05
28
+ * Better HTML output
29
+
30
+ == 0.3.2 - 2011-02-27
31
+ * Bugfix in option parsing
32
+ * Bugfix for missing constants
33
+
34
+ == 0.3.1 - 2011-02-26
35
+ * Fix broken include [Robert Postill]
36
+
37
+ == 0.3.0 - 2011-02-26
38
+ * Added text report
39
+ * Bug fix for missing constants
40
+
41
+ == 0.2.1 - 2011-02-19
42
+ * Proper option parsing
43
+
44
+ == 0.2 - 2011-02-14
45
+ * Added some specs
46
+ * Improved output
47
+ * Updated usage message
48
+
49
+ == 0.1 - 2011-01-16
50
+ * Initial release
data/README.rdoc ADDED
@@ -0,0 +1,28 @@
1
+ = Stepdown
2
+ Stepdown allows you to see where your most used Cucumber steps are, your unused steps and how they are clustered
3
+
4
+ == Statistics available
5
+ * Total number of scenarios
6
+ * Total number of steps
7
+ * Number of empty scenarios (scenarios without any steps)
8
+ * Number of steps per scenario
9
+ * Number of unique steps per scenario
10
+ * Per step
11
+ * Total usage
12
+ * Number of scenarios
13
+ * Usage per scenario
14
+ * Scenario grouping (number of times used with another step)
15
+
16
+ == Installation
17
+ Stepdown is available as a Ruby gem
18
+ gem install stepdown
19
+
20
+ Or, add the following to your Gemfile
21
+ gem 'stepdown'
22
+
23
+ == Usage
24
+ From the root folder of your project. This assumes step definitions are in PROJECT_ROOT/features/step_definitions and feature files are in PROJECT_ROOT/features
25
+ stepdown
26
+ Or, set the the directory parameters manually
27
+ stepdown --steps <step definition directory> --features <feature file directory>
28
+ e.g. stepdown --steps features/step_definitions --features features
data/Rakefile ADDED
@@ -0,0 +1,14 @@
1
+ require 'rspec/core/rake_task'
2
+ require 'bundler/gem_tasks'
3
+
4
+ RSpec::Core::RakeTask.new(:spec) do |t|
5
+ t.fail_on_error = false
6
+ end
7
+
8
+ RSpec::Core::RakeTask.new(:coverage) do |t|
9
+ t.fail_on_error = false
10
+ t.rcov_opts = %w{ --exclude gems\/,spec\/,features\/}
11
+ t.rcov = true
12
+ end
13
+
14
+ task :default => :spec
data/bin/stepdown ADDED
@@ -0,0 +1,23 @@
1
+ #!/usr/bin/env ruby
2
+ lib = File.expand_path('../lib/', __FILE__)
3
+ $:.unshift lib unless $:.include?(lib)
4
+
5
+ require 'stepdown/options'
6
+ require 'stepdown'
7
+
8
+ begin
9
+
10
+ options = Stepdown::Options.new
11
+ options.parse(ARGV)
12
+ options.validate
13
+
14
+ Stepdown.quiet = options.quiet
15
+ Stepdown.output_directory = options.output_directory
16
+
17
+ Stepdown::Analyzer.new(options.steps_dir, options.features_dir, options.reporter).analyse
18
+
19
+ rescue Interrupt => e
20
+ puts "Quiting..."
21
+ exit 1
22
+ end
23
+
@@ -0,0 +1,74 @@
1
+ require 'gherkin/parser/parser'
2
+
3
+ module Stepdown
4
+ class Analyzer
5
+ def initialize(steps_dir, feature_dir, reporter)
6
+ @feature_dir = feature_dir
7
+ @steps_dir = steps_dir
8
+ @reporter = reporter
9
+ end
10
+
11
+ def analyse
12
+ scenarios = collect_scenarios
13
+
14
+ stats = Statistics.new(scenarios, instance.step_collection)
15
+ stats.generate
16
+
17
+ reporter = reporter(@reporter, stats)
18
+ reporter.output_overview
19
+
20
+ Stepdown::YamlWriter.write(stats)
21
+ Stepdown::Graph.create_graph
22
+ end
23
+
24
+ def collect_scenarios
25
+ puts "Parsing feature files..." unless Stepdown.quiet
26
+ process_feature_files(feature_files)
27
+ end
28
+
29
+ def process_feature_files(feature_files)
30
+ listener = Stepdown::FeatureParser.new(instance)
31
+
32
+ parser = Gherkin::Parser::Parser.new(listener, true, 'root')
33
+
34
+ feature_files.each do |feature_file|
35
+ parser.parse(File.read(feature_file), feature_file, 0)
36
+ end
37
+ listener.scenarios
38
+ end
39
+
40
+ def reporter(type, stats)
41
+ case type
42
+ when "html"
43
+ Stepdown::HTMLReporter.new(stats)
44
+ when "text"
45
+ Stepdown::TextReporter.new(stats)
46
+ when "quiet"
47
+ Stepdown::Reporter.new(stats)
48
+ end
49
+ end
50
+
51
+
52
+ def instance
53
+ @instance ||= begin
54
+ new_inst = Stepdown::StepInstance.new
55
+
56
+ Dir.glob(step_files).each do |file_name|
57
+ new_inst.instance_eval File.read(file_name)
58
+ end
59
+ new_inst
60
+ end
61
+ end
62
+
63
+ private
64
+ def feature_files
65
+ return @feature_files if @feature_files
66
+ @feature_files = Dir.glob(@feature_dir + '/**/*.feature')
67
+ end
68
+
69
+ def step_files
70
+ return @step_files if @step_files
71
+ @step_files = Dir.glob(@steps_dir + '/**/*.rb')
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,60 @@
1
+ require 'stepdown/step'
2
+ require 'stepdown/scenario'
3
+ module Stepdown
4
+ class FeatureParser
5
+
6
+ def initialize(instance)
7
+ @instance = instance
8
+ @scenarios = []
9
+ end
10
+
11
+ def scenarios
12
+ unless @scenarios.last == @current_scenario
13
+ @scenarios << @current_scenario
14
+ end
15
+ @scenarios.compact
16
+ end
17
+
18
+ def background(background)
19
+ @scenarios << @current_scenario
20
+ @current_scenario = Scenario.new(background.name)
21
+ end
22
+
23
+ def scenario(scenario)
24
+ @scenarios << @current_scenario
25
+ @current_scenario = Scenario.new(scenario.name)
26
+ end
27
+
28
+ def scenario_outline(scenario_outline)
29
+ @scenarios << @current_scenario
30
+ @current_scenario = Scenario.new(scenario_outline.name)
31
+ end
32
+
33
+ def step(step)
34
+ matched_step = @instance.line_matches(step.name)
35
+ @current_scenario.add_step(matched_step) if matched_step
36
+ end
37
+
38
+ def uri(*args) end
39
+
40
+ def feature(*args) end
41
+
42
+ def examples(*args) end
43
+
44
+ def comment(*args) end
45
+
46
+ def tag(*args) end
47
+
48
+ def table(*args) end
49
+
50
+ def py_string(*args) end
51
+
52
+ def eof(*args) end
53
+
54
+ def syntax_error(*args)
55
+ # raise "SYNTAX ERROR"
56
+ end
57
+
58
+ end
59
+ end
60
+
@@ -0,0 +1,75 @@
1
+ require 'json'
2
+ require 'date'
3
+ module Stepdown
4
+ class Graph
5
+ BLUFF_GRAPH_SIZE = "890x400"
6
+ BLUFF_DEFAULT_OPTIONS = <<-EOS
7
+ var g = new Bluff.Line('graph', "#{BLUFF_GRAPH_SIZE}");
8
+ g.theme_37signals();
9
+ g.tooltips = true;
10
+ g.title_font_size = "24px"
11
+ g.legend_font_size = "12px"
12
+ g.marker_font_size = "10px"
13
+ EOS
14
+
15
+ def self.create_graph
16
+ stats, labels = collect_stats
17
+ label_set = {}
18
+ labels.each_with_index do |label, i|
19
+ label_set.update({i => label})
20
+ end
21
+
22
+ content = <<-EOS
23
+ #{BLUFF_DEFAULT_OPTIONS}
24
+ g.title = 'Stepdown';
25
+ g.data('Total scenarios', [#{stats[:number_scenarios].join(',')}]);
26
+ g.data('Total steps', [#{stats[:total_steps].join(',')}]);
27
+ g.data('Total steps per scenario', [#{stats[:steps_per_scenario].join(',')}]);
28
+ g.data('Total unused steps', [#{stats[:unused_steps].join(',')}]);
29
+ g.labels = #{label_set.to_json};
30
+ g.draw();
31
+ EOS
32
+
33
+ File.open(File.join(Stepdown.output_directory, 'stepdown.js'), 'w') do
34
+ |f| f << content
35
+ end
36
+ end
37
+
38
+ def self.collect_stats
39
+ stats = Hash.new {|hsh, key| hsh[key] = [] }
40
+ labels = []
41
+
42
+ load_stats.each do |stat_set|
43
+ stat_set.each{|key, val| stats[key].push val }
44
+ labels.push(stat_set[:label])
45
+ end
46
+
47
+ [stats, labels]
48
+ end
49
+
50
+ def self.load_stats
51
+ stat_collection = []
52
+ Dir.glob("#{Stepdown.output_directory}/*.yml").sort.each do |file_name|
53
+ stats = Hash.new {|hsh, key| hsh[key] = [] }
54
+ file = File.open(file_name)
55
+ stat_set = YAML::load(file)
56
+
57
+ stat_set.each do |key, val|
58
+ stats[key].push(val)
59
+ end
60
+ stats[:label] = date_from_file_name(file_name)
61
+ stat_collection << stats
62
+
63
+ file.close
64
+ end
65
+
66
+ stat_collection
67
+ end
68
+
69
+ def self.date_from_file_name(file_name)
70
+ label_date = Date.strptime(file_name.match(/(\d+)/)[1], "%Y%m%d")
71
+ "#{label_date.day} / #{label_date.month}"
72
+ end
73
+
74
+ end
75
+ end
@@ -0,0 +1,37 @@
1
+ require 'fileutils'
2
+ require 'stepdown/reporter'
3
+ require 'haml'
4
+
5
+ module Stepdown
6
+ class HTMLReporter < Reporter
7
+
8
+ def output_overview()
9
+ puts "Generating report..." unless Stepdown.quiet
10
+ FileUtils.mkdir_p(Stepdown.output_directory)
11
+ copy_files()
12
+
13
+ ["index", "_empty", "_unused", "_grouping", "_usages"].each { |template| write_html_from_erb(template) }
14
+
15
+ puts "\nReport output to #{Stepdown.output_directory}/index.html" unless Stepdown.quiet
16
+ end
17
+
18
+ protected
19
+
20
+ def write_html_from_erb(template)
21
+ file = File.open(File.expand_path(File.dirname(__FILE__)) + "/../../templates/#{template}.html.erb")
22
+ erb = ERB.new(file.read())
23
+
24
+ file.close
25
+ out = File.new(Stepdown.output_directory + "/#{template}.html",'w+')
26
+ out.puts erb.result(binding())
27
+ out.close
28
+ end
29
+
30
+ def copy_files
31
+ ['step_down.js', 'jquery-1.6.1.min.js', 'bluff-min.js', 'excanvas.js', 'js-class.js', 'stepdown.css'].each do |file|
32
+ src = File.expand_path("#{File.dirname(__FILE__)}/../../public/#{file}")
33
+ FileUtils.cp(src, File.join(Stepdown.output_directory, "#{file}"))
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,68 @@
1
+ require 'optparse'
2
+
3
+ module Stepdown
4
+ class Options
5
+ attr_reader :steps_dir, :features_dir, :reporter, :quiet, :output_directory
6
+
7
+ OUTPUT_FORMATS = ["html", "text", "quiet"]
8
+
9
+ def parse(params)
10
+ @steps_dir = "features/step_definitions"
11
+ @features_dir = "features"
12
+ @reporter = "html"
13
+ @quiet = false
14
+ @output_directory = "./stepdown"
15
+ parser = OptionParser.new do |opts|
16
+ opts.banner = <<-USE
17
+ Usage: stepdown
18
+ stepdown --steps <STEP_DEFINITION_DIRECTORY> --features <FEATURE_FILE_DIRECTORY>
19
+ USE
20
+
21
+ opts.separator("")
22
+
23
+ opts.on("--output=TYPE", OUTPUT_FORMATS, "Select ouput format (#{OUTPUT_FORMATS.join(',')}). Default: html") do |o|
24
+ @reporter = o
25
+ end
26
+
27
+ opts.on("--steps=STEPS_DIR", "Step definition directory. Default: ./features/step_definitions") do |o|
28
+ @steps_dir = o
29
+ end
30
+
31
+ opts.on("--features=FEATURE_DIR", "Feature file directory. Default: ./features") do |o|
32
+ @features_dir = o
33
+ end
34
+
35
+ opts.on("--quiet", "-q", "Supress output") do |o|
36
+ @quiet = true
37
+ end
38
+
39
+ opts.on_tail("-h", "--help", "You're looking at it") do |o|
40
+ puts opts
41
+ exit
42
+ end
43
+
44
+ end
45
+
46
+ begin
47
+ parser.parse(params)
48
+
49
+ rescue OptionParser::ParseError => e
50
+ puts e
51
+ exit 1
52
+ end
53
+ end
54
+
55
+ def validate(io = STDOUT)
56
+ @steps_dir = File.join(Dir.pwd, @steps_dir)
57
+ @features_dir = File.join(Dir.pwd, @features_dir)
58
+
59
+ [@steps_dir, @features_dir].each do |dir|
60
+ unless File.exists?(dir)
61
+ io.puts "Directory #{dir} does not exist"
62
+ exit 1
63
+ end
64
+ end
65
+
66
+ end
67
+ end
68
+ end