diff --git a/changelog/fix_fix_styleclassandmodulechildren_false.md b/changelog/fix_fix_styleclassandmodulechildren_false.md new file mode 100644 index 00000000000..dae20dd748d --- /dev/null +++ b/changelog/fix_fix_styleclassandmodulechildren_false.md @@ -0,0 +1 @@ +* [#9761](https://github.com/rubocop/rubocop/issues/9761): Fix `Style/ClassAndModuleChildren` false negative for `compact` style when a class/module is partially nested. ([@dvandersluis][]) diff --git a/lib/rubocop/cop/style/class_and_module_children.rb b/lib/rubocop/cop/style/class_and_module_children.rb index 16b26c1cf63..1a03cf43478 100644 --- a/lib/rubocop/cop/style/class_and_module_children.rb +++ b/lib/rubocop/cop/style/class_and_module_children.rb @@ -132,7 +132,7 @@ def check_nested_style(node) end def check_compact_style(node, body) - return unless one_child?(body) && !compact_node_name?(node) + return unless needs_compacting?(body) add_offense(node.loc.name, message: COMPACT_MSG) do |corrector| autocorrect(corrector, node) @@ -145,12 +145,12 @@ def autocorrect(corrector, node) nest_or_compact(corrector, node) end - def one_child?(body) + def needs_compacting?(body) body && %i[module class].include?(body.type) end def compact_node_name?(node) - /::/.match?(node.loc.name.source) + /::/.match?(node.identifier.source) end end end diff --git a/spec/rubocop/cop/style/class_and_module_children_spec.rb b/spec/rubocop/cop/style/class_and_module_children_spec.rb index f1f6b129deb..f3b1312ad3a 100644 --- a/spec/rubocop/cop/style/class_and_module_children_spec.rb +++ b/spec/rubocop/cop/style/class_and_module_children_spec.rb @@ -91,6 +91,44 @@ module BarModule RUBY end + it 'registers an offense for partially nested classes' do + expect_offense(<<~RUBY) + class Foo::Bar + ^^^^^^^^ Use nested module/class definitions instead of compact style. + class Baz + end + end + RUBY + + expect_correction(<<~RUBY) + module Foo + class Bar + class Baz + end + end + end + RUBY + end + + it 'registers an offense for partially nested modules' do + expect_offense(<<~RUBY) + module Foo::Bar + ^^^^^^^^ Use nested module/class definitions instead of compact style. + module Baz + end + end + RUBY + + expect_correction(<<~RUBY) + module Foo + module Bar + module Baz + end + end + end + RUBY + end + it 'accepts nested children' do expect_no_offenses(<<~RUBY) class FooClass @@ -165,6 +203,54 @@ module FooModule::BarModule RUBY end + it 'registers an offense for classes with partially nested children' do + expect_offense(<<~RUBY) + class Foo::Bar + ^^^^^^^^ Use compact module/class definition instead of nested style. + class Baz + end + end + + class Foo + ^^^ Use compact module/class definition instead of nested style. + class Bar::Baz + end + end + RUBY + + expect_correction(<<~RUBY) + class Foo::Bar::Baz + end + + class Foo::Bar::Baz + end + RUBY + end + + it 'registers an offense for modules with partially nested children' do + expect_offense(<<~RUBY) + module Foo::Bar + ^^^^^^^^ Use compact module/class definition instead of nested style. + module Baz + end + end + + module Foo + ^^^ Use compact module/class definition instead of nested style. + module Bar::Baz + end + end + RUBY + + expect_correction(<<~RUBY) + module Foo::Bar::Baz + end + + module Foo::Bar::Baz + end + RUBY + end + it 'accepts compact style for classes/modules' do expect_no_offenses(<<~RUBY) class FooClass::BarClass