polishgeeks-dev-tools 1.1.2 → 1.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f4c7e5f2ebd0f096a10ac590409dd86df64cb6b0
4
- data.tar.gz: c2a9424bac6e6719c716ce3f1dab75cbe933ebf3
3
+ metadata.gz: 1b6c0bc8902d3041b3290e9203d08670b816f81d
4
+ data.tar.gz: 37da8e02f5fbea0ce3f33c8ff892230b4937aa56
5
5
  SHA512:
6
- metadata.gz: 56b7f225f663f401a4c89f486f3cab8627ba84e6cab5b6d0c2a6a0d7f37b7ecce6e843b2bb7225ea1abc0e0d00cde28594e9baf01d4937d1e9f6c88618758a77
7
- data.tar.gz: 753bd5caff7b3183e938f175342d52eee52a2bb3d7a130e252838a522934ed974b3b2d1bcffa10a20951c0209a02a3187dfc3e9db7d9396fd8d36313172bde89
6
+ metadata.gz: dbf1e6be185a824c260365d8a6b872f579cd566d2dd20dc4de9fbdea41d30eb82e2739668f8c3775ac5a83cbfaef144b1a0d5bb047324696fa30964751e56f43
7
+ data.tar.gz: 4d0aa7a04328efe66cdc50b8e1e26b28bd1f81e8a29fed363dd40140b64caea9317102d511e291c0ba3e7bfd3463272d817113b047eec830e304bd9d1805646f
@@ -1,5 +1,8 @@
1
1
  # PolishGeeks Dev Tools Changelog
2
2
 
3
+ ## 1.1.3
4
+ - Added EmptyMethod command which checks if some files have empty methods
5
+
3
6
  ## 1.1.2
4
7
 
5
8
  - Ignore .DS_Store files in FinalBlankLine validator.
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- polishgeeks-dev-tools (1.1.2)
4
+ polishgeeks-dev-tools (1.1.3)
5
5
  brakeman
6
6
  faker
7
7
  haml-lint
@@ -38,16 +38,17 @@ GEM
38
38
  descendants_tracker (~> 0.0.4)
39
39
  ice_nine (~> 0.11.0)
40
40
  thread_safe (~> 0.3, >= 0.3.1)
41
- brakeman (3.0.5)
41
+ brakeman (3.1.0)
42
42
  erubis (~> 2.6)
43
43
  fastercsv (~> 1.5)
44
44
  haml (>= 3.0, < 5.0)
45
- highline (~> 1.6.20)
45
+ highline (~> 1.6)
46
46
  multi_json (~> 1.2)
47
- ruby2ruby (~> 2.1.1)
47
+ ruby2ruby (>= 2.1.1, < 2.3.0)
48
48
  ruby_parser (~> 3.7.0)
49
49
  sass (~> 3.0)
50
- terminal-table (~> 1.4)
50
+ slim (>= 1.3.6, < 4.0)
51
+ terminal-table (~> 1.4.5)
51
52
  bson (3.2.1)
52
53
  builder (3.2.2)
53
54
  coderay (1.1.0)
@@ -78,7 +79,7 @@ GEM
78
79
  haml (~> 4.0)
79
80
  rubocop (>= 0.25.0)
80
81
  sysexits (~> 1.1)
81
- highline (1.6.21)
82
+ highline (1.7.3)
82
83
  i18n (0.7.0)
83
84
  ice_nine (0.11.1)
84
85
  json (1.8.3)
@@ -129,14 +130,14 @@ GEM
129
130
  diff-lcs (>= 1.2.0, < 2.0)
130
131
  rspec-support (~> 3.3.0)
131
132
  rspec-support (3.3.0)
132
- rubocop (0.33.0)
133
+ rubocop (0.34.0)
133
134
  astrolabe (~> 1.3)
134
135
  parser (>= 2.2.2.5, < 3.0)
135
136
  powerpack (~> 0.1)
136
137
  rainbow (>= 1.99.1, < 3.0)
137
138
  ruby-progressbar (~> 1.4)
138
139
  ruby-progressbar (1.7.5)
139
- ruby2ruby (2.1.4)
140
+ ruby2ruby (2.2.0)
140
141
  ruby_parser (~> 3.1)
141
142
  sexp_processor (~> 4.0)
142
143
  ruby_parser (3.7.1)
@@ -161,9 +162,13 @@ GEM
161
162
  json (~> 1.8)
162
163
  simplecov-html (~> 0.10.0)
163
164
  simplecov-html (0.10.0)
165
+ slim (3.0.6)
166
+ temple (~> 0.7.3)
167
+ tilt (>= 1.3.3, < 2.1)
164
168
  slop (3.6.0)
165
169
  sysexits (1.2.0)
166
- terminal-table (1.5.2)
170
+ temple (0.7.6)
171
+ terminal-table (1.4.5)
167
172
  thread_safe (0.3.5)
168
173
  tilt (2.0.1)
169
174
  timecop (0.8.0)
