gitlab-crystalball 0.7.2 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3059723052c6c3bfe9f58ee458b2ab15ef18aaf4227c4ec3a5eeefd53c8630e1
4
- data.tar.gz: 892c339d1bf8bbf599dba57b6bbf45b1f0ab8dfb1c41b2df1c279c22a6df8d24
3
+ metadata.gz: 7ec4fa9b1270e8b3aec30a4b7d5d10968278d7c588b3c954b3aff25dacadfa8a
4
+ data.tar.gz: ce71ab46817998338ef0cf7d19d52eae19a9b33ef663c0e63b920691bb990afb
5
5
  SHA512:
6
- metadata.gz: c9e81eef06568c4b5dd3c757d8507427d448cf48a7f050704c877abc23f5f7711f769e16f3ef75f08aa4797dd4c0fb2120dceb6ca1ce7add83cf7b73f6fcab27
7
- data.tar.gz: 71106979d5350594e4344d3404e9bc1bcc282b81c5180ca8e0e51ab73dbb7c760ab35402444e71fcb95cea6c258bf6dab756d6adfecc363b87c4c8ac6bf362a3
6
+ metadata.gz: 215d5ca4f23d09a63c0df24d125374bbe36a6730f3386defb0c2195ad804cdff2140d114edbb5dd6e686f1708daa9e88c89ef9098c231a9ac18a1c02378e86ad
7
+ data.tar.gz: 396ee4f17aadc5422bbe4da993e8ef7d7e2f7f246b154d7b0ce04b6bae9517294df2e382bac964390ab45795c806d768e2ccc8dad5b57c8ad4bd70d479745e5a
@@ -8,6 +8,7 @@ module Crystalball
8
8
  # Class for detecting code execution path based on coverage information diff
9
9
  class ExecutionDetector
10
10
  include ::Crystalball::MapGenerator::Helpers::PathFilter
11
+
11
12
  # Detects files affected during example execution. Transforms absolute paths to relative.
12
13
  # Exclude paths outside of repository
13
14
  #
@@ -15,7 +16,15 @@ module Crystalball
15
16
  # @param[Array<String>] list of files affected after example execution
16
17
  # @return [Array<String>]
17
18
  def detect(before, after)
18
- filter after.reject { |file_name, after_coverage| before[file_name] == after_coverage }.keys
19
+ after.filter_map do |file, coverage|
20
+ before_cov = before[file]&.fetch(:lines, [])
21
+ next if before_cov == coverage[:lines]
22
+
23
+ path = valid_path(file)
24
+ next unless path
25
+
26
+ path
27
+ end
19
28
  end
20
29
  end
21
30
  end
@@ -12,12 +12,12 @@ module Crystalball
12
12
 
13
13
  attr_reader :execution_detector
14
14
 
15
- def initialize(execution_detector = ExecutionDetector.new)
15
+ def initialize(execution_detector: ExecutionDetector.new)
16
16
  @execution_detector = execution_detector
17
17
  end
18
18
 
19
19
  def after_register
20
- Coverage.start unless Coverage.running?
20
+ Coverage.start(lines: true) unless Coverage.running?
21
21
  end
22
22
 
23
23
  # Adds to the example_map's used files the ones the ones in which
@@ -5,19 +5,38 @@ module Crystalball
5
5
  module Helpers
6
6
  # Helper module to filter file paths
7
7
  module PathFilter
8
- attr_reader :root_path
8
+ attr_reader :root_path, :exclude_prefixes
9
9
 
10
10
  # @param [String] root_path - absolute path to root folder of repository
11
- def initialize(root_path = Dir.pwd)
11
+ # @param [Array] exclude_prefixes - list of prefixes to filter out from paths
12
+ def initialize(root_path = Dir.pwd, exclude_prefixes: [])
12
13
  @root_path = root_path
14
+ @exclude_prefixes = exclude_prefixes
13
15
  end
14
16
 
15
17
  # @param [Array<String>] paths
16
- # @return relatve paths inside root_path only
18
+ # @return relative paths inside root_path only
17
19
  def filter(paths)
