timers 4.3.0 → 4.3.2

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: ccf7aa14dc18086e3a47fb44eb3a12569ba6752e6f7d22aecf7486684a594331
4
- data.tar.gz: 0c37cdab96fc3ae8a1fbd0deb07b69800260b32118c7d1b37d2a4114258c32e8
3
+ metadata.gz: 52ef1e26aab6a7bbbf5c9d687028bdc36f52810dd7ebc0c76873b6bef9f30ca2
4
+ data.tar.gz: 26105fe04a6d2bfcdf9efb46ebd83d9562a08af3c2f113892a8be57713be6112
5
5
  SHA512:
6
- metadata.gz: dcb1826464d594d78d0a67bf18f89bb3137ffdbdcb36306176bbaa961aab387b93442c4827f5a8e331b90de056dbc9f9f63dbdeb22671dcdd35203741f415967
7
- data.tar.gz: 43dcaccab4fab882ca498ec196f08d47beb2636044b62103640406e5a0411d1eb6d837363eae50266c11642a59880179eca6a9f4053aefab1b4daf11a28319bd
6
+ metadata.gz: 2a3ae0e0d9644627fef3aeffdfde86456d74c28ab89194486743fee2a25e8832c5aafb05f88174f6ee27d4f9402e05b4f80776c49cc34d70da527e63f9097685
7
+ data.tar.gz: 1f30b97aa11f6f42b3ce1786ae42f06334a86064306601635774b8d84cc88df765e8312a455798984520d44e3db35f8094fb23ec35cb736eb2191bfa27dece0c
@@ -1,11 +1,26 @@
1
1
  # frozen_string_literal: true
2
- #
3
- # This file is part of the "timers" project and released under the MIT license.
4
- #
5
- # Copyright, 2018, by Samuel Williams. All rights reserved.
6
- #
7
2
 
8
- require "timers/version"
3
+ # Copyright, 2020, by Samuel G. D. Williams. <http://www.codeotaku.com>
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the "Software"), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in
13
+ # all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ # THE SOFTWARE.
9
22
 
10
- require "timers/group"
11
- require "timers/wait"
23
+ require_relative "timers/version"
24
+
25
+ require_relative "timers/group"
26
+ require_relative "timers/wait"
@@ -1,9 +1,24 @@
1
1
  # frozen_string_literal: true
2
- #
3
- # This file is part of the "timers" project and released under the MIT license.
4
- #
5
- # Copyright, 2018, by Samuel Williams. All rights reserved.
6
- #
2
+
3
+ # Copyright, 2018, by Samuel G. D. Williams. <http://www.codeotaku.com>
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the "Software"), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in
13
+ # all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ # THE SOFTWARE.
7
22
 
8
23
  require_relative "timer"
9
24
 
@@ -1,9 +1,24 @@
1
1
  # frozen_string_literal: true
2
- #
3
- # This file is part of the "timers" project and released under the MIT license.
4
- #
5
- # Copyright, 2018, by Samuel Williams. All rights reserved.
6
- #
2
+
3
+ # Copyright, 2018, by Samuel G. D. Williams. <http://www.codeotaku.com>
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the "Software"), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in
13
+ # all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ # THE SOFTWARE.
7
22
 
8
23
  require "set"
9
24
  require "forwardable"
@@ -1,9 +1,24 @@
1
1
  # frozen_string_literal: true
2
- #
3
- # This file is part of the "timers" project and released under the MIT license.
4
- #
5
- # Copyright, 2018, by Samuel Williams. All rights reserved.
6
- #
2
+
3
+ # Copyright, 2018, by Samuel G. D. Williams. <http://www.codeotaku.com>
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the "Software"), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in
13
+ # all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ # THE SOFTWARE.
7
22
 
8
23
  module Timers
9
24
  # A collection of timers which may fire at different times
@@ -1,9 +1,24 @@
1
1
  # frozen_string_literal: true
2
- #
3
- # This file is part of the "timers" project and released under the MIT license.
4
- #
5
- # Copyright, 2018, by Samuel Williams. All rights reserved.
6
- #
2
+
3
+ # Copyright, 2018, by Samuel G. D. Williams. <http://www.codeotaku.com>
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the "Software"), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in
13
+ # all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ # THE SOFTWARE.
7
22
 
8
23
  module Timers
9
24
  # An individual timer set to fire a given proc at a given time. A timer is
@@ -1,10 +1,25 @@
1
1
  # frozen_string_literal: true
2
- #
3
- # This file is part of the "timers" project and released under the MIT license.
4
- #
5
- # Copyright, 2018, by Samuel Williams. All rights reserved.
6
- #
2
+
3
+ # Copyright, 2018, by Samuel G. D. Williams. <http://www.codeotaku.com>
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the "Software"), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in
13
+ # all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ # THE SOFTWARE.
7
22
 
8
23
  module Timers
9
- VERSION = "4.3.0"
24
+ VERSION = "4.3.2"
10
25
  end
@@ -1,9 +1,24 @@
1
1
  # frozen_string_literal: true
