class FlakeySpecCatcher::ChangeCapsule

ChangeCapsule class

Summarizes a git change for a single file.

A ChangeCapsule object will represent the changes made to a block of code. It accomplishes this using ChangeContext and ChangeSummary objects.

Constants

SCOPE_SPECIFIERS
SHARED_EXAMPLES

Attributes

change_contexts[R]
change_summary[R]
file_name[R]

Public Class Methods

new(file_name, change_summary, change_contexts = []) click to toggle source
# File lib/flakey_spec_catcher/change_capsule.rb, line 15
def initialize(file_name, change_summary, change_contexts = [])
  @file_name = file_name
  @change_summary = change_summary
  @change_contexts = []
  handle_initial_change_contexts(change_contexts)
end

Public Instance Methods

changed_examples() click to toggle source
# File lib/flakey_spec_catcher/change_capsule.rb, line 22
def changed_examples
  @change_contexts.map(&:rerun_info)
end
fill_contexts() click to toggle source
# File lib/flakey_spec_catcher/change_capsule.rb, line 26
def fill_contexts
  change_context_stack = []
  ignore_scope_closure = 0
  lines_in_file = File.read(@file_name).split("\n")
  lines_in_file.each_with_index do |line, index|
    # Check if line matches an rspec example or examplegroup format
    if line =~ spec_scope
      handle_change_context(line, index, change_context_stack)
    # Else, ignore other blocks that might pollute context stack
    elsif line_matches_method_or_block(line)
      ignore_scope_closure += 1
    end

    fill_context(line, index, change_context_stack)

    # Note - some things use do-like loops and we need to be able to ignore those
    if line =~ pop_scope
      if ignore_scope_closure.positive?
        ignore_scope_closure -= 1
      else
        change_context_stack.pop
      end
    end
  end
end

Private Instance Methods

add_change_context(context) click to toggle source
# File lib/flakey_spec_catcher/change_capsule.rb, line 60
def add_change_context(context)
  if context.nil?
    change_context = FlakeySpecCatcher::ChangeContext.new(description: nil,
                                                          line_number: nil,
                                                          file_name: @file_name)
    @change_contexts.push(change_context)
  else
    @change_contexts.push(context) unless @change_contexts.any? { |c| c == context }
  end
end
fill_context(line, index, change_context_stack) click to toggle source
# File lib/flakey_spec_catcher/change_capsule.rb, line 88
def fill_context(line, index, change_context_stack)
  return unless line_is_inside_a_block_of_changed_code?(index)
  return if line_is_a_comment_or_whitespace?(line)

  add_change_context(change_context_stack[-1])
end
handle_change_context(line, line_number, change_context_stack) click to toggle source
# File lib/flakey_spec_catcher/change_capsule.rb, line 107
def handle_change_context(line, line_number, change_context_stack)
  change_context = FlakeySpecCatcher::ChangeContext.new(
    description: line, line_number: (line_number + 1),
    file_name: @file_name, ancestor_contexts: change_context_stack.dup
  )

  change_context_stack.push(change_context) unless
    change_context_stack.any? { |c| c == change_context }
end
handle_initial_change_contexts(change_contexts) click to toggle source
# File lib/flakey_spec_catcher/change_capsule.rb, line 54
def handle_initial_change_contexts(change_contexts)
  change_contexts.each do |context|
    add_change_context(context)
  end
end
line_is_a_comment_or_whitespace?(line) click to toggle source
# File lib/flakey_spec_catcher/change_capsule.rb, line 103
def line_is_a_comment_or_whitespace?(line)
  line =~ /^((\s*)?|(\s*#.*))$/
end
line_is_inside_a_block_of_changed_code?(index) click to toggle source
# File lib/flakey_spec_catcher/change_capsule.rb, line 95
def line_is_inside_a_block_of_changed_code?(index)
  changed_line_start = @change_summary.working_commit_line_number
  changed_line_count = @change_summary.working_commit_lines_altered
  changed_line_end = changed_line_start + changed_line_count
  changed_line_start == (index + 1) ||
    (changed_line_start...changed_line_end).cover?(index + 1)
end
line_matches_method_or_block(line) click to toggle source
# File lib/flakey_spec_catcher/change_capsule.rb, line 78
def line_matches_method_or_block(line)
  return true if line =~ /\s*do(\s+|$)/ || line =~ /^\s*def\s+/ || line =~ /^\s*if\s+/

  false
end
pop_scope() click to toggle source
# File lib/flakey_spec_catcher/change_capsule.rb, line 84
def pop_scope
  /\s+end(\s+|$)/
end
spec_scope() click to toggle source
# File lib/flakey_spec_catcher/change_capsule.rb, line 71
def spec_scope
  # Not sure if we need to check for description in quotes
  # spec_scope = /^\s*(#{SCOPE_SPECIFIERS.join("|")})\s*('.*'|".*").*do\s*$/

  /\s*(#{SCOPE_SPECIFIERS.join("|")}).*\s+do.*$/
end