Module: RuboCop::SortedMethodsByCall::Compare

Defined in:
lib/rubocop/sorted_methods_by_call/compare.rb

Overview

RuboCop::SortedMethodsByCall::Compare provides helpers to compare definition orders and call orders using “ordered subsequence” semantics. It’s used by the cop to check that called methods appear in the same relative order as they are defined (not necessarily contiguously).

Class Method Summary collapse

Class Method Details

.hashes_ordered_equal?(actual, expected) ⇒ Bool

RuboCop::SortedMethodsByCall::Compare.hashes_ordered_equal?(actual, expected) -> Bool

For each scope key, checks that every call in expected[k] exists in actual[k] and appears in the same relative order (i.e., expected[k] is a subsequence of actual[k]). Returns false if a call is unknown (not present in actual[k]) or out of order.

Examples:

defs  = { main: %i[abc foo bar a hello] }
calls = { main: %i[foo bar hello] }
RuboCop::SortedMethodsByCall::Compare.hashes_ordered_equal?(defs, calls) #=> true

calls2 = { main: %i[bar foo] }
RuboCop::SortedMethodsByCall::Compare.hashes_ordered_equal?(defs, calls2) #=> false

Parameters:

  • actual (Hash{Object=>Array<Symbol>})

    Actual definitions per scope.

  • expected (Hash{Object=>Array<Symbol>})

    Expected calls per scope.

Returns:

  • (Bool)

    true if for every scope k, expected[k] is a subsequence of actual[k] and contains no unknown methods.



29
30
31
32
33
34
35
36
37
# File 'lib/rubocop/sorted_methods_by_call/compare.rb', line 29

def hashes_ordered_equal?(actual, expected)
  return false unless actual.is_a?(Hash) && expected.is_a?(Hash)

  (actual.keys | expected.keys).all? do |k|
    defs = Array(actual[k])
    calls = Array(expected[k])
    (calls - defs).empty? && subsequence?(defs, calls)
  end
end

.subsequence?(arr, sub) ⇒ Bool

RuboCop::SortedMethodsByCall::Compare.subsequence?(arr, sub) -> Bool

Returns true if sub is a subsequence of arr (order preserved), not necessarily contiguous. An empty sub returns true.

Examples:

arr = %i[abc foo bar a hello]
RuboCop::SortedMethodsByCall::Compare.subsequence?(arr, %i[foo bar hello]) #=> true
RuboCop::SortedMethodsByCall::Compare.subsequence?(arr, %i[bar foo])       #=> false

Parameters:

  • arr (Array<#==>)

    Base sequence (typically Array<Symbol>).

  • sub (Array<#==>, nil)

    Candidate subsequence (typically Array<Symbol>).

Returns:

  • (Bool)

    true if sub appears in arr in order.



52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/rubocop/sorted_methods_by_call/compare.rb', line 52

def subsequence?(arr, sub)
  return true if sub.nil? || sub.empty?

  i = 0
  sub.each do |el|
    found = false
    while i < arr.length
      if arr[i] == el
        found = true
        i += 1
        break
      end
      i += 1
    end
    return false unless found
  end
  true
end