rspec-core 3.3.0 → 3.4.0

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 (46) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/.document +1 -1
  4. data/.yardopts +1 -1
  5. data/Changelog.md +88 -0
  6. data/{License.txt → LICENSE.md} +6 -5
  7. data/README.md +18 -3
  8. data/lib/rspec/core/bisect/example_minimizer.rb +78 -39
  9. data/lib/rspec/core/configuration.rb +87 -25
  10. data/lib/rspec/core/configuration_options.rb +1 -1
  11. data/lib/rspec/core/example.rb +55 -7
  12. data/lib/rspec/core/example_group.rb +28 -8
  13. data/lib/rspec/core/example_status_persister.rb +16 -16
  14. data/lib/rspec/core/formatters/bisect_progress_formatter.rb +44 -15
  15. data/lib/rspec/core/formatters/exception_presenter.rb +150 -59
  16. data/lib/rspec/core/formatters/helpers.rb +1 -1
  17. data/lib/rspec/core/formatters/html_formatter.rb +3 -3
  18. data/lib/rspec/core/formatters/html_printer.rb +2 -3
  19. data/lib/rspec/core/formatters/html_snippet_extractor.rb +116 -0
  20. data/lib/rspec/core/formatters/protocol.rb +9 -0
  21. data/lib/rspec/core/formatters/snippet_extractor.rb +124 -97
  22. data/lib/rspec/core/formatters.rb +2 -1
  23. data/lib/rspec/core/hooks.rb +2 -2
  24. data/lib/rspec/core/memoized_helpers.rb +2 -2
  25. data/lib/rspec/core/metadata.rb +3 -2
  26. data/lib/rspec/core/metadata_filter.rb +11 -6
  27. data/lib/rspec/core/notifications.rb +3 -2
  28. data/lib/rspec/core/option_parser.rb +22 -4
  29. data/lib/rspec/core/project_initializer/spec/spec_helper.rb +2 -2
  30. data/lib/rspec/core/rake_task.rb +12 -3
  31. data/lib/rspec/core/reporter.rb +18 -2
  32. data/lib/rspec/core/ruby_project.rb +1 -1
  33. data/lib/rspec/core/shared_example_group.rb +2 -0
  34. data/lib/rspec/core/source/location.rb +13 -0
  35. data/lib/rspec/core/source/node.rb +93 -0
  36. data/lib/rspec/core/source/syntax_highlighter.rb +71 -0
  37. data/lib/rspec/core/source/token.rb +43 -0
  38. data/lib/rspec/core/source.rb +76 -0
  39. data/lib/rspec/core/version.rb +1 -1
  40. data/lib/rspec/core/world.rb +25 -6
  41. data.tar.gz.sig +0 -0
  42. metadata +14 -11
  43. metadata.gz.sig +0 -0
  44. data/lib/rspec/core/bisect/subset_enumerator.rb +0 -39
  45. data/lib/rspec/core/mutex.rb +0 -63
  46. data/lib/rspec/core/reentrant_mutex.rb +0 -52