2
- #
3
- # This file is part of the "timers" project and released under the MIT license.
4
- #
5
- # Copyright, 2018, by Samuel Williams. All rights reserved.
6
- #
2
+
3
+ # Copyright, 2018, by Samuel G. D. Williams. <http://www.codeotaku.com>
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the "Software"), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in
13
+ # all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ # THE SOFTWARE.
7
22
 
8
23
  require_relative "interval"
9
24
 
metadata CHANGED
@@ -1,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: timers
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.3.0
4
+ version: 4.3.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Samuel Williams
8
8
  - Tony Arcieri
9
- autorequire:
9
+ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2019-01-21 00:00:00.000000000 Z
12
+ date: 2020-09-04 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
@@ -26,49 +26,39 @@ dependencies:
26
26
  - !ruby/object:Gem::Version
27
27
  version: '0'
28
28
  - !ruby/object:Gem::Dependency
29
- name: rspec
29
+ name: covered
30
30
  requirement: !ruby/object:Gem::Requirement
31
31
  requirements:
32
- - - "~>"
32
+ - - ">="
33
33
  - !ruby/object:Gem::Version
34
- version: '3.6'
34
+ version: '0'
35
35
  type: :development
36
36
  prerelease: false
37
37
  version_requirements: !ruby/object:Gem::Requirement
38
38
  requirements:
39
- - - "~>"
39
+ - - ">="
40
40
  - !ruby/object:Gem::Version
41
- version: '3.6'
41
+ version: '0'
42
42
  - !ruby/object:Gem::Dependency
43
- name: rake
43
+ name: rspec
44
44
  requirement: !ruby/object:Gem::Requirement
45
45
  requirements:
46
- - - ">="
46
+ - - "~>"
47
47
  - !ruby/object:Gem::Version
48
- version: '0'
48
+ version: '3.0'
49
49
  type: :development
50
50
  prerelease: false
51
51
  version_requirements: !ruby/object:Gem::Requirement
52
52
  requirements:
53
- - - ">="
53
+ - - "~>"
54
54
  - !ruby/object:Gem::Version
55
- version: '0'
56
- description: Schedule procs to run after a certain time, or at periodic intervals,
57
- using any API that accepts a timeout.
55
+ version: '3.0'
56
+ description:
58
57
  email:
59
- - samuel@codeotaku.com
60
- - bascule@gmail.com
61
58
  executables: []
62
59
  extensions: []
63
60
  extra_rdoc_files: []
64
61
  files:
65
- - ".editorconfig"
66
- - ".gitignore"
67
- - ".rspec"
68
- - ".travis.yml"
69
- - Gemfile
70
- - README.md
71
- - Rakefile
72
62
  - lib/timers.rb
73
63
  - lib/timers/events.rb
74
64
  - lib/timers/group.rb
@@ -76,20 +66,11 @@ files:
76
66
  - lib/timers/timer.rb
77
67
  - lib/timers/version.rb
78
68
  - lib/timers/wait.rb
79
- - spec/spec_helper.rb
80
- - spec/timers/cancel_spec.rb
81
- - spec/timers/events_spec.rb
82
- - spec/timers/every_spec.rb
83
- - spec/timers/group_spec.rb
84
- - spec/timers/performance_spec.rb
85
- - spec/timers/strict_spec.rb
86
- - spec/timers/wait_spec.rb
87
- - timers.gemspec
88
69
  homepage: https://github.com/socketry/timers
89
70
  licenses:
90
71
  - MIT
91
72
  metadata: {}
92
- post_install_message:
73
+ post_install_message:
93
74
  rdoc_options: []
94
75
  require_paths:
95
76
  - lib
@@ -97,23 +78,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
97
78
  requirements:
98
79
  - - ">="
99
80
  - !ruby/object:Gem::Version
100
- version: 2.2.1
81
+ version: '0'
101
82
  required_rubygems_version: !ruby/object:Gem::Requirement
102
83
  requirements:
103
84
  - - ">="
104
85
  - !ruby/object:Gem::Version
105
86
  version: '0'
106
87
  requirements: []
107
- rubygems_version: 3.0.1
108
- signing_key:
88
+ rubygems_version: 3.1.2
89
+ signing_key:
109
90
  specification_version: 4
