mutant 0.9.5 → 0.9.10

Sign up to get free protection for your applications and to get access to all the features.
Files changed (190) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +121 -0
  3. data/.rubocop.yml +203 -0
  4. data/Changelog.md +27 -0
  5. data/Gemfile +0 -7
  6. data/Gemfile.lock +30 -87
  7. data/Gemfile.shared +7 -0
  8. data/README.md +88 -27
  9. data/config/reek.yml +1 -0
  10. data/lib/mutant.rb +5 -3
  11. data/lib/mutant/ast.rb +0 -9
  12. data/lib/mutant/ast/find_metaclass_containing.rb +48 -0
  13. data/lib/mutant/ast/meta/send.rb +0 -6
  14. data/lib/mutant/bootstrap.rb +0 -36
  15. data/lib/mutant/cli.rb +5 -49
  16. data/lib/mutant/config.rb +0 -8
  17. data/lib/mutant/context.rb +0 -3
  18. data/lib/mutant/env.rb +0 -6
  19. data/lib/mutant/expression/method.rb +6 -6
  20. data/lib/mutant/expression/methods.rb +6 -6
  21. data/lib/mutant/expression/parser.rb +0 -6
  22. data/lib/mutant/integration.rb +0 -18
  23. data/lib/mutant/isolation/fork.rb +0 -22
  24. data/lib/mutant/license.rb +12 -1
  25. data/lib/mutant/matcher.rb +0 -14
  26. data/lib/mutant/matcher/config.rb +0 -11
  27. data/lib/mutant/matcher/method.rb +0 -31
  28. data/lib/mutant/matcher/method/instance.rb +0 -8
  29. data/lib/mutant/matcher/method/metaclass.rb +86 -0
  30. data/lib/mutant/matcher/method/singleton.rb +0 -25
  31. data/lib/mutant/matcher/methods.rb +17 -28
  32. data/lib/mutant/matcher/namespace.rb +0 -10
  33. data/lib/mutant/matcher/scope.rb +2 -4
  34. data/lib/mutant/meta/example/dsl.rb +0 -21
  35. data/lib/mutant/meta/example/verification.rb +0 -20
  36. data/lib/mutant/mutation.rb +0 -3
  37. data/lib/mutant/mutator.rb +1 -29
  38. data/lib/mutant/mutator/node.rb +1 -66
  39. data/lib/mutant/mutator/node/and_asgn.rb +0 -3
  40. data/lib/mutant/mutator/node/argument.rb +0 -15
  41. data/lib/mutant/mutator/node/arguments.rb +0 -20
  42. data/lib/mutant/mutator/node/begin.rb +0 -3
  43. data/lib/mutant/mutator/node/binary.rb +0 -23
  44. data/lib/mutant/mutator/node/block.rb +0 -15
  45. data/lib/mutant/mutator/node/break.rb +0 -3
  46. data/lib/mutant/mutator/node/case.rb +0 -9
  47. data/lib/mutant/mutator/node/class.rb +0 -3
  48. data/lib/mutant/mutator/node/conditional_loop.rb +0 -3
  49. data/lib/mutant/mutator/node/const.rb +0 -3
  50. data/lib/mutant/mutator/node/define.rb +0 -11
  51. data/lib/mutant/mutator/node/defined.rb +0 -3
  52. data/lib/mutant/mutator/node/dstr.rb +0 -3
  53. data/lib/mutant/mutator/node/dsym.rb +0 -3
  54. data/lib/mutant/mutator/node/generic.rb +0 -67
  55. data/lib/mutant/mutator/node/if.rb +0 -12
  56. data/lib/mutant/mutator/node/index.rb +0 -27
  57. data/lib/mutant/mutator/node/kwbegin.rb +0 -3
  58. data/lib/mutant/mutator/node/literal.rb +0 -3
  59. data/lib/mutant/mutator/node/literal/array.rb +0 -6
  60. data/lib/mutant/mutator/node/literal/boolean.rb +0 -4
  61. data/lib/mutant/mutator/node/literal/float.rb +0 -9
  62. data/lib/mutant/mutator/node/literal/hash.rb +0 -9
  63. data/lib/mutant/mutator/node/literal/integer.rb +0 -9
  64. data/lib/mutant/mutator/node/literal/nil.rb +0 -3
  65. data/lib/mutant/mutator/node/literal/range.rb +1 -7
  66. data/lib/mutant/mutator/node/literal/regex.rb +0 -6
  67. data/lib/mutant/mutator/node/literal/string.rb +0 -3
  68. data/lib/mutant/mutator/node/literal/symbol.rb +0 -3
  69. data/lib/mutant/mutator/node/masgn.rb +0 -3
  70. data/lib/mutant/mutator/node/match_current_line.rb +0 -3
  71. data/lib/mutant/mutator/node/mlhs.rb +0 -3
  72. data/lib/mutant/mutator/node/named_value/access.rb +2 -14
  73. data/lib/mutant/mutator/node/named_value/constant_assignment.rb +0 -9
  74. data/lib/mutant/mutator/node/named_value/variable_assignment.rb +0 -6
  75. data/lib/mutant/mutator/node/next.rb +0 -3
  76. data/lib/mutant/mutator/node/noop.rb +0 -3
  77. data/lib/mutant/mutator/node/nthref.rb +0 -3
  78. data/lib/mutant/mutator/node/op_asgn.rb +0 -3
  79. data/lib/mutant/mutator/node/or_asgn.rb +0 -3
  80. data/lib/mutant/mutator/node/procarg_zero.rb +0 -3
  81. data/lib/mutant/mutator/node/regopt.rb +0 -6
  82. data/lib/mutant/mutator/node/resbody.rb +0 -6
  83. data/lib/mutant/mutator/node/rescue.rb +2 -19
  84. data/lib/mutant/mutator/node/return.rb +0 -3
  85. data/lib/mutant/mutator/node/sclass.rb +20 -0
  86. data/lib/mutant/mutator/node/send.rb +2 -61
  87. data/lib/mutant/mutator/node/send/attribute_assignment.rb +0 -9
  88. data/lib/mutant/mutator/node/send/binary.rb +0 -11
  89. data/lib/mutant/mutator/node/send/conditional.rb +0 -3
  90. data/lib/mutant/mutator/node/splat.rb +0 -3
  91. data/lib/mutant/mutator/node/super.rb +0 -3
  92. data/lib/mutant/mutator/node/when.rb +0 -19
  93. data/lib/mutant/mutator/node/yield.rb +0 -3
  94. data/lib/mutant/mutator/node/zsuper.rb +0 -3
  95. data/lib/mutant/mutator/util/array.rb +0 -6
  96. data/lib/mutant/mutator/util/symbol.rb +0 -3
  97. data/lib/mutant/parallel.rb +0 -13
  98. data/lib/mutant/parallel/driver.rb +0 -10
  99. data/lib/mutant/parallel/worker.rb +0 -22
  100. data/lib/mutant/registry.rb +2 -7
  101. data/lib/mutant/reporter/cli.rb +0 -5
  102. data/lib/mutant/reporter/cli/format.rb +0 -9
  103. data/lib/mutant/reporter/cli/printer.rb +2 -42
  104. data/lib/mutant/reporter/cli/printer/env_progress.rb +0 -15
  105. data/lib/mutant/reporter/cli/printer/isolation_result.rb +0 -18
  106. data/lib/mutant/reporter/cli/printer/mutation_progress_result.rb +0 -5
  107. data/lib/mutant/reporter/cli/printer/mutation_result.rb +1 -22
  108. data/lib/mutant/reporter/cli/printer/status_progressive.rb +0 -8
  109. data/lib/mutant/reporter/cli/printer/subject_progress.rb +0 -9
  110. data/lib/mutant/repository/diff.rb +1 -13
  111. data/lib/mutant/repository/diff/ranges.rb +0 -11
  112. data/lib/mutant/result.rb +0 -3
  113. data/lib/mutant/runner.rb +0 -18
  114. data/lib/mutant/runner/sink.rb +0 -5
  115. data/lib/mutant/subject.rb +0 -8
  116. data/lib/mutant/subject/method.rb +0 -3
  117. data/lib/mutant/subject/method/instance.rb +40 -6
  118. data/lib/mutant/subject/method/metaclass.rb +30 -0
  119. data/lib/mutant/transform.rb +0 -92
  120. data/lib/mutant/version.rb +1 -1
  121. data/lib/mutant/warnings.rb +0 -6
  122. data/lib/mutant/zombifier.rb +2 -34
  123. data/meta/and.rb +0 -2
  124. data/meta/array.rb +0 -3
  125. data/meta/begin.rb +0 -3
  126. data/meta/block.rb +0 -3
  127. data/meta/break.rb +0 -1
  128. data/meta/case.rb +0 -6
  129. data/meta/casgn.rb +0 -3
  130. data/meta/cvasgn.rb +0 -1
  131. data/meta/def.rb +0 -7
  132. data/meta/ensure.rb +0 -1
  133. data/meta/false.rb +0 -1
  134. data/meta/gvasgn.rb +0 -1
  135. data/meta/hash.rb +0 -4
  136. data/meta/if.rb +0 -5
  137. data/meta/ivasgn.rb +0 -1
  138. data/meta/kwbegin.rb +0 -1
  139. data/meta/lvasgn.rb +0 -1
  140. data/meta/match_current_line.rb +0 -1
  141. data/meta/next.rb +0 -1
  142. data/meta/or.rb +0 -2
  143. data/meta/range.rb +26 -0
  144. data/meta/regexp.rb +0 -1
  145. data/meta/rescue.rb +0 -6
  146. data/meta/sclass.rb +12 -0
  147. data/meta/send.rb +0 -4
  148. data/meta/true.rb +0 -1
  149. data/meta/until.rb +0 -1
  150. data/meta/while.rb +0 -2
  151. data/meta/yield.rb +0 -1
  152. data/mutant.gemspec +8 -4
  153. data/mutant.sh +12 -0
  154. data/spec/integrations.yml +3 -1
  155. data/spec/spec_helper.rb +37 -22
  156. data/spec/unit/mutant/ast/find_metaclass_containing_spec.rb +64 -0
  157. data/spec/unit/mutant/expression/methods_spec.rb +7 -2
  158. data/spec/unit/mutant/license_spec.rb +17 -5
  159. data/spec/unit/mutant/matcher/method/metaclass_spec.rb +108 -0
  160. data/spec/unit/mutant/matcher/methods/metaclass_spec.rb +62 -0
  161. data/spec/unit/mutant/matcher/namespace_spec.rb +3 -1
  162. data/spec/unit/mutant/matcher/scope_spec.rb +11 -1
  163. data/spec/unit/mutant/meta/example_spec.rb +3 -3
  164. data/spec/unit/mutant/mutator/node_spec.rb +1 -6
  165. data/spec/unit/mutant/parallel/driver_spec.rb +4 -4
  166. data/spec/unit/mutant/parallel/worker_spec.rb +5 -5
  167. data/spec/unit/mutant/parallel_spec.rb +7 -7
  168. data/spec/unit/mutant/registry_spec.rb +52 -25
  169. data/spec/unit/mutant/reporter/cli/printer/env_result_spec.rb +1 -1
  170. data/spec/unit/mutant/reporter/cli/printer/mutation_progress_result_spec.rb +2 -2
  171. data/spec/unit/mutant/reporter/cli/printer/mutation_result_spec.rb +12 -12
  172. data/spec/unit/mutant/reporter/cli/printer/subject_result_spec.rb +1 -1
  173. data/spec/unit/mutant/reporter/cli/printer_spec.rb +4 -4
  174. data/spec/unit/mutant/reporter/cli_spec.rb +1 -1
  175. data/spec/unit/mutant/subject/method/instance_spec.rb +117 -22
  176. data/spec/unit/mutant/subject/method/metaclass_spec.rb +63 -0
  177. data/test_app/Gemfile.minitest +2 -0
  178. data/test_app/lib/test_app.rb +5 -0
  179. data/test_app/lib/test_app/metaclasses.rb +108 -0
  180. metadata +85 -25
  181. data/.circleci/config.yml +0 -53
  182. data/config/rubocop.yml +0 -205
  183. data/lib/mutant/color.rb +0 -43
  184. data/lib/mutant/diff.rb +0 -114
  185. data/lib/mutant/variable.rb +0 -282
  186. data/spec/shared/base_behavior.rb +0 -45
  187. data/spec/support/test_app.rb +0 -7
  188. data/spec/support/warnings.yml +0 -6
  189. data/spec/unit/mutant/diff_spec.rb +0 -189
  190. data/spec/unit/mutant/variable_spec.rb +0 -618