18
- paths
19
- .select { |file_name| file_name.start_with?(root_path) }
20
- .map { |file_name| file_name.sub("#{root_path}/", "") }
20
+ paths.filter_map do |path|
21
+ next unless path.start_with?(root_path)
22
+
23
+ valid_path(path)
24
+ end
25
+ end
26
+
27
+ private
28
+
29
+ # Return relative path if it is a valid path
30
+ #
31
+ # @param path [String]
32
+ # @return [<String, nil>]
33
+ def valid_path(path)
34
+ return unless path.start_with?(root_path)
35
+
36
+ relative_path = path.sub("#{root_path}/", "")
37
+ return if exclude_prefixes&.any? { |prefix| relative_path.start_with?(prefix) }
38
+
39
+ relative_path
21
40
  end
22
41
  end
23
42
  end
@@ -13,11 +13,12 @@ module Crystalball
13
13
  attr_reader :definition_tracer, :hierarchy_fetcher
14
14
 
15
15
  def initialize(
16
- root_path:,
16
+ root_path: Dir.pwd,
17
17
  definition_tracer: DefinitionTracer.new(root_path),
18
- hierarchy_fetcher: HierarchyFetcher.new
18
+ hierarchy_fetcher: HierarchyFetcher.new,
19
+ exclude_prefixes: []
19
20
  )
20
- super(root_path)
21
+ super(root_path, exclude_prefixes: exclude_prefixes)
21
22
 
22
23
  @definition_tracer = definition_tracer
23
24
  @hierarchy_fetcher = hierarchy_fetcher
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "coverage"
4
+ require "crystalball/map_generator/base_strategy"
5
+
6
+ require_relative "helpers/path_filter"
7
+
8
+ module Crystalball
9
+ class MapGenerator
10
+ # Map generator strategy based on harvesting Coverage information during example execution
11
+ class OneshotCoverageStrategy
12
+ include BaseStrategy
13
+ include Helpers::PathFilter
14
+
15
+ def after_register
16
+ raise "Coverage must not be started for oneshot_line strategy" if Coverage.running?
17
+ end
18
+
19
+ # Adds to the example_map's used files the ones the ones in which
20
+ # the coverage has changed after the tests runs.
21
+ # @param [Crystalball::ExampleGroupMap] example_map - object holding example metadata and used files
22
+ # @param [RSpec::Core::Example] example - a RSpec example
23
+ def call(example_map, example)
24
+ Coverage.start(oneshot_lines: true)
25
+ yield example_map, example
26
+ paths = Coverage.result.keys
27
+ example_map.push(*filter(paths))
28
+ end
29
+ end
30
+ end
31
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Crystalball
4
- VERSION = "0.7.2"
4
+ VERSION = "0.8.0"
5
5
  end
data/lib/crystalball.rb CHANGED
@@ -16,6 +16,7 @@ require "crystalball/execution_map"
16
16
  require "crystalball/map_generator"
17
17
  require "crystalball/map_generator/configuration"
18
18
  require "crystalball/map_generator/coverage_strategy"
19
+ require "crystalball/map_generator/oneshot_coverage_strategy"
19
20
  require "crystalball/map_generator/allocated_objects_strategy"
20
21
  require "crystalball/map_generator/described_class_strategy"
21
22
  require "crystalball/map_storage/yaml_storage"
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gitlab-crystalball
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.2
4
+ version: 0.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Developer Experience Team
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2025-05-08 00:00:00.000000000 Z
10
+ date: 2025-05-12 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: git
@@ -247,6 +247,7 @@ files:
247
247
  - lib/crystalball/map_generator/object_sources_detector.rb
248
248
  - lib/crystalball/map_generator/object_sources_detector/definition_tracer.rb
249
249
  - lib/crystalball/map_generator/object_sources_detector/hierarchy_fetcher.rb
250
+ - lib/crystalball/map_generator/oneshot_coverage_strategy.rb
250
251
  - lib/crystalball/map_generator/parser_strategy.rb
251
252
  - lib/crystalball/map_generator/parser_strategy/processor.rb
252
253
  - lib/crystalball/map_generator/strategies_collection.rb