rspec_log_formatter 0.0.1

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.
checksums.yaml ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ MGJmODJlZTJkMzNjOGY5OWRjNDRjNmIxYzUyMTM0ZWEyY2MxN2U0Ng==
5
+ data.tar.gz: !binary |-
6
+ YzQ3MDllYzM1MmQ5NmJjNzJkYmVlMjE0ZjkxY2U1ZmFiZjg1ZDYxMw==
7
+ SHA512:
8
+ metadata.gz: !binary |-
9
+ MzBjMWQ3NGZjMzZmODM1M2VhY2ZmYjA3MGE0NjQzYTg5Zjg1YjEwNTA3YjIy
10
+ ZDhmMDZlNDBmYTc5Y2ZjZjc1Njg3MjMwYzQ1ZjRlNmJhOTFmZTI5NzQwZDlj
11
+ MDA0OGQ5ODJjNmQxZWU1NDZlOTJkM2Q4NTU2YzFlNGJiMmQ0ZGQ=
12
+ data.tar.gz: !binary |-
13
+ Mzc5NWQ5MzEyZmFiMDE0ODZjODEyZTkxYWQ4MWQ3ZDRjYmUzNDI5ODY3YjVm
14
+ NTY2ZTg1ZjJkZWY1YjczMGQyMWE3OTE4M2Q4YjJjMDA4YTdjNTM0Nzg3YjRk
15
+ MjdhMjgzZjM4Y2JkY2MwNjE2OWFiYzQwNWIwM2M2YzAyNjE4MTQ=
data/.gitignore ADDED
@@ -0,0 +1,20 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ dummy
19
+ rspec.history
20
+ rspec.times
data/.ruby-gemset ADDED
@@ -0,0 +1 @@
1
+ rspec_log_formatter
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 1.9.3
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in rspec_log_formatter.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Serguei Filimonov
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 ADDED
@@ -0,0 +1,29 @@
1
+ # RspecLogFormatter
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'rspec_log_formatter'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install rspec_log_formatter
18
+
19
+ ## Usage
20
+
21
+ TODO: Write usage instructions here
22
+
23
+ ## Contributing
24
+
25
+ 1. Fork it ( http://github.com/<my-github-username>/rspec_log_formatter/fork )
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
27
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
28
+ 4. Push to the branch (`git push origin my-new-feature`)
29
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,38 @@
1
+ require 'csv'
2
+
3
+ module RspecLogFormatter
4
+ module Analysis
5
+ class Analyzer
6
+ def analyze(filepath, options = {})
7
+ window = options[:last_builds]
8
+
9
+ build_numbers = []
10
+ results = File.open(filepath).each_line.map do |line|
11
+ result = Result.new(*CSV.parse_line(line, col_sep: "\t").first(7))
12
+ build_numbers << result.build_number
13
+ result
14
+ end
15
+ build_numbers.uniq!.sort!
16
+
17
+
18
+ scores = []
19
+ results.group_by(&:description).each do |description, results|
20
+ score = Score.new(description)
21
+
22
+ results.group_by(&:build_number).each do |build_number, results|
23
+ next if (window && !build_numbers.last(window).include?(build_number))
24
+ next if results.all?(&:failure?) #not flaky
25
+
26
+
27
+ score.runs += results.count
28
+ score.failures += results.count(&:failure?)
29
+ score.failure_messages += results.select(&:failure?).map { |r| "#{r.klass}\n #{r.message}" }
30
+ end
31
+ scores << score if score.runs > 0
32
+ end
33
+
34
+ scores.sort.map(&:as_hash)
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,19 @@
1
+ module RspecLogFormatter
2
+ module Analysis
3
+ class PrettyPrinter
4
+ def initialize(results)
5
+ @results = results
6
+ end
7
+
8
+ def to_s
9
+ results = @results.first(10)
10
+ header = "Top #{results.count} flakiest examples\n"
11
+ header + results.each_with_index.map do |result, i|
12
+ title = " #{i+1}) #{result[:description]} -- #{result[:percent]}%"
13
+ failure_messages = result[:failure_messages].map { |fm| " * #{fm}" }.join("\n")
14
+ title + "\n" + failure_messages
15
+ end.join("\n")
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,25 @@
1
+ module RspecLogFormatter
2
+ module Analysis
3
+ class Result
4
+ def initialize(build_number, time, outcome, description, spec_path, message=nil, klass=nil)
5
+ @build_number = build_number
6
+ @description = description
7
+ @outcome = outcome
8
+ @spec_path = spec_path
9
+ @message = message
10
+ @klass = klass
11
+ end
12
+
13
+ attr_accessor :build_number, :description
14
+ attr_reader :message, :klass
15
+
16
+ def failure?
17
+ @outcome == "failed"
18
+ end
19
+
20
+ def success?
21
+ @outcome == "passed"
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,29 @@
1
+ module RspecLogFormatter
2
+ module Analysis
3
+ class Score
4
+ def initialize(desc)
5
+ @description = desc
6
+ @runs = 0
7
+ @failures = 0
8
+ @failure_messages = []
9
+ end
10
+
11
+ def percent
12
+ 100 * @failures.to_f/@runs
13
+ end
14
+
15
+ def <=>(other)
16
+ other.percent <=> percent
17
+ end
18
+
19
+ def as_hash
20
+ {
21
+ description: @description,
22
+ percent: percent,
23
+ failure_messages: failure_messages,
24
+ }
25
+ end
26
+ attr_accessor :runs, :failures, :failure_messages
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,69 @@
1
+ require "csv"
2
+ require "rspec/core/formatters/base_formatter"
3
+
4
+ module RspecLogFormatter
5
+ class Formatter < RSpec::Core::Formatters::BaseFormatter
6
+ FILENAME = "rspec.history"
7
+
8
+ class Config
9
+ def clock=(clock)
10
+ @clock = clock
11
+ end
12
+ def clock
13
+ @clock ||= Time
14
+ @clock
15
+ end
16
+ end
17
+ CONFIG = Config.new
18
+
19
+ def initialize(*args)
20
+ super
21
+ end
22
+
23
+ def self.analyze(filepath)
24
+ Analysis::Analyzer.new.analyze(filepath)
25
+ end
26
+
27
+ def example_started(example)
28
+ @clock_start = clock.now
29
+ end
30
+
31
+ def example_passed(example)
32
+ record("passed", example, clock.now, clock.now - @clock_start)
33
+ end
34
+
35
+ def example_failed(example)
36
+ record("failed", example, clock.now, clock.now - @clock_start, example.exception)
37
+ end
38
+
39
+ private
40
+
41
+ def clock
42
+ CONFIG.clock
43
+ end
44
+
45
+ def record(outcome, example, time, duration, exception=nil)
46
+ if exception
47
+ exception_data = [
48
+ exception.message.gsub(/\r|\n|\t/, " "),
49
+ exception.class,
50
+ ]
51
+ else
52
+ exception_data = [nil,nil]
53
+ end
54
+
55
+ example_data = [
56
+ ENV["BUILD_NUMBER"],
57
+ time,
58
+ outcome,
59
+ example.full_description.to_s.gsub(/\r|\n|\t/, " "),
60
+ example.file_path,
61
+ ] + exception_data + [duration]
62
+
63
+ File.open(FILENAME, "a") do |f|
64
+ f.puts example_data.to_csv(col_sep: "\t")
65
+ end
66
+ end
67
+
68
+ end
69
+ end
@@ -0,0 +1,3 @@
1
+ module RspecLogFormatter
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,4 @@
1
+ require "rspec_log_formatter/version"
2
+ Dir[File.join(File.dirname(__FILE__), "./**/*.rb")].each {|file| require file }
3
+ module RspecLogFormatter
4
+ end
@@ -0,0 +1,25 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'rspec_log_formatter/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "rspec_log_formatter"
8
+ spec.version = RspecLogFormatter::VERSION
9
+ spec.authors = ["Serguei Filimonov"]
10
+ spec.email = ["sfilimonov@pivotallabs.com"]
11
+ spec.summary = "Logs the outcomes of the tests to a file"
12
+ spec.description = "Logs the outcomes of the tests to a file"
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_development_dependency "bundler", "~> 1.5"
22
+ spec.add_development_dependency "rake"
23
+ spec.add_development_dependency "rspec"
24
+ spec.add_development_dependency "pry"
25
+ end
@@ -0,0 +1,70 @@
1
+ 2014-01-21 16:08:25 -0800 passed description0 ./spec/m1k1_spec.rb
2
+ 2014-01-21 16:08:25 -0800 passed description1 ./spec/m1k1_spec.rb
3
+ 2014-01-21 16:08:25 -0800 passed description2 ./spec/m1k1_spec.rb
4
+ 2014-01-21 16:08:25 -0800 passed description3 ./spec/m1k1_spec.rb
5
+ 2014-01-21 16:08:25 -0800 passed description4 ./spec/m1k1_spec.rb
6
+ 2014-01-21 16:08:25 -0800 passed description5 ./spec/m1k1_spec.rb
7
+ 2014-01-21 16:08:25 -0800 passed description6 ./spec/m1k1_spec.rb
8
+ 2014-01-21 16:08:25 -0800 passed description7 ./spec/m1k1_spec.rb
9
+ 2014-01-21 16:08:25 -0800 passed description8 ./spec/m1k1_spec.rb
10
+ 2014-01-21 16:08:25 -0800 passed description9 ./spec/m1k1_spec.rb
11
+ 2014-01-22 16:08:25 -0800 failed description0 ./spec/m1k1_spec.rb msg10 ec10
12
+ 2014-01-22 16:08:25 -0800 passed description1 ./spec/m1k1_spec.rb
13
+ 2014-01-22 16:08:25 -0800 passed description2 ./spec/m1k1_spec.rb
14
+ 2014-01-22 16:08:25 -0800 passed description3 ./spec/m1k1_spec.rb
15
+ 2014-01-22 16:08:25 -0800 passed description4 ./spec/m1k1_spec.rb
16
+ 2014-01-22 16:08:25 -0800 passed description5 ./spec/m1k1_spec.rb
17
+ 2014-01-22 16:08:25 -0800 passed description6 ./spec/m1k1_spec.rb
18
+ 2014-01-22 16:08:25 -0800 passed description7 ./spec/m1k1_spec.rb
19
+ 2014-01-22 16:08:25 -0800 passed description8 ./spec/m1k1_spec.rb
20
+ 2014-01-22 16:08:25 -0800 passed description9 ./spec/m1k1_spec.rb
21
+ 2014-01-23 16:08:25 -0800 failed description0 ./spec/m1k1_spec.rb msg20 ec20
22
+ 2014-01-23 16:08:25 -0800 failed description1 ./spec/m1k1_spec.rb msg21 ec21
23
+ 2014-01-23 16:08:25 -0800 passed description2 ./spec/m1k1_spec.rb
24
+ 2014-01-23 16:08:25 -0800 passed description3 ./spec/m1k1_spec.rb
25
+ 2014-01-23 16:08:25 -0800 passed description4 ./spec/m1k1_spec.rb
26
+ 2014-01-23 16:08:25 -0800 passed description5 ./spec/m1k1_spec.rb
27
+ 2014-01-23 16:08:25 -0800 passed description6 ./spec/m1k1_spec.rb
28
+ 2014-01-23 16:08:25 -0800 passed description7 ./spec/m1k1_spec.rb
29
+ 2014-01-23 16:08:25 -0800 passed description8 ./spec/m1k1_spec.rb
30
+ 2014-01-23 16:08:25 -0800 passed description9 ./spec/m1k1_spec.rb
31
+ 2014-01-24 16:08:25 -0800 failed description0 ./spec/m1k1_spec.rb msg30 ec30
32
+ 2014-01-24 16:08:25 -0800 failed description1 ./spec/m1k1_spec.rb msg31 ec31
33
+ 2014-01-24 16:08:25 -0800 failed description2 ./spec/m1k1_spec.rb msg32 ec32
34
+ 2014-01-24 16:08:25 -0800 passed description3 ./spec/m1k1_spec.rb
35
+ 2014-01-24 16:08:25 -0800 passed description4 ./spec/m1k1_spec.rb
36
+ 2014-01-24 16:08:25 -0800 passed description5 ./spec/m1k1_spec.rb
37
+ 2014-01-24 16:08:25 -0800 passed description6 ./spec/m1k1_spec.rb
38
+ 2014-01-24 16:08:25 -0800 passed description7 ./spec/m1k1_spec.rb
39
+ 2014-01-24 16:08:25 -0800 passed description8 ./spec/m1k1_spec.rb
40
+ 2014-01-24 16:08:25 -0800 passed description9 ./spec/m1k1_spec.rb
41
+ 2014-01-25 16:08:25 -0800 failed description0 ./spec/m1k1_spec.rb msg40 ec40
42
+ 2014-01-25 16:08:25 -0800 failed description1 ./spec/m1k1_spec.rb msg41 ec41
43
+ 2014-01-25 16:08:25 -0800 failed description2 ./spec/m1k1_spec.rb msg42 ec42
44
+ 2014-01-25 16:08:25 -0800 failed description3 ./spec/m1k1_spec.rb msg43 ec43
45
+ 2014-01-25 16:08:25 -0800 passed description4 ./spec/m1k1_spec.rb
46
+ 2014-01-25 16:08:25 -0800 passed description5 ./spec/m1k1_spec.rb
47
+ 2014-01-25 16:08:25 -0800 passed description6 ./spec/m1k1_spec.rb
48
+ 2014-01-25 16:08:25 -0800 passed description7 ./spec/m1k1_spec.rb
49
+ 2014-01-25 16:08:25 -0800 passed description8 ./spec/m1k1_spec.rb
50
+ 2014-01-25 16:08:25 -0800 passed description9 ./spec/m1k1_spec.rb
51
+ 2014-01-26 16:08:25 -0800 failed description0 ./spec/m1k1_spec.rb msg50 ec50
52
+ 2014-01-26 16:08:25 -0800 failed description1 ./spec/m1k1_spec.rb msg51 ec51
53
+ 2014-01-26 16:08:25 -0800 failed description2 ./spec/m1k1_spec.rb msg52 ec52
54
+ 2014-01-26 16:08:25 -0800 failed description3 ./spec/m1k1_spec.rb msg53 ec53
55
+ 2014-01-26 16:08:25 -0800 failed description4 ./spec/m1k1_spec.rb msg54 ec54
56
+ 2014-01-26 16:08:25 -0800 passed description5 ./spec/m1k1_spec.rb
57
+ 2014-01-26 16:08:25 -0800 passed description6 ./spec/m1k1_spec.rb
58
+ 2014-01-26 16:08:25 -0800 passed description7 ./spec/m1k1_spec.rb
59
+ 2014-01-26 16:08:25 -0800 passed description8 ./spec/m1k1_spec.rb
60
+ 2014-01-26 16:08:25 -0800 passed description9 ./spec/m1k1_spec.rb
61
+ 2014-01-27 16:08:25 -0800 failed description0 ./spec/m1k1_spec.rb msg60 ec60
62
+ 2014-01-27 16:08:25 -0800 failed description1 ./spec/m1k1_spec.rb msg61 ec61
63
+ 2014-01-27 16:08:25 -0800 failed description2 ./spec/m1k1_spec.rb msg62 ec62
64
+ 2014-01-27 16:08:25 -0800 failed description3 ./spec/m1k1_spec.rb msg63 ec63
65
+ 2014-01-27 16:08:25 -0800 failed description4 ./spec/m1k1_spec.rb msg64 ec64
66
+ 2014-01-27 16:08:25 -0800 failed description5 ./spec/m1k1_spec.rb msg65 ec65
67
+ 2014-01-27 16:08:25 -0800 failed description6 ./spec/m1k1_spec.rb msg66 ec66
68
+ 2014-01-27 16:08:25 -0800 failed description7 ./spec/m1k1_spec.rb msg67 ec67
69
+ 2014-01-27 16:08:25 -0800 failed description8 ./spec/m1k1_spec.rb msg68 ec68
70
+ 2014-01-27 16:08:25 -0800 failed description9 ./spec/m1k1_spec.rb msg69 ec69
@@ -0,0 +1,10 @@
1
+ 1 2014-01-21 16:08:25 -0800 failed desc ./spec/m1k1_spec.rb msg10 ec10
2
+ 1 2014-01-21 16:08:25 -0800 passed desc ./spec/m1k1_spec.rb
3
+ 2 2014-01-21 16:08:25 -0800 failed desc ./spec/m1k1_spec.rb msg10 ec10
4
+ 2 2014-01-21 16:08:25 -0800 passed desc ./spec/m1k1_spec.rb
5
+ 3 2014-01-21 16:08:25 -0800 failed desc ./spec/m1k1_spec.rb msg10 ec10
6
+ 3 2014-01-21 16:08:25 -0800 passed desc ./spec/m1k1_spec.rb
7
+ 4 2014-01-21 16:08:25 -0800 passed desc ./spec/m1k1_spec.rb
8
+ 5 2014-01-21 16:08:25 -0800 passed desc ./spec/m1k1_spec.rb
9
+ 6 2014-01-21 16:08:25 -0800 passed desc ./spec/m1k1_spec.rb
10
+ 7 2014-01-21 16:08:25 -0800 passed desc ./spec/m1k1_spec.rb
@@ -0,0 +1,9 @@
1
+ 1 2014-01-21 16:08:25 -0800 failed desc1 ./spec/m1k1_spec.rb msg10 ec10
2
+ 1 2014-01-21 16:08:25 -0800 passed desc1 ./spec/m1k1_spec.rb
3
+ 1 2014-01-21 16:08:25 -0800 failed desc3 ./spec/m1k1_spec.rb msg10 ec10
4
+ 1 2014-01-21 16:08:25 -0800 failed desc3 ./spec/m1k1_spec.rb msg10 ec10
5
+ 1 2014-01-21 16:08:25 -0800 failed desc3 ./spec/m1k1_spec.rb msg10 ec10
6
+ 1 2014-01-21 16:08:25 -0800 passed desc3 ./spec/m1k1_spec.rb
7
+ 1 2014-01-21 16:08:25 -0800 failed desc2 ./spec/m1k1_spec.rb msg10 ec10
8
+ 1 2014-01-21 16:08:25 -0800 failed desc2 ./spec/m1k1_spec.rb msg10 ec10
9
+ 1 2014-01-21 16:08:25 -0800 passed desc2 ./spec/m1k1_spec.rb
@@ -0,0 +1,41 @@
1
+ require "spec_helper"
2
+
3
+ describe RspecLogFormatter::Analysis::Analyzer do
4
+ it "sorts the parsed results by failure percentage" do
5
+ filepath = File.expand_path("../../../../fixtures/varying_flakiness.history", __FILE__)
6
+ described_class.new.analyze(filepath).map{|r| r[:percent] }.should == [
7
+ 75.0, 100*2.0/3.0, 50.0
8
+ ]
9
+ end
10
+
11
+ it "works" do
12
+ filepath = File.expand_path("../../../../fixtures/fail_history_analyzer.rspec.history", __FILE__)
13
+ described_class.new.analyze(filepath).first.should == {
14
+ description: "description0",
15
+ percent: 85.71428571428571,
16
+ failure_messages: [
17
+ "ec10\n msg10",
18
+ "ec20\n msg20",
19
+ "ec30\n msg30",
20
+ "ec40\n msg40",
21
+ "ec50\n msg50",
22
+ "ec60\n msg60",
23
+ ]
24
+ }
25
+ end
26
+
27
+ it "can analyze only a window of builds" do
28
+ filepath = File.expand_path("../../../../fixtures/test_was_flaky_then_fixed.history", __FILE__)
29
+ subject.analyze(filepath, last_builds: 7).first.should == {
30
+ description: "desc",
31
+ percent: 30.0,
32
+ failure_messages: ["ec10\n msg10", "ec10\n msg10", "ec10\n msg10"]
33
+ }
34
+ subject.analyze(filepath, last_builds: 4).first.should == {
35
+ description: "desc",
36
+ percent: 0.0,
37
+ failure_messages: []
38
+ }
39
+
40
+ end
41
+ end
@@ -0,0 +1,56 @@
1
+ require 'spec_helper'
2
+
3
+ describe RspecLogFormatter::Analysis::PrettyPrinter do
4
+ it "pretty prints the results of an analysis" do
5
+ results = [{
6
+ description: "I fail a lot.",
7
+ percent: 99,
8
+ failure_messages: ["I'm a total failure."]
9
+ },{
10
+ description: "I fail often.",
11
+ percent: 70,
12
+ failure_messages: ["I am a failure message.", "I'm another failure message."]
13
+ }]
14
+
15
+ described_class.new(results).to_s.should == <<-TEXT.strip
16
+ Top 2 flakiest examples
17
+ 1) I fail a lot. -- 99%
18
+ * I'm a total failure.
19
+ 2) I fail often. -- 70%
20
+ * I am a failure message.
21
+ * I'm another failure message.
22
+ TEXT
23
+ end
24
+
25
+ context "when there are more than 10 results" do
26
+ it "only prints the top 10" do
27
+ results = (1..20).map do |i|
28
+ {description: "hi#{i}", percent: 1, failure_messages: ["bye#{i}"]}
29
+ end
30
+
31
+ described_class.new(results).to_s.should == <<-TEXT.strip
32
+ Top 10 flakiest examples
33
+ 1) hi1 -- 1%
34
+ * bye1
35
+ 2) hi2 -- 1%
36
+ * bye2
37
+ 3) hi3 -- 1%
38
+ * bye3
39
+ 4) hi4 -- 1%
40
+ * bye4
41
+ 5) hi5 -- 1%
42
+ * bye5
43
+ 6) hi6 -- 1%
44
+ * bye6
45
+ 7) hi7 -- 1%
46
+ * bye7
47
+ 8) hi8 -- 1%
48
+ * bye8
49
+ 9) hi9 -- 1%
50
+ * bye9
51
+ 10) hi10 -- 1%
52
+ * bye10
53
+ TEXT
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,36 @@
1
+ require 'spec_helper'
2
+
3
+ describe RspecLogFormatter::Formatter do
4
+
5
+ def make_example(opts={})
6
+ @count ||= 0; @count += 1
7
+ double({
8
+ full_description: "description_#{@count}",
9
+ file_path: "path_#{@count}"
10
+ }.merge(opts))
11
+ end
12
+
13
+ it "works" do
14
+ failed_example = make_example(exception: Exception.new("Error"))
15
+ passed_example = make_example(exception: nil)
16
+ time = Time.parse("2014-02-06 16:01:10")
17
+ clock = double(now: time)
18
+ RspecLogFormatter::Formatter::CONFIG.clock = clock
19
+
20
+ formatter = RspecLogFormatter::Formatter.new(StringIO.new)
21
+ formatter.example_started(failed_example)
22
+ #clock.stub(now: time + 5)
23
+ RspecLogFormatter::Formatter::CONFIG.clock = double(now: time + 5)
24
+ formatter.example_failed(failed_example)
25
+
26
+ formatter.example_started(passed_example)
27
+ #clock.stub(:now, time + 8)
28
+ RspecLogFormatter::Formatter::CONFIG.clock = double(now: time + 8)
29
+ formatter.example_passed(passed_example)
30
+ formatter.dump_summary(1,2,3,4)
31
+ File.open('rspec.history').readlines.should == [
32
+ "\t2014-02-06 16:01:15 -0800\tfailed\tdescription_1\tpath_1\tError\tException\t5.0\n",
33
+ "\t2014-02-06 16:01:18 -0800\tpassed\tdescription_2\tpath_2\t\t\t3.0\n",
34
+ ]
35
+ end
36
+ end
@@ -0,0 +1,10 @@
1
+ require 'fileutils'
2
+ require 'pry'
3
+
4
+ Dir["./lib/**/*.rb"].each {|file| require file }
5
+
6
+ RSpec.configure do |config|
7
+ config.before(:each) do
8
+ FileUtils.rm('rspec.history', {force: true})
9
+ end
10
+ end
metadata ADDED
@@ -0,0 +1,129 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rspec_log_formatter
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Serguei Filimonov
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-02-07 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.5'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.5'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ! '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ! '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ! '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: pry
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ! '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ description: Logs the outcomes of the tests to a file
70
+ email:
71
+ - sfilimonov@pivotallabs.com
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - .gitignore
77
+ - .ruby-gemset
78
+ - .ruby-version
79
+ - Gemfile
80
+ - LICENSE.txt
81
+ - README.md
82
+ - Rakefile
83
+ - lib/rspec_log_formatter.rb
84
+ - lib/rspec_log_formatter/analysis/analyzer.rb
85
+ - lib/rspec_log_formatter/analysis/pretty_printer.rb
86
+ - lib/rspec_log_formatter/analysis/result.rb
87
+ - lib/rspec_log_formatter/analysis/score.rb
88
+ - lib/rspec_log_formatter/formatter.rb
89
+ - lib/rspec_log_formatter/version.rb
90
+ - rspec_log_formatter.gemspec
91
+ - spec/fixtures/fail_history_analyzer.rspec.history
92
+ - spec/fixtures/test_was_flaky_then_fixed.history
93
+ - spec/fixtures/varying_flakiness.history
94
+ - spec/lib/rspec_log_analyzer/analysis/analyzer_spec.rb
95
+ - spec/lib/rspec_log_analyzer/analysis/pretty_printer_spec.rb
96
+ - spec/lib/rspec_log_analyzer/formatter_spec.rb
97
+ - spec/spec_helper.rb
98
+ homepage: ''
99
+ licenses:
100
+ - MIT
101
+ metadata: {}
102
+ post_install_message:
103
+ rdoc_options: []
104
+ require_paths:
105
+ - lib
106
+ required_ruby_version: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ! '>='
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ required_rubygems_version: !ruby/object:Gem::Requirement
112
+ requirements:
113
+ - - ! '>='
114
+ - !ruby/object:Gem::Version
115
+ version: '0'
116
+ requirements: []
117
+ rubyforge_project:
118
+ rubygems_version: 2.2.2
119
+ signing_key:
120
+ specification_version: 4
121
+ summary: Logs the outcomes of the tests to a file
122
+ test_files:
123
+ - spec/fixtures/fail_history_analyzer.rspec.history
124
+ - spec/fixtures/test_was_flaky_then_fixed.history
125
+ - spec/fixtures/varying_flakiness.history
126
+ - spec/lib/rspec_log_analyzer/analysis/analyzer_spec.rb
127
+ - spec/lib/rspec_log_analyzer/analysis/pretty_printer_spec.rb
128
+ - spec/lib/rspec_log_analyzer/formatter_spec.rb
129
+ - spec/spec_helper.rb