reek 3.0.4 → 3.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG +6 -0
- data/README.md +41 -20
- data/features/configuration_files/directory_specific_directives.feature +280 -0
- data/features/configuration_files/masking_smells.feature +0 -14
- data/features/step_definitions/sample_file_steps.rb +2 -2
- data/lib/reek/ast/sexp_extensions.rb +72 -60
- data/lib/reek/cli/application.rb +2 -5
- data/lib/reek/cli/reek_command.rb +1 -1
- data/lib/reek/configuration/app_configuration.rb +115 -61
- data/lib/reek/configuration/configuration_file_finder.rb +19 -0
- data/lib/reek/context/code_context.rb +102 -29
- data/lib/reek/context/method_context.rb +11 -48
- data/lib/reek/context/module_context.rb +2 -6
- data/lib/reek/context/root_context.rb +7 -14
- data/lib/reek/examiner.rb +15 -10
- data/lib/reek/report/report.rb +5 -4
- data/lib/reek/smells/boolean_parameter.rb +1 -1
- data/lib/reek/smells/duplicate_method_call.rb +1 -5
- data/lib/reek/smells/irresponsible_module.rb +2 -2
- data/lib/reek/smells/smell_repository.rb +30 -16
- data/lib/reek/smells/utility_function.rb +1 -1
- data/lib/reek/source/source_code.rb +10 -6
- data/lib/reek/source/source_locator.rb +27 -26
- data/lib/reek/spec.rb +8 -6
- data/lib/reek/spec/should_reek.rb +6 -2
- data/lib/reek/spec/should_reek_of.rb +5 -2
- data/lib/reek/spec/should_reek_only_of.rb +1 -1
- data/lib/reek/tree_walker.rb +49 -21
- data/lib/reek/version.rb +1 -1
- data/spec/reek/ast/sexp_extensions_spec.rb +4 -12
- data/spec/reek/configuration/app_configuration_spec.rb +80 -52
- data/spec/reek/configuration/configuration_file_finder_spec.rb +27 -15
- data/spec/reek/context/code_context_spec.rb +66 -17
- data/spec/reek/context/method_context_spec.rb +66 -64
- data/spec/reek/context/root_context_spec.rb +3 -1
- data/spec/reek/context/singleton_method_context_spec.rb +1 -2
- data/spec/reek/examiner_spec.rb +5 -8
- data/spec/reek/report/xml_report_spec.rb +3 -2
- data/spec/reek/smells/attribute_spec.rb +12 -17
- data/spec/reek/smells/duplicate_method_call_spec.rb +17 -25
- data/spec/reek/smells/feature_envy_spec.rb +4 -5
- data/spec/reek/smells/irresponsible_module_spec.rb +43 -0
- data/spec/reek/smells/nested_iterators_spec.rb +12 -26
- data/spec/reek/smells/too_many_statements_spec.rb +2 -210
- data/spec/reek/smells/utility_function_spec.rb +49 -5
- data/spec/reek/source/source_locator_spec.rb +39 -43
- data/spec/reek/spec/should_reek_of_spec.rb +3 -2
- data/spec/reek/spec/should_reek_spec.rb +25 -17
- data/spec/reek/tree_walker_spec.rb +214 -23
- data/spec/samples/configuration/full_configuration.reek +9 -0
- data/spec/spec_helper.rb +10 -10
- metadata +4 -3
- data/features/configuration_files/overrides_defaults.feature +0 -15
data/lib/reek/spec.rb
CHANGED
@@ -85,8 +85,10 @@ module Reek
|
|
85
85
|
#
|
86
86
|
# expect(src).to reek_of(Reek::Smells::DuplicateMethodCall, name: '@other.thing')
|
87
87
|
#
|
88
|
-
def reek_of(smell_category,
|
89
|
-
|
88
|
+
def reek_of(smell_category,
|
89
|
+
smell_details = {},
|
90
|
+
configuration = Configuration::AppConfiguration.new)
|
91
|
+
ShouldReekOf.new(smell_category, smell_details, configuration)
|
90
92
|
end
|
91
93
|
|
92
94
|
#
|
@@ -96,15 +98,15 @@ module Reek
|
|
96
98
|
# 1.) "reek_of" doesn't mind if there are other smells of a different category.
|
97
99
|
# "reek_only_of" will fail in that case.
|
98
100
|
# 2.) "reek_only_of" doesn't support the additional smell_details hash.
|
99
|
-
def reek_only_of(smell_category)
|
100
|
-
ShouldReekOnlyOf.new(smell_category)
|
101
|
+
def reek_only_of(smell_category, configuration = Configuration::AppConfiguration.new)
|
102
|
+
ShouldReekOnlyOf.new(smell_category, configuration)
|
101
103
|
end
|
102
104
|
|
103
105
|
#
|
104
106
|
# Returns +true+ if and only if the target source code contains smells.
|
105
107
|
#
|
106
|
-
def reek
|
107
|
-
ShouldReek.new
|
108
|
+
def reek(configuration = Configuration::AppConfiguration.new)
|
109
|
+
ShouldReek.new configuration
|
108
110
|
end
|
109
111
|
end
|
110
112
|
end
|
@@ -7,9 +7,13 @@ module Reek
|
|
7
7
|
# An rspec matcher that matches when the +actual+ has code smells.
|
8
8
|
#
|
9
9
|
# @api private
|
10
|
-
class ShouldReek
|
10
|
+
class ShouldReek
|
11
|
+
def initialize(configuration = Configuration::AppConfiguration.new)
|
12
|
+
@configuration = configuration
|
13
|
+
end
|
14
|
+
|
11
15
|
def matches?(actual)
|
12
|
-
@examiner = Examiner.new(actual)
|
16
|
+
@examiner = Examiner.new(actual, configuration: @configuration)
|
13
17
|
@examiner.smelly?
|
14
18
|
end
|
15
19
|
|
@@ -8,13 +8,16 @@ module Reek
|
|
8
8
|
#
|
9
9
|
# @api private
|
10
10
|
class ShouldReekOf
|
11
|
-
def initialize(smell_category,
|
11
|
+
def initialize(smell_category,
|
12
|
+
smell_details = {},
|
13
|
+
configuration = Configuration::AppConfiguration.new)
|
12
14
|
@smell_category = normalize smell_category
|
13
15
|
@smell_details = smell_details
|
16
|
+
@configuration = configuration
|
14
17
|
end
|
15
18
|
|
16
19
|
def matches?(actual)
|
17
|
-
@examiner = Examiner.new(actual)
|
20
|
+
@examiner = Examiner.new(actual, configuration: @configuration)
|
18
21
|
@all_smells = @examiner.smells
|
19
22
|
@all_smells.any? { |warning| warning.matches?(@smell_category, @smell_details) }
|
20
23
|
end
|
data/lib/reek/tree_walker.rb
CHANGED
@@ -2,24 +2,36 @@ require_relative 'context/method_context'
|
|
2
2
|
require_relative 'context/module_context'
|
3
3
|
require_relative 'context/root_context'
|
4
4
|
require_relative 'context/singleton_method_context'
|
5
|
-
require_relative 'smells/smell_repository'
|
6
5
|
require_relative 'ast/node'
|
7
6
|
|
8
7
|
module Reek
|
9
8
|
#
|
10
|
-
# Traverses
|
11
|
-
#
|
9
|
+
# Traverses an abstract syntax tree and fires events whenever it encounters
|
10
|
+
# specific node types.
|
12
11
|
#
|
13
12
|
# SMELL: This class is responsible for counting statements and for feeding
|
14
13
|
# each context to the smell repository.
|
15
14
|
#
|
15
|
+
# TODO: Make TreeWalker responsible only for creating Context objects, and
|
16
|
+
# loop over the created set of contexts elsewhere.
|
17
|
+
#
|
16
18
|
# @api private
|
17
19
|
class TreeWalker
|
18
|
-
def initialize(smell_repository
|
20
|
+
def initialize(smell_repository, exp)
|
19
21
|
@smell_repository = smell_repository
|
20
|
-
@
|
22
|
+
@exp = exp
|
23
|
+
@element = Context::RootContext.new(exp)
|
21
24
|
end
|
22
25
|
|
26
|
+
def walk
|
27
|
+
@result ||= process(@exp)
|
28
|
+
@result.each do |element|
|
29
|
+
@smell_repository.examine(element)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
23
35
|
def process(exp)
|
24
36
|
context_processor = "process_#{exp.type}"
|
25
37
|
if context_processor_exists?(context_processor)
|
@@ -30,12 +42,6 @@ module Reek
|
|
30
42
|
@element
|
31
43
|
end
|
32
44
|
|
33
|
-
def process_default(exp)
|
34
|
-
exp.children.each do |child|
|
35
|
-
process(child) if child.is_a? AST::Node
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
45
|
def process_module(exp)
|
40
46
|
inside_new_context(Context::ModuleContext, exp) do
|
41
47
|
process_default(exp)
|
@@ -44,6 +50,14 @@ module Reek
|
|
44
50
|
|
45
51
|
alias_method :process_class, :process_module
|
46
52
|
|
53
|
+
def process_casgn(exp)
|
54
|
+
if exp.defines_module?
|
55
|
+
process_module(exp)
|
56
|
+
else
|
57
|
+
process_default(exp)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
47
61
|
def process_def(exp)
|
48
62
|
inside_new_context(Context::MethodContext, exp) do
|
49
63
|
count_clause(exp.body)
|
@@ -58,6 +72,12 @@ module Reek
|
|
58
72
|
end
|
59
73
|
end
|
60
74
|
|
75
|
+
def process_default(exp)
|
76
|
+
exp.children.each do |child|
|
77
|
+
process(child) if child.is_a? AST::Node
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
61
81
|
def process_args(_) end
|
62
82
|
|
63
83
|
#
|
@@ -65,12 +85,19 @@ module Reek
|
|
65
85
|
#
|
66
86
|
|
67
87
|
def process_send(exp)
|
88
|
+
if visibility_modifier? exp
|
89
|
+
@element.track_visibility(exp.method_name, exp.arg_names)
|
90
|
+
end
|
68
91
|
@element.record_call_to(exp)
|
69
92
|
process_default(exp)
|
70
93
|
end
|
71
94
|
|
72
|
-
|
73
|
-
|
95
|
+
def process_attrasgn(exp)
|
96
|
+
@element.record_call_to(exp)
|
97
|
+
process_default(exp)
|
98
|
+
end
|
99
|
+
|
100
|
+
alias_method :process_op_asgn, :process_attrasgn
|
74
101
|
|
75
102
|
def process_ivar(exp)
|
76
103
|
@element.record_use_of_self
|
@@ -145,10 +172,8 @@ module Reek
|
|
145
172
|
process_default(exp)
|
146
173
|
end
|
147
174
|
|
148
|
-
private
|
149
|
-
|
150
175
|
def context_processor_exists?(name)
|
151
|
-
|
176
|
+
self.class.private_method_defined?(name)
|
152
177
|
end
|
153
178
|
|
154
179
|
def count_clause(sexp)
|
@@ -161,22 +186,25 @@ module Reek
|
|
161
186
|
|
162
187
|
def inside_new_context(klass, exp)
|
163
188
|
scope = klass.new(@element, exp)
|
189
|
+
@element.append_child_context(scope)
|
164
190
|
push(scope) do
|
165
191
|
yield
|
166
|
-
check_smells(exp.type)
|
167
192
|
end
|
168
193
|
scope
|
169
194
|
end
|
170
195
|
|
171
|
-
def check_smells(type)
|
172
|
-
@smell_repository.examine(@element, type)
|
173
|
-
end
|
174
|
-
|
175
196
|
def push(scope)
|
176
197
|
orig = @element
|
177
198
|
@element = scope
|
178
199
|
yield
|
179
200
|
@element = orig
|
180
201
|
end
|
202
|
+
|
203
|
+
# FIXME: Move to SendNode?
|
204
|
+
def visibility_modifier?(call_node)
|
205
|
+
VISIBILITY_MODIFIERS.include?(call_node.method_name)
|
206
|
+
end
|
207
|
+
|
208
|
+
VISIBILITY_MODIFIERS = [:private, :public, :protected, :module_function]
|
181
209
|
end
|
182
210
|
end
|
data/lib/reek/version.rb
CHANGED
@@ -309,15 +309,11 @@ RSpec.describe Reek::AST::SexpExtensions::ModuleNode do
|
|
309
309
|
end
|
310
310
|
|
311
311
|
it 'has the correct #name' do
|
312
|
-
expect(subject.name).to eq
|
312
|
+
expect(subject.name).to eq 'Fred'
|
313
313
|
end
|
314
314
|
|
315
315
|
it 'has the correct #simple_name' do
|
316
|
-
expect(subject.simple_name).to eq
|
317
|
-
end
|
318
|
-
|
319
|
-
it 'has the correct #text_name' do
|
320
|
-
expect(subject.text_name).to eq 'Fred'
|
316
|
+
expect(subject.simple_name).to eq 'Fred'
|
321
317
|
end
|
322
318
|
|
323
319
|
it 'has a simple full_name' do
|
@@ -335,15 +331,11 @@ RSpec.describe Reek::AST::SexpExtensions::ModuleNode do
|
|
335
331
|
end
|
336
332
|
|
337
333
|
it 'has the correct #name' do
|
338
|
-
expect(subject.name).to eq
|
334
|
+
expect(subject.name).to eq 'Foo::Bar'
|
339
335
|
end
|
340
336
|
|
341
337
|
it 'has the correct #simple_name' do
|
342
|
-
expect(subject.simple_name).to eq
|
343
|
-
end
|
344
|
-
|
345
|
-
it 'has the correct #text_name' do
|
346
|
-
expect(subject.text_name).to eq 'Foo::Bar'
|
338
|
+
expect(subject.simple_name).to eq 'Bar'
|
347
339
|
end
|
348
340
|
|
349
341
|
it 'has a simple full_name' do
|
@@ -1,78 +1,106 @@
|
|
1
|
+
require 'pathname'
|
1
2
|
require_relative '../../spec_helper'
|
2
3
|
require_relative '../../../lib/reek/configuration/app_configuration'
|
3
4
|
require_relative '../../../lib/reek/smells/smell_repository'
|
5
|
+
require_relative '../../../lib/reek/source/source_code'
|
4
6
|
|
5
7
|
RSpec.describe Reek::Configuration::AppConfiguration do
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
'
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
8
|
+
describe '#initialize' do
|
9
|
+
let(:full_configuration_path) { SAMPLES_PATH.join('configuration/full_configuration.reek') }
|
10
|
+
let(:expected_exclude_paths) do
|
11
|
+
[SAMPLES_PATH.join('two_smelly_files'),
|
12
|
+
SAMPLES_PATH.join('source_with_non_ruby_files')]
|
13
|
+
end
|
14
|
+
let(:expected_default_directive) do
|
15
|
+
{ Reek::Smells::IrresponsibleModule => { 'enabled' => false } }
|
16
|
+
end
|
17
|
+
let(:expected_directory_directives) do
|
18
|
+
{ Pathname.new('spec/samples/three_clean_files') =>
|
19
|
+
{ Reek::Smells::UtilityFunction => { 'enabled' => false } } }
|
20
|
+
end
|
16
21
|
|
17
|
-
|
18
|
-
it 'loads a configuration file if it can find one' do
|
22
|
+
it 'properly loads configuration and processes it' do
|
19
23
|
finder = Reek::Configuration::ConfigurationFileFinder
|
20
|
-
allow(finder).to receive(:
|
21
|
-
expect(described_class.configuration).to eq(default_configuration)
|
24
|
+
allow(finder).to receive(:find_by_cli).and_return full_configuration_path
|
22
25
|
|
23
|
-
|
24
|
-
expect(
|
26
|
+
expect(subject.exclude_paths).to eq(expected_exclude_paths)
|
27
|
+
expect(subject.default_directive).to eq(expected_default_directive)
|
28
|
+
expect(subject.directory_directives).to eq(expected_directory_directives)
|
25
29
|
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe '#directive_for' do
|
33
|
+
context 'our source is in a directory for which we have a directive' do
|
34
|
+
let(:baz_config) { { Reek::Smells::IrresponsibleModule => { enabled: false } } }
|
35
|
+
let(:bang_config) { { Reek::Smells::Attribute => { enabled: true } } }
|
26
36
|
|
27
|
-
|
28
|
-
|
29
|
-
|
37
|
+
let(:directory_directives) do
|
38
|
+
{
|
39
|
+
Pathname.new('foo/bar/baz') => baz_config,
|
40
|
+
Pathname.new('foo/bar/bang') => bang_config
|
41
|
+
}
|
42
|
+
end
|
43
|
+
let(:source_via) { 'foo/bar/bang/dummy.rb' }
|
30
44
|
|
31
|
-
|
32
|
-
|
45
|
+
it 'returns the corresponding directive' do
|
46
|
+
allow(subject).to receive(:directory_directives).and_return directory_directives
|
47
|
+
expect(subject.directive_for(source_via)).to eq(bang_config)
|
48
|
+
end
|
33
49
|
end
|
34
|
-
end
|
35
50
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
51
|
+
context 'our source is not in a directory for which we have a directive' do
|
52
|
+
let(:baz_config) { { Reek::Smells::IrresponsibleModule => { enabled: false } } }
|
53
|
+
let(:default_directive) do
|
54
|
+
{ Reek::Smells::Attribute => { enabled: true } }
|
55
|
+
end
|
56
|
+
let(:directory_directives) do
|
57
|
+
{ Pathname.new('foo/bar/baz') => baz_config }
|
58
|
+
end
|
59
|
+
let(:source_via) { 'foo/bar/bang/dummy.rb' }
|
41
60
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
61
|
+
it 'returns the default directive' do
|
62
|
+
allow(subject).to receive(:directory_directives).and_return directory_directives
|
63
|
+
allow(subject).to receive(:default_directive).and_return default_directive
|
64
|
+
expect(subject.directive_for(source_via)).to eq(default_directive)
|
65
|
+
end
|
46
66
|
end
|
47
67
|
end
|
48
68
|
|
49
|
-
describe '
|
50
|
-
let(:
|
69
|
+
describe '#best_directory_match_for' do
|
70
|
+
let(:directory_directives) do
|
71
|
+
{
|
72
|
+
Pathname.new('foo/bar/baz') => {},
|
73
|
+
Pathname.new('foo/bar') => {},
|
74
|
+
Pathname.new('bar/boo') => {}
|
75
|
+
}
|
76
|
+
end
|
51
77
|
|
52
|
-
|
53
|
-
|
54
|
-
expect(described_class.exclude_paths).to eq [
|
55
|
-
'spec/samples/source_with_exclude_paths/ignore_me',
|
56
|
-
'spec/samples/source_with_exclude_paths/nested/ignore_me_as_well'
|
57
|
-
]
|
58
|
-
end
|
78
|
+
before do
|
79
|
+
allow(subject).to receive(:directory_directives).and_return directory_directives
|
59
80
|
end
|
60
|
-
end
|
61
81
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
expect(
|
82
|
+
it 'returns the corresponding directory when source_base_dir is a leaf' do
|
83
|
+
source_base_dir = 'foo/bar/baz/bang'
|
84
|
+
hit = subject.send :best_directory_match_for, source_base_dir
|
85
|
+
expect(hit.to_s).to eq('foo/bar/baz')
|
66
86
|
end
|
67
|
-
end
|
68
87
|
|
69
|
-
|
70
|
-
|
71
|
-
|
88
|
+
it 'returns the corresponding directory when source_base_dir is in the middle of the tree' do
|
89
|
+
source_base_dir = 'foo/bar'
|
90
|
+
hit = subject.send :best_directory_match_for, source_base_dir
|
91
|
+
expect(hit.to_s).to eq('foo/bar')
|
92
|
+
end
|
93
|
+
|
94
|
+
it 'returns nil we are on top at the top of the and all other directories are below' do
|
95
|
+
source_base_dir = 'foo'
|
96
|
+
hit = subject.send :best_directory_match_for, source_base_dir
|
97
|
+
expect(hit).to be_nil
|
98
|
+
end
|
72
99
|
|
73
|
-
|
74
|
-
|
75
|
-
|
100
|
+
it 'returns nil when there source_base_dir is not part of any directory directive at all' do
|
101
|
+
source_base_dir = 'non/existent'
|
102
|
+
hit = subject.send :best_directory_match_for, source_base_dir
|
103
|
+
expect(hit).to be_nil
|
76
104
|
end
|
77
105
|
end
|
78
106
|
end
|
@@ -16,36 +16,31 @@ RSpec.describe Reek::Configuration::ConfigurationFileFinder do
|
|
16
16
|
|
17
17
|
it 'returns the file in current dir if config_file is nil' do
|
18
18
|
options = double(config_file: nil)
|
19
|
-
|
20
|
-
found
|
21
|
-
expect(found).to eq(Pathname.new('spec/samples/exceptions.reek'))
|
19
|
+
found = described_class.find(options: options, current: SAMPLES_PATH)
|
20
|
+
expect(found).to eq(SAMPLES_PATH.join('exceptions.reek'))
|
22
21
|
end
|
23
22
|
|
24
23
|
it 'returns the file in current dir if options is nil' do
|
25
|
-
|
26
|
-
found
|
27
|
-
expect(found).to eq(Pathname.new('spec/samples/exceptions.reek'))
|
24
|
+
found = described_class.find(current: SAMPLES_PATH)
|
25
|
+
expect(found).to eq(SAMPLES_PATH.join('exceptions.reek'))
|
28
26
|
end
|
29
27
|
|
30
28
|
it 'returns the file in a parent dir if none in current dir' do
|
31
|
-
|
32
|
-
found
|
33
|
-
expect(found).to eq(Pathname.new('spec/samples/exceptions.reek'))
|
29
|
+
found = described_class.find(current: SAMPLES_PATH.join('no_config_file'))
|
30
|
+
expect(found).to eq(SAMPLES_PATH.join('exceptions.reek'))
|
34
31
|
end
|
35
32
|
|
36
33
|
it 'returns the file even if it’s just ‘.reek’' do
|
37
|
-
|
38
|
-
found
|
39
|
-
expect(found).to eq(Pathname.new('spec/samples/masked_by_dotfile/.reek'))
|
34
|
+
found = described_class.find(current: SAMPLES_PATH.join('masked_by_dotfile'))
|
35
|
+
expect(found).to eq(SAMPLES_PATH.join('masked_by_dotfile/.reek'))
|
40
36
|
end
|
41
37
|
|
42
38
|
it 'returns the file in home if traversing from the current dir fails' do
|
43
39
|
skip_if_a_config_in_tempdir
|
44
40
|
Dir.mktmpdir do |tempdir|
|
45
41
|
current = Pathname.new(tempdir)
|
46
|
-
|
47
|
-
found
|
48
|
-
expect(found).to eq(Pathname.new('spec/samples/exceptions.reek'))
|
42
|
+
found = described_class.find(current: current, home: SAMPLES_PATH)
|
43
|
+
expect(found).to eq(SAMPLES_PATH.join('exceptions.reek'))
|
49
44
|
end
|
50
45
|
end
|
51
46
|
|
@@ -70,6 +65,23 @@ RSpec.describe Reek::Configuration::ConfigurationFileFinder do
|
|
70
65
|
end
|
71
66
|
end
|
72
67
|
|
68
|
+
describe '.load_from_file' do
|
69
|
+
let(:sample_configuration_path) do
|
70
|
+
SAMPLES_PATH.join('configuration/simple_configuration.reek')
|
71
|
+
end
|
72
|
+
let(:sample_configuration_loaded) do
|
73
|
+
{
|
74
|
+
'UncommunicativeVariableName' => { 'enabled' => false },
|
75
|
+
'UncommunicativeMethodName' => { 'enabled' => false }
|
76
|
+
}
|
77
|
+
end
|
78
|
+
|
79
|
+
it 'loads the configuration from given file' do
|
80
|
+
configuration = described_class.load_from_file(sample_configuration_path)
|
81
|
+
expect(configuration).to eq(sample_configuration_loaded)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
73
85
|
private
|
74
86
|
|
75
87
|
def skip_if_a_config_in_tempdir
|