rspec-legacy_formatters 1.0.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. checksums.yaml +7 -0
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +1 -0
  4. data/.gitignore +11 -0
  5. data/.rspec +2 -0
  6. data/.travis.yml +16 -0
  7. data/.yardopts +7 -0
  8. data/Changelog.md +3 -0
  9. data/Gemfile +30 -0
  10. data/License.txt +22 -0
  11. data/README.md +41 -0
  12. data/Rakefile +27 -0
  13. data/cucumber.yml +6 -0
  14. data/features/custom_formatter.feature +28 -0
  15. data/features/regression_tests_for_built_in_formatters.feature +86 -0
  16. data/features/regression_tests_for_custom_formatters.feature +94 -0
  17. data/features/step_definitions/additional_cli_steps.rb +4 -0
  18. data/features/support/env.rb +13 -0
  19. data/lib/rspec/legacy_formatters.rb +59 -0
  20. data/lib/rspec/legacy_formatters/adaptor.rb +230 -0
  21. data/lib/rspec/legacy_formatters/base_formatter.rb +248 -0
  22. data/lib/rspec/legacy_formatters/base_text_formatter.rb +330 -0
  23. data/lib/rspec/legacy_formatters/documentation_formatter.rb +69 -0
  24. data/lib/rspec/legacy_formatters/helpers.rb +108 -0
  25. data/lib/rspec/legacy_formatters/html_formatter.rb +157 -0
  26. data/lib/rspec/legacy_formatters/html_printer.rb +412 -0
  27. data/lib/rspec/legacy_formatters/json_formatter.rb +71 -0
  28. data/lib/rspec/legacy_formatters/progress_formatter.rb +31 -0
  29. data/lib/rspec/legacy_formatters/snippet_extractor.rb +92 -0
  30. data/lib/rspec/legacy_formatters/version.rb +9 -0
  31. data/maintenance-branch +1 -0
  32. data/rspec-legacy_formatters.gemspec +43 -0
  33. data/script/functions.sh +144 -0
  34. data/script/run_build +13 -0
  35. data/spec/rspec/legacy_formatters_spec.rb +184 -0
  36. data/spec/spec_helper.rb +7 -0
  37. data/spec/support/formatter_support.rb +83 -0
  38. data/spec/support/legacy_formatter_using_sub_classing_example.rb +87 -0
  39. data/spec/support/old_style_formatter_example.rb +69 -0
  40. metadata +243 -0
  41. metadata.gz.sig +2 -0
