tldr 0.4.0 → 0.5.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/CHANGELOG.md +9 -1
- data/README.md +22 -1
- data/lib/tldr/argv_parser.rb +4 -8
- data/lib/tldr/parallelizer.rb +10 -4
- data/lib/tldr/path_util.rb +41 -0
- data/lib/tldr/planner.rb +6 -44
- data/lib/tldr/rake.rb +40 -3
- data/lib/tldr/reporters/default.rb +1 -1
- data/lib/tldr/reporters/icon_provider.rb +8 -0
- data/lib/tldr/runner.rb +1 -1
- data/lib/tldr/strategizer.rb +14 -4
- data/lib/tldr/value/config.rb +54 -31
- data/lib/tldr/version.rb +1 -1
- data/lib/tldr.rb +1 -0
- metadata +4 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 32f7b9dbcf9e09433eef762eaafe19804643aa543ac2c0a9599303ea2e960f25
|
|
4
|
+
data.tar.gz: 789c07fb2db1fad39b234976999b575a1bea27c4796a4d062a373df11d3716e5
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 7975ec24ae3f080ed564666c5319928964c970794a740a21253551be1be9b945374394b2f860cdd8737151f8e21fdb0d592c126895dd02b91dd21c899824226a
|
|
7
|
+
data.tar.gz: b11f3c52624b63a7aa44eadd4f17aa662d134648d61eb55eb7124e7956d0b28f20a04545552f9af8710330ffa98c94e85cec87dc80715a532522ccdeb15a8b42
|
data/CHANGELOG.md
CHANGED
|
@@ -1,4 +1,12 @@
|
|
|
1
|
-
## [
|
|
1
|
+
## [0.5.0]
|
|
2
|
+
|
|
3
|
+
* Define your own Rake tasks with `TLDR::Task` and pass in a custom configuration
|
|
4
|
+
* Any tests with `--prepend` AND marked thread-unsafe with `dont_run_these_in_parallel`
|
|
5
|
+
will be run BEFORE the parallel tests start running. This way if you're working
|
|
6
|
+
on a non-parallelizable test, running `tldr` will automatically run it first
|
|
7
|
+
thing
|
|
8
|
+
* Stop printing `--seed` in run commands, since it can be confusing to discover
|
|
9
|
+
that will disable `--parallel`. Instead, print the seed option beneath
|
|
2
10
|
|
|
3
11
|
## [0.4.0]
|
|
4
12
|
|
data/README.md
CHANGED
|
@@ -181,6 +181,27 @@ You could then run the task with:
|
|
|
181
181
|
$ TLDR_OPTS="--no-parallel" bundle exec rake tldr
|
|
182
182
|
```
|
|
183
183
|
|
|
184
|
+
One reason you'd want to invoke TLDR with Rake is because you have multiple
|
|
185
|
+
test suites that you want to be able to conveniently run separately ([this
|
|
186
|
+
talk](https://blog.testdouble.com/talks/2014-05-25-breaking-up-with-your-test-suite/)
|
|
187
|
+
discussed a few reasons why this can be useful).
|
|
188
|
+
|
|
189
|
+
To create a custom TLDR Rake test, just instantiate `TLDR::Task` like this:
|
|
190
|
+
|
|
191
|
+
```ruby
|
|
192
|
+
require "tldr/rake"
|
|
193
|
+
|
|
194
|
+
TLDR::Task.new(name: :safe_tests, config: TLDR::Config.new(
|
|
195
|
+
paths: FileList["safe/**/*_test.rb"],
|
|
196
|
+
helper: "safe/helper.rb",
|
|
197
|
+
load_paths: ["lib", "safe"]
|
|
198
|
+
))
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
The above will create a second Rake task named `safe_tests` running a different
|
|
202
|
+
set of tests than the default `tldr` task. Here's [an
|
|
203
|
+
example](/example/b/Rakefile).
|
|
204
|
+
|
|
184
205
|
### Running tests without the CLI
|
|
185
206
|
|
|
186
207
|
If you'd rather use TLDR by running Ruby files instead of the `tldr` CLI
|
|
@@ -207,7 +228,7 @@ $ ruby test/some_test.rb
|
|
|
207
228
|
|
|
208
229
|
To maximize control and to avoid running code accidentally (and _unlike_ the
|
|
209
230
|
`tldr` CLI), running `at_exit!` will not set default values to the `paths`,
|
|
210
|
-
`helper`, `load_paths`, and `
|
|
231
|
+
`helper`, `load_paths`, and `prepend_paths` config properties. You'll have to
|
|
211
232
|
pass any values you want to set on a [Config object](/lib/tldr/value/config.rb)
|
|
212
233
|
and pass it to `at_exit!`.
|
|
213
234
|
|
data/lib/tldr/argv_parser.rb
CHANGED
|
@@ -4,11 +4,7 @@ class TLDR
|
|
|
4
4
|
class ArgvParser
|
|
5
5
|
PATTERN_FRIENDLY_SPLITTER = /,(?=(?:[^\/]*\/[^\/]*\/)*[^\/]*$)/
|
|
6
6
|
|
|
7
|
-
def parse(args)
|
|
8
|
-
options = {
|
|
9
|
-
cli_mode: true
|
|
10
|
-
}
|
|
11
|
-
|
|
7
|
+
def parse(args, options = {cli_defaults: true})
|
|
12
8
|
OptionParser.new do |opts|
|
|
13
9
|
opts.banner = "Usage: tldr [options] some_tests/**/*.rb some/path.rb:13 ..."
|
|
14
10
|
|
|
@@ -47,9 +43,9 @@ class TLDR
|
|
|
47
43
|
options[:no_helper] = true
|
|
48
44
|
end
|
|
49
45
|
|
|
50
|
-
opts.on "#{CONFLAGS[:
|
|
51
|
-
options[:
|
|
52
|
-
options[:
|
|
46
|
+
opts.on "#{CONFLAGS[:prepend_paths]} PATH", Array, "Prepend one or more paths to run before the rest (Default: most recently modified test)" do |prepend|
|
|
47
|
+
options[:prepend_paths] ||= []
|
|
48
|
+
options[:prepend_paths] += prepend
|
|
53
49
|
end
|
|
54
50
|
|
|
55
51
|
opts.on CONFLAGS[:no_prepend], "Don't prepend any tests before the rest of the suite" do
|
data/lib/tldr/parallelizer.rb
CHANGED
|
@@ -8,12 +8,18 @@ class TLDR
|
|
|
8
8
|
)
|
|
9
9
|
end
|
|
10
10
|
|
|
11
|
-
def parallelize all_tests,
|
|
12
|
-
return run_in_sequence(all_tests, &blk) if all_tests.size < 2 || !parallel
|
|
11
|
+
def parallelize all_tests, config, &blk
|
|
12
|
+
return run_in_sequence(all_tests, &blk) if all_tests.size < 2 || !config.parallel
|
|
13
13
|
|
|
14
|
-
strategy = @strategizer.strategize
|
|
14
|
+
strategy = @strategizer.strategize(
|
|
15
|
+
all_tests,
|
|
16
|
+
GROUPED_TESTS,
|
|
17
|
+
THREAD_UNSAFE_TESTS,
|
|
18
|
+
(config.no_prepend ? [] : config.prepend_paths)
|
|
19
|
+
)
|
|
15
20
|
|
|
16
|
-
|
|
21
|
+
run_in_sequence(strategy.prepend_thread_unsafe_tests, &blk) +
|
|
22
|
+
run_in_parallel(strategy.parallel_tests_and_groups, &blk) +
|
|
17
23
|
run_in_sequence(strategy.thread_unsafe_tests, &blk)
|
|
18
24
|
end
|
|
19
25
|
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
class TLDR
|
|
2
|
+
module PathUtil
|
|
3
|
+
def self.expand_search_locations path_strings
|
|
4
|
+
path_strings.flat_map { |path_string|
|
|
5
|
+
File.directory?(path_string) ? Dir["#{path_string}/**/*.rb"] : path_string
|
|
6
|
+
}.flat_map { |path_string|
|
|
7
|
+
absolute_path = File.expand_path(path_string.gsub(/:.*$/, ""), Dir.pwd)
|
|
8
|
+
line_numbers = path_string.scan(/:(\d+)/).flatten.map(&:to_i)
|
|
9
|
+
|
|
10
|
+
if line_numbers.any?
|
|
11
|
+
line_numbers.map { |line_number| Location.new absolute_path, line_number }
|
|
12
|
+
else
|
|
13
|
+
[Location.new(absolute_path, nil)]
|
|
14
|
+
end
|
|
15
|
+
}.uniq
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# Because search paths to TLDR can include line numbers (e.g. a.rb:4), we
|
|
19
|
+
# can't just pass everything to Dir.glob. Instead, we have to check whether
|
|
20
|
+
# a user-provided search path looks like a glob, and if so, expand it
|
|
21
|
+
#
|
|
22
|
+
# Globby characters specified here:
|
|
23
|
+
# https://ruby-doc.org/3.2.2/Dir.html#method-c-glob
|
|
24
|
+
def self.expand_globs search_paths
|
|
25
|
+
search_paths.flat_map { |search_path|
|
|
26
|
+
if search_path.match?(/[*?\[\]{}]/)
|
|
27
|
+
raise Error, "Can't combine globs and line numbers in: #{search_path}" if search_path.match?(/:(\d+)$/)
|
|
28
|
+
Dir[search_path]
|
|
29
|
+
else
|
|
30
|
+
search_path
|
|
31
|
+
end
|
|
32
|
+
}
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def self.locations_include_test? locations, test
|
|
36
|
+
locations.any? { |location|
|
|
37
|
+
location.file == test.file && (location.line.nil? || test.covers_line?(location.line))
|
|
38
|
+
}
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
data/lib/tldr/planner.rb
CHANGED
|
@@ -3,7 +3,7 @@ require "pathname"
|
|
|
3
3
|
class TLDR
|
|
4
4
|
class Planner
|
|
5
5
|
def plan config
|
|
6
|
-
search_locations = expand_search_locations config.paths
|
|
6
|
+
search_locations = PathUtil.expand_search_locations config.paths
|
|
7
7
|
|
|
8
8
|
prepend_load_paths config
|
|
9
9
|
require_test_helper config
|
|
@@ -32,21 +32,6 @@ class TLDR
|
|
|
32
32
|
|
|
33
33
|
private
|
|
34
34
|
|
|
35
|
-
def expand_search_locations path_strings
|
|
36
|
-
path_strings.flat_map { |path_string|
|
|
37
|
-
File.directory?(path_string) ? Dir["#{path_string}/**/*.rb"] : path_string
|
|
38
|
-
}.flat_map { |path_string|
|
|
39
|
-
absolute_path = File.expand_path(path_string.gsub(/:.*$/, ""), Dir.pwd)
|
|
40
|
-
line_numbers = path_string.scan(/:(\d+)/).flatten.map(&:to_i)
|
|
41
|
-
|
|
42
|
-
if line_numbers.any?
|
|
43
|
-
line_numbers.map { |line_number| Location.new absolute_path, line_number }
|
|
44
|
-
else
|
|
45
|
-
[Location.new(absolute_path, nil)]
|
|
46
|
-
end
|
|
47
|
-
}.uniq
|
|
48
|
-
end
|
|
49
|
-
|
|
50
35
|
def gather_tests
|
|
51
36
|
gather_descendants(TLDR).flat_map { |subklass|
|
|
52
37
|
subklass.instance_methods.grep(/^test_/).sort.map { |method|
|
|
@@ -57,9 +42,9 @@ class TLDR
|
|
|
57
42
|
|
|
58
43
|
def prepend tests, config
|
|
59
44
|
return tests if config.no_prepend
|
|
60
|
-
prepended_locations = expand_search_locations expand_globs config.
|
|
45
|
+
prepended_locations = PathUtil.expand_search_locations PathUtil.expand_globs config.prepend_paths
|
|
61
46
|
prepended, rest = tests.partition { |test|
|
|
62
|
-
locations_include_test? prepended_locations, test
|
|
47
|
+
PathUtil.locations_include_test? prepended_locations, test
|
|
63
48
|
}
|
|
64
49
|
prepended + rest
|
|
65
50
|
end
|
|
@@ -69,11 +54,11 @@ class TLDR
|
|
|
69
54
|
end
|
|
70
55
|
|
|
71
56
|
def exclude_by_path tests, exclude_paths
|
|
72
|
-
excluded_locations = expand_search_locations expand_globs exclude_paths
|
|
57
|
+
excluded_locations = PathUtil.expand_search_locations PathUtil.expand_globs exclude_paths
|
|
73
58
|
return tests if excluded_locations.empty?
|
|
74
59
|
|
|
75
60
|
tests.reject { |test|
|
|
76
|
-
locations_include_test? excluded_locations, test
|
|
61
|
+
PathUtil.locations_include_test? excluded_locations, test
|
|
77
62
|
}
|
|
78
63
|
end
|
|
79
64
|
|
|
@@ -94,7 +79,7 @@ class TLDR
|
|
|
94
79
|
return tests if line_specific_locations.empty?
|
|
95
80
|
|
|
96
81
|
tests.select { |test|
|
|
97
|
-
locations_include_test? line_specific_locations, test
|
|
82
|
+
PathUtil.locations_include_test? line_specific_locations, test
|
|
98
83
|
}
|
|
99
84
|
end
|
|
100
85
|
|
|
@@ -133,29 +118,6 @@ class TLDR
|
|
|
133
118
|
}
|
|
134
119
|
end
|
|
135
120
|
|
|
136
|
-
def locations_include_test? locations, test
|
|
137
|
-
locations.any? { |location|
|
|
138
|
-
location.file == test.file && (location.line.nil? || test.covers_line?(location.line))
|
|
139
|
-
}
|
|
140
|
-
end
|
|
141
|
-
|
|
142
|
-
# Because search paths to TLDR can include line numbers (e.g. a.rb:4), we
|
|
143
|
-
# can't just pass everything to Dir.glob. Instead, we have to check whether
|
|
144
|
-
# a user-provided search path looks like a glob, and if so, expand it
|
|
145
|
-
#
|
|
146
|
-
# Globby characters specified here:
|
|
147
|
-
# https://ruby-doc.org/3.2.2/Dir.html#method-c-glob
|
|
148
|
-
def expand_globs search_paths
|
|
149
|
-
search_paths.flat_map { |search_path|
|
|
150
|
-
if search_path.match?(/[*?\[\]{}]/)
|
|
151
|
-
raise Error, "Can't combine globs and line numbers in: #{search_path}" if search_path.match?(/:(\d+)$/)
|
|
152
|
-
Dir[search_path]
|
|
153
|
-
else
|
|
154
|
-
search_path
|
|
155
|
-
end
|
|
156
|
-
}
|
|
157
|
-
end
|
|
158
|
-
|
|
159
121
|
def expand_names_with_patterns names
|
|
160
122
|
names.map { |name|
|
|
161
123
|
if name.is_a?(String) && name =~ /^\/(.*)\/$/
|
data/lib/tldr/rake.rb
CHANGED
|
@@ -1,4 +1,41 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
require "rake"
|
|
2
|
+
require "shellwords"
|
|
3
|
+
|
|
4
|
+
require "tldr"
|
|
5
|
+
|
|
6
|
+
class TLDR
|
|
7
|
+
class Task
|
|
8
|
+
include Rake::DSL
|
|
9
|
+
|
|
10
|
+
def initialize(name: "tldr", config: Config.new)
|
|
11
|
+
define name, config
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
private
|
|
15
|
+
|
|
16
|
+
def define name, task_config
|
|
17
|
+
desc "Run #{name} tests (use TLDR_OPTS or .tldr.yml to configure)"
|
|
18
|
+
task name do
|
|
19
|
+
cli_args = build_cli_args(task_config)
|
|
20
|
+
fail unless system "#{"bundle exec " if defined?(Bundler)}tldr #{cli_args}"
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def build_cli_args task_config
|
|
25
|
+
config = if ENV["TLDR_OPTS"]
|
|
26
|
+
env_argv = Shellwords.shellwords(ENV["TLDR_OPTS"])
|
|
27
|
+
opts_config = ArgvParser.new.parse(env_argv, {
|
|
28
|
+
config_intended_for_merge_only: true
|
|
29
|
+
})
|
|
30
|
+
task_config.merge(opts_config)
|
|
31
|
+
else
|
|
32
|
+
task_config
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
config.to_full_args
|
|
36
|
+
end
|
|
37
|
+
end
|
|
4
38
|
end
|
|
39
|
+
|
|
40
|
+
# Create the default tldr task for users
|
|
41
|
+
TLDR::Task.new
|
|
@@ -9,7 +9,7 @@ class TLDR
|
|
|
9
9
|
def before_suite tests
|
|
10
10
|
@suite_start_time = Process.clock_gettime Process::CLOCK_MONOTONIC, :microsecond
|
|
11
11
|
@out.print <<~MSG
|
|
12
|
-
Command: #{tldr_command} #{@config.to_full_args}
|
|
12
|
+
Command: #{tldr_command} #{@config.to_full_args}#{"\n#{@icons.seed} #{CONFLAGS[:seed]} #{@config.seed}" unless @config.seed_set_intentionally}
|
|
13
13
|
|
|
14
14
|
#{@icons.run} Running:
|
|
15
15
|
|
data/lib/tldr/runner.rb
CHANGED
|
@@ -34,7 +34,7 @@ class TLDR
|
|
|
34
34
|
end
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
results = @parallelizer.parallelize(plan.tests, config
|
|
37
|
+
results = @parallelizer.parallelize(plan.tests, config) { |test|
|
|
38
38
|
e = nil
|
|
39
39
|
start_time = Process.clock_gettime(Process::CLOCK_MONOTONIC, :microsecond)
|
|
40
40
|
wip_test = WIPTest.new test, start_time
|
data/lib/tldr/strategizer.rb
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
class TLDR
|
|
2
2
|
class Strategizer
|
|
3
|
-
Strategy = Struct.new :parallel_tests_and_groups, :thread_unsafe_tests
|
|
3
|
+
Strategy = Struct.new :prepend_thread_unsafe_tests, :parallel_tests_and_groups, :thread_unsafe_tests
|
|
4
4
|
|
|
5
5
|
# Combine all discovered test methods with any methods grouped by run_these_together!
|
|
6
6
|
#
|
|
@@ -8,13 +8,13 @@ class TLDR
|
|
|
8
8
|
# - Map over tests to build out groups in order to retain shuffle order
|
|
9
9
|
# (group will run in position of first test in the group)
|
|
10
10
|
# - If a test is in multiple groups, only run it once
|
|
11
|
-
def strategize all_tests, run_these_together_groups, thread_unsafe_test_groups
|
|
11
|
+
def strategize all_tests, run_these_together_groups, thread_unsafe_test_groups, prepend_paths
|
|
12
12
|
thread_unsafe_tests, thread_safe_tests = partition_unsafe(all_tests, thread_unsafe_test_groups)
|
|
13
|
+
prepend_thread_unsafe_tests, thread_unsafe_tests = partition_prepend(thread_unsafe_tests, prepend_paths)
|
|
13
14
|
|
|
14
15
|
grouped_tests = prepare_run_together_groups run_these_together_groups, thread_safe_tests, thread_unsafe_tests
|
|
15
16
|
already_included_groups = []
|
|
16
|
-
|
|
17
|
-
Strategy.new thread_safe_tests.map { |test|
|
|
17
|
+
Strategy.new prepend_thread_unsafe_tests, thread_safe_tests.map { |test|
|
|
18
18
|
if (group = grouped_tests.find { |group| group.tests.include? test })
|
|
19
19
|
if already_included_groups.include? group
|
|
20
20
|
next
|
|
@@ -39,6 +39,16 @@ class TLDR
|
|
|
39
39
|
}
|
|
40
40
|
end
|
|
41
41
|
|
|
42
|
+
# Sadly duplicative with Planner.rb, necessitating the extraction of PathUtil
|
|
43
|
+
# Suboptimal, but we do indeed need to do this work in two places ¯\_(ツ)_/¯
|
|
44
|
+
def partition_prepend thread_unsafe_tests, prepend_paths
|
|
45
|
+
locations = PathUtil.expand_search_locations PathUtil.expand_globs prepend_paths
|
|
46
|
+
|
|
47
|
+
thread_unsafe_tests.partition { |test|
|
|
48
|
+
PathUtil.locations_include_test? locations, test
|
|
49
|
+
}
|
|
50
|
+
end
|
|
51
|
+
|
|
42
52
|
def prepare_run_together_groups run_these_together_groups, thread_safe_tests, thread_unsafe_tests
|
|
43
53
|
grouped_tests = run_these_together_groups.map(&:dup)
|
|
44
54
|
|
data/lib/tldr/value/config.rb
CHANGED
|
@@ -10,7 +10,7 @@ class TLDR
|
|
|
10
10
|
names: "--name",
|
|
11
11
|
fail_fast: "--fail-fast",
|
|
12
12
|
no_emoji: "--no-emoji",
|
|
13
|
-
|
|
13
|
+
prepend_paths: "--prepend",
|
|
14
14
|
no_prepend: "--no-prepend",
|
|
15
15
|
exclude_paths: "--exclude-path",
|
|
16
16
|
exclude_names: "--exclude-name",
|
|
@@ -19,25 +19,35 @@ class TLDR
|
|
|
19
19
|
paths: nil
|
|
20
20
|
}.freeze
|
|
21
21
|
|
|
22
|
-
PATH_FLAGS = [:paths, :helper, :load_paths, :
|
|
22
|
+
PATH_FLAGS = [:paths, :helper, :load_paths, :prepend_paths, :exclude_paths].freeze
|
|
23
23
|
MOST_RECENTLY_MODIFIED_TAG = "MOST_RECENTLY_MODIFIED".freeze
|
|
24
24
|
|
|
25
25
|
Config = Struct.new :paths, :seed, :no_helper, :verbose, :reporter,
|
|
26
26
|
:helper, :load_paths, :parallel, :names, :fail_fast, :no_emoji,
|
|
27
|
-
:
|
|
27
|
+
:prepend_paths, :no_prepend, :exclude_paths, :exclude_names, :base_path,
|
|
28
28
|
:no_dotfile,
|
|
29
|
-
|
|
29
|
+
# Internal properties
|
|
30
|
+
:config_intended_for_merge_only, :seed_set_intentionally, :cli_defaults,
|
|
31
|
+
keyword_init: true do
|
|
30
32
|
def initialize(**args)
|
|
31
|
-
|
|
32
|
-
|
|
33
|
+
unless args[:config_intended_for_merge_only]
|
|
34
|
+
change_working_directory_because_i_am_bad_and_i_should_feel_bad!(args[:base_path])
|
|
35
|
+
args = merge_dotfile_args(args) unless args[:no_dotfile]
|
|
36
|
+
end
|
|
37
|
+
args = undefault_parallel_if_seed_set(args)
|
|
38
|
+
unless args[:config_intended_for_merge_only]
|
|
39
|
+
args = merge_defaults(args)
|
|
40
|
+
end
|
|
33
41
|
|
|
34
|
-
super(**
|
|
42
|
+
super(**args)
|
|
35
43
|
end
|
|
36
44
|
|
|
37
|
-
#
|
|
38
|
-
undef_method :
|
|
45
|
+
# These are for internal tracking and resolved at initialization-time
|
|
46
|
+
undef_method :config_intended_for_merge_only=, :seed_set_intentionally=,
|
|
47
|
+
# These must be set when the Config is first initialized
|
|
48
|
+
:cli_defaults=, :no_dotfile=, :base_path=
|
|
39
49
|
|
|
40
|
-
def self.build_defaults
|
|
50
|
+
def self.build_defaults cli_defaults: true
|
|
41
51
|
common = {
|
|
42
52
|
seed: rand(10_000),
|
|
43
53
|
no_helper: false,
|
|
@@ -53,36 +63,36 @@ class TLDR
|
|
|
53
63
|
base_path: nil
|
|
54
64
|
}
|
|
55
65
|
|
|
56
|
-
if
|
|
66
|
+
if cli_defaults
|
|
57
67
|
common.merge(
|
|
58
68
|
paths: Dir["test/**/*_test.rb", "test/**/test_*.rb"],
|
|
59
69
|
helper: "test/helper.rb",
|
|
60
70
|
load_paths: ["test"],
|
|
61
|
-
|
|
71
|
+
prepend_paths: [MOST_RECENTLY_MODIFIED_TAG]
|
|
62
72
|
)
|
|
63
73
|
else
|
|
64
74
|
common.merge(
|
|
65
75
|
paths: [],
|
|
66
76
|
helper: nil,
|
|
67
77
|
load_paths: [],
|
|
68
|
-
|
|
78
|
+
prepend_paths: []
|
|
69
79
|
)
|
|
70
80
|
end
|
|
71
81
|
end
|
|
72
82
|
|
|
73
|
-
def
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
83
|
+
def undefault_parallel_if_seed_set args
|
|
84
|
+
args.merge(
|
|
85
|
+
seed_set_intentionally: !args[:seed].nil?,
|
|
86
|
+
parallel: (args[:parallel].nil? ? args[:seed].nil? : args[:parallel])
|
|
87
|
+
)
|
|
88
|
+
end
|
|
77
89
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
merged_args[:parallel] = merged_args[:seed].nil?
|
|
82
|
-
end
|
|
90
|
+
def merge_defaults user_args
|
|
91
|
+
merged_args = user_args.dup
|
|
92
|
+
defaults = Config.build_defaults(cli_defaults: merged_args[:cli_defaults])
|
|
83
93
|
|
|
84
94
|
# Arrays
|
|
85
|
-
[:paths, :load_paths, :names, :
|
|
95
|
+
[:paths, :load_paths, :names, :prepend_paths, :exclude_paths, :exclude_names].each do |key|
|
|
86
96
|
merged_args[key] = defaults[key] if merged_args[key].nil? || merged_args[key].empty?
|
|
87
97
|
end
|
|
88
98
|
|
|
@@ -99,13 +109,21 @@ class TLDR
|
|
|
99
109
|
merged_args
|
|
100
110
|
end
|
|
101
111
|
|
|
112
|
+
def merge other
|
|
113
|
+
this_config = to_h
|
|
114
|
+
kwargs = this_config.merge(
|
|
115
|
+
other.to_h.compact.except(:config_intended_for_merge_only)
|
|
116
|
+
)
|
|
117
|
+
Config.new(**kwargs)
|
|
118
|
+
end
|
|
119
|
+
|
|
102
120
|
# We needed this hook (to be called by the planner), because we can't know
|
|
103
121
|
# the default prepend location until we have all the resolved test paths,
|
|
104
122
|
# so we have to mutate it after the fact.
|
|
105
123
|
def update_after_gathering_tests! tests
|
|
106
|
-
return unless
|
|
124
|
+
return unless prepend_paths.include?(MOST_RECENTLY_MODIFIED_TAG)
|
|
107
125
|
|
|
108
|
-
self.
|
|
126
|
+
self.prepend_paths = prepend_paths.map { |path|
|
|
109
127
|
if path == MOST_RECENTLY_MODIFIED_TAG
|
|
110
128
|
most_recently_modified_test_file tests
|
|
111
129
|
else
|
|
@@ -115,12 +133,17 @@ class TLDR
|
|
|
115
133
|
end
|
|
116
134
|
|
|
117
135
|
def to_full_args(exclude: [])
|
|
118
|
-
to_cli_argv(
|
|
136
|
+
to_cli_argv(
|
|
137
|
+
CONFLAGS.keys -
|
|
138
|
+
exclude - [
|
|
139
|
+
(:seed unless seed_set_intentionally)
|
|
140
|
+
]
|
|
141
|
+
).join(" ")
|
|
119
142
|
end
|
|
120
143
|
|
|
121
144
|
def to_single_path_args(path)
|
|
122
145
|
argv = to_cli_argv(CONFLAGS.keys - [
|
|
123
|
-
:seed, :parallel, :names, :fail_fast, :paths, :
|
|
146
|
+
:seed, :parallel, :names, :fail_fast, :paths, :prepend_paths,
|
|
124
147
|
:no_prepend, :exclude_paths
|
|
125
148
|
])
|
|
126
149
|
|
|
@@ -129,14 +152,14 @@ class TLDR
|
|
|
129
152
|
|
|
130
153
|
private
|
|
131
154
|
|
|
132
|
-
def to_cli_argv
|
|
133
|
-
defaults = Config.build_defaults(
|
|
155
|
+
def to_cli_argv options = CONFLAGS.keys
|
|
156
|
+
defaults = Config.build_defaults(cli_defaults: true)
|
|
134
157
|
options.map { |key|
|
|
135
158
|
flag = CONFLAGS[key]
|
|
136
159
|
|
|
137
160
|
# Special cases
|
|
138
|
-
if key == :
|
|
139
|
-
if
|
|
161
|
+
if key == :prepend_paths
|
|
162
|
+
if prepend_paths.map { |s| stringify(key, s) }.sort == paths.map { |s| stringify(:paths, s) }.sort
|
|
140
163
|
# Don't print prepended tests if they're the same as the test paths
|
|
141
164
|
next
|
|
142
165
|
elsif no_prepend
|
data/lib/tldr/version.rb
CHANGED
data/lib/tldr.rb
CHANGED
|
@@ -6,6 +6,7 @@ require_relative "tldr/backtrace_filter"
|
|
|
6
6
|
require_relative "tldr/error"
|
|
7
7
|
require_relative "tldr/parallel_controls"
|
|
8
8
|
require_relative "tldr/parallelizer"
|
|
9
|
+
require_relative "tldr/path_util"
|
|
9
10
|
require_relative "tldr/planner"
|
|
10
11
|
require_relative "tldr/reporters"
|
|
11
12
|
require_relative "tldr/runner"
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: tldr
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.5.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Justin Searls
|
|
@@ -9,7 +9,7 @@ authors:
|
|
|
9
9
|
autorequire:
|
|
10
10
|
bindir: exe
|
|
11
11
|
cert_chain: []
|
|
12
|
-
date: 2023-09-
|
|
12
|
+
date: 2023-09-28 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
|
14
14
|
- !ruby/object:Gem::Dependency
|
|
15
15
|
name: super_diff
|
|
@@ -62,6 +62,7 @@ files:
|
|
|
62
62
|
- lib/tldr/error.rb
|
|
63
63
|
- lib/tldr/parallel_controls.rb
|
|
64
64
|
- lib/tldr/parallelizer.rb
|
|
65
|
+
- lib/tldr/path_util.rb
|
|
65
66
|
- lib/tldr/planner.rb
|
|
66
67
|
- lib/tldr/rake.rb
|
|
67
68
|
- lib/tldr/reporters.rb
|
|
@@ -105,7 +106,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
105
106
|
- !ruby/object:Gem::Version
|
|
106
107
|
version: '0'
|
|
107
108
|
requirements: []
|
|
108
|
-
rubygems_version: 3.4.
|
|
109
|
+
rubygems_version: 3.4.6
|
|
109
110
|
signing_key:
|
|
110
111
|
specification_version: 4
|
|
111
112
|
summary: TLDR will run your tests, but only for 1.8 seconds.
|