C0 code coverage information

Generated on Sun Jun 11 23:15:17 CEST 2006 with rcov 0.6.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/spam_protection.rb 136 105
82.4% 
79.0% 
  1 require_dependency 'blacklist_pattern'
  2 
  3 class SpamProtection
Calls
      1   Class#inherited at vendor/rails/activesupport/lib/active_support/class_inheritable_attributes.rb:108

  4 
  5   IP_RBL = [ 'opm.blitzed.us', 'bsb.empty.us' ]
  6   HOST_RBL = [ 'sc.surbl.org', 'bsb.empty.us' ]
  7   SECOND_LEVEL = [ 'co', 'com', 'net', 'org', 'gov' ]
  8 
  9   def article_closed?(record)
Calls
      1   #<Class:Object>#method_added at vendor/rails/actionpack/lib/action_view/vendor/builder/blankslate.rb:47
Called by
      8   lib/spam_protection.rb:131 in 'ActiveRecord::Validations::ClassMethods#validates_age_of'

 10     if config['sp_article_auto_close'] > 0
Calls
      8   Object#config at app/models/configuration.rb:18
      8   ConfigManager#[] at app/models/config_manager.rb:18

 11       if record.article.created_at.to_i < config['sp_article_auto_close'].days.ago.to_i
Calls
      8   Object#config at app/models/configuration.rb:18
      8   ConfigManager#[] at app/models/config_manager.rb:18
      8   ActiveSupport::CoreExtensions::Numeric::Time#days at vendor/rails/activesupport/lib/active_support/core_ext/numeric/time.rb:16
      8   ActiveSupport::CoreExtensions::Numeric::Time#ago at vendor/rails/activesupport/lib/active_support/core_ext/numeric/time.rb:42
      8   ActiveRecord::Associations::AssociationProxy#method_missing at vendor/rails/activerecord/lib/active_record/associations/association_proxy.rb:73

 12         logger.info("[SP] Blocked interaction with #{record.article.title}") 
 13         return true
 14       end
 15     end
 16   end
 17 
 18   def is_spam?(string)
Calls
      1   #<Class:Object>#method_added at vendor/rails/actionpack/lib/action_view/vendor/builder/blankslate.rb:47
Called by
     28   lib/spam_protection.rb:122 in 'ActiveRecord::Validations::ClassMethods#validates_against_spamdb'

 19     return false unless config['sp_global']
Calls
     28   Object#config at app/models/configuration.rb:18
     28   ConfigManager#[] at app/models/config_manager.rb:18

 20     return false if string.blank?
Calls
     19   String#blank? at vendor/rails/activesupport/lib/active_support/core_ext/blank.rb:29
      9   NilClass#blank? at vendor/rails/activesupport/lib/active_support/core_ext/blank.rb:3

 21 
 22     reason = catch(:hit) do
 23       case string
 24         when Format::IP_ADDRESS: self.scan_ip(string)
Calls
      1   Module#const_missing at vendor/rails/activesupport/lib/active_support/dependencies.rb:187

 25         when Format::HTTP_URI: self.scan_uri(URI.parse(string).host) rescue URI::InvalidURIError
Calls
      6   SpamProtection#scan_uri at lib/spam_protection.rb:80
      6   #<Class:URI>#parse at /home/batsman/usr/lib/ruby/1.8/uri/common.rb:479

 26         else self.scan_text(string)
Calls
     13   SpamProtection#scan_text at lib/spam_protection.rb:53

 27       end
 28     end
 29     
 30     if reason
 31       logger.info("[SP] Hit: #{reason}")
 32       return true
 33     end
 34   end
 35   
 36   protected
 37   
 38   def scan_ip(ip_address)
Calls
      1   #<Class:Object>#method_added at vendor/rails/actionpack/lib/action_view/vendor/builder/blankslate.rb:47

 39     logger.info("[SP] Scanning IP #{ip_address}")
 40     
 41     IP_RBL.each do |rbl|
 42       begin
 43         if IPSocket.getaddress((ip_address.split('.').reverse + [rbl]).join('.')) == "127.0.0.2"
 44           throw :hit, "#{rbl} positively resolved #{ip_address}"
 45         end
 46       rescue SocketError
 47       end
 48     end
 49     
 50     return false
 51   end
 52   
 53   def scan_text(string)
Calls
      1   #<Class:Object>#method_added at vendor/rails/actionpack/lib/action_view/vendor/builder/blankslate.rb:47
