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.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/.document +1 -1
- data/.yardopts +1 -1
- data/Changelog.md +88 -0
- data/{License.txt → LICENSE.md} +6 -5
- data/README.md +18 -3
- data/lib/rspec/core/bisect/example_minimizer.rb +78 -39
- data/lib/rspec/core/configuration.rb +87 -25
- data/lib/rspec/core/configuration_options.rb +1 -1
- data/lib/rspec/core/example.rb +55 -7
- data/lib/rspec/core/example_group.rb +28 -8
- data/lib/rspec/core/example_status_persister.rb +16 -16
- data/lib/rspec/core/formatters/bisect_progress_formatter.rb +44 -15
- data/lib/rspec/core/formatters/exception_presenter.rb +150 -59
- data/lib/rspec/core/formatters/helpers.rb +1 -1
- data/lib/rspec/core/formatters/html_formatter.rb +3 -3
- data/lib/rspec/core/formatters/html_printer.rb +2 -3
- data/lib/rspec/core/formatters/html_snippet_extractor.rb +116 -0
- data/lib/rspec/core/formatters/protocol.rb +9 -0
- data/lib/rspec/core/formatters/snippet_extractor.rb +124 -97
- data/lib/rspec/core/formatters.rb +2 -1
- data/lib/rspec/core/hooks.rb +2 -2
- data/lib/rspec/core/memoized_helpers.rb +2 -2
- data/lib/rspec/core/metadata.rb +3 -2
- data/lib/rspec/core/metadata_filter.rb +11 -6
- data/lib/rspec/core/notifications.rb +3 -2
- data/lib/rspec/core/option_parser.rb +22 -4
- data/lib/rspec/core/project_initializer/spec/spec_helper.rb +2 -2
- data/lib/rspec/core/rake_task.rb +12 -3
- data/lib/rspec/core/reporter.rb +18 -2
- data/lib/rspec/core/ruby_project.rb +1 -1
- data/lib/rspec/core/shared_example_group.rb +2 -0
- data/lib/rspec/core/source/location.rb +13 -0
- data/lib/rspec/core/source/node.rb +93 -0
- data/lib/rspec/core/source/syntax_highlighter.rb +71 -0
- data/lib/rspec/core/source/token.rb +43 -0
- data/lib/rspec/core/source.rb +76 -0
- data/lib/rspec/core/version.rb +1 -1
- data/lib/rspec/core/world.rb +25 -6
- data.tar.gz.sig +0 -0
- metadata +14 -11
- metadata.gz.sig +0 -0
- data/lib/rspec/core/bisect/subset_enumerator.rb +0 -39
- data/lib/rspec/core/mutex.rb +0 -63
- 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
|
data/lib/rspec/core/version.rb
CHANGED
data/lib/rspec/core/world.rb
CHANGED
@@ -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[:
|
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
|
-
|
130
|
+
report_filter_message("Run options: #{filter_announcements[0]}")
|
117
131
|
else
|
118
|
-
|
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
|
-
|
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
|
-
|
146
|
+
report_filter_message("No examples found.")
|
133
147
|
elsif exclusion_filter.empty? || inclusion_filter.empty?
|
134
|
-
|
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.
|
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-
|
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.
|
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.
|
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:
|
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:
|
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
|
-
-
|
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.
|
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
|
data/lib/rspec/core/mutex.rb
DELETED
@@ -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
|