stoplight 3.0.2 → 4.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 (61) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +176 -180
  3. data/lib/stoplight/builder.rb +68 -0
  4. data/lib/stoplight/circuit_breaker.rb +92 -0
  5. data/lib/stoplight/configurable.rb +95 -0
  6. data/lib/stoplight/configuration.rb +126 -0
  7. data/lib/stoplight/data_store/memory.rb +20 -5
  8. data/lib/stoplight/data_store/redis.rb +37 -5
  9. data/lib/stoplight/default.rb +2 -0
  10. data/lib/stoplight/error.rb +1 -0
  11. data/lib/stoplight/light/deprecated.rb +44 -0
  12. data/lib/stoplight/light/lockable.rb +45 -0
  13. data/lib/stoplight/light/runnable.rb +25 -24
  14. data/lib/stoplight/light.rb +69 -63
  15. data/lib/stoplight/rspec/generic_notifier.rb +42 -0
  16. data/lib/stoplight/rspec.rb +3 -0
  17. data/lib/stoplight/version.rb +1 -1
  18. data/lib/stoplight.rb +32 -8
  19. data/spec/spec_helper.rb +7 -0
  20. data/spec/stoplight/builder_spec.rb +165 -0
  21. data/spec/stoplight/circuit_breaker_spec.rb +35 -0
  22. data/spec/stoplight/configurable_spec.rb +25 -0
  23. data/spec/stoplight/data_store/memory_spec.rb +12 -149
  24. data/spec/stoplight/data_store/redis_spec.rb +26 -158
  25. data/spec/stoplight/error_spec.rb +10 -0
  26. data/spec/stoplight/light/lockable_spec.rb +93 -0
  27. data/spec/stoplight/light/runnable_spec.rb +12 -273
  28. data/spec/stoplight/light_spec.rb +4 -28
  29. data/spec/stoplight/notifier/generic_spec.rb +35 -35
  30. data/spec/stoplight/notifier/io_spec.rb +1 -0
  31. data/spec/stoplight/notifier/logger_spec.rb +3 -0
  32. data/spec/stoplight_spec.rb +17 -6
  33. data/spec/support/configurable.rb +69 -0
  34. data/spec/support/data_store/base/clear_failures.rb +18 -0
  35. data/spec/support/data_store/base/clear_state.rb +20 -0
  36. data/spec/support/data_store/base/get_all.rb +44 -0
  37. data/spec/support/data_store/base/get_failures.rb +30 -0
  38. data/spec/support/data_store/base/get_state.rb +7 -0
  39. data/spec/support/data_store/base/names.rb +29 -0
  40. data/spec/support/data_store/base/record_failures.rb +70 -0
  41. data/spec/support/data_store/base/set_state.rb +15 -0
  42. data/spec/support/data_store/base/with_notification_lock.rb +27 -0
  43. data/spec/support/data_store/base.rb +21 -0
  44. data/spec/support/database_cleaner.rb +26 -0
  45. data/spec/support/exception_helpers.rb +9 -0
  46. data/spec/support/light/runnable/color.rb +79 -0
  47. data/spec/support/light/runnable/run.rb +247 -0
  48. data/spec/support/light/runnable.rb +4 -0
  49. metadata +51 -231
  50. data/lib/stoplight/notifier/bugsnag.rb +0 -37
  51. data/lib/stoplight/notifier/honeybadger.rb +0 -44
  52. data/lib/stoplight/notifier/pagerduty.rb +0 -21
  53. data/lib/stoplight/notifier/raven.rb +0 -40
  54. data/lib/stoplight/notifier/rollbar.rb +0 -39
  55. data/lib/stoplight/notifier/slack.rb +0 -21
  56. data/spec/stoplight/notifier/bugsnag_spec.rb +0 -90
  57. data/spec/stoplight/notifier/honeybadger_spec.rb +0 -88
  58. data/spec/stoplight/notifier/pagerduty_spec.rb +0 -40
  59. data/spec/stoplight/notifier/raven_spec.rb +0 -90
  60. data/spec/stoplight/notifier/rollbar_spec.rb +0 -90
  61. data/spec/stoplight/notifier/slack_spec.rb +0 -46
