minitest-tagz 1.6.0 → 1.7.0

Sign up to get free protection for your applications and to get access to all the features.
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