rspec-support 3.6.0.beta2 → 3.6.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.tar.gz.sig +0 -0
- data/Changelog.md +8 -1
- data/lib/rspec/support/object_formatter.rb +6 -1
- data/lib/rspec/support/ruby_features.rb +8 -3
- data/lib/rspec/support/source.rb +75 -0
- data/lib/rspec/support/source/location.rb +21 -0
- data/lib/rspec/support/source/node.rb +107 -0
- data/lib/rspec/support/source/token.rb +87 -0
- data/lib/rspec/support/spec/in_sub_process.rb +29 -12
- data/lib/rspec/support/version.rb +1 -1
- metadata +10 -6
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a39471f0a21ffe1247f79c44e1e2975452335c0d
|
4
|
+
data.tar.gz: a0b069a829099dc903dc988dd2dfaa640e8492a7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 89338ce6b89473bd3bd5aa5d1d8d37270d144799f222bed8a2261d8e07d84aaafdfeedb4f18e58e1270583919e61ff9c5b5af4383adf9c872184cd83b7965947
|
7
|
+
data.tar.gz: acd5ecc188371e729570a9d9d82fba8bb57a8ba220ad5aed7d3bafb612e4e185b07c47305612b75d3736831de260234bc9a880fd555790351c3a24aec7d1bafa
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data.tar.gz.sig
CHANGED
Binary file
|
data/Changelog.md
CHANGED
@@ -1,7 +1,14 @@
|
|
1
|
+
### 3.6.0 / 2017-05-04
|
2
|
+
[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.6.0.beta2...3.6.0)
|
3
|
+
|
4
|
+
Enhancements:
|
5
|
+
|
6
|
+
* Import `Source` classes from rspec-core. (Yuji Nakayama, #315)
|
7
|
+
|
1
8
|
### 3.6.0.beta2 / 2016-12-12
|
2
9
|
[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.6.0.beta1...v3.6.0.beta2)
|
3
10
|
|
4
|
-
No user-
|
11
|
+
No user-facing changes.
|
5
12
|
|
6
13
|
### 3.6.0.beta1 / 2016-10-09
|
7
14
|
[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.5.0...v3.6.0.beta1)
|
@@ -243,7 +243,12 @@ module RSpec
|
|
243
243
|
DescribableMatcherInspector,
|
244
244
|
DelegatorInspector,
|
245
245
|
InspectableObjectInspector
|
246
|
-
]
|
246
|
+
].tap do |classes|
|
247
|
+
# 2.4 has improved BigDecimal formatting so we do not need
|
248
|
+
# to provide our own.
|
249
|
+
# https://github.com/ruby/bigdecimal/pull/42
|
250
|
+
classes.delete(BigDecimalInspector) if RUBY_VERSION >= '2.4'
|
251
|
+
end
|
247
252
|
|
248
253
|
private
|
249
254
|
|
@@ -28,6 +28,10 @@ module RSpec
|
|
28
28
|
RUBY_PLATFORM == 'java'
|
29
29
|
end
|
30
30
|
|
31
|
+
def jruby_version
|
32
|
+
@jruby_version ||= ComparableVersion.new(JRUBY_VERSION)
|
33
|
+
end
|
34
|
+
|
31
35
|
def jruby_9000?
|
32
36
|
jruby? && JRUBY_VERSION >= '9.0.0.0'
|
33
37
|
end
|
@@ -75,9 +79,10 @@ module RSpec
|
|
75
79
|
ripper_requirements.push(false) if Ruby.rbx?
|
76
80
|
|
77
81
|
if Ruby.jruby?
|
78
|
-
ripper_requirements.push(
|
79
|
-
# Ripper on JRuby 9.0.0.0.rc1 or later reports wrong line number
|
80
|
-
|
82
|
+
ripper_requirements.push(Ruby.jruby_version >= '1.7.5')
|
83
|
+
# Ripper on JRuby 9.0.0.0.rc1 or later reports wrong line number
|
84
|
+
# or cannot parse source including `:if`.
|
85
|
+
ripper_requirements.push(Ruby.jruby_version < '9.0.0.0.rc1')
|
81
86
|
end
|
82
87
|
|
83
88
|
if ripper_requirements.all?
|
@@ -0,0 +1,75 @@
|
|
1
|
+
RSpec::Support.require_rspec_support 'encoded_string'
|
2
|
+
RSpec::Support.require_rspec_support 'ruby_features'
|
3
|
+
|
4
|
+
module RSpec
|
5
|
+
module Support
|
6
|
+
# @private
|
7
|
+
# Represents a Ruby source file and provides access to AST and tokens.
|
8
|
+
class Source
|
9
|
+
attr_reader :source, :path
|
10
|
+
|
11
|
+
def self.from_file(path)
|
12
|
+
source = File.read(path)
|
13
|
+
new(source, path)
|
14
|
+
end
|
15
|
+
|
16
|
+
if String.method_defined?(:encoding)
|
17
|
+
def initialize(source_string, path=nil)
|
18
|
+
@source = RSpec::Support::EncodedString.new(source_string, Encoding.default_external)
|
19
|
+
@path = path ? File.expand_path(path) : '(string)'
|
20
|
+
end
|
21
|
+
else # for 1.8.7
|
22
|
+
# :nocov:
|
23
|
+
def initialize(source_string, path=nil)
|
24
|
+
@source = RSpec::Support::EncodedString.new(source_string)
|
25
|
+
@path = path ? File.expand_path(path) : '(string)'
|
26
|
+
end
|
27
|
+
# :nocov:
|
28
|
+
end
|
29
|
+
|
30
|
+
def lines
|
31
|
+
@lines ||= source.split("\n")
|
32
|
+
end
|
33
|
+
|
34
|
+
def inspect
|
35
|
+
"#<#{self.class} #{path}>"
|
36
|
+
end
|
37
|
+
|
38
|
+
if RSpec::Support::RubyFeatures.ripper_supported?
|
39
|
+
RSpec::Support.require_rspec_support 'source/node'
|
40
|
+
RSpec::Support.require_rspec_support 'source/token'
|
41
|
+
|
42
|
+
def ast
|
43
|
+
@ast ||= begin
|
44
|
+
require 'ripper'
|
45
|
+
sexp = Ripper.sexp(source)
|
46
|
+
raise SyntaxError unless sexp
|
47
|
+
Node.new(sexp)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def tokens
|
52
|
+
@tokens ||= begin
|
53
|
+
require 'ripper'
|
54
|
+
tokens = Ripper.lex(source)
|
55
|
+
Token.tokens_from_ripper_tokens(tokens)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def nodes_by_line_number
|
60
|
+
@nodes_by_line_number ||= begin
|
61
|
+
nodes_by_line_number = ast.select(&:location).group_by { |node| node.location.line }
|
62
|
+
Hash.new { |hash, key| hash[key] = [] }.merge(nodes_by_line_number)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def tokens_by_line_number
|
67
|
+
@tokens_by_line_number ||= begin
|
68
|
+
nodes_by_line_number = tokens.group_by { |token| token.location.line }
|
69
|
+
Hash.new { |hash, key| hash[key] = [] }.merge(nodes_by_line_number)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module RSpec
|
2
|
+
module Support
|
3
|
+
class Source
|
4
|
+
# @private
|
5
|
+
# Represents a source location of node or token.
|
6
|
+
Location = Struct.new(:line, :column) do
|
7
|
+
include Comparable
|
8
|
+
|
9
|
+
def self.location?(array)
|
10
|
+
array.is_a?(Array) && array.size == 2 && array.all? { |e| e.is_a?(Integer) }
|
11
|
+
end
|
12
|
+
|
13
|
+
def <=>(other)
|
14
|
+
line_comparison = (line <=> other.line)
|
15
|
+
return line_comparison unless line_comparison == 0
|
16
|
+
column <=> other.column
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
RSpec::Support.require_rspec_support 'source/location'
|
2
|
+
|
3
|
+
module RSpec
|
4
|
+
module Support
|
5
|
+
class Source
|
6
|
+
# @private
|
7
|
+
# A wrapper for Ripper AST node which is generated with `Ripper.sexp`.
|
8
|
+
class Node
|
9
|
+
include Enumerable
|
10
|
+
|
11
|
+
attr_reader :sexp, :parent
|
12
|
+
|
13
|
+
def self.sexp?(array)
|
14
|
+
array.is_a?(Array) && array.first.is_a?(Symbol)
|
15
|
+
end
|
16
|
+
|
17
|
+
def initialize(ripper_sexp, parent=nil)
|
18
|
+
@sexp = ripper_sexp.freeze
|
19
|
+
@parent = parent
|
20
|
+
end
|
21
|
+
|
22
|
+
def type
|
23
|
+
sexp[0]
|
24
|
+
end
|
25
|
+
|
26
|
+
def args
|
27
|
+
@args ||= raw_args.map do |raw_arg|
|
28
|
+
if Node.sexp?(raw_arg)
|
29
|
+
Node.new(raw_arg, self)
|
30
|
+
elsif Location.location?(raw_arg)
|
31
|
+
Location.new(*raw_arg)
|
32
|
+
elsif raw_arg.is_a?(Array)
|
33
|
+
ExpressionSequenceNode.new(raw_arg, self)
|
34
|
+
else
|
35
|
+
raw_arg
|
36
|
+
end
|
37
|
+
end.freeze
|
38
|
+
end
|
39
|
+
|
40
|
+
def children
|
41
|
+
@children ||= args.select { |arg| arg.is_a?(Node) }.freeze
|
42
|
+
end
|
43
|
+
|
44
|
+
def location
|
45
|
+
@location ||= args.find { |arg| arg.is_a?(Location) }
|
46
|
+
end
|
47
|
+
|
48
|
+
def each(&block)
|
49
|
+
return to_enum(__method__) unless block_given?
|
50
|
+
|
51
|
+
yield self
|
52
|
+
|
53
|
+
children.each do |child|
|
54
|
+
child.each(&block)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def each_ancestor
|
59
|
+
return to_enum(__method__) unless block_given?
|
60
|
+
|
61
|
+
current_node = self
|
62
|
+
|
63
|
+
while (current_node = current_node.parent)
|
64
|
+
yield current_node
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def inspect
|
69
|
+
"#<#{self.class} #{type}>"
|
70
|
+
end
|
71
|
+
|
72
|
+
private
|
73
|
+
|
74
|
+
def raw_args
|
75
|
+
sexp[1..-1] || []
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
# @private
|
80
|
+
# Basically `Ripper.sexp` generates arrays whose first element is a symbol (type of sexp),
|
81
|
+
# but it exceptionally generates typeless arrays for expression sequence:
|
82
|
+
#
|
83
|
+
# Ripper.sexp('foo; bar')
|
84
|
+
# => [
|
85
|
+
# :program,
|
86
|
+
# [ # Typeless array
|
87
|
+
# [:vcall, [:@ident, "foo", [1, 0]]],
|
88
|
+
# [:vcall, [:@ident, "bar", [1, 5]]]
|
89
|
+
# ]
|
90
|
+
# ]
|
91
|
+
#
|
92
|
+
# We wrap typeless arrays in this pseudo type node
|
93
|
+
# so that it can be handled in the same way as other type node.
|
94
|
+
class ExpressionSequenceNode < Node
|
95
|
+
def type
|
96
|
+
:_expression_sequence
|
97
|
+
end
|
98
|
+
|
99
|
+
private
|
100
|
+
|
101
|
+
def raw_args
|
102
|
+
sexp
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
RSpec::Support.require_rspec_support 'source/location'
|
2
|
+
|
3
|
+
module RSpec
|
4
|
+
module Support
|
5
|
+
class Source
|
6
|
+
# @private
|
7
|
+
# A wrapper for Ripper token which is generated with `Ripper.lex`.
|
8
|
+
class Token
|
9
|
+
CLOSING_TYPES_BY_OPENING_TYPE = {
|
10
|
+
:on_lbracket => :on_rbracket,
|
11
|
+
:on_lparen => :on_rparen,
|
12
|
+
:on_lbrace => :on_rbrace,
|
13
|
+
:on_heredoc_beg => :on_heredoc_end
|
14
|
+
}.freeze
|
15
|
+
|
16
|
+
CLOSING_KEYWORDS_BY_OPENING_KEYWORD = {
|
17
|
+
'def' => 'end',
|
18
|
+
'do' => 'end',
|
19
|
+
}.freeze
|
20
|
+
|
21
|
+
attr_reader :token
|
22
|
+
|
23
|
+
def self.tokens_from_ripper_tokens(ripper_tokens)
|
24
|
+
ripper_tokens.map { |ripper_token| new(ripper_token) }.freeze
|
25
|
+
end
|
26
|
+
|
27
|
+
def initialize(ripper_token)
|
28
|
+
@token = ripper_token.freeze
|
29
|
+
end
|
30
|
+
|
31
|
+
def location
|
32
|
+
@location ||= Location.new(*token[0])
|
33
|
+
end
|
34
|
+
|
35
|
+
def type
|
36
|
+
token[1]
|
37
|
+
end
|
38
|
+
|
39
|
+
def string
|
40
|
+
token[2]
|
41
|
+
end
|
42
|
+
|
43
|
+
def ==(other)
|
44
|
+
token == other.token
|
45
|
+
end
|
46
|
+
|
47
|
+
alias_method :eql?, :==
|
48
|
+
|
49
|
+
def inspect
|
50
|
+
"#<#{self.class} #{type} #{string.inspect}>"
|
51
|
+
end
|
52
|
+
|
53
|
+
def keyword?
|
54
|
+
type == :on_kw
|
55
|
+
end
|
56
|
+
|
57
|
+
def opening?
|
58
|
+
opening_delimiter? || opening_keyword?
|
59
|
+
end
|
60
|
+
|
61
|
+
def closed_by?(other)
|
62
|
+
closed_by_delimiter?(other) || closed_by_keyword?(other)
|
63
|
+
end
|
64
|
+
|
65
|
+
private
|
66
|
+
|
67
|
+
def opening_delimiter?
|
68
|
+
CLOSING_TYPES_BY_OPENING_TYPE.key?(type)
|
69
|
+
end
|
70
|
+
|
71
|
+
def opening_keyword?
|
72
|
+
return false unless keyword?
|
73
|
+
CLOSING_KEYWORDS_BY_OPENING_KEYWORD.key?(string)
|
74
|
+
end
|
75
|
+
|
76
|
+
def closed_by_delimiter?(other)
|
77
|
+
other.type == CLOSING_TYPES_BY_OPENING_TYPE[type]
|
78
|
+
end
|
79
|
+
|
80
|
+
def closed_by_keyword?(other)
|
81
|
+
return false unless other.keyword?
|
82
|
+
other.string == CLOSING_KEYWORDS_BY_OPENING_KEYWORD[string]
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
@@ -3,40 +3,57 @@ module RSpec
|
|
3
3
|
module InSubProcess
|
4
4
|
if Process.respond_to?(:fork) && !(Ruby.jruby? && RUBY_VERSION == '1.8.7')
|
5
5
|
|
6
|
+
UnmarshableObject = Struct.new(:error)
|
7
|
+
|
6
8
|
# Useful as a way to isolate a global change to a subprocess.
|
7
9
|
|
8
10
|
# rubocop:disable MethodLength
|
9
11
|
def in_sub_process(prevent_warnings=true)
|
10
|
-
|
12
|
+
exception_reader, exception_writer = IO.pipe
|
13
|
+
result_reader, result_writer = IO.pipe
|
11
14
|
|
12
15
|
pid = Process.fork do
|
13
|
-
exception = nil
|
14
16
|
warning_preventer = $stderr = RSpec::Support::StdErrSplitter.new($stderr)
|
15
17
|
|
16
18
|
begin
|
17
|
-
yield
|
19
|
+
result = yield
|
18
20
|
warning_preventer.verify_no_warnings! if prevent_warnings
|
19
|
-
|
20
|
-
|
21
|
+
# rubocop:disable Lint/HandleExceptions
|
22
|
+
rescue Support::AllExceptionsExceptOnesWeMustNotRescue => exception
|
23
|
+
# rubocop:enable Lint/HandleExceptions
|
21
24
|
end
|
22
25
|
|
23
|
-
|
26
|
+
exception_writer.write marshal_dump_with_unmarshable_object_handling(exception)
|
27
|
+
exception_reader.close
|
28
|
+
exception_writer.close
|
29
|
+
|
30
|
+
result_writer.write marshal_dump_with_unmarshable_object_handling(result)
|
31
|
+
result_reader.close
|
32
|
+
result_writer.close
|
24
33
|
|
25
|
-
readme.close
|
26
|
-
writeme.close
|
27
34
|
exit! # prevent at_exit hooks from running (e.g. minitest)
|
28
35
|
end
|
29
36
|
|
30
|
-
|
37
|
+
exception_writer.close
|
38
|
+
result_writer.close
|
31
39
|
Process.waitpid(pid)
|
32
40
|
|
33
|
-
exception = Marshal.load(
|
34
|
-
|
35
|
-
|
41
|
+
exception = Marshal.load(exception_reader.read)
|
42
|
+
exception_reader.close
|
36
43
|
raise exception if exception
|
44
|
+
|
45
|
+
result = Marshal.load(result_reader.read)
|
46
|
+
result_reader.close
|
47
|
+
result
|
37
48
|
end
|
38
49
|
# rubocop:enable MethodLength
|
39
50
|
alias :in_sub_process_if_possible :in_sub_process
|
51
|
+
|
52
|
+
def marshal_dump_with_unmarshable_object_handling(object)
|
53
|
+
Marshal.dump(object)
|
54
|
+
rescue TypeError => error
|
55
|
+
Marshal.dump(UnmarshableObject.new(error))
|
56
|
+
end
|
40
57
|
else
|
41
58
|
def in_sub_process(*)
|
42
59
|
skip "This spec requires forking to work properly, " \
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rspec-support
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.6.0
|
4
|
+
version: 3.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Chelimsky
|
@@ -48,7 +48,7 @@ cert_chain:
|
|
48
48
|
ZsVDj6a7lH3cNqtWXZxrb2wO38qV5AkYj8SQK7Hj3/Yui9myUX3crr+PdetazSqQ
|
49
49
|
F3MdtaDehhjC
|
50
50
|
-----END CERTIFICATE-----
|
51
|
-
date:
|
51
|
+
date: 2017-05-04 00:00:00.000000000 Z
|
52
52
|
dependencies:
|
53
53
|
- !ruby/object:Gem::Dependency
|
54
54
|
name: bundler
|
@@ -116,6 +116,10 @@ files:
|
|
116
116
|
- lib/rspec/support/recursive_const_methods.rb
|
117
117
|
- lib/rspec/support/reentrant_mutex.rb
|
118
118
|
- lib/rspec/support/ruby_features.rb
|
119
|
+
- lib/rspec/support/source.rb
|
120
|
+
- lib/rspec/support/source/location.rb
|
121
|
+
- lib/rspec/support/source/node.rb
|
122
|
+
- lib/rspec/support/source/token.rb
|
119
123
|
- lib/rspec/support/spec.rb
|
120
124
|
- lib/rspec/support/spec/deprecation_helpers.rb
|
121
125
|
- lib/rspec/support/spec/formatting_support.rb
|
@@ -144,13 +148,13 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
144
148
|
version: 1.8.7
|
145
149
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
146
150
|
requirements:
|
147
|
-
- - "
|
151
|
+
- - ">="
|
148
152
|
- !ruby/object:Gem::Version
|
149
|
-
version:
|
153
|
+
version: '0'
|
150
154
|
requirements: []
|
151
155
|
rubyforge_project:
|
152
|
-
rubygems_version: 2.
|
156
|
+
rubygems_version: 2.4.5.2
|
153
157
|
signing_key:
|
154
158
|
specification_version: 4
|
155
|
-
summary: rspec-support-3.6.0
|
159
|
+
summary: rspec-support-3.6.0
|
156
160
|
test_files: []
|
metadata.gz.sig
CHANGED
Binary file
|