diff options
Diffstat (limited to 'activerecord/lib/active_record')
-rw-r--r-- | activerecord/lib/active_record/test_case.rb | 62 |
1 files changed, 61 insertions, 1 deletions
diff --git a/activerecord/lib/active_record/test_case.rb b/activerecord/lib/active_record/test_case.rb index 86687afdda..4d881f0f7d 100644 --- a/activerecord/lib/active_record/test_case.rb +++ b/activerecord/lib/active_record/test_case.rb @@ -14,7 +14,7 @@ module ActiveRecord end def teardown - ActiveRecord::SQLCounter.log.clear + SQLCounter.log.clear end def cleanup_identity_map @@ -30,5 +30,65 @@ module ActiveRecord assert_equal expected.to_s, actual.to_s, message end end + + def assert_sql(*patterns_to_match) + SQLCounter.log = [] + yield + SQLCounter.log + ensure + failed_patterns = [] + patterns_to_match.each do |pattern| + failed_patterns << pattern unless SQLCounter.log.any?{ |sql| pattern === sql } + end + assert failed_patterns.empty?, "Query pattern(s) #{failed_patterns.map{ |p| p.inspect }.join(', ')} not found.#{SQLCounter.log.size == 0 ? '' : "\nQueries:\n#{SQLCounter.log.join("\n")}"}" + end + + def assert_queries(num = 1) + SQLCounter.log = [] + yield + ensure + assert_equal num, SQLCounter.log.size, "#{SQLCounter.log.size} instead of #{num} queries were executed.#{SQLCounter.log.size == 0 ? '' : "\nQueries:\n#{SQLCounter.log.join("\n")}"}" + end + + def assert_no_queries(&block) + prev_ignored_sql = SQLCounter.ignored_sql + SQLCounter.ignored_sql = [] + assert_queries(0, &block) + ensure + SQLCounter.ignored_sql = prev_ignored_sql + end + + end + + class SQLCounter + class << self + attr_accessor :ignored_sql, :log + end + + self.log = [] + + self.ignored_sql = [/^PRAGMA (?!(table_info))/, /^SELECT currval/, /^SELECT CAST/, /^SELECT @@IDENTITY/, /^SELECT @@ROWCOUNT/, /^SAVEPOINT/, /^ROLLBACK TO SAVEPOINT/, /^RELEASE SAVEPOINT/, /^SHOW max_identifier_length/, /^BEGIN/, /^COMMIT/] + + # FIXME: this needs to be refactored so specific database can add their own + # ignored SQL. This ignored SQL is for Oracle. + ignored_sql.concat [/^select .*nextval/i, /^SAVEPOINT/, /^ROLLBACK TO/, /^\s*select .* from all_triggers/im] + + + attr_reader :ignore + + def initialize(ignore = Regexp.union(self.class.ignored_sql)) + @ignore = ignore + end + + def call(name, start, finish, message_id, values) + sql = values[:sql] + + # FIXME: this seems bad. we should probably have a better way to indicate + # the query was cached + return if 'CACHE' == values[:name] || ignore =~ sql + self.class.log << sql + end end + + ActiveSupport::Notifications.subscribe('sql.active_record', SQLCounter.new) end |