diff --git a/CHANGELOG.md b/CHANGELOG.md index 250b2ea76f6e..32763e073d37 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,10 @@ * [#896](https://github.com/bbatsov/rubocop/issues/896): New option `--fail-level` changes minimum severity for exit with error code. ([@hiroponz][]) * `VariableInterpolation` cop does auto-correction. ([@bbatsov][]) +### Changes + +* [#913](https://github.com/bbatsov/rubocop/issues/913): `FileName` accepts multiple extensions. ([@tamird][]) + ### Bugs fixed * [#904](https://github.com/bbatsov/rubocop/issues/904): Fixed a NPE in `LiteralInInterpolation`. ([@bbatsov][]) @@ -794,3 +798,4 @@ [@tmorris-fiksu]: https://github.com/tmorris-fiksu [@mockdeep]: https://github.com/mockdeep [@hiroponz]: https://github.com/hiroponz +[@tamird]: https://github.com/tamird diff --git a/lib/rubocop/cop/style/file_name.rb b/lib/rubocop/cop/style/file_name.rb index 399b4c2043f5..c37f76fff26b 100644 --- a/lib/rubocop/cop/style/file_name.rb +++ b/lib/rubocop/cop/style/file_name.rb @@ -16,7 +16,7 @@ def investigate(processed_source) basename = File.basename(file_path).sub(/\.[^\.]+$/, '') - unless basename =~ SNAKE_CASE + unless basename.split('.').all? { |fragment| fragment =~ SNAKE_CASE } add_offense(nil, source_range(processed_source.buffer, processed_source[0..0], diff --git a/spec/rubocop/cop/style/file_name_spec.rb b/spec/rubocop/cop/style/file_name_spec.rb index b7096a1ac7c6..405b56620518 100644 --- a/spec/rubocop/cop/style/file_name_spec.rb +++ b/spec/rubocop/cop/style/file_name_spec.rb @@ -6,67 +6,79 @@ subject(:cop) { described_class.new(config) } let(:config) do - Rubocop::Config.new({ 'AllCops' => { 'Includes' => includes } }, - '/some/.rubocop.yml') + Rubocop::Config.new( + { 'AllCops' => { 'Includes' => includes } }, + '/some/.rubocop.yml' + ) end let(:includes) { [] } + let(:source) { ['print 1'] } + let(:processed_source) { parse_source(source) } - it 'reports offense for camelCase file names ending in .rb' do - source = ['print 1'] - processed_source = parse_source(source) + before do allow(processed_source.buffer) - .to receive(:name).and_return('/some/dir/testCase.rb') + .to receive(:name).and_return(filename) _investigate(cop, processed_source) - expect(cop.offenses.size).to eq(1) end - it 'reports offense for camelCase file names without file extension' do - source = ['print 1'] - processed_source = parse_source(source) - allow(processed_source.buffer) - .to receive(:name).and_return('/some/dir/testCase') - _investigate(cop, processed_source) - expect(cop.offenses.size).to eq(1) + context 'with camelCase file names ending in .rb' do + let(:filename) { '/some/dir/testCase.rb' } + + it 'reports an offense' do + expect(cop.offenses.size).to eq(1) + end end - it 'accepts offense for snake_case file names ending in .rb' do - source = ['print 1'] - processed_source = parse_source(source) - allow(processed_source.buffer) - .to receive(:name).and_return('/some/dir/test_case.rb') - _investigate(cop, processed_source) - expect(cop.offenses).to be_empty + context 'with camelCase file names without file extension' do + let(:filename) { '/some/dir/testCase' } + + it 'reports an offense' do + expect(cop.offenses.size).to eq(1) + end end - it 'accepts offense for snake_case file names without file extension' do - source = ['print 1'] - processed_source = parse_source(source) - allow(processed_source.buffer) - .to receive(:name).and_return('/some/dir/test_case') - _investigate(cop, processed_source) - expect(cop.offenses).to be_empty + context 'with snake_case file names ending in .rb' do + let(:filename) { '/some/dir/test_case.rb' } + + it 'reports an offense' do + expect(cop.offenses).to be_empty + end end - it 'accepts offense for snake_case file names with non-rb extension' do - source = ['print 1'] - processed_source = parse_source(source) - allow(processed_source.buffer) - .to receive(:name).and_return('/some/dir/some_task.rake') - _investigate(cop, processed_source) - expect(cop.offenses).to be_empty + context 'with snake_case file names without file extension' do + let(:filename) { '/some/dir/test_case' } + + it 'does not report an offense' do + expect(cop.offenses).to be_empty + end + end + + context 'with snake_case file names with non-rb extension' do + let(:filename) { '/some/dir/some_task.rake' } + + it 'does not report an offense' do + expect(cop.offenses).to be_empty + end + end + + context 'with snake_case file names with multiple extensions' do + let(:filename) { 'some/dir/some_view.html.slim_spec.rb' } + + it 'does not report an offense' do + expect(cop.offenses).to be_empty + end end context 'when the file is specified in AllCops/Includes' do let(:includes) { ['**/Gemfile'] } - it 'accepts the file name even if it is not snake_case' do - source = ['print 1'] - processed_source = parse_source(source) - allow(processed_source.buffer) - .to receive(:name).and_return('/some/dir/Gemfile') - _investigate(cop, processed_source) - expect(cop.offenses).to be_empty + context 'with a non-snake_case file name' do + let(:filename) { '/some/dir/Gemfile' } + + it 'does not report an offense' do + expect(cop.offenses).to be_empty + end end end end