Module: RSpec::Signal::Symptoms::Record

Defined in:
lib/rspec/signal/symptoms/record.rb

Overview

ActiveRecord shapes: a model that has no rows, a validation that keeps failing, a column or table the schema does not have.

The model, the validation sentence and the missing identifier are the cluster keys. A RecordNotFound for User and one for Order are two different problems and stay apart.

Constant Summary collapse

NOT_FOUND =
/Couldn't find (?<model>[A-Z]\w*(?:::\w+)*)/
VALIDATION =
%r{Validation failed: (?<detail>.{1,120}?)(?=\s{2,}|\s+Caused by\b|\s+Failure/Error\b|\z)}
MISSING =
/(?<what>column|relation|table)\s+["'`]?(?<name>[\w."]+?)["'`]?\s+does not exist/i
SQLITE =
/no such (?<what>column|table):\s*(?<name>[\w.]+)/i

Class Method Summary collapse

Class Method Details

.call(_failure, text) ⇒ Object



20
21
22
# File 'lib/rspec/signal/symptoms/record.rb', line 20

def call(_failure, text)
  not_found(text) || schema(text) || validation(text)
end

.not_found(text) ⇒ Object



24
25
26
27
28
29
30
31
# File 'lib/rspec/signal/symptoms/record.rb', line 24

def not_found(text)
  match = NOT_FOUND.match(text)
  return nil unless match

  model = match[:model]
  Symptom.new(kind: :record_not_found, key: "record-not-found:#{model}",
              label: "missing `#{model}` records", detail: "no #{model} found")
end

.schema(text) ⇒ Object



33
34
35
36
37
38
39
40
41
# File 'lib/rspec/signal/symptoms/record.rb', line 33

def schema(text)
  match = MISSING.match(text) || SQLITE.match(text)
  return nil unless match

  what = match[:what].downcase
  name = match[:name].delete('"')
  Symptom.new(kind: :schema, key: "schema:#{what}:#{name}",
              label: "missing database #{what} `#{name}`", detail: "#{what} #{name} does not exist")
end

.validation(text) ⇒ Object



43
44
45
46
47
48
49
50
51
52
# File 'lib/rspec/signal/symptoms/record.rb', line 43

def validation(text)
  match = VALIDATION.match(text)
  return nil unless match

  detail = match[:detail].strip.sub(/[.,]\z/, "")
  return nil if detail.empty?

  Symptom.new(kind: :validation, key: "validation:#{detail.downcase}",
              label: "validation failure `#{detail}`", detail: detail)
end