You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

161 lines
3.4 KiB

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