123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161 |
- 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
|