diff --git a/lib/degem/find_unused.rb b/lib/degem/find_unused.rb index 81ac2d5..64aaffd 100644 --- a/lib/degem/find_unused.rb +++ b/lib/degem/find_unused.rb @@ -36,9 +36,11 @@ def reject_used(rubygems) def matchers [ method(:based_on_top_module), - method(:based_on_top_composite_module), + method(:based_on_top_composite_module_dash), + method(:based_on_top_composite_module_underscore), method(:based_on_top_call), - method(:based_on_top_composite_call), + method(:based_on_top_composite_call_dash), + method(:based_on_top_composite_call_underscore), method(:based_on_require), method(:based_on_require_prefix_path), method(:based_on_require_path) @@ -66,8 +68,21 @@ def based_on_top_module(rubygem, line) regex.match?(line) end + # gem foo_bar -> FooBar (but not XFooBar or X::FooBar) + def based_on_top_composite_module_underscore(rubygem, line) + return false unless rubygem.name.include?("_") + + regex = %r{ + (? Foo::Bar (but not XFoo::Bar or X::Foo::Bar) - def based_on_top_composite_module(rubygem, line) + def based_on_top_composite_module_dash(rubygem, line) return false unless rubygem.name.include?("-") regex = %r{ @@ -92,7 +107,7 @@ def based_on_top_call(rubygem, line) end # gem foo-bar -> FooBar. (but not X::FooBar. or XFooBar.) - def based_on_top_composite_call(rubygem, line) + def based_on_top_composite_call_dash(rubygem, line) return false unless rubygem.name.include?("-") regex = %r{ @@ -104,6 +119,19 @@ def based_on_top_composite_call(rubygem, line) regex.match?(line) end + # gem foo_bar -> FooBar. (but not X::FooBar. or XFooBar.) + def based_on_top_composite_call_underscore(rubygem, line) + return false unless rubygem.name.include?("_") + + regex = %r{ + (? require 'foo-bar' def based_on_require(rubygem, line) regex = %r{ diff --git a/test/test_find_unused.rb b/test/test_find_unused.rb index a44b19a..9f5de39 100644 --- a/test/test_find_unused.rb +++ b/test/test_find_unused.rb @@ -98,6 +98,48 @@ def test_it_detects_unused_gems_based_on_the_top_module_6 end end + def test_it_detects_unused_gems_based_on_the_top_module_7 + content = "FooBar::Baz".prepend(padding).concat(padding) + + with_gemfile do |gemfile_path| + bundle_install(%w[foo foobar foo-bar foo_bar bar]) do |gemspec_paths| + with_file(path: File.join("app", "services", "baz.rb"), content: content) do |f| + gem_specification = TestableGemSpecification.new(gemspec_paths) + actual = Degem::FindUnused.new(gemfile_path:, gem_specification:, bundle_paths: ->(_) { [f] }).call + assert_equal %w[foo foobar foo-bar bar], actual.map(&:name) + end + end + end + end + + def test_it_detects_unused_gems_based_on_the_top_module_8 + content = "XFooBar::Baz".prepend(padding).concat(padding) + + with_gemfile do |gemfile_path| + bundle_install(%w[foo foobar foo-bar foo_bar bar]) do |gemspec_paths| + with_file(path: File.join("app", "services", "baz.rb"), content: content) do |f| + gem_specification = TestableGemSpecification.new(gemspec_paths) + actual = Degem::FindUnused.new(gemfile_path:, gem_specification:, bundle_paths: ->(_) { [f] }).call + assert_equal %w[foo foobar foo-bar foo_bar bar], actual.map(&:name) + end + end + end + end + + def test_it_detects_unused_gems_based_on_the_top_module_9 + content = "X::FooBar::Baz".prepend(padding).concat(padding) + + with_gemfile do |gemfile_path| + bundle_install(%w[foo foobar foo-bar foo_bar bar]) do |gemspec_paths| + with_file(path: File.join("app", "services", "baz.rb"), content: content) do |f| + gem_specification = TestableGemSpecification.new(gemspec_paths) + actual = Degem::FindUnused.new(gemfile_path:, gem_specification:, bundle_paths: ->(_) { [f] }).call + assert_equal %w[foo foobar foo-bar foo_bar bar], actual.map(&:name) + end + end + end + end + def test_it_detects_unused_gems_based_on_the_top_call_1 content = "Foobar.new.call".prepend(padding).concat(padding) @@ -168,6 +210,48 @@ def test_it_detects_unused_gems_based_on_the_top_call_5 end end + def test_it_detects_unused_gems_based_on_the_top_call_6 + content = "FooBar.baz".prepend(padding).concat(padding) + + with_gemfile do |gemfile_path| + bundle_install(%w[foo foobar foo-bar foo_bar bar]) do |gemspec_paths| + with_file(path: File.join("app", "services", "baz.rb"), content: content) do |f| + gem_specification = TestableGemSpecification.new(gemspec_paths) + actual = Degem::FindUnused.new(gemfile_path:, gem_specification:, bundle_paths: ->(_) { [f] }).call + assert_equal %w[foo foobar bar], actual.map(&:name) + end + end + end + end + + def test_it_detects_unused_gems_based_on_the_top_call_7 + content = "XFooBar.baz".prepend(padding).concat(padding) + + with_gemfile do |gemfile_path| + bundle_install(%w[foo foobar foo-bar foo_bar bar]) do |gemspec_paths| + with_file(path: File.join("app", "services", "baz.rb"), content: content) do |f| + gem_specification = TestableGemSpecification.new(gemspec_paths) + actual = Degem::FindUnused.new(gemfile_path:, gem_specification:, bundle_paths: ->(_) { [f] }).call + assert_equal %w[foo foobar foo-bar foo_bar bar], actual.map(&:name) + end + end + end + end + + def test_it_detects_unused_gems_based_on_the_top_call_8 + content = "X::FooBar.baz".prepend(padding).concat(padding) + + with_gemfile do |gemfile_path| + bundle_install(%w[foo foobar foo-bar foo_bar bar]) do |gemspec_paths| + with_file(path: File.join("app", "services", "baz.rb"), content: content) do |f| + gem_specification = TestableGemSpecification.new(gemspec_paths) + actual = Degem::FindUnused.new(gemfile_path:, gem_specification:, bundle_paths: ->(_) { [f] }).call + assert_equal %w[foo foobar foo-bar foo_bar bar], actual.map(&:name) + end + end + end + end + def test_it_detects_unused_gems_based_on_require content = "require 'foo-bar'".prepend(padding).concat(padding)