Module: DeepCover::Base
- Included in:
- DeepCover
- Defined in:
- lib/deep_cover/base.rb
Instance Method Summary collapse
- #all_tracked_file_paths ⇒ Object
-
#auto_detected_paths ⇒ Object
Auto detects path that we want to cover.
- #autoload_tracker ⇒ Object
- #config_changed(what) ⇒ Object
- #cover(paths: nil) ⇒ Object
- #coverage ⇒ Object
- #covered_code(filename) ⇒ Object
- #custom_requirer ⇒ Object
- #delete_trackers ⇒ Object
- #line_coverage(filename) ⇒ Object
- #lookup_globs ⇒ Object
- #persistence ⇒ Object
- #reset ⇒ Object
- #running? ⇒ Boolean
- #start ⇒ Object
- #stop ⇒ Object
- #tracked_file_path?(path) ⇒ Boolean
Instance Method Details
#all_tracked_file_paths ⇒ Object
157 158 159 160 161 162 163 164 165 |
# File 'lib/deep_cover/base.rb', line 157 def all_tracked_file_paths return @all_tracked_file_paths.dup if @all_tracked_file_paths paths_found = Dir[*lookup_globs] paths_found.select! { |path| path.end_with?('.rb') } paths_found.select! { |path| File.file?(path) } paths_found.uniq! @all_tracked_file_paths = paths_found @all_tracked_file_paths.dup end |
#auto_detected_paths ⇒ Object
Auto detects path that we want to cover. This is used when :auto_detect is in the config.paths. If the results aren’t what you expect, then specify the paths yourself. We want this to work for most project’s struture:
-
Single gems: just a gem directly in the top-level
-
Multi gems: contains multiple gems, each in a dir of the top-level dir (the rails gem does that)
-
Hybrid gems: a gem in the top-level dir and one in sub-dirs (the deep-cover gem does that)
-
Rails application
For gems and Rails application, normally, everything to check coverage for is in lib/, and app/. For other projects, we go for every directories except test/ spec/ bin/ exe/.
If the current dir has a .gemspec file, we consider it a “root”. In addition, if any sub-dir of the current dir (not recursive) has a .gemspec file, we also consider them as “roots” If the current dir looks like a Rails application, add it as a “root” For each “roots”, the “tracked dirs” will be “#Top Level Namespace/app” and “#Top Level Namespace/lib”
If no “tracked dirs” exist, fallback to everything in current directory except each of test/ spec/ bin/ exe/.
126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 |
# File 'lib/deep_cover/base.rb', line 126 def auto_detected_paths require_relative 'tools/looks_like_rails_project' gemspec_paths = Dir['./*.gemspec'] + Dir['./*/*.gemspec'] root_paths = gemspec_paths.map!(&File.method(:dirname)) root_paths.uniq! root_paths << '.' if !root_paths.include?('.') && Tools::LooksLikeRailsProject.looks_like_rails_project?('.') tracked_paths = root_paths.flat_map { |p| [File.join(p, 'app'), File.join(p, 'lib')] } tracked_paths.select! { |p| File.exist?(p) } if tracked_paths.empty? # So track every sub-dirs except a couple # The final '/' in Dir[] makes it return directories only, but they will also end with a '/' # So need to include that last '/' in the substracted paths. # TODO: We probably want a cleaner way of filtering out some directories. But for now, that's what we got. tracked_paths = Dir['./*/'] - %w(./autotest/ ./features/ ./spec/ ./test/ ./bin/ ./exe/) # And track every ruby files in the top-level tracked_paths << './*.rb' end tracked_paths # path expansion is done in #lookup_globs end |
#autoload_tracker ⇒ Object
171 172 173 |
# File 'lib/deep_cover/base.rb', line 171 def autoload_tracker @autoload_tracker ||= AutoloadTracker.new end |
#config_changed(what) ⇒ Object
68 69 70 71 72 73 74 75 76 77 |
# File 'lib/deep_cover/base.rb', line 68 def config_changed(what) case what when :paths warn "Changing DeepCover's paths after starting coverage is highly discouraged" if running? @lookup_globs = @all_tracked_file_paths = nil when :tracker_global raise NotImplementedError, "Changing DeepCover's tracker global after starting coverage is not supported" if running? @coverage = nil end end |
#cover(paths: nil) ⇒ Object
56 57 58 59 60 61 62 63 64 65 66 |
# File 'lib/deep_cover/base.rb', line 56 def cover(paths: nil) if paths prev = config.paths config.paths(paths) end start yield ensure stop config.paths(prev) if paths end |
#coverage ⇒ Object
86 87 88 |
# File 'lib/deep_cover/base.rb', line 86 def coverage @coverage ||= Coverage.new end |
#covered_code(filename) ⇒ Object
52 53 54 |
# File 'lib/deep_cover/base.rb', line 52 def covered_code(filename) coverage.covered_code(handle_relative_filename(filename)) end |
#custom_requirer ⇒ Object
167 168 169 |
# File 'lib/deep_cover/base.rb', line 167 def custom_requirer @custom_requirer ||= CustomRequirer.new end |
#delete_trackers ⇒ Object
44 45 46 |
# File 'lib/deep_cover/base.rb', line 44 def delete_trackers persistence.delete_trackers end |
#line_coverage(filename) ⇒ Object
48 49 50 |
# File 'lib/deep_cover/base.rb', line 48 def line_coverage(filename) coverage.line_coverage(handle_relative_filename(filename), **config.to_h) end |
#lookup_globs ⇒ Object
90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 |
# File 'lib/deep_cover/base.rb', line 90 def lookup_globs return @lookup_globs if @lookup_globs paths = Array(config.paths || :auto_detect).dup paths.concat(auto_detected_paths) if paths.delete(:auto_detect) paths = paths.map { |p| File.(p) } paths = ['/'] if paths.include?('/') globs = paths.map! do |path| if File.directory?(path) # File.join is needed to avoid //**/*.rb File.join(path, '**/*.rb') else # Either a single file's path, a glob, or a path that doesn't exists path end end @lookup_globs = globs end |
#persistence ⇒ Object
175 176 177 |
# File 'lib/deep_cover/base.rb', line 175 def persistence @persistence ||= Persistence.new(config.cache_directory) end |
#reset ⇒ Object
79 80 81 82 83 84 |
# File 'lib/deep_cover/base.rb', line 79 def reset stop if running? @coverage = @custom_requirer = @autoload_tracker = @lookup_globs = @all_tracked_file_paths = nil config.reset self end |
#running? ⇒ Boolean
5 6 7 |
# File 'lib/deep_cover/base.rb', line 5 def running? @started ||= false # rubocop:disable Naming/MemoizedInstanceVariableName [#5648] end |
#start ⇒ Object
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
# File 'lib/deep_cover/base.rb', line 9 def start return if running? if defined?(RUBY_ENGINE) && RUBY_ENGINE == 'jruby' # Autoload is not supported in JRuby. We currently need to use binding_of_caller # and that is not available in JRuby. An extension may be able to replace this requirement. # require_relative 'core_ext/autoload_overrides' # AutoloadOverride.active = true require_relative 'core_ext/load_overrides' require_relative 'core_ext/require_overrides' LoadOverride.active = RequireOverride.active = true elsif RUBY_VERSION >= '2.3.0' require_relative 'core_ext/instruction_sequence_load_iseq' else require_relative 'core_ext/autoload_overrides' require_relative 'core_ext/load_overrides' require_relative 'core_ext/require_overrides' AutoloadOverride.active = LoadOverride.active = RequireOverride.active = true autoload_tracker.initialize_autoloaded_paths { |mod, name, path| mod.autoload_without_deep_cover(name, path) } end config # actualize configuration @lookup_globs = @all_tracked_file_paths = nil @started = true end |
#stop ⇒ Object
34 35 36 37 38 39 40 41 42 |
# File 'lib/deep_cover/base.rb', line 34 def stop if defined? AutoloadOverride AutoloadOverride.active = false autoload_tracker.remove_interceptors { |mod, name, path| mod.autoload_without_deep_cover(name, path) } end RequireOverride.active = false if defined? RequireOverride @started = false end |
#tracked_file_path?(path) ⇒ Boolean
150 151 152 153 154 155 |
# File 'lib/deep_cover/base.rb', line 150 def tracked_file_path?(path) # The flags are to make fnmatch match the same things as Dir.glob... This doesn't seem to be documented anywhere # EXTGLOB: allow matching {lib,app} as either lib or app # PATHNAME: Makes wildcard match not match /, and make /**/ (and pattern starting with **/) be any number of nested directory lookup_globs.any? { |glob| File.fnmatch?(glob, path, File::FNM_EXTGLOB | File::FNM_PATHNAME) } end |