447 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
			
		
		
	
	
			447 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
| # frozen_string_literal: true
 | |
| 
 | |
| require "rubocops/presence"
 | |
| 
 | |
| RSpec.describe RuboCop::Cop::Homebrew::Presence, :config do
 | |
|   it "registers an offense and corrects when `a.present? ? a : nil`" do
 | |
|     expect_offense(<<~RUBY)
 | |
|       a.present? ? a : nil
 | |
|       ^^^^^^^^^^^^^^^^^^^^ Use `a.presence` instead of `a.present? ? a : nil`.
 | |
|     RUBY
 | |
| 
 | |
|     expect_correction(<<~RUBY)
 | |
|       a.presence
 | |
|     RUBY
 | |
|   end
 | |
| 
 | |
|   it "registers an offense and corrects when `!a.present? ? nil: a`" do
 | |
|     expect_offense(<<~RUBY)
 | |
|       !a.present? ? nil: a
 | |
|       ^^^^^^^^^^^^^^^^^^^^ Use `a.presence` instead of `!a.present? ? nil: a`.
 | |
|     RUBY
 | |
| 
 | |
|     expect_correction(<<~RUBY)
 | |
|       a.presence
 | |
|     RUBY
 | |
|   end
 | |
| 
 | |
|   it "registers an offense and corrects when `a.blank? ? nil : a`" do
 | |
|     expect_offense(<<~RUBY)
 | |
|       a.blank? ? nil : a
 | |
|       ^^^^^^^^^^^^^^^^^^ Use `a.presence` instead of `a.blank? ? nil : a`.
 | |
|     RUBY
 | |
| 
 | |
|     expect_correction(<<~RUBY)
 | |
|       a.presence
 | |
|     RUBY
 | |
|   end
 | |
| 
 | |
|   it "registers an offense and corrects when `!a.blank? ? a : nil`" do
 | |
|     expect_offense(<<~RUBY)
 | |
|       !a.blank? ? a : nil
 | |
|       ^^^^^^^^^^^^^^^^^^^ Use `a.presence` instead of `!a.blank? ? a : nil`.
 | |
|     RUBY
 | |
| 
 | |
|     expect_correction(<<~RUBY)
 | |
|       a.presence
 | |
|     RUBY
 | |
|   end
 | |
| 
 | |
|   it "registers an offense and corrects when `a.present? ? a : b`" do
 | |
|     expect_offense(<<~RUBY)
 | |
|       a.present? ? a : b
 | |
|       ^^^^^^^^^^^^^^^^^^ Use `a.presence || b` instead of `a.present? ? a : b`.
 | |
|     RUBY
 | |
| 
 | |
|     expect_correction(<<~RUBY)
 | |
|       a.presence || b
 | |
|     RUBY
 | |
|   end
 | |
| 
 | |
|   it "registers an offense and corrects when `!a.present? ? b : a`" do
 | |
|     expect_offense(<<~RUBY)
 | |
|       !a.present? ? b : a
 | |
|       ^^^^^^^^^^^^^^^^^^^ Use `a.presence || b` instead of `!a.present? ? b : a`.
 | |
|     RUBY
 | |
| 
 | |
|     expect_correction(<<~RUBY)
 | |
|       a.presence || b
 | |
|     RUBY
 | |
|   end
 | |
| 
 | |
|   it "registers an offense and corrects when `a.blank? ? b : a`" do
 | |
|     expect_offense(<<~RUBY)
 | |
|       a.blank? ? b : a
 | |
|       ^^^^^^^^^^^^^^^^ Use `a.presence || b` instead of `a.blank? ? b : a`.
 | |
|     RUBY
 | |
| 
 | |
|     expect_correction(<<~RUBY)
 | |
|       a.presence || b
 | |
|     RUBY
 | |
|   end
 | |
| 
 | |
|   it "registers an offense and corrects when `!a.blank? ? a : b`" do
 | |
|     expect_offense(<<~RUBY)
 | |
|       !a.blank? ? a : b
 | |
|       ^^^^^^^^^^^^^^^^^ Use `a.presence || b` instead of `!a.blank? ? a : b`.
 | |
|     RUBY
 | |
| 
 | |
|     expect_correction(<<~RUBY)
 | |
|       a.presence || b
 | |
|     RUBY
 | |
|   end
 | |
| 
 | |
|   it "registers an offense and corrects when `a.present? ? a : 1`" do
 | |
|     expect_offense(<<~RUBY)
 | |
|       a.present? ? a : 1
 | |
|       ^^^^^^^^^^^^^^^^^^ Use `a.presence || 1` instead of `a.present? ? a : 1`.
 | |
|     RUBY
 | |
