Module: Kennel::OptionalValidations

Included in:
Models::Record
Defined in:
lib/kennel/optional_validations.rb

Defined Under Namespace

Classes: ValidationMessage

Constant Summary collapse

UNIGNORABLE =
:unignorable
UNUSED_IGNORES =
:unused_ignores

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.filter_validation_errors(part) ⇒ Object



54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/kennel/optional_validations.rb', line 54

def self.filter_validation_errors(part)
  errors = part.validation_errors
  ignored_tags = part.ignored_errors

  if errors.empty? # 95% case, so keep it fast
    if ignored_tags.empty? || ignored_tags.include?(UNUSED_IGNORES)
      []
    else
      # tell users to remove the whole line and not just an element
      [
        ValidationMessage.new(
          UNUSED_IGNORES,
          "`ignored_errors` is non-empty, but there are no errors to ignore. Remove `ignored_errors`"
        )
      ]
    end
  else
    reported_errors =
      if ENV["NO_IGNORED_ERRORS"] # let users see what errors are suppressed
        errors
      else
        errors.select { |err| err.tag == UNIGNORABLE || !ignored_tags.include?(err.tag) }
      end

    # let users know when they can remove an ignore ... unless they don't care (for example for a generic monitor)
    unless ignored_tags.include?(UNUSED_IGNORES)
      unused_ignored_tags = ignored_tags - errors.map(&:tag)
      if unused_ignored_tags.any?
        reported_errors << ValidationMessage.new(
          UNUSED_IGNORES,
          "Unused ignores #{unused_ignored_tags.map(&:inspect).sort.uniq.join(" ")}. Remove these from `ignored_errors`"
        )
      end
    end

    reported_errors
  end
end

.included(base) ⇒ Object



9
10
11
12
13
# File 'lib/kennel/optional_validations.rb', line 9

def self.included(base)
  base.settings :ignored_errors
  base.defaults(ignored_errors: -> { [] })
  base.attr_reader :validation_errors
end

.valid?(parts) ⇒ Boolean

Returns:

  • (Boolean)


24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/kennel/optional_validations.rb', line 24

def self.valid?(parts)
  parts_with_errors = parts.map { |p| [p, filter_validation_errors(p)] }
  return true if parts_with_errors.all? { |_, errors| errors.empty? }

  # print errors in order
  example_tag = nil
  Kennel.err.puts
  parts_with_errors.sort_by! { |p, _| p.safe_tracking_id }
  parts_with_errors.each do |part, errors|
    errors.each do |err|
      Kennel.err.puts "#{part.safe_tracking_id} [#{err.tag.inspect}] #{err.text.gsub("\n", " ")}"
      example_tag = err.tag unless err.tag == :unignorable
    end
  end
  Kennel.err.puts

  if example_tag
    Kennel.err.puts <<~MESSAGE
      If a particular error cannot be fixed, it can be marked as ignored via `ignored_errors`, e.g.:
        Kennel::Models::Monitor.new(
          ...,
          ignored_errors: [#{example_tag.inspect}]
        )

    MESSAGE
  end

  false
end

Instance Method Details

#initializeObject



15
16
17
18
# File 'lib/kennel/optional_validations.rb', line 15

def initialize(...)
  super
  @validation_errors = []
end

#invalid!(tag, message) ⇒ Object



20
21
22
# File 'lib/kennel/optional_validations.rb', line 20

def invalid!(tag, message)
  validation_errors << ValidationMessage.new(tag, message)
end