@@ -0,0 +1,71 @@
1
+ module RSpec
2
+ module Core
3
+ class Source
4
+ # @private
5
+ # Provides terminal syntax highlighting of code snippets
6
+ # when coderay is available.
7
+ class SyntaxHighlighter
8
+ def initialize(configuration)
9
+ @configuration = configuration
10
+ end
11
+
12
+ def highlight(lines)
13
+ implementation.highlight_syntax(lines)
14
+ end
15
+
16
+ private
17
+
18
+ if RSpec::Support::OS.windows?
19
+ # :nocov:
20
+ def implementation
21
+ WindowsImplementation
22
+ end
23
+ # :nocov:
24
+ else
25
+ def implementation
26
+ return color_enabled_implementation if @configuration.color_enabled?
27
+ NoSyntaxHighlightingImplementation
28
+ end
29
+ end
30
+
31
+ def color_enabled_implementation
32
+ @color_enabled_implementation ||= begin
33
+ ::Kernel.require 'coderay'
34
+ CodeRayImplementation
35
+ rescue LoadError
36
+ NoSyntaxHighlightingImplementation
37
+ end
38
+ end
39
+
40
+ # @private
41
+ module CodeRayImplementation
42
+ RESET_CODE = "\e[0m"
43
+
44
+ def self.highlight_syntax(lines)
45
+ highlighted = begin
46
+ CodeRay.encode(lines.join("\n"), :ruby, :terminal)
47
+ rescue Support::AllExceptionsExceptOnesWeMustNotRescue
48
+ return lines
49
+ end
50
+
51
+ highlighted.split("\n").map do |line|
52
+ line.sub(/\S/) { |char| char.insert(0, RESET_CODE) }
53
+ end
54
+ end
55
+ end
56
+
57
+ # @private
58
+ module NoSyntaxHighlightingImplementation
59
+ def self.highlight_syntax(lines)
60
+ lines
61
+ end
62
+ end
63
+
64
+ # @private
65
+ # Not sure why, but our code above (and/or coderay itself) does not work
66
+ # on Windows, so we disable the feature on Windows.
67
+ WindowsImplementation = NoSyntaxHighlightingImplementation
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,43 @@
1
+ RSpec::Support.require_rspec_core "source/location"
2
+
3
+ module RSpec
4
+ module Core
5
+ class Source
6
+ # @private
7
+ # A wrapper for Ripper token which is generated with `Ripper.lex`.
8
+ class Token
9
+ attr_reader :token
10
+
11
+ def self.tokens_from_ripper_tokens(ripper_tokens)
12
+ ripper_tokens.map { |ripper_token| new(ripper_token) }.freeze
13
+ end
14
+
15
+ def initialize(ripper_token)
16
+ @token = ripper_token.freeze
17
+ end
18
+
19
+ def location
20
+ @location ||= Location.new(*token[0])
21
+ end
22
+
23
+ def type
24
+ token[1]
25
+ end
26
+
27
+ def string
28
+ token[2]
29
+ end
30
+
31
+ def ==(other)
32
+ token == other.token
33
+ end
34
+
35
+ alias_method :eql?, :==
36
+
37
+ def inspect
38
+ "#<#{self.class} #{type} #{string.inspect}>"
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,76 @@
1
+ RSpec::Support.require_rspec_core 'source/node'
2
+ RSpec::Support.require_rspec_core 'source/syntax_highlighter'
3
+ RSpec::Support.require_rspec_core 'source/token'
4
+
5
+ module RSpec
6
+ module Core
7
+ # @private
8
+ # Represents a Ruby source file and provides access to AST and tokens.
9
+ class Source
10
+ attr_reader :source, :path
11
+
12
+ def self.from_file(path)
13
+ source = File.read(path)
14
+ new(source, path)
15
+ end
16
+
17
+ def initialize(source_string, path=nil)
18
+ @source = source_string
19
+ @path = path ? File.expand_path(path) : '(string)'
20
+ end
21
+
22
+ def lines
23
+ @lines ||= source.split("\n")
24
+ end
25
+
26
+ def ast
27
+ @ast ||= begin
28
+ require 'ripper'
29
+ sexp = Ripper.sexp(source)
30
+ raise SyntaxError unless sexp
31
+ Node.new(sexp)
32
+ end
33
+ end
34
+
35
+ def tokens
36
+ @tokens ||= begin
37
+ require 'ripper'
38
+ tokens = Ripper.lex(source)
39
+ Token.tokens_from_ripper_tokens(tokens)
40
+ end
41
+ end
42
+
43
+ def nodes_by_line_number
44
+ @nodes_by_line_number ||= begin
45
+ nodes_by_line_number = ast.select(&:location).group_by { |node| node.location.line }
46
+ Hash.new { |hash, key| hash[key] = [] }.merge(nodes_by_line_number)
47
+ end
48
+ end
49
+
50
+ def tokens_by_line_number
51
+ @tokens_by_line_number ||= begin
52
+ nodes_by_line_number = tokens.group_by { |token| token.location.line }
53
+ Hash.new { |hash, key| hash[key] = [] }.merge(nodes_by_line_number)
54
+ end
55
+ end
56
+
57
+ def inspect
58
+ "#<#{self.class} #{path}>"
59
+ end
60
+
61
+ # @private
62
+ class Cache
63
+ attr_reader :syntax_highlighter
64
+
65
+ def initialize(configuration)
66
+ @sources_by_path = {}
67
+ @syntax_highlighter = SyntaxHighlighter.new(configuration)
68
+ end
69
+
70
+ def source_from_file(path)
71
+ @sources_by_path[path] ||= Source.from_file(path)
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end
@@ -3,7 +3,7 @@ module RSpec
3
3
  # Version information for RSpec Core.