@@ -1,88 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'spec_helper'
4
-
5
- # require 'honeybadger'
6
- module Honeybadger
7
- end
8
-
9
- RSpec.describe Stoplight::Notifier::Honeybadger 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).formatter).to eql(
21
- Stoplight::Default::FORMATTER
22
- )
23
- end
24
-
25
- it 'reads the formatter' do
26
- formatter = proc {}
27
- expect(described_class.new(nil, formatter).formatter).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).options).to eql(
34
- Stoplight::Notifier::Honeybadger::DEFAULT_OPTIONS
35
- )
36
- end
37
-
38
- it 'reads the options' do
39
- options = { key: :value }
40
- expect(described_class.new(nil, nil, options).options).to eql(
41
- Stoplight::Notifier::Honeybadger::DEFAULT_OPTIONS.merge(options)
42
- )
43
- end
44
- end
45
-
46
- describe '#notify' do
47
- let(:light) { Stoplight::Light.new(name, &code) }
48
- let(:name) { ('a'..'z').to_a.shuffle.join }
49
- let(:code) { -> {} }
50
- let(:from_color) { Stoplight::Color::GREEN }
51
- let(:to_color) { Stoplight::Color::RED }
52
- let(:notifier) { described_class.new(api_key) }
53
- let(:api_key) { ('a'..'z').to_a.shuffle.join }
54
-
55
- before do
56
- allow(Honeybadger).to receive(:notify)
57
- end
58
-
59
- it 'returns the message' do
60
- error = nil
61
- message = notifier.formatter.call(light, from_color, to_color, error)
62
- expect(notifier.notify(light, from_color, to_color, error)).to eql(
63
- message
64
- )
65
- expect(Honeybadger).to have_received(:notify).with(
66
- hash_including(
67
- api_key: api_key,
68
- error_message: message
69
- )
70
- )
71
- end
72
-
73
- it 'returns the message with an error' do
74
- error = ZeroDivisionError.new('divided by 0')
75
- message = notifier.formatter.call(light, from_color, to_color, error)
76
- expect(notifier.notify(light, from_color, to_color, error)).to eql(
77
- message
78
- )
79
- expect(Honeybadger).to have_received(:notify).with(
80
- hash_including(
81
- api_key: api_key,
82
- error_message: message,
83
- backtrace: error.backtrace
84
- )
85
- )
86
- end
87
- end
88
- end
@@ -1,40 +0,0 @@
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,90 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'spec_helper'
4
-
5
- # require 'sentry-raven'
6
- module Raven
7
- class Configuration
8
- end
9
- end
10
-
11
- RSpec.describe Stoplight::Notifier::Raven do
12
- it 'is a class' do
13
- expect(described_class).to be_a(Class)
14
- end
15
-
16
- it 'is a subclass of Base' do
17
- expect(described_class).to be < Stoplight::Notifier::Base
18
- end
19
-
20
- describe '#formatter' do
21
- it 'is initially the default' do
22
- expect(described_class.new(nil).formatter).to eql(
23
- Stoplight::Default::FORMATTER
24
- )
25
- end
26
-
27
- it 'reads the formatter' do
28
- formatter = proc {}
29
- expect(described_class.new(nil, formatter).formatter).to eql(formatter)
30
- end
31
- end
32
-
33
- describe '#options' do
34
- it 'is initially the default' do
35
- expect(described_class.new(nil).options).to eql(
36
- Stoplight::Notifier::Raven::DEFAULT_OPTIONS
37
- )
38
- end
39
-
40
- it 'reads the options' do
41
- options = { key: :value }
42
- expect(described_class.new(nil, nil, options).options).to eql(
43
- Stoplight::Notifier::Raven::DEFAULT_OPTIONS.merge(options)
44
- )
45
- end
46
- end
47
-
48
- describe '#notify' do
49
- let(:light) { Stoplight::Light.new(name, &code) }
50
- let(:name) { ('a'..'z').to_a.shuffle.join }
51
- let(:code) { -> {} }
52
- let(:from_color) { Stoplight::Color::GREEN }
53
- let(:to_color) { Stoplight::Color::RED }
54
- let(:notifier) { described_class.new(configuration) }
55
- let(:configuration) { instance_double(::Raven::Configuration) }
56
-
57
- before do
58
- allow(::Raven).to receive(:capture_message)
59
- end
60
-
61
- it 'returns the message' do
62
- error = nil
63
- message = notifier.formatter.call(light, from_color, to_color, error)
64
- expect(notifier.notify(light, from_color, to_color, error)).to eql(
65
- message
66
- )
67
- expect(::Raven).to have_received(:capture_message).with(
68
- message,
69
- hash_including(
70
- configuration: configuration
71
- )
72
- )
73
- end
74
-
75
- it 'returns the message with an error' do
76
- error = ZeroDivisionError.new('divided by 0')
77
- message = notifier.formatter.call(light, from_color, to_color, error)
78
- expect(notifier.notify(light, from_color, to_color, error)).to eql(
79
- message
80
- )
81
- expect(::Raven).to have_received(:capture_message).with(
82
- message,
83
- hash_including(
84
- configuration: configuration,
85
- backtrace: error.backtrace
86
- )
87
- )
88
- end
89
- end
90
- end
@@ -1,90 +0,0 @@
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,46 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'spec_helper'
4
-
5
- # require 'slack-notifier'
6
- module Slack
7
- class Notifier
8
- def initialize(*); end
9
- end
10
- end
11
-
12
- RSpec.describe Stoplight::Notifier::Slack do
13
- it_behaves_like 'a generic notifier'
14
-
15
- it 'is a class' do
16
- expect(described_class).to be_a(Class)
17
- end
18
-
19
- it 'is a subclass of Base' do
20
- expect(described_class).to be < Stoplight::Notifier::Base
21
- end
22
-
23
- describe '#slack' do
24
- it 'reads Slack::Notifier client' do
25
- slack = Slack::Notifier.new('WEBHOOK_URL')
26
- expect(described_class.new(slack).slack).to eql(slack)
27
- end
28
- end
29
-
30
- describe '#notify' do
31
- let(:light) { Stoplight::Light.new(name, &code) }
32
- let(:name) { ('a'..'z').to_a.shuffle.join }
33
- let(:code) { -> {} }
34
- let(:from_color) { Stoplight::Color::GREEN }
35
- let(:to_color) { Stoplight::Color::RED }
36
- let(:notifier) { described_class.new(slack) }
37
- let(:slack) { double(Slack::Notifier).as_null_object }
38
-
39
- it 'pings Slack' do
40
- error = nil
41
- message = notifier.formatter.call(light, from_color, to_color, error)
42
- expect(slack).to receive(:ping).with(message)
43
- notifier.notify(light, from_color, to_color, error)
44
- end
45
- end
46
- end