/
ruby_features_spec.rb
177 lines (153 loc) · 5.38 KB
/
ruby_features_spec.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
require 'rspec/support/ruby_features'
module RSpec
module Support
describe OS do
describe ".windows?" do
%w[cygwin mswin mingw bccwin wince emx].each do |fragment|
it "returns true when host os is #{fragment}" do
stub_const("RbConfig::CONFIG", 'host_os' => fragment)
expect(OS.windows?).to be true
end
end
%w[darwin linux].each do |fragment|
it "returns false when host os is #{fragment}" do
stub_const("RbConfig::CONFIG", 'host_os' => fragment)
expect(OS.windows?).to be false
end
end
end
describe ".windows_file_path?" do
it "returns true when the file alt seperator is a colon" do
stub_const("File::ALT_SEPARATOR", "\\") unless OS.windows?
expect(OS).to be_windows_file_path
end
it "returns false when file alt seperator is not present" do
stub_const("File::ALT_SEPARATOR", nil) if OS.windows?
expect(OS).to_not be_windows_file_path
end
end
end
describe Ruby do
specify "jruby? reflects the state of RUBY_PLATFORM" do
stub_const("RUBY_PLATFORM", "java")
expect(Ruby).to be_jruby
stub_const("RUBY_PLATFORM", "")
expect(Ruby).to_not be_jruby
end
specify "rbx? reflects the state of RUBY_ENGINE" do
stub_const("RUBY_ENGINE", "rbx")
expect(Ruby).to be_rbx
hide_const("RUBY_ENGINE")
expect(Ruby).to_not be_rbx
end
specify "jruby_9000? reflects the state of RUBY_PLATFORM and JRUBY_VERSION" do
stub_const("RUBY_PLATFORM", "java")
stub_const("JRUBY_VERSION", "")
expect(Ruby).to_not be_jruby_9000
stub_const("JRUBY_VERSION", "9.0.3.0")
expect(Ruby).to be_jruby_9000
stub_const("RUBY_PLATFORM", "")
expect(Ruby).to_not be_jruby_9000
end
specify "rbx? reflects the state of RUBY_ENGINE" do
hide_const("RUBY_ENGINE")
expect(Ruby).to be_mri
stub_const("RUBY_ENGINE", "ruby")
expect(Ruby).to be_mri
stub_const("RUBY_ENGINE", "rbx")
expect(Ruby).to_not be_mri
end
end
describe RubyFeatures do
specify "#module_refinement_supported? reflects refinement support" do
if Ruby.mri? && RUBY_VERSION >= '2.1.0'
expect(RubyFeatures.module_refinement_supported?).to eq true
end
end
specify "#fork_supported? exists" do
RubyFeatures.fork_supported?
end
specify "#supports_exception_cause? exists" do
RubyFeatures.supports_exception_cause?
end
specify "#kw_args_supported? exists" do
RubyFeatures.kw_args_supported?
end
specify "#required_kw_args_supported? exists" do
RubyFeatures.required_kw_args_supported?
end
specify "#supports_rebinding_module_methods? exists" do
RubyFeatures.supports_rebinding_module_methods?
end
specify "#supports_taint?" do
RubyFeatures.supports_taint?
end
specify "#caller_locations_supported? exists" do
RubyFeatures.caller_locations_supported?
if Ruby.mri?
expect(RubyFeatures.caller_locations_supported?).to eq(RUBY_VERSION >= '2.0.0')
end
end
describe "#ripper_supported?" do
def ripper_is_implemented?
in_sub_process_if_possible do
begin
require 'ripper'
!!defined?(::Ripper) && Ripper.respond_to?(:lex)
rescue LoadError
false
end
end
end
def ripper_works_correctly?
ripper_reports_correct_line_number? &&
ripper_can_parse_source_including_keywordish_symbol? &&
ripper_can_parse_source_referencing_keyword_arguments?
end
# https://github.com/jruby/jruby/issues/3386
def ripper_reports_correct_line_number?
in_sub_process_if_possible do
require 'ripper'
tokens = ::Ripper.lex('foo')
token = tokens.first
location = token.first
line_number = location.first
line_number == 1
end
end
# https://github.com/jruby/jruby/issues/4562
def ripper_can_parse_source_including_keywordish_symbol?
in_sub_process_if_possible do
require 'ripper'
sexp = ::Ripper.sexp(':if')
!sexp.nil?
end
end
# https://github.com/jruby/jruby/issues/5209
def ripper_can_parse_source_referencing_keyword_arguments?
in_sub_process_if_possible do
require 'ripper'
# It doesn't matter if keyword arguments don't exist.
if Ruby.mri? || Ruby.jruby?
if RUBY_VERSION < '2.0'
true
else
begin
!::Ripper.sexp('def a(**kw_args); end').nil?
rescue NoMethodError
false
end
end
end
end
end
it 'returns whether Ripper is correctly implemented in the current environment' do
expect(RubyFeatures.ripper_supported?).to eq(ripper_is_implemented? && ripper_works_correctly?)
end
it 'does not load Ripper' do
expect { RubyFeatures.ripper_supported? }.not_to change { defined?(::Ripper) }
end
end
end
end
end