4
4
  module Version
5
5
  # Current version of RSpec Core, in semantic versioning format.
6
- STRING = '3.3.0'
6
+ STRING = '3.4.0'
7
7
  end
8
8
  end
9
9
  end
@@ -40,12 +40,18 @@ module RSpec
40
40
  @configuration.filter_manager
41
41
  end
42
42
 
43
+ # @private
44
+ def registered_example_group_files
45
+ @example_group_counts_by_spec_file.keys
46
+ end
47
+
43
48
  # @api private
44
49
  #
45
50
  # Register an example group.
46
51
  def register(example_group)
52
+ @configuration.on_example_group_definition_callbacks.each { |block| block.call(example_group) }
47
53
  example_groups << example_group
48
- @example_group_counts_by_spec_file[example_group.metadata[:file_path]] += 1
54
+ @example_group_counts_by_spec_file[example_group.metadata[:absolute_file_path]] += 1
49
55
  example_group
50
56
  end
51
57
 
@@ -101,6 +107,14 @@ module RSpec
101
107
  @configuration.reporter
102
108
  end
103
109
 
110
+ # @private
111
+ def source_cache
112
+ @source_cache ||= begin
113
+ RSpec::Support.require_rspec_core "source"
114
+ Source::Cache.new(@configuration)
115
+ end
116
+ end
117
+
104
118
  # @api private
105
119
  #
106
120
  # Notify reporter of filters.
@@ -113,14 +127,14 @@ module RSpec
113
127
 
114
128
  unless filter_manager.empty?
115
129
  if filter_announcements.length == 1
116
- reporter.message("Run options: #{filter_announcements[0]}")
130
+ report_filter_message("Run options: #{filter_announcements[0]}")
117
131
  else
118
- reporter.message("Run options:\n #{filter_announcements.join("\n ")}")
132
+ report_filter_message("Run options:\n #{filter_announcements.join("\n ")}")
119
133
  end
120
134
  end
121
135
 
122
136
  if @configuration.run_all_when_everything_filtered? && example_count.zero? && !@configuration.only_failures?
123
- reporter.message("#{everything_filtered_message}; ignoring #{inclusion_filter.description}")
137
+ report_filter_message("#{everything_filtered_message}; ignoring #{inclusion_filter.description}")
124
138
  filtered_examples.clear
125
139
  inclusion_filter.clear
126
140
  end
@@ -129,12 +143,17 @@ module RSpec
129
143
 
130
144
  example_groups.clear
131
145
  if filter_manager.empty?
132
- reporter.message("No examples found.")
146
+ report_filter_message("No examples found.")
133
147
  elsif exclusion_filter.empty? || inclusion_filter.empty?
134
- reporter.message(everything_filtered_message)
148
+ report_filter_message(everything_filtered_message)
135
149
  end
136
150
  end
137
151
 
152
+ # @private
153
+ def report_filter_message(message)
154
+ reporter.message(message) unless @configuration.silence_filter_announcements?
155
+ end
156
+
138
157
  # @private
139
158
  def everything_filtered_message
140
159
  "\nAll examples were filtered out"
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rspec-core
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.3.0
4
+ version: 3.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Steven Baker
@@ -46,7 +46,7 @@ cert_chain:
46
46
  ZsVDj6a7lH3cNqtWXZxrb2wO38qV5AkYj8SQK7Hj3/Yui9myUX3crr+PdetazSqQ
47
47
  F3MdtaDehhjC
48
48
  -----END CERTIFICATE-----
49
- date: 2015-06-12 00:00:00.000000000 Z
49
+ date: 2015-11-12 00:00:00.000000000 Z
50
50
  dependencies:
51
51
  - !ruby/object:Gem::Dependency
52
52
  name: rspec-support
@@ -54,14 +54,14 @@ dependencies:
54
54
  requirements:
55
55
  - - "~>"
56
56
  - !ruby/object:Gem::Version
57
- version: 3.3.0
57
+ version: 3.4.0
58
58
  type: :runtime
59
59
  prerelease: false
60
60
  version_requirements: !ruby/object:Gem::Requirement
61
61
  requirements:
62
62
  - - "~>"
63
63
  - !ruby/object:Gem::Version
