C0 code coverage information

Generated on Tue Oct 16 11:40:47 -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/alexandria/book_providers.rb 325 258
40.0% 
29.5% 
  1 # Copyright (C) 2004-2006 Laurent Sansonetti
  2 #
  3 # Alexandria is free software; you can redistribute it and/or
  4 # modify it under the terms of the GNU General Public License as
  5 # published by the Free Software Foundation; either version 2 of the
  6 # License, or (at your option) any later version.
  7 #
  8 # Alexandria is distributed in the hope that it will be useful,
  9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 11 # General Public License for more details.
 12 #
 13 # You should have received a copy of the GNU General Public
 14 # License along with Alexandria; see the file COPYING.  If not,
 15 # write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 16 # Boston, MA 02111-1307, USA.
 17 
 18 require 'singleton'
 19 
 20 module Alexandria
 21   class BookProviders < Array
 22     include Singleton
 23     include GetText
 24     GetText.bindtextdomain(Alexandria::TEXTDOMAIN, nil, nil, "UTF-8")
 25 
 26     SEARCH_BY_ISBN, SEARCH_BY_TITLE, SEARCH_BY_AUTHORS,
 27       SEARCH_BY_KEYWORD = (0..3).to_a
 28 
 29     class SearchError < StandardError; end
 30     class NoResultsError < SearchError; end
 31     class TooManyResultsError < SearchError; end
 32     class InvalidSearchTypeError < SearchError; end
 33 
 34     def self.search(criterion, type)
 35       factory_n = 0
 36       begin
 37         factory = self.instance[factory_n]
 38         puts factory.fullname + " lookup" if $DEBUG
 39         results = factory.search(criterion, type)
 40 
 41         if results.length == 0
 42           raise NoResultsError
 43         else
 44           puts "found at " + factory.fullname
 45           return results
 46         end
 47       rescue Exception => boom
 48         if self.last == factory
 49           puts "Error while searching #{criterion}"
 50           raise case boom
 51         when Timeout::Error
 52           _("Couldn't reach the provider '%s': timeout " +
 53                               "expired.") % factory.name
 54 
 55         when SocketError
 56           _("Couldn't reach the provider '%s': socket " +
 57                               "error (%s).") % [factory.name, boom.message]
 58 
 59         when NoResultsError
 60           _("No results were found.  Make sure your " +
 61                               "search criterion is spelled correctly, and " +
 62                               "try again.")
 63 
 64         when TooManyResultsError
 65           _("Too many results for that search.")
 66 
 67         when InvalidSearchTypeError
 68           _("Invalid search type.")
 69 
 70         else
 71           boom.message
 72         end
 73       else
 74         factory_n += 1
 75         retry
 76       end
 77     end
 78   end
 79 
 80   def self.isbn_search(criterion)
 81     self.search(criterion, SEARCH_BY_ISBN)
 82   end
 83 
 84   class Preferences < Array
 85     def initialize(provider)
 86       @provider = provider
 87     end
 88 
 89     class Variable
 90       attr_reader :provider_name, :name, :description,
 91         :possible_values
 92       attr_accessor :value
 93 
 94       def initialize(provider, name, description, default_value,
 95                      possible_values=nil, mandatory=true)
 96 
 97         @provider = provider
 98         @name = name
 99         @description = description