110
- summary: Pure Ruby one-shot and periodic timers
111
- test_files:
112
- - spec/spec_helper.rb
113
- - spec/timers/cancel_spec.rb
114
- - spec/timers/events_spec.rb
115
- - spec/timers/every_spec.rb
116
- - spec/timers/group_spec.rb
117
- - spec/timers/performance_spec.rb
118
- - spec/timers/strict_spec.rb
119
- - spec/timers/wait_spec.rb
91
+ summary: Pure Ruby one-shot and periodic timers.
92
+ test_files: []
@@ -1,6 +0,0 @@
1
- root = true
2
-
3
- [*]
4
- indent_style = tab
5
- indent_size = 2
6
-
data/.gitignore DELETED
@@ -1,17 +0,0 @@
1
- *.gem
2
- *.rbc
3
- .bundle
4
- .config
5
- .yardoc
6
- Gemfile.lock
7
- InstalledFiles
8
- _yardoc
9
- coverage
10
- doc/
11
- lib/bundler/man
12
- pkg
13
- rdoc
14
- spec/reports
15
- test/tmp
16
- test/version_tmp
17
- tmp
data/.rspec DELETED
@@ -1,3 +0,0 @@
1
- --format documentation
2
- --warnings
3
- --require spec_helper
@@ -1,20 +0,0 @@
1
- language: ruby
2
- dist: xenial
3
- cache: bundler
4
-
5
- matrix:
6
- include:
7
- - rvm: 2.3
8
- - rvm: 2.4
9
- - rvm: 2.5
10
- - rvm: 2.6
11
- - rvm: jruby-head
12
- env: JRUBY_OPTS="--debug -X+O"
13
- - rvm: truffleruby
14
- - rvm: ruby-head
15
- - rvm: rbx-3
16
- allow_failures:
17
- - rvm: ruby-head
18
- - rvm: jruby-head
19
- - rvm: rbx-3
20
- - rvm: truffleruby
data/Gemfile DELETED
@@ -1,15 +0,0 @@
1
- source 'https://rubygems.org'
2
-
3
- gemspec
4
-
5
- group :development do
6
- gem 'pry'
7
- end
8
-
9
- group :test do
10
- gem 'benchmark-ips'
11
-
12
- gem "ruby-prof", platform: :mri
13
- gem 'simplecov', platform: :mri
14
- gem 'coveralls', platform: :mri
15
- end
data/README.md DELETED
@@ -1,149 +0,0 @@
1
- # Timers
2
-
3
- Collections of one-shot and periodic timers, intended for use with event loops such as [async].
4
-
5
- [![Build Status](https://secure.travis-ci.org/socketry/timers.svg)](https://travis-ci.org/socketry/timers)
6
- [![Code Climate](https://codeclimate.com/github/socketry/timers.svg)](https://codeclimate.com/github/socketry/timers)
7
- [![Coverage Status](https://coveralls.io/repos/socketry/timers/badge.svg)](https://coveralls.io/r/socketry/timers)
8
-
9
- [async]: https://github.com/socketry/async
10
-
11
- ## Installation
12
-
13
- Add this line to your application's Gemfile:
14
-
15
- ```ruby
16
- gem 'timers'
17
- ```
18
-
19
- And then execute:
20
-
21
- $ bundle
22
-
23
- Or install it yourself as:
24
-
25
- $ gem install timers
26
-
27
- ## Usage
28
-
29
- Create a new timer group with `Timers::Group.new`:
30
-
31
- ```ruby
32
- require 'timers'
33
-
34
- timers = Timers::Group.new
35
- ```
36
-
37
- Schedule a proc to run after 5 seconds with `Timers::Group#after`:
38
-
39
- ```ruby
40
- five_second_timer = timers.after(5) { puts "Take five" }
41
- ```
42
-
43
- The `five_second_timer` variable is now bound to a Timers::Timer object. To
44
- cancel a timer, use `Timers::Timer#cancel`
45
-
46
- Once you've scheduled a timer, you can wait until the next timer fires with `Timers::Group#wait`:
47
-
48
- ```ruby
49
- # Waits 5 seconds
50
- timers.wait
51
-
52
- # The script will now print "Take five"
53
- ```
54
-
55
- You can schedule a block to run periodically with `Timers::Group#every`:
56
-
57
- ```ruby
58
- every_five_seconds = timers.every(5) { puts "Another 5 seconds" }
59
-
60
- loop { timers.wait }
61
- ```
62
-
63
- You can also schedule a block to run immediately and periodically with `Timers::Group#now_and_every`:
64
- ```ruby
65
- now_and_every_five_seconds = timers.now_and_every(5) { puts "Now and in another 5 seconds" }
66
-
67
- loop { timers.wait }
68
- ```
69
-
70
- If you'd like another method to do the waiting for you, e.g. `Kernel.select`,
71
- you can use `Timers::Group#wait_interval` to obtain the amount of time to wait. When
72
- a timeout is encountered, you can fire all pending timers with `Timers::Group#fire`:
73
-
74
- ```ruby
75
- loop do
76
- interval = timers.wait_interval
77
- ready_readers, ready_writers = select readers, writers, nil, interval
78
-
79
- if ready_readers || ready_writers
80
- # Handle IO
81
- ...
82
- else
83
- # Timeout!
84
- timers.fire
85
- end
86
- end
87
- ```
88
-
89
- You can also pause and continue individual timers, or all timers:
90
-
91
- ```ruby
92
- paused_timer = timers.every(5) { puts "I was paused" }
93
-
94
- paused_timer.pause
95
- 10.times { timers.wait } # will not fire paused timer
96
-
97
- paused_timer.resume
98
- 10.times { timers.wait } # will fire timer
99
-
100
- timers.pause
101
- 10.times { timers.wait } # will not fire any timers
102
-
103
- timers.resume
104
- 10.times { timers.wait } # will fire all timers
105
- ```
106
-
107
- ## Contributing
108
-
109
- 1. Fork it
110
- 2. Create your feature branch (`git checkout -b my-new-feature`)
111
- 3. Commit your changes (`git commit -am 'Add some feature'`)
112
- 4. Push to the branch (`git push origin my-new-feature`)
113
- 5. Create new Pull Request
114
-
115
- ## License
116
-
117
- Released under the MIT license.
118
-
119
- Copyright, 2018, by [Samuel G. D. Williams](http://www.codeotaku.com/samuel-williams).
120
- Copyright, 2016, by [Tony Arcieri](bascule@gmail.com).
121
- Copyright, 2016, by Jeremy Hinegardner.
122
- Copyright, 2016, by Sean Gregory.
123
- Copyright, 2016, by Chuck Remes.
124
- Copyright, 2016, by Utenmiki.
125
- Copyright, 2016, by Ron Evans.
126
- Copyright, 2016, by Larry Lv.
127
- Copyright, 2016, by Bruno Enten.
128
- Copyright, 2016, by Jesse Cooke.
129
- Copyright, 2016, by Nicholas Evans.
130
- Copyright, 2016, by Dimitrij Denissenko.
131
- Copyright, 2016, by Ryan LeCompte.
132
-
133
- Permission is hereby granted, free of charge, to any person obtaining a copy
134
- of this software and associated documentation files (the "Software"), to deal
135
- in the Software without restriction, including without limitation the rights
136
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
137
- copies of the Software, and to permit persons to whom the Software is
138
- furnished to do so, subject to the following conditions:
139
-
140
- The above copyright notice and this permission notice shall be included in
141
- all copies or substantial portions of the Software.
142
-
143
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
144
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
145
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
146
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
147
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
148
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
149
- THE SOFTWARE.
data/Rakefile DELETED
@@ -1,6 +0,0 @@
1
- require "bundler/gem_tasks"
2
- require "rspec/core/rake_task"
3
-
4
- RSpec::Core::RakeTask.new(:test)
5
-
6
- task :default => :test
@@ -1,40 +0,0 @@
1
- # frozen_string_literal: true
2
- #
3
- # This file is part of the "timers" project and released under the MIT license.
4
- #
5
- # Copyright, 2018, by Samuel Williams. All rights reserved.
6
- #
7
-
8
- # Level of accuracy enforced by tests (50ms)
9
- TIMER_QUANTUM = 0.05
10
-
11
- if ENV['COVERAGE'] || ENV['TRAVIS']
12
- begin
13
- require 'simplecov'
14
-
15
- SimpleCov.start do
16
- add_filter "/spec/"
17
- end
18
-
19
- if ENV['TRAVIS']
20
- require 'coveralls'
21
- Coveralls.wear!
22
- end
23
- rescue LoadError
24
- warn "Could not load simplecov: #{$!}"
25
- end
26
- end
27
-
28
- require 'bundler/setup'
29
- Bundler.require(:test)
30
-
31
- require 'timers'
32
-
33
- RSpec.configure do |config|
34
- # Enable flags like --only-failures and --next-failure
35
- config.example_status_persistence_file_path = ".rspec_status"
36
-
37
- config.expect_with :rspec do |c|
38
- c.syntax = :expect
39
- end
40
- end
@@ -1,50 +0,0 @@
1
- # frozen_string_literal: true
2
- #
3
- # This file is part of the "timers" project and released under the MIT license.
4
- #
5
- # Copyright, 2018, by Samuel Williams. All rights reserved.
6
- #
7
-
8
- RSpec.describe Timers::Group do
9
- it "should be able to cancel twice" do
10
- fired = false
11
-
12
- timer = subject.after(0.1) { fired = true }
13
-
14
- 2.times do
15
- timer.cancel
16
- subject.wait
17
- end
18
-
19
- expect(fired).to be false
20
- end
21
-
22
- it "should be possble to reset after cancel" do
23
- fired = false
24
-
25
- timer = subject.after(0.1) { fired = true }
26
- timer.cancel
27
-
28
- subject.wait
29
-
30
- timer.reset
31
-
32
- subject.wait
33
-
34
- expect(fired).to be true
35
- end
36
-
37
- it "should cancel and remove one shot timers after they fire" do
38
- x = 0
39
-
40
- Timers::Wait.for(2) do |_remaining|
41
- timer = subject.every(0.2) { x += 1 }
42
- subject.after(0.1) { timer.cancel }
43
-
44
- subject.wait
45
- end
46
-
47
- expect(subject.timers).to be_empty
48
- expect(x).to be == 0
49
- end
50
- end
@@ -1,61 +0,0 @@
1
- # frozen_string_literal: true
2
- #
3
- # This file is part of the "timers" project and released under the MIT license.
4
- #
5
- # Copyright, 2018, by Samuel Williams. All rights reserved.
6
- #
7
-
8
- RSpec.describe Timers::Events do
9
- it "should register an event" do
10
- fired = false
11
-
12
- callback = proc do |_time|
13
- fired = true
14
- end
15
-
16
- subject.schedule(0.1, callback)
17
-
18
- expect(subject.size).to be == 1
19
-
20
- subject.fire(0.15)
21
-
22
- expect(subject.size).to be == 0
23
-
24
- expect(fired).to be true
25
- end
26
-
27
- it "should register events in order" do
28
- fired = []
29
-
30
- times = [0.95, 0.1, 0.3, 0.5, 0.4, 0.2, 0.01, 0.9]
31
-
32
- times.each do |requested_time|
33
- callback = proc do |_time|
34
- fired << requested_time
35
- end
36
-
37
- subject.schedule(requested_time, callback)
38
- end
39
-
40
- subject.fire(0.5)
41
- expect(fired).to be == times.sort.first(6)
42
-
43
- subject.fire(1.0)
44
- expect(fired).to be == times.sort
45
- end
46
-
47
- it "should fire events with the time they were fired at" do
48
- fired_at = :not_fired
49
-
50
- callback = proc do |time|
51
- # The time we actually were fired at:
52
- fired_at = time
53
- end
54
-
55
- subject.schedule(0.5, callback)
56
-
57
- subject.fire(1.0)
58
-
59
- expect(fired_at).to be == 1.0
60
- end
61
- end
@@ -1,38 +0,0 @@
1
- # frozen_string_literal: true
2
- #
3
- # This file is part of the "timers" project and released under the MIT license.
4
- #
5
- # Copyright, 2018, by Samuel Williams. All rights reserved.
6
- #
7
-
8
- RSpec.describe Timers::Group do
9
- it "should fire several times" do
10
- result = []
11
-
12
- subject.every(0.7) { result << :a }
13
- subject.every(2.3) { result << :b }
14
- subject.every(1.3) { result << :c }
15
- subject.every(2.4) { result << :d }
16
-
17
- Timers::Wait.for(2.5) do |remaining|
18
- subject.wait if subject.wait_interval < remaining
19
- end
20
-
21
- expect(result).to be == [:a, :c, :a, :a, :b, :d]
22
- end
23
-
24
- it "should fire immediately and then several times later" do
25
- result = []
26
-
27
- subject.every(0.7) { result << :a }
28
- subject.every(2.3) { result << :b }
29
- subject.now_and_every(1.3) { result << :c }
30
- subject.now_and_every(2.4) { result << :d }
31
-
32
- Timers::Wait.for(2.5) do |remaining|
33
- subject.wait if subject.wait_interval < remaining
34
- end
35
-
36
- expect(result).to be == [:c, :d, :a, :c, :a, :a, :b, :d]
37
- end
38
- end
@@ -1,260 +0,0 @@
1
- # frozen_string_literal: true
2
- #
3
- # This file is part of the "timers" project and released under the MIT license.
4
- #
5
- # Copyright, 2018, by Samuel Williams. All rights reserved.
6
- #
7
-
8
- RSpec.describe Timers::Group do
9
- describe "#wait" do
10
- it "calls the wait block with nil" do
11
- called = false
12
-
13
- subject.wait do |interval|
14
- expect(interval).to be_nil
15
- called = true
16
- end
17
-
18
- expect(called).to be true
19
- end
20
-
21
- it "calls the wait block with an interval" do
22
- called = false
23
- fired = false
24
-
25
- subject.after(0.1) { fired = true }
26
-
27
- subject.wait do |interval|
28
- expect(interval).to be_within(TIMER_QUANTUM).of(0.1)
29
- called = true
30
- sleep 0.2
31
- end
32
-
33
- expect(called).to be true
34
- expect(fired).to be true
35
- end
36
- end
37
-
38
- it "sleeps until the next timer" do
39
- interval = TIMER_QUANTUM * 2
40
- started_at = Time.now
41
-
42
- fired = false
43
- subject.after(interval) { fired = true }
44
- subject.wait
45
-
46
- expect(fired).to be true
47
- expect(Time.now - started_at).to be_within(TIMER_QUANTUM).of interval
48
- end
49
-
50
- it "fires instantly when next timer is in the past" do
51
- fired = false
52
- subject.after(TIMER_QUANTUM) { fired = true }
53
- sleep(TIMER_QUANTUM * 2)
54
- subject.wait
55
-
56
- expect(fired).to be true
57
- end
58
-
59
- it "calculates the interval until the next timer should fire" do
60
- interval = 0.1
61
-
62
- subject.after(interval)
63
- expect(subject.wait_interval).to be_within(TIMER_QUANTUM).of interval
64
-
65
- sleep(interval)
66
- expect(subject.wait_interval).to be <= 0
67
- end
68
-
69
- it "fires timers in the correct order" do
70
- result = []
71
-
72
- subject.after(TIMER_QUANTUM * 2) { result << :two }
73
- subject.after(TIMER_QUANTUM * 3) { result << :three }
74
- subject.after(TIMER_QUANTUM * 1) { result << :one }
75
-
76
- sleep TIMER_QUANTUM * 4
77
- subject.fire
78
-
79
- expect(result).to eq [:one, :two, :three]
80
- end
81
-
82
- it "raises TypeError if given an invalid time" do
83
- expect do
84
- subject.after(nil) { nil }
85
- end.to raise_exception(TypeError)
86
- end
87
-
88
- describe "recurring timers" do
89
- it "continues to fire the timers at each interval" do
90
- result = []
91
-
92
- subject.every(TIMER_QUANTUM * 2) { result << :foo }
93
-
94
- sleep TIMER_QUANTUM * 3
95
- subject.fire
96
- expect(result).to eq [:foo]
97
-
98
- sleep TIMER_QUANTUM * 5
99
- subject.fire
100
- expect(result).to eq [:foo, :foo]
101
- end
102
- end
103
-
104
- it "calculates the proper interval to wait until firing" do
105
- interval_ms = 25
106
-
107
- subject.after(interval_ms / 1000.0)
108
-
109
- expect(subject.wait_interval).to be_within(TIMER_QUANTUM).of(interval_ms / 1000.0)
110
- end
111
-
112
- describe "pause and continue timers" do
113
- before(:each) do
114
- @interval = TIMER_QUANTUM * 2
115
-
116
- @fired = false
117
- @timer = subject.after(@interval) { @fired = true }
118
- @fired2 = false
119
- @timer2 = subject.after(@interval) { @fired2 = true }
120
- end
121
-
122
- it "does not fire when paused" do
123
- @timer.pause
124
- subject.wait
125
- expect(@fired).to be false
126
- end
127
-
128
- it "fires when continued after pause" do
129
- @timer.pause
130
- subject.wait
131
- @timer.resume
132
-
133
- sleep @timer.interval
134
- subject.wait
135
-
136
- expect(@fired).to be true
137
- end
138
-
139
- it "can pause all timers at once" do
140
- subject.pause
141
- subject.wait
142
- expect(@fired).to be false
143
- expect(@fired2).to be false
144
- end
145
-
146
- it "can continue all timers at once" do
147
- subject.pause
148
- subject.wait
149
- subject.resume
150
-
151
- # We need to wait until we are sure both timers will fire, otherwise highly accurate clocks
152
- # (e.g. JVM)may only fire the first timer, but not the second, because they are actually
153
- # schedueled at different times.
154
- sleep TIMER_QUANTUM * 2
155
- subject.wait
156
-
157
- expect(@fired).to be true
158
- expect(@fired2).to be true
159
- end
160
-
161
- it "can fire the timer directly" do
162
- fired = false
163
- timer = subject.after(TIMER_QUANTUM * 1) { fired = true }
164
- timer.pause
165
- subject.wait
166
- expect(fired).not_to be true
167
- timer.resume
168
- expect(fired).not_to be true
169
- timer.fire
170
- expect(fired).to be true
171
- end
172
- end
173
-
174
- describe "delay timer" do
175
- it "adds appropriate amount of time to timer" do
176
- timer = subject.after(10)
177
- timer.delay(5)
178
- expect(timer.offset - subject.current_offset).to be_within(TIMER_QUANTUM).of(15)
179
- end
180
- end
181
-
182
- describe "delay timer collection" do
183
- it "delay on set adds appropriate amount of time to all timers" do
184
- timer = subject.after(10)
185
- timer2 = subject.after(20)
186
- subject.delay(5)
187
- expect(timer.offset - subject.current_offset).to be_within(TIMER_QUANTUM).of(15)
188
- expect(timer2.offset - subject.current_offset).to be_within(TIMER_QUANTUM).of(25)
189
- end
190
- end
191
-
192
- describe "on delaying a timer" do
193
- it "fires timers in the correct order" do
194
- result = []
195
-
196
- subject.after(TIMER_QUANTUM * 2) { result << :two }
197
- subject.after(TIMER_QUANTUM * 3) { result << :three }
198
- first = subject.after(TIMER_QUANTUM * 1) { result << :one }
199
- first.delay(TIMER_QUANTUM * 3)
200
-
201
- sleep TIMER_QUANTUM * 5
202
- subject.fire
203
-
204
- expect(result).to eq [:two, :three, :one]
205
- end
206
- end
207
-
208
- describe "#inspect" do
209
- it "before firing" do
210
- fired = false
211
- timer = subject.after(TIMER_QUANTUM * 5) { fired = true }
212
- timer.pause
213
- expect(fired).not_to be true
214
- expect(timer.inspect).to match(/\A#<Timers::Timer:0x[\da-f]+ fires in [-\.\de]+ seconds>\Z/)
215
- end
216
-
217
- it "after firing" do
218
- fired = false
219
- timer = subject.after(TIMER_QUANTUM) { fired = true }
220
-
221
- subject.wait
222
-
223
- expect(fired).to be true
224
- expect(timer.inspect).to match(/\A#<Timers::Timer:0x[\da-f]+ fired [-\.\de]+ seconds ago>\Z/)
225
- end
226
-
227
- it "recurring firing" do
228
- result = []
229
- timer = subject.every(TIMER_QUANTUM) { result << :foo }
230
-
231
- subject.wait
232
- expect(result).not_to be_empty
233
- regex = /\A#<Timers::Timer:0x[\da-f]+ fires in [-\.\de]+ seconds, recurs every #{format("%0.2f", TIMER_QUANTUM)}>\Z/
234
- expect(timer.inspect).to match(regex)
235
- end
236
- end
237
-
238
- describe "#fires_in" do
239
- let(:interval) { TIMER_QUANTUM * 2 }
240
-
241
- it "calculates the interval until the next fire if it's recurring" do
242
- timer = subject.every(interval) { true }
243
- expect(timer.fires_in).to be_within(TIMER_QUANTUM).of(interval)
244
- end
245
-
246
- context "when timer is not recurring" do
247
- let!(:timer) { subject.after(interval) { true } }
248
-
249
- it "calculates the interval until the next fire if it hasn't already fired" do
250
- expect(timer.fires_in).to be_within(TIMER_QUANTUM).of(interval)
251
- end
252
-
253
- it "calculates the interval since last fire if already fired" do
254
- subject.wait
255
- sleep(interval)
256
- expect(timer.fires_in).to be_within(TIMER_QUANTUM).of(0 - interval)
257
- end
258
- end
259
- end
260
- end
@@ -1,124 +0,0 @@
1
- # frozen_string_literal: true
2
- #
3
- # This file is part of the "timers" project and released under the MIT license.
4
- #
5
- # Copyright, 2018, by Samuel Williams. All rights reserved.
6
- #
7
-
8
- require "spec_helper"
9
-
10
- # Event based timers:
11
-
12
- # Serviced 31812 events in 2.39075272 seconds, 13306.320832794887 e/s.
13
- # Thread ID: 7336700
14
- # Fiber ID: 30106340
15
- # Total: 2.384043
16
- # Sort by: self_time
17
-
18
- # %self total self wait child calls name
19
- # 13.48 0.510 0.321 0.000 0.189 369133 Timers::Events::Handle#<=>
20
- # 8.12 0.194 0.194 0.000 0.000 427278 Timers::Events::Handle#to_f
21
- # 4.55 0.109 0.109 0.000 0.000 427278 Float#<=>
22
- # 4.40 1.857 0.105 0.000 1.752 466376 *Timers::Events#bsearch
23
- # 4.30 0.103 0.103 0.000 0.000 402945 Float#to_f
24
- # 2.65 0.063 0.063 0.000 0.000 33812 Array#insert
25
- # 2.64 1.850 0.063 0.000 1.787 33812 Timers::Events#schedule
26
- # 2.40 1.930 0.057 0.000 1.873 33812 Timers::Timer#reset
27
- # 1.89 1.894 0.045 0.000 1.849 31812 Timers::Timer#fire
28
- # 1.69 1.966 0.040 0.000 1.926 31812 Timers::Events::Handle#fire
29
- # 1.35 0.040 0.032 0.000 0.008 33812 Timers::Events::Handle#initialize
30
- # 1.29 0.044 0.031 0.000 0.013 44451 Timers::Group#current_offset
31
-
32
- # SortedSet based timers:
33
-
34
- # Serviced 32516 events in 66.753277275 seconds, 487.1072288781219 e/s.
35
- # Thread ID: 15995640
36
- # Fiber ID: 38731780
37
- # Total: 66.716394
38
- # Sort by: self_time
39
-
40
- # %self total self wait child calls name
41
- # 54.73 49.718 36.513 0.000 13.205 57084873 Timers::Timer#<=>
42
- # 23.74 65.559 15.841 0.000 49.718 32534 Array#sort!
43
- # 19.79 13.205 13.205 0.000 0.000 57084873 Float#<=>
44
-
45
- # Max out events performance (on my computer):
46
- # Serviced 1142649 events in 11.194903921 seconds, 102068.70405115146 e/s.
47
-
48
- RSpec.describe Timers::Group do
49
- context "with profiler" do
50
- if defined? RubyProf
51
- before(:each) do
52
- # Running RubyProf makes the code slightly slower.
53
- RubyProf.start
54
- puts "*** Running with RubyProf reduces performance ***"
55
- end
56
-
57
- after(:each) do
58
- if RubyProf.running?
59
- # file = arg.metadata[:description].gsub(/\s+/, '-')
60
-
61
- result = RubyProf.stop
62
-
63
- printer = RubyProf::FlatPrinter.new(result)
64
- printer.print($stderr, min_percent: 1.0)
65
- end
66
- end
67
- end
68
-
69
- it "runs efficiently" do
70
- result = []
71
- range = (1..500)
72
- duration = 2.0
73
-
74
- total = 0
75
- range.each do |index|
76
- offset = index.to_f / range.max
77
- total += (duration / offset).floor
78
-
79
- subject.every(index.to_f / range.max, :strict) { result << index }
80
- end
81
-
82
- subject.wait while result.size < total
83
-
84
- rate = result.size.to_f / subject.current_offset
85
- puts "Serviced #{result.size} events in #{subject.current_offset} seconds, #{rate} e/s."
86
-
87
- expect(subject.current_offset).to be_within(20).percent_of(duration)
88
- end
89
- end
90
-
91
- it "runs efficiently at high volume" do
92
- results = []
93
- range = (1..300)
94
- groups = (1..20)
95
- duration = 11
96
-
97
- timers = []
98
- @mutex = Mutex.new
99
- start = Time.now
100
- groups.each do |gi|
101
- timers << Thread.new {
102
- result = []
103
- timer = Timers::Group.new
104
- total = 0
105
- range.each do |ri|
106
- offset = ri.to_f / range.max
107
- total += (duration / offset).floor
108
- timer.every(ri.to_f / range.max, :strict) { result << ri }
109
- end
110
- timer.wait while result.size < total
111
- @mutex.synchronize { results += result }
112
-
113
- }
114
- end
115
- timers.each { |t| t.join }
116
- finish = Time.now
117
-
118
- rate = results.size.to_f / ( runtime = finish - start )
119
-
120
- puts "Serviced #{results.size} events in #{runtime} seconds, #{rate} e/s; across #{groups.max} timers."
121
-
122
- expect(runtime).to be_within(20).percent_of(duration)
123
- end
124
- end
@@ -1,39 +0,0 @@
1
- # frozen_string_literal: true
2
- #
3
- # This file is part of the "timers" project and released under the MIT license.
4
- #
5
- # Copyright, 2018, by Samuel Williams. All rights reserved.
6
- #
7
-
8
- RSpec.describe Timers::Group do
9
- it "should not diverge too much" do
10
- fired = :not_fired_yet
11
- count = 0
12
- quantum = 0.01
13
-
14
- start_offset = subject.current_offset
15
- Timers::Timer.new(subject, quantum, :strict, start_offset) do |offset|
16
- fired = offset
17
- count += 1
18
- end
19
-
20
- iterations = 1000
21
- subject.wait while count < iterations
22
-
23
- # In my testing on the JVM, without the :strict recurring, I noticed 60ms of error here.
24
- expect(fired - start_offset).to be_within(quantum).of(iterations * quantum)
25
- end
26
-
27
- it "should only fire 0-interval timer once per iteration" do
28
- count = 0
29
-
30
- start_offset = subject.current_offset
31
- Timers::Timer.new(subject, 0, :strict, start_offset) do |offset, timer|
32
- count += 1
33
- end
34
-
35
- subject.wait
36
-
37
- expect(count).to be == 1
38
- end
39
- end
@@ -1,35 +0,0 @@
1
- # frozen_string_literal: true
2
- #
3
- # This file is part of the "timers" project and released under the MIT license.
4
- #
5
- # Copyright, 2018, by Samuel Williams. All rights reserved.
6
- #
7
-
8
- require "spec_helper"
9
- require "timers/wait"
10
-
11
- RSpec.describe Timers::Wait do
12
- it "repeats until timeout expired" do
13
- timeout = Timers::Wait.new(5)
14
- count = 0
15
-
16
- timeout.while_time_remaining do |remaining|
17
- expect(remaining).to be_within(TIMER_QUANTUM).of(timeout.duration - count)
18
-
19
- count += 1
20
- sleep 1
21
- end
22
-
23
- expect(count).to eq(5)
24
- end
25
-
26
- it "yields results as soon as possible" do
27
- timeout = Timers::Wait.new(5)
28
-
29
- result = timeout.while_time_remaining do |_remaining|
30
- break :done
31
- end
32
-
33
- expect(result).to eq(:done)
34
- end
35
- end
@@ -1,33 +0,0 @@
1
- # frozen_string_literal: true
2
- #
3
- # This file is part of the "timers" project and released under the MIT license.
4
- #
5
- # Copyright, 2018, by Samuel Williams. All rights reserved.
6
- #
7
-
8
- require_relative 'lib/timers/version'
9
-
10
- Gem::Specification.new do |spec|
11
- spec.name = "timers"
12
- spec.version = Timers::VERSION
13
- spec.authors = ["Samuel Williams", "Tony Arcieri"]
14
- spec.email = ["samuel@codeotaku.com", "bascule@gmail.com"]
15
- spec.licenses = ["MIT"]
16
- spec.homepage = "https://github.com/socketry/timers"
17
- spec.summary = "Pure Ruby one-shot and periodic timers"
18
- spec.description = <<-DESCRIPTION.strip.gsub(/\s+/, " ")
19
- Schedule procs to run after a certain time, or at periodic intervals,
20
- using any API that accepts a timeout.
21
- DESCRIPTION
22
-
23
- spec.files = `git ls-files`.split($OUTPUT_RECORD_SEPARATOR)
24
- spec.executables = spec.files.grep(%r{^bin/}).map { |f| File.basename(f) }
25
- spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
26
- spec.require_paths = ["lib"]
27
-
28
- spec.required_ruby_version = '>= 2.2.1'
29
-
30
- spec.add_development_dependency "bundler"
31
- spec.add_development_dependency "rspec", "~> 3.6"
32
- spec.add_development_dependency "rake"
33
- end