minitest-tagz 1.6.0 → 1.7.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
- SHA256:
3
- metadata.gz: 347d2a3aa8e7d5e66ee59e3372e69d78901ca244c6504cbbf2bdfe52e6e11b1e
4
- data.tar.gz: e56b65e7fc29a800855af0e267faa14104c19b2d846f002469411740a3c47ef6
2
+ SHA1:
3
+ metadata.gz: 1a7c2e69a5484b7fe73c7ef7f2f87c22453647b1
4
+ data.tar.gz: c5fd2e1086daca6e88a567764dd82f6bb21b061e
5
5
  SHA512:
6
- metadata.gz: 6d7067bf81f5f82a8d9693779e6ab60c482e528082bad305103473e1ce81c7b9c11d0b0602f298fa441601d497294b19d08c2bf9854ef485c5ce6def3df86afc
7
- data.tar.gz: 6ca7806d80a96c8dbfa2409e84e5161d74d51bad13faa10c4e4c696982b9ac34f6f268cc1941aacfbb4d5ec8ee61b2508ab3af0efe461b8da5c1e8dc300b54b5
6
+ metadata.gz: 481ae12df1710000e24b1f5c09b7e50f34192f40c4f9bcf7fdffc4dc9241539c8b2afe0cb87a5d04fae978550dcd754d955a83e62e8002ef4067a7d4bb861da4
7
+ data.tar.gz: 4f0df35fc26d5b5a08b336f21541fe765fcf8eba5981092bdaebf0bccc87835ff71252318bed73e270713962f251099db5c17e578ceb5321daa7da421b0a2080
@@ -1,6 +1,9 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 2.1.3
3
+ - 2.5.1
4
+ - 2.4.4
5
+ - 2.3.7
4
6
  - 2.2.0
5
7
  - 2.2.1
8
+ - 2.1.3
6
9
  - 2.0.0
@@ -1,208 +1,12 @@
1
1
  require 'minitest'
2
+ require 'minitest/tagz/minitest_patch'
3
+ require 'minitest/tagz/minitest_test_patch'
4
+ require 'minitest/tagz/tagger'
5
+ require 'minitest/tagz/patcher'
2
6
  require 'minitest/tagz/version'
3
7
 
4
8
  module Minitest
5
9
  module Tagz
