Class: Rematch

Inherits:
Object
  • Object
show all
Defined in:
lib/rematch.rb,
lib/rematch/store.rb,
lib/rematch/source.rb

Overview

Handles the key/value store for each test file

Defined Under Namespace

Classes: Source, Store

Constant Summary collapse

VERSION =
'5.0.2'
CONFIG =

rubocop:disable Style/MutableConstant

{ ext: '.yaml' }

Class Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(test) ⇒ Rematch

Returns a new instance of Rematch.



46
47
48
49
50
# File 'lib/rematch.rb', line 46

def initialize(test)
  @path   = test.method(test.name).source_location.first
  @env    = self.class.environment(@path)
  @counts = Hash.new(0) # Track rematch counts per line
end

Class Attribute Details

.cacheObject

Returns the value of attribute cache.



19
20
21
# File 'lib/rematch.rb', line 19

def cache
  @cache
end

.rebuildObject

Returns the value of attribute rebuild.



19
20
21
# File 'lib/rematch.rb', line 19

def rebuild
  @rebuild
end

.skip_warningObject

Returns the value of attribute skip_warning.



19
20
21
# File 'lib/rematch.rb', line 19

def skip_warning
  @skip_warning
end

Class Method Details

.check_rebuild(path) ⇒ Object



21
22
23
24
25
26
27
# File 'lib/rematch.rb', line 21

def check_rebuild(path)
  return unless @rebuild && !@rebuilt.include?(path)

  FileUtils.rm_f(path)
  @rebuilt << path
  puts "Rebuilt #{path}"
end

.environment(path) ⇒ Object

Get source and store for the test file (cached because invoked for every test in the file)



33
34
35
36
37
38
39
40
41
42
43
# File 'lib/rematch.rb', line 33

def environment(path)
  return cache[path] if cache[path]

  store_path = "#{path}#{CONFIG[:ext]}"
  check_rebuild(store_path)

  source      = Source.new(File.read(path))
  source_ids  = source.index.values.flatten.to_set
  store       = Store.new(store_path, source_ids)
  cache[path] = { source: source, store: store }
end

.extract_label(args) ⇒ Object

Utility used by the plugin to extract label from args (kept for compatibility)



30
# File 'lib/rematch.rb', line 30

def extract_label(args) = ((args.last.is_a?(Hash) && args.last.key?(:label) && args.pop) || {})[:label]

Instance Method Details

#rematch(value, overwrite: nil, label: nil) ⇒ Object

Retrieves the stored value for the current assertion, updating the store if the key is new or moved.



53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/rematch.rb', line 53

def rematch(value, overwrite: nil, label: nil)
  lineno = caller_locations.find { |l| l.path == @path }&.lineno
  ids    = @env[:source].index[lineno]
  raise "Rematch Error: No code detected at #{@path}:#{lineno}. Please check syntax." if ids.empty? # never happen

  count   = (@counts[lineno] += 1)
  id      = ids[(count - 1) % ids.size]
  new_key = %(L#{lineno}#{".#{count}" if count > 1}#{" [#{label}]" if label} #{id})
  store   = @env[:store]
  old_key = store.pull(id)
  if old_key && old_key != new_key  # Reconcile Move first to ensure clean state
    store[new_key] = store.delete(old_key)
    old_key        = new_key   # Normalize so we only check the verwrite logic below
  end
  case
  when !old_key
    warn "Rematch stored new value generated by: #{@path}:#{lineno}\n" unless overwrite || self.class.skip_warning
    store[new_key] = value
  when overwrite
    store[new_key] = value
  else
    store[new_key]
  end
end

#saveObject



78
# File 'lib/rematch.rb', line 78

def save = @env[:store].save