async-rspec 1.13.0 → 1.14.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
2
  SHA256:
3
- metadata.gz: 97dcfa776e85aa05a958dccc0211b29022faf1fbe054a9c294070efd23785e97
4
- data.tar.gz: 267e2a08e809376bba96b59f80face4062d8782bf67406678a10c458cda9320c
3
+ metadata.gz: f46e5f7273a9f4b02334cb93c5af94692a1be38475e786650ba0bbe18b758bb4
4
+ data.tar.gz: 03dae4d878f4745f25185afa43712384b7045358492b7c7b403953d407e44210
5
5
  SHA512:
6
- metadata.gz: 5c68ec95f28cef903eeb5c806d76e8c22260a7ba662179c96c96b9eaa8af268c6fc5f8b519d9fbde914ad7933b7495ed4a1e6a1424f479e46b5ff295d5862938
7
- data.tar.gz: aa6aee44bb59f53f89a7a90f287728c946cd41508729b8274b92770c5fdafeab75d0fe5b72e90c359767eaa5f9a04ee05e7ea27ab5bd039791c308f7bf74b66a
6
+ metadata.gz: c97bc9bac72f0106c943f02562d5c94a2f4c01044611328a779cd7ee80f8dbac87d8cbfb1c820c7164cd538c4ec5a94a600439817457d30b4b640b65c3fd0986
7
+ data.tar.gz: 8d2b079fa24d81c270bd44dfad3ad4aed1456b100e03c5298661db9ae7a3a3f12bfc9eee7810416f2c6e5a103e4f38239f80d4ac24595f36b79ff36557ecfe46
@@ -3,7 +3,6 @@ cache: bundler
3
3
 
4
4
  matrix:
5
5
  include:
6
- - rvm: 2.3
7
6
  - rvm: 2.4
8
7
  - rvm: 2.5
9
8
  - rvm: 2.6
data/Gemfile CHANGED
@@ -3,6 +3,8 @@ source 'https://rubygems.org'
3
3
  # Specify your gem's dependencies in async-rspec.gemspec
4
4
  gemspec
5
5
 
6
+ # gem "async", path: "../async"
7
+
6
8
  group :test do
7
- gem "ruby-prof", platform: :mri
8
- end
9
+ gem "ruby-prof", git: "https://github.com/ruby-prof/ruby-prof"
10
+ end
data/README.md CHANGED
@@ -32,52 +32,7 @@ require 'async/rspec'
32
32
 
33
33
  ## Usage
34
34
 
35
- ### Leaks
36
-
37
- Leaking sockets and other kinds of IOs are a problem for long running services. `Async::RSpec::Leaks` tracks all open sockets both before and after the spec. If any are left open, a `RuntimeError` is raised and the spec fails.
38
-
39
- ```ruby
40
- RSpec.describe "leaky ios" do
41
- include_context Async::RSpec::Leaks
42
-
43
- # The following fails:
44
- it "leaks io" do
45
- @input, @output = IO.pipe
46
- end
47
- end
48
- ```
49
-
50
- In some cases, the Ruby garbage collector will close IOs. In the above case, it's possible that just writing `IO.pipe` will not leak as Ruby will garbage collect the resulting IOs immediately. It's still incorrect to not close IOs, so don't depend on this behaviour.
51
-
52
- ### Allocations
53
-
54
- Allocating large amounts of objects can lead to memery problems. `Async::RSpec::Memory` adds a `limit_allocations` matcher, which tracks the number of allocations and memory size for each object type and allows you to specify expected limits.
55
-
56
- ```ruby
57
- RSpec.describe "memory allocations" do
58
- include_context Async::RSpec::Memory
59
-
60
- it "limits allocation counts" do
61
- expect do
62
- 6.times{String.new}
63
- end.to limit_allocations(String => 10) # 10 strings can be allocated
64
- end
65
-
66
- it "limits allocation counts (hash)" do
67
- expect do
68
- 6.times{String.new}
69
- end.to limit_allocations(String => {count: 10}) # 10 strings can be allocated
70
- end
71
-
72
- it "limits allocation size" do
73
- expect do
74
- 6.times{String.new("foo")}
75
- end.to limit_allocations(String => {size: 1024}) # 1 KB of strings can be allocated
76
- end
77
- end
78
- ```
79
-
80
- ### Reactor
35
+ ### Async Reactor
81
36
 
82
37
  Many specs need to run within a reactor. A shared context is provided which includes all the relevant bits, including the above leaks checks. If your spec fails to run in less than 10 seconds, an `Async::TimeoutError` raises to prevent your test suite from hanging.
83
38
 
@@ -111,6 +66,37 @@ RSpec.describe Async::IO do
111
66
  end