6
- # The strategy for patching the Minitest run time
7
- module MinitestRunnerStrategy
8
- class << self
9
- def serialize(owner, test_name)
10
- "#{owner} >> #{test_name}"
11
- end
12
-
13
- module RunnableMethodsFilter
14
- def runnable_methods
15
- all_runnables = super
16
-
17
- if Tagz.positive_tags.any?
18
- all_runnables.select! do |r|
19
- serialized = MinitestRunnerStrategy.serialize(self, r)
20
- tags_on_runnable = MinitestRunnerStrategy.tag_map[serialized]
21
- next false unless tags_on_runnable
22
- (Tagz.positive_tags - tags_on_runnable).empty?
23
- end
24
- end
25
-
26
- if Tagz.negative_tags.any?
27
- all_runnables.reject! do |r|
28
- serialized = MinitestRunnerStrategy.serialize(self, r)
29
- tags_on_runnable = MinitestRunnerStrategy.tag_map[serialized]
30
- next false unless tags_on_runnable
31
- (Tagz.negative_tags & tags_on_runnable).any?
32
- end
33
- end
34
-
35
- all_runnables
36
- end
37
- end
38
-
39
- module RunPatch
40
- def run(*args)
41
- # Check for no match and don't filter runnable methods if there would be no match
42
- if Tagz.run_all_if_no_match?
43
- run_map = Runnable.runnables.reduce({}) {|memo, r| memo[r] = r.runnable_methods; memo}
44
- should_skip_filter = run_map.all? do |ctxt, methods|
45
- methods.all? do |m|
46
- serialized = MinitestRunnerStrategy.serialize(ctxt, m)
47
- tags = MinitestRunnerStrategy.tag_map[serialized]
48
- tags.nil? ||
49
- tags.empty? ||
50
- ((tags & Tagz.positive_tags).empty? &&
51
- (tags & Tagz.negative_tags).empty?)
52
- end
53
- end
54
- if should_skip_filter
55
- puts "Couldn't find any runnables with the given tag, running all runnables" if Tagz.log_if_no_match?
56
- return super
57
- end
58
- end
59
-
60
- ::Minitest::Test.singleton_class.class_eval { prepend(RunnableMethodsFilter) }
61
- super
62
- end
63
- end
64
-
65
- def patch
66
- ::Minitest.singleton_class.class_eval { prepend(RunPatch) }
67
- end
68
-
69
- def tag_map
70
- @tag_map ||= {}
71
- end
72
- end
73
- end
74
-
75
- # Patch the Minitest runtime to hook into Tagz
76
- MinitestRunnerStrategy.patch
77
-
78
- # Alias
79
- RunnerStrategy = MinitestRunnerStrategy
80
-
81
- # Was more useful when I was trying to add
82
- # shoulda-context support
83
- module BaseMixin
84
- def tag(*tags)
85
- Tagz.declare_tag_assignment(self, tags)
86
- end
87
- end
88
-
89
- # Was more useful when I was trying to add
90
- # shoulda-context support
91
- class TaggerFactory
92
- def self.create_tagger(owner, pending_tags)
93
- patchers = [MinitestPatcher]
94
- Tagger.new(patchers, owner, pending_tags)
95
- end
96
- end
97
-
98
- # Represents the individual instance of a `tag` call
99
- # It is essentially a state machine that works with the
100
- # patcher to patch and unpatch Minitest properly
101
- class Tagger
102
- def tags_declared
103
- patch_test_definitions
104
- @awaiting_initial_test_definition = true
105
- end
106
-
107
- attr_reader :patchers, :owner, :pending_tags
108
-
109
- def initialize(patchers, owner, pending_tags)
110
- @patchers = patchers
111
- @owner = owner
112
- @pending_tags = pending_tags.map(&:to_s)
113
- super()
114
- end
115
-
116
- def patch_test_definitions
117
- @patchers.each {|p| p.patch(self)}
118
- end
119
-
120
- def unpatch_test_definitions
121
- @patchers.each(&:unpatch)
122
- end
123
-
124
- def handle_initial_test_definition
125
- is_initial = @awaiting_initial_test_definition
126
- @awaiting_initial_test_definition = false if is_initial
127
- res = yield
128
- unpatch_test_definitions if is_initial
129
- res
130
- end
131
- end
132
-
133
- # Patches Minitest to track tags
134
- module MinitestPatcher
135
- ::Minitest::Test.extend(Tagz::BaseMixin)
136
-
137
- class << self
138
- def patch(state_machine)
139
- patch_minitest_test(state_machine)
140
- patch_minitest_spec(state_machine) if spec_included?
141
- end
142
-
143
- def unpatch
144
- unpatch_minitest_test
145
- unpatch_minitest_spec if spec_included?
146
- end
147
-
148
- private
149
-
150
- def spec_included?
151
- !defined?(::Minitest::Spec).nil?
152
- end
153
-
154
- def patch_minitest_test(state_machine)
155
- Minitest::Test.class_eval do
156
- self.singleton_class.class_eval do
157
- alias :old_method_added :method_added
158
-
159
- define_method(:method_added) do |name|
160
- if name[/^test_/]
161
- state_machine.handle_initial_test_definition do
162
- Tagz::RunnerStrategy.tag_map ||= {}
163
- Tagz::RunnerStrategy.tag_map[Tagz::RunnerStrategy.serialize(self, name)] ||= []
164
- Tagz::RunnerStrategy.tag_map[Tagz::RunnerStrategy.serialize(self, name)] += state_machine.pending_tags
165
- old_method_added(name)
166
- end
167
- else
168
- old_method_added(name)
169
- end
170
- end
171
- end
172
- end
173
- end
174
-
175
- def unpatch_minitest_test
176
- Minitest::Test.class_eval do
177
- self.singleton_class.class_eval do
178
- undef_method :method_added
179
- alias :method_added :old_method_added
180
- end
181
- end
182
- end
183
-
184
- def patch_minitest_spec(state_machine)
185
- Kernel.module_eval do
186
- alias :old_describe :describe
187
-
188
- define_method(:describe) do |*args, &block|
189
- state_machine.handle_initial_test_definition do
190
- old_describe(*args, &block)
191
- end
192
- end
193
- end
194
- end
195
-
196
- def unpatch_minitest_spec
197
- Kernel.module_eval do
198
- undef_method :describe
199
- alias :describe :old_describe
200
- end
201
- end
202
- end
203
- end
204
-
205
- # Main extensions to Minitest
206
10
  class << self
207
11
  attr_accessor :run_all_if_no_match, :log_if_no_match
208
12
 
@@ -211,6 +15,7 @@ module Minitest
211
15
 
