C0 code coverage information

Generated on Sun Oct 26 11:17:55 -0500 2008 with rcov 0.8.1.2


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/aquarium/utils/options_utils.rb 258 153
100.0% 
100.0% 
  1 require 'logger'
  2 require 'aquarium/utils/default_logger'
  3 
  4 module Aquarium
  5   module Utils
  6 
  7     # == OptionsUtils
  8     # Support parsing and processing of key-value pairs of options, where the values are always converted
  9     # to Sets.
 10     # Types including this module should have their <tt>initialize</tt> methods call this module's
 11     # #init_specification to do the options processing. See its documentation for more details.
 12     #
 13     # Several <i>class</i> methods are included for defining convenience <i>instance</i> methods.
 14     # For example, for options <tt>:foo</tt> and <tt>:bar</tt>, calling:
 15     #
 16     #   canonical_options_given_methods :foo, :bar
 17     #
 18     # will define several methods for each option specified, e.g.,:
 19     #
 20     #   foo_given    # => returns the value of @specification[:foo]
 21     #   foo_given?   # => returns true "foo_given" is not nil or empty.
 22     #   bar_given    # etc...
 23     #   bar_given?
 24     #
 25     # If you would like corresponding reader and writer methods, pass a list of the keys for which you want these
 26     # methods defined to one of the following methods:
 27     #
 28     #   canonical_option_reader   :foo, :bar   # analogous to attr_reader
 29     #   canonical_option_writer   :foo, :bar   # analogous to attr_writer
 30     #   canonical_option_accessor :foo, :bar   # analogous to attr_accessor
 31     #
 32     # For all of these methods, you can also pass <tt>CANONICAL_OPTIONS</tt> (discussed below) to define methods
 33     # for all of the "canonical" options, <i>e.g.,</i>
 34     #
 35     #   canonical_option_accessor CANONICAL_OPTIONS
 36     #
 37     # These methods are not defined by default to prevent accidentally overriding other methods that you might
 38     # have defined with the same names. Also, note that the writer methods will convert the inputs to sets,
 39     # following the conventions for the options and the readers will return the sets. If you want different handling,
 40     # you'll have to provide custom implementations. 
 41     #
 42     # Note that special-case accessor methods are already defined for the <tt>:noop</tt> and <tt>:logger</tt>
 43     # options (discussed below) where the writers expect single values, not sets, and the
 44     # readers return the single values. (Yea, it's a bit inconsistent...)
 45     #
 46     # Finally, these <tt>canonical_option_*</tt> methods should only be called with the *keys* for the +CANONICAL_OPTIONS+.
 47     # The keys are considered the "canonical options", while the values for the keys are synonyms that can be used instead.
 48     #
 49     # This module also defines several universal options that will be available to all types that include this module:
 50     # <tt>:logger</tt>::
 51     #   A Ruby standard library Logger used for any messages. A default system-wide logger is used otherwise.
 52     #   The corresponding <tt>logger</tt> and <tt>logger=</tt> accessors are defined.
 53     #
 54     # <tt>:logger_stream</tt>::
 55     #   An an alternative to defining the logger, you can define just the output stream where log output will be written.
 56     #   If this option is specified, a new logger will be created for the instance with this output stream.
 57     #   There are no corresponding accessors; use the appropriate methods on the <tt>logger</tt> object instead.
 58     #
 59     # <tt>:severity</tt>::
 60     #   The logging severity level, one of the Logger::Severity values or a corresponding integer value.
 61     #   If this option is specified, a new logger will be created for the instance with this output stream.
 62     #   There are no corresponding accessors; use the corresponding methods on the <tt>logger</tt> object instead.
 63     #
 64     # <tt>:noop => options_hash[:noop] || false</tt>::
 65     #   If true, don't do "anything", the interpretation of which will vary with the type receiving the option.
 66     #   For example, a type might go through some initialization, such as parsng its options, but
 67     #   do nothing after that. Primarily useful for debugging and testing.    
 68     #   The value can be accessed through the <tt>noop</tt> and <tt>noop=</tt> accessors.
 69     #
 70     module OptionsUtils
 71       include SetUtils
 72       include ArrayUtils
 73       
 74       def self.universal_options
 75         [:logger_stream, :logger, :severity, :noop]
 76       end
 77       
 78       def self.universal_prepositions
 79         [:for, :on, :in, :within]
 80       end
 81 
 82       attr_reader :specification
 83 
 84       # Class #initialize methods call this method to process the input options.
 85       # Pass an optional block to the method that takes no parameters if you want 
 86       # to do additional processing of the options before init_specification validates 
 87       # the options. The block will have access to the @specification hash built up by
 88       # init_specification and to a new attribute @original_options, which will be a 
 89       # copy of the original options passed to init_specification (it will be either a 
 90       # hash or an array). 
 91       # Finally, if the block returns a value or an array of values, they will be 
 92       # treated as keys to ignore in the options when they are validated. This is a 
 93       # way of dynamically treating an option as valid that can't be known in advance.
 94       # (See Aspect and Pointcut for examples of this feature in use.)
 95       def init_specification options, canonical_options, additional_allowed_options = []
 96         @canonical_options = canonical_options
 97         @additional_allowed_options = additional_allowed_options.map{|x| x.respond_to?(:intern) ? x.intern : x}
 98         @original_options = options.nil? ? {} : options.dup 
 99         @specification = {}