| 
 | |
|     expect_correction(<<~RUBY)
 | |
|       a.presence || 1
 | |
|     RUBY
 | |
|   end
 | |
| 
 | |
|   it "registers an offense and corrects when `a.blank? ? 1 : a`" do
 | |
|     expect_offense(<<~RUBY)
 | |
|       a.blank? ? 1 : a
 | |
|       ^^^^^^^^^^^^^^^^ Use `a.presence || 1` instead of `a.blank? ? 1 : a`.
 | |
|     RUBY
 | |
| 
 | |
|     expect_correction(<<~RUBY)
 | |
|       a.presence || 1
 | |
|     RUBY
 | |
|   end
 | |
| 
 | |
|   it "registers an offense and corrects when `a(:bar).map(&:baz).present? ? a(:bar).map(&:baz) : nil`" do
 | |
|     expect_offense(<<~RUBY)
 | |
|       a(:bar).map(&:baz).present? ? a(:bar).map(&:baz) : nil
 | |
|       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Use `a(:bar).map(&:baz).presence` instead of `a(:bar).map(&:baz).present? ? a(:bar).map(&:baz) : nil`.
 | |
|     RUBY
 | |
| 
 | |
|     expect_correction(<<~RUBY)
 | |
|       a(:bar).map(&:baz).presence
 | |
|     RUBY
 | |
|   end
 | |
| 
 | |
|   it "registers an offense and corrects when `a.present? ? a : b[:c]`" do
 | |
|     expect_offense(<<~RUBY)
 | |
|       a.present? ? a : b[:c]
 | |
|       ^^^^^^^^^^^^^^^^^^^^^^ Use `a.presence || b[:c]` instead of `a.present? ? a : b[:c]`.
 | |
|     RUBY
 | |
| 
 | |
|     expect_correction(<<~RUBY)
 | |
|       a.presence || b[:c]
 | |
|     RUBY
 | |
|   end
 | |
| 
 | |
|   it "registers an offense and corrects when multi-line if node" do
 | |
|     expect_offense(<<~RUBY)
 | |
|       if a.present?
 | |
|       ^^^^^^^^^^^^^ Use `a.presence` instead of `if a.present? ... end`.
 | |
|         a
 | |
|       else
 | |
|         nil
 | |
|       end
 | |
|     RUBY
 | |
| 
 | |
|     expect_correction(<<~RUBY)
 | |
|       a.presence
 | |
|     RUBY
 | |
|   end
 | |
| 
 | |
|   it "registers an offense and corrects when multi-line unless node" do
 | |
|     expect_offense(<<~RUBY)
 | |
|       unless a.present?
 | |
|       ^^^^^^^^^^^^^^^^^ Use `a.presence` instead of `unless a.present? ... end`.
 | |
|         nil
 | |
|       else
 | |
|         a
 | |
|       end
 | |
|     RUBY
 | |
| 
 | |
|     expect_correction(<<~RUBY)
 | |
|       a.presence
 | |
|     RUBY
 | |
|   end
 | |
| 
 | |
|   it "registers an offense and corrects when multi-line if node with `+` operators in the else branch" do
 | |
|     expect_offense(<<~RUBY)
 | |
|       if a.present?
 | |
|       ^^^^^^^^^^^^^ Use `a.presence || b.to_f + 12.0` instead of `if a.present? ... end`.
 | |
|         a
 | |
|       else
 | |
|         b.to_f + 12.0
 | |
|       end
 | |
|     RUBY
 | |
| 
 | |
|     expect_correction(<<~RUBY)
 | |
|       a.presence || b.to_f + 12.0
 | |
|     RUBY
 | |
|   end
 | |
| 
 | |
|   it "registers an offense and corrects when multi-line if `*` operators in the else branch" do
 | |
|     expect_offense(<<~RUBY)
 | |
|       if a.present?
 | |
|       ^^^^^^^^^^^^^ Use `a.presence || b.to_f * 12.0` instead of `if a.present? ... end`.
 | |
|         a
 | |
|       else
 | |
|         b.to_f * 12.0
 | |
|       end
 | |
|     RUBY
 | |
| 
 | |
|     expect_correction(<<~RUBY)
 | |
|       a.presence || b.to_f * 12.0
 | |
|     RUBY
 | |
|   end
 | |
| 
 | |
|   it "registers an offense and corrects when `a if a.present?`" do
 | |
|     expect_offense(<<~RUBY)
 | |
|       a if a.present?
 | |
|       ^^^^^^^^^^^^^^^ Use `a.presence` instead of `a if a.present?`.
 | |
|     RUBY
 | |
| 
 | |
