factory_sloth 1.3.0 → 1.3.1
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/CHANGELOG.md +8 -2
- data/lib/factory_sloth/code_mod.rb +35 -20
- data/lib/factory_sloth/color.rb +5 -1
- data/lib/factory_sloth/execution_check.rb +7 -3
- data/lib/factory_sloth/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1ca25fc42535f24034b3a52ddb2b88d9e64dbd68b83e2febb7ddb31679daa118
|
4
|
+
data.tar.gz: 92814709e951c1dc15040496ec1c5dea101f2bdcb8d58eb1298182a91a2df2f1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 188f7f29920ba9f868171c65c21e7e4611e8c8c9cf41eb229e3f1a17fb98c6c970a491051fac6b501b5544b4298cef22f42335e8306e93370225c9acedfe8182
|
7
|
+
data.tar.gz: dbc6452a523efb648d0f2d71594d883c469194164b86a8f2f16ece21a171e8d82bd2a8260072e777b731b1001ad9f0eb0c5f51ce1610ebf3f8cc67b7d19e4471
|
data/CHANGELOG.md
CHANGED
@@ -1,11 +1,17 @@
|
|
1
1
|
## [Unreleased]
|
2
2
|
|
3
|
+
## [1.3.1] - 2023-05-24
|
4
|
+
|
5
|
+
### Fixed
|
6
|
+
|
7
|
+
- Stop trying to patch lines with multiple create calls, which was unreliable
|
8
|
+
|
3
9
|
## [1.3.0] - 2023-05-22
|
4
10
|
|
5
11
|
### Added
|
6
12
|
|
7
|
-
-
|
8
|
-
-
|
13
|
+
- Nicer output
|
14
|
+
- Verbose mode
|
9
15
|
|
10
16
|
## [1.2.2] - 2023-05-18
|
11
17
|
|
@@ -22,17 +22,7 @@ module FactorySloth
|
|
22
22
|
def call
|
23
23
|
self.create_calls = CreateCallFinder.call(code: original_code)
|
24
24
|
|
25
|
-
|
26
|
-
# given spec file to tempfiles first, and then run them all in a single
|
27
|
-
# rspec call. However, this would make it impossible to use `--fail-fast`,
|
28
|
-
# and might make examples fail that are not as idempotent as they should be.
|
29
|
-
self.changed_create_calls =
|
30
|
-
create_calls.sort_by { |call| [-call.line, -call.column] }.select do |call|
|
31
|
-
build_result = try_patch(call, 'build')
|
32
|
-
next if build_result == ABORT
|
33
|
-
|
34
|
-
build_result == SUCCESS || try_patch(call, 'build_stubbed') == SUCCESS
|
35
|
-
end
|
25
|
+
self.changed_create_calls = find_changeable_create_calls
|
36
26
|
|
37
27
|
# validate whole spec after changes, e.g. to detect side-effects
|
38
28
|
self.ok = changed_create_calls.none? || begin
|
@@ -65,6 +55,27 @@ module FactorySloth
|
|
65
55
|
|
66
56
|
attr_writer :create_calls, :changed_create_calls, :ok, :path, :original_code, :patched_code
|
67
57
|
|
58
|
+
# Performance note: it might be faster to write ALL possible patches for a
|
59
|
+
# given spec file to tempfiles first, and then run them all in a single
|
60
|
+
# rspec call. However, this would make it impossible to use `--fail-fast`,
|
61
|
+
# and might make examples fail that are not as idempotent as they should be.
|
62
|
+
def find_changeable_create_calls
|
63
|
+
lines = create_calls.map(&:line)
|
64
|
+
|
65
|
+
self.changed_create_calls =
|
66
|
+
create_calls.sort_by { |call| [-call.line, -call.column] }.select do |call|
|
67
|
+
if lines.count(call.line) > 1
|
68
|
+
print_call_info(call, 'multiple create calls per line are unsupported, skipping')
|
69
|
+
next
|
70
|
+
end
|
71
|
+
|
72
|
+
build_result = try_patch(call, 'build')
|
73
|
+
next if build_result == ABORT
|
74
|
+
|
75
|
+
build_result == SUCCESS || try_patch(call, 'build_stubbed') == SUCCESS
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
68
79
|
def try_patch(call, base_variant)
|
69
80
|
variant = call.name.sub('create', base_variant)
|
70
81
|
FactorySloth.verbose && puts("#{link_to_call(call)}: trying #{variant} ...")
|
@@ -79,14 +90,14 @@ module FactorySloth
|
|
79
90
|
|
80
91
|
if result.success?
|
81
92
|
info = FactorySloth.dry_run ? 'can be replaced' : 'replaced'
|
82
|
-
|
93
|
+
print_call_info(call, "#{info} with #{variant}")
|
83
94
|
self.patched_code = new_patched_code
|
84
95
|
SUCCESS
|
85
96
|
elsif result.exitstatus == ExecutionCheck::FACTORY_UNUSED_CODE
|
86
|
-
|
97
|
+
print_call_info(call, "is never executed, skipping")
|
87
98
|
ABORT
|
88
99
|
elsif result.exitstatus == ExecutionCheck::FACTORY_PERSISTED_LATER_CODE
|
89
|
-
FactorySloth.verbose &&
|
100
|
+
FactorySloth.verbose && print_call_info("record is persisted later, skipping")
|
90
101
|
ABORT
|
91
102
|
end
|
92
103
|
end
|
@@ -100,13 +111,17 @@ module FactorySloth
|
|
100
111
|
ABORT = :ABORT # returned if there is no need to try other variants
|
101
112
|
SUCCESS = :SUCCESS
|
102
113
|
|
103
|
-
def
|
114
|
+
def print_call_info(call, message)
|
104
115
|
line_content = original_code[/\A(?:.*\R){#{call.line - 1}}\K.*/]
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
116
|
+
indentation = line_content[/^\s*/]
|
117
|
+
underline = Color.yellow('^' * call.name.size)
|
118
|
+
|
119
|
+
puts(
|
120
|
+
"#{link_to_call(call)}: #{call.name} #{message}",
|
121
|
+
" #{line_content.delete_prefix(indentation)}",
|
122
|
+
" #{' ' * (call.column - indentation.size)}#{underline}",
|
123
|
+
"",
|
124
|
+
)
|
110
125
|
end
|
111
126
|
|
112
127
|
def link_to_call(call)
|
data/lib/factory_sloth/color.rb
CHANGED
@@ -14,8 +14,12 @@ module FactorySloth::Color
|
|
14
14
|
private
|
15
15
|
|
16
16
|
def colorize(str, color_code)
|
17
|
-
return str unless
|
17
|
+
return str unless tty?
|
18
18
|
|
19
19
|
"\e[#{color_code}m#{str}\e[0m"
|
20
20
|
end
|
21
|
+
|
22
|
+
def tty?
|
23
|
+
$stdout.is_a?(IO) && $stdout.tty?
|
24
|
+
end
|
21
25
|
end
|
@@ -4,6 +4,10 @@
|
|
4
4
|
# The rationale behind a) is that things like skipped examples should not
|
5
5
|
# be broken. The rationale behind b) is that not much DB work would be saved,
|
6
6
|
# but diff noise would be increased and ease of editing the example reduced.
|
7
|
+
#
|
8
|
+
# Note: the caller column is only available in a roundabout way in Ruby >= 3.1,
|
9
|
+
# https://bugs.ruby-lang.org/issues/17930, 19452, so multiple replacements
|
10
|
+
# in one line would not be validated correctly iff they had mixed validity.
|
7
11
|
|
8
12
|
module FactorySloth::ExecutionCheck
|
9
13
|
FACTORY_UNUSED_CODE = 77
|
@@ -15,10 +19,10 @@ module FactorySloth::ExecutionCheck
|
|
15
19
|
records_by_line = {} # track records initialized through factories per line
|
16
20
|
|
17
21
|
FactoryBot::Syntax::Methods.class_eval do
|
18
|
-
|
22
|
+
original_variant = instance_method("#{variant}") # e.g. build
|
19
23
|
|
20
|
-
define_method("#{variant}") do |*args, **kwargs, &blk|
|
21
|
-
result =
|
24
|
+
define_method("#{variant}") do |*args, **kwargs, &blk|
|
25
|
+
result = original_variant.bind_call(self, *args, **kwargs, &blk)
|
22
26
|
list = records_by_line[caller_locations(1, 1)&.first&.lineno] ||= []
|
23
27
|
list.concat([result].flatten) # to work with single, list, and pair
|
24
28
|
result
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: factory_sloth
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.3.
|
4
|
+
version: 1.3.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Janosch Müller
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-05-
|
11
|
+
date: 2023-05-24 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description:
|
14
14
|
email:
|