stoplight 2.1.3 → 3.0.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.
Files changed (54) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +48 -16
  3. data/lib/stoplight/color.rb +4 -4
  4. data/lib/stoplight/data_store/base.rb +1 -1
  5. data/lib/stoplight/data_store/memory.rb +1 -1
  6. data/lib/stoplight/data_store/redis.rb +23 -25
  7. data/lib/stoplight/data_store.rb +1 -1
  8. data/lib/stoplight/default.rb +3 -3
  9. data/lib/stoplight/error.rb +1 -1
  10. data/lib/stoplight/failure.rb +11 -7
  11. data/lib/stoplight/light/runnable.rb +7 -5
  12. data/lib/stoplight/light.rb +1 -1
  13. data/lib/stoplight/notifier/base.rb +1 -1
  14. data/lib/stoplight/notifier/bugsnag.rb +1 -1
  15. data/lib/stoplight/notifier/generic.rb +1 -1
  16. data/lib/stoplight/notifier/hip_chat.rb +1 -1
  17. data/lib/stoplight/notifier/honeybadger.rb +2 -2
  18. data/lib/stoplight/notifier/io.rb +1 -1
  19. data/lib/stoplight/notifier/logger.rb +1 -1
  20. data/lib/stoplight/notifier/pagerduty.rb +21 -0
  21. data/lib/stoplight/notifier/raven.rb +2 -2
  22. data/lib/stoplight/notifier/rollbar.rb +39 -0
  23. data/lib/stoplight/notifier/slack.rb +1 -1
  24. data/lib/stoplight/notifier.rb +1 -1
  25. data/lib/stoplight/state.rb +4 -4
  26. data/lib/stoplight/version.rb +2 -2
  27. data/lib/stoplight.rb +3 -1
  28. data/spec/spec_helper.rb +2 -3
  29. data/spec/stoplight/color_spec.rb +1 -1
  30. data/spec/stoplight/data_store/base_spec.rb +1 -1
  31. data/spec/stoplight/data_store/memory_spec.rb +1 -1
  32. data/spec/stoplight/data_store/redis_spec.rb +1 -1
  33. data/spec/stoplight/data_store_spec.rb +1 -1
  34. data/spec/stoplight/default_spec.rb +2 -2
  35. data/spec/stoplight/error_spec.rb +1 -1
  36. data/spec/stoplight/failure_spec.rb +6 -1
  37. data/spec/stoplight/light/runnable_spec.rb +7 -9
  38. data/spec/stoplight/light_spec.rb +5 -5
  39. data/spec/stoplight/notifier/base_spec.rb +1 -1
  40. data/spec/stoplight/notifier/bugsnag_spec.rb +2 -4
  41. data/spec/stoplight/notifier/generic_spec.rb +1 -1
  42. data/spec/stoplight/notifier/hip_chat_spec.rb +2 -3
  43. data/spec/stoplight/notifier/honeybadger_spec.rb +1 -1
  44. data/spec/stoplight/notifier/io_spec.rb +1 -1
  45. data/spec/stoplight/notifier/logger_spec.rb +1 -1
  46. data/spec/stoplight/notifier/pagerduty_spec.rb +40 -0
  47. data/spec/stoplight/notifier/raven_spec.rb +1 -1
  48. data/spec/stoplight/notifier/rollbar_spec.rb +90 -0
  49. data/spec/stoplight/notifier/slack_spec.rb +2 -3
  50. data/spec/stoplight/notifier_spec.rb +1 -1
  51. data/spec/stoplight/state_spec.rb +1 -1
  52. data/spec/stoplight/version_spec.rb +1 -1
  53. data/spec/stoplight_spec.rb +1 -1
  54. metadata +80 -47
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: e73b740e1d020caa3c2231d358358f7f1405d339
4
- data.tar.gz: f228a34259327f769ee5a43630815ee31ec754ee
2
+ SHA256:
3
+ metadata.gz: 2f7c163955f261ad3eeca89a851a06a15f5734d78d045695297f29c143532a58
4
+ data.tar.gz: 9ff3e5911bf7e9f198c714ce1eb0f10c6ba09834e96a8c8c2d16dd3e184ed0ce
5
5
  SHA512:
6
- metadata.gz: ef7a7ec7291ffc27d4b12c2900e52927abe9b9faf93e26f5086959742e57c69c4b8d05a880e66eba7439193686983bd516f429d1c4e6eb61067b86d5870c9f9d
7
- data.tar.gz: 68ef1c8e9583434ae5da043aa0c7ef3f5e0a23a9b9bef40ac58bdffac57fa83de4d9d148e3bfbf68bda3caaf8f831cd10a5d28882952a533655a47fb3b7f21f2
6
+ metadata.gz: 5e42cd0050cdbf9440e80d68d70091e6c22c574c64cf06a29aa9dca320f5f4915dca48e5582ebf18db757fde4ad295c20af05bc6a879695d726afa65ff50dea8
7
+ data.tar.gz: a5088d9ba81a5578cbc078d0671c601fd13738f07f6a67dd12936df3e8a7927053314538d50c1e65ce6913607e9764ff09d6c05f931c4be8984e2e6744399288
data/README.md CHANGED
@@ -4,7 +4,6 @@
4
4
  [![Build badge][]][build]
5
5
  [![Coverage badge][]][coverage]
6
6
  [![Climate badge][]][climate]
7
- [![Dependencies badge][]][dependencies]
8
7
 
9
8
  Stoplight is traffic control for code. It's an implementation of the circuit
10
9
  breaker pattern in Ruby.