@@ -0,0 +1,71 @@
1
+ require 'rspec/legacy_formatters/base_formatter'
2
+ require 'json'
3
+
4
+ module RSpec
5
+ module Core
6
+ module Formatters
7
+ remove_const :JsonFormatter
8
+
9
+ class JsonFormatter < BaseFormatter
10
+
11
+ attr_reader :output_hash
12
+
13
+ def initialize(output)
14
+ super
15
+ @output_hash = {}
16
+ end
17
+
18
+ def message(message)
19
+ (@output_hash[:messages] ||= []) << message
20
+ end
21
+
22
+ def dump_summary(duration, example_count, failure_count, pending_count)
23
+ super(duration, example_count, failure_count, pending_count)
24
+ @output_hash[:summary] = {
25
+ :duration => duration,
26
+ :example_count => example_count,
27
+ :failure_count => failure_count,
28
+ :pending_count => pending_count
29
+ }
30
+ @output_hash[:summary_line] = summary_line(example_count, failure_count, pending_count)
31
+ end
32
+
33
+ def summary_line(example_count, failure_count, pending_count)
34
+ summary = pluralize(example_count, "example")
35
+ summary << ", " << pluralize(failure_count, "failure")
36
+ summary << ", #{pending_count} pending" if pending_count > 0
37
+ summary
38
+ end
39
+
40
+ def stop
41
+ super
42
+ @output_hash[:examples] = examples.map do |example|
43
+ {
44
+ :description => example.description,
45
+ :full_description => example.full_description,
46
+ :status => example.execution_result.status,
47
+ # :example_group,
48
+ # :execution_result,
49
+ :file_path => example.metadata[:file_path],
50
+ :line_number => example.metadata[:line_number],
51
+ }.tap do |hash|
52
+ if e=example.exception
53
+ hash[:exception] = {
54
+ :class => e.class.name,
55
+ :message => e.message,
56
+ :backtrace => e.backtrace,
57
+ }
58
+ end
59
+ end
60
+ end
61
+ end
62
+
63
+ def close
64
+ output.write @output_hash.to_json
65
+ output.close if IO === output && output != $stdout
66
+ end
67
+
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,31 @@
1
+ require 'rspec/legacy_formatters/base_text_formatter'
2
+
3
+ module RSpec
4
+ module Core
5
+ module Formatters
6
+ remove_const :ProgressFormatter
7
+
8
+ class ProgressFormatter < BaseTextFormatter
9
+ def example_passed(example)
10
+ super(example)
11
+ output.print success_color('.')
12
+ end
13
+
14
+ def example_pending(example)
15
+ super(example)
16
+ output.print pending_color('*')
17
+ end
18
+
19
+ def example_failed(example)
20
+ super(example)
21
+ output.print failure_color('F')
22
+ end
23
+
24
+ def start_dump
25
+ super()
26
+ output.puts
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,92 @@
1
+ module RSpec
2
+ module Core
3
+ module Formatters
4
+ # @api private
5
+ #
6
+ # Extracts code snippets by looking at the backtrace of the passed error and applies synax highlighting and line numbers using html.
7
+ class SnippetExtractor
8
+ class NullConverter; def convert(code, pre); code; end; end
9
+
10
+ begin
11
+ require 'syntax/convertors/html'
12
+ @@converter = Syntax::Convertors::HTML.for_syntax "ruby"
13
+ rescue LoadError
14
+ @@converter = NullConverter.new
15
+ end
16
+
17
+ # @api private
18
+ #
19
+ # Extract lines of code corresponding to a backtrace.
20
+ #
21
+ # @param [String] backtrace the backtrace from a test failure
22
+ # @return [String] highlighted code snippet indicating where the test failure occured
23
+ #
24
+ # @see #post_process
25
+ def snippet(backtrace)
26
+ raw_code, line = snippet_for(backtrace[0])
27
+ highlighted = @@converter.convert(raw_code, false)
28
+ highlighted << "\n<span class=\"comment\"># gem install syntax to get syntax highlighting</span>" if @@converter.is_a?(NullConverter)
29
+ post_process(highlighted, line)
30
+ end
31
+
32
+ # @api private
33
+ #
34
+ # Create a snippet from a line of code.
35
+ #
36
+ # @param [String] error_line file name with line number (i.e. 'foo_spec.rb:12')
37
+ # @return [String] lines around the target line within the file
38
+ #
39
+ # @see #lines_around
40
+ def snippet_for(error_line)
41
+ if error_line =~ /(.*):(\d+)/
42
+ file = $1
43
+ line = $2.to_i
44
+ [lines_around(file, line), line]
45
+ else
46
+ ["# Couldn't get snippet for #{error_line}", 1]
47
+ end
48
+ end
49
+
50
+ # @api private
51
+ #
52
+ # Extract lines of code centered around a particular line within a source file.
53
+ #
54
+ # @param [String] file filename
55
+ # @param [Fixnum] line line number
56
+ # @return [String] lines around the target line within the file (2 above and 1 below).
57
+ def lines_around(file, line)
58
+ if File.file?(file)
59
+ lines = File.read(file).split("\n")
60
+ min = [0, line-3].max
61
+ max = [line+1, lines.length-1].min
62
+ selected_lines = []
63
+ selected_lines.join("\n")
64
+ lines[min..max].join("\n")
65
+ else
66
+ "# Couldn't get snippet for #{file}"
67
+ end
68
+ rescue SecurityError
69
+ "# Couldn't get snippet for #{file}"
70
+ end
71
+
72
+ # @api private
73
+ #
74
+ # Adds line numbers to all lines and highlights the line where the failure occurred using html `span` tags.
75
+ #
76
+ # @param [String] highlighted syntax-highlighted snippet surrounding the offending line of code
77
+ # @param [Fixnum] offending_line line where failure occured
78
+ # @return [String] completed snippet
79
+ def post_process(highlighted, offending_line)
80
+ new_lines = []
81
+ highlighted.split("\n").each_with_index do |line, i|
82
+ new_line = "<span class=\"linenum\">#{offending_line+i-2}</span>#{line}"
83
+ new_line = "<span class=\"offending\">#{new_line}</span>" if i == 2
84
+ new_lines << new_line
85
+ end
86
+ new_lines.join("\n")
87
+ end
88
+
89
+ end
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,9 @@
1
+ module RSpec
2
+ module LegacyFormatters
3
+ # Version information for RSpec LegacyFormatters.
4
+ module Version
5
+ # Current version of RSpec LegacyFormatters, in semantic versioning format.
6
+ STRING = '1.0.0.rc1'
7
+ end
8
+ end
9
+ end
@@ -0,0 +1 @@
1
+ master
@@ -0,0 +1,43 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'rspec/legacy_formatters/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "rspec-legacy_formatters"
8
+ spec.version = RSpec::LegacyFormatters::Version::STRING
9
+ spec.authors = ["Jon Rowe"]
10
+ spec.email = ["hello@jonrowe.co.uk"]
11
+ spec.email = "rspec@googlegroups.com"
12
+ spec.homepage = "http://github.com/rspec/rspec-legacy_formatters"
13
+ spec.summary = "rspec-legacy_formatters-#{RSpec::LegacyFormatters::Version::STRING}"
14
+ spec.description = %q{Support for RSpec 2.x formatters on 3.x}
15
+ spec.license = "MIT"
16
+
17
+ spec.files = `git ls-files -z`.split("\x0")
18
+ spec.test_files = []
19
+ spec.rdoc_options = ["--charset=UTF-8"]
20
+ spec.require_paths = ["lib"]
21
+
22
+ spec.required_ruby_version = '>= 1.8.7'
23
+
24
+ private_key = File.expand_path('~/.gem/rspec-gem-private_key.pem')
25
+ if File.exist?(private_key)
26
+ spec.signing_key = private_key
27
+ spec.cert_chain = [File.expand_path('~/.gem/rspec-gem-public_cert.pem')]
28
+ end
29
+
30
+ spec.add_runtime_dependency "rspec-core", ">= 3.0.0.beta2"
31
+ spec.add_runtime_dependency "rspec-support", ">= 3.0.0.beta2"
32
+
33
+ spec.add_development_dependency "cucumber", "~> 1.3"
34
+ spec.add_development_dependency "aruba", "~> 0.5"
35
+ spec.add_development_dependency "rake", "~> 10.0.0"
36
+
37
+ # For legacy custom formatter regression tests
38
+ spec.add_development_dependency "fuubar", "1.3.2"
39
+ spec.add_development_dependency "nyan-cat-formatter", "0.5.2"
40
+ spec.add_development_dependency "rspec-instafail", "0.2.4"
41
+ spec.add_development_dependency "rspec-extra-formatters", "1.0.0"
42
+ spec.add_development_dependency "fivemat", "1.2.1"
43
+ end
@@ -0,0 +1,144 @@
1
+ # This file was generated on 2014-03-30T13:16:22-07:00 from the rspec-dev repo.
2
+ # DO NOT modify it by hand as your changes will get lost the next time it is generated.
3
+
4
+ # idea taken from: http://blog.headius.com/2010/03/jruby-startup-time-tips.html
5
+ export JRUBY_OPTS='-X-C' # disable JIT since these processes are so short lived
6
+ SPECS_HAVE_RUN_FILE=specs.out
7
+ MAINTENANCE_BRANCH=`cat maintenance-branch`
8
+
9
+ # Taken from:
10
+ # https://github.com/travis-ci/travis-build/blob/e9314616e182a23e6a280199cd9070bfc7cae548/lib/travis/build/script/templates/header.sh#L34-L53
11
+ travis_retry() {
12
+ local result=0
13
+ local count=1
14
+ while [ $count -le 3 ]; do
15
+ [ $result -ne 0 ] && {
16
+ echo -e "\n\033[33;1mThe command \"$@\" failed. Retrying, $count of 3.\033[0m\n" >&2
17
+ }
18
+ "$@"
19
+ result=$?
20
+ [ $result -eq 0 ] && break
21
+ count=$(($count + 1))
22
+ sleep 1
23
+ done
24
+
25
+ [ $count -eq 3 ] && {
26
+ echo "\n\033[33;1mThe command \"$@\" failed 3 times.\033[0m\n" >&2
27
+ }
28
+
29
+ return $result
30
+ }
31
+
32
+ function is_mri {
33
+ if ruby -e "exit(!defined?(RUBY_ENGINE) || RUBY_ENGINE == 'ruby')"; then
34
+ # RUBY_ENGINE only returns 'ruby' on MRI.
35
+ # MRI 1.8.7 lacks the constant but all other rubies have it (including JRuby in 1.8 mode)
36
+ return 0
37
+ else
38
+ return 1
39
+ fi;
40
+ }
41
+
42
+ function is_mri_192 {
43
+ if is_mri; then
44
+ if ruby -e "exit(RUBY_VERSION == '1.9.2')"; then
45
+ return 0
46
+ else
47
+ return 1
48
+ fi
49
+ else
50
+ return 1
51
+ fi
52
+ }
53
+
54
+ function rspec_support_compatible {
55
+ if [ "$MAINTENANCE_BRANCH" != "2-99-maintenance" ] && [ "$MAINTENANCE_BRANCH" != "2-14-maintenance" ]; then
56
+ return 0
57
+ else
58
+ return 1
59
+ fi
60
+ }
61
+
62
+ function documentation_enforced {
63
+ if [ -x ./bin/yard ]; then
64
+ return 0
65
+ else
66
+ return 1
67
+ fi
68
+ }
69
+
70
+ function clone_repo {
71
+ if [ ! -d $1 ]; then # don't clone if the dir is already there
72
+ travis_retry git clone git://github.com/rspec/$1 --depth 1 --branch $MAINTENANCE_BRANCH
73
+ fi;
74
+ }
75
+
76
+ function run_specs_and_record_done {
77
+ local rspec_bin=bin/rspec
78
+
79
+ # rspec-core needs to run with a special script that loads simplecov first,
80
+ # so that it can instrument rspec-core's code before rspec-core has been loaded.
81
+ if [ -f script/rspec_with_simplecov ]; then
82
+ rspec_bin=script/rspec_with_simplecov
83
+ fi;
84
+
85
+ $rspec_bin spec --backtrace --format progress --profile --format progress --out $SPECS_HAVE_RUN_FILE
86
+ }
87
+
88
+ function run_cukes {
89
+ if [ -d features ]; then
90
+ # force jRuby to use client mode JVM or a compilation mode thats as close as possible,
91
+ # idea taken from https://github.com/jruby/jruby/wiki/Improving-startup-time
92
+ #
93
+ # Note that we delay setting this until we run the cukes because we've seen
94
+ # spec failures in our spec suite due to problems with this mode.
95
+ export JAVA_OPTS='-client -XX:+TieredCompilation -XX:TieredStopAtLevel=1'
96
+
97
+ if is_mri_192; then
98
+ # For some reason we get SystemStackError on 1.9.2 when using
99
+ # the bin/cucumber approach below. That approach is faster
100
+ # (as it avoids the bundler tax), so we use it on rubies where we can.
101
+ bundle exec cucumber --strict
102
+ else
103
+ # Prepare RUBYOPT for scenarios that are shelling out to ruby,
104
+ # and PATH for those that are using `rspec` or `rake`.
105
+ RUBYOPT="-I${PWD}/../bundle -rbundler/setup" \
106
+ PATH="${PWD}/bin:$PATH" \
107
+ bin/cucumber --strict
108
+ fi
109
+ fi
110
+ }
111
+
112
+ function run_specs_one_by_one {
113
+ for file in `find spec -iname '*_spec.rb'`; do
114
+ bin/rspec $file -b --format progress
115
+ done
116
+ }
117
+
118
+ function run_spec_suite_for {
119
+ if [ ! -f ../$1/$SPECS_HAVE_RUN_FILE ]; then # don't rerun specs that have already run
120
+ pushd ../$1
121
+ echo
122
+ echo "Running specs for $1"
123
+ echo
124
+ unset BUNDLE_GEMFILE
125
+ bundle_install_flags=`cat .travis.yml | grep bundler_args | tr -d '"' | grep -o " .*"`
126
+ travis_retry bundle install $bundle_install_flags
127
+ run_specs_and_record_done
128
+ popd
129
+ fi;
130
+ }
131
+
132
+ function check_documentation_coverage {
133
+ bin/yard stats --list-undoc | ruby -e "
134
+ while line = gets
135
+ coverage ||= line[/([\d\.]+)% documented/, 1]
136
+ puts line
137
+ end
138
+
139
+ unless Float(coverage) == 100
140
+ puts \"\n\nMissing documentation coverage (currently at #{coverage}%)\"
141
+ exit(1)
142
+ end
143
+ "
144
+ }
@@ -0,0 +1,13 @@
1
+ #!/bin/bash
2
+ # This file was generated on 2014-03-30T13:16:22-07:00 from the rspec-dev repo.
3
+ # DO NOT modify it by hand as your changes will get lost the next time it is generated.
4
+
5
+ set -e -x
6
+ source script/functions.sh
7
+
8
+ run_specs_and_record_done
9
+ run_cukes
10
+
11
+ if documentation_enforced; then
12
+ check_documentation_coverage
13
+ fi
@@ -0,0 +1,184 @@
1
+ require 'rspec/core/formatters/console_codes'
2
+ require 'rspec/legacy_formatters'
3
+
4
+ RSpec.describe RSpec::LegacyFormatters do
5
+ include FormatterSupport
6
+
7
+ it 'can access attributes provided by base class accessors in #initialize' do
8
+ klass = Class.new(LegacyFormatterUsingSubClassing) do
9
+ def initialize(*args)
10
+ examples
11
+ super
12
+ end
13
+ end
14
+
15
+ config.add_formatter klass
16
+ expect(config.formatters.first).to be_a(RSpec::LegacyFormatters::Adaptor)
17
+ expect(config.formatters.first.formatter).to be_a(klass)
18
+ end
19
+
20
+ [OldStyleFormatterExample, LegacyFormatterUsingSubClassing].each do |klass|
21
+
22
+ describe "#{klass}" do
23
+ let(:described_class) { klass }
24
+
25
+ describe "#start" do
26
+ it "notifies formatter of start" do
27
+ send_notification :start, start_notification(5)
28
+ expect(output.string).to include "Started 5 examples"
29
+ end
30
+ end
31
+
32
+ describe "#example_group_started" do
33
+ it "notifies formatter of example_group_started" do
34
+ send_notification :example_group_started, group_notification
35
+ expect(output.string).to include "Started Group"
36
+ end
37
+ end
38
+
39
+ describe "#example_group_finished" do
40
+ it "notifies formatter of example_group_finished" do
41
+ send_notification :example_group_finished, group_notification
42
+ expect(output.string).to include "Finished Group"
43
+ end
44
+ end
45
+
46
+ describe "#example_started" do
47
+ it "notifies formatter of example_started" do
48
+ send_notification :example_started, example_notification
49
+ expect(output.string).to include "Started Example"
50
+ end
51
+ end
52
+
53
+ describe "#example_passed" do
54
+ it "notifies formatter of example_passed" do
55
+ send_notification :example_passed, example_notification
56
+ expect(output.string).to include "."
57
+ end
58
+ end
59
+
60
+ describe "#example_pending" do
61
+ it "notifies formatter of example_pending" do
62
+ send_notification :example_pending, example_notification
63
+ expect(output.string).to include "P"
64
+ end
65
+ end
66
+
67
+ describe "#example_failed" do
68
+ it "notifies formatter of example_failed" do
69
+ send_notification :example_failed, example_notification
70
+ expect(output.string).to include "F"
71
+ end
72
+ end
73
+
74
+ describe "#message" do
75
+ it "notifies formatter of message" do
76
+ send_notification :message, message_notification("A Message")
77
+ expect(output.string).to include "A Message"
78
+ end
79
+ end
80
+
81
+ describe "#stop" do
82
+ it "notifies formatter of stop" do
83
+ send_notification :stop, null_notification
84
+ expect(output.string).to include "Stopped"
85
+ end
86
+ end
87
+
88
+ describe "#start_dump" do
89
+ it "notifies formatter of start_dump" do
90
+ send_notification :start_dump, null_notification
91
+ expect(output.string).to include "Dumping!"
92
+ end
93
+ end
94
+
95
+ describe "#dump_failures" do
96
+ it "notifies formatter of dump_failures" do
97
+ send_notification :dump_failures, null_notification
98
+ expect(output.string).to include "Failures:"
99
+ end
100
+ end
101
+
102
+ describe "#dump_summary" do
103
+ it "notifies formatter of dump_summary" do
104
+ duration, count, failures, pending = 3.5, 10, 3, 2
105
+ send_notification :dump_summary, summary_notification(duration, count, failures, pending, 0)
106
+ expect(output.string).to(
107
+ match("Finished in 3.5").
108
+ and match("3/10 failed.").
109
+ and match("2 pending.")
110
+ )
111
+ end
112
+ end
113
+
114
+ describe "#dump_pending" do
115
+ it "notifies formatter of dump_pending" do
116
+ send_notification :dump_pending, null_notification
117
+ expect(output.string).to match "Pending:"
118
+ end
119
+ end
120
+
121
+ describe "#seed" do
122
+ it "notifies formatter of seed" do
123
+ send_notification :seed, seed_notification(17)
124
+ expect(output.string).to match "Randomized with seed 17"
125
+ end
126
+ end
127
+
128
+ describe "#close" do
129
+ it "notifies formatter of close" do
130
+ send_notification :close, null_notification
131
+ end
132
+ end
133
+ end
134
+ end
135
+
136
+ describe LegacyFormatterUsingSubClassing do
137
+ let(:legacy_formatter) { formatter.formatter }
138
+
139
+ it "will lookup colour codes" do
140
+ expect(legacy_formatter.color_code_for(:black)).to eq 30
141
+ end
142
+
143
+ it "will colorize text" do
144
+ allow(RSpec.configuration).to receive(:color_enabled?) { true }
145
+ expect(legacy_formatter.colorize("text", :black)).to eq "\e[30mtext\e[0m"
146
+ end
147
+
148
+ it "will colorize summary" do
149
+ allow(RSpec.configuration).to receive(:color_enabled?) { true }
150
+ expect(legacy_formatter.colorise_summary("text")).to include "\e[32mtext\e[0m"
151
+ end
152
+
153
+ it "allows access to the deprecated constants" do
154
+ pending "caller filter update"
155
+ legacy_formatter
156
+ expect_deprecation_with_call_site(__FILE__, __LINE__ + 1)
157
+ expect(described_class::VT100_COLORS).to eq ::RSpec::Core::Formatters::ConsoleCodes::VT100_CODES
158
+ expect_deprecation_with_call_site(__FILE__, __LINE__ + 1)
159
+ expect(described_class::VT100_COLOR_CODES).to eq ::RSpec::Core::Formatters::ConsoleCodes::VT100_CODE_VALUES
160
+ end
161
+
162
+ ::RSpec::Core::Formatters::ConsoleCodes::VT100_CODES.each do |name, number|
163
+ next if name == :black || name == :bold
164
+
165
+ describe "##{name}" do
166
+ before do
167
+ allow(RSpec.configuration).to receive(:color_enabled?) { true }
168
+ allow(RSpec).to receive(:deprecate)
169
+ end
170
+
171
+ it "prints the text using the color code for #{name}" do
172
+ expect(legacy_formatter.send(name, "text")).to eq("\e[#{number}mtext\e[0m")
173
+ end
174
+
175
+ it "prints a deprecation warning" do
176
+ expect(RSpec).to receive(:deprecate) {|*args|
177
+ expect(args.first).to match(/#{name}/)
178
+ }
179
+ legacy_formatter.send(name, "text")
180
+ end
181
+ end
182
+ end
183
+ end
184
+ end