C0 code coverage information

Generated on Mon May 21 22:36:02 -0400 2007 with rcov 0.8.0


Code reported as executed by Ruby looks like this...
and this: this line is also marked as covered.
Lines considered as run by rcov, but not reported by Ruby, look like this,
and this: these lines were inferred by rcov (using simple heuristics).
Finally, here's a line marked as not executed.
Name Total lines Lines of code Total coverage Code coverage
lib/rools/rule.rb 142 81
85.2% 
77.8% 
  1 require 'rools/errors'
  2 require 'rools/default_parameter_proc'
  3 require 'rools/base'
  4 
  5 module Rools
  6   class Rule < Base
  7     attr_reader :name, :priority, :rule_set
  8     attr_reader :parameters, :conditions, :consequences
  9    
 10     
 11     # A Rule requires a Rools::RuleSet, a name, and an associated block
 12     # which will be executed at initialization
 13     def initialize(rule_set, name, priority, b)
 14       @rule_set     = rule_set
 15       @name         = name
 16       @priority     = priority
 17       @conditions   = []
 18       @consequences = []
 19       @parameters   = []
 20       
 21       begin
 22         instance_eval(&b) if b
 23       rescue Exception => e
 24         raise RuleCheckError.new( self, e)
 25       end
 26     end
 27     
 28     # Adds a condition to the Rule.
 29     # For readability, it might be preferrable to use a
 30     # new condition for every evaluation when possible.
 31     # ==Example
 32     #   condition { person.name == 'Fred' }
 33     #   condition { person.age > 18 }
 34     # As opposed to:
 35     #   condition { person.name == 'Fred' && person.age > 18 }
 36     def condition(&b)
 37       @conditions << DefaultParameterProc.new(self, b)
 38     end
 39     
 40     # Adds a consequence to the Rule
 41     # ==Example
 42     #   consequence { user.failed_logins += 1; user.save! }
 43     def consequence(&b)
 44       @consequences << DefaultParameterProc.new(self, b)
 45     end
 46     
 47     # Sets the parameters of the Rule
 48     # ==Example
 49     #   parameters Person, :name, :occupation
 50     # The arguments passed are evaluated with :is_a? for each
 51     # constant-name passed, and :responds_to? for each symbol.
 52     # So the above example would be the same as:
 53     #   obj.is_a?(Person) &&
 54     #     obj.responds_to?(:name) &&
 55     #     obj.responds_to?(:occupation)
 56     # You can pass any combination of symbols or constants.
 57     # You might want to refrain from referencing constants to
 58     # aid in "duck-typing", or you might want to use parameters such as:
 59     #   parameters Person, Employee, :department
 60     # To verify that the asserted object is an Employee, that inherits from
 61     # Person, and responds to :department
 62     def parameters(*matches)
 63       logger.debug( "Adding parameters: #{matches}") if logger
 64       @parameters += matches
 65     end
 66     
 67     # parameters is aliased to aid in readability if you decide
 68     # to pass only one parameter.
 69     alias :parameter :parameters
 70     
 71     # Checks to see if this Rule's parameters match the asserted object
 72     def parameters_match?(obj)
 73       @parameters.each do |p|
 74         logger.debug( "#{self} match p:#{p} obj:#{obj} sym:#{Symbol}") if logger
 75         if p.is_a?(Symbol)
 76           #return false unless obj.respond_to?(p)
 77           return true if obj.respond_to?(p)
 78         else
 79           logger.debug( "#{self} is_a p:#{p} obj:#{obj} #{obj.is_a?(p)}") if logger
 80           #return false unless obj.is_a?(p)
 81           return true if obj.is_a?(p)
 82         end
 83       end
 84       
 85       # if parameters are not specified, let's assume that the rule is always relevant
 86       if @parameters.size == 0
 87         logger.debug "no parameters defined for rule: #{self}" if logger
 88         return true
 89       end
 90       
 91       logger.debug( "no parameter match") if logger
 92       return false
 93     end
 94     
 95     # Checks to see if this Rule's conditions match the asserted object
 96     # Any StandardErrors are caught and wrapped in RuleCheckErrors, then raised.
 97     def conditions_match?(obj)
 98       begin
 99         @conditions.each { |c| return false unless c.call(obj) }
100       rescue StandardError => e
101         logger.error( "rule StandardError #{e} #{e.backtrace.join("\n")}") if logger
102         raise RuleCheckError.new(self, e)
103       end
104       
105       return true
106     end
107     
108     # Calls Rools::RuleSet#assert in the bound working-set
109     def assert(obj)
110       @rule_set.assert(obj)
111     end
112     
113     # Execute each consequence.
114     # Any StandardErrors are caught and wrapped in Rools::RuleConsequenceError,
115     # then raised to break out of the current assertion.
116     def call(obj)
117       begin
118         @consequences.each do |c|
119           c.call(obj)
120         end
121       rescue StandardError => e
122         # discontinue the Rools::RuleSet#assert if any consequence fails
123         logger.error( "rule RuleConsequenceError #{e.to_s} #{e.backtrace.join("\n")}") if logger
124         raise RuleConsequenceError.new(rule, e)
125       end
126     end
127     
128     # Stops the current assertion. Does not indicate failure.
129     def stop(message = nil)
130       @rule_set.stop(message)
131     end
132     
133     # Stops the current assertion and change status to :fail
134     def fail(message = nil)
135       @rule_set.fail(message)
136     end
137     
138     def to_s
139       @name
140     end
141   end
142 end

Generated using the rcov code coverage analysis tool for Ruby version 0.8.0.

Valid XHTML 1.0! Valid CSS!