112
67
  ```
113
68
 
69
+ ### Changing Timeout
70
+
71
+ You can change the timeout by specifying it as an option:
72
+
73
+ ```ruby
74
+ RSpec.describe MySlowThing, timeout: 60 do
75
+ # ...
76
+ end
77
+ ```
78
+
79
+ ### File Descriptor Leaks
80
+
81
+ Leaking sockets and other kinds of IOs are a problem for long running services. `Async::RSpec::Leaks` tracks all open sockets both before and after the spec. If any are left open, a `RuntimeError` is raised and the spec fails.
82
+
83
+ ```ruby
84
+ RSpec.describe "leaky ios" do
85
+ include_context Async::RSpec::Leaks
86
+
87
+ # The following fails:
88
+ it "leaks io" do
89
+ @input, @output = IO.pipe
90
+ end
91
+ end
92
+ ```
93
+
94
+ In some cases, the Ruby garbage collector will close IOs. In the above case, it's possible that just writing `IO.pipe` will not leak as Ruby will garbage collect the resulting IOs immediately. It's still incorrect to not close IOs, so don't depend on this behaviour.
95
+
96
+ ### Allocations
97
+
98
+ This functionality was moved to [`rspec-memory`](https://github.com/socketry/rspec-memory).
99
+
114
100
  ## Contributing
115
101
 
116
102
  1. Fork it
@@ -21,7 +21,7 @@ Gem::Specification.new do |spec|
21
21
  spec.add_dependency "rspec-files", "~> 1.0"
22
22
 
23
23
  # Since we test the shared contexts, we need some bits of async:
24
- spec.add_development_dependency "async", "~> 1.8"
24
+ spec.add_development_dependency "async", "~> 1.24"
25
25
 
26
26
  spec.add_development_dependency "covered"
27
27
  spec.add_development_dependency "bundler"
@@ -20,49 +20,58 @@
20
20
 
21
21
  require_relative 'leaks'
22
22
 
23
+ require 'kernel/async'
24
+
23
25
  require 'async/reactor'
24
26
  require 'async/debug/selector'
25
27
 
26
28
  module Async
27
29
  module RSpec
28
30
  module Reactor
29
- def run_example(reactor, example, duration)
31
+ def notify_failure(exception = $!)
32
+ ::RSpec::Support.notify_failure(exception)
33
+ end
34
+
35
+ def run_in_reactor(reactor, duration = nil)
30
36
  result = nil
31
37
 
38
+ timer_task = nil
39
+
40
+ if duration
41
+ timer_task = reactor.async do |task|
42
+ # Wait for the timeout, at any point this task might be cancelled if the user code completes:
43
+ task.annotate("timer task duration=#{duration}")
44
+ task.sleep(duration)
45
+
46
+ # The timeout expired, so generate an error:
47
+ buffer = StringIO.new
48
+ reactor.print_hierarchy(buffer)
49
+
50
+ # Raise an error so it is logged:
51
+ raise TimeoutError, "run time exceeded duration #{duration}s:\r\n#{buffer.string}"
52
+ end
53
+ end
54
+
32
55
  reactor.run do |task|
33
56
  task.annotate(self.class)
34
57
 
35
- reactor = task.reactor
36
- timer = nil
37
-
38
- if duration
39
- timer = reactor.async do |task|
40
- task.annotate("timer task duration=#{duration}")
41
- task.sleep(duration)
42
-
43
- buffer = StringIO.new
44
- reactor.print_hierarchy(buffer)
45
-
46
- reactor.stop
47
-
48
- raise TimeoutError, "run time exceeded duration #{duration}s:\r\n#{buffer.string}"
49
- end
50
- end
51
-
52
- task.async do |spec_task|
53
- spec_task.annotate("example runner")
58
+ spec_task = task.async do |spec_task|
59
+ spec_task.annotate("running example")
60
+
61
+ result = yield
54
62
 
55
- result = example.run
63
+ timer_task&.stop
56
64
 
57
- if result.is_a? Exception
58
- reactor.stop
59
- else
60
- spec_task.children&.each(&:wait)
61
- end
62
- end.wait
65
+ raise Async::Stop
66
+ end
63
67
 
64
- timer.stop if timer
65
- end
68
+ begin
69
+ timer_task&.wait
70
+ spec_task.wait
71
+ ensure
72
+ spec_task.stop
73
+ end
74
+ end.wait
66
75
 
67
76
  return result
68
77
  end
@@ -79,7 +88,9 @@ module Async
79
88
  duration = example.metadata.fetch(:timeout, 10)
80
89
 
81
90
  begin
82
- run_example(reactor, example, duration)
91
+ run_in_reactor(reactor, duration) do
92
+ example.run
93
+ end
83
94
  ensure
84
95
  reactor.close
85
96
  end
@@ -20,6 +20,6 @@
20
20
 
21
21
  module Async
22
22
  module RSpec
23
- VERSION = "1.13.0"
23
+ VERSION = "1.14.0"
24
24
  end
25
25
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: async-rspec
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.13.0
4
+ version: 1.14.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Samuel Williams
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-07-10 00:00:00.000000000 Z
11
+ date: 2019-12-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec
@@ -58,14 +58,14 @@ dependencies:
58
58
  requirements:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: '1.8'
61
+ version: '1.24'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: '1.8'
68
+ version: '1.24'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: covered
71
71
  requirement: !ruby/object:Gem::Requirement
@@ -149,7 +149,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
149
149
  - !ruby/object:Gem::Version
150
150
  version: '0'
151
151
  requirements: []
152
- rubygems_version: 3.0.3
152
+ rubygems_version: 3.0.6
153
153
  signing_key:
154
154
  specification_version: 4
155
155
  summary: Helpers for writing specs against the async gem.