rspec-legacy_formatters 1.0.0.rc1

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.
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