File: ruby_features_spec.rb

package info (click to toggle)
ruby-rspec 3.13.0c0e0m0s1-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 6,856 kB
  • sloc: ruby: 70,868; sh: 1,423; makefile: 99
file content (188 lines) | stat: -rw-r--r-- 6,037 bytes parent folder | download
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
178
179
180
181
182
183
184
185
186
187
188
require 'rspec/support/ruby_features'

module RSpec
  module Support
    RSpec.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 separator 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 separator is not present" do
          stub_const("File::ALT_SEPARATOR", nil) if OS.windows?
          expect(OS).to_not be_windows_file_path
        end
      end
    end

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

    RSpec.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 "distincts_kw_args_from_positional_hash?" do
        RubyFeatures.distincts_kw_args_from_positional_hash?
      end

      specify "#supports_rebinding_module_methods? exists" do
        RubyFeatures.supports_rebinding_module_methods?
      end

      specify "#supports_syntax_suggest?" do
        expect(RubyFeatures.supports_syntax_suggest?).to eq(RUBY_VERSION.to_f >= 3.2)
      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? || Ruby.truffleruby?
              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
          if RSpec::Support::Ruby.jruby? && RSpec::Support::Ruby.jruby_version.between?('9.0.0.0', '9.2.1.0')
            pending "Ripper is not supported on JRuby 9.1.17.0 despite this tests claims"
          end
          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