data/README.md CHANGED
@@ -51,6 +51,7 @@ determine, which you can use in your project:
51
51
  | brakeman | Rails | A static analysis security vulnerability scanner for Ruby on Rails |
52
52
  | rubocop | - | Used to check Ruby syntax according to our styling |
53
53
  | final_blank_line | - | Check if all files have final blank line |
54
+ | empty_method | - | Check if some files have empty methods |
54
55
  | expires_in | - | Checks if there are typos like expire_in, etc that might brake app caching |
55
56
  | haml_lint | - | User to check HAML syntax in the app views |
56
57
  | yard | - | YARD documentation standards checking |
@@ -74,6 +75,7 @@ Some validators might accept additional config settings - please refer to this t
74
75
  |-------------------------------|-----------------------|-------------------------------------------------------------------------------------------------------------|
75
76
  | rspec_files_structure_ignored | rspec_files_structure | You can provide an array of files that should be ignored |
76
77
  | final_blank_line_ignored | final_blank_line | You can provide an array of files (ex. lib/file.rb) or directories (ex. lib/command) that should be ignored |
78
+ | empty_method_ignored | empty_method | You can provide an array of files (ex. lib/file.rb) or directories (ex. lib/command) that should be ignored |
77
79
 
78
80
  ## Usage in any Rails/Ruby application
79
81
 
data/Rakefile CHANGED
@@ -10,6 +10,10 @@ task :check do
10
10
  config.expires_in_files_ignored = %w(
11
11
  lib/polishgeeks/dev-tools/command/expires_in.rb
12
12
  )
13
+ config.empty_method_ignored = %w(
14
+ empty_method_spec.rb
15
+ file_parser_spec.rb
16
+ )
13
17
  end
14
18
 
