Skip to content

Commit

Permalink
Simplify CodeComment implementation
Browse files Browse the repository at this point in the history
- Removes undocumented support for underscored smell names.
- Improves smell suppression documentation.
  • Loading branch information
mvz committed Sep 4, 2015
1 parent fd78451 commit 5313768
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 24 deletions.
22 changes: 18 additions & 4 deletions docs/Smell-Suppression.md
@@ -1,15 +1,18 @@
## Introduction

In some cases, it might be necessary to suppress one or more of `reek`'s smell warnings for a particular method or class.
In some cases, it might be necessary to suppress one or more of `reek`'s smell
warnings for a particular method or class.

Possible reasons for this could be:

* The code is outside of your control and you can't fix it
* `reek` is not the police. You might have legit reasons why your source code is good as it is.
* `reek` is not the police. You might have legit reasons why your source code
is good as it is.

## How to disable smell detection

First and foremost, there are the [Basic Smell Options](Basic-Smell-Options.md) you can use.
First and foremost, there are the [Basic Smell Options](Basic-Smell-Options.md)
you can use.

Besides from that, you can use special comments, like so:

Expand All @@ -20,7 +23,9 @@ def smelly_method foo
end
```

The method `smelly_method` will not be reported. The general pattern is to put the string ':reek:', followed by the smell class, in a comment before the method or class.
The method `smelly_method` will not be reported. The general pattern is to put
the string ':reek:', followed by the smell class, in a comment before the
method or class.

It is also possible to specify options for a particular smell detector, like so:

Expand All @@ -30,3 +35,12 @@ def many_parameters_it_has foo, bar, baz, qux
# ...
end
```

Multiple smells may be configured for the same method or class:

```ruby
# :reek:LongParameterList: { max_params: 4 } and :reek:NestedIterators
def many_parameters_it_has foo, bar, baz, qux
foo.each {|bar| bar.each {|baz| baz.qux(qux)}}
end
```
15 changes: 5 additions & 10 deletions lib/reek/code_comment.rb
Expand Up @@ -14,31 +14,26 @@ class CodeComment
CONFIG_REGEX = /:reek:(\w+)(:\s*\{.*?\})?/

def initialize(text)
@config = Hash.new { |hash, key| hash[key] = {} }
@text = text.gsub(CONFIG_REGEX) do
add_to_config($1, $2)
@config.merge! add_to_config($1, $2)
''
end.gsub(/#/, '').gsub(/\n/, '').strip
end

def config
@config ||= Hash.new { |hash, key| hash[key] = {} }
end
attr_reader :config

def descriptive?
text.split(/\s+/).length >= 2
end

protected
private

def add_to_config(smell, options)
options ||= ': { enabled: false }'
config.merge! YAML.load(smell.gsub(/(?:^|_)(.)/) { $1.upcase } + options)
# TODO: extend this to all configs -------------------^
# TODO: extend to allow configuration of whole smell class, not just subclass
YAML.load(smell + options)
end

private

private_attr_reader :text
end
end
18 changes: 8 additions & 10 deletions spec/reek/code_comment_spec.rb
Expand Up @@ -36,49 +36,47 @@
expect(config['Duplication']).to include('enabled')
expect(config['Duplication']['enabled']).to be_falsey
end
it 'parses hashed options with Ruby names' do
comment = '# :reek:nested_iterators: { enabled: true }'
config = described_class.new(comment).config
expect(config).to include('NestedIterators')
expect(config['NestedIterators']).to include('enabled')
expect(config['NestedIterators']['enabled']).to be_truthy
end

it 'parses multiple hashed options' do
config = described_class.new('
# :reek:Duplication: { enabled: false }
:reek:nested_iterators: { enabled: true }
# :reek:NestedIterators: { enabled: true }
').config
expect(config).to include('Duplication', 'NestedIterators')
expect(config['Duplication']).to include('enabled')
expect(config['Duplication']['enabled']).to be_falsey
expect(config['NestedIterators']).to include('enabled')
expect(config['NestedIterators']['enabled']).to be_truthy
end

it 'parses multiple hashed options on the same line' do
config = described_class.new('
#:reek:Duplication: { enabled: false } and :reek:nested_iterators: { enabled: true }
#:reek:Duplication: { enabled: false } and :reek:NestedIterators: { enabled: true }
').config
expect(config).to include('Duplication', 'NestedIterators')
expect(config['Duplication']).to include('enabled')
expect(config['Duplication']['enabled']).to be_falsey
expect(config['NestedIterators']).to include('enabled')
expect(config['NestedIterators']['enabled']).to be_truthy
end

it 'parses multiple unhashed options on the same line' do
comment = '# :reek:Duplication and :reek:nested_iterators'
comment = '# :reek:Duplication and :reek:NestedIterators'
config = described_class.new(comment).config
expect(config).to include('Duplication', 'NestedIterators')
expect(config['Duplication']).to include('enabled')
expect(config['Duplication']['enabled']).to be_falsey
expect(config['NestedIterators']).to include('enabled')
expect(config['NestedIterators']['enabled']).to be_falsey
end

it 'disables the smell if no options are specifed' do
config = described_class.new('# :reek:Duplication').config
expect(config).to include('Duplication')
expect(config['Duplication']).to include('enabled')
expect(config['Duplication']['enabled']).to be_falsey
end

it 'ignores smells after a space' do
config = described_class.new('# :reek: Duplication').config
expect(config).not_to include('Duplication')
Expand Down

0 comments on commit 5313768

Please sign in to comment.