From 6010d78e4c4a7bf85200fcd032bfb4e831a15d29 Mon Sep 17 00:00:00 2001 From: Dan Mayer Date: Wed, 28 Dec 2022 22:55:12 -0700 Subject: [PATCH 1/5] refactor to leverage abstract tracker --- lib/coverband.rb | 1 + lib/coverband/at_exit.rb | 3 +- lib/coverband/collectors/abstract_tracker.rb | 153 ++++++++++++++++++ lib/coverband/collectors/route_tracker.rb | 146 +++-------------- .../collectors/translation_tracker.rb | 151 ++--------------- lib/coverband/collectors/view_tracker.rb | 120 +++----------- .../collectors/view_tracker_service.rb | 2 +- lib/coverband/integrations/background.rb | 4 +- lib/coverband/reporters/web.rb | 2 +- lib/coverband/utils/html_formatter.rb | 6 +- lib/coverband/utils/railtie.rb | 6 +- .../collectors/route_tracker_test.rb | 44 ++--- .../coverband/collectors/view_tracker_test.rb | 58 +++---- views/route_tracker.erb | 8 +- views/view_tracker.erb | 8 +- 15 files changed, 276 insertions(+), 436 deletions(-) create mode 100644 lib/coverband/collectors/abstract_tracker.rb diff --git a/lib/coverband.rb b/lib/coverband.rb index ab8ccca8..7c357e83 100644 --- a/lib/coverband.rb +++ b/lib/coverband.rb @@ -16,6 +16,7 @@ require "coverband/adapters/null_store" require "coverband/utils/file_hasher" require "coverband/collectors/coverage" +require "coverband/collectors/abstract_tracker" require "coverband/collectors/view_tracker" require "coverband/collectors/view_tracker_service" require "coverband/collectors/route_tracker" diff --git a/lib/coverband/at_exit.rb b/lib/coverband/at_exit.rb index 837de5c0..0464572a 100644 --- a/lib/coverband/at_exit.rb +++ b/lib/coverband/at_exit.rb @@ -22,7 +22,8 @@ def self.register Coverband.report_coverage # to ensure we track mailer views we now need to report views tracking # at exit as well for rake tasks and background tasks that can trigger email - Coverband.configuration.view_tracker&.report_views_tracked + Coverband.configuration.view_tracker&.save_report + Coverband.configuration.translations_tracker&.save_report end end end diff --git a/lib/coverband/collectors/abstract_tracker.rb b/lib/coverband/collectors/abstract_tracker.rb new file mode 100644 index 00000000..6010fbb2 --- /dev/null +++ b/lib/coverband/collectors/abstract_tracker.rb @@ -0,0 +1,153 @@ +# frozen_string_literal: true + +require "set" +require "singleton" + +module Coverband + module Collectors + ### + # This abstract class makes it easy to track any used/unused with timestamp set of usage + ### + class AbstractTracker + attr_accessor :target + attr_reader :logger, :store, :ignore_patterns + + def initialize(options = {}) + raise NotImplementedError, "#{self.class.name} requires a newer version of Rails" unless self.class.supported_version? + raise "Coverband: #{self.class.name} initialized before configuration!" if !Coverband.configured? && ENV["COVERBAND_TEST"] == "test" + + @ignore_patterns = Coverband.configuration.ignore + @store = options.fetch(:store) { Coverband.configuration.store } + @logger = options.fetch(:logger) { Coverband.configuration.logger } + @target = options.fetch(:target) do + concrete_target + end + + @one_time_timestamp = false + + @logged_keys = Set.new + @keys_to_record = Set.new + end + + def logged_keys + @logged_keys.to_a + end + + def keys_to_record + @keys_to_record.to_a + end + + ### + # This method is called on every translation usage + ### + def track_key(key) + if key + if newly_seen_key?(key) + @logged_keys << key + @keys_to_record << key if track_key?(key) + end + end + end + + def used_keys + redis_store.hgetall(tracker_key) + end + + def all_keys + target.uniq + end + + def unused_keys(used_keys = nil) + recently_used_keys = (used_keys || self.used_keys).keys + all_keys.reject { |k| recently_used_keys.include?(k.to_s) } + end + + def as_json + used_keys = self.used_keys + { + unused_keys: unused_keys(used_keys), + used_keys: used_keys + }.to_json + end + + def tracking_since + if (tracking_time = redis_store.get(tracker_time_key)) + Time.at(tracking_time.to_i).iso8601 + else + "N/A" + end + end + + def reset_recordings + redis_store.del(tracker_key) + redis_store.del(tracker_time_key) + end + + def clear_key!(key) + return unless key + puts "#{tracker_key} key #{key}" + redis_store.hdel(tracker_key, key) + @logged_keys.delete(key) + end + + def save_report + redis_store.set(tracker_time_key, Time.now.to_i) unless @one_time_timestamp || tracker_time_key_exists? + @one_time_timestamp = true + reported_time = Time.now.to_i + @keys_to_record.to_a.each do |key| + redis_store.hset(tracker_key, key.to_s, reported_time) + end + @keys_to_record.clear + rescue => e + # we don't want to raise errors if Coverband can't reach redis. + # This is a nice to have not a bring the system down + logger&.error "Coverband: #{self.class.name} failed to store, error #{e.class.name} info #{e.message}" + end + + # This is the basic rails version supported, if there is something more unique over ride in subclass + def self.supported_version? + defined?(Rails) && defined?(Rails::VERSION) && Rails::VERSION::STRING.split(".").first.to_i >= 5 + end + + protected + + def newly_seen_key?(key) + !@logged_keys.include?(key) + end + + def track_key?(key, options = {}) + @ignore_patterns.none? { |pattern| key.to_s.include?(pattern) } + end + + private + + def concrete_target + raise "subclass must implement" + end + + def redis_store + store.raw_store + end + + def tracker_time_key_exists? + if defined?(redis_store.exists?) + redis_store.exists?(tracker_time_key) + else + redis_store.exists(tracker_time_key) + end + end + + def tracker_key + "#{class_key}_tracker" + end + + def tracker_time_key + "#{class_key}_tracker_time" + end + + def class_key + @class_key ||= self.class.name.split("::").last + end + end + end +end diff --git a/lib/coverband/collectors/route_tracker.rb b/lib/coverband/collectors/route_tracker.rb index eb77a4d1..d2b36e73 100644 --- a/lib/coverband/collectors/route_tracker.rb +++ b/lib/coverband/collectors/route_tracker.rb @@ -8,51 +8,12 @@ module Collectors ### # This class tracks route usage via ActiveSupport::Notifications ### - class RouteTracker - attr_accessor :target - attr_reader :logger, :store, :ignore_patterns - - def initialize(options = {}) - raise NotImplementedError, "Route Tracker requires Rails 4 or greater" unless self.class.supported_version? - raise "Coverband: route tracker initialized before configuration!" if !Coverband.configured? && ENV["COVERBAND_TEST"] == "test" - - @ignore_patterns = Coverband.configuration.ignore - @store = options.fetch(:store) { Coverband.configuration.store } - @logger = options.fetch(:logger) { Coverband.configuration.logger } - @target = options.fetch(:target) do - if defined?(Rails.application) - Rails.application.routes.routes.map do |route| - { - controller: route.defaults[:controller], - action: route.defaults[:action], - url_path: route.path.spec.to_s.gsub("(.:format)", ""), - verb: route.verb - } - end - else - [] - end - end - - @one_time_timestamp = false - - @logged_routes = Set.new - @routes_to_record = Set.new - end - - def logged_routes - @logged_routes.to_a - end - - def routes_to_record - @routes_to_record.to_a - end - + class RouteTracker < AbstractTracker ### # This method is called on every routing call, so we try to reduce method calls # and ensure high performance ### - def track_routes(_name, _start, _finish, _id, payload) + def track_key(payload) route = if payload[:request] { controller: nil, @@ -69,104 +30,39 @@ def track_routes(_name, _start, _finish, _id, payload) } end if route - if newly_seen_route?(route) - @logged_routes << route - @routes_to_record << route if track_route?(route) + if newly_seen_key?(route) + @logged_keys << route + @keys_to_record << route if track_key?(route) end end end - def used_routes - redis_store.hgetall(tracker_key) - end - - def all_routes - target.uniq - end - - def unused_routes(used_routes = nil) - recently_used_routes = (used_routes || self.used_routes).keys - # NOTE: we match with or without path to handle paths with named params like `/user/:user_id` to used routes filling with all the variable named paths - all_routes.reject { |r| recently_used_routes.include?(r.to_s) || recently_used_routes.include?(r.merge(url_path: nil).to_s) } - end - - def as_json - used_routes = self.used_routes - { - unused_routes: unused_routes(used_routes), - used_routes: used_routes - }.to_json - end - - def tracking_since - if (tracking_time = redis_store.get(tracker_time_key)) - Time.at(tracking_time.to_i).iso8601 - else - "N/A" - end - end - - def reset_recordings - redis_store.del(tracker_key) - redis_store.del(tracker_time_key) - end - - def clear_route!(route) - return unless route - - redis_store.hdel(tracker_key, route) - @logged_routes.delete(route) - end - - def report_routes_tracked - redis_store.set(tracker_time_key, Time.now.to_i) unless @one_time_timestamp || tracker_time_key_exists? - @one_time_timestamp = true - reported_time = Time.now.to_i - @routes_to_record.to_a.each do |route| - redis_store.hset(tracker_key, route.to_s, reported_time) - end - @routes_to_record.clear - rescue => e - # we don't want to raise errors if Coverband can't reach redis. - # This is a nice to have not a bring the system down - logger&.error "Coverband: route_tracker failed to store, error #{e.class.name} info #{e.message}" - end - def self.supported_version? - defined?(Rails) && defined?(Rails::VERSION) && Rails::VERSION::STRING.split(".").first.to_i >= 4 + defined?(Rails) && defined?(Rails::VERSION) && Rails::VERSION::STRING.split(".").first.to_i >= 6 end - protected - - def newly_seen_route?(route) - !@logged_routes.include?(route) - end - - def track_route?(route, options = {}) - @ignore_patterns.none? { |pattern| route.to_s.include?(pattern) } + def unused_keys(used_keys = nil) + recently_used_routes = (used_keys || self.used_keys).keys + # NOTE: we match with or without path to handle paths with named params like `/user/:user_id` to used routes filling with all the variable named paths + all_keys.reject { |r| recently_used_routes.include?(r.to_s) || recently_used_routes.include?(r.merge(url_path: nil).to_s) } end private - def redis_store - store.raw_store - end - - def tracker_time_key_exists? - if defined?(redis_store.exists?) - redis_store.exists?(tracker_time_key) + def concrete_target + if defined?(Rails.application) + Rails.application.routes.routes.map do |route| + { + controller: route.defaults[:controller], + action: route.defaults[:action], + url_path: route.path.spec.to_s.gsub("(.:format)", ""), + verb: route.verb + } + end else - redis_store.exists(tracker_time_key) + [] end end - - def tracker_key - "route_tracker_2" - end - - def tracker_time_key - "route_tracker_time" - end end end end diff --git a/lib/coverband/collectors/translation_tracker.rb b/lib/coverband/collectors/translation_tracker.rb index b6e29b9e..869f9e28 100644 --- a/lib/coverband/collectors/translation_tracker.rb +++ b/lib/coverband/collectors/translation_tracker.rb @@ -20,129 +20,22 @@ def lookup(locale, key, scope = [], options = {}) ### # This class tracks translation usage via I18n::Backend ### - class TranslationTracker - attr_accessor :target - attr_reader :logger, :store, :ignore_patterns - - def initialize(options = {}) - raise NotImplementedError, "#{self.class.name} requires Rails 4 or greater" unless self.class.supported_version? - raise "Coverband: #{self.class.name} initialized before configuration!" if !Coverband.configured? && ENV["COVERBAND_TEST"] == "test" - - @ignore_patterns = Coverband.configuration.ignore - @store = options.fetch(:store) { Coverband.configuration.store } - @logger = options.fetch(:logger) { Coverband.configuration.logger } - @target = options.fetch(:target) do - if defined?(Rails.application) - # I18n.eager_load! - # I18n.backend.send(:translations) - app_translation_keys = [] - app_translation_files = ::I18n.load_path.select { |f| f.match(/config\/locales/) } - app_translation_files.each do |file| - app_translation_keys += flatten_hash(YAML.load_file(file)).keys - end - app_translation_keys.uniq - else - [] - end - end - - @one_time_timestamp = false - - @logged_keys = Set.new - @keys_to_record = Set.new - end - - def logged_keys - @logged_keys.to_a - end - - def keys_to_record - @keys_to_record.to_a - end + class TranslationTracker < AbstractTracker + private - ### - # This method is called on every translation usage - ### - def track_key(key) - if key - if newly_seen_key?(key) - @logged_keys << key - @keys_to_record << key if track_key?(key) + def concrete_target + if defined?(Rails.application) + app_translation_keys = [] + app_translation_files = ::I18n.load_path.select { |f| f.match(/config\/locales/) } + app_translation_files.each do |file| + app_translation_keys += flatten_hash(YAML.load_file(file)).keys end - end - end - - def used_keys - redis_store.hgetall(tracker_key) - end - - def all_keys - target.uniq - end - - def unused_keys(used_keys = nil) - recently_used_keys = (used_keys || self.used_keys).keys - all_keys.reject { |k| recently_used_keys.include?(k.to_s) } - end - - def as_json - used_keys = self.used_keys - { - unused_keys: unused_keys(used_keys), - used_keys: used_keys - }.to_json - end - - def tracking_since - if (tracking_time = redis_store.get(tracker_time_key)) - Time.at(tracking_time.to_i).iso8601 + app_translation_keys.uniq else - "N/A" - end - end - - def reset_recordings - redis_store.del(tracker_key) - redis_store.del(tracker_time_key) - end - - def clear_key!(key) - return unless key - - redis_store.hdel(tracker_key, key) - @logged_keys.delete(key) - end - - def save_report - redis_store.set(tracker_time_key, Time.now.to_i) unless @one_time_timestamp || tracker_time_key_exists? - @one_time_timestamp = true - reported_time = Time.now.to_i - @keys_to_record.to_a.each do |key| - redis_store.hset(tracker_key, key.to_s, reported_time) + [] end - @keys_to_record.clear - rescue => e - # we don't want to raise errors if Coverband can't reach redis. - # This is a nice to have not a bring the system down - logger&.error "Coverband: #{self.class.name} failed to store, error #{e.class.name} info #{e.message}" - end - - def self.supported_version? - defined?(Rails) && defined?(Rails::VERSION) && Rails::VERSION::STRING.split(".").first.to_i >= 4 - end - - protected - - def newly_seen_key?(key) - !@logged_keys.include?(key) end - def track_key?(key, options = {}) - @ignore_patterns.none? { |pattern| key.to_s.include?(pattern) } - end - - private - def flatten_hash(hash) hash.each_with_object({}) do |(k, v), h| if v.is_a? Hash @@ -154,30 +47,6 @@ def flatten_hash(hash) end end end - - def redis_store - store.raw_store - end - - def tracker_time_key_exists? - if defined?(redis_store.exists?) - redis_store.exists?(tracker_time_key) - else - redis_store.exists(tracker_time_key) - end - end - - def tracker_key - "#{class_key}_tracker" - end - - def tracker_time_key - "#{class_key}_tracker_time" - end - - def class_key - @class_key ||= self.class.name.split("::").last - end end end end diff --git a/lib/coverband/collectors/view_tracker.rb b/lib/coverband/collectors/view_tracker.rb index 61775c2a..ea6ab0c5 100644 --- a/lib/coverband/collectors/view_tracker.rb +++ b/lib/coverband/collectors/view_tracker.rb @@ -12,45 +12,26 @@ module Collectors # but am now rolling into Coverband # https://github.com/livingsocial/flatfoot ### - class ViewTracker - attr_accessor :target - attr_reader :logger, :roots, :store, :ignore_patterns + class ViewTracker < AbstractTracker + attr_reader :roots def initialize(options = {}) - raise NotImplementedError, "View Tracker requires Rails 4 or greater" unless self.class.supported_version? - raise "Coverband: view tracker initialized before configuration!" if !Coverband.configured? && ENV["COVERBAND_TEST"] == "test" - @project_directory = File.expand_path(Coverband.configuration.root) - @ignore_patterns = Coverband.configuration.ignore - @store = options.fetch(:store) { Coverband.configuration.store } - @logger = options.fetch(:logger) { Coverband.configuration.logger } - @target = options.fetch(:target) { Dir.glob("#{@project_directory}/app/views/**/*.html.{erb,haml,slim}") } - @roots = options.fetch(:roots) { Coverband.configuration.all_root_patterns } @roots = @roots.split(",") if @roots.is_a?(String) - @one_time_timestamp = false - - @logged_views = Set.new - @views_to_record = Set.new - end - def logged_views - @logged_views.to_a - end - - def views_to_record - @views_to_record.to_a + super end ### # This method is called on every render call, so we try to reduce method calls # and ensure high performance ### - def track_views(_name, _start, _finish, _id, payload) + def track_key(payload) if (file = payload[:identifier]) - if newly_seen_file?(file) - @logged_views << file - @views_to_record << file if track_file?(file) + if newly_seen_key?(file) + @logged_keys << file + @keys_to_record << file if track_key?(file) end end @@ -61,13 +42,13 @@ def track_views(_name, _start, _finish, _id, payload) # http://edgeguides.rubyonrails.org/active_support_instrumentation.html#render_partial-action_view ### return unless (layout_file = payload[:layout]) - return unless newly_seen_file?(layout_file) + return unless newly_seen_key?(layout_file) - @logged_views << layout_file - @views_to_record << layout_file if track_file?(layout_file, layout: true) + @logged_keys << layout_file + @keys_to_record << layout_file if track_file?(layout_file, layout: true) end - def used_views + def used_keys views = redis_store.hgetall(tracker_key) normalized_views = {} views.each_pair do |view, time| @@ -79,7 +60,7 @@ def used_views normalized_views end - def all_views + def all_keys all_views = [] target.each do |view| roots.each do |root| @@ -90,92 +71,35 @@ def all_views all_views.uniq end - def unused_views(used_views = nil) - recently_used_views = (used_views || self.used_views).keys - unused_views = all_views - recently_used_views + def unused_keys(used_views = nil) + recently_used_views = (used_keys || used_keys).keys + unused_views = all_keys - recently_used_views # since layouts don't include format we count them used if they match with ANY formats unused_views.reject { |view| view.match(/\/layouts\//) && recently_used_views.any? { |used_view| view.include?(used_view) } } end - def as_json - used_views = self.used_views - { - unused_views: unused_views(used_views), - used_views: used_views - }.to_json - end - - def tracking_since - if (tracking_time = redis_store.get(tracker_time_key)) - Time.at(tracking_time.to_i).iso8601 - else - "N/A" - end - end - - def reset_recordings - redis_store.del(tracker_key) - redis_store.del(tracker_time_key) - end - - def clear_file!(filename) + def clear_key!(filename) return unless filename filename = "#{@project_directory}/#{filename}" redis_store.hdel(tracker_key, filename) - @logged_views.delete(filename) - end - - def report_views_tracked - redis_store.set(tracker_time_key, Time.now.to_i) unless @one_time_timestamp || tracker_time_key_exists? - @one_time_timestamp = true - reported_time = Time.now.to_i - @views_to_record.to_a.each do |file| - redis_store.hset(tracker_key, file, reported_time) - end - @views_to_record.clear - rescue => e - # we don't want to raise errors if Coverband can't reach redis. - # This is a nice to have not a bring the system down - logger&.error "Coverband: view_tracker failed to store, error #{e.class.name}" - end - - def self.supported_version? - defined?(Rails) && defined?(Rails::VERSION) && Rails::VERSION::STRING.split(".").first.to_i >= 4 + @logged_keys.delete(filename) end - protected - - def newly_seen_file?(file) - !@logged_views.include?(file) - end + private def track_file?(file, options = {}) (file.start_with?(@project_directory) || options[:layout]) && @ignore_patterns.none? { |pattern| file.include?(pattern) } end - private - - def redis_store - store.raw_store - end - - def tracker_time_key_exists? - if defined?(redis_store.exists?) - redis_store.exists?(tracker_time_key) + def concrete_target + if defined?(Rails.application) + Dir.glob("#{@project_directory}/app/views/**/*.html.{erb,haml,slim}") else - redis_store.exists(tracker_time_key) + [] end end - - def tracker_key - "render_tracker_2" - end - - def tracker_time_key - "render_tracker_time" - end end end end diff --git a/lib/coverband/collectors/view_tracker_service.rb b/lib/coverband/collectors/view_tracker_service.rb index aafdfdb0..1e3996cf 100644 --- a/lib/coverband/collectors/view_tracker_service.rb +++ b/lib/coverband/collectors/view_tracker_service.rb @@ -6,7 +6,7 @@ module Collectors # This class extends view tracker to support web service reporting ### class ViewTrackerService < ViewTracker - def report_views_tracked + def save_report reported_time = Time.now.to_i if @views_to_record.any? relative_views = @views_to_record.map! do |view| diff --git a/lib/coverband/integrations/background.rb b/lib/coverband/integrations/background.rb index 8d6d3ae6..998d3850 100644 --- a/lib/coverband/integrations/background.rb +++ b/lib/coverband/integrations/background.rb @@ -38,8 +38,8 @@ def self.start # if deferred is set also sleep frst to spread load sleep(sleep_seconds.to_i) if Coverband.configuration.defer_eager_loading_data? Coverband.report_coverage - Coverband.configuration.view_tracker&.report_views_tracked - Coverband.configuration.route_tracker&.report_routes_tracked + Coverband.configuration.view_tracker&.save_report + Coverband.configuration.route_tracker&.save_report Coverband.configuration.translations_tracker&.save_report if Coverband.configuration.verbose logger.debug("Coverband: background reporting coverage (#{Coverband.configuration.store.type}). Sleeping #{sleep_seconds}s") diff --git a/lib/coverband/reporters/web.rb b/lib/coverband/reporters/web.rb index f0db3580..3a8c0aa9 100644 --- a/lib/coverband/reporters/web.rb +++ b/lib/coverband/reporters/web.rb @@ -206,7 +206,7 @@ def clear_route_tracking_route if Coverband.configuration.web_enable_clear tracker = Coverband::Collectors::RouteTracker.new(store: Coverband.configuration.store) route = request.params["route"] - tracker.clear_route!(route) + tracker.clear_key!(route) notice = "coverage for route #{route} cleared" else notice = "web_enable_clear isn't enabled in your configuration" diff --git a/lib/coverband/utils/html_formatter.rb b/lib/coverband/utils/html_formatter.rb index f900e2bb..2454cd33 100644 --- a/lib/coverband/utils/html_formatter.rb +++ b/lib/coverband/utils/html_formatter.rb @@ -42,7 +42,7 @@ def format_route_tracker! end def format_translations_tracker! - format_translations_tracker + template("translations_tracker").result(binding) end def format_source_file!(filename) @@ -69,10 +69,6 @@ def format_route_tracker template("route_tracker").result(binding) end - def format_translations_tracker - template("translations_tracker").result(binding) - end - def format(result) Dir[File.join(File.dirname(__FILE__), "../../../public/*")].each do |path| FileUtils.cp_r(path, asset_output_path) diff --git a/lib/coverband/utils/railtie.rb b/lib/coverband/utils/railtie.rb index 632b5e29..aad86151 100644 --- a/lib/coverband/utils/railtie.rb +++ b/lib/coverband/utils/railtie.rb @@ -36,7 +36,7 @@ class Railtie < Rails::Railtie Coverband.configuration.route_tracker = Coverband::Collectors::RouteTracker.new ActiveSupport::Notifications.subscribe("start_processing.action_controller") do |name, start, finish, id, payload| - Coverband.configuration.route_tracker.track_routes(name, start, finish, id, payload) + Coverband.configuration.route_tracker.track_key(payload) end # NOTE: This event was instrumented in Aug 10th 2022, but didn't make the 7.0.4 release and should be in the next release @@ -44,7 +44,7 @@ class Railtie < Rails::Railtie # Automatic tracking of redirects isn't avaible before Rails 7.1.0 (currently tested against the 7.1.0.alpha) # We could consider back porting or patching a solution that works on previous Rails versions ActiveSupport::Notifications.subscribe("redirect.action_dispatch") do |name, start, finish, id, payload| - Coverband.configuration.route_tracker.track_routes(name, start, finish, id, payload) + Coverband.configuration.route_tracker.track_key(payload) end end @@ -65,7 +65,7 @@ class Railtie < Rails::Railtie Coverband.configuration.view_tracker = COVERBAND_VIEW_TRACKER ActiveSupport::Notifications.subscribe(/render_(template|partial|collection).action_view/) do |name, start, finish, id, payload| - COVERBAND_VIEW_TRACKER.track_views(name, start, finish, id, payload) unless name.include?("!") + COVERBAND_VIEW_TRACKER.track_key(payload) unless name.include?("!") end end rescue Redis::CannotConnectError => error diff --git a/test/coverband/collectors/route_tracker_test.rb b/test/coverband/collectors/route_tracker_test.rb index 8d6852ce..be31b0d4 100644 --- a/test/coverband/collectors/route_tracker_test.rb +++ b/test/coverband/collectors/route_tracker_test.rb @@ -23,7 +23,7 @@ def setup assert_equal nil, tracker.target.first assert !tracker.store.nil? assert_equal [], tracker.target - assert_equal [], tracker.logged_routes + assert_equal [], tracker.logged_keys end test "track redirect routes" do @@ -35,9 +35,9 @@ def setup payload = { request: Payload.new("path", "GET") } - tracker.track_routes("name", "start", "finish", "id", payload) - tracker.report_routes_tracked - assert_equal [route_hash], tracker.logged_routes + tracker.track_key(payload) + tracker.save_report + assert_equal [route_hash], tracker.logged_keys end test "track controller routes" do @@ -52,9 +52,9 @@ def setup path: "path", method: "GET" } - tracker.track_routes("name", "start", "finish", "id", payload) - tracker.report_routes_tracked - assert_equal [route_hash], tracker.logged_routes + tracker.track_key(payload) + tracker.save_report + assert_equal [route_hash], tracker.logged_keys end test "report used routes" do @@ -68,9 +68,9 @@ def setup path: "path", method: "GET" } - tracker.track_routes("name", "start", "finish", "id", payload) - tracker.report_routes_tracked - assert_equal [route_hash.to_s], tracker.used_routes.keys + tracker.track_key(payload) + tracker.save_report + assert_equal [route_hash.to_s], tracker.used_keys.keys end test "report unused routes" do @@ -97,9 +97,9 @@ def setup path: "path", method: "GET" } - tracker.track_routes("name", "start", "finish", "id", payload) - tracker.report_routes_tracked - assert_equal [app_routes.first], tracker.unused_routes + tracker.track_key(payload) + tracker.save_report + assert_equal [app_routes.first], tracker.unused_keys end test "report unused routes pulls out parameterized routes" do @@ -120,9 +120,9 @@ def setup path: "some/controller/123", method: "GET" } - tracker.track_routes("name", "start", "finish", "id", payload) - tracker.report_routes_tracked - assert_equal [], tracker.unused_routes + tracker.track_key(payload) + tracker.save_report + assert_equal [], tracker.unused_keys end test "reset store" do @@ -135,9 +135,9 @@ def setup method: "GET" } store.raw_store.expects(:del).with(tracker_key) - store.raw_store.expects(:del).with("route_tracker_time") + store.raw_store.expects(:del).with("RouteTracker_tracker_time") tracker = Coverband::Collectors::RouteTracker.new(store: store, roots: "dir") - tracker.track_routes("name", "start", "finish", "id", payload) + tracker.track_key(payload) tracker.reset_recordings end @@ -152,10 +152,10 @@ def setup path: "path", method: "GET" } - tracker.track_routes("name", "start", "finish", "id", payload) - tracker.report_routes_tracked - assert_equal [route_hash.to_s], tracker.used_routes.keys - tracker.clear_route!(route_hash.to_s) + tracker.track_key(payload) + tracker.save_report + assert_equal [route_hash.to_s], tracker.used_keys.keys + tracker.clear_key!(route_hash.to_s) assert_equal [], tracker.store.raw_store.hgetall(tracker_key).keys end diff --git a/test/coverband/collectors/view_tracker_test.rb b/test/coverband/collectors/view_tracker_test.rb index 87abb470..960156fb 100644 --- a/test/coverband/collectors/view_tracker_test.rb +++ b/test/coverband/collectors/view_tracker_test.rb @@ -4,7 +4,7 @@ class ViewTrackerTest < Minitest::Test def tracker_key - "render_tracker_2" + "ViewTracker_tracker" end def setup @@ -18,7 +18,7 @@ def setup assert_equal "dir", tracker.roots.first assert !tracker.store.nil? assert_equal [], tracker.target - assert_equal [], tracker.logged_views + assert_equal [], tracker.logged_keys end test "track partials" do @@ -27,9 +27,9 @@ def setup file_path = "#{File.expand_path(Coverband.configuration.root)}/file" store.raw_store.expects(:hset).with(tracker_key, file_path, anything) tracker = Coverband::Collectors::ViewTracker.new(store: store, roots: "dir") - tracker.track_views("name", "start", "finish", "id", identifier: file_path) - tracker.report_views_tracked - assert_equal [file_path], tracker.logged_views + tracker.track_key(identifier: file_path) + tracker.save_report + assert_equal [file_path], tracker.logged_keys end test "track partials that include the word vendor in the path" do @@ -37,9 +37,9 @@ def setup store = fake_store file_path = "#{File.expand_path(Coverband.configuration.root)}/vendor_relations/file" tracker = Coverband::Collectors::ViewTracker.new(store: store, roots: "dir") - tracker.track_views("name", "start", "finish", "id", identifier: file_path) - tracker.report_views_tracked - assert_equal [file_path], tracker.used_views.keys + tracker.track_key(identifier: file_path) + tracker.save_report + assert_equal [file_path], tracker.used_keys.keys end test "track partials that include the word _mailer in the path" do @@ -47,9 +47,9 @@ def setup store = fake_store file_path = "#{File.expand_path(Coverband.configuration.root)}/_mailer/file" tracker = Coverband::Collectors::ViewTracker.new(store: store, roots: "dir") - tracker.track_views("name", "start", "finish", "id", identifier: file_path) - tracker.report_views_tracked - assert_equal [file_path], tracker.used_views.keys + tracker.track_key(identifier: file_path) + tracker.save_report + assert_equal [file_path], tracker.used_keys.keys end test "ignore partials that include the folder vendor in the path" do @@ -57,9 +57,9 @@ def setup store = fake_store file_path = "#{File.expand_path(Coverband.configuration.root)}/vendor/file" tracker = Coverband::Collectors::ViewTracker.new(store: store, roots: "dir") - tracker.track_views("name", "start", "finish", "id", identifier: file_path) - tracker.report_views_tracked - assert_equal({}, tracker.used_views) + tracker.track_key(identifier: file_path) + tracker.save_report + assert_equal({}, tracker.used_keys) end test "track layouts" do @@ -68,9 +68,9 @@ def setup file_path = "#{File.expand_path(Coverband.configuration.root)}/layout" store.raw_store.expects(:hset).with(tracker_key, file_path, anything) tracker = Coverband::Collectors::ViewTracker.new(store: store, roots: "dir") - tracker.track_views("name", "start", "finish", "id", layout: file_path) - tracker.report_views_tracked - assert_equal [file_path], tracker.logged_views + tracker.track_key(layout: file_path) + tracker.save_report + assert_equal [file_path], tracker.logged_keys end test "report used partials" do @@ -78,9 +78,9 @@ def setup store = fake_store file_path = "#{File.expand_path(Coverband.configuration.root)}/file" tracker = Coverband::Collectors::ViewTracker.new(store: store, roots: "dir") - tracker.track_views("name", "start", "finish", "id", identifier: file_path) - tracker.report_views_tracked - assert_equal [file_path], tracker.used_views.keys + tracker.track_key(identifier: file_path) + tracker.save_report + assert_equal [file_path], tracker.used_keys.keys end test "report unused partials" do @@ -89,30 +89,30 @@ def setup file_path = "#{File.expand_path(Coverband.configuration.root)}/file" target = [file_path, "not_used"] tracker = Coverband::Collectors::ViewTracker.new(store: store, roots: "dir", target: target) - tracker.track_views("name", "start", "finish", "id", identifier: file_path) - tracker.report_views_tracked - assert_equal ["not_used"], tracker.unused_views + tracker.track_key(identifier: file_path) + tracker.save_report + assert_equal ["not_used"], tracker.unused_keys end test "reset store" do Coverband::Collectors::ViewTracker.expects(:supported_version?).returns(true) store = fake_store store.raw_store.expects(:del).with(tracker_key) - store.raw_store.expects(:del).with("render_tracker_time") + store.raw_store.expects(:del).with("ViewTracker_tracker_time") tracker = Coverband::Collectors::ViewTracker.new(store: store, roots: "dir") - tracker.track_views("name", "start", "finish", "id", identifier: "file") + tracker.track_key(identifier: "file") tracker.reset_recordings end - test "clear_file" do + test "clear_key" do Coverband::Collectors::ViewTracker.expects(:supported_version?).returns(true) store = fake_store file_path = "#{File.expand_path(Coverband.configuration.root)}/file" store.raw_store.expects(:hdel).with(tracker_key, file_path) tracker = Coverband::Collectors::ViewTracker.new(store: store, roots: "dir") - tracker.track_views("name", "start", "finish", "id", identifier: file_path) - tracker.clear_file!("file") - assert_equal [], tracker.logged_views + tracker.track_key(identifier: file_path) + tracker.clear_key!("file") + assert_equal [], tracker.logged_keys end protected diff --git a/views/route_tracker.erb b/views/route_tracker.erb index 7ee42865..019143a1 100644 --- a/views/route_tracker.erb +++ b/views/route_tracker.erb @@ -19,18 +19,18 @@ <%= button("#{base_path}clear_route_tracking", 'reset route tracker', delete: true) %> <% end %> -

Unused Routes: (<%= tracker.unused_routes.length %>)

+

Unused Routes: (<%= tracker.unused_keys.length %>)

These routes have not been rendered since recording started at <%= tracker.tracking_since %>

-

Used Routes: (<%= tracker.used_routes.length %>)

+

Used Routes: (<%= tracker.used_keys.length %>)

These routes have been rendered at least once