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 189 190 191 192 193
|
# frozen_string_literal: true
require_relative "../spec_helper"
module SyntaxSuggest
ruby = ENV.fetch("RUBY", "ruby")
RSpec.describe "Requires with ruby cli" do
it "namespaces all monkeypatched methods" do
Dir.mktmpdir do |dir|
tmpdir = Pathname(dir)
script = tmpdir.join("script.rb")
script.write <<~EOM
puts Kernel.private_methods
EOM
syntax_suggest_methods_file = tmpdir.join("syntax_suggest_methods.txt")
api_only_methods_file = tmpdir.join("api_only_methods.txt")
kernel_methods_file = tmpdir.join("kernel_methods.txt")
d_pid = Process.spawn("#{ruby} -I#{lib_dir} -rsyntax_suggest #{script} 2>&1 > #{syntax_suggest_methods_file}")
k_pid = Process.spawn("#{ruby} #{script} 2>&1 >> #{kernel_methods_file}")
r_pid = Process.spawn("#{ruby} -I#{lib_dir} -rsyntax_suggest/api #{script} 2>&1 > #{api_only_methods_file}")
Process.wait(k_pid)
Process.wait(d_pid)
Process.wait(r_pid)
kernel_methods_array = kernel_methods_file.read.strip.lines.map(&:strip)
syntax_suggest_methods_array = syntax_suggest_methods_file.read.strip.lines.map(&:strip)
api_only_methods_array = api_only_methods_file.read.strip.lines.map(&:strip)
# In ruby 3.1.0-preview1 the `timeout` file is already required
# we can remove it if it exists to normalize the output for
# all ruby versions
[syntax_suggest_methods_array, kernel_methods_array, api_only_methods_array].each do |array|
array.delete("timeout")
end
methods = (syntax_suggest_methods_array - kernel_methods_array).sort
if methods.any?
expect(methods).to eq(["syntax_suggest_original_load", "syntax_suggest_original_require", "syntax_suggest_original_require_relative"])
end
methods = (api_only_methods_array - kernel_methods_array).sort
expect(methods).to eq([])
end
end
# Since Ruby 3.2 includes syntax_suggest as a default gem, we might accidentally
# be requiring the default gem instead of this library under test. Assert that's
# not the case
it "tests current version of syntax_suggest" do
Dir.mktmpdir do |dir|
tmpdir = Pathname(dir)
script = tmpdir.join("script.rb")
contents = <<~'EOM'
puts "suggest_version is #{SyntaxSuggest::VERSION}"
EOM
script.write(contents)
out = `#{ruby} -I#{lib_dir} -rsyntax_suggest/version #{script} 2>&1`
expect(out).to include("suggest_version is #{SyntaxSuggest::VERSION}").once
end
end
it "detects require error and adds a message with auto mode" do
Dir.mktmpdir do |dir|
tmpdir = Pathname(dir)
script = tmpdir.join("script.rb")
script.write <<~EOM
describe "things" do
it "blerg" do
end
it "flerg"
end
it "zlerg" do
end
end
EOM
require_rb = tmpdir.join("require.rb")
require_rb.write <<~EOM
load "#{script.expand_path}"
EOM
out = `#{ruby} -I#{lib_dir} -rsyntax_suggest #{require_rb} 2>&1`
expect($?.success?).to be_falsey
expect(out).to include('> 5 it "flerg"').once
end
end
it "gem can be tested when executing on Ruby with default gem included" do
skip if Gem::Version.new(RUBY_VERSION) < Gem::Version.new("3.2")
out = `#{ruby} -I#{lib_dir} -rsyntax_suggest -e "puts SyntaxError.instance_method(:detailed_message).source_location" 2>&1`
expect($?.success?).to be_truthy
expect(out).to include(lib_dir.join("syntax_suggest").join("core_ext.rb").to_s).once
end
it "annotates a syntax error in Ruby 3.2+ when require is not used" do
skip if Gem::Version.new(RUBY_VERSION) < Gem::Version.new("3.2")
Dir.mktmpdir do |dir|
tmpdir = Pathname(dir)
script = tmpdir.join("script.rb")
script.write <<~EOM
describe "things" do
it "blerg" do
end
it "flerg"
end
it "zlerg" do
end
end
EOM
out = `#{ruby} -I#{lib_dir} -rsyntax_suggest #{script} 2>&1`
expect($?.success?).to be_falsey
expect(out).to include('> 5 it "flerg"').once
end
end
it "does not load internals into memory if no syntax error" do
Dir.mktmpdir do |dir|
tmpdir = Pathname(dir)
script = tmpdir.join("script.rb")
script.write <<~EOM
class Dog
end
if defined?(SyntaxSuggest::DEFAULT_VALUE)
puts "SyntaxSuggest is loaded"
else
puts "SyntaxSuggest is NOT loaded"
end
EOM
require_rb = tmpdir.join("require.rb")
require_rb.write <<~EOM
load "#{script.expand_path}"
EOM
out = `#{ruby} -I#{lib_dir} -rsyntax_suggest #{require_rb} 2>&1`
expect($?.success?).to be_truthy
expect(out).to include("SyntaxSuggest is NOT loaded").once
end
end
it "ignores eval" do
Dir.mktmpdir do |dir|
tmpdir = Pathname(dir)
script = tmpdir.join("script.rb")
script.write <<~EOM
$stderr = STDOUT
eval("def lol")
EOM
out = `#{ruby} -I#{lib_dir} -rsyntax_suggest #{script} 2>&1`
expect($?.success?).to be_falsey
expect(out).to match(/\(eval.*\):1/)
expect(out).to_not include("SyntaxSuggest")
expect(out).to_not include("Could not find filename")
end
end
it "does not say 'syntax ok' when a syntax error fires" do
Dir.mktmpdir do |dir|
tmpdir = Pathname(dir)
script = tmpdir.join("script.rb")
script.write <<~EOM
break
EOM
out = `#{ruby} -I#{lib_dir} -rsyntax_suggest -e "require_relative '#{script}'" 2>&1`
expect($?.success?).to be_falsey
expect(out.downcase).to_not include("syntax ok")
expect(out).to include("Invalid break")
end
end
end
end
|