mutant 0.9.5 → 0.9.6

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
2
  SHA256:
3
- metadata.gz: da54128dceeae02111b3708c3b3bdc80d49d926661069bb1e852468ceaad0502
4
- data.tar.gz: 3a925f8be1f50b4fa767047324e06a268a8ba3f6b2b5797b795bd1581c69a84f
3
+ metadata.gz: ef6c23cfd4cebac6873c8d422c919b3821a4eb09cb77b8b9786185fb711c7f70
4
+ data.tar.gz: 3035168adda27d5ba4476606ddbf84ddeba62d00bf12a9a26d9b55fcc48a8a74
5
5
  SHA512:
6
- metadata.gz: bd0520621ef6fb51b2e31ca9232d1d56226a867a8684e7246a83b20382e506ac0e86457f8ac7a1d9d602f70f7459207153464e3c1cabb63144f3634a85f1a73f
7
- data.tar.gz: 7293cb707fee3343a7e089b4c7ba35487262c35740a3caf3392fad5ec7f3d956a2fd54c43f5925deb1cb6e99e2f0b146fc2af4ab2a16ad5e339206e5d71c178e
6
+ metadata.gz: 0b137d304dfd008cb9e12373c9665fcd494ddaad91e630ee1cd0bf96ace97abb0181513d152d61dba38dab9ed71f9a473b441983e9e04361e1c4bced66449410
7
+ data.tar.gz: f1566c734cb33af620ae3a1d440cd26f9b2c8f8ecf9665bfade140438b5d5e2e8c21732db42cb6bb2130aae87481a11324ca47dac4fb51f17065ee7e2262f8f6
@@ -1,3 +1,8 @@
1
+ # v0.9.6 2020-04-20
2
+
3
+ * Dependencies upgrade, should not change user facing semantics.
4
+ * Bump license nudge to 40s
5
+
1
6
  # v0.9.5 2020-02-02
2
7
 
3
8
  * Change to 2.7 parser series.
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- mutant (0.9.4)
4
+ mutant (0.9.6)
5
5
  abstract_type (~> 0.0.7)
6
6
  adamantium (~> 0.2.0)
7
7
  anima (~> 0.3.1)
@@ -15,6 +15,7 @@ PATH
15
15
  parser (~> 2.7.0.2)
16
16
  procto (~> 0.0.2)
17
17
  unparser (~> 0.4.6)
18
+ variable (~> 0.0.1)
18
19
 
19
20
  GEM
20
21
  remote: https://rubygems.org/
@@ -142,6 +143,8 @@ GEM
142
143
  equalizer (~> 0.0.9)
143
144
  parser (>= 2.6.5)
144
145
  procto (~> 0.0.2)
146
+ variable (0.0.1)
147
+ equalizer (~> 0.0.11)
145
148
  virtus (1.0.5)
146
149
  axiom-types (~> 0.1)
147
150
  coercible (~> 1.0)
@@ -21,6 +21,7 @@ require 'set'
21
21
  require 'singleton'
22
22
  require 'stringio'
23
23
  require 'unparser'
24
+ require 'variable'
24
25
  require 'yaml'
25
26
 
26
27
  # This setting is done to make errors within the parallel
@@ -185,7 +186,6 @@ require 'mutant/reporter/cli/format'
185
186
  require 'mutant/repository'
186
187
  require 'mutant/repository/diff'
187
188
  require 'mutant/repository/diff/ranges'
188
- require 'mutant/variable'
189
189
  require 'mutant/warnings'
190
190
  require 'mutant/zombifier'
191
191
  require 'mutant/range'
@@ -4,7 +4,7 @@ module Mutant
4
4
  module License
5
5
  NAME = 'mutant-license'
6
6
  VERSION = '~> 0.1.0'
7
- SLEEP = 20
7
+ SLEEP = 40
8
8
 
9
9
  UNLICENSED =