100         @value = default_value
101         @possible_values = possible_values
102         @mandatory = mandatory
103       end
104 
105       def default_value=(new_value)
106         self.value = new_value
107       end
108 
109       def new_value=(new_value)
110         message = @provider.variable_name(self) + '='
111         Alexandria::Preferences.instance.send(message,
112                                               new_value)
113                                               self.value = new_value
114       end
115 
116       def provider_name
117         @provider.name.downcase
118       end
119 
120       def mandatory?
121         @mandatory
122       end
123     end
124 
125     def add(*args)
126       self << Variable.new(@provider, *args)
127     end
128 
129     def [](obj)
130       case obj
131       when String
132         var = variable_named(obj)
133         var ? var.value : nil
134       when Integer
135         super(obj)
136       end
137     end
138 
139     def variable_named(name)
140       self.find { |var| var.name == name }
141     end
142 
143     def read
144       self.each do |var|
145         message = @provider.variable_name(var)
146         val = Alexandria::Preferences.instance.send(message)
147         var.value = val unless (val.nil? or (val == "" and var.mandatory?))
148       end
149     end
150   end
151 
152   class AbstractProvider
153     attr_reader :prefs
154     attr_accessor :name, :fullname
155 
156     def initialize(name, fullname=nil)
157       @name = name
158       @fullname = (fullname or name)
159       @prefs = Preferences.new(self)
160     end
161 
162     def reinitialize(fullname)
163       @name << '_' << fullname.hash.to_s
164       @fullname = fullname
165       prefs = Alexandria::Preferences.instance
166       ary = prefs.abstract_providers
167       ary ||= []
168       ary << @name
169       prefs.abstract_providers = ary
170       message = variable_name('name') + '=' 
171       prefs.send(message, @fullname)
172     end
173 
174     def remove
175       prefs = Alexandria::Preferences.instance
176       if ary = prefs.abstract_providers
177         ary.delete(@name)
178         prefs.abstract_providers = ary
179       end
180       if ary = prefs.providers_priority and ary.include?(@name)
181         ary.delete(@name)
182         prefs.providers_priority = ary
183       end
184       self.prefs.each do |variable|
185         name = variable_name(variable)
186         prefs.remove_preference(name)
187       end
188       name = variable_name('name')
189       prefs.remove_preference(name)
190     end
191 
192     def variable_name(object)
193       s = case object
194           when String
195             object
196           when Preferences::Variable
197             object.name
198           else
199             raise
200           end
201       @name.downcase + '_' + s
202     end
203 
204     def transport
205       config = Alexandria::Preferences.instance.http_proxy_config
206       config ? Net::HTTP.Proxy(*config) : Net::HTTP
207     end
208 
209     def abstract?
210       self.class.abstract?
211     end
212 
213     def self.abstract?
214       (not self.included_modules.include?(Singleton))
215     end
216 
217     def <=>(provider)
218       self.fullname <=> provider.fullname
219     end
220 
221     def self.unabstract
222       include Singleton
223       undef_method :reinitialize
224       undef_method :name=
225         undef_method :fullname=
226         undef_method :remove
227     end
228   end
229 
230   class GenericProvider < AbstractProvider
231     unabstract
232   end
233 
234   require 'alexandria/book_providers/bn'
235   require 'alexandria/book_providers/proxis'
236   require 'alexandria/book_providers/mcu'
237   require 'alexandria/book_providers/thalia'
238   require 'alexandria/book_providers/ibs_it'
239   require 'alexandria/book_providers/renaud'
240   require 'alexandria/book_providers/adlibris'
241   require 'alexandria/book_providers/ls'
242   require 'alexandria/book_providers/bol_it'
243   require 'alexandria/book_providers/webster_it'
244   require 'alexandria/book_providers/worldcat'
245 
246   begin
247     require 'alexandria/book_providers/amazon'
248   rescue LoadError
249     puts "Can't load Ruby/Amazon, hence provider Amazon not available"
250   end
251 
252   # mechanize is optional
253   begin
254     require 'alexandria/book_providers/dea_store_it'
255   rescue LoadError
256     puts "Can't load mechanize, hence provider Deastore not available"
257   end
258 
259   # Ruby/ZOOM is optional
260   begin
261     require 'alexandria/book_providers/z3950'
262   rescue LoadError
263     puts "Can't load Ruby/ZOOM, hence Z39.50 and providers Library of Congress, British Library not available"
264   end
265 
266   attr_reader :abstract_classes
267 
268   def initialize
269     @prefs = Alexandria::Preferences.instance
270     @abstract_classes = []
271     update_priority
272   end
273 
274   def update_priority
275 
276     # This is weird code that sorts through the list of classes brought
277     # in by requires and sorts through whether they are 'Abstract' or not,
278     # adding their names to @prefs.
279 
280     @abstract_classes.clear
281     providers = {}
282     self.class.constants.each do |constant|
283       next unless md = /(.+)Provider$/.match(constant)
284       klass = self.class.module_eval(constant)
285       if klass.ancestors.include?(AbstractProvider) and
286         klass != GenericProvider and
287         klass != AbstractProvider
288 
289         if klass.abstract?
290           @abstract_classes << klass
291         else
292           providers[md[1]] = klass.instance
293         end
294       end
295     end
296     if ary = @prefs.abstract_providers
297       ary.each do |name|
298         md = /^(.+)_/.match(name)
299         next unless md
300         klass_name = md[1] + 'Provider'
301         klass = @abstract_classes.find { |x| x.name.include?(klass_name) }
302         next unless klass
303         fullname = @prefs.send(name.downcase + '_name')
304         next unless fullname
305         instance = klass.new
306         instance.name = name
307         instance.fullname = fullname
308         instance.prefs.read
309         providers[name] = instance
310       end
311     end
312     self.clear
313     priority = (@prefs.providers_priority or [])
314     priority.map! { |x| x.strip }
315     rest = providers.keys - priority
316     priority.each { |pname| self << providers[pname] }
317     rest.sort.each { |pname| self << providers[pname] }
318     self.compact!
319   end
320 
321   def self.method_missing(id, *args, &block)
322     self.instance.method(id).call(*args, &block)
323   end
324 end
325 end

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

Valid XHTML 1.0! Valid CSS!