chartspec 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -1,14 +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
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
data/LICENSE.txt CHANGED
@@ -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
+
data/bin/chartspec CHANGED
@@ -1,5 +1,5 @@
1
- #!/usr/bin/env ruby
2
-
3
- require 'chartspec'
4
-
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'chartspec'
4
+
5
5
  Chartspec::run ARGV
data/chartspec.gemspec CHANGED
@@ -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
data/lib/chartspec.rb CHANGED
@@ -1,50 +1,141 @@
1
- require "chartspec/version"
2
- require "rspec"
3
- require "rspec/core/formatters/progress_formatter"
4
- require "rspec/core/formatters/console_codes"
5
-
6
- module Chartspec
7
- def self.run argv
8
- config = RSpec.configuration
9
- formatter = Formatter.new config.output_stream
10
- reporter = RSpec::Core::Reporter.new(config)
11
- config.instance_variable_set :@reporter, reporter
12
- loader = config.send :formatter_loader
13
- notifications = loader.send :notifications_for, Formatter
14
- reporter.register_listener formatter, *notifications
15
- RSpec::Core::Runner::run [argv]
16
- end
17
-
18
- class Formatter < RSpec::Core::Formatters::ProgressFormatter
19
- RSpec::Core::Formatters.register self, :message, :dump_summary, :dump_profile, :stop, :close
20
-
21
- def initialize(output)
22
- super
23
- p "initialize"
24
- end
25
-
26
- def message(notification)
27
- p "message"
28
- end
29
-
30
- def dump_summary(summary)
31
- output.puts summary.fully_formatted
32
- end
33
-
34
- def stop(notification)
35
- p "stop"
36
- notification.examples.each do |example|
37
- p example.inspect
38
- end
39
- end
40
-
41
- def close(notification)
42
- p "close"
43
- super
44
- end
45
-
46
- def dump_profile(profile)
47
- p "dump_profile"
48
- end
49
- end
50
- end
1
+ require "chartspec/version"
2
+ require "rspec"
3
+ require "rspec/core/formatters/progress_formatter"
4
+ require "rspec/core/formatters/console_codes"
5
+ require 'sqlite3'
6
+ require 'erb'
7
+
8
+ module Chartspec
9
+ def self.run argv
10
+ config = RSpec.configuration
11
+ formatter = Formatter.new config.output_stream
12
+ reporter = RSpec::Core::Reporter.new(config)
13
+ config.instance_variable_set :@reporter, reporter
14
+ loader = config.send :formatter_loader
15
+ notifications = loader.send :notifications_for, Formatter
16
+ reporter.register_listener formatter, *notifications
17
+ RSpec::Core::Runner::run [argv]
18
+ end
19
+
20
+ class Formatter < RSpec::Core::Formatters::ProgressFormatter
21
+ RSpec::Core::Formatters.register self, :start, :stop, :example_group_started, :start_dump, :example_started, :example_passed, :example_failed, :example_pending, :dump_profile
22
+
23
+ def initialize(output)
24
+ super(output)
25
+ @db = SQLite3::Database.new( ENV["CHARTSPEC_DB"] || "tmp/chartspec.sqlite3" )
26
+ @title = ENV["CHARTSPEC_TITLE"]
27
+ @name = ENV["CHARTSPEC_NAME"]
28
+ @db.execute( "CREATE TABLE IF NOT EXISTS specs(id INTEGER PRIMARY KEY, file TEXT, example_group TEXT, example TEXT, duration NUMERIC, measured_at DATETIME);" )
29
+ end
30
+
31
+ def start(notification)
32
+ super
33
+ @failed_examples = []
34
+ @example_group_number = 0
35
+ @example_number = 0
36
+ @header_red = false
37
+ @output_hash = {}
38
+ end
39
+
40
+ def stop(notification)
41
+ @output_hash[:examples] = notification.examples.map do |example|
42
+ format_example(example).tap do |hash|
43
+ e = example.exception
44
+ if e
45
+ hash[:exception] = {
46
+ :class => e.class.name,
47
+ :message => e.message,
48
+ :backtrace => e.backtrace,
49
+ }
50
+ else
51
+ @db.execute("INSERT INTO specs(file, name, duration, measured_at) VALUES (?, ?, ?, ?)", [
52
+ example.metadata[:file_path], example.full_description, example.execution_result.run_time, Time.now.to_i
53
+ ]) if example.metadata[:chart]
54
+ end
55
+ end
56
+ end
57
+ end
58
+
59
+ def dump_summary(summary)
60
+ output.puts summary.fully_formatted
61
+ @output_hash[:summary] = {
62
+ :duration => summary.duration,
63
+ :example_count => summary.example_count,
64
+ :failure_count => summary.failure_count,
65
+ :pending_count => summary.pending_count
66
+ }
67
+ @output_hash[:summary_line] = summary.totals_line
68
+
69
+ specs_history = [].tap do |cd|
70
+ @db.execute( "select file, name, duration, measured_at from specs where measured_at > ?", (Time.now - ((ENV['CHARTSPEC_HISTORY_HOURS'] || 2)*3600)).to_i).each do |row|
71
+ cd << {
72
+ file: row[0],
73
+ name: row[1],
74
+ duration: row[2],
75
+ measured_at: row[3]
76
+ }
77
+ end
78
+ end
79
+
80
+ @chart_data = {}.tap do |spec_summary|
81
+ specs_history.group_by{ |x| x[:name] }.each do |name, specs|
82
+ measures = []
83
+ specs.each do |spec|
84
+ measures << [Time.at(spec[:measured_at]), spec[:duration], spec[:name]]
85
+ end
86
+ spec_summary[name] = measures
87
+ end
88
+ end
89
+
90
+ @chartspec_root = File.expand_path("../../", __FILE__)
91
+ template = ERB.new File.new(File.expand_path("../../templates/chartspec.html.erb", __FILE__)).read, nil, "%"
92
+ template.result(binding)
93
+
94
+ File.open("tmp/chartspec.html", "w") do |file|
95
+ file.puts template.result(binding)
96
+ end
97
+ end
98
+
99
+ def example_group_started(notification)
100
+ super
101
+ @example_group_red = false
102
+ @example_group_number += 1
103
+ end
104
+
105
+ def start_dump(_notification)
106
+ end
107
+
108
+ def example_started(_notification)
109
+ @example_number += 1
110
+ end
111
+
112
+ def example_passed(passed)
113
+ super
114
+ end
115
+
116
+ def example_failed(failure)
117
+ super
118
+ @failed_examples << failure.example
119
+ unless @header_red
120
+ @header_red = true
121
+ end
122
+ end
123
+
124
+ def example_pending(pending)
125
+ super
126
+ end
127
+
128
+ private
129
+ def format_example(example)
130
+ {
131
+ :description => example.description,
132
+ :full_description => example.full_description,
133
+ :status => example.execution_result.status.to_s,
134
+ :file_path => example.metadata[:file_path],
135
+ :line_number => example.metadata[:line_number],
136
+ :run_time => example.execution_result.run_time
137
+ }
138
+ end
139
+
140
+ end
141
+ end
@@ -1,3 +1,3 @@
1
- module Chartspec
2
- VERSION = "0.0.1"
3
- end
1
+ module Chartspec
2
+ VERSION = "0.0.2"
3
+ end
@@ -0,0 +1,12 @@
1
+ require 'spec_helper'
2
+
3
+ describe Chartspec do
4
+
5
+ describe 'run' do
6
+
7
+ it 'should work', chart: true do
8
+ expect(Chartspec).to eq(Chartspec)
9
+ end
10
+
11
+ end
12
+ end
@@ -0,0 +1 @@
1
+ require 'chartspec'
@@ -0,0 +1,67 @@
1
+ <!DOCTYPE HTML PUBLIC>
2
+ <html>
3
+ <head>
4
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
5
+ <title><%= @title %></title>
6
+ <style>
7
+ <%= File.open(File.join(@chartspec_root,"vendor/assets/stylesheets/jquery.jqplot.min.css")).read %>
8
+ </style>
9
+ <!--[if lt IE 9]><script language='javascript' type='text/javascript' src='http://www.jqplot.com/src/excanvas.js'></script><![endif]-->
10
+ </head>
11
+ <body>
12
+ <h1><%= @name %></h1>
13
+ <div id='chartdiv' style='height:400px;width:100%;'></div>
14
+ <h3><%= @output_hash[:summary_line] %></h3>
15
+ <% @output_hash[:examples].each do |test| %>
16
+ <% if test[:status] == 'passed' %>
17
+ <b style='color:green;'>[&nbsp;OK&nbsp;]</b> <%= test[:description] %> / <%= test[:run_time] %>
18
+ <% else %>
19
+ <b style='color:red;'>[FAIL]</b> <%= test[:description] %> / <%= test[:run_time] %>
20
+ <blockquote>
21
+ <b><%= test[:exception][:class] %></b><br />
22
+ <span style="color:red;"><%= test[:exception][:message] %></span><br />
23
+ <%= test[:exception][:backtrace].join('<br />') %>
24
+ </blockquote>
25
+ <% end %>
26
+ <br />
27
+ <% end %>
28
+ <script>
29
+ <%= File.open(File.join(@chartspec_root,"vendor/assets/javascripts/jquery.min.js")).read %>
30
+ <%= File.open(File.join(@chartspec_root,"vendor/assets/javascripts/jquery.jqplot.min.js")).read %>
31
+ <%= File.open(File.join(@chartspec_root,"vendor/assets/javascripts/jqplot.dateAxisRenderer.min.js")).read %>
32
+ <%= File.open(File.join(@chartspec_root,"vendor/assets/javascripts/jqplot.highlighter.min.js")).read %>
33
+ $(document).ready(function(){
34
+ var chart_data = <%= (@chart_data || {}).values.to_json %>;
35
+ var chart = $.jqplot('chartdiv', chart_data,
36
+ {
37
+ title: '<%= "#{@title} / #{Time.now.strftime("%b %d %T")}" %>',
38
+ axes:{
39
+ xaxis:{
40
+ renderer:$.jqplot.DateAxisRenderer,
41
+ tickOptions:{
42
+ formatString:'%b&nbsp;%#d %T'
43
+ }
44
+ },
45
+ yaxis:{
46
+ tickOptions:{
47
+ formatString:'%.3f'
48
+ }
49
+ }
50
+ },
51
+ highlighter: {
52
+ show: true,
53
+ sizeAdjust: 7.5
54
+ },
55
+ legend: {
56
+ location: 'nw',
57
+ labels: <%= (@chart_data || {}).keys.to_json %>,
58
+ show: true,
59
+ placement: 'insideGrid'
60
+ }
61
+ }
62
+ );
63
+ });
64
+ </script>
65
+ </body>
66
+ </html>
67
+