@@ -1,45 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- RSpec.shared_examples 'no block evaluation' do
4
- context 'with block' do
5
- let(:block) { -> { fail } }
6
-
7
- it 'does not evaluate block' do
8
- apply
9
- end
10
- end
11
- end
12
-
13
- RSpec.shared_examples 'requires block' do
14
- context 'without block' do
15
- let(:block) { nil }
16
-
17
- specify do
18
- expect { apply }.to raise_error(LocalJumpError)
19
- end
20
- end
21
- end
22
-
23
- RSpec.shared_examples 'returns self' do
24
- it 'returns self' do
25
- expect(apply).to be(subject)
26
- end
27
- end
28
-
29
- RSpec.shared_examples '#apply block evaluation' do
30
- it 'evaluates block and returns its wrapped result' do
31
- expect { expect(apply).to eql(block_result) }
32
- .to change(yields, :to_a)
33
- .from([])
34
- .to([value])
35
- end
36
- end
37
-
38
- RSpec.shared_examples 'Functor#fmap block evaluation' do
39
- it 'evaluates block and returns its wrapped result' do
40
- expect { expect(apply).to eql(described_class.new(block_result)) }
41
- .to change(yields, :to_a)
42
- .from([])
43
- .to([value])
44
- end
45
- end
@@ -1,7 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module TestApp
4
- def self.root
5
- File.expand_path('../../test_app', __dir__)
6
- end
7
- end # TestApp
@@ -1,6 +0,0 @@
1
- ---
2
- - "lib/mutant/subject/method/instance.rb:9: warning: undefining `initialize' may cause serious problems"
3
- - 'lib/parallel.rb:222: warning: shadowing outer local variable - args'
4
- - 'lib/parallel.rb:227: warning: shadowing outer local variable - args'
5
- - 'lib/parser/lexer.rb:10836: warning: assigned but unused variable - testEof'
6
- - 'lib/regexp_parser/scanner.rb:1146: warning: assigned but unused variable - testEof'
@@ -1,189 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- RSpec.describe Mutant::Diff do
4
- let(:object) { described_class }
5
-
6
- describe '.build' do
7
-
8
- subject { object.build(old_string, new_string) }
9
-
10
- let(:old_string) { "foo\nbar" }
11
- let(:new_string) { "bar\nbaz" }
12
-
13
- it { should eql(Mutant::Diff.new(%w[foo bar], %w[bar baz])) }
14
-
15
- end
16
-
17
- describe '#colorized_diff' do
18
- let(:object) { described_class.new(old, new) }
19
-
20
- subject { object.colorized_diff }
21
-
22
- context 'when there is a diff at begin of hunk' do
23
- let(:old) { %w[foo bar] }
24
- let(:new) { %w[baz bar] }
25
-
26
- let(:expectation) do
27
- [
28
- "@@ -1,3 +1,3 @@\n",
29
- Mutant::Color::RED.format("-foo\n"),
30
- Mutant::Color::GREEN.format("+baz\n"),
31
- " bar\n"
32
- ].join
33
- end
34
-
35
- it { should eql(expectation) }
36
-
37
- it_should_behave_like 'an idempotent method'
38
- end
39
-
40
- context 'when there is no diff' do
41
- let(:old) { '' }
42
- let(:new) { '' }
43
-
44
- it { should be(nil) }
45
-
46
- it_should_behave_like 'an idempotent method'
47
- end
48
- end
49
-
50
- describe '#diff' do
51
- let(:object) { described_class.new(old, new) }
52
-
53
- subject { object.diff }
54
-
55
- context 'when there is a diff at begin and end' do
56
- let(:old) { %w[foo bar foo] }
57
- let(:new) { %w[baz bar baz] }
58
-
59
- let(:expectation) do
60
- <<~STR
61
- @@ -1,4 +1,4 @@
62
- -foo
63
- +baz
64
- bar
65
- -foo
66
- +baz
67
- STR
68
- end
69
-
70
- it { should eql(expectation) }
71
-
72
- it_should_behave_like 'an idempotent method'
73
- end
74
-
75
- context 'when there is a diff at begin of hunk' do
76
- let(:old) { %w[foo bar] }
77
- let(:new) { %w[baz bar] }
78
-
79
- let(:expectation) do
80
- <<~STR
81
- @@ -1,3 +1,3 @@
82
- -foo
83
- +baz
84
- bar
85
- STR
86
- end
87
-
88
- it { should eql(expectation) }
89
-
90
- it_should_behave_like 'an idempotent method'
91
- end
92
-
93
- context 'when there is a diff NOT at begin of hunk' do
94
- let(:old) { %w[foo bar] }
95
- let(:new) { %w[foo baz bar] }
96
-
97
- let(:expectation) do
98
- <<~STR
99
- @@ -1,3 +1,4 @@
100
- foo
101
- +baz
102
- bar
103
- STR
104
- end
105
-
106
- it { should eql(expectation) }
107
-
108
- it_should_behave_like 'an idempotent method'
109
- end
110
-
111
- context 'when the diff has a long context at begin' do
112
- let(:old) { %w[foo bar baz boz a b c] }
113
- let(:new) { %w[foo bar baz boz a b c other] }
114
-
115
- let(:expectation) do
116
- <<~STR
117
- @@ -1,8 +1,9 @@
118
- foo
119
- bar
120
- baz
121
- boz
122
- a
123
- b
124
- c
125
- +other
126
- STR
127
- end
128
-
129
- it { should eql(expectation) }
130
-
131
- it_should_behave_like 'an idempotent method'
132
- end
133
-
134
- context 'when the diff has a long context at end, deleting' do
135
- let(:old) { %w[other foo bar baz boz a b c] }
136
- let(:new) { %w[foo bar baz boz a b c] }
137
-
138
- let(:expectation) do
139
- <<~STR
140
- @@ -1,9 +1,8 @@
141
- -other
142
- foo
143
- bar
144
- baz
145
- boz
146
- a
147
- b
148
- c
149
- STR
150
- end
151
-
152
- it { should eql(expectation) }
153
-
154
- it_should_behave_like 'an idempotent method'
155
- end
156
-
157
- context 'when the diff has a long context at end, inserting' do
158
- let(:old) { %w[foo bar baz boz a b c] }
159
- let(:new) { %w[other foo bar baz boz a b c] }
160
-
161
- let(:expectation) do
162
- <<~STR
163
- @@ -1,8 +1,9 @@
164
- +other
165
- foo
166
- bar
167
- baz
168
- boz
169
- a
170
- b
171
- c
172
- STR
173
- end
174
-
175
- it { should eql(expectation) }
176
-
177
- it_should_behave_like 'an idempotent method'
178
- end
179
-
180
- context 'when there is no diff' do
181
- let(:old) { '' }
182
- let(:new) { '' }
183
-
184
- it { should be(nil) }
185
-
186
- it_should_behave_like 'an idempotent method'
187
- end
188
- end
189
- end
@@ -1,618 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module MutantSpec
4
- module VariableHelper
5
- def empty
6
- described_class.new(
7
- condition_variable: condition_variable_class,
8
- mutex: mutex_class
9
- )
10
- end
11
-
12
- def full(value)
13
- described_class.new(
14
- condition_variable: condition_variable_class,
15
- mutex: mutex_class,
16
- value: value
17
- )
18
- end
19
-
20
- # rubocop:disable Metrics/AbcSize
21
- # rubocop:disable Metrics/MethodLength
22
- def self.shared_setup
23
- lambda do |_host|
24
- let(:condition_variable_class) { class_double(ConditionVariable) }
25
- let(:expected_result) { value }
26
- let(:full_condition) { instance_double(ConditionVariable, 'full') }
27
- let(:mutex) { instance_double(Mutex) }
28
- let(:mutex_class) { class_double(Mutex) }
29
- let(:value) { instance_double(Object, 'value') }
30
-
31
- let(:synchronize) do
32
- {
33
- receiver: mutex,
34
- selector: :synchronize,
35
- reaction: { yields: [] }
36
- }
37
- end
38
-
39
- let(:signal_full) do
40
- {
41
- receiver: full_condition,
42
- selector: :signal
43
- }
44
- end
45
-
46
- let(:put) do
47
- {
48
- receiver: full_condition,
49
- selector: :wait,
50
- arguments: [mutex],
51
- reaction: { execute: -> { subject.put(value) } }
52
- }
53
- end
54
-
55
- let(:wait_empty) do
56
- {
57
- receiver: empty_condition,
58
- selector: :wait,
59
- arguments: [mutex]
60
- }
61
- end
62
-
63
- let(:wait_full) do
64
- {
65
- receiver: full_condition,
66
- selector: :wait,
67
- arguments: [mutex]
68
- }
69
- end
70
-
71
- let(:signal_empty) do
72
- {
73
- receiver: empty_condition,
74
- selector: :signal
75
- }
76
- end
77
-
78
- shared_examples 'consumes events' do
79
- specify do
80
- verify_events do
81
- expect(apply).to eql(expected_result)
82
- end
83
- end
84
- end
85
- end
86
- end
87
- end
88
- end
89
-
90
- RSpec.describe Mutant::Variable::IVar do
91
- include MutantSpec::VariableHelper
92
-
93
- class_eval(&MutantSpec::VariableHelper.shared_setup)
94
-
95
- subject { empty }
96
-
97
- let(:setup) do
98
- [
99
- {
100
- receiver: condition_variable_class,
101
- selector: :new,
102
- reaction: { return: full_condition }
103
- },
104
- {
105
- receiver: mutex_class,
106
- selector: :new,
107
- reaction: { return: mutex }
108
- },
109
- synchronize
110
- ]
111
- end
112
-
113
- describe '#take' do
114
- def apply
115
- subject.take
116
- end
117
-
118
- context 'when ivar is initially full' do
119
- subject { full(value) }
120
-
121
- let(:raw_expectations) { setup }
122
-
123
- include_examples 'consumes events'
124
- end
125
-
126
- context 'when ivar is initially empty' do
127
- let(:raw_expectations) do
128
- [
129
- *setup,
130
- put,
131
- synchronize,
132
- signal_full
133
- ]
134
- end
135
-
136
- include_examples 'consumes events'
137
- end
138
- end
139
-
140
- describe '#take_timeout' do
141
- def apply
142
- subject.take_timeout(1.0)
143
- end
144
-
145
- context 'when ivar is initially full' do
146
- subject { full(value) }
147
-
148
- let(:raw_expectations) { setup }
149
-
150
- let(:expected_result) do
151
- Mutant::Variable.const_get(:Result)::Value.new(value)
152
- end
153
-
154
- include_examples 'consumes events'
155
- end
156
-
157
- context 'when ivar is initially empty' do
158
- def wait(time)
159
- {
160
- receiver: full_condition,
161
- selector: :wait,
162
- arguments: [mutex, time]
163
- }
164
- end
165
-
166
- def elapsed(time)
167
- {
168
- receiver: Mutant::Timer,
169
- selector: :elapsed,
170
- reaction: { yields: [], return: time }
171
- }
172
- end
173
-
174
- context 'and timeout occurs before value is put' do
175
- let(:expected_result) do
176
- Mutant::Variable.const_get(:Result)::Timeout.new
177
- end
178
-
179
- context 'wait exactly runs to zero left time on the clock' do
180
- let(:raw_expectations) do
181
- [
182
- *setup,
183
- elapsed(0.5),
184
- wait(1.0),
185
- elapsed(0.5),
186
- wait(0.5)
187
- ]
188
- end
189
-
190
- include_examples 'consumes events'
191
- end
192
-
193
- context 'wait overruns timeout' do
194
- let(:raw_expectations) do
195
- [
196
- *setup,
197
- elapsed(1.5),
198
- wait(1.0)
199
- ]
200
- end
201
-
202
- include_examples 'consumes events'
203
- end
204
- end
205
-
206
- context 'and put occurs before timeout' do
207
- let(:expected_result) do
208
- Mutant::Variable.const_get(:Result)::Value.new(value)
209
- end
210
-
211
- let(:raw_expectations) do
212
- [
213
- *setup,
214
- elapsed(0.5),
215
- wait(1.0).merge(reaction: { execute: -> { subject.put(value) } }),
216
- synchronize,
217
- signal_full
218
- ]
219
- end
220
-
221
- include_examples 'consumes events'
222
- end
223
- end
224
- end
225
-
226
- describe '#put' do
227
- def apply
228
- subject.put(value)
229
- end
230
-
231
- context 'when ivar is initially empty' do
232
- context 'when not reading result' do
233
- let(:expected_result) { subject }
234
-
235
- let(:raw_expectations) do
236
- [
237
- *setup,
238
- signal_full
239
- ]
240
- end
241
-
242
- include_examples 'consumes events'
243
- end
244
-
245
- context 'when reading result back' do
246
- let(:expected_result) { value }
247
-
248
- def apply
249
- super
250
- subject.read
251
- end
252
-
253
- let(:raw_expectations) do
254
- [
255
- *setup,
256
- signal_full,
257
- synchronize
258
- ]
259
- end
260
-
261
- include_examples 'consumes events'
262
- end
263
- end
264
-
265
- context 'when ivar is initially full' do
266
- subject { full(value) }
267
-
268
- let(:raw_expectations) { setup }
269
-
270
- it 'raises expected exception' do
271
- verify_events do
272
- expect { apply }.to raise_error(Mutant::Variable::IVar::Error, 'is immutable')
273
- end
274
- end
275
- end
276
- end
277
-
278
- describe '#try_put' do
279
- def apply
280
- subject.try_put(value)
281
- end
282
-
283
- let(:expected_result) { subject }
284
-
285
- context 'when ivar is initially empty' do
286
- let(:raw_expectations) do
287
- [
288
- *setup,
289
- signal_full
290
- ]
291
- end
292
-
293
- include_examples 'consumes events'
294
-
295
- context 'reading the put value' do
296
- let(:expected_result) { value }
297
-
298
- let(:raw_expectations) do
299
- [
300
- *super(),
301
- synchronize
302
- ]
303
- end
304
-
305
- def apply
306
- super
307
- subject.read
308
- end
309
-
310
- include_examples 'consumes events'
311
- end
312
- end
313
-
314
- context 'when ivar is initially full' do
315
- subject { full(value) }
316
-
317
- let(:raw_expectations) { setup }
318
-
319
- include_examples 'consumes events'
320
- end
321
- end
322
-
323
- describe '#read' do
324
- def apply
325
- subject.read
326
- end
327
-
328
- context 'when ivar is initially empty' do
329
- let(:raw_expectations) do
330
- [
331
- *setup,
332
- wait_full.merge(reaction: { execute: -> { subject.put(value) } }),
333
- synchronize,
334
- signal_full
335
- ]
336
- end
337
-
338
- include_examples 'consumes events'
339
- end
340
-
341
- context 'when ivar is initially full' do
342
- subject { full(value) }
343
-
344
- let(:raw_expectations) { setup }
345
-
346
- include_examples 'consumes events'
347
- end
348
- end
349
-
350
- describe '#with' do
351
- def apply
352
- subject.with do |value|
353
- @value = value
354
- end
355
- end
356
-
357
- before { @value = nil }
358
-
359
- context 'when ivar is initially full' do
360
- subject { full(value) }
361
-
362
- let(:raw_expectations) { setup }
363
-
364
- include_examples 'consumes events'
365
-
366
- it 'should yield value' do
367
- verify_events do
368
- expect { apply }.to change { @value }.from(nil).to(value)
369
- end
370
- end
371
- end
372
-
373
- context 'when ivar is initially empty' do
374
- subject { empty }
375
-
376
- let(:raw_expectations) do
377
- [
378
- *setup,
379
- put,
380
- synchronize,
381
- signal_full
382
- ]
383
- end
384
-
385
- include_examples 'consumes events'
386
-
387
- it 'should yield value' do
388
- verify_events do
389
- expect { apply }.to change { @value }.from(nil).to(value)
390
- end
391
- end
392
- end
393
- end
394
- end
395
-
396
- describe Mutant::Variable::MVar do
397
- include MutantSpec::VariableHelper
398
-
399
- class_eval(&MutantSpec::VariableHelper.shared_setup)
400
-
401
- subject { empty }
402
-
403
- let(:empty_condition) { instance_double(ConditionVariable, 'empty') }
404
-
405
- let(:setup) do
406
- [
407
- {
408
- receiver: condition_variable_class,
409
- selector: :new,
410
- reaction: { return: full_condition }
411
- },
412
- {
413
- receiver: mutex_class,
414
- selector: :new,
415
- reaction: { return: mutex }
416
- },
417
- {
418
- receiver: condition_variable_class,
419
- selector: :new,
420
- reaction: { return: empty_condition }
421
- },
422
- synchronize
423
- ]
424
- end
425
-
426
- describe '#put' do
427
- def apply
428
- subject.put(value)
429
- end
430
-
431
- context 'when ivar is initially empty' do
432
- context 'when not reading result' do
433
- let(:expected_result) { subject }
434
-
435
- let(:raw_expectations) do
436
- [
437
- *setup,
438
- signal_full
439
- ]
440
- end
441
-
442
- include_examples 'consumes events'
443
- end
444
-
445
- context 'when reading result back' do
446
- let(:expected_result) { value }
447
-
448
- def apply
449
- super
450
- subject.read
451
- end
452
-
453
- let(:raw_expectations) do
454
- [
455
- *setup,
456
- signal_full,
457
- synchronize
458
- ]
459
- end
460
-
461
- include_examples 'consumes events'
462
- end
463
- end
464
-
465
- context 'when ivar is initially full' do
466
- context 'when not reading result' do
467
- subject { full(value) }
468
-
469
- let(:expected_result) { subject }
470
-
471
- let(:raw_expectations) do
472
- [
473
- *setup,
474
- wait_empty.merge(reaction: { execute: -> { subject.take } }),
475
- synchronize,
476
- signal_empty,
477
- signal_full
478
- ]
479
- end
480
-
481
- include_examples 'consumes events'
482
- end
483
-
484
- context 'when reading result back' do
485
- subject { full(value) }
486
-
487
- def apply
488
- super
489
- subject.read
490
- end
491
-
492
- let(:expected_result) { value }
493
-
494
- let(:raw_expectations) do
495
- [
496
- *setup,
497
- wait_empty.merge(reaction: { execute: -> { subject.take } }),
498
- synchronize,
499
- signal_empty,
500
- signal_full,
501
- synchronize
502
- ]
503
- end
504
-
505
- include_examples 'consumes events'
506
- end
507
- end
508
- end
509
-
510
- describe '#modify' do
511
- let(:expected_result) { 1 }
512
- let(:value) { 0 }
513
-
514
- def apply
515
- subject.modify(&:succ)
516
- end
517
-
518
- context 'when ivar is initially empty' do
519
- let(:raw_expectations) do
520
- [
521
- *setup,
522
- wait_full.merge(reaction: { execute: -> { subject.put(value) } }),
523
- synchronize,
524
- signal_full,
525
- signal_full
526
- ]
527
- end
528
-
529
- include_examples 'consumes events'
530
- end
531
-
532
- context 'when ivar is initially full' do
533
- subject { full(value) }
534
-
535
- let(:raw_expectations) do
536
- [
537
- *setup,
538
- signal_full
539
- ]
540
- end
541
-
542
- include_examples 'consumes events'
543
- end
544
- end
545
-
546
- describe '#take' do
547
- def apply
548
- subject.take
549
- end
550
-
551
- context 'when ivar is initially empty' do
552
- let(:expected_result) { value }
553
-
554
- let(:raw_expectations) do
555
- [
556
- *setup,
557
- wait_full.merge(reaction: { execute: -> { subject.put(value) } }),
558
- synchronize,
559
- signal_full,
560
- signal_empty
561
- ]
562
- end
563
-
564
- include_examples 'consumes events'
565
- end
566
-
567
- context 'when ivar is initially full' do
568
- subject { full(value) }
569
-
570
- let(:expected_result) { value }
571
-
572
- let(:raw_expectations) do
573
- [
574
- *setup,
575
- signal_empty
576
- ]
577
- end
578
-
579
- include_examples 'consumes events'
580
- end
581
- end
582
- end
583
-
584
- describe Mutant::Variable.const_get(:Result)::Value do
585
- subject { described_class.new(nil) }
586
-
587
- describe '#timeout?' do
588
- def apply
589
- subject.timeout?
590
- end
591
-
592
- it 'returns false' do
593
- expect(apply).to be(false)
594
- end
595
- end
596
- end
597
-
598
- describe Mutant::Variable.const_get(:Result)::Timeout do
599
- describe '.new' do
600
- it 'is instance of timeout' do
601
- expect(described_class.new.instance_of?(described_class)).to be(true)
602
- end
603
-
604
- it 'is idempotent' do
605
- expect(described_class.new).to be(described_class.new)
606
- end
607
- end
608
-
609
- describe '#timeout?' do
610
- def apply
611
- subject.timeout?
612
- end
613
-
614
- it 'returns true' do
615
- expect(apply).to be(true)
616
- end
617
- end
618
- end