212
16
  # Create a master TagSet that you wish to test. You only
213
17
  # want to run tests with tags in this set
18
+ #
214
19
  # @param [Enumerable<Symbol>] tags - a list of tags you want to test
215
20
  # @param [Boolean] run_all_if_no_match - will run all tests if no tests are found with the tag
216
21
  # @param [Boolean] log_if_no_match - puts if no match specs found
@@ -220,23 +25,33 @@ module Minitest
220
25
  @log_if_no_match = log_if_no_match
221
26
  end
222
27
 
28
+ # @private
223
29
  def chosen_tags
224
30
  @chosen_tags ||= []
225
31
  end
226
32
 
33
+ # @private
227
34
  def positive_tags
228
35
  chosen_tags.reject {|t| t.is_a?(String) && t[/^-/]}
229
36
  end
230
37
 
38
+ # @private
231
39
  def negative_tags
232
40
  chosen_tags.select {|t| t.is_a?(String) && t[/^-/]}.map {|t| t[1..-1]}
233
41
  end
234
42
 
235
- def declare_tag_assignment(owner, pending_tags)
236
- tag_machine = TaggerFactory.create_tagger(owner, pending_tags)
237
- tag_machine.tags_declared
238
- tag_machine
43
+ # @private
44
+ def serialize(owner, test_name)
45
+ "#{owner} >> #{test_name}"
46
+ end
47
+
48
+ # @private
49
+ def tag_map
50
+ @tag_map ||= {}
239
51
  end
240
52
  end
241
53
  end
242
54
  end