10
10
  IceNine.deep_freeze(
@@ -52,7 +52,7 @@ module Mutant
52
52
  # @param [Class] klass
53
53
  # @param [Config] config
54
54
  #
55
- # @return [Mutant::Variable]
55
+ # @return [Variable]
56
56
  #
57
57
  # ignore :reek:LongParameterList
58
58
  def self.shared(klass, config, **attributes)
@@ -2,5 +2,5 @@
2
2
 
3
3
  module Mutant
4
4
  # Current mutant version
5
- VERSION = '0.9.5'
5
+ VERSION = '0.9.6'
6
6
  end # Mutant
@@ -34,6 +34,7 @@ Gem::Specification.new do |gem|
34
34
  gem.add_runtime_dependency('parser', '~> 2.7.0.2')
35
35
  gem.add_runtime_dependency('procto', '~> 0.0.2')
36
36
  gem.add_runtime_dependency('unparser', '~> 0.4.6')
37
+ gem.add_runtime_dependency('variable', '~> 0.0.1')
37
38
 
38
39
  gem.add_development_dependency('devtools', '~> 0.1.25')
39
40
  gem.add_development_dependency('parallel', '~> 1.3')
@@ -2,13 +2,14 @@
2
2
  - name: rubyspec
3
3
  namespace: Rubyspec
4
4
  repo_uri: 'https://github.com/ruby/rubyspec.git'
5
- repo_ref: 'origin/master'
5
+ repo_ref: 249a36c2e9fcddbb208a0d618d05f6bd9a64fd17
6
6
  integration: mspec
7
7
  mutation_coverage: false
8
8
  mutation_generation: true
9
9
  exclude:
10
10
  - command_line/fixtures/bad_syntax.rb
11
11
  - command_line/fixtures/freeze_flag_required_diff_enc.rb
12
+ - core/file/stat_spec.rb
12
13
  - core/kernel/shared/sprintf_encoding.rb
13
14
  - core/module/fixtures/autoload_empty.rb
14
15
  - core/module/fixtures/autoload_never_set.rb
@@ -26,6 +27,7 @@
26
27
  - language/predefined/fixtures/data_only.rb
27
28
  - language/source_encoding_spec.rb
28
29
  - library/base64/decode64_spec.rb
30
+ - library/cgi/escapeHTML_spec.rb
29
31
  - security/cve_2010_1330_spec.rb
30
32
  - name: regexp_parser
31
33
  namespace: Regexp
@@ -89,7 +89,7 @@ RSpec.describe Mutant::License do
89
89
 
90
90
  expect(stderr)
91
91
  .to have_received(:puts)
92
- .with('[Mutant-License-Error]: Soft fail, continuing in 20 seconds')
92
+ .with('[Mutant-License-Error]: Soft fail, continuing in 40 seconds')
93
93
  .ordered
94
94
 
95
95
  expect(stderr)
@@ -104,7 +104,7 @@ RSpec.describe Mutant::License do
104
104
 
105
105
  expect(kernel)
106
106
  .to have_received(:sleep)
107
- .with(20)
107
+ .with(40)
108
108
  .ordered
109
109
  end
110
110
  end
@@ -16,15 +16,15 @@ RSpec.describe Mutant::Parallel::Driver do
16
16
  end
17
17
 
18
18
  let(:var_active_jobs) do
19
- instance_double(Mutant::Variable::IVar, 'active jobs')
19
+ instance_double(Variable::IVar, 'active jobs')
20
20
  end
21
21
 
22
22
  let(:var_final) do
23
- instance_double(Mutant::Variable::IVar, 'final')
23
+ instance_double(Variable::IVar, 'final')
24
24
  end
25
25
 
26
26
  let(:var_sink) do
27
- instance_double(Mutant::Variable::IVar, 'sink')
27
+ instance_double(Variable::IVar, 'sink')
28
28
  end
29
29
 
30
30
  subject do
@@ -64,7 +64,7 @@ RSpec.describe Mutant::Parallel::Driver do
64
64
  receiver: var_final,
65
65
  selector: :take_timeout,
66
66
  arguments: [timeout],
67
- reaction: { return: Mutant::Variable.const_get(:Result)::Timeout.new }
67
+ reaction: { return: Variable.const_get(:Result)::Timeout.new }
68
68
  },