|     expect_correction(<<~RUBY)
 | |
|       a.presence
 | |
|     RUBY
 | |
|   end
 | |
| 
 | |
|   it "registers an offense and corrects when `a unless a.blank?`" do
 | |
|     expect_offense(<<~RUBY)
 | |
|       a unless a.blank?
 | |
|       ^^^^^^^^^^^^^^^^^ Use `a.presence` instead of `a unless a.blank?`.
 | |
|     RUBY
 | |
| 
 | |
|     expect_correction(<<~RUBY)
 | |
|       a.presence
 | |
|     RUBY
 | |
|   end
 | |
| 
 | |
|   it "registers an offense and corrects when `.present?` with method chain" do
 | |
|     expect_offense(<<~RUBY)
 | |
|       if [1, 2, 3].map { |num| num + 1 }
 | |
|       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Use `[1, 2, 3].map { |num| num + 1 }.map { |num| num + 2 }.presence || b` instead of `if [1, 2, 3].map { |num| num + 1 }.map { |num| num + 2 }.present? ... end`.
 | |
|                   .map { |num| num + 2 }
 | |
|                   .present?
 | |
|                   [1, 2, 3].map { |num| num + 1 }.map { |num| num + 2 }
 | |
|       else
 | |
|         b
 | |
|       end
 | |
|     RUBY
 | |
| 
 | |
|     expect_correction(<<~RUBY)
 | |
|       [1, 2, 3].map { |num| num + 1 }
 | |
|                   .map { |num| num + 2 }.presence || b
 | |
|     RUBY
 | |
|   end
 | |
| 
 | |
|   context "when multiline ternary can be replaced" do
 | |
|     it "registers an offense and corrects" do
 | |
|       expect_offense(<<~RUBY)
 | |
|         a.present? ?
 | |
|         ^^^^^^^^^^^^ Use `a.presence` instead of `a.present? ? a : nil`.
 | |
|           a :
 | |
|           nil
 | |
|       RUBY
 | |
| 
 | |
|       expect_correction(<<~RUBY)
 | |
|         a.presence
 | |
|       RUBY
 | |
|     end
 | |
|   end
 | |
| 
 | |
|   context "when a method argument of `else` branch is enclosed in parentheses" do
 | |
|     it "registers an offense and corrects" do
 | |
|       expect_offense(<<~RUBY)
 | |
|         if value.present?
 | |
|         ^^^^^^^^^^^^^^^^^ Use `value.presence || do_something(value)` instead of `if value.present? ... end`.
 | |
|           value
 | |
|         else
 | |
|           do_something(value)
 | |
|         end
 | |
|       RUBY
 | |
| 
 | |
|       expect_correction(<<~RUBY)
 | |
|         value.presence || do_something(value)
 | |
|       RUBY
 | |
|     end
 | |
|   end
 | |
| 
 | |
|   context "when a method argument of `else` branch is not enclosed in parentheses" do
 | |
|     it "registers an offense and corrects" do
 | |
|       expect_offense(<<~RUBY)
 | |
|         if value.present?
 | |
|         ^^^^^^^^^^^^^^^^^ Use `value.presence || do_something(value)` instead of `if value.present? ... end`.
 | |
|           value
 | |
|         else
 | |
|           do_something value
 | |
|         end
 | |
|       RUBY
 | |
| 
 | |
|       expect_correction(<<~RUBY)
 | |
|         value.presence || do_something(value)
 | |
|       RUBY
 | |
|     end
 | |
|   end
 | |
| 
 | |
|   context "when multiple method arguments of `else` branch is not enclosed in parentheses" do
 | |
|     it "registers an offense and corrects" do
 | |
|       expect_offense(<<~RUBY)
 | |
|         if value.present?
 | |
|         ^^^^^^^^^^^^^^^^^ Use `value.presence || do_something(arg1, arg2)` instead of `if value.present? ... end`.
 | |
|           value
 | |
|         else
 | |
|           do_something arg1, arg2
 | |
|         end
 | |
|       RUBY
 | |
| 
 | |
|       expect_correction(<<~RUBY)
 | |
|         value.presence || do_something(arg1, arg2)
 | |
|       RUBY
 | |
|     end
 | |
|   end
 | |
| 
 | |
|   context "when a method argument with a receiver of `else` branch is not enclosed in parentheses" do
 | |
|     it "registers an offense and corrects" do
 | |
|       expect_offense(<<~RUBY)
 | |
|         if value.present?
 | |
|         ^^^^^^^^^^^^^^^^^ Use `value.presence || foo.do_something(value)` instead of `if value.present? ... end`.
 | |
|           value
 | |
|         else
 | |
|           foo.do_something value
 | |