Called by
     13   lib/spam_protection.rb:26 in 'SpamProtection#is_spam?'

 54     # Scan contained URLs
 55     uri_list = string.scan(/(http:\/\/[^\s"]+)/m).flatten
 56 
 57     # Check for URL count limit    
 58     if config['sp_url_limit'] > 0
Calls
     13   Object#config at app/models/configuration.rb:18
     13   ConfigManager#[] at app/models/config_manager.rb:18

 59       throw :hit, "Hard URL Limit hit: #{uri_list.size} > #{config['sp_url_limit']}" if uri_list.size > config['sp_url_limit']
Calls
     13   Object#config at app/models/configuration.rb:18
     13   ConfigManager#[] at app/models/config_manager.rb:18

 60     end
 61     
 62     uri_list.collect { |uri| URI.parse(uri).host rescue nil }.uniq.compact.each do |host|
Calls
      3   #<Class:URI>#parse at /home/batsman/usr/lib/ruby/1.8/uri/common.rb:479

 63       scan_uri(host)
Calls
      3   SpamProtection#scan_uri at lib/spam_protection.rb:80

 64     end
 65     
 66     # Pattern scanning
 67     BlacklistPattern.find_all.each do |pattern|
Calls
     13   #<Class:ActiveRecord::Base>#find_all at vendor/rails/activerecord/lib/active_record/deprecated_finders.rb:35

 68       logger.info("[SP] Scanning for #{pattern.class} #{pattern.pattern}")
Calls
     26   Logger#info at /home/batsman/usr/lib/ruby/1.8/logger.rb:382
     26   SpamProtection#logger at lib/spam_protection.rb:109
     13   RegexPattern#pattern at (eval):1
     13   StringPattern#pattern at (eval):1

 69 
 70       if pattern.kind_of?(RegexPattern)
 71         throw :hit, "Regex #{pattern.pattern} matched" if string.match(/#{pattern.pattern}/)
Calls
     13   RegexPattern#pattern at (eval):1

 72       else
 73         throw :hit, "String #{pattern.pattern} matched" if string.match(/\b#{Regexp.quote(pattern.pattern)}\b/) 
Calls
     13   StringPattern#pattern at (eval):1

 74       end
 75     end
 76     
 77     return false
 78   end
 79 
 80   def scan_uri(host)
Calls
      1   #<Class:Object>#method_added at vendor/rails/actionpack/lib/action_view/vendor/builder/blankslate.rb:47
Called by
      6   lib/spam_protection.rb:25 in 'SpamProtection#is_spam?'
      3   lib/spam_protection.rb:63 in 'SpamProtection#scan_text'

 81     return scan_ip(host) if host =~ Format::IP_ADDRESS
 82 
 83     host_parts = host.split('.').reverse
 84     domain = Array.new
 85     
 86 
 87     # Check for two level TLD
 88     (SECOND_LEVEL.include?(host_parts[1]) ? 3:2).times do
 89       domain.unshift(host_parts.shift)
 90     end
 91 
 92     logger.info("[SP] Scanning domain #{domain.join('.')}")
Calls
      9   SpamProtection#logger at lib/spam_protection.rb:109
      9   Logger#info at /home/batsman/usr/lib/ruby/1.8/logger.rb:382

 93 
 94     HOST_RBL.each do |rbl|
 95       begin
 96         if [
 97             IPSocket.getaddress([host, rbl].join('.')),
Calls
     18   #<Class:IPSocket>#getaddress at test/mocks/test/dns_mock.rb:2

 98             IPSocket.getaddress((domain + [rbl]).join('.'))
Calls
     18   #<Class:IPSocket>#getaddress at test/mocks/test/dns_mock.rb:2

 99            ].include?("127.0.0.2")
100           throw :hit, "#{rbl} positively resolved #{domain.join('.')}"
101         end
102       rescue SocketError
103       end
104     end
105     
106     return false
107   end
108 
109   def logger
Calls
      1   #<Class:Object>#method_added at vendor/rails/actionpack/lib/action_view/vendor/builder/blankslate.rb:47
Called by
     26   lib/spam_protection.rb:68 in 'SpamProtection#scan_text'
      9   lib/spam_protection.rb:92 in 'SpamProtection#scan_uri'

110     @logger ||= RAILS_DEFAULT_LOGGER || Logger.new(STDOUT)
111   end
112 end
113 
114 module ActiveRecord
115   module Validations
116     module ClassMethods
117       def validates_against_spamdb(*attr_names)
Called by
      1   app/models/comment.rb:7 in '#'
      1   app/models/trackback.rb:7 in '#'

118         configuration = { :message => "blocked by SpamProtection" }
119         configuration.update(attr_names.pop) if attr_names.last.is_a?(Hash)
120 
121         validates_each(attr_names, configuration) do |record, attr_name, value|
Calls
      2   ActiveRecord::Validations::ClassMethods#validates_each at vendor/rails/activerecord/lib/active_record/validations.rb:285

122           record.errors.add(attr_name, configuration[:message]) if SpamProtection.new.is_spam?(value)
Calls
     28   SpamProtection#is_spam? at lib/spam_protection.rb:18

123         end
124       end
125       def validates_age_of(*attr_names)
Called by
      1   app/models/trackback.rb:6 in '#'
      1   app/models/comment.rb:8 in '#'

126         configuration = { :message => "points to an item that is no longer available for interaction"}
127         configuration.update(attr_names.pop) if attr_names.last.is_a?(Hash)
128         
129         validates_each(attr_names, configuration) do |record, attr_name, value|
Calls
      2   ActiveRecord::Validations::ClassMethods#validates_each at vendor/rails/activerecord/lib/active_record/validations.rb:285

130           next unless value.to_i > 0
131           record.errors.add(attr_name, configuration[:message]) if SpamProtection.new.article_closed?(record)
Calls
      8   SpamProtection#article_closed? at lib/spam_protection.rb:9

132         end
133       end
134     end
135   end
136 end

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

Valid XHTML 1.0! Valid CSS!