cryptcheck/lib/cryptcheck/state.rb

162 lines
3.4 KiB
Ruby
Raw Blame History

This file contains invisible Unicode characters!

This file contains invisible Unicode characters that may be processed differently from what appears below. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to reveal hidden characters.

module CryptCheck
module State
def states
# Remove duplicated test for each level
@states ||= State.empty.merge(self.checks.group_by { |c| c[1] }.collect do |level, checks|
states = checks.group_by(&:first).collect do |name, checks|
states = checks.collect &:last
# true > false > nil
state = if states.include? true
true
elsif states.include? false
false
else
nil
end
[name, state]
end.to_h
[level, states]
end.to_h)
end
def status
@status ||= State.status self.checks.select { |c| c.last == true }.collect { |c| c[1] }
end
BADS = %i(critical error warning).freeze
GOODS = %i(good great best).freeze
LEVELS = (BADS + GOODS).freeze
def self.good?(level)
GOODS.include? level
end
def self.bad?(level)
BADS.include? level
end
def self.good_or_bad(level)
if self.good?(level)
:good
else
:bad
end
end
def self.state(states, level)
state =states[level].values.uniq
case State.good_or_bad(level)
when :bad
if state.include? true
true
else
false
end
when :good
if state.include? false
if state.include? true
:some
else
false
end
else
:all
end
end
end
extend Enumerable
def self.each(&block)
LEVELS.each &block
end
def self.empty
self.collect { |s| [s, {}] }.to_h
end
def self.status(states)
states = self.convert states
self.min LEVELS, states
end
class << self
alias_method :'[]', :status
end
def self.problem(states)
states = self.convert states
self.min BADS, states
end
def self.sort(states)
states.sort { |a, b| self.compare a, b }
end
def self.compare(a, b)
a = LEVELS.find_index(a.status) || (LEVELS.size - 1) / 2.0
b = LEVELS.find_index(b.status) || (LEVELS.size - 1) / 2.0
b <=> a
end
protected
def checks
@checks ||= self.available_checks.collect { |c| perform_check c }.flatten(1) + children.collect(&:checks).flatten(1)
end
private
def self.convert(status)
status = [status] unless status.respond_to? :first
first = status.first
status = status.collect &:status if first.respond_to? :status
status
end
def self.min(levels, states)
return nil if states.empty?
(levels & states).first
end
def self.max(levels, states)
return nil if states.empty?
(levels & states).last
end
def self.merge(*states)
State.collect do |s|
state = states.collect { |ss| ss.fetch s, [] }
.inject(&:+).uniq
[s, state]
end.to_h
end
def children
[]
end
def perform_check(check)
name, levels, check = check
result = check.call self
case levels
when Symbol # Expected result is true/false/nil
return [[name, levels, result]]
else # Expected result is the best/worst case
# N/A, so return all levels as N/A
return levels.collect { |l| [name, l, nil] } if result.nil?
checks = []
if BADS.include? result
checks += (GOODS & levels).collect { |l| [name, l, false] }
index = BADS.index result
checks += (BADS & levels).collect { |l| [name, l, BADS.index(l) >= index] }
else
checks += (BADS & levels).collect { |l| [name, l, false] }
index = GOODS.index result
checks += (GOODS & levels).collect { |l| [name, l, GOODS.index(l) <= index] }
end
return checks
end
end
end
end