|         end
 | |
|       RUBY
 | |
| 
 | |
|       expect_correction(<<~RUBY)
 | |
|         value.presence || foo.do_something(value)
 | |
|       RUBY
 | |
|     end
 | |
|   end
 | |
| 
 | |
|   context "when a right-hand side of the relational operator" do
 | |
|     %w[< > <= >= == !=].each do |operator|
 | |
|       it "registers an offense and corrects when `#{operator}`" do
 | |
|         expect_offense(<<~RUBY, operator:)
 | |
|           a #{operator} if b.present?
 | |
|             _{operator} ^^^^^^^^^^^^^ Use `(b.presence || c)` instead of `if b.present? ... end`.
 | |
|             b
 | |
|           else
 | |
|             c
 | |
|           end
 | |
|         RUBY
 | |
| 
 | |
|         expect_correction(<<~RUBY)
 | |
|           a #{operator} (b.presence || c)
 | |
|         RUBY
 | |
|       end
 | |
|     end
 | |
|   end
 | |
| 
 | |
|   it "does not register an offense when using `#presence`" do
 | |
|     expect_no_offenses(<<~RUBY)
 | |
|       a.presence
 | |
|     RUBY
 | |
|   end
 | |
| 
 | |
|   it "does not register an offense when the expression does not return the receiver of `#present?`" do
 | |
|     expect_no_offenses(<<~RUBY)
 | |
|       a.present? ? b : nil
 | |
|     RUBY
 | |
| 
 | |
|     expect_no_offenses(<<~RUBY)
 | |
|       puts foo if present?
 | |
|       puts foo if !present?
 | |
|     RUBY
 | |
|   end
 | |
| 
 | |
|   it "does not register an offense when the expression does not return the receiver of `#blank?`" do
 | |
|     expect_no_offenses(<<~RUBY)
 | |
|       a.blank? ? nil : b
 | |
|     RUBY
 | |
| 
 | |
|     expect_no_offenses(<<~RUBY)
 | |
|       puts foo if blank?
 | |
|       puts foo if !blank?
 | |
|     RUBY
 | |
|   end
 | |
| 
 | |
|   it "does not register an offense when if or unless modifier is used" do
 | |
|     [
 | |
|       "a if a.blank?",
 | |
|       "a unless a.present?",
 | |
|     ].each { |source| expect_no_offenses(source) }
 | |
|   end
 | |
| 
 | |
|   it "does not register an offense when the else block is multiline" do
 | |
|     expect_no_offenses(<<~RUBY)
 | |
|       if a.present?
 | |
|         a
 | |
|       else
 | |
|         something
 | |
|         something
 | |
|         something
 | |
|       end
 | |
|     RUBY
 | |
|   end
 | |
| 
 | |
|   it "does not register an offense when the else block has multiple statements" do
 | |
|     expect_no_offenses(<<~RUBY)
 | |
|       if a.present?
 | |
|         a
 | |
|       else
 | |
|         something; something; something
 | |
|       end
 | |
|     RUBY
 | |
|   end
 | |
| 
 | |
|   it "does not register an offense when including the elsif block" do
 | |
|     expect_no_offenses(<<~RUBY)
 | |
|       if a.present?
 | |
|         a
 | |
|       elsif b
 | |
|         b
 | |
|       end
 | |
|     RUBY
 | |
|   end
 | |
| 
 | |
|   it "does not register an offense when the else block has `if` node" do
 | |
|     expect_no_offenses(<<~RUBY)
 | |
|       if a.present?
 | |
|         a
 | |
|       else
 | |
|         b if c
 | |
|       end
 | |
|     RUBY
 | |
|   end
 | |
| 
 | |
|   it "does not register an offense when the else block has `rescue` node" do
 | |
|     expect_no_offenses(<<~RUBY)
 | |
|       if something_method.present?
 | |
|         something_method
 | |
|       else
 | |
|         invalid_method rescue StandardError
 | |
|       end
 | |
|     RUBY
 | |
|   end
 | |
| 
 | |
|   it "does not register an offense when the else block has `while` node" do
 | |
|     expect_no_offenses(<<~RUBY)
 | |
|       if a.present?
 | |
|         a
 | |
|       else
 | |
|         fetch_state while waiting?
 | |
|       end
 | |
|     RUBY
 | |
|   end
 | |
| 
 | |
|   it "does not register an offense when using #present? with elsif block" do
 | |
|     expect_no_offenses(<<~RUBY)
 | |
|       if something?
 | |
|         a
 | |
|       elsif b.present?
 | |
|         b
 | |
|       end
 | |
|     RUBY
 | |
|   end
 | |
| end
 | 