15
19
  PolishGeeks::DevTools::Runner.new.execute(
@@ -36,8 +36,13 @@ module PolishGeeks
36
36
  end
37
37
 
38
38
  require 'polishgeeks/dev-tools/command/base'
39
+ require 'polishgeeks/dev-tools/command/empty_method'
40
+ require 'polishgeeks/dev-tools/command/empty_method/string_refinements'
39
41
 
40
42
  commands_path = File.dirname(__FILE__) + '/polishgeeks/dev-tools/command/*.rb'
41
43
  Dir[commands_path].each { |file| require file }
42
44
 
45
+ commands_path = File.dirname(__FILE__) + '/polishgeeks/dev-tools/command/**/*.rb'
46
+ Dir[commands_path].each { |file| require file }
47
+
43
48
  load 'polishgeeks/dev-tools/tasks/dev-tools.rake'
@@ -0,0 +1,104 @@
1
+ module PolishGeeks
2
+ module DevTools
3
+ module Command
4
+ # Validator used to check if all '.rb' files don't have empty methods
5
+ class EmptyMethod < Base
6
+ self.type = :validator
7
+
8
+ attr_reader :counter
9
+
10
+ # Default paths which we want to exclude from analyse
11
+ DEFAULT_PATHS_TO_EXCLUDE = %w(
12
+ coverage
13
+ tmp
14
+ doc
15
+ log
16
+ vendor
17
+ public
18
+ app/assets/images
19
+ app/assets/fonts
20
+ )
21
+
22
+ # Executes this command and set output and counter variables
23
+ def execute
24
+ @output = []
25
+ @counter = 0
26
+
27
+ files_to_analyze.each do |file|
28
+ @counter += 1
29
+ empty_methods = FileParser.new(file).find_empty_methods
30
+ @output << sanitize(file) + " lines #{empty_methods}" unless empty_methods.empty?
31
+ end
32
+ end
33
+
34
+ # @return [Boolean] true if none of the files include any empty methods
35
+ def valid?
36
+ output.empty?
37
+ end
38
+
39
+ # @return [String] default label for this command
40
+ def label
41
+ "Empty methods: #{counter} files checked"
42
+ end
43
+
44
+ # @return [String] message that should be printed when some files have
45
+ # empty methods
46
+ def error_message
47
+ "Following files contains blank methods: \n#{output.join("\n")}\n"
48
+ end
49
+
50
+ private
51
+
52
+ # @return [Array<String>] array with files to analyze
53
+ # @note method take all not excluded files
54
+ def files_to_analyze
55
+ files = files_from_path('**/*.rb')
56
+ remove_excludes files
57
+ end
58
+
59
+ # @param [Array<String>] files list which we want analyse
60
+ # @return [Array<String>] array without excluded files
61
+ def remove_excludes(files)
62
+ excluded_paths = excludes
63
+
64
+ files.delete_if do |file|
65
+ excluded_paths.any? { |exclude| file =~ /#{exclude}/ }
66
+ end
67
+ end
68
+
69
+ # @return [Array<String>] list of files/directories that
70
+ # should be excluded from checking
71
+ # @note excluded files/directories are defined in DEFAULT_PATHS_TO_EXCLUDE
72
+ # and in configuration file
73
+ def excludes
74
+ config_excludes + DEFAULT_PATHS_TO_EXCLUDE
75
+ end
76
+
77
+ # @return [Array<String>] list of excluded files/directories from config file
78
+ def config_excludes
79
+ DevTools.config.empty_method_ignored || []
80
+ end
81
+
82
+ # @param [String] path from which we want take files
83
+ # @return [Array<String>] list of files in path with app prefix path
84
+ # @note if path is a file return array with file path with app prefix path
85
+ def files_from_path(path)
86
+ full_path = "#{::PolishGeeks::DevTools.app_root}/#{path}"
87
+ return [full_path] if File.file?(full_path)
88
+
89
+ Dir.glob(full_path).select { |f| File.file? f }
90
+ end
91
+
92
+ # @param [String] file name that we want to sanitize
93
+ # @return [String] sanitized file name
94
+ # @example
95
+ # file = /home/something/app/lib/lib.rb,
96
+ # where /home/something/app/ is a app root path, then
97
+ # sanitize(file) #=> lib/lib.rb
98
+ def sanitize(file)
99
+ file.gsub("#{PolishGeeks::DevTools.app_root}/", '')
100
+ end
101
+ end
102
+ end
103
+ end
104
+ end
@@ -0,0 +1,74 @@
1
+ module PolishGeeks
2
+ module DevTools
3
+ module Command
4
+ class EmptyMethod
5
+ # Parse file and search whether it contain empty methods
6
+ class FileParser
7
+ attr_reader :empty_methods
8
+ using StringRefinements
9
+
10
+ def initialize(file)
11
+ @file = IO.readlines(file)
12
+ @empty_methods = []
13
+ end
14
+
15
+ # @return [Array<Fixnum>] list of lines where empty methods are defined
16
+ # @example
17
+ # file = " class Example
18
+ # def empty_method; end
19
+ # end
20
+ # "
21
+ # FileParser.new(file).find_empty_methods => [2]
22
+ #
23
+ # file = ""
24
+ # FileParser.new(file).find_empty_methods => []
25
+ def find_empty_methods
26
+ @file.each_with_index do |line, index|
27
+ next add_empty_method(index) if line.one_line_empty_method?
28
+ check_bodies_existence(line, index)
29
+ end
30
+ empty_methods
31
+ end
32
+
33
+ private
34
+
35
+ # Adds line of empty method definition to array of empty_methods
36
+ # Remembers line where method is defined; search end of method definition
37
+ # and check whether body of method is empty or not.
38
+ # @param [String] line line to parse for empty methods definition
39
+ # @param [Fixnum] index index of line in file
40
+ def check_bodies_existence(line, index)
41
+ @method_definition_line = index if line.defines_method?
42
+ return unless @method_definition_line && line.defines_end?
43
+
44
+ if method_has_no_lines?(@method_definition_line, index)
45
+ return add_empty_method(@method_definition_line)
46
+ end
47
+
48
+ body_lines = (@method_definition_line + 1)..(index - 1)
49
+ method_body = @file[body_lines]
50
+
51
+ add_empty_method(@method_definition_line) if method_is_empty?(method_body)
52
+ @method_definition_line = nil
53
+ end
54
+
55
+ # @param [Array<String>] method_body
56
+ # @return [Boolean] whether method is empty or not
57
+ def method_is_empty?(method_body)
58
+ !method_body.inject(false) { |a, e| a || e.not_commented_or_empty? }
59
+ end
60
+
61
+ # Adds line number of empty method to empty_methods.
62
+ # @param [Fixnum] index index of line
63
+ def add_empty_method(index)
64
+ empty_methods << index + 1
65
+ end
66
+
67
+ def method_has_no_lines?(body_begin, body_end)
68
+ body_end - body_begin < 2
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,45 @@
1
+ module PolishGeeks
2
+ module DevTools
3
+ module Command
4
+ class EmptyMethod
5
+ # Adds ability to check strings on specific regex matching
6
+ module StringRefinements
7
+ # Regex to determine commented or empty string
8
+ COMMENTED_OR_EMPTY = /^\s*(|#.*)$/
9
+ # Regex to determine definition of method with 'def'
10
+ DEFINITION_OF_METHOD = /^\s*def\s+\w*(\s*|\s*#.*)$/
11
+ # Regex to determine empty one-line method
12
+ EMPTY_ONE_LINE_METHOD = /^\s*def\s+.*;\s*end\s*(\s+|#.*|\n|$)$/
13
+ # Regex to determine end of method
14
+ END_REGEX = /^\s*end(\.\w+(\s+|$)|\s*#.+|\s+|$)\s*/
15
+ # Regex to determine begin of method definition through define_method
16
+ DEFINE_METHOD = '^\s*(define_method|define_singleton_method)'
17
+ # Regex to determine definition of method with do-end block
18
+ DEFINE_METHOD_WITH_DO_END =
19
+ /#{DEFINE_METHOD}(\s+|\().*do(\s*(\s*|.*\|\s*))(\s*|#.*)$/
20
+ # Regex to determine empty one-line methods
21
+ EMPTY_ONE_LINE_DEFINE_METHODS =
22
+ /#{DEFINE_METHOD}.+\s+({\s*)\s*((\|.*\|\s+})|})(\s+|\n|#|$|\.)/
23
+
24
+ refine String do
25
+ def one_line_empty_method?
26
+ match(EMPTY_ONE_LINE_METHOD) || match(EMPTY_ONE_LINE_DEFINE_METHODS)
27
+ end
28
+
29
+ def defines_method?
30
+ match(DEFINITION_OF_METHOD) || match(DEFINE_METHOD_WITH_DO_END)
31
+ end
32
+
33
+ def defines_end?
34
+ match END_REGEX
35
+ end
36
+
37
+ def not_commented_or_empty?
38
+ match(COMMENTED_OR_EMPTY).nil?
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -18,6 +18,7 @@ module PolishGeeks
18
18
  app/assets/images
19
19
  app/assets/fonts
20
20
  .DS_Store
21
+ .gem
21
22
  )
22
23
 
23
24
  # Executes this command and set output and counter variables
@@ -26,6 +26,7 @@ module PolishGeeks
26
26
  rspec_files_structure
27
27
  expires_in_files
28
28
  final_blank_line
29
+ empty_method
29
30
  ).each do |attr|
30
31
  attr_accessor "#{attr}_ignored"
31
32
  end
@@ -38,6 +39,7 @@ module PolishGeeks
38
39
  brakeman
39
40
  rubocop
40
41
  final_blank_line
42
+ empty_method
41
43
  haml_lint
42
44
  allowed_extensions
43
45
  yml_parser
@@ -14,7 +14,7 @@ module PolishGeeks
14
14
  Config::COMMANDS.each do |command|
15
15
  next unless DevTools.config.public_send(:"#{command}?")
16
16
 
17
- klass = command.to_s.gsub(/(?<=_|^)(\w)/) { |el| el.upcase }.gsub(/(?:_)(\w)/, '\1')
17
+ klass = command.to_s.gsub(/(?<=_|^)(\w)/, &:upcase).gsub(/(?:_)(\w)/, '\1')
18
18
  cmd = Object.const_get("PolishGeeks::DevTools::Command::#{klass}").new
19
19
  cmd.stored_output = output
20
20
  cmd.execute
@@ -3,6 +3,6 @@ module PolishGeeks
3
3
  # Dev Tools for PolishGeeks developers
4
4
  module DevTools
5
5
  # Current version of dev tools
6
- VERSION = '1.1.2'
6
+ VERSION = '1.1.3'
7
7
  end
8
8
  end
@@ -0,0 +1,194 @@
1
+ RSpec.describe PolishGeeks::DevTools::Command::EmptyMethod::FileParser do
2
+ let(:file) { Tempfile.new('foo') }
3
+ subject { described_class.new(file) }
4
+
5
+ describe '#find_empty_methods' do
6
+ context 'empty define_singleton_methods' do
7
+ before do
8
+ file.write("
9
+ define_singleton_method(:a) {}
10
+
11
+ define_singleton_method('b') { |_a, _b| }
12
+ define_singleton_method :c do |_a, _b|
13
+ #
14
+ #
15
+ end
16
+
17
+ define_singleton_method :d do |_a, _b|
18
+ end
19
+ ")
20
+ file.read
21
+ end
22
+
23
+ it { expect(subject.find_empty_methods).to eq([2, 4, 5, 10]) }
24
+ end
25
+
26
+ context 'empty define_methods with comments' do
27
+ before do
28
+ file.write("
29
+ define_method(:a) {} # comment
30
+
31
+ define_method('b') { |_a, _b| } # comment
32
+ define_method :c do |_a, _b| # comment
33
+ #
34
+ end
35
+ ")
36
+ file.read
37
+ end
38
+
39
+ it { expect(subject.find_empty_methods).to eq([2, 4, 5]) }
40
+ end
41
+
42
+ context 'empty define_methods' do
43
+ before do
44
+ file.write("
45
+ define_method(:a) {}
46
+
47
+ define_method('b') { |_a, _b| }
48
+ define_method :c do |_a, _b|
49
+ #
50
+ end
51
+ ")
52
+ file.read
53
+ end
54
+
55
+ it { expect(subject.find_empty_methods).to eq([2, 4, 5]) }
56
+ end
57
+
58
+ context 'singleton_methods and methods are defined' do
59
+ before do
60
+ file.write("
61
+ define_singleton_method(:a) { puts rand(5) }
62
+
63
+ define_singleton_method(:ab) { |_a, _b| rand(5) }
64
+ define_singleton_method :c do |_a, _b|
65
+ rand(5)
66
+ end
67
+ define_method(:d) { puts rand(5) }
68
+
69
+ define_method(:e) { |_a, _b| rand(5) }
70
+ define_method :f do |_a, _b|
71
+ # comment
72
+ # comment
73
+ rand(5)
74
+ end")
75
+ file.read
76
+ end
77
+
78
+ it { expect(subject.find_empty_methods).to be_empty }
79
+ end
80
+
81
+ context 'empty one line method' do
82
+ before do
83
+ file.write(' def a; end ')
84
+ file.read
85
+ end
86
+
87
+ it { expect(subject.find_empty_methods).to eq([1]) }
88
+ end
89
+
90
+ context 'empty one line method with comment' do
91
+ before do
92
+ file.write(' def a; end #comment ')
93
+ file.read
94
+ end
95
+
96
+ it { expect(subject.find_empty_methods).to eq([1]) }
97
+ end
98
+
99
+ context 'empty body method' do
100
+ before do
101
+ file.write(" def a
102
+ end ")
103
+ file.read
104
+ end
105
+
106
+ it { expect(subject.find_empty_methods).to eq([1]) }
107
+ end
108
+
109
+ context 'empty body method with comment' do
110
+ before do
111
+ file.write(" def a # comment
112
+ end #comment")
113
+ file.read
114
+ end
115
+
116
+ it { expect(subject.find_empty_methods).to eq([1]) }
117
+ end
118
+
119
+ context 'empty method' do
120
+ before do
121
+ file.write(" def a
122
+ #
123
+
124
+ #
125
+ end ")
126
+ file.read
127
+ end
128
+
129
+ it { expect(subject.find_empty_methods).to eq([1]) }
130
+ end
131
+
132
+ context 'method with comments inside' do
133
+ before do
134
+ file.write(" def a
135
+ # comment
136
+ # comment
137
+ # comment
138
+ rand(10)
139
+ end ")
140
+ file.read
141
+ end
142
+
143
+ it { expect(subject.find_empty_methods).to be_empty }
144
+ end
145
+
146
+ context 'method which defines empty define_method inside' do
147
+ before do
148
+ file.write(" def a
149
+ define_method(:asd) {}
150
+ end ")
151
+ file.read
152
+ end
153
+
154
+ it { expect(subject.find_empty_methods).to eq([2]) }
155
+ end
156
+
157
+ context 'method which defines empty define_singleton_method inside' do
158
+ before do
159
+ file.write(" def a
160
+ define_singleton_method(:asd) do
161
+ # comment
162
+ end
163
+ end ")
164
+ file.read
165
+ end
166
+
167
+ it { expect(subject.find_empty_methods).to eq([2]) }
168
+ end
169
+
170
+ context 'method which defines define_method inside' do
171
+ before do
172
+ file.write(" def a
173
+ define_method(:asd) { rand(150) } #
174
+ end ")
175
+ file.read
176
+ end
177
+
178
+ it { expect(subject.find_empty_methods).to be_empty }
179
+ end
180
+ end
181
+
182
+ describe '#method_has_no_lines?' do
183
+ it { expect(subject.send(:method_has_no_lines?, 2, 4)).to be_falsey }
184
+ it { expect(subject.send(:method_has_no_lines?, 2, 3)).to be_truthy }
185
+ end
186
+
187
+ describe '#add_empty_method' do
188
+ it { expect(subject.send(:add_empty_method, 2)).to eq [3] }
189
+ end
190
+
191
+ describe '#add_empty_method' do
192
+ it { expect(subject.send(:add_empty_method, 2)).to eq [3] }
193
+ end
194
+ end
@@ -0,0 +1,167 @@
1
+ RSpec.describe PolishGeeks::DevTools::Command::EmptyMethod::StringRefinements do
2
+ using described_class
3
+
4
+ describe '#defines_method?' do
5
+ context 'def method' do
6
+ line = ' def method_for_calculation'
7
+
8
+ it { expect(line.defines_method?).to be_truthy }
9
+ end
10
+
11
+ context 'define_method method without whitespace after' do
12
+ line = ' define_method(:method_for_calculation) do'
13
+
14
+ it { expect(line.defines_method?).to be_truthy }
15
+ end
16
+
17
+ context 'define_method method symbol definition' do
18
+ line = ' define_method :method_for_calculation do'
19
+
20
+ it { expect(line.defines_method?).to be_truthy }
21
+ end
22
+
23
+ context 'define_method method with string definition' do
24
+ line = ' define_method ("method_for_calculation") do'
25
+
26
+ it { expect(line.defines_method?).to be_truthy }
27
+ end
28
+
29
+ context 'define_method method with comment' do
30
+ line = ' define_method (:method_for_calculation) do #comment'
31
+
32
+ it { expect(line.defines_method?).to be_truthy }
33
+ end
34
+
35
+ context 'define_method method with params' do
36
+ line = ' define_method (:method_for_calculation) do |a, b| '
37
+
38
+ it { expect(line.defines_method?).to be_truthy }
39
+ end
40
+
41
+ context 'define_method method with params and comment' do
42
+ line = ' define_method (:method_for_calculation) do |a, b| #comment'
43
+
44
+ it { expect(line.defines_method?).to be_truthy }
45
+ end
46
+
47
+ context 'string that is not method definition' do
48
+ line = ' define_methods(:method_for_calculation) do |a, b| #comment'
49
+
50
+ it { expect(line.defines_method?).to be_falsey }
51
+ end
52
+
53
+ context 'string that is not method definition' do
54
+ line = ' define_methods (:method_for_calculation) do |a, b| '
55
+
56
+ it { expect(line.defines_method?).to be_falsey }
57
+ end
58
+ end
59
+
60
+ describe '#one_line_empty_method?' do
61
+ context 'def method' do
62
+ line = ' def method_for_calculation; end'
63
+
64
+ it { expect(line.one_line_empty_method?).to be_truthy }
65
+ end
66
+
67
+ context 'def method with comment' do
68
+ line = ' def method_for_calculation; end # comment'
69
+
70
+ it { expect(line.one_line_empty_method?).to be_truthy }
71
+ end
72
+
73
+ context 'define_method method' do
74
+ line = ' define_method :method_for_calculation {} '
75
+
76
+ it { expect(line.one_line_empty_method?).to be_truthy }
77
+ end
78
+
79
+ context 'define_method method with comment' do
80
+ line = ' define_method(:method_for_calculation) {} # comment'
81
+
82
+ it { expect(line.one_line_empty_method?).to be_truthy }
83
+ end
84
+
85
+ context 'define_method method with name as string' do
86
+ line = ' define_method "method_for_calculation" {} '
87
+
88
+ it { expect(line.one_line_empty_method?).to be_truthy }
89
+ end
90
+
91
+ context 'define_method method with block' do
92
+ line = ' define_method :method_for_calculation { |_a, _b| } # comment'
93
+
94
+ it { expect(line.one_line_empty_method?).to be_truthy }
95
+ end
96
+
97
+ context 'define_method method with block' do
98
+ line = ' define_method :method_for_calculation { |_a, _b| "5" } # comment'
99
+
100
+ it { expect(line.one_line_empty_method?).to be_falsey }
101
+ end
102
+
103
+ context 'not empty define_method method' do
104
+ line = ' define_method :method_for_calculation { 5 } # comment'
105
+
106
+ it { expect(line.one_line_empty_method?).to be_falsey }
107
+ end
108
+
109
+ context 'not empty def method' do
110
+ line = ' def method_for_calculation; 5 end # comment'
111
+
112
+ it { expect(line.one_line_empty_method?).to be_falsey }
113
+ end
114
+ end
115
+
116
+ describe '#defines_end?' do
117
+ context 'end' do
118
+ line = 'end'
119
+
120
+ it { expect(line.defines_end?).to be_truthy }
121
+ end
122
+
123
+ context 'end with method call' do
124
+ line = 'end.compact'
125
+
126
+ it { expect(line.defines_end?).to be_truthy }
127
+ end
128
+
129
+ context 'end with comment' do
130
+ line = 'end.compact # compacts result array'
131
+
132
+ it { expect(line.defines_end?).to be_truthy }
133
+ end
134
+
135
+ context 'end is commented' do
136
+ line = '# end'
137
+
138
+ it { expect(line.defines_end?).to be_falsey }
139
+ end
140
+
141
+ context 'similar words' do
142
+ line = 'ends'
143
+
144
+ it { expect(line.defines_end?).to be_falsey }
145
+ end
146
+ end
147
+
148
+ describe '#not_commented_or_empty?' do
149
+ context 'empty line' do
150
+ line = ' '
151
+
152
+ it { expect(line.not_commented_or_empty?).to be_falsey }
153
+ end
154
+
155
+ context 'commented line' do
156
+ line = ' # commented line '
157
+
158
+ it { expect(line.not_commented_or_empty?).to be_falsey }
159
+ end
160
+
161
+ context 'commented line' do
162
+ line = ' line '
163
+
164
+ it { expect(line.not_commented_or_empty?).to be_truthy }
165
+ end
166
+ end
167
+ end
@@ -0,0 +1,212 @@
1
+ require 'spec_helper'
2
+ require 'tempfile'
3
+
4
+ RSpec.describe PolishGeeks::DevTools::Command::EmptyMethod do
5
+ subject { described_class.new }
6
+ describe '#execute' do
7
+ let(:file) { [rand.to_s] }
8
+
9
+ before do
10
+ expect(subject)
11
+ .to receive(:files_to_analyze)
12
+ .and_return(file)
13
+ allow(described_class::FileParser)
14
+ .to receive_message_chain(:new, :find_empty_methods)
15
+ .and_return(empty_methods)
16
+ end
17
+
18
+ context 'when all files are valid' do
19
+ let(:empty_methods) { [] }
20
+ before do
21
+ subject.execute
22
+ end
23
+
24
+ it 'should set appropriate variables' do
25
+ expect(subject.output).to eq []
26
+ expect(subject.counter).to eq(file.count)
27
+ end
28
+ end
29
+
30
+ context 'when exist not valid file' do
31
+ let(:empty_methods) { [rand.to_s, rand.to_s] }
32
+ before do
33
+ expect(subject)
34
+ .to receive(:sanitize)
35
+ .with(file.first)
36
+ .and_return(file.first)
37
+ subject.execute
38
+ end
39
+
40
+ it 'should set appropriate variables' do
41
+ expect(subject.output.first).to eq "#{file.first} lines #{empty_methods}"
42
+ expect(subject.counter).to eq(file.count)
43
+ end
44
+ end
45
+ end
46
+
47
+ describe '#valid?' do
48
+ before do
49
+ subject.instance_variable_set('@output', output)
50
+ end
51
+
52
+ context 'when output is empty' do
53
+ let(:output) { [] }
54
+
55
+ it { expect(subject.valid?).to eq true }
56
+ end
57
+
58
+ context 'when output have some files' do
59
+ let(:output) { ['file_name'] }
60
+
61
+ it { expect(subject.valid?).to eq false }
62
+ end
63
+ end
64
+
65
+ describe '#label' do
66
+ let(:counter) { rand(10) }
67
+ let(:expected) { "Empty methods: #{counter} files checked" }
68
+
69
+ before do
70
+ subject.instance_variable_set('@counter', counter)
71
+ end
72
+
73
+ it { expect(subject.label).to eq expected }
74
+ end
75
+
76
+ describe '#error_message' do
77
+ let(:output) { [rand.to_s, rand.to_s] }
78
+ let(:expected) { "Following files contains blank methods: \n#{output.join("\n")}\n" }
79
+
80
+ before do
81
+ subject.instance_variable_set('@output', output)
82
+ end
83
+
84
+ it { expect(subject.error_message).to eq expected }
85
+ end
86
+
87
+ describe '#files_to_analyze' do
88
+ let(:files) { [rand.to_s, rand.to_s] }
89
+
90
+ before do
91
+ expect(subject)
92
+ .to receive(:files_from_path)
93
+ .with('**/*.rb')
94
+ .and_return(files)
95
+
96
+ expect(subject)
97
+ .to receive(:remove_excludes)
98
+ .with(files)
99
+ .and_return(files)
100
+ end
101
+
102
+ it { expect(subject.send(:files_to_analyze)).to eq files }
103
+ end
104
+
105
+ describe '#remove_excludes' do
106
+ let(:files) { %w(lib/file.txt exclude.txt file.rb) }
107
+ let(:excludes) { %w(lib exclude.txt) }
108
+
109
+ before do
110
+ expect(subject)
111
+ .to receive(:excludes)
112
+ .and_return(excludes)
113
+ end
114
+
115
+ it { expect(subject.send(:remove_excludes, files)).to eq ['file.rb'] }
116
+ end
117
+
118
+ describe '#excludes' do
119
+ let(:configs) { [rand.to_s] }
120
+ let(:expected) { configs + described_class::DEFAULT_PATHS_TO_EXCLUDE }
121
+
122
+ before do
123
+ expect(subject)
124
+ .to receive(:config_excludes)
125
+ .and_return(configs)
126
+ end
127
+
128
+ it { expect(subject.send(:excludes)).to eq expected }
129
+ end
130
+
131
+ describe '#config_excludes' do
132
+ context 'empty_method_ignored is set' do
133
+ let(:paths) { ["#{rand}.rb", "#{rand}.rb"] }
134
+ let(:config) { double(empty_method_ignored: paths) }
135
+
136
+ before do
137
+ expect(PolishGeeks::DevTools)
138
+ .to receive(:config)
139
+ .and_return config
140
+ end
141
+
142
+ it { expect(subject.send(:config_excludes)).to eq paths }
143
+ end
144
+
145
+ context 'empty_method_ignored is not set' do
146
+ let(:config) { double(empty_method_ignored: nil) }
147
+
148
+ before do
149
+ expect(PolishGeeks::DevTools)
150
+ .to receive(:config)
151
+ .and_return config
152
+ end
153
+
154
+ it { expect(subject.send(:config_excludes)).to eq [] }
155
+ end
156
+ end
157
+
158
+ describe '#files_from_path' do
159
+ let(:app_root) { PolishGeeks::DevTools.app_root }
160
+
161
+ context 'path is a directory' do
162
+ let(:path) { rand.to_s }
163
+ let(:file_in_path) { "#{app_root}/#{rand}" }
164
+ let(:dir_in_path) { "#{app_root}/#{rand}" }
165
+
166
+ before do
167
+ expect(File)
168
+ .to receive(:file?)
169
+ .with("#{app_root}/#{path}")
170
+ .and_return(false)
171
+
172
+ expect(Dir)
173
+ .to receive(:glob)
174
+ .with("#{app_root}/#{path}")
175
+ .and_return([file_in_path, dir_in_path])
176
+
177
+ expect(File)
178
+ .to receive(:file?)
179
+ .with(file_in_path)
180
+ .and_return(true)
181
+
182
+ expect(File)
183
+ .to receive(:file?)
184
+ .with(dir_in_path)
185
+ .and_return(false)
186
+ end
187
+
188
+ it { expect(subject.send(:files_from_path, path)).to eq [file_in_path] }
189
+ end
190
+
191
+ context 'path is a file' do
192
+ let(:path) { rand.to_s }
193
+
194
+ before do
195
+ expect(File)
196
+ .to receive(:file?)
197
+ .with("#{app_root}/#{path}")
198
+ .and_return(true)
199
+ end
200
+
201
+ it { expect(subject.send(:files_from_path, path)).to eq ["#{app_root}/#{path}"] }
202
+ end
203
+ end
204
+
205
+ describe '#sanitize' do
206
+ let(:file) { rand.to_s }
207
+ let(:app_root) { PolishGeeks::DevTools.app_root }
208
+ let(:path) { "#{app_root}/#{file}" }
209
+
210
+ it { expect(subject.send(:sanitize, "#{app_root}/#{path}")).to eq file }
211
+ end
212
+ end
@@ -21,7 +21,7 @@ RSpec.describe PolishGeeks::DevTools::Runner do
21
21
  PolishGeeks::DevTools::Config::COMMANDS.each do |command|
22
22
  config.public_send(:"#{command}=", true)
23
23
 
24
- klass_name = command.to_s.gsub(/(?<=_|^)(\w)/) { |el| el.upcase }.gsub(/(?:_)(\w)/, '\1')
24
+ klass_name = command.to_s.gsub(/(?<=_|^)(\w)/, &:upcase).gsub(/(?:_)(\w)/, '\1')
25
25
  klass = Object.const_get("PolishGeeks::DevTools::Command::#{klass_name}")
26
26
 
27
27
  instance = double
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: polishgeeks-dev-tools
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.2
4
+ version: 1.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Maciej Mensfeld
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-08-31 00:00:00.000000000 Z
11
+ date: 2015-09-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -230,6 +230,9 @@ files:
230
230
  - lib/polishgeeks/dev-tools/command/base.rb
231
231
  - lib/polishgeeks/dev-tools/command/brakeman.rb
232
232
  - lib/polishgeeks/dev-tools/command/coverage.rb
233
+ - lib/polishgeeks/dev-tools/command/empty_method.rb
234
+ - lib/polishgeeks/dev-tools/command/empty_method/file_parser.rb
235
+ - lib/polishgeeks/dev-tools/command/empty_method/string_refinements.rb
233
236
  - lib/polishgeeks/dev-tools/command/examples_comparator.rb
234
237
  - lib/polishgeeks/dev-tools/command/expires_in.rb
235
238
  - lib/polishgeeks/dev-tools/command/final_blank_line.rb
@@ -258,6 +261,9 @@ files:
258
261
  - spec/lib/polishgeeks/dev-tools/command/base_spec.rb
259
262
  - spec/lib/polishgeeks/dev-tools/command/brakeman_spec.rb
260
263
  - spec/lib/polishgeeks/dev-tools/command/coverage_spec.rb
264
+ - spec/lib/polishgeeks/dev-tools/command/empty_method/file_parser_spec.rb
265
+ - spec/lib/polishgeeks/dev-tools/command/empty_method/string_refinements_spec.rb
266
+ - spec/lib/polishgeeks/dev-tools/command/empty_method_spec.rb
261
267
  - spec/lib/polishgeeks/dev-tools/command/examples_comparator_spec.rb
262
268
  - spec/lib/polishgeeks/dev-tools/command/expires_in_spec.rb
263
269
  - spec/lib/polishgeeks/dev-tools/command/final_blank_line_spec.rb
@@ -309,6 +315,9 @@ test_files:
309
315
  - spec/lib/polishgeeks/dev-tools/command/base_spec.rb
310
316
  - spec/lib/polishgeeks/dev-tools/command/brakeman_spec.rb
311
317
  - spec/lib/polishgeeks/dev-tools/command/coverage_spec.rb
318
+ - spec/lib/polishgeeks/dev-tools/command/empty_method/file_parser_spec.rb
319
+ - spec/lib/polishgeeks/dev-tools/command/empty_method/string_refinements_spec.rb
320
+ - spec/lib/polishgeeks/dev-tools/command/empty_method_spec.rb
312
321
  - spec/lib/polishgeeks/dev-tools/command/examples_comparator_spec.rb
313
322
  - spec/lib/polishgeeks/dev-tools/command/expires_in_spec.rb
314
323
  - spec/lib/polishgeeks/dev-tools/command/final_blank_line_spec.rb
@@ -331,3 +340,4 @@ test_files:
331
340
  - spec/lib/polishgeeks/dev-tools/shell_spec.rb
332
341
  - spec/lib/polishgeeks/dev-tools/version_spec.rb
333
342
  - spec/spec_helper.rb
343
+ has_rdoc: