module TestProf::AnyFixture
Make DB fixtures from blocks.
Constants
- ANY_FIXTURE_IGNORE_RXP
- ANY_FIXTURE_RXP
- INSERT_RXP
- MODIFY_RXP
Attributes
adapter[R]
Public Class Methods
cached(id) { || ... }
click to toggle source
# File lib/test_prof/any_fixture.rb, line 127 def cached(id) cache.fetch(id) { yield } end
clean()
click to toggle source
Clean all affected tables (but do not reset cache)
# File lib/test_prof/any_fixture.rb, line 165 def clean disable_referential_integrity do tables_cache.keys.reverse_each do |table| ActiveRecord::Base.connection.execute %( DELETE FROM #{table} ) end end end
config()
click to toggle source
# File lib/test_prof/any_fixture.rb, line 96 def config @config ||= Configuration.new end
configure() { |config| ... }
click to toggle source
# File lib/test_prof/any_fixture.rb, line 100 def configure yield config end
register(id) { || ... }
click to toggle source
Register a block of code as a fixture, returns the result of the block execution
# File lib/test_prof/any_fixture.rb, line 119 def register(id) cached(id) do ActiveSupport::Notifications.subscribed(method(:subscriber), "sql.active_record") do yield end end end
register_dump(name, clean: true, **options) { || ... }
click to toggle source
Create and register new SQL dump. Use `watch` to provide additional paths to watch for dump re-generation
# File lib/test_prof/any_fixture.rb, line 134 def register_dump(name, clean: true, **options) called_from = caller_locations(1, 1).first.path watch = options.delete(:watch) || [called_from] cache_key = options.delete(:cache_key) skip = options.delete(:skip_if) id = "sql/#{name}" register_method = clean ? :register : :cached public_send(register_method, id) do dump = Dump.new(name, watch: watch, cache_key: cache_key) unless dump.force? next if skip&.call(dump: dump) next dump.within_prepared_env(import: true, **options) { dump.load } if dump.exists? end subscriber = ActiveSupport::Notifications.subscribe("sql.active_record", dump.subscriber) res = dump.within_prepared_env(**options) { yield } dump.commit! res ensure ActiveSupport::Notifications.unsubscribe(subscriber) if subscriber end end
report_stats()
click to toggle source
# File lib/test_prof/any_fixture.rb, line 193 def report_stats if cache.stats.empty? log :info, "AnyFixture has not been used" return end msgs = [] msgs << <<~MSG AnyFixture usage stats: MSG first_column = cache.stats.keys.map(&:size).max + 2 msgs << format( "%#{first_column}s %12s %9s %12s", "key", "build time", "hit count", "saved time" ) msgs << "" total_spent = 0.0 total_saved = 0.0 total_miss = 0.0 cache.stats.to_a.sort_by { |(_, v)| -v[:hit] }.each do |(key, stats)| total_spent += stats[:time] saved = stats[:time] * stats[:hit] total_saved += saved total_miss += stats[:time] if stats[:hit].zero? msgs << format( "%#{first_column}s %12s %9d %12s", key, stats[:time].duration, stats[:hit], saved.duration ) end msgs << <<~MSG Total time spent: #{total_spent.duration} Total time saved: #{total_saved.duration} Total time wasted: #{total_miss.duration} MSG log :info, msgs.join("\n") end
reporting_enabled()
click to toggle source
# File lib/test_prof/any_fixture.rb, line 110 def reporting_enabled warn "AnyFixture.reporting_enabled is deprecated and will be removed in 1.1. Use AnyFixture.config.reporting_enabled instead" config.reporting_enabled end
Also aliased as: reporting_enabled?
reporting_enabled=(val)
click to toggle source
Backward compatibility
# File lib/test_prof/any_fixture.rb, line 105 def reporting_enabled=(val) warn "AnyFixture.reporting_enabled is deprecated and will be removed in 1.1. Use AnyFixture.config.reporting_enabled instead" config.reporting_enabled = val end
reset()
click to toggle source
Reset all information and clean tables
# File lib/test_prof/any_fixture.rb, line 176 def reset clean tables_cache.clear cache.clear end
subscriber(_event, _start, _finish, _id, data)
click to toggle source
# File lib/test_prof/any_fixture.rb, line 182 def subscriber(_event, _start, _finish, _id, data) matches = data.fetch(:sql).match(INSERT_RXP) return unless matches table_name = matches[1] return if /sqlite_sequence/.match?(table_name) tables_cache[table_name] = true end
Private Class Methods
cache()
click to toggle source
# File lib/test_prof/any_fixture.rb, line 248 def cache @cache ||= Cache.new end
disable_referential_integrity() { || ... }
click to toggle source
# File lib/test_prof/any_fixture.rb, line 256 def disable_referential_integrity connection = ActiveRecord::Base.connection return yield unless connection.respond_to?(:disable_referential_integrity) connection.disable_referential_integrity { yield } end
tables_cache()
click to toggle source
# File lib/test_prof/any_fixture.rb, line 252 def tables_cache @tables_cache ||= {} end
Public Instance Methods
to_digest()
click to toggle source
# File lib/test_prof/any_fixture/dump.rb, line 15 def to_digest to_s end
Private Instance Methods
build_path(name, digest)
click to toggle source
# File lib/test_prof/any_fixture/dump.rb, line 185 def build_path(name, digest) dir = TestProf.artifact_path( File.join(AnyFixture.config.dumps_dir) ) FileUtils.mkdir_p(dir) File.join(dir, "#{name}-#{digest}.sql") end
import_via_active_record()
click to toggle source
# File lib/test_prof/any_fixture/dump.rb, line 175 def import_via_active_record conn = ActiveRecord::Base.connection File.open(path).each_line do |query| next if query.empty? conn.execute query end end
run_after_callbacks(callback:, **options)
click to toggle source
# File lib/test_prof/any_fixture/dump.rb, line 204 def run_after_callbacks(callback:, **options) # The order is vice versa to setup callback&.call(**options) adapter.teardown_env unless options[:import] AnyFixture.config.after_dump.each { |clbk| clbk.call(**options) } end
run_before_callbacks(callback:, **options)
click to toggle source
# File lib/test_prof/any_fixture/dump.rb, line 195 def run_before_callbacks(callback:, **options) # First, call config-defined setup callbacks AnyFixture.config.before_dump.each { |clbk| clbk.call(**options) } # Then, adapter-defined callbacks adapter.setup_env unless options[:import] # Finally, user-provided callback callback&.call(**options) end