@@ -32,6 +31,8 @@ Check out [stoplight-admin][] for controlling your stoplights.
32
31
  - [HipChat](#hipchat)
33
32
  - [Honeybadger](#honeybadger)
34
33
  - [Logger](#logger)
34
+ - [Pagerduty](#pagerduty)
35
+ - [Rollbar](#rollbar)
35
36
  - [Sentry](#sentry)
36
37
  - [Slack](#slack)
37
38
  - [Rails](#rails-1)
@@ -204,7 +205,7 @@ The default threshold is `3`.
204
205
  ### Custom cool off time
205
206
 
206
207
  Stoplights will automatically attempt to recover after a certain amount of
207
- time. A light in the red state for longer than the cool of period will
208
+ time. A light in the red state for longer than the cool off period will
208
209
  transition to the yellow state. This cool off time is customizable.
209
210
 
210
211
  ``` rb
@@ -356,6 +357,36 @@ Stoplight::Light.default_notifiers += [notifier]
356
357
  # => [#<Stoplight::Notifier::IO:...>, #<Stoplight::Notifier::Logger:...>]
357
358
  ```
358
359
 
360
+ #### Pagerduty
361
+
362
+ Make sure you have [the Pagerduty gem][] (`~> 2.1`) installed before configuring
363
+ Stoplight.
364
+
365
+ ``` rb
366
+ require 'pagerduty'
367
+ # => true
368
+ pagerduty = Pagerduty.new('http://www.example.com/webhook-url')
369
+ # => #<Pagerduty:...>
370
+ notifier = Stoplight::Notifier::Pagerduty.new(pagerduty)
371
+ # => #<Stoplight::Notifier::Pagerduty:...>
372
+ Stoplight::Light.default_notifiers += [notifier]
373
+ # => [#<Stoplight::Notifier::IO:...>, #<Stoplight::Notifier::Pagerduty:...>]
374
+ ```
375
+
376
+ #### Rollbar
377
+
378
+ Make sure you have [the Rollbar gem][] (`~> 2.0`) installed before configuring
379
+ Stoplight.
380
+
381
+ ``` rb
382
+ require 'rollbar'
383
+ # => true
384
+ notifier = Stoplight::Notifier::Rollbar.new(Rollbar)
385
+ # => #<Stoplight::Notifier::Rollbar:...>
386
+ Stoplight::Light.default_notifiers += [notifier]
387
+ # => [#<Stoplight::Notifier::IO:...>, #<Stoplight::Notifier::Rollbar:...>]
388
+ ```
389
+
359
390
  #### Sentry
360
391
 
361
392
  Make sure you have [the Sentry gem][] (`~> 1.2`) installed before configuring
@@ -463,24 +494,22 @@ stoplight = Stoplight("test-#{rand}") { ... }
463
494
 
464
495
  ## Credits
465
496
 
466
- Stoplight is brought to you by [@camdez][] and [@tfausak][] from [@OrgSync][].
467
- A [complete list of contributors][] is available on GitHub. We were inspired by
468
- Martin Fowler's [CircuitBreaker][] article.
497
+ Stoplight is brought to you by [@camdez][] and [@tfausak][] from [@OrgSync][]. [@bolshakov][] is the current
498
+ maintainer of the gem. A [complete list of contributors][] is available on GitHub. We were inspired by
499
+ Martin Fowler's [CircuitBreaker][] article.
469
500
 
470
501
  Stoplight is licensed under [the MIT License][].
471
502
 
472
- [Stoplight]: https://github.com/orgsync/stoplight
503
+ [Stoplight]: https://github.com/bolshakov/stoplight
473
504
  [Version badge]: https://img.shields.io/gem/v/stoplight.svg?label=version
474
505
  [version]: https://rubygems.org/gems/stoplight
475
- [Build badge]: https://img.shields.io/travis/orgsync/stoplight/master.svg?label=build
476
- [build]: https://travis-ci.org/orgsync/stoplight
477
- [Coverage badge]: https://img.shields.io/coveralls/orgsync/stoplight/master.svg?label=coverage
478
- [coverage]: https://coveralls.io/r/orgsync/stoplight
479
- [Climate badge]: https://img.shields.io/codeclimate/github/orgsync/stoplight.svg?label=climate
480
- [climate]: https://codeclimate.com/github/orgsync/stoplight
481
- [Dependencies badge]: https://img.shields.io/gemnasium/orgsync/stoplight.svg?label=dependencies
482
- [dependencies]: https://gemnasium.com/orgsync/stoplight
483
- [stoplight-admin]: https://github.com/orgsync/stoplight-admin
506
+ [Build badge]: https://github.com/bolshakov/stoplight/workflows/Specs/badge.svg
507
+ [build]: https://github.com/bolshakov/stoplight/actions?query=branch%3Amaster
508
+ [Coverage badge]: https://img.shields.io/coveralls/bolshakov/stoplight/master.svg?label=coverage
509
+ [coverage]: https://coveralls.io/r/bolshakov/stoplight
510
+ [Climate badge]: https://api.codeclimate.com/v1/badges/3451c2d281ffa345441a/maintainability
511
+ [climate]: https://codeclimate.com/github/bolshakov/stoplight
512
+ [stoplight-admin]: https://github.com/bolshakov/stoplight-admin
484
513
  [Semantic Versioning]: http://semver.org/spec/v2.0.0.html
485
514
  [the change log]: CHANGELOG.md
486
515
  [the notifiers section]: #notifiers
@@ -490,11 +519,14 @@ Stoplight is licensed under [the MIT License][].
490
519
  [the HipChat gem]: https://rubygems.org/gems/hipchat
491
520
  [the Honeybadger gem]: https://rubygems.org/gems/honeybadger
492
521
  [the Logger class]: http://ruby-doc.org/stdlib-2.2.3/libdoc/logger/rdoc/Logger.html
522
+ [the Rollbar gem]: https://rubygems.org/gems/rollbar
493
523
  [the Sentry gem]: https://rubygems.org/gems/sentry-raven
494
524
  [the Slack gem]: https://rubygems.org/gems/slack-notifier
525
+ [the Pagerduty gem]: https://rubygems.org/gems/pagerduty
495
526
  [@camdez]: https://github.com/camdez
496
527
  [@tfausak]: https://github.com/tfausak
497
528
  [@orgsync]: https://github.com/OrgSync
498
- [complete list of contributors]: https://github.com/orgsync/stoplight/graphs/contributors
529
+ [@bolshakov]: https://github.com/bolshakov
530
+ [complete list of contributors]: https://github.com/bolshakov/stoplight/graphs/contributors
499
531
  [CircuitBreaker]: http://martinfowler.com/bliki/CircuitBreaker.html
500
532
  [the MIT license]: LICENSE.md
@@ -1,9 +1,9 @@
1
- # coding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Stoplight
4
4
  module Color
5
- GREEN = 'green'.freeze
6
- YELLOW = 'yellow'.freeze
7
- RED = 'red'.freeze
5
+ GREEN = 'green'
6
+ YELLOW = 'yellow'
7
+ RED = 'red'
8
8
  end
9
9
  end
@@ -1,4 +1,4 @@
1
- # coding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Stoplight
4
4
  module DataStore
@@ -1,4 +1,4 @@
1
- # coding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  require 'monitor'
4
4
 
@@ -1,11 +1,11 @@
1
- # coding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Stoplight
4
4
  module DataStore
5
5
  # @see Base
6
6
  class Redis < Base
7
- KEY_PREFIX = 'stoplight'.freeze
8
- KEY_SEPARATOR = ':'.freeze
7
+ KEY_PREFIX = 'stoplight'
8
+ KEY_SEPARATOR = ':'
9
9
 
10
10
  # @param redis [::Redis]
11
11
  def initialize(redis)
@@ -25,9 +25,9 @@ module Stoplight
25
25
  end
26
26
 
27
27
  def get_all(light)
28
- failures, state = @redis.multi do
29
- query_failures(light)
30
- @redis.hget(states_key, light.name)
28
+ failures, state = @redis.multi do |transaction|
29
+ query_failures(light, transaction: transaction)
30
+ transaction.hget(states_key, light.name)
31
31
  end
32
32
 
33
33
  [
@@ -41,18 +41,18 @@ module Stoplight
41
41
  end
42
42
 
43
43
  def record_failure(light, failure)
44
- size, = @redis.multi do
45
- @redis.lpush(failures_key(light), failure.to_json)
46
- @redis.ltrim(failures_key(light), 0, light.threshold - 1)
44
+ size, = @redis.multi do |transaction|
45
+ transaction.lpush(failures_key(light), failure.to_json)
46
+ transaction.ltrim(failures_key(light), 0, light.threshold - 1)
47
47
  end
48
48
 
49
49
  size
50
50
  end
51
51
 
52
52
  def clear_failures(light)
53
- failures, = @redis.multi do
54
- query_failures(light)
55
- @redis.del(failures_key(light))
53
+ failures, = @redis.multi do |transaction|
54
+ query_failures(light, transaction: transaction)
55
+ transaction.del(failures_key(light))
56
56
  end
57
57
 
58
58
  normalize_failures(failures, light.error_notifier)
@@ -68,9 +68,9 @@ module Stoplight
68
68
  end
69
69
 
70
70
  def clear_state(light)
71
- state, = @redis.multi do
72
- query_state(light)
73
- @redis.hdel(states_key, light.name)
71
+ state, = @redis.multi do |transaction|
72
+ query_state(light, transaction: transaction)
73
+ transaction.hdel(states_key, light.name)
74
74
  end
75
75
 
76
76
  normalize_state(state)
@@ -78,23 +78,21 @@ module Stoplight
78
78
 
79
79
  private
80
80
 
81
- def query_failures(light)
82
- @redis.lrange(failures_key(light), 0, -1)
81
+ def query_failures(light, transaction: @redis)
82
+ transaction.lrange(failures_key(light), 0, -1)
83
83
  end
84
84
 
85
85
  def normalize_failures(failures, error_notifier)
86
86
  failures.map do |json|
87
- begin
88
- Failure.from_json(json)
89
- rescue => error
90
- error_notifier.call(error)
91
- Failure.from_error(error)
92
- end
87
+ Failure.from_json(json)
88
+ rescue StandardError => e
89
+ error_notifier.call(e)
90
+ Failure.from_error(e)
93
91
  end
94
92
  end
95
93
 
96
- def query_state(light)
97
- @redis.hget(states_key, light.name)
94
+ def query_state(light, transaction: @redis)
95
+ transaction.hget(states_key, light.name)
98
96
  end
99
97
 
100
98
  def normalize_state(state)
@@ -1,4 +1,4 @@
1
- # coding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Stoplight
4
4
  module DataStore # rubocop:disable Style/Documentation
@@ -1,4 +1,4 @@
1
- # coding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Stoplight
4
4
  module Default
@@ -6,9 +6,9 @@ module Stoplight
6
6
 
7
7
  DATA_STORE = DataStore::Memory.new
8
8
 
9
- ERROR_HANDLER = -> (error, handler) { handler.call(error) }
9
+ ERROR_HANDLER = ->(error, handler) { handler.call(error) }
10
10
 
11
- ERROR_NOTIFIER = -> (error) { warn error }
11
+ ERROR_NOTIFIER = ->(error) { warn error }
12
12
 
13
13
  FALLBACK = nil
14
14
 
@@ -1,4 +1,4 @@
1
- # coding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Stoplight
4
4
  module Error
@@ -1,11 +1,11 @@
1
- # coding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  require 'json'
4
4
  require 'time'
5
5
 
6
6
  module Stoplight
7
7
  class Failure # rubocop:disable Style/Documentation
8
- TIME_FORMAT = '%Y-%m-%dT%H:%M:%S.%N%:z'.freeze
8
+ TIME_FORMAT = '%Y-%m-%dT%H:%M:%S.%N%:z'
9
9
 
10
10
  # @return [String]
11
11
  attr_reader :error_class
@@ -52,14 +52,18 @@ module Stoplight
52
52
  time == other.time
53
53
  end
54
54
 
55
+ # @param options [Object, nil]
55
56
  # @return [String]
56
- def to_json
57
+ def to_json(options = nil)
57
58
  JSON.generate(
58
- error: {
59
- class: error_class,
60
- message: error_message
59
+ {
60
+ error: {
61
+ class: error_class,
62
+ message: error_message
63
+ },
64
+ time: time.strftime(TIME_FORMAT)
61
65
  },
62
- time: time.strftime(TIME_FORMAT)
66
+ options
63
67
  )
64
68
  end
65
69
  end
@@ -1,4 +1,4 @@
1
- # coding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Stoplight
4
4
  class Light
@@ -44,23 +44,25 @@ module Stoplight
44
44
 
45
45
  def run_red
46
46
  raise Error::RedLight, name unless fallback
47
+
47
48
  fallback.call(nil)
48
49
  end
49
50
 
50
51
  def run_code(on_success, on_failure)
51
52
  result = code.call
52
53
  failures = clear_failures
53
- on_success.call(failures) if on_success
54
+ on_success&.call(failures)
54
55
  result
55
- rescue Exception => error # rubocop:disable Lint/RescueException
56
- handle_error(error, on_failure)
56
+ rescue Exception => e # rubocop:disable Lint/RescueException
57
+ handle_error(e, on_failure)
57
58
  end
58
59
 
59
60
  def handle_error(error, on_failure)
60
61
  error_handler.call(error, Error::HANDLER)
61
62
  size = record_failure(error)
62
- on_failure.call(size, error) if on_failure
63
+ on_failure&.call(size, error)
63
64
  raise error unless fallback
65
+
64
66
  fallback.call(error)
65
67
  end
66
68
 
@@ -1,4 +1,4 @@
1
- # coding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Stoplight
4
4
  class Light # rubocop:disable Style/Documentation
@@ -1,4 +1,4 @@
1
- # coding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Stoplight
4
4
  module Notifier
@@ -1,4 +1,4 @@
1
- # coding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Stoplight
4
4
  module Notifier
@@ -1,4 +1,4 @@
1
- # coding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Stoplight
4
4
  module Notifier
@@ -1,4 +1,4 @@
1
- # coding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Stoplight
4
4
  module Notifier
@@ -1,4 +1,4 @@
1
- # coding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Stoplight
4
4
  module Notifier
@@ -34,7 +34,7 @@ module Stoplight
34
34
  h = options.merge(
35
35
  api_key: api_key,
36
36
  error_message: message,
37
- backtrace: (error.backtrace if error)
37
+ backtrace: error&.backtrace
38
38
  )
39
39
  ::Honeybadger.notify(h)
40
40
  message
@@ -1,4 +1,4 @@
1
- # coding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Stoplight
4
4
  module Notifier
@@ -1,4 +1,4 @@
1
- # coding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Stoplight
4
4
  module Notifier
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Stoplight
4
+ module Notifier
5
+ # @see Base
6
+ class Pagerduty < Base
7
+ include Generic
8
+
9
+ # @return [::Pagerduty]
10
+ def pagerduty
11
+ @object
12
+ end
13
+
14
+ private
15
+
16
+ def put(message)
17
+ pagerduty.trigger(message)
18
+ end
19
+ end
20
+ end
21
+ end
@@ -1,4 +1,4 @@
1
- # coding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Stoplight
4
4
  module Notifier
@@ -30,7 +30,7 @@ module Stoplight
30
30
 
31
31
  h = options.merge(
32
32
  configuration: configuration,
33
- backtrace: (error.backtrace if error)
33
+ backtrace: error&.backtrace
34
34
  )
35
35
  ::Raven.capture_message(message, h)
36
36
  message
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Stoplight
4
+ module Notifier
5
+ # @see Base
6
+ class Rollbar < Base
7
+ DEFAULT_OPTIONS = {
8
+ severity: 'info'
9
+ }.freeze
10
+
11
+ StoplightStatusChange = Class.new(Error::Base)
12
+
13
+ # @return [Proc]
14
+ attr_reader :formatter
15
+ # @return [::Rollbar]
16
+ attr_reader :rollbar
17
+ # @return [Hash{Symbol => Object}]
18
+ attr_reader :options
19
+
20
+ # @param rollbar [::Rollbar]
21
+ # @param formatter [Proc, nil]
22
+ # @param options [Hash{Symbol => Object}]
23
+ # @option options [String] :severity
24
+ def initialize(rollbar, formatter = nil, options = {})
25
+ @rollbar = rollbar
26
+ @formatter = formatter || Default::FORMATTER
27
+ @options = DEFAULT_OPTIONS.merge(options)
28
+ end
29
+
30
+ def notify(light, from_color, to_color, error)
31
+ formatter.call(light, from_color, to_color, error).tap do |message|
32
+ severity = options.fetch(:severity)
33
+ exception = StoplightStatusChange.new(message)
34
+ rollbar.__send__(severity, exception)
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -1,4 +1,4 @@
1
- # coding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Stoplight
4
4
  module Notifier
@@ -1,4 +1,4 @@
1
- # coding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Stoplight
4
4
  module Notifier # rubocop:disable Style/Documentation
@@ -1,9 +1,9 @@
1
- # coding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Stoplight
4
4
  module State
5
- UNLOCKED = 'unlocked'.freeze
6
- LOCKED_GREEN = 'locked_green'.freeze
7
- LOCKED_RED = 'locked_red'.freeze
5
+ UNLOCKED = 'unlocked'
6
+ LOCKED_GREEN = 'locked_green'
7
+ LOCKED_RED = 'locked_red'
8
8
  end
9
9
  end
@@ -1,5 +1,5 @@
1
- # coding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Stoplight
4
- VERSION = Gem::Version.new('2.1.3')
4
+ VERSION = Gem::Version.new('3.0.0')
5
5
  end
data/lib/stoplight.rb CHANGED
@@ -1,4 +1,4 @@
1
- # coding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Stoplight # rubocop:disable Style/Documentation
4
4
  end
@@ -24,7 +24,9 @@ require 'stoplight/notifier/hip_chat'
24
24
  require 'stoplight/notifier/honeybadger'
25
25
  require 'stoplight/notifier/io'
26
26
  require 'stoplight/notifier/logger'
27
+ require 'stoplight/notifier/pagerduty'
27
28
  require 'stoplight/notifier/raven'
29
+ require 'stoplight/notifier/rollbar'
28
30
  require 'stoplight/notifier/slack'
29
31
 
30
32
  require 'stoplight/default'
data/spec/spec_helper.rb CHANGED
@@ -1,7 +1,6 @@
1
- # coding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
- require 'coveralls'
4
- Coveralls.wear!
3
+ require 'simplecov'
5
4
 
6
5
  require 'stoplight'
7
6
  require 'timecop'
@@ -1,4 +1,4 @@
1
- # coding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  require 'spec_helper'
4
4
 
@@ -1,4 +1,4 @@
1
- # coding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  require 'spec_helper'
4
4
 
@@ -1,4 +1,4 @@
1
- # coding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  require 'spec_helper'
4
4
 
@@ -1,4 +1,4 @@
1
- # coding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  require 'spec_helper'
4
4
  require 'fakeredis'
@@ -1,4 +1,4 @@
1
- # coding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  require 'spec_helper'
4
4
 
@@ -1,4 +1,4 @@
1
- # coding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  require 'spec_helper'
4
4
 
@@ -74,7 +74,7 @@ RSpec.describe Stoplight::Default do
74
74
 
75
75
  describe '::THRESHOLD' do
76
76
  it 'is an integer' do
77
- expect(Stoplight::Default::THRESHOLD).to be_a(Fixnum)
77
+ expect(Stoplight::Default::THRESHOLD).to be_a(Integer)
78
78
  end
79
79
  end
80
80
  end
@@ -1,4 +1,4 @@
1
- # coding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  require 'spec_helper'
4
4
 
@@ -1,4 +1,4 @@
1
- # coding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  require 'spec_helper'
4
4
 
@@ -89,6 +89,11 @@ RSpec.describe Stoplight::Failure do
89
89
  expect(described_class.new(error_class, error_message, time).to_json)
90
90
  .to eql(json)
91
91
  end
92
+
93
+ it 'generates JSON with options' do
94
+ expect(described_class.new(error_class, error_message, time).to_json({}))
95
+ .to eql(json)
96
+ end
92
97
  end
93
98
 
94
99
  describe '::TIME_FORMAT' do
@@ -1,4 +1,4 @@
1
- # coding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  require 'spec_helper'
4
4
  require 'stringio'
@@ -8,7 +8,7 @@ RSpec.describe Stoplight::Light::Runnable do
8
8
 
9
9
  let(:code) { -> { code_result } }
10
10
  let(:code_result) { random_string }
11
- let(:fallback) { -> (_) { fallback_result } }
11
+ let(:fallback) { ->(_) { fallback_result } }
12
12
  let(:fallback_result) { random_string }
13
13
  let(:name) { random_string }
14
14
 
@@ -123,12 +123,10 @@ RSpec.describe Stoplight::Light::Runnable do
123
123
 
124
124
  context 'with an error handler' do
125
125
  let(:result) do
126
- begin
127
- subject.run
128
- expect(false).to be(true)
129
- rescue error.class
130
- expect(true).to be(true)
131
- end
126
+ subject.run
127
+ expect(false).to be(true)
128
+ rescue error.class
129
+ expect(true).to be(true)
132
130
  end
133
131
 
134
132
  it 'records the failure when the handler does nothing' do
@@ -171,7 +169,7 @@ RSpec.describe Stoplight::Light::Runnable do
171
169
 
172
170
  context 'when the data store is failing' do
173
171
  let(:data_store) { Object.new }
174
- let(:error_notifier) { -> (_) {} }
172
+ let(:error_notifier) { ->(_) {} }
175
173
 
176
174
  before do
177
175
  subject
@@ -1,4 +1,4 @@
1
- # coding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  require 'spec_helper'
4
4
  require 'stringio'
@@ -42,7 +42,7 @@ RSpec.describe Stoplight::Light do
42
42
  after { described_class.default_error_notifier = @default_error_notifier }
43
43
 
44
44
  it 'sets the error notifier' do
45
- default_error_notifier = -> (_) {}
45
+ default_error_notifier = ->(_) {}
46
46
  described_class.default_error_notifier = default_error_notifier
47
47
  expect(described_class.default_error_notifier)
48
48
  .to eql(default_error_notifier)
@@ -140,7 +140,7 @@ RSpec.describe Stoplight::Light do
140
140
 
141
141
  describe '#with_error_handler' do
142
142
  it 'sets the error handler' do
143
- error_handler = -> (_, _) {}
143
+ error_handler = ->(_, _) {}
144
144
  light.with_error_handler(&error_handler)
145
145
  expect(light.error_handler).to eql(error_handler)
146
146
  end
@@ -148,7 +148,7 @@ RSpec.describe Stoplight::Light do
148
148
 
149
149
  describe '#with_error_notifier' do
150
150
  it 'sets the error notifier' do
151
- error_notifier = -> (_) {}
151
+ error_notifier = ->(_) {}
152
152
  light.with_error_notifier(&error_notifier)
153
153
  expect(light.error_notifier).to eql(error_notifier)
154
154
  end
@@ -156,7 +156,7 @@ RSpec.describe Stoplight::Light do
156
156
 
157
157
  describe '#with_fallback' do
158
158
  it 'sets the fallback' do
159
- fallback = -> (_) {}
159
+ fallback = ->(_) {}
160
160
  light.with_fallback(&fallback)
161
161
  expect(light.fallback).to eql(fallback)
162
162
  end
@@ -1,4 +1,4 @@
1
- # coding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  require 'spec_helper'
4
4
 
@@ -1,4 +1,4 @@
1
- # coding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  require 'spec_helper'
4
4
 
@@ -7,8 +7,6 @@ module Bugsnag
7
7
  end
8
8
 
9
9
  RSpec.describe Stoplight::Notifier::Bugsnag do
10
- StoplightStatusChange = Stoplight::Notifier::Bugsnag::StoplightStatusChange
11
-
12
10
  it 'is a class' do
13
11
  expect(described_class).to be_a(Class)
14
12
  end
@@ -65,7 +63,7 @@ RSpec.describe Stoplight::Notifier::Bugsnag do
65
63
  end
66
64
 
67
65
  before do
68
- status_change = StoplightStatusChange.new(message)
66
+ status_change = described_class::StoplightStatusChange.new(message)
69
67
  expect(bugsnag).to receive(:notify).with(status_change, severity: 'info')
70
68
  end
71
69
 
@@ -1,4 +1,4 @@
1
- # coding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  require 'spec_helper'
4
4
 
@@ -1,12 +1,11 @@
1
- # coding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  require 'spec_helper'
4
4
 
5
5
  # require 'hipchat'
6
6
  module HipChat
7
7
  class Client
8
- def initialize(*)
9
- end
8
+ def initialize(*); end
10
9
  end
11
10
  end
12
11
 
@@ -1,4 +1,4 @@
1
- # coding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  require 'spec_helper'
4
4
 
@@ -1,4 +1,4 @@
1
- # coding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  require 'spec_helper'
4
4
  require 'stringio'
@@ -1,4 +1,4 @@
1
- # coding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  require 'spec_helper'
4
4
  require 'logger'
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+ require 'pagerduty'
5
+
6
+ RSpec.describe Stoplight::Notifier::Pagerduty do
7
+ it_behaves_like 'a generic notifier'
8
+
9
+ it 'is a class' do
10
+ expect(described_class).to be_a(Class)
11
+ end
12
+
13
+ it 'is a subclass of Base' do
14
+ expect(described_class).to be < Stoplight::Notifier::Base
15
+ end
16
+
17
+ describe '#pagerduty' do
18
+ it 'reads Pagerduty client' do
19
+ pagerduty = Pagerduty.new('WEBHOOK_URL')
20
+ expect(described_class.new(pagerduty).pagerduty).to eql(pagerduty)
21
+ end
22
+ end
23
+
24
+ describe '#notify' do
25
+ let(:light) { Stoplight::Light.new(name, &code) }
26
+ let(:name) { ('a'..'z').to_a.shuffle.join }
27
+ let(:code) { -> {} }
28
+ let(:from_color) { Stoplight::Color::GREEN }
29
+ let(:to_color) { Stoplight::Color::RED }
30
+ let(:notifier) { described_class.new(pagerduty) }
31
+ let(:pagerduty) { double(Pagerduty).as_null_object }
32
+
33
+ it 'pings Pagerduty' do
34
+ error = nil
35
+ message = notifier.formatter.call(light, from_color, to_color, error)
36
+ expect(pagerduty).to receive(:trigger).with(message)
37
+ notifier.notify(light, from_color, to_color, error)
38
+ end
39
+ end
40
+ end
@@ -1,4 +1,4 @@
1
- # coding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  require 'spec_helper'
4
4
 
@@ -0,0 +1,90 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ # require 'rollbar'
6
+ module Rollbar
7
+ end
8
+
9
+ RSpec.describe Stoplight::Notifier::Rollbar do
10
+ it 'is a class' do
11
+ expect(described_class).to be_a(Class)
12
+ end
13
+
14
+ it 'is a subclass of Base' do
15
+ expect(described_class).to be < Stoplight::Notifier::Base
16
+ end
17
+
18
+ describe '#formatter' do
19
+ it 'is initially the default' do
20
+ expect(described_class.new(nil, nil).formatter)
21
+ .to eql(Stoplight::Default::FORMATTER)
22
+ end
23
+
24
+ it 'reads the formatter' do
25
+ formatter = proc {}
26
+ expect(described_class.new(nil, formatter).formatter)
27
+ .to eql(formatter)
28
+ end
29
+ end
30
+
31
+ describe '#options' do
32
+ it 'is initially the default' do
33
+ expect(described_class.new(nil, nil).options)
34
+ .to eql(Stoplight::Notifier::Rollbar::DEFAULT_OPTIONS)
35
+ end
36
+
37
+ it 'reads the options' do
38
+ options = { key: :value }
39
+ expect(described_class.new(nil, nil, options).options)
40
+ .to eql(Stoplight::Notifier::Rollbar::DEFAULT_OPTIONS.merge(options))
41
+ end
42
+ end
43
+
44
+ describe '#rollbar' do
45
+ it 'reads the Rollbar client' do
46
+ client = Rollbar
47
+ expect(described_class.new(client, nil).rollbar)
48
+ .to eql(client)
49
+ end
50
+ end
51
+
52
+ describe '#notify' do
53
+ let(:light) { Stoplight::Light.new(name, &code) }
54
+ let(:name) { ('a'..'z').to_a.shuffle.join }
55
+ let(:code) { -> {} }
56
+ let(:from_color) { Stoplight::Color::GREEN }
57
+ let(:to_color) { Stoplight::Color::RED }
58
+ let(:notifier) { described_class.new(rollbar) }
59
+ let(:rollbar) { Rollbar }
60
+
61
+ subject(:result) do
62
+ notifier.notify(light, from_color, to_color, error)
63
+ end
64
+
65
+ before do
66
+ status_change = described_class::StoplightStatusChange.new(message)
67
+ expect(rollbar).to receive(:info).with(status_change)
68
+ end
69
+
70
+ context 'when no error given' do
71
+ let(:error) { nil }
72
+
73
+ it 'logs message' do
74
+ expect(result).to eq(message)
75
+ end
76
+ end
77
+
78
+ context 'when message with an error given' do
79
+ let(:error) { ZeroDivisionError.new('divided by 0') }
80
+
81
+ it 'logs message' do
82
+ expect(result).to eq(message)
83
+ end
84
+ end
85
+
86
+ def message
87
+ notifier.formatter.call(light, from_color, to_color, error)
88
+ end
89
+ end
90
+ end
@@ -1,12 +1,11 @@
1
- # coding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  require 'spec_helper'
4
4
 
5
5
  # require 'slack-notifier'
6
6
  module Slack
7
7
  class Notifier
8
- def initialize(*)
9
- end
8
+ def initialize(*); end
10
9
  end
11
10
  end
12
11
 
@@ -1,4 +1,4 @@
1
- # coding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  require 'spec_helper'
4
4
 
@@ -1,4 +1,4 @@
1
- # coding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  require 'spec_helper'
4
4
 
@@ -1,4 +1,4 @@
1
- # coding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  require 'spec_helper'
4
4
 
@@ -1,4 +1,4 @@
1
- # coding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  require 'spec_helper'
4
4
 
metadata CHANGED
@@ -1,16 +1,16 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: stoplight
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.3
4
+ version: 3.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Cameron Desautels
8
8
  - Taylor Fausak
9
9
  - Justin Steffy
10
- autorequire:
10
+ autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2018-04-01 00:00:00.000000000 Z
13
+ date: 2022-02-23 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: benchmark-ips
@@ -40,20 +40,6 @@ dependencies:
40
40
  - - "~>"
41
41
  - !ruby/object:Gem::Version
42
42
  version: '4.0'
43
- - !ruby/object:Gem::Dependency
44
- name: coveralls
45
- requirement: !ruby/object:Gem::Requirement
46
- requirements:
47
- - - "~>"
48
- - !ruby/object:Gem::Version
49
- version: '0.8'
50
- type: :development
51
- prerelease: false
52
- version_requirements: !ruby/object:Gem::Requirement
53
- requirements:
54
- - - "~>"
55
- - !ruby/object:Gem::Version
56
- version: '0.8'
57
43
  - !ruby/object:Gem::Dependency
58
44
  name: fakeredis
59
45
  requirement: !ruby/object:Gem::Requirement
@@ -97,33 +83,33 @@ dependencies:
97
83
  - !ruby/object:Gem::Version
98
84
  version: '2.5'
99
85
  - !ruby/object:Gem::Dependency
100
- name: sentry-raven
86
+ name: pagerduty
101
87
  requirement: !ruby/object:Gem::Requirement
102
88
  requirements:
103
89
  - - "~>"
104
90
  - !ruby/object:Gem::Version
105
- version: '1.2'
91
+ version: 2.1.1
106
92
  type: :development
107
93
  prerelease: false
108
94
  version_requirements: !ruby/object:Gem::Requirement
109
95
  requirements:
110
96
  - - "~>"
111
97
  - !ruby/object:Gem::Version
112
- version: '1.2'
98
+ version: 2.1.1
113
99
  - !ruby/object:Gem::Dependency
114
100
  name: rake
115
101
  requirement: !ruby/object:Gem::Requirement
116
102
  requirements:
117
103
  - - "~>"
118
104
  - !ruby/object:Gem::Version
119
- version: '11.1'
105
+ version: '13.0'
120
106
  type: :development
121
107
  prerelease: false
122
108
  version_requirements: !ruby/object:Gem::Requirement
123
109
  requirements:
124
110
  - - "~>"
125
111
  - !ruby/object:Gem::Version
126
- version: '11.1'
112
+ version: '13.0'
127
113
  - !ruby/object:Gem::Dependency
128
114
  name: redis
129
115
  requirement: !ruby/object:Gem::Requirement
@@ -158,14 +144,56 @@ dependencies:
158
144
  requirements:
159
145
  - - "~>"
160
146
  - !ruby/object:Gem::Version
161
- version: 0.40.0
147
+ version: 1.0.0
148
+ type: :development
149
+ prerelease: false
150
+ version_requirements: !ruby/object:Gem::Requirement
151
+ requirements:
152
+ - - "~>"
153
+ - !ruby/object:Gem::Version
154
+ version: 1.0.0
155
+ - !ruby/object:Gem::Dependency
156
+ name: sentry-raven
157
+ requirement: !ruby/object:Gem::Requirement
158
+ requirements:
159
+ - - "~>"
160
+ - !ruby/object:Gem::Version
161
+ version: '1.2'
162
+ type: :development
163
+ prerelease: false
164
+ version_requirements: !ruby/object:Gem::Requirement
165
+ requirements:
166
+ - - "~>"
167
+ - !ruby/object:Gem::Version
168
+ version: '1.2'
169
+ - !ruby/object:Gem::Dependency
170
+ name: simplecov
171
+ requirement: !ruby/object:Gem::Requirement
172
+ requirements:
173
+ - - "~>"
174
+ - !ruby/object:Gem::Version
175
+ version: '0.21'
176
+ type: :development
177
+ prerelease: false
178
+ version_requirements: !ruby/object:Gem::Requirement
179
+ requirements:
180
+ - - "~>"
181
+ - !ruby/object:Gem::Version
182
+ version: '0.21'
183
+ - !ruby/object:Gem::Dependency
184
+ name: simplecov-lcov
185
+ requirement: !ruby/object:Gem::Requirement
186
+ requirements:
187
+ - - "~>"
188
+ - !ruby/object:Gem::Version
189
+ version: '0.8'
162
190
  type: :development
163
191
  prerelease: false
164
192
  version_requirements: !ruby/object:Gem::Requirement
165
193
  requirements:
166
194
  - - "~>"
167
195
  - !ruby/object:Gem::Version
168
- version: 0.40.0
196
+ version: '0.8'
169
197
  - !ruby/object:Gem::Dependency
170
198
  name: slack-notifier
171
199
  requirement: !ruby/object:Gem::Requirement
@@ -225,7 +253,9 @@ files:
225
253
  - lib/stoplight/notifier/honeybadger.rb
226
254
  - lib/stoplight/notifier/io.rb
227
255
  - lib/stoplight/notifier/logger.rb
256
+ - lib/stoplight/notifier/pagerduty.rb
228
257
  - lib/stoplight/notifier/raven.rb
258
+ - lib/stoplight/notifier/rollbar.rb
229
259
  - lib/stoplight/notifier/slack.rb
230
260
  - lib/stoplight/state.rb
231
261
  - lib/stoplight/version.rb
@@ -247,17 +277,19 @@ files:
247
277
  - spec/stoplight/notifier/honeybadger_spec.rb
248
278
  - spec/stoplight/notifier/io_spec.rb
249
279
  - spec/stoplight/notifier/logger_spec.rb
280
+ - spec/stoplight/notifier/pagerduty_spec.rb
250
281
  - spec/stoplight/notifier/raven_spec.rb
282
+ - spec/stoplight/notifier/rollbar_spec.rb
251
283
  - spec/stoplight/notifier/slack_spec.rb
252
284
  - spec/stoplight/notifier_spec.rb
253
285
  - spec/stoplight/state_spec.rb
254
286
  - spec/stoplight/version_spec.rb
255
287
  - spec/stoplight_spec.rb
256
- homepage: https://github.com/orgsync/stoplight
288
+ homepage: https://github.com/bolshakov/stoplight
257
289
  licenses:
258
290
  - MIT
259
291
  metadata: {}
260
- post_install_message:
292
+ post_install_message:
261
293
  rdoc_options: []
262
294
  require_paths:
263
295
  - lib
@@ -265,40 +297,41 @@ required_ruby_version: !ruby/object:Gem::Requirement
265
297
  requirements:
266
298
  - - ">="
267
299
  - !ruby/object:Gem::Version
268
- version: '2.1'
300
+ version: '2.6'
269
301
  required_rubygems_version: !ruby/object:Gem::Requirement
270
302
  requirements:
271
303
  - - ">="
272
304
  - !ruby/object:Gem::Version
273
305
  version: '0'
274
306
  requirements: []
275
- rubyforge_project:
276
- rubygems_version: 2.5.2
277
- signing_key:
307
+ rubygems_version: 3.2.3
308
+ signing_key:
278
309
  specification_version: 4
279
310
  summary: Traffic control for code.
280
311
  test_files:
281
312
  - spec/spec_helper.rb
282
- - spec/stoplight_spec.rb
313
+ - spec/stoplight/color_spec.rb
314
+ - spec/stoplight/data_store/base_spec.rb
315
+ - spec/stoplight/data_store/memory_spec.rb
316
+ - spec/stoplight/data_store/redis_spec.rb
317
+ - spec/stoplight/data_store_spec.rb
318
+ - spec/stoplight/default_spec.rb
283
319
  - spec/stoplight/error_spec.rb
284
320
  - spec/stoplight/failure_spec.rb
285
- - spec/stoplight/notifier/raven_spec.rb
286
- - spec/stoplight/notifier/io_spec.rb
287
- - spec/stoplight/notifier/logger_spec.rb
288
- - spec/stoplight/notifier/honeybadger_spec.rb
289
- - spec/stoplight/notifier/generic_spec.rb
290
- - spec/stoplight/notifier/slack_spec.rb
321
+ - spec/stoplight/light/runnable_spec.rb
322
+ - spec/stoplight/light_spec.rb
291
323
  - spec/stoplight/notifier/base_spec.rb
292
324
  - spec/stoplight/notifier/bugsnag_spec.rb
325
+ - spec/stoplight/notifier/generic_spec.rb
293
326
  - spec/stoplight/notifier/hip_chat_spec.rb
294
- - spec/stoplight/version_spec.rb
295
- - spec/stoplight/state_spec.rb
327
+ - spec/stoplight/notifier/honeybadger_spec.rb
328
+ - spec/stoplight/notifier/io_spec.rb
329
+ - spec/stoplight/notifier/logger_spec.rb
330
+ - spec/stoplight/notifier/pagerduty_spec.rb
331
+ - spec/stoplight/notifier/raven_spec.rb
332
+ - spec/stoplight/notifier/rollbar_spec.rb
333
+ - spec/stoplight/notifier/slack_spec.rb
296
334
  - spec/stoplight/notifier_spec.rb
297
- - spec/stoplight/color_spec.rb
298
- - spec/stoplight/default_spec.rb
299
- - spec/stoplight/data_store_spec.rb
300
- - spec/stoplight/data_store/memory_spec.rb
301
- - spec/stoplight/data_store/redis_spec.rb
302
- - spec/stoplight/data_store/base_spec.rb
303
- - spec/stoplight/light/runnable_spec.rb
304
- - spec/stoplight/light_spec.rb
335
+ - spec/stoplight/state_spec.rb
336
+ - spec/stoplight/version_spec.rb
337
+ - spec/stoplight_spec.rb