chartspec 0.0.5 → 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 24cfaa604d3d446a47b4caeae756627df553c10e
4
+ data.tar.gz: 835a894b657f9db5ce9e39c466861150abc9e871
5
+ SHA512:
6
+ metadata.gz: 50249f305f147233199cf313e441589b5ef62bece32812f879f481d932633a5cfc414e852b20f2f12cb789794f35ee7ff25553f98f7c85dd10da95e9964a9c7f
7
+ data.tar.gz: 3c79cce6185f90e84f55b1c6fde3d21ef9a22bc1a3838ebbb86bcc83fa3c924af804a58396b29ea41f7322cd47c38c7f4f02db8d9119594071a705c4851a4ab0
data/.gitignore CHANGED
@@ -1,16 +1,16 @@
1
- /.bundle/
2
- /.yardoc
3
- /Gemfile.lock
4
- /_yardoc/
5
- /coverage/
6
- /doc/
7
- /pkg/
8
- /spec/reports/
9
- /tmp/
10
- *.bundle
11
- *.so
12
- *.o
13
- *.a
14
- mkmf.log
15
- .project
16
- pkg
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
15
+ .project
16
+ pkg
data/Gemfile CHANGED
@@ -1,4 +1,4 @@
1
- source 'https://rubygems.org'
2
-
3
- # Specify your gem's dependencies in chartspec.gemspec
4
- gemspec
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in chartspec.gemspec
4
+ gemspec
@@ -1,22 +1,22 @@
1
- Copyright (c) 2014 AlexVangelov
2
-
3
- MIT License
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining
6
- a copy of this software and associated documentation files (the
7
- "Software"), to deal in the Software without restriction, including
8
- without limitation the rights to use, copy, modify, merge, publish,
9
- distribute, sublicense, and/or sell copies of the Software, and to
10
- permit persons to whom the Software is furnished to do so, subject to
11
- the following conditions:
12
-
13
- The above copyright notice and this permission notice shall be
14
- included in all copies or substantial portions of the Software.
15
-
16
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
- LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
- OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1
+ Copyright (c) 2014 AlexVangelov
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md CHANGED
@@ -1,31 +1,31 @@
1
- # Chartspec
2
-
3
- Generates HTML files with case execution time charts for recurrent RSpec tests
4
-
5
- ## Installation
6
-
7
- Add this line to your application's Gemfile:
8
-
9
- ```ruby
10
- gem 'chartspec'
11
- ```
12
-
13
- And then execute:
14
-
15
- $ bundle
16
-
17
- Or install it yourself as:
18
-
19
- $ gem install chartspec
20
-
21
- ## Usage
22
-
23
- TODO: Write usage instructions here
24
-
25
- ## Contributing
26
-
27
- 1. Fork it ( https://github.com/[my-github-username]/chartspec/fork )
28
- 2. Create your feature branch (`git checkout -b my-new-feature`)
29
- 3. Commit your changes (`git commit -am 'Add some feature'`)
30
- 4. Push to the branch (`git push origin my-new-feature`)
31
- 5. Create a new Pull Request
1
+ # Chartspec
2
+
3
+ Generates HTML files with case execution time charts for recurrent RSpec tests
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'chartspec'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install chartspec
20
+
21
+ ## Usage
22
+
23
+ TODO: Write usage instructions here
24
+
25
+ ## Contributing
26
+
27
+ 1. Fork it ( https://github.com/[my-github-username]/chartspec/fork )
28
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
29
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
30
+ 4. Push to the branch (`git push origin my-new-feature`)
31
+ 5. Create a new Pull Request
data/Rakefile CHANGED
@@ -1,2 +1,2 @@
1
- require "bundler/gem_tasks"
2
-
1
+ require "bundler/gem_tasks"
2
+
@@ -1,7 +1,7 @@
1
- #!/usr/bin/env ruby
2
-
3
- require 'rspec'
4
- require 'chartspec'
5
-
6
- #RSpec::Core::Runner::run ARGV + ["--format", "Chartspec::Formatter", "--out", ENV["CHARTSPEC_HTML"] || "tmp/chartspec.html"]
7
- RSpec::Core::Runner::run ARGV + ["--format", "Chartspec::Formatter"]
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rspec'
4
+ require 'chartspec'
5
+
6
+ code = RSpec::Core::Runner::run ARGV + ["--format", "Chartspec::Formatter", "--out", ENV["CHARTSPEC_HTML"] || "tmp/chartspec.html"]
7
+ exit(code) unless code == 0
@@ -1,28 +1,28 @@
1
- # coding: utf-8
2
- lib = File.expand_path('../lib', __FILE__)
3
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require 'chartspec/version'
5
-
6
- Gem::Specification.new do |spec|
7
- spec.name = "chartspec"
8
- spec.version = Chartspec::VERSION
9
- spec.authors = ["AlexVangelov"]
10
- spec.email = ["email@data.bg"]
11
- spec.summary = %q{RSpec with execution time history charts}
12
- spec.description = %q{Generates HTML files with case execution time charts for recurrent RSpec tests}
13
- spec.homepage = ""
14
- spec.license = "MIT"
15
-
16
- spec.files = `git ls-files -z`.split("\x0")
17
- spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
- spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
- spec.require_paths = ["lib"]
20
-
21
- spec.add_dependency 'rspec'
22
- spec.add_dependency 'sqlite3'
23
-
24
- spec.add_development_dependency "bundler", "~> 1.6"
25
- spec.add_development_dependency "rake", "~> 10.0"
26
-
27
- spec.executables << 'chartspec'
28
- end
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'chartspec/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "chartspec"
8
+ spec.version = Chartspec::VERSION
9
+ spec.authors = ["AlexVangelov"]
10
+ spec.email = ["email@data.bg"]
11
+ spec.summary = %q{RSpec with execution time history charts}
12
+ spec.description = %q{Generates HTML files with case execution time charts for recurrent RSpec tests}
13
+ spec.homepage = ""
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_dependency 'rspec'
22
+ spec.add_dependency 'sqlite3'
23
+
24
+ spec.add_development_dependency "bundler", "~> 1.6"
25
+ spec.add_development_dependency "rake", "~> 10.0"
26
+
27
+ spec.executables << 'chartspec'
28
+ end
@@ -0,0 +1,20 @@
1
+ Feature: Chartspec
2
+ @chart
3
+ Scenario: Chartspec passed feature
4
+ Given I have a feature
5
+ When I run the feature
6
+ And there is no errors
7
+ Then the feature should pass
8
+
9
+ Scenario: Chartspec pending feature
10
+ Given I have a feature
11
+ When I run the feature
12
+ And there is no defined steps
13
+ Then the feature should be pending
14
+
15
+ Scenario: Chartspec failed feature
16
+ Given I have a feature
17
+ When I run the feature
18
+ And there is an error
19
+ Then the feature should fail
20
+ And the backtrace should be visible
@@ -0,0 +1,11 @@
1
+ step "I have a feature" do; end
2
+
3
+ step "I run the feature" do; end
4
+
5
+ step "there is no errors" do; end
6
+
7
+ step "the feature should pass" do; end
8
+
9
+ step "there is an error" do
10
+ raise "there is an error"
11
+ end
@@ -1,4 +1,3 @@
1
- require "chartspec/version"
2
- require "chartspec/formatter"
3
-
4
-
1
+ require "chartspec/version"
2
+ require "chartspec/formatter"
3
+ requires"chartspec/ext/turnip/rspec" if defined? Turnip
@@ -1,29 +1,31 @@
1
- require 'sqlite3'
2
-
3
- module Chartspec
4
- class Db
5
- def initialize db = nil
6
- @db_file = db || "tmp/chartspec.sqlite3"
7
- db_dirname = File.dirname(@db_file)
8
- unless File.directory?(db_dirname)
9
- FileUtils.mkdir_p(db_dirname)
10
- end
11
- @db = SQLite3::Database.new @db_file
12
- @db.execute( "CREATE TABLE IF NOT EXISTS specs(id INTEGER PRIMARY KEY, file TEXT, name TEXT, duration NUMERIC, measured_at DATETIME);" )
13
- end
14
-
15
- def add(file, name, duration, measured_at = Time.now.to_i)
16
- @db.execute("INSERT INTO specs(file, name, duration, measured_at) VALUES (?, ?, ?, ?)", [
17
- file, name, duration, measured_at
18
- ])
19
- end
20
-
21
- def all
22
- @db.execute( "select file, name, duration, measured_at from specs where measured_at > ?", (Time.now - ((ENV['CHARTSPEC_HISTORY_HOURS'] || 2)*3600)).to_i)
23
- end
24
-
25
- def file_name
26
- @db_file
27
- end
28
- end
1
+ require 'sqlite3'
2
+
3
+ module Chartspec
4
+ class Db
5
+ def initialize db = nil
6
+ @db_file = db || "tmp/chartspec.sqlite3"
7
+ db_dirname = File.dirname(@db_file)
8
+ unless File.directory?(db_dirname)
9
+ FileUtils.mkdir_p(db_dirname)
10
+ end
11
+ @db = SQLite3::Database.new @db_file
12
+ @db.execute( "CREATE TABLE IF NOT EXISTS specs(id INTEGER PRIMARY KEY, file TEXT, chart TEXT, name TEXT, duration NUMERIC, measured_at DATETIME);" )
13
+ end
14
+
15
+ def add(file, chart, name, duration, measured_at = Time.now.to_i)
16
+ @db.execute("INSERT INTO specs(file, chart, name, duration, measured_at) VALUES (?, ?, ?, ?, ?)", [
17
+ file, chart.to_s, name, duration, measured_at
18
+ ])
19
+ end
20
+
21
+ def select_by_file_and_chart(file, chart)
22
+ @db.execute( "select name, duration, measured_at from specs where file = ? and chart = ? and measured_at > ?", [
23
+ file, chart.to_s, (Time.now - ((ENV['CHARTSPEC_HISTORY_HOURS'] || 8)*3600)).to_i
24
+ ])
25
+ end
26
+
27
+ def file_name
28
+ @db_file
29
+ end
30
+ end
29
31
  end
@@ -0,0 +1,37 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ require 'turnip/rspec'
4
+
5
+ module Turnip
6
+ module RSpec
7
+ class << self
8
+ alias_method :original_run, :run
9
+
10
+ def run(feature_file)
11
+ features = original_run(feature_file)
12
+ example_groups = ::RSpec.world.example_groups[-features.length..-1]
13
+
14
+ features.zip(example_groups).each do |feature, example_group|
15
+ update_metadata(feature, example_group)
16
+ end
17
+ end
18
+
19
+ #
20
+ # @param [Turnip::Builder::Feature] feature
21
+ # @param [RSpec::Core::ExampleGroup] example_group
22
+ #
23
+ def update_metadata(feature, example_group)
24
+ background_steps = feature.backgrounds.map(&:steps).flatten
25
+ examples = example_group.children
26
+
27
+ feature.scenarios.zip(examples).each do |scenario, parent_example|
28
+ example = parent_example.examples.first
29
+ steps = background_steps + scenario.steps
30
+ tags = (feature.tags + scenario.tags).uniq
31
+
32
+ example.metadata[:turnip] = { steps: steps, tags: tags }
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -1,140 +1,126 @@
1
- require "rspec"
2
- require "rspec/core/formatters/progress_formatter"
3
- require "chartspec/printer"
4
- require "chartspec/db"
5
- require 'json'
6
-
7
- module Chartspec
8
- class Formatter < RSpec::Core::Formatters::ProgressFormatter
9
- RSpec::Core::Formatters.register self, :start, :stop, :example_group_started, :start_dump, :example_started, :example_passed, :example_failed, :example_pending, :dump_profile
10
-
11
- def initialize(output)
12
- super output
13
- @failed_examples = []
14
- @current_file = {}
15
- @example_group_number = 0
16
- @example_number = 0
17
- @header_red = false
18
- @db = Db.new ENV["CHARTSPEC_DB"]
19
- #@printer = Printer.new output
20
- end
21
-
22
- def start(notification)
23
- super
24
- @output_hash = {}
25
- #@printer.print_html_start
26
- #@printer.flush
27
- end
28
-
29
- def stop(notification)
30
- @output_hash[:examples] = notification.examples.map do |example|
31
- format_example(example).tap do |hash|
32
- e = example.exception
33
- if e
34
- hash[:exception] = {
35
- :class => e.class.name,
36
- :message => e.message,
37
- :backtrace => e.backtrace,
38
- }
39
- else
40
- @db.add(example.metadata[:file_path], example.full_description, example.execution_result.run_time) if example.metadata[:chart]
41
- end
42
- end
43
- end
44
- end
45
-
46
- def dump_summary(summary)
47
- output.puts summary.fully_formatted
48
- @output_hash[:summary] = {
49
- :duration => summary.duration,
50
- :example_count => summary.example_count,
51
- :failure_count => summary.failure_count,
52
- :pending_count => summary.pending_count
53
- }
54
- @output_hash[:summary_line] = summary.totals_line
55
-
56
- specs_history = [].tap do |cd|
57
- @db.all.each do |row|
58
- cd << {
59
- file: row[0],
60
- name: row[1],
61
- duration: row[2],
62
- measured_at: row[3]
63
- }
64
- end
65
- end
66
-
67
- @chart_data = {}.tap do |spec_summary|
68
- specs_history.group_by{ |x| x[:name] }.each do |name, specs|
69
- measures = []
70
- specs.each do |spec|
71
- measures << [Time.at(spec[:measured_at]), spec[:duration], spec[:name]]
72
- end
73
- spec_summary[name] = measures
74
- end
75
- end
76
-
77
- @chartspec_root = File.expand_path("../../../", __FILE__)
78
- template = ERB.new File.new(File.expand_path("../../../templates/chartspec.html.erb", __FILE__)).read, nil, "%"
79
- template.result(binding)
80
-
81
- @chart_file = ENV["CHARTSPEC_HTML"] || "tmp/chartspec.html"
82
- chart_dirname = File.dirname(@chart_file)
83
- unless File.directory?(chart_dirname)
84
- FileUtils.mkdir_p(chart_dirname)
85
- end
86
- File.open(@chart_file, "w") do |file|
87
- file.puts template.result(binding)
88
- end
89
- puts "* Chartspec output: #{@chart_file}\n"
90
- puts "* Chartspec tmp_db: #{@db.file_name}\n"
91
- end
92
-
93
- def example_group_started(notification)
94
- super
95
- @example_group_red = false
96
- @example_group_number += 1
97
- end
98
-
99
- def start_dump(notification)
100
-
101
- end
102
-
103
- def example_started(notification)
104
- @example_number += 1
105
- end
106
-
107
- def example_passed(passed)
108
- super
109
- end
110
-
111
- def example_failed(failure)
112
- super
113
- @failed_examples << failure.example
114
- unless @header_red
115
- @header_red = true
116
- end
117
- end
118
-
119
- def example_pending(pending)
120
- super
121
- end
122
-
123
- private
124
- def example_group_number
125
- @example_group_number
126
- end
127
-
128
- def format_example(example)
129
- {
130
- :description => example.description,
131
- :full_description => example.full_description,
132
- :status => example.execution_result.status.to_s,
133
- :file_path => example.metadata[:file_path],
134
- :line_number => example.metadata[:line_number],
135
- :run_time => example.execution_result.run_time
136
- }
137
- end
138
-
139
- end
1
+ require "rspec"
2
+ require "rspec/core/formatters/base_text_formatter"
3
+ require "rspec/core/formatters/console_codes"
4
+ require "chartspec/printer"
5
+ require "chartspec/db"
6
+ require 'json'
7
+
8
+ module Chartspec
9
+ class Formatter < RSpec::Core::Formatters::BaseTextFormatter
10
+ RSpec::Core::Formatters.register self, :start, :example_group_started, :start_dump, :example_started, :example_passed, :example_failed, :example_pending, :dump_failures, :dump_pending
11
+
12
+ def initialize(output)
13
+ super output
14
+ @failed_examples = []
15
+ @current_file = {}
16
+ @example_group_number = 0
17
+ @example_number = 0
18
+ @header_red = false
19
+ @db = Db.new ENV["CHARTSPEC_DB"]
20
+ @printer = Printer.new output
21
+ @charts = {}
22
+ end
23
+
24
+ def start(notification)
25
+ @printer.print_html_start
26
+ @printer.flush
27
+ end
28
+
29
+ def dump_summary(summary)
30
+ puts summary.totals_line
31
+ @printer.print_html_end
32
+ @printer.flush
33
+ end
34
+
35
+ def example_group_started(notification)
36
+ @example_group_red = false
37
+ @example_group_number += 1
38
+
39
+ unless example_group_number == 1
40
+ @printer.print_group_end
41
+ generate_chart @current_file, @current_group
42
+ end
43
+ @printer.print_group_start example_group_number, notification.group.to_s, notification.group.description, notification.group.parent_groups.size
44
+ @charts[@example_group_number] = []
45
+ end
46
+
47
+ def start_dump(notification)
48
+ @printer.print_group_end
49
+ generate_chart @current_file, @current_group
50
+ puts
51
+ end
52
+
53
+ def example_started(notification)
54
+ @example_number += 1
55
+ @current_group = notification.example.example_group
56
+ @current_file = notification.example.metadata[:file_path]
57
+ end
58
+
59
+ def example_passed(passed)
60
+ putc RSpec::Core::Formatters::ConsoleCodes.wrap('.', :success)
61
+ @printer.print_example_passed(passed.example.description, passed.example.execution_result.run_time, passed.example.metadata[:turnip])
62
+ @db.add(
63
+ passed.example.metadata[:file_path],
64
+ passed.example.example_group,
65
+ passed.example.description,
66
+ passed.example.execution_result.run_time
67
+ ) if passed.example.metadata[:chart]
68
+ end
69
+
70
+ def example_failed(failure)
71
+ putc RSpec::Core::Formatters::ConsoleCodes.wrap('F', :failure)
72
+ @failed_examples << failure.example
73
+ unless @header_red
74
+ @header_red = true
75
+ end
76
+ @printer.print_example_failed(@example_number, failure.example.metadata[:file_path], failure.example.description, failure.example.execution_result.run_time,
77
+ failure.example.exception.message, failure.example.exception.backtrace, failure.example.metadata[:turnip])
78
+ end
79
+
80
+ def example_pending(pending)
81
+ putc RSpec::Core::Formatters::ConsoleCodes.wrap('*', :pending)
82
+ @printer.print_example_pending(pending.example.description, pending.example.execution_result.pending_message, pending.example.metadata[:turnip])
83
+ end
84
+
85
+ def dump_failures(notification)
86
+ return if notification.failure_notifications.empty?
87
+ puts notification.fully_formatted_failed_examples
88
+ end
89
+
90
+ def dump_pending(notification)
91
+ return if notification.pending_examples.empty?
92
+ puts notification.fully_formatted_pending_examples
93
+ end
94
+
95
+ private
96
+ def example_group_number
97
+ @example_group_number
98
+ end
99
+
100
+ def format_example(example)
101
+ {
102
+ :description => example.description,
103
+ :full_description => example.full_description,
104
+ :status => example.execution_result.status.to_s,
105
+ :file_path => example.metadata[:file_path],
106
+ :line_number => example.metadata[:line_number],
107
+ :run_time => example.execution_result.run_time
108
+ }
109
+ end
110
+
111
+ def generate_chart example_file, example_group
112
+ return unless example_group and example_file
113
+
114
+ chart_data = {}.tap do |spec_summary|
115
+ @db.select_by_file_and_chart(example_file, example_group).group_by{ |x| x[0] }.each do |name, specs|
116
+ measures = []
117
+ specs.each do |spec|
118
+ measures << [Time.at(spec[2]), spec[1]]
119
+ end
120
+ spec_summary[name[0..60]] = measures
121
+ end
122
+ end
123
+ @printer.print_chart_script(example_file, example_group, chart_data) unless chart_data.empty?
124
+ end
125
+ end
140
126
  end