constable-rails 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 +68 -1
- data/lib/constable/cli.rb +1 -1
- data/lib/constable/cold_case/rspec.rb +44 -0
- data/lib/constable/importer/reopener.rb +29 -4
- data/lib/constable/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e3b589fed13c38522dab7443ab1bb967bedeaec7abb34beaecd5c4f2c9a4298a
|
|
4
|
+
data.tar.gz: b646c7160830f81bc2c6c5af9fe60728a8c7e1f40236e594fb64a51eed04080f
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ee0579e80cb81345601ce2c40090db63b87b1498698a77fbc8c34d0df478d36f3210295b3909bd8290835a1f245f2522952f491caca6776d7ac28981dcae7b74
|
|
7
|
+
data.tar.gz: aea8a0a67d5bdc8868706db9820af271ded921871da905c9e09fe83ac74a359c8c5e9ef8649d737367075f8faa9fabc32fff13156a8f2a9f6e9f69516464441a
|
data/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,72 @@ All notable changes to this project are documented here. This project adheres to
|
|
|
5
5
|
|
|
6
6
|
## [Unreleased]
|
|
7
7
|
|
|
8
|
+
## [1.3.1]
|
|
9
|
+
|
|
10
|
+
### Cold cases now read `.rspec`
|
|
11
|
+
|
|
12
|
+
The bug that mattered. `.rspec` is where an RSpec suite says what to load before any spec
|
|
13
|
+
file:
|
|
14
|
+
|
|
15
|
+
```
|
|
16
|
+
--require spec_helper
|
|
17
|
+
--require rails_helper
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
That is what `rspec --init` generates, and it is why a real spec file usually has no
|
|
21
|
+
`require` line of its own — there is nothing for it to repeat. RSpec's own runner reads
|
|
22
|
+
those files. Constable's cold-case driver did not.
|
|
23
|
+
|
|
24
|
+
So a cold case ran with no `rails_helper` at all: no FactoryBot, no shoulda-matchers, no
|
|
25
|
+
`spec/support/**`. On a 1,277-file suite that is **entirely green under
|
|
26
|
+
`bundle exec rspec`**, `constable test spec/models --full` reported:
|
|
27
|
+
|
|
28
|
+
```
|
|
29
|
+
✓ 774 passed ✗ 3589 failed
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
2,637 of them `undefined method 'create'`, the rest `belong_to`,
|
|
33
|
+
`validate_presence_of`, missing support constants. Every one of them Constable's fault,
|
|
34
|
+
and every one of them looking like the user's.
|
|
35
|
+
|
|
36
|
+
Cold cases now apply the `--require` directives from `.rspec`, `~/.rspec`, `.rspec-local`
|
|
37
|
+
and `SPEC_OPTS`, parsed by RSpec itself so the precedence is its own rather than a guess.
|
|
38
|
+
Only `--require` is taken: formatters, colour and output streams belong to Constable's
|
|
39
|
+
reporter, ordering is Constable's job, and a `--tag` filter meant for a different run
|
|
40
|
+
should not silently drop tests from this one.
|
|
41
|
+
|
|
42
|
+
The same file is now 14 passed, 0 failed — matching `bundle exec rspec` exactly.
|
|
43
|
+
|
|
44
|
+
This never showed up before because the app it was developed against wrote
|
|
45
|
+
`require "rails_helper"` at the top of every spec, which is the one arrangement that
|
|
46
|
+
hides it.
|
|
47
|
+
|
|
48
|
+
### `constable import` says what it actually did
|
|
49
|
+
|
|
50
|
+
It reported `did reopen 1277 file(s)`. "Reopen" is this code's internal word and means
|
|
51
|
+
nothing to a reader, and "import" on its own suggests the files were copied somewhere —
|
|
52
|
+
which is the opposite of what happened. A real user read it exactly that way and asked
|
|
53
|
+
why their specs had not moved into `test/`.
|
|
54
|
+
|
|
55
|
+
```
|
|
56
|
+
Adopted 1277 rspec files as cold cases.
|
|
57
|
+
|
|
58
|
+
Your rspec files stay exactly where they are and are not changed.
|
|
59
|
+
One line was added to .constable/config.yml:
|
|
60
|
+
|
|
61
|
+
cold_cases:
|
|
62
|
+
- spec/**/*_spec.rb
|
|
63
|
+
|
|
64
|
+
Constable runs them from there, through real RSpec, and folds
|
|
65
|
+
the results into its own reporting, flake history and CI gate.
|
|
66
|
+
|
|
67
|
+
Next: constable test --full run everything, cold and native
|
|
68
|
+
constable test --unsafe run only these
|
|
69
|
+
constable modernize PATH see what one file would look like
|
|
70
|
+
as a native case (writes nothing)
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
|
|
8
74
|
## [1.3.0]
|
|
9
75
|
|
|
10
76
|
Adoption at scale. Everything here came from installing 1.2.0 into a 1,277-spec-file
|
|
@@ -462,7 +528,8 @@ Initial release.
|
|
|
462
528
|
- Diff-based coverage gate — only lines changed in the current diff are held to the
|
|
463
529
|
threshold. `constable beat` for the full picture, `--html` for a browsable report.
|
|
464
530
|
|
|
465
|
-
[Unreleased]: https://github.com/Ray-Hughes/constable/compare/v1.3.
|
|
531
|
+
[Unreleased]: https://github.com/Ray-Hughes/constable/compare/v1.3.1...HEAD
|
|
532
|
+
[1.3.1]: https://github.com/Ray-Hughes/constable/compare/v1.3.0...v1.3.1
|
|
466
533
|
[1.3.0]: https://github.com/Ray-Hughes/constable/compare/v1.2.0...v1.3.0
|
|
467
534
|
[1.2.0]: https://github.com/Ray-Hughes/constable/compare/v1.1.0...v1.2.0
|
|
468
535
|
[1.1.0]: https://github.com/Ray-Hughes/constable/compare/v1.0.0...v1.1.0
|
data/lib/constable/cli.rb
CHANGED
|
@@ -168,8 +168,8 @@ module Constable
|
|
|
168
168
|
strategy: options[:strategy].to_sym
|
|
169
169
|
)
|
|
170
170
|
|
|
171
|
+
# The summary says this in full now, in the reader's own terms.
|
|
171
172
|
say result.summary
|
|
172
|
-
say "\nNothing was rewritten -- cold cases run through their own engine, unchanged." if result.any_changes?
|
|
173
173
|
exit(EXIT_CLEAN)
|
|
174
174
|
end
|
|
175
175
|
|
|
@@ -278,9 +278,53 @@ module Constable
|
|
|
278
278
|
# rspec-core's own default; restated because rspec-rails turns it off and a
|
|
279
279
|
# verbatim legacy file may well open with a bare `describe`.
|
|
280
280
|
configuration.expose_dsl_globally = true if configuration.respond_to?(:expose_dsl_globally=)
|
|
281
|
+
apply_rspec_options(configuration)
|
|
281
282
|
@session_prepared = true
|
|
282
283
|
end
|
|
283
284
|
|
|
285
|
+
# `.rspec` is where a suite says what to load before any spec file.
|
|
286
|
+
#
|
|
287
|
+
# --require spec_helper
|
|
288
|
+
# --require rails_helper
|
|
289
|
+
#
|
|
290
|
+
# That is what `rspec --init` generates, and it is why a real spec file usually
|
|
291
|
+
# has no `require` line of its own -- there is nothing for it to repeat. RSpec's
|
|
292
|
+
# own runner reads those files; driving example groups directly does not, so
|
|
293
|
+
# without this a cold case runs with no rails_helper at all: no FactoryBot, no
|
|
294
|
+
# shoulda-matchers, no spec/support. In one real suite that was 2,637 tests
|
|
295
|
+
# failing on `undefined method 'create'` -- a suite that is entirely green under
|
|
296
|
+
# `bundle exec rspec`.
|
|
297
|
+
#
|
|
298
|
+
# Only `--require` is taken. Formatters, colour and output streams belong to
|
|
299
|
+
# Constable's reporter, ordering is Constable's job, and a `--tag` filter from a
|
|
300
|
+
# file RSpec would apply to its own run should not silently drop tests from this
|
|
301
|
+
# one. Requires are the part that decides whether the suite can run at all.
|
|
302
|
+
def apply_rspec_options(configuration)
|
|
303
|
+
requires = rspec_option_requires
|
|
304
|
+
return if requires.empty?
|
|
305
|
+
|
|
306
|
+
# `requires=` rather than plain Kernel#require: it is RSpec's own accessor, and
|
|
307
|
+
# it puts `lib` and the default path (`spec`) on the load path first, which is
|
|
308
|
+
# what makes a bare `require "rails_helper"` resolve.
|
|
309
|
+
configuration.requires = requires
|
|
310
|
+
rescue StandardError => e
|
|
311
|
+
# A helper that will not load is the suite's problem to fix, and it will say so
|
|
312
|
+
# loudly on the first file. Constable's job here is not to disappear.
|
|
313
|
+
Constable.warn!("could not load what .rspec requires (#{e.class}: #{e.message}). " \
|
|
314
|
+
"Cold cases will run without it.", kind: :cold_case)
|
|
315
|
+
end
|
|
316
|
+
|
|
317
|
+
# Parsed by RSpec itself, so `.rspec`, `~/.rspec`, `.rspec-local` and SPEC_OPTS are
|
|
318
|
+
# all read with its precedence rather than a guess at the format.
|
|
319
|
+
def rspec_option_requires
|
|
320
|
+
return [] unless defined?(::RSpec::Core::ConfigurationOptions)
|
|
321
|
+
|
|
322
|
+
options = ::RSpec::Core::ConfigurationOptions.new([]).options
|
|
323
|
+
Array(options[:requires])
|
|
324
|
+
rescue StandardError
|
|
325
|
+
[]
|
|
326
|
+
end
|
|
327
|
+
|
|
284
328
|
def clear_examples
|
|
285
329
|
world = ::RSpec.instance_variable_get(:@world)
|
|
286
330
|
world.reset if world.respond_to?(:reset)
|
|
@@ -114,12 +114,26 @@ module Constable
|
|
|
114
114
|
}
|
|
115
115
|
end
|
|
116
116
|
|
|
117
|
+
# Written for somebody who has just typed `constable import` and does not yet know
|
|
118
|
+
# what a cold case is. "reopen" is the word this code uses internally and it means
|
|
119
|
+
# nothing to a reader; "import" itself suggests files were copied somewhere, which
|
|
120
|
+
# is the opposite of what happened. So: say where the files are, say what changed,
|
|
121
|
+
# and say what to do next.
|
|
117
122
|
def summary
|
|
118
|
-
verb = dry_run? ? "
|
|
119
|
-
|
|
123
|
+
verb = dry_run? ? "Would adopt" : "Adopted"
|
|
124
|
+
noun = imported_count == 1 ? "file" : "files"
|
|
125
|
+
lines = ["#{verb} #{imported_count} #{@from} #{noun} as cold cases."]
|
|
126
|
+
|
|
120
127
|
unless @globs_added.empty?
|
|
121
|
-
lines << "
|
|
122
|
-
|
|
128
|
+
lines << ""
|
|
129
|
+
lines << " Your #{@from} files stay exactly where they are and are not changed."
|
|
130
|
+
lines << " #{dry_run? ? "One line would be added to" : "One line was added to"} " \
|
|
131
|
+
"#{@config_path}:"
|
|
132
|
+
lines << ""
|
|
133
|
+
@globs_added.each { |glob| lines << " cold_cases:\n - #{glob}" }
|
|
134
|
+
lines << ""
|
|
135
|
+
lines << " Constable runs them from there, through real #{engine_label}, and folds"
|
|
136
|
+
lines << " the results into its own reporting, flake history and CI gate."
|
|
123
137
|
unless comments_preserved?
|
|
124
138
|
lines << " note: config.yml was rewritten from parsed YAML; comments were not preserved"
|
|
125
139
|
end
|
|
@@ -133,9 +147,20 @@ module Constable
|
|
|
133
147
|
@skipped.each { |s| lines << " - #{s[:path]} (#{s[:reason]})" }
|
|
134
148
|
end
|
|
135
149
|
@errors.each { |e| lines << " error: #{e[:path]} -- #{e[:message]}" }
|
|
150
|
+
|
|
151
|
+
unless dry_run? || imported_count.zero?
|
|
152
|
+
lines << ""
|
|
153
|
+
lines << " Next: constable test --full run everything, cold and native"
|
|
154
|
+
lines << " constable test --unsafe run only these"
|
|
155
|
+
lines << " constable modernize PATH see what one file would look like"
|
|
156
|
+
lines << " as a native case (writes nothing)"
|
|
157
|
+
end
|
|
158
|
+
|
|
136
159
|
lines.join("\n")
|
|
137
160
|
end
|
|
138
161
|
|
|
162
|
+
def engine_label = @from.to_s == "rspec" ? "RSpec" : "Minitest"
|
|
163
|
+
|
|
139
164
|
def superclass_name = ENGINES.fetch(@from)[:superclass]
|
|
140
165
|
|
|
141
166
|
def covered_by(glob)
|
data/lib/constable/version.rb
CHANGED