55
+
56
+ Minitest.singleton_class.prepend(Minitest::Tagz::MinitestPatch)
57
+ Minitest::Test.extend(Minitest::Tagz::MinitestTestPatch)
@@ -0,0 +1,56 @@
1
+ module Minitest
2
+ module Tagz
3
+ module MinitestPatch
4
+ def run(*args)
5
+ # Check for no match and don't filter runnable methods if there would be no match
6
+ if Tagz.run_all_if_no_match?
7
+ run_map = Minitest::Runnable.runnables.reduce({}) {|memo, r| memo[r] = r.runnable_methods; memo}
8
+ should_skip_filter = run_map.all? do |ctxt, methods|
9
+ methods.all? do |m|
10
+ serialized = Tagz.serialize(ctxt, m)
11
+ tags = Tagz.tag_map[serialized]
12
+ tags.nil? ||
13
+ tags.empty? ||
14
+ ((tags & Tagz.positive_tags).empty? &&
15
+ (tags & Tagz.negative_tags).empty?)
16
+ end
17
+ end
18
+ if should_skip_filter
19
+ puts "Couldn't find any runnables with the given tag, running all runnables" if Tagz.log_if_no_match?
20
+ return super
21
+ end
22
+ end
23
+
24
+ Minitest::Test.singleton_class.class_eval { prepend(MinitestPatch::RunnableMethodsPatch) }
25
+ super
26
+ end
27
+
28
+ # Patch which is used ot filter Minitest's `runnable_methods`
29
+ module RunnableMethodsPatch
30
+ def runnable_methods
31
+ all_runnables = super
32
+
33
+ if Tagz.positive_tags.any?
34
+ all_runnables.select! do |r|
35
+ serialized = Tagz.serialize(self, r)
36
+ tags_on_runnable = Tagz.tag_map[serialized]
37
+ next false unless tags_on_runnable
38
+ (Tagz.positive_tags - tags_on_runnable).empty?
39
+ end
40
+ end
41
+
42
+ if Tagz.negative_tags.any?
43
+ all_runnables.reject! do |r|
44
+ serialized = Tagz.serialize(self, r)
45
+ tags_on_runnable = Tagz.tag_map[serialized]
46
+ next false unless tags_on_runnable
47
+ (Tagz.negative_tags & tags_on_runnable).any?
48
+ end
49
+ end
50
+
51
+ all_runnables
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,13 @@
1
+ # Adds the `tag` method to Minitest::Test. When we encounter a `tag` then we
2
+ # want to create a state machine that will be used to patch/unpatch Minitest
3
+ module Minitest
4
+ module Tagz
5
+ module MinitestTestPatch
6
+ def tag(*tags)
7
+ state_machine = Tagger.new([Minitest::Tagz::Patcher], self, tags)
8
+ state_machine.tags_declared!
9
+ state_machine
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,73 @@
1
+ # Responsible for patching/unpatching Minitest. When `tag` is called we patch Minitest and
2
+ module Minitest
3
+ module Tagz
4
+ module Patcher
5
+ class << self
6
+ def patch(state_machine)
7
+ patch_minitest_test(state_machine)
8
+ patch_minitest_spec(state_machine) if spec_included?
9
+ end
10
+
11
+ def unpatch
12
+ unpatch_minitest_test
13
+ unpatch_minitest_spec if spec_included?
14
+ end
15
+
16
+ private
17
+
18
+ def spec_included?
19
+ !defined?(::Minitest::Spec).nil?
20
+ end
21
+
22
+ def patch_minitest_test(state_machine)
23
+ Minitest::Test.class_eval do
24
+ self.singleton_class.class_eval do
25
+ alias :old_method_added :method_added
26
+
27
+ define_method(:method_added) do |name|
28
+ if name[/^test_/]
29
+ state_machine.handle_initial_test_definition! do
30
+ Tagz.tag_map ||= {}
31
+ Tagz.tag_map[Tagz.serialize(self, name)] ||= []
32
+ Tagz.tag_map[Tagz.serialize(self, name)] += state_machine.pending_tags
33
+ old_method_added(name)
34
+ end
35
+ else
36
+ old_method_added(name)
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+
43
+ def unpatch_minitest_test
44
+ Minitest::Test.class_eval do
45
+ self.singleton_class.class_eval do
46
+ undef_method :method_added
47
+ alias :method_added :old_method_added
48
+ end
49
+ end
50
+ end
51
+
52
+ def patch_minitest_spec(state_machine)
53
+ Kernel.module_eval do
54
+ alias :old_describe :describe
55
+
56
+ define_method(:describe) do |*args, &block|
57
+ state_machine.handle_initial_test_definition! do
58
+ old_describe(*args, &block)
59
+ end
60
+ end
61
+ end
62
+ end
63
+
64
+ def unpatch_minitest_spec
65
+ Kernel.module_eval do
66
+ undef_method :describe
67
+ alias :describe :old_describe
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,39 @@
1
+ module Minitest
2
+ module Tagz
3
+ # Represents the individual instance of a `tag` call
4
+ # It is essentially a state machine that works with the
5
+ # patcher to patch and unpatch Minitest properly
6
+ class Tagger
7
+ attr_reader :patchers, :owner, :pending_tags
8
+
9
+ def initialize(patchers, owner, pending_tags)
10
+ @patchers = patchers
11
+ @owner = owner
12
+ @pending_tags = pending_tags.map(&:to_s)
13
+ end
14
+
15
+ def tags_declared!
16
+ patch_test_definitions
17
+ @awaiting_initial_test_definition = true
18
+ end
19
+
20
+ def handle_initial_test_definition!
21
+ is_initial = @awaiting_initial_test_definition
22
+ @awaiting_initial_test_definition = false if is_initial
23
+ res = yield
24
+ unpatch_test_definitions if is_initial
25
+ res
26
+ end
27
+
28
+ private
29
+
30
+ def patch_test_definitions
31
+ @patchers.each {|p| p.patch(self)}
32
+ end
33
+
34
+ def unpatch_test_definitions
35
+ @patchers.each(&:unpatch)
36
+ end
37
+ end
38
+ end
39
+ end
@@ -1,5 +1,5 @@
1
1
  module Minitest
2
2
  module Tagz
3
- VERSION = "1.6.0"
3
+ VERSION = "1.7.0"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: minitest-tagz
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.6.0
4
+ version: 1.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Josh Bodah
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-05-09 00:00:00.000000000 Z
11
+ date: 2019-02-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: minitest
@@ -112,6 +112,10 @@ files:
112
112
  - Rakefile
113
113
  - lib/minitest/tagz.rb
114
114
  - lib/minitest/tagz/focus.rb
115
+ - lib/minitest/tagz/minitest_patch.rb
116
+ - lib/minitest/tagz/minitest_test_patch.rb
117
+ - lib/minitest/tagz/patcher.rb
118
+ - lib/minitest/tagz/tagger.rb
115
119
  - lib/minitest/tagz/version.rb
116
120
  - minitest-tagz.gemspec
117
121
  homepage: https://github.com/jbodah/minitest-tagz
@@ -134,7 +138,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
134
138
  version: '0'
135
139
  requirements: []
136
140
  rubyforge_project:
137
- rubygems_version: 2.7.3
141
+ rubygems_version: 2.5.2.3
138
142
  signing_key:
139
143
  specification_version: 4
140
144
  summary: yet another tags implementation for Minitest