100         options ||= {} 
101         options_hash = hashify options
102         @canonical_options.keys.each do |key|
103           all_related_options = make_array(options_hash[key.intern]) || []
104           @canonical_options[key].inject(all_related_options) do |ary, o| 
105             ary << options_hash[o.intern] if options_hash[o.intern]
106             ary
107           end
108           @specification[key.intern] = Set.new(all_related_options.flatten)
109         end
110         
111         OptionsUtils::universal_options.each do |uopt| 
112           @specification[uopt] = Set.new(make_array(options_hash[uopt])) unless options_hash[uopt].nil? 
113         end
114         @specification[:noop] ||= Set.new([false])
115         set_logger_if_stream_specified     
116         set_logger_severity_if_specified   
117         set_default_logger_if_not_specified 
118         
119         ignorables = yield if block_given?
120         ignorables = [] if ignorables.nil? 
121         ignorables = [ignorables] unless ignorables.kind_of? Array
122         validate_options(options_hash.reject {|k,v| ignorables.include?(k)})
123       end
124       
125       def hashify options
126         return options if options.kind_of?(Hash)
127         new_options = {}
128         options.each do |x|
129           if x.kind_of?(Hash)
130             new_options.merge!(x)
131           else
132             new_options[x] = Set.new([])
133           end
134         end
135         new_options
136       end
137       
138       def validate_options options
139         unknowns = options.keys - all_allowed_option_symbols - OptionsUtils::universal_options
140         raise Aquarium::Utils::InvalidOptions.new("Unknown options specified: #{unknowns.inspect}") if unknowns.size > 0
141       end
142   
143       [:logger, :noop].each do |name|
144         module_eval(<<-EOF, __FILE__, __LINE__)
145           def #{name}
146             @specification[:#{name}].kind_of?(Set) ? @specification[:#{name}].to_a.first : @specification[:#{name}]
147           end
148           def #{name}= value
149             @specification[:#{name}] = make_set(make_array(value))
150           end
151         EOF
152       end
153     
154       module ClassMethods
155         def canonical_option_reader *canonical_option_key_list
156           return if canonical_option_key_list.nil? or canonical_option_key_list.empty?
157           keys = determine_options_for_accessors canonical_option_key_list
158           keys.each do |name|
159             define_method(name) do 
160               @specification[name]
161             end
162           end
163         end
164         def canonical_option_writer *canonical_option_key_list
165           return if canonical_option_key_list.nil? or canonical_option_key_list.empty?
166           keys = determine_options_for_accessors canonical_option_key_list
167           keys.each do |name|
168             define_method("#{name}=") do |value|
169               @specification[name] = make_set(make_array(value))
170             end
171           end
172         end
173         def canonical_option_accessor *canonical_option_key_list
174           canonical_option_reader *canonical_option_key_list
175           canonical_option_writer *canonical_option_key_list
176         end
177       
178         def canonical_options_given_methods canonical_options
179           keys = canonical_options.respond_to?(:keys) ? canonical_options.keys : canonical_options 
180           (keys + OptionsUtils::universal_options).each do |name|
181             module_eval(<<-EOF, __FILE__, __LINE__)
182               def #{name}_given
183                 @specification[:#{name}]
184               end
185   
186               def #{name}_given?
187                 not (#{name}_given.nil? or #{name}_given.empty?)
188               end
189             EOF
190           end
191         end
192 
193         # Service method that adds a new canonical option and corresponding array with 
194         # "exclude_" prepended to all values. The new options are added to the input hash.
195         def add_exclude_options_for option, options_hash
196           all_variants = options_hash[option].dup
197           options_hash["exclude_#{option}"] = all_variants.map {|x| "exclude_#{x}"}
198         end
199 
200         # Service method that adds a new canonical option and corresponding array with 
201         # "preposition" prefixes, e.g., "on_", "for_", etc. prepended to all values. 
202         # The new options are added to the input hash.
203         def add_prepositional_option_variants_for option, options_hash
204           all_variants = options_hash[option].dup + [option]
205           OptionsUtils.universal_prepositions.each do |prefix|
206             all_variants.each do |variant|
207               options_hash[option] << "#{prefix}_#{variant}" 
208             end
209           end
210         end
211 
212         private
213         
214         def determine_options_for_accessors canonical_option_key_list
215           keys = canonical_option_key_list
216           if canonical_option_key_list.kind_of?(Array) and canonical_option_key_list.size == 1
217             keys = canonical_option_key_list[0]
218           end
219           if keys.respond_to? :keys
220             keys = keys.keys
221           end
222           keys
223         end
224       end
225       
226       def self.append_features clazz
227         super
228         ClassMethods.send :append_features, (class << clazz; self; end)
229       end
230   
231       private
232     
233       def all_allowed_option_symbols
234         @canonical_options.to_a.flatten.map {|o| o.intern} + @additional_allowed_options
235       end
236       
237       # While it's tempting to use the #logger_stream_given?, etc. methods, they will only exist if the
238       # including class called canonical_options_given_methods!
239       def set_logger_if_stream_specified 
240         return if @specification[:logger_stream].nil? or @specification[:logger_stream].empty?
241         self.logger = Logger.new @specification[:logger_stream].to_a.first
242         self.logger.level = DefaultLogger::DEFAULT_SEVERITY_LEVEL
243       end
244     
245       def set_logger_severity_if_specified 
246         return if @specification[:severity].nil? or @specification[:severity].empty?
247         if self.logger.nil?
248           self.logger = Logger.new STDERR
249         end
250         self.logger.level = @specification[:severity].to_a.first
251       end
252     
253       def set_default_logger_if_not_specified 
254         self.logger ||= DefaultLogger.logger
255       end
256     end
257   end
258 end

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

Valid XHTML 1.0! Valid CSS!