69
69
  {
70
70
  receiver: var_active_jobs,
@@ -31,23 +31,23 @@ RSpec.describe Mutant::Parallel::Worker do
31
31
  end
32
32
 
33
33
  let(:var_active_jobs) do
34
- instance_double(Mutant::Variable::IVar, 'active jobs')
34
+ instance_double(Variable::IVar, 'active jobs')
35
35
  end
36
36
 
37
37
  let(:var_final) do
38
- instance_double(Mutant::Variable::IVar, 'final')
38
+ instance_double(Variable::IVar, 'final')
39
39
  end
40
40
 
41
41
  let(:var_running) do
42
- instance_double(Mutant::Variable::MVar, 'running')
42
+ instance_double(Variable::MVar, 'running')
43
43
  end
44
44
 
45
45
  let(:var_sink) do
46
- instance_double(Mutant::Variable::IVar, 'sink')
46
+ instance_double(Variable::IVar, 'sink')
47
47
  end
48
48
 
49
49
  let(:var_source) do
50
- instance_double(Mutant::Variable::IVar, 'source')
50
+ instance_double(Variable::IVar, 'source')
51
51
  end
52
52
 
53
53
  subject do
@@ -30,28 +30,28 @@ RSpec.describe Mutant::Parallel do
30
30
  end
31
31
 
32
32
  let(:var_active_jobs) do
33
- instance_double(Mutant::Variable::IVar, 'active jobs')
33
+ instance_double(Variable::IVar, 'active jobs')
34
34
  end
35
35
 
36
36
  let(:var_final) do
37
- instance_double(Mutant::Variable::IVar, 'final')
37
+ instance_double(Variable::IVar, 'final')
38
38
  end
39
39
 
40
40
  let(:var_running) do
41
- instance_double(Mutant::Variable::MVar, 'running')
41
+ instance_double(Variable::MVar, 'running')
42
42
  end
43
43
 
44
44
  let(:var_sink) do
45
- instance_double(Mutant::Variable::IVar, 'sink')
45
+ instance_double(Variable::IVar, 'sink')
46
46
  end
47
47
 
48
48
  let(:var_source) do
49
- instance_double(Mutant::Variable::IVar, 'source')
49
+ instance_double(Variable::IVar, 'source')
50
50
  end
51
51
 
52
52
  def ivar(value, **attributes)
53
53
  {
54
- receiver: Mutant::Variable::IVar,
54
+ receiver: Variable::IVar,
55
55
  selector: :new,
56
56
  arguments: [
57
57
  condition_variable: condition_variable,
@@ -63,7 +63,7 @@ RSpec.describe Mutant::Parallel do
63
63
  end
64
64
 
65
65
  def mvar(*arguments)
66
- ivar(*arguments).merge(receiver: Mutant::Variable::MVar)
66
+ ivar(*arguments).merge(receiver: Variable::MVar)
67
67
  end
68
68
 
69
69
  let(:raw_expectations) do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mutant
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.5
4
+ version: 0.9.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Markus Schirp
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-02-02 00:00:00.000000000 Z
11
+ date: 2020-04-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: abstract_type
@@ -192,6 +192,20 @@ dependencies:
192
192
  - - "~>"
193
193
  - !ruby/object:Gem::Version
194
194
  version: 0.4.6
195
+ - !ruby/object:Gem::Dependency
196
+ name: variable
197
+ requirement: !ruby/object:Gem::Requirement
198
+ requirements:
199
+ - - "~>"
200
+ - !ruby/object:Gem::Version
201
+ version: 0.0.1
202
+ type: :runtime
203
+ prerelease: false
204
+ version_requirements: !ruby/object:Gem::Requirement
205
+ requirements:
206
+ - - "~>"
207
+ - !ruby/object:Gem::Version
208
+ version: 0.0.1
195
209
  - !ruby/object:Gem::Dependency
196
210
  name: devtools
197
211
  requirement: !ruby/object:Gem::Requirement
@@ -409,7 +423,6 @@ files:
409
423
  - lib/mutant/timer.rb
410
424
  - lib/mutant/transform.rb
411
425
  - lib/mutant/util.rb
412
- - lib/mutant/variable.rb
413
426
  - lib/mutant/version.rb
414
427
  - lib/mutant/warnings.rb
415
428
  - lib/mutant/zombifier.rb
@@ -594,7 +607,6 @@ files:
594
607
  - spec/unit/mutant/transform/primitive_spec.rb
595
608
  - spec/unit/mutant/transform/sequence_spec.rb
596
609
  - spec/unit/mutant/util/one_spec.rb
597
- - spec/unit/mutant/variable_spec.rb
598
610
  - spec/unit/mutant/warnings_spec.rb
599
611
  - spec/unit/mutant/world_spec.rb
600
612
  - spec/unit/mutant/zombifier_spec.rb
@@ -625,7 +637,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
625
637
  - !ruby/object:Gem::Version
626
638
  version: '0'
627
639
  requirements: []
628
- rubygems_version: 3.0.3
640
+ rubygems_version: 3.1.2
629
641
  signing_key:
630
642
  specification_version: 4
631
643
  summary: ''
@@ -730,7 +742,6 @@ test_files:
730
742
  - spec/unit/mutant/transform/primitive_spec.rb
731
743
  - spec/unit/mutant/transform/sequence_spec.rb
732
744
  - spec/unit/mutant/util/one_spec.rb
733
- - spec/unit/mutant/variable_spec.rb
734
745
  - spec/unit/mutant/warnings_spec.rb
735
746
  - spec/unit/mutant/world_spec.rb
736
747
  - spec/unit/mutant/zombifier_spec.rb
@@ -1,282 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Mutant
4
- # Lightweight shared variables
5
- #
6
- # ignore :reek:TooManyMethods
7
- class Variable
8
- EMPTY = Class.new do
9
- const_set(:INSPECT, 'Mutant::Variable::EMPTY')
10
- end.new.freeze
11
-
12
- TIMEOUT = Class.new do
13
- const_set(:INSPECT, 'Mutant::Variable::TIMEOUT')
14
- end.new.freeze
15
-
16
- # Result of operation that may time out
17
- class Result
18
- include AbstractType, Adamantium::Flat
19
-
20
- # Test if take resulted in a timeout
21
- #
22
- # @return [Boolean]
23
- #
24
- # @api private
25
- def timeout?
26
- instance_of?(Timeout)
27
- end
28
-
29
- abstract_method :value
30
-
31
- # Instance returned on timeouts
32
- class Timeout < self
33
- include Equalizer.new
34
-
35
- INSTANCE = new
36
-
37
- # Construct new object
38
- #
39
- # @return [Timeout]
40
- def self.new
41
- INSTANCE
42
- end
43
- end # Timeout
44
-
45
- # Instance returned without timeouts
46
- class Value < self
47
- include Concord::Public.new(:value)
48
- end # Value
49
- end # Result
50
-
51
- private_constant(*constants(false))
52
-
53
- # Initialize object
54
- #
55
- # @param [Object] value
56
- # the initial value
57
- #
58
- # @return [undefined]
59
- def initialize(condition_variable:, mutex:, value: EMPTY)
60
- @full = condition_variable.new
61
- @mutex = mutex.new
62
- @value = value
63
- end
64
-
65
- # Take value from mvar, block on empty
66
- #
67
- # @return [Object]
68
- def take
69
- synchronize do
70
- wait_full
71
- perform_take
72
- end
73
- end
74
-
75
- # Take value from mvar, with timeout
76
- #
77
- # @param [Float] Timeout
78
- #
79
- # @return [Result::Timeout]
80
- # in case take resulted in a timeout
81
- #
82
- # @return [Result::Value]
83
- # in case take resulted in a value
84
- def take_timeout(timeout)
85
- synchronize do
86
- if wait_timeout(@full, timeout, &method(:full?))
87
- Result::Timeout.new
88
- else
89
- Result::Value.new(perform_take)
90
- end
91
- end
92
- end
93
-
94
- # Read value from variable
95
- #
96
- # @return [Object]
97
- # the contents of the mvar
98
- def read
99
- synchronize do
100
- wait_full
101
- @value
102
- end
103
- end
104
-
105
- # Try put value into the variable, non blocking
106
- #
107
- # @param [Object] value
108
- #
109
- # @return [self]
110
- def try_put(value)
111
- synchronize do
112
- perform_put(value) if empty?
113
- end
114
-
115
- self
116
- end
117
-
118
- # Execute block with value, blocking
119
- #
120
- # @yield [Object]
121
- #
122
- # @return [Object]
123
- # the blocks return value
124
- def with
125
- synchronize do
126
- wait_full
127
- yield @value
128
- end
129
- end
130
-
131
- private
132
-
133
- # Perform the put
134
- #
135
- # @param [Object] value
136
- def perform_put(value)
137
- (@value = value).tap { @full.signal }
138
- end
139
-
140
- # Execute block under mutex
141
- #
142
- # @return [self]
143
- def synchronize(&block)
144
- @mutex.synchronize(&block)
145
- end
146
-
147
- # Wait for block predicate
148
- #
149
- # @param [ConditionVariable] event
150
- #
151
- # @return [undefined]
152
- def wait(event)
153
- event.wait(@mutex) until yield
154
- end
155
-
156
- # Wait with timeout for block predicate
157
- #
158
- # @param [ConditionVariable] event
159
- #
160
- # @return [Boolean]
161
- # if wait was terminated due a timeout
162
- #
163
- # @return [undefined]
164
- # otherwise
165
- def wait_timeout(event, timeout)
166
- loop do
167
- break true if timeout <= 0
168
- break if yield
169
- timeout -= Timer.elapsed { event.wait(@mutex, timeout) }
170
- end
171
- end
172
-
173
- # Wait till mvar is full
174
- #
175
- # @return [undefined]
176
- def wait_full
177
- wait(@full, &method(:full?))
178
- end
179
-
180
- # Test if state is full
181
- #
182
- # @return [Boolean]
183
- def full?
184
- !empty?
185
- end
186
-
187
- # Test if state is empty
188
- #
189
- # @return [Boolean]
190
- def empty?
191
- @value.equal?(EMPTY)
192
- end
193
-
194
- # Shared variable that can be written at most once
195
- #
196
- # ignore :reek:InstanceVariableAssumption
197
- class IVar < self
198
-
199
- # Exception raised on ivar errors
200
- class Error < RuntimeError; end
201
-
202
- # Put valie into the mvar, raises if already full
203
- #
204
- # @param [Object] value
205
- #
206
- # @return [self]
207
- #
208
- # @raise Error
209
- # if already full
210
- def put(value)
211
- synchronize do
212
- fail Error, 'is immutable' if full?
213
- perform_put(value)
214
- end
215
-
216
- self
217
- end
218
-
219
- private
220
-
221
- # Perform take operation
222
- #
223
- # @return [Object]
224
- def perform_take
225
- @value
226
- end
227
- end # IVar
228
-
229
- # Shared variable that can be written multiple times
230
- #
231
- # ignore :reek:InstanceVariableAssumption
232
- class MVar < self
233
-
234
- # Initialize object
235
- #
236
- # @param [Object] value
237
- # the initial value
238
- #
239
- # @return [undefined]
240
- def initialize(condition_variable:, mutex:, value: EMPTY)
241
- super
242
- @empty = condition_variable.new
243
- end
244
-
245
- # Put value into mvar, block on full
246
- #
247
- # @param [Object] value
248
- #
249
- # @return [self]
250
- def put(value)
251
- synchronize do
252
- wait(@empty, &method(:empty?))
253
- perform_put(value)
254
- end
255
-
256
- self
257
- end
258
-
259
- # Modify mvar
260
- #
261
- # @return [Object]
262
- def modify
263
- synchronize do
264
- wait_full
265
- perform_put(yield(@value))
266
- end
267
- end
268
-
269
- private
270
-
271
- # Empty the mvar
272
- #
273
- # @return [Object]
274
- def perform_take
275
- @value.tap do
276
- @value = EMPTY
277
- @empty.signal
278
- end
279
- end
280
- end # MVar
281
- end # Variable
282
- end # Mutant
@@ -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