forked from rubocop/rubocop
/
shared_contexts.rb
140 lines (108 loc) · 3.61 KB
/
shared_contexts.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
# frozen_string_literal: true
require 'tmpdir'
RSpec.shared_context 'isolated environment', :isolated_environment do
around do |example|
Dir.mktmpdir do |tmpdir|
original_home = ENV['HOME']
original_xdg_config_home = ENV['XDG_CONFIG_HOME']
# Make sure to expand all symlinks in the path first. Otherwise we may
# get mismatched pathnames when loading config files later on.
tmpdir = File.realpath(tmpdir)
virtual_home = File.expand_path(File.join(tmpdir, 'home'))
Dir.mkdir(virtual_home)
ENV['HOME'] = virtual_home
ENV.delete('XDG_CONFIG_HOME')
base_dir = example.metadata[:project_inside_home] ? virtual_home : tmpdir
root = example.metadata[:root]
working_dir = root ? File.join(base_dir, 'work', root) : File.join(base_dir, 'work')
# Make upwards search for .rubocop.yml files stop at this directory.
RuboCop::FileFinder.root_level = working_dir
begin
FileUtils.mkdir_p(working_dir)
Dir.chdir(working_dir) do
example.run
end
ensure
ENV['HOME'] = original_home
ENV['XDG_CONFIG_HOME'] = original_xdg_config_home
RuboCop::FileFinder.root_level = nil
end
end
end
end
RSpec.shared_context 'maintain registry', :restore_registry do
around(:each) do |example|
RuboCop::Cop::Registry.with_temporary_global { example.run }
end
def stub_cop_class(name, inherit: RuboCop::Cop::Base, &block)
klass = Class.new(inherit, &block)
stub_const(name, klass)
klass
end
end
# This context assumes nothing and defines `cop`, among others.
RSpec.shared_context 'config', :config do # rubocop:disable Metrics/BlockLength
### Meant to be overridden at will
let(:cop_class) do
unless described_class.is_a?(Class) && described_class < RuboCop::Cop::Base
raise 'Specify which cop class to use (e.g `let(:cop_class) { RuboCop::Cop::Base }`, ' \
'or RuboCop::Cop::Cop for legacy)'
end
described_class
end
let(:cop_config) { {} }
let(:other_cops) { {} }
let(:cop_options) { {} }
### Utilities
def source_range(range, buffer: source_buffer)
Parser::Source::Range.new(buffer, range.begin,
range.exclude_end? ? range.end : range.end + 1)
end
### Useful intermediary steps (less likely to be overridden)
let(:processed_source) { parse_source(source, 'test') }
let(:source_buffer) { processed_source.buffer }
let(:all_cops_config) do
rails = { 'TargetRubyVersion' => ruby_version }
rails['TargetRailsVersion'] = rails_version if rails_version
rails
end
let(:cur_cop_config) do
RuboCop::ConfigLoader
.default_configuration.for_cop(cop_class)
.merge({
'Enabled' => true, # in case it is 'pending'
'AutoCorrect' => true # in case defaults set it to false
})
.merge(cop_config)
end
let(:config) do
hash = { 'AllCops' => all_cops_config,
cop_class.cop_name => cur_cop_config }.merge!(other_cops)
RuboCop::Config.new(hash, "#{Dir.pwd}/.rubocop.yml")
end
let(:cop) do
cop_class.new(config, cop_options)
end
end
RSpec.shared_context 'mock console output' do
before do
$stdout = StringIO.new
$stderr = StringIO.new
end
after do
$stdout = STDOUT
$stderr = STDERR
end
end
RSpec.shared_context 'ruby 2.4', :ruby24 do
let(:ruby_version) { 2.4 }
end
RSpec.shared_context 'ruby 2.5', :ruby25 do
let(:ruby_version) { 2.5 }
end
RSpec.shared_context 'ruby 2.6', :ruby26 do
let(:ruby_version) { 2.6 }
end
RSpec.shared_context 'ruby 2.7', :ruby27 do
let(:ruby_version) { 2.7 }
end