64
- version: 3.3.0
64
+ version: 3.4.0
65
65
  - !ruby/object:Gem::Dependency
66
66
  name: rake
67
67
  requirement: !ruby/object:Gem::Requirement
@@ -110,14 +110,14 @@ dependencies:
110
110
  requirements:
111
111
  - - "~>"
112
112
  - !ruby/object:Gem::Version
113
- version: '0.6'
113
+ version: 0.6.2
114
114
  type: :development
115
115
  prerelease: false
116
116
  version_requirements: !ruby/object:Gem::Requirement
117
117
  requirements:
118
118
  - - "~>"
119
119
  - !ruby/object:Gem::Version
120
- version: '0.6'
120
+ version: 0.6.2
121
121
  - !ruby/object:Gem::Dependency
122
122
  name: nokogiri
123
123
  requirement: !ruby/object:Gem::Requirement
@@ -212,7 +212,7 @@ files:
212
212
  - ".document"
213
213
  - ".yardopts"
214
214
  - Changelog.md
215
- - License.txt
215
+ - LICENSE.md
216
216
  - README.md
217
217
  - exe/rspec
218
218
  - lib/rspec/autorun.rb
@@ -222,7 +222,6 @@ files:
222
222
  - lib/rspec/core/bisect/example_minimizer.rb
223
223
  - lib/rspec/core/bisect/runner.rb
224
224
  - lib/rspec/core/bisect/server.rb
225
- - lib/rspec/core/bisect/subset_enumerator.rb
226
225
  - lib/rspec/core/configuration.rb
227
226
  - lib/rspec/core/configuration_options.rb
228
227
  - lib/rspec/core/drb.rb
@@ -245,6 +244,7 @@ files:
245
244
  - lib/rspec/core/formatters/helpers.rb
246
245
  - lib/rspec/core/formatters/html_formatter.rb
247
246
  - lib/rspec/core/formatters/html_printer.rb
247
+ - lib/rspec/core/formatters/html_snippet_extractor.rb
248
248
  - lib/rspec/core/formatters/json_formatter.rb
249
249
  - lib/rspec/core/formatters/profile_formatter.rb
250
250
  - lib/rspec/core/formatters/progress_formatter.rb
@@ -260,7 +260,6 @@ files:
260
260
  - lib/rspec/core/mocking_adapters/null.rb
261
261
  - lib/rspec/core/mocking_adapters/rr.rb
262
262
  - lib/rspec/core/mocking_adapters/rspec.rb
263
- - lib/rspec/core/mutex.rb
264
263
  - lib/rspec/core/notifications.rb
265
264
  - lib/rspec/core/option_parser.rb
266
265
  - lib/rspec/core/ordering.rb
@@ -270,7 +269,6 @@ files:
270
269
  - lib/rspec/core/project_initializer/.rspec
271
270
  - lib/rspec/core/project_initializer/spec/spec_helper.rb
272
271
  - lib/rspec/core/rake_task.rb
273
- - lib/rspec/core/reentrant_mutex.rb
274
272
  - lib/rspec/core/reporter.rb
275
273
  - lib/rspec/core/ruby_project.rb
276
274
  - lib/rspec/core/runner.rb
@@ -279,6 +277,11 @@ files:
279
277
  - lib/rspec/core/shared_context.rb
280
278
  - lib/rspec/core/shared_example_group.rb
281
279
  - lib/rspec/core/shell_escape.rb
280
+ - lib/rspec/core/source.rb
281
+ - lib/rspec/core/source/location.rb
282
+ - lib/rspec/core/source/node.rb
283
+ - lib/rspec/core/source/syntax_highlighter.rb
284
+ - lib/rspec/core/source/token.rb
282
285
  - lib/rspec/core/test_unit_assertions_adapter.rb
283
286
  - lib/rspec/core/version.rb
284
287
  - lib/rspec/core/warnings.rb
@@ -307,6 +310,6 @@ rubyforge_project:
307
310
  rubygems_version: 2.2.2
308
311
  signing_key:
309
312
  specification_version: 4
310
- summary: rspec-core-3.3.0
313
+ summary: rspec-core-3.4.0
311
314
  test_files: []
312
315
  has_rdoc:
metadata.gz.sig CHANGED
Binary file
@@ -1,39 +0,0 @@
1
- module RSpec
2
- module Core
3
- module Bisect
4
- # Enumerates each subset of the given list of ids that is half the
5
- # size of the total list, so that hopefully we can discard half the
6
- # list each repeatedly in order to our minimal repro case.
7
- # @private
8
- class SubsetEnumerator
9
- include Enumerable
10
-
11
- def initialize(ids)
12
- @ids = ids
13
- end
14
-
15
- def subset_size
16
- @subset_size ||= (@ids.size / 2.0).ceil
17
- end
18
-
19
- def each
20
- yielded = Set.new
21
- slice_size = subset_size
22
- combo_count = 1
23
-
24
- while slice_size > 0
25
- @ids.each_slice(slice_size).to_a.combination(combo_count) do |combos|
26
- subset = combos.flatten
27
- next if yielded.include?(subset)
28
- yield subset
29
- yielded << subset
30
- end
31
-
32
- slice_size /= 2
33
- combo_count *= 2
34
- end
35
- end
36
- end
37
- end
38
- end
39
- end
@@ -1,63 +0,0 @@
1
- module RSpec
2
- module Core
3
- # On 1.8.7, it's in the stdlib.
4
- # We don't want to load the stdlib, b/c this is a test tool, and can affect the test environment,
5
- # causing tests to pass where they should fail.
6
- #
7
- # So we're transcribing/modifying it from https://github.com/ruby/ruby/blob/v1_8_7_374/lib/thread.rb#L56
8
- # Some methods we don't need are deleted.
9
- # Anything I don't understand (there's quite a bit, actually) is left in.
10
- # Some formating changes are made to appease the robot overlord:
11
- # https://travis-ci.org/rspec/rspec-core/jobs/54410874
12
- # @private
13
- class Mutex
14
- def initialize
15
- @waiting = []
16
- @locked = false
17
- @waiting.taint
18
- taint
19
- end
20
-
21
- # @private
22
- def lock
23
- while Thread.critical = true && @locked
24
- @waiting.push Thread.current
25
- Thread.stop
26
- end
27
- @locked = true
28
- Thread.critical = false
29
- self
30
- end
31
-
32
- # @private
33
- def unlock
34
- return unless @locked
35
- Thread.critical = true
36
- @locked = false
37
- begin
38
- t = @waiting.shift
39
- t.wakeup if t
40
- rescue ThreadError
41
- retry
42
- end
43
- Thread.critical = false
44
- begin
45
- t.run if t
46
- rescue ThreadError
47
- :noop
48
- end
49
- self
50
- end
51
-
52
- # @private
53
- def synchronize
54
- lock
55
- begin
56
- yield
57
- ensure
58
- unlock
59
- end
60
- end
61
- end unless defined?(::RSpec::Core::Mutex) # Avoid warnings for library wide checks spec
62
- end
63
- end
@@ -1,52 +0,0 @@
1
- module RSpec
2
- module Core
3
- # Allows a thread to lock out other threads from a critical section of code,
4
- # while allowing the thread with the lock to reenter that section.
5
- #
6
- # Based on Monitor as of 2.2 - https://github.com/ruby/ruby/blob/eb7ddaa3a47bf48045d26c72eb0f263a53524ebc/lib/monitor.rb#L9
7
- #
8
- # Depends on Mutex, but Mutex is only available as part of core since 1.9.1:
9
- # exists - http://ruby-doc.org/core-1.9.1/Mutex.html
10
- # dne - http://ruby-doc.org/core-1.9.0/Mutex.html
11
- #
12
- # @private
13
- class ReentrantMutex
14
- def initialize
15
- @owner = nil
16
- @count = 0
17
- @mutex = Mutex.new
18
- end
19
-
20
- def synchronize
21
- enter
22
- yield
23
- ensure
24
- exit
25
- end
26
-
27
- private
28
-
29
- def enter
30
- @mutex.lock if @owner != Thread.current
31
- @owner = Thread.current
32
- @count += 1
33
- end
34
-
35
- def exit
36
- @count -= 1
37
- return unless @count == 0
38
- @owner = nil
39
- @mutex.unlock
40
- end
41
- end
42
-
43
- if defined? ::Mutex
44
- # On 1.9 and up, this is in core, so we just use the real one
45
- Mutex = ::Mutex
46
- else # For 1.8.7
47
- # :nocov:
48
- RSpec::Support.require_rspec_core "mutex"
49
- # :nocov:
50
- end
51
- end
52
- end