factory_trace 2.0.0 → 3.0.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 +4 -4
- data/lib/factory_trace/configuration.rb +2 -1
- data/lib/factory_trace/fixture_tracker.rb +25 -0
- data/lib/factory_trace/monkey_patches/dsl.rb +2 -2
- data/lib/factory_trace/monkey_patches/monkey_patches.rb +0 -1
- data/lib/factory_trace/preprocessors/extract_defined.rb +1 -1
- data/lib/factory_trace/preprocessors/extract_defined_fixtures.rb +58 -0
- data/lib/factory_trace/version.rb +1 -1
- data/lib/factory_trace/writers/report_writer.rb +19 -6
- data/lib/factory_trace/writers/trace_writer.rb +8 -1
- data/lib/factory_trace.rb +37 -5
- metadata +19 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: bd70e8ea6fe8ffb3e815147ea925478d36f4d298b9bbbd5b359b7d5e900d5265
|
|
4
|
+
data.tar.gz: e838d1f5525179c4fba7fa6daba3baf7ab8b23d27e981076069c3a4d33268472
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 0a0b4c5d0b471d570a4ab18567feed01559f861363779e4ba5010e8eb1b1a75a159d3affe54b0742da8c1909095df14cee0ec45eb7fbefcf3e594b8a58140037
|
|
7
|
+
data.tar.gz: 54b1804ed50d4ba0f327e9f18d100ad9c95c39c7ce6a373ed846aa5bbf8c6a9e7f5b42560db21b7922927aa135574a8f6d1acef6b39179b56bc911ba00dba151
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
module FactoryTrace
|
|
4
4
|
class Configuration
|
|
5
|
-
attr_accessor :path, :enabled, :color, :mode, :trace_definition
|
|
5
|
+
attr_accessor :path, :enabled, :color, :mode, :trace_definition, :fixture_path
|
|
6
6
|
|
|
7
7
|
def initialize
|
|
8
8
|
@enabled = ENV.key?("FB_TRACE") || ENV.key?("FB_TRACE_FILE")
|
|
@@ -10,6 +10,7 @@ module FactoryTrace
|
|
|
10
10
|
@color = path.nil?
|
|
11
11
|
@mode = extract_mode(ENV["FB_TRACE"]) || :full
|
|
12
12
|
@trace_definition = true
|
|
13
|
+
@fixture_path = "test/fixtures"
|
|
13
14
|
end
|
|
14
15
|
|
|
15
16
|
def trace_definition?
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module FactoryTrace
|
|
4
|
+
class FixtureTracker
|
|
5
|
+
attr_reader :storage
|
|
6
|
+
|
|
7
|
+
def initialize
|
|
8
|
+
@storage = {}
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def track!
|
|
12
|
+
tracker_storage = @storage
|
|
13
|
+
|
|
14
|
+
::ActiveRecord::FixtureSet.prepend(Module.new do
|
|
15
|
+
define_method(:[]) do |fixture_name|
|
|
16
|
+
if fixture_name
|
|
17
|
+
tracker_storage[name] ||= Set.new
|
|
18
|
+
tracker_storage[name].add(fixture_name.to_s)
|
|
19
|
+
end
|
|
20
|
+
super(fixture_name)
|
|
21
|
+
end
|
|
22
|
+
end)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -10,7 +10,7 @@ module FactoryTrace
|
|
|
10
10
|
proxy = FactoryBot::DefinitionProxy.new(factory.definition)
|
|
11
11
|
proxy.instance_eval(&block) if block
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
FactoryTrace.factory_bot_register.register_factory(factory)
|
|
14
14
|
|
|
15
15
|
proxy.child_factories.each do |(child_name, child_caller_location, child_options, child_block)|
|
|
16
16
|
parent_factory = child_options.delete(:parent) || name
|
|
@@ -19,7 +19,7 @@ module FactoryTrace
|
|
|
19
19
|
end
|
|
20
20
|
|
|
21
21
|
def trait(name, &block)
|
|
22
|
-
|
|
22
|
+
FactoryTrace.factory_bot_register.register_trait(FactoryBot::Trait.new(name, Helpers::Caller.location, &block))
|
|
23
23
|
end
|
|
24
24
|
end
|
|
25
25
|
end
|
|
@@ -7,7 +7,7 @@ module FactoryTrace
|
|
|
7
7
|
def self.call
|
|
8
8
|
collection = FactoryTrace::Structures::Collection.new
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
FactoryTrace.factory_bot_register.traits.each do |trait|
|
|
11
11
|
collection.add(FactoryTrace::Helpers::Converter.trait(trait))
|
|
12
12
|
end
|
|
13
13
|
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module FactoryTrace
|
|
4
|
+
module Preprocessors
|
|
5
|
+
class ExtractDefinedFixtures
|
|
6
|
+
# Extracts all defined fixture sets and their entries from fixture YAML files
|
|
7
|
+
#
|
|
8
|
+
# @param [String, Array<String>] fixture_path path(s) to directories containing fixture YAML files
|
|
9
|
+
#
|
|
10
|
+
# @return [FactoryTrace::Structures::Collection]
|
|
11
|
+
def self.call(fixture_path)
|
|
12
|
+
collection = FactoryTrace::Structures::Collection.new
|
|
13
|
+
|
|
14
|
+
Array(fixture_path).each do |path|
|
|
15
|
+
Dir.glob(File.join(path, "**", "*.yml")).sort.each do |file|
|
|
16
|
+
fixture_set_name = File.basename(file, ".yml")
|
|
17
|
+
entries = parse_fixture_file(file)
|
|
18
|
+
|
|
19
|
+
traits = entries.map do |entry_name, definition_path|
|
|
20
|
+
FactoryTrace::Structures::Trait.new(entry_name, definition_path: definition_path)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
factory = FactoryTrace::Structures::Factory.new(
|
|
24
|
+
[fixture_set_name],
|
|
25
|
+
traits,
|
|
26
|
+
definition_path: "#{file}:1"
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
collection.add(factory)
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
collection
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Parses a fixture YAML file and returns a hash of entry names to definition paths
|
|
37
|
+
#
|
|
38
|
+
# @param [String] file_path
|
|
39
|
+
#
|
|
40
|
+
# @return [Hash<String, String>]
|
|
41
|
+
def self.parse_fixture_file(file_path)
|
|
42
|
+
entries = {}
|
|
43
|
+
lineno = 1
|
|
44
|
+
|
|
45
|
+
File.foreach(file_path) do |line|
|
|
46
|
+
if (match = line.match(/\A(\w+):(?:\s|$)/))
|
|
47
|
+
entries[match[1]] = "#{file_path}:#{lineno}"
|
|
48
|
+
end
|
|
49
|
+
lineno += 1
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
entries
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
private_class_method :parse_fixture_file
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
@@ -16,11 +16,14 @@ module FactoryTrace
|
|
|
16
16
|
}.freeze
|
|
17
17
|
|
|
18
18
|
# @param [Array<Hash>] results
|
|
19
|
-
|
|
19
|
+
# @param [Symbol] kind - :factory (default) or :fixture
|
|
20
|
+
def write(results, kind:)
|
|
21
|
+
io.puts("")
|
|
22
|
+
|
|
20
23
|
total_color = (results.any? { |result| result[:code] == :unused && !result.key?(:value) }) ? :red : :green
|
|
21
24
|
|
|
22
25
|
results.each do |result|
|
|
23
|
-
io.puts(convert(result, total_color: total_color))
|
|
26
|
+
io.puts(convert(result, total_color: total_color, kind: kind))
|
|
24
27
|
end
|
|
25
28
|
end
|
|
26
29
|
|
|
@@ -28,13 +31,23 @@ module FactoryTrace
|
|
|
28
31
|
|
|
29
32
|
# @param [Hash<Symbol, Object>] result
|
|
30
33
|
# @param [Symbol] total_color
|
|
31
|
-
|
|
34
|
+
# @param [Symbol] kind - :factory_bot or :fixtures
|
|
35
|
+
def convert(result, total_color:, kind:)
|
|
32
36
|
if result[:value]
|
|
33
|
-
|
|
37
|
+
label = (kind == :fixtures) ? "fixture sets & entries" : "factories & traits"
|
|
38
|
+
colorize(total_color, "total number of unique #{humanize_code(result[:code])} #{label}: #{result[:value]}")
|
|
34
39
|
elsif result[:factory_names] && result[:trait_name]
|
|
35
|
-
|
|
40
|
+
if kind == :fixtures
|
|
41
|
+
append_definition_path(result) { "#{humanize_code(result[:code])} fixture entry #{colorize(:blue, result[:trait_name])} of fixture set #{list(result[:factory_names])}" }
|
|
42
|
+
else
|
|
43
|
+
append_definition_path(result) { "#{humanize_code(result[:code])} trait #{colorize(:blue, result[:trait_name])} of factory #{list(result[:factory_names])}" }
|
|
44
|
+
end
|
|
36
45
|
elsif result[:factory_names]
|
|
37
|
-
|
|
46
|
+
if kind == :fixtures
|
|
47
|
+
append_definition_path(result) { "#{humanize_code(result[:code])} fixture set #{list(result[:factory_names])}" }
|
|
48
|
+
else
|
|
49
|
+
append_definition_path(result) { "#{humanize_code(result[:code])} factory #{list(result[:factory_names])}" }
|
|
50
|
+
end
|
|
38
51
|
else
|
|
39
52
|
append_definition_path(result) { "#{humanize_code(result[:code])} global trait #{colorize(:blue, result[:trait_name])}" }
|
|
40
53
|
end
|
|
@@ -5,7 +5,14 @@ module FactoryTrace
|
|
|
5
5
|
class TraceWriter < Writer
|
|
6
6
|
# @param [FactoryTrace::Structures::Collection] defined
|
|
7
7
|
# @param [FactoryTrace::Structures::Collection] used
|
|
8
|
-
def write(defined, used)
|
|
8
|
+
def write(defined, used, kind:)
|
|
9
|
+
io.puts("")
|
|
10
|
+
text =
|
|
11
|
+
case kind
|
|
12
|
+
when :factory_bot then "FactoryBot"
|
|
13
|
+
when :fixtures then "Fixtures"
|
|
14
|
+
end
|
|
15
|
+
io.puts("#{text} definitions and usages:")
|
|
9
16
|
io.puts(JSON.pretty_generate(defined: defined.to_h, used: used.to_h))
|
|
10
17
|
end
|
|
11
18
|
end
|
data/lib/factory_trace.rb
CHANGED
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
# External dependencies
|
|
4
4
|
require "active_support"
|
|
5
|
-
require "factory_bot"
|
|
6
5
|
require "json"
|
|
7
6
|
require "set"
|
|
8
7
|
require "pathname"
|
|
@@ -13,6 +12,7 @@ require "factory_trace/helpers/converter"
|
|
|
13
12
|
require "factory_trace/helpers/statusable"
|
|
14
13
|
require "factory_trace/helpers/caller"
|
|
15
14
|
require "factory_trace/tracker"
|
|
15
|
+
require "factory_trace/fixture_tracker"
|
|
16
16
|
|
|
17
17
|
require "factory_trace/structures/factory"
|
|
18
18
|
require "factory_trace/structures/trait"
|
|
@@ -20,6 +20,7 @@ require "factory_trace/structures/collection"
|
|
|
20
20
|
|
|
21
21
|
require "factory_trace/preprocessors/extract_defined"
|
|
22
22
|
require "factory_trace/preprocessors/extract_used"
|
|
23
|
+
require "factory_trace/preprocessors/extract_defined_fixtures"
|
|
23
24
|
|
|
24
25
|
require "factory_trace/processors/find_unused"
|
|
25
26
|
|
|
@@ -44,19 +45,24 @@ module FactoryTrace
|
|
|
44
45
|
return unless configuration.enabled
|
|
45
46
|
trace_definitions! if configuration.trace_definition?
|
|
46
47
|
|
|
47
|
-
tracker.track!
|
|
48
|
+
tracker.track! if factory_bot?
|
|
49
|
+
fixture_tracker.track! if fixtures?
|
|
48
50
|
end
|
|
49
51
|
|
|
50
52
|
def stop
|
|
51
53
|
return unless configuration.enabled
|
|
52
54
|
|
|
53
55
|
# This is required to exclude parent traits from +defined_traits+
|
|
54
|
-
FactoryBot.reload
|
|
56
|
+
FactoryBot.reload if factory_bot?
|
|
55
57
|
|
|
56
58
|
if configuration.mode?(:full)
|
|
57
|
-
Writers::ReportWriter.new(configuration.out, configuration)
|
|
59
|
+
writer = Writers::ReportWriter.new(configuration.out, configuration)
|
|
60
|
+
writer.write(Processors::FindUnused.call(defined, used), kind: :factory_bot) if factory_bot?
|
|
61
|
+
writer.write(Processors::FindUnused.call(defined_fixtures, used_fixtures), kind: :fixtures) if fixtures?
|
|
58
62
|
elsif configuration.mode?(:trace_only)
|
|
59
|
-
Writers::TraceWriter.new(configuration.out, configuration)
|
|
63
|
+
writer = Writers::TraceWriter.new(configuration.out, configuration)
|
|
64
|
+
writer.write(defined, used, kind: :factory_bot) if factory_bot?
|
|
65
|
+
writer.write(defined_fixtures, used_fixtures, kind: :fixtures) if fixtures?
|
|
60
66
|
end
|
|
61
67
|
end
|
|
62
68
|
|
|
@@ -68,6 +74,10 @@ module FactoryTrace
|
|
|
68
74
|
@configuration ||= Configuration.new
|
|
69
75
|
end
|
|
70
76
|
|
|
77
|
+
def factory_bot_register
|
|
78
|
+
@factory_bot_register ||= (FactoryBot::VERSION >= "5.1.0") ? FactoryBot::Internal : FactoryBot
|
|
79
|
+
end
|
|
80
|
+
|
|
71
81
|
private
|
|
72
82
|
|
|
73
83
|
def used
|
|
@@ -82,7 +92,29 @@ module FactoryTrace
|
|
|
82
92
|
@tracker ||= Tracker.new
|
|
83
93
|
end
|
|
84
94
|
|
|
95
|
+
def fixture_tracker
|
|
96
|
+
@fixture_tracker ||= FixtureTracker.new
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def defined_fixtures
|
|
100
|
+
@defined_fixtures ||= Preprocessors::ExtractDefinedFixtures.call(configuration.fixture_path)
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def used_fixtures
|
|
104
|
+
@used_fixtures ||= Preprocessors::ExtractUsed.call(fixture_tracker.storage)
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def factory_bot?
|
|
108
|
+
defined?(FactoryBot)
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def fixtures?
|
|
112
|
+
defined?(ActiveRecord::FixtureSet)
|
|
113
|
+
end
|
|
114
|
+
|
|
85
115
|
def trace_definitions!
|
|
116
|
+
return unless factory_bot?
|
|
117
|
+
|
|
86
118
|
FactoryBot::Factory.prepend(FactoryTrace::MonkeyPatches::Factory)
|
|
87
119
|
FactoryBot::Trait.prepend(FactoryTrace::MonkeyPatches::Trait)
|
|
88
120
|
FactoryBot::Syntax::Default::DSL.prepend(FactoryTrace::MonkeyPatches::Default::DSL)
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: factory_trace
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 3.0.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- djezzzl
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-03-
|
|
11
|
+
date: 2026-03-18 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: factory_bot
|
|
@@ -17,7 +17,21 @@ dependencies:
|
|
|
17
17
|
- - ">="
|
|
18
18
|
- !ruby/object:Gem::Version
|
|
19
19
|
version: '4.0'
|
|
20
|
-
type: :
|
|
20
|
+
type: :development
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - ">="
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '4.0'
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: activerecord
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - ">="
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: '4.0'
|
|
34
|
+
type: :development
|
|
21
35
|
prerelease: false
|
|
22
36
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
37
|
requirements:
|
|
@@ -91,6 +105,7 @@ files:
|
|
|
91
105
|
- exe/factory_trace
|
|
92
106
|
- lib/factory_trace.rb
|
|
93
107
|
- lib/factory_trace/configuration.rb
|
|
108
|
+
- lib/factory_trace/fixture_tracker.rb
|
|
94
109
|
- lib/factory_trace/helpers/caller.rb
|
|
95
110
|
- lib/factory_trace/helpers/converter.rb
|
|
96
111
|
- lib/factory_trace/helpers/statusable.rb
|
|
@@ -100,6 +115,7 @@ files:
|
|
|
100
115
|
- lib/factory_trace/monkey_patches/monkey_patches.rb
|
|
101
116
|
- lib/factory_trace/monkey_patches/trait.rb
|
|
102
117
|
- lib/factory_trace/preprocessors/extract_defined.rb
|
|
118
|
+
- lib/factory_trace/preprocessors/extract_defined_fixtures.rb
|
|
103
119
|
- lib/factory_trace/preprocessors/extract_used.rb
|
|
104
120
|
- lib/factory_trace/processors/find_unused.rb
|
|
105
121
|
- lib/factory_trace/readers/trace_reader.rb
|