stoplight 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 99e35ef6375d1da3d14f453873c410bcad7ad4c6
4
- data.tar.gz: 16d8b5d40dd9f17de105a3df570f5d41cdd997c6
3
+ metadata.gz: c9ae554bc9377af5da84befa1e47b71f28d3610b
4
+ data.tar.gz: a65e07dbe879f7895751607894992ad5e8a437f1
5
5
  SHA512:
6
- metadata.gz: 24bc5b7cc600179cdd4ef63976d544379574078c33810faf507aaee6e8a37e78c8a28f88d5897ff053f9b8ffc819dd6a5b07ddecb2e97402ffa7deb436b325ac
7
- data.tar.gz: d3b3339c2ff9c14233ea35035ac96e127894d5455748d9085f7384077bb04d45c7ac31c5f4bd7ed94d21ed876e66f52fda8363bfb5c7464e54b7f5cb18e94082
6
+ metadata.gz: e7e320df17b172d01c35e397d21046f44d30608a3491eb05036b2cfeb75c79afc83c15e01c1fc676518de5e3313fa4597bfd5ca84f0322fbf30ff387bf5eead2
7
+ data.tar.gz: 0db404935da87b9e0b731d9a191288234db19f0b37b240bfe4d32418482a9fe4a6a03f2a039263d379447b5db991e1b172629216997bcf69278f2fb0ed743eda
data/CHANGELOG.md CHANGED
@@ -1,6 +1,10 @@
1
- # Changelog
1
+ # Change log
2
2
 
3
- This project uses [Semantic Versioning][1].
3
+ Stoplight uses [Semantic Versioning][1].
4
+
5
+ ## v1.1.0 (2015-07-04)
6
+
7
+ - #71: Added Slack notifier. Thanks, @s1mplex!
4
8
 
5
9
  ## v1.0.0 (2015-02-19)
6
10
 
data/LICENSE.md CHANGED
@@ -1,20 +1,21 @@
1
+ The MIT License (MIT)
2
+
1
3
  Copyright (c) 2015 Cameron Desautels, Taylor Fausak & Justin Steffy
2
4
 
3
- Permission is hereby granted, free of charge, to any person obtaining
4
- a copy of this software and associated documentation files (the
5
- "Software"), to deal in the Software without restriction, including
6
- without limitation the rights to use, copy, modify, merge, publish,
7
- distribute, sublicense, and/or sell copies of the Software, and to
8
- permit persons to whom the Software is furnished to do so, subject
9
- to the following conditions:
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:
10
11
 
11
- The above copyright notice and this permission notice shall be
12
- included in all copies or substantial portions of the Software.
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
13
14
 
14
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17
- IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
18
- ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
19
- CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
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.
data/README.md CHANGED
@@ -1,37 +1,20 @@
1
- <p align="center">
2
- <img alt="Stoplight" src="https://a.pomf.se/wdlzpt.svg">
3
- </p>
4
-
5
- <h1 align="center">
6
- <a href="https://github.com/orgsync/stoplight">
7
- Stoplight
8
- </a>
9
- </h1>
10
-
11
- <p align="center">
12
- Stoplight is traffic control for code. It's an implementation of
13
- the circuit breaker pattern in Ruby.
14
- </p>
15
-
16
- <p align="center">
17
- <a href="https://rubygems.org/gems/stoplight">
18
- <img alt="" src="https://img.shields.io/gem/v/stoplight.svg">
19
- </a>
20
- <a href="https://travis-ci.org/orgsync/stoplight">
21
- <img alt="" src="https://img.shields.io/travis/orgsync/stoplight/master.svg">
22
- </a>
23
- <a href="https://coveralls.io/r/orgsync/stoplight">
24
- <img alt="" src="https://img.shields.io/coveralls/orgsync/stoplight/master.svg">
25
- </a>
26
- <a href="https://codeclimate.com/github/orgsync/stoplight">
27
- <img alt="" src="https://img.shields.io/codeclimate/github/orgsync/stoplight.svg">
28
- </a>
29
- <a href="https://gemnasium.com/orgsync/stoplight">
30
- <img alt="" src="https://img.shields.io/gemnasium/orgsync/stoplight.svg">
31
- </a>
32
- </p>
33
-
34
- <hr>
1
+ # [Stoplight][]
2
+
3
+ [![Version][]](https://rubygems.org/gems/stoplight)
4
+ [![Build][]](https://travis-ci.org/orgsync/stoplight)
5
+ [![Coverage][]](https://coveralls.io/r/orgsync/stoplight)
6
+ [![Grade][]](http://www.libgrader.com/libraries/ruby/stoplight)
7
+ [![Climate][]](https://codeclimate.com/github/orgsync/stoplight)
8
+ [![Dependencies][]](https://gemnasium.com/orgsync/stoplight)
9
+
10
+ Stoplight is traffic control for code. It's an implementation of the circuit
11
+ breaker pattern in Ruby.
12
+
13
+ ---
14
+
15
+ Does your code use unreliable systems, like a flaky database or a
16
+ spotty web service? Wrap those up with stoplights to prevent them
17
+ from affecting the rest of your application down.
35
18
 
36
19
  Check out [stoplight-admin][] for controlling your stoplights.
37
20
 
@@ -45,9 +28,12 @@ Check out [stoplight-admin][] for controlling your stoplights.
45
28
  - [Setup](#setup)
46
29
  - [Data store](#data-store)
47
30
  - [Notifiers](#notifiers)
31
+ - [HipChat](#hipchat)
32
+ - [Slack](#slack)
48
33
  - [Rails](#rails-1)
49
34
  - [Advanced usage](#advanced-usage)
50
35
  - [Locking](#locking)
36
+ - [Testing](#testing)
51
37
  - [Credits](#credits)
52
38
 
53
39
  ## Installation
@@ -55,15 +41,20 @@ Check out [stoplight-admin][] for controlling your stoplights.
55
41
  Add it to your Gemfile:
56
42
 
57
43
  ``` rb
58
- gem 'stoplight', '~> 1.0'
44
+ gem 'stoplight', '~> 1.1'
59
45
  ```
60
46
 
61
47
  Or install it manually:
62
48
 
63
49
  ``` sh
64
- $ gem install stoplight --version '~> 1.0'
50
+ $ gem install stoplight --version '~> 1.1'
65
51
  ```
66
52
 
53
+ Stoplight uses [Semantic Versioning][]. Check out [the change log][] for a
54
+ detailed list of changes.
55
+
56
+ Stoplight works with all supported versions of Ruby (2.0 through 2.2).
57
+
67
58
  ## Basic usage
68
59
 
69
60
  To get started, create a stoplight:
@@ -74,7 +65,8 @@ light = Stoplight('example-1') { 22.0 / 7 }
74
65
  ```
75
66
 
76
67
  Then you can run it and it will return the result of calling the
77
- block. This is the green state.
68
+ block. This is the green state. (The green state corresponds to the
69
+ closed state for circuit breakers.)
78
70
 
79
71
  ``` rb
80
72
  light.run
@@ -94,7 +86,8 @@ light = Stoplight('example-2') { 1 / 0 }
94
86
 
95
87
  Now when you run it, the error will be recorded and passed through.
96
88
  After running it a few times, the stoplight will stop trying and
97
- fail fast. This is the red state.
89
+ fail fast. This is the red state. (The red state corresponds to the
90
+ open state for circuit breakers.)
98
91
 
99
92
  ``` rb
100
93
  light.run
@@ -111,7 +104,16 @@ light.color
111
104
  ```
112
105
 
113
106
  When the stoplight changes from green to red, it will notify every
114
- configured notifier.
107
+ configured notifier. See [the notifiers section][] to learn more
108
+ about notifiers.
109
+
110
+ The stoplight will move into the yellow state after being in the
111
+ red state for a while. (The yellow state corresponds to the half
112
+ open state for circuit breakers.) To configure how long it takes
113
+ to switch into the yellow state, check out [the timeout section][]
114
+ When stoplights are yellow, they'll try to run their code. If it
115
+ fails, they'll switch back to red. If it succeeds, they'll switch
116
+ to green.
115
117
 
116
118
  ### Custom errors
117
119
 
@@ -179,7 +181,7 @@ light.run
179
181
  ### Custom timeout
180
182
 
181
183
  Stoplights will automatically attempt to recover after a certain
182
- amount of time. A light in the red state for longer than the timeout
184
+ amount of time. A light in the red state for longer than the timeout
183
185
  will transition to the yellow state. This timeout is customizable.
184
186
 
185
187
  ``` rb
@@ -211,7 +213,9 @@ Here's an example configuration:
211
213
  ``` rb
212
214
  class ApplicationController < ActionController::Base
213
215
  around_action :stoplight
216
+
214
217
  private
218
+
215
219
  def stoplight(&block)
216
220
  Stoplight("#{params[:controller]}##{params[:action]}", &block)
217
221
  .with_allowed_errors([ActiveRecord::RecordNotFound])
@@ -262,10 +266,12 @@ Stoplight::Light.default_notifiers
262
266
  # => [#<Stoplight::Notifier::IO:...>]
263
267
  ```
264
268
 
265
- If you want to send notifications elsewhere, you'll have to set
266
- them up. Currently the only other supported notifier is HipChat.
267
- Make sure you have [the HipChat gem][] installed before configuring
268
- Stoplight.
269
+ If you want to send notifications elsewhere, you'll have to set them up.
270
+ Currently the only supported notifiers are HipChat and Slack.
271
+
272
+ #### HipChat
273
+
274
+ Make sure you have [the HipChat gem][] installed before configuring Stoplight.
269
275
 
270
276
  ``` rb
271
277
  require 'hipchat'
@@ -278,6 +284,21 @@ Stoplight::Light.default_notifiers += [notifier]
278
284
  # => [#<Stoplight::Notifier::IO:...>, #<Stoplight::Notifier::HipChat:...>]
279
285
  ```
280
286
 
287
+ #### Slack
288
+
289
+ Make sure you have [the Slack gem][] installed before configuring Stoplight.
290
+
291
+ ``` rb
292
+ require 'slack-notifier'
293
+ # => true
294
+ slack = Slack::Notifier.new('http://www.example.com/webhook-url')
295
+ # => #<Slack::Notifier:...>
296
+ notifier = Stoplight::Notifier::Slack.new(slack)
297
+ # => #<Stoplight::Notifier::Slack:...>
298
+ Stoplight::Light.default_notifiers += [notifier]
299
+ # => [#<Stoplight::Notifier::IO:...>, #<Stoplight::Notifier::Slack:...>]
300
+ ```
301
+
281
302
  ### Rails
282
303
 
283
304
  Stoplight is designed to work seamlessly with Rails. If you want
@@ -316,16 +337,61 @@ If you have configured a custom data store and that data store
316
337
  fails, Stoplight will switch over to using a blank in-memory data
317
338
  store. That means you will lose the locked state of any stoplights.
318
339
 
340
+ ## Testing
341
+
342
+ Stoplights typically work as expected without modification in test suites.
343
+ However there are a few things you can do to make them behave better. If your
344
+ stoplights are spewing messages into your test output, you can silence them
345
+ with a couple configuration changes.
346
+
347
+ ``` rb
348
+ Stoplight::Light.default_error_notifier = -> _ {}
349
+ Stoplight::Light.default_notifiers = []
350
+ ```
351
+
352
+ If your tests mysteriously fail because stoplights are the wrong color, you can
353
+ try resetting the data store before each test case. For example, this would
354
+ give each test case a fresh data store with RSpec.
355
+
356
+ ``` rb
357
+ before(:each) do
358
+ Stoplight::Light.default_data_Store = Stoplight::DataStore::Memory.new
359
+ end
360
+ ```
361
+
362
+ Sometimes you may want to test stoplights directly. You can avoid resetting the
363
+ data store by giving each stoplight a unique name.
364
+
365
+ ``` rb
366
+ stoplight = Stoplight("test-#{rand}") { ... }
367
+ ```
368
+
319
369
  ## Credits
320
370
 
321
- Stoplight is brought to you by [@camdez][] and [@tfausak][] from
322
- [@OrgSync][]. We were inspired by Martin Fowler's [CircuitBreaker][]
323
- article.
371
+ Stoplight is brought to you by [@camdez][] and [@tfausak][] from [@OrgSync][].
372
+ A [complete list of contributors][] is available on GitHub. We were inspired by
373
+ Martin Fowler's [CircuitBreaker][] article.
374
+
375
+ Stoplight is licensed under [the MIT License][].
324
376
 
377
+ [stoplight]: https://github.com/orgsync/stoplight
378
+ [version]: https://img.shields.io/gem/v/stoplight.svg?label=version
379
+ [build]: https://img.shields.io/travis/orgsync/stoplight/master.svg?label=build
380
+ [grade]: https://img.shields.io/badge/grade-A-brightgreen.svg
381
+ [coverage]: https://img.shields.io/coveralls/orgsync/stoplight/master.svg?label=coverage
382
+ [climate]: https://img.shields.io/codeclimate/github/orgsync/stoplight.svg?label=climate
383
+ [dependencies]: https://img.shields.io/gemnasium/orgsync/stoplight.svg?label=dependencies
325
384
  [stoplight-admin]: https://github.com/orgsync/stoplight-admin
385
+ [semantic versioning]: http://semver.org/spec/v2.0.0.html
386
+ [the change log]: CHANGELOG.md
387
+ [the notifiers section]: #notifiers
388
+ [the timeout section]: #custom-timeout
326
389
  [the redis gem]: https://rubygems.org/gems/redis
327
390
  [the hipchat gem]: https://rubygems.org/gems/hipchat
391
+ [the slack gem]: https://rubygems.org/gems/slack-notifier
328
392
  [@camdez]: https://github.com/camdez
329
393
  [@tfausak]: https://github.com/tfausak
330
394
  [@orgsync]: https://github.com/OrgSync
395
+ [complete list of contributors]: https://github.com/orgsync/stoplight/graphs/contributors
331
396
  [circuitbreaker]: http://martinfowler.com/bliki/CircuitBreaker.html
397
+ [the mit license]: LICENSE.md
data/lib/stoplight.rb CHANGED
@@ -19,6 +19,7 @@ require 'stoplight/notifier'
19
19
  require 'stoplight/notifier/base'
20
20
  require 'stoplight/notifier/hip_chat'
21
21
  require 'stoplight/notifier/io'
22
+ require 'stoplight/notifier/slack'
22
23
 
23
24
  require 'stoplight/default'
24
25
 
@@ -40,7 +40,7 @@ module Stoplight
40
40
  end
41
41
 
42
42
  def record_failure(light, failure)
43
- size, _ = @redis.multi do
43
+ size, = @redis.multi do
44
44
  @redis.lpush(failures_key(light), failure.to_json)
45
45
  @redis.ltrim(failures_key(light), 0, light.threshold - 1)
46
46
  end
@@ -49,7 +49,7 @@ module Stoplight
49
49
  end
50
50
 
51
51
  def clear_failures(light)
52
- failures, _ = @redis.multi do
52
+ failures, = @redis.multi do
53
53
  query_failures(light)
54
54
  @redis.del(failures_key(light))
55
55
  end
@@ -67,7 +67,7 @@ module Stoplight
67
67
  end
68
68
 
69
69
  def clear_state(light)
70
- state, _ = @redis.multi do
70
+ state, = @redis.multi do
71
71
  query_state(light)
72
72
  @redis.hdel(states_key, light.name)
73
73
  end
@@ -0,0 +1,27 @@
1
+ # coding: utf-8
2
+
3
+ module Stoplight
4
+ module Notifier
5
+ # @see Base
6
+ class Slack < Base
7
+ # @return [Proc]
8
+ attr_reader :formatter
9
+
10
+ # @return [::Slack::Notifier]
11
+ attr_reader :slack
12
+
13
+ # @param slack [::Slack::Notifier]
14
+ # @param formatter [Proc, nil]
15
+ def initialize(slack, formatter = nil)
16
+ @slack = slack
17
+ @formatter = formatter || Default::FORMATTER
18
+ end
19
+
20
+ def notify(light, from_color, to_color, error)
21
+ message = formatter.call(light, from_color, to_color, error)
22
+ slack.ping(message)
23
+ message
24
+ end
25
+ end
26
+ end
27
+ end
@@ -1,5 +1,5 @@
1
1
  # coding: utf-8
2
2
 
3
3
  module Stoplight
4
- VERSION = Gem::Version.new('1.0.0')
4
+ VERSION = Gem::Version.new('1.1.0')
5
5
  end
data/spec/spec_helper.rb CHANGED
@@ -7,3 +7,10 @@ require 'stoplight'
7
7
  require 'timecop'
8
8
 
9
9
  Timecop.safe_mode = true
10
+
11
+ RSpec.configure do |rspec|
12
+ rspec.color = true
13
+ rspec.disable_monkey_patching!
14
+ rspec.order = :random
15
+ rspec.warnings = true
16
+ end
@@ -2,7 +2,7 @@
2
2
 
3
3
  require 'spec_helper'
4
4
 
5
- describe Stoplight::Color do
5
+ RSpec.describe Stoplight::Color do
6
6
  it 'is a module' do
7
7
  expect(described_class).to be_a(Module)
8
8
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  require 'spec_helper'
4
4
 
5
- describe Stoplight::DataStore::Base do
5
+ RSpec.describe Stoplight::DataStore::Base do
6
6
  let(:data_store) { described_class.new }
7
7
 
8
8
  it 'is a class' do
@@ -2,7 +2,7 @@
2
2
 
3
3
  require 'spec_helper'
4
4
 
5
- describe Stoplight::DataStore::Memory do
5
+ RSpec.describe Stoplight::DataStore::Memory do
6
6
  let(:data_store) { described_class.new }
7
7
  let(:light) { Stoplight::Light.new(name) {} }
8
8
  let(:name) { ('a'..'z').to_a.shuffle.join }
@@ -3,7 +3,7 @@
3
3
  require 'spec_helper'
4
4
  require 'fakeredis'
5
5
 
6
- describe Stoplight::DataStore::Redis do
6
+ RSpec.describe Stoplight::DataStore::Redis do
7
7
  let(:data_store) { described_class.new(redis) }
8
8
  let(:redis) { Redis.new }
9
9
  let(:light) { Stoplight::Light.new(name) {} }
@@ -2,7 +2,7 @@
2
2
 
3
3
  require 'spec_helper'
4
4
 
5
- describe Stoplight::DataStore do
5
+ RSpec.describe Stoplight::DataStore do
6
6
  it 'is a module' do
7
7
  expect(described_class).to be_a(Module)
8
8
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  require 'spec_helper'
4
4
 
5
- describe Stoplight::Default do
5
+ RSpec.describe Stoplight::Default do
6
6
  it 'is a module' do
7
7
  expect(described_class).to be_a(Module)
8
8
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  require 'spec_helper'
4
4
 
5
- describe Stoplight::Error do
5
+ RSpec.describe Stoplight::Error do
6
6
  it 'is a module' do
7
7
  expect(described_class).to be_a(Module)
8
8
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  require 'spec_helper'
4
4
 
5
- describe Stoplight::Failure do
5
+ RSpec.describe Stoplight::Failure do
6
6
  let(:error) { ZeroDivisionError.new('divided by 0') }
7
7
  let(:error_class) { error.class.name }
8
8
  let(:error_message) { error.message }
@@ -2,7 +2,7 @@
2
2
 
3
3
  require 'spec_helper'
4
4
 
5
- describe Stoplight::Light::Runnable do
5
+ RSpec.describe Stoplight::Light::Runnable do
6
6
  subject { Stoplight::Light.new(name, &code) }
7
7
 
8
8
  let(:code) { -> { code_result } }
@@ -20,7 +20,7 @@ describe Stoplight::Light::Runnable do
20
20
  let(:time) { Time.new }
21
21
 
22
22
  def random_string
23
- ('a'..'z').to_a.shuffle.first(8).join
23
+ ('a'..'z').to_a.sample(8).join
24
24
  end
25
25
 
26
26
  describe '#color' do
@@ -2,7 +2,7 @@
2
2
 
3
3
  require 'spec_helper'
4
4
 
5
- describe Stoplight::Light do
5
+ RSpec.describe Stoplight::Light do
6
6
  let(:light) { described_class.new(name, &code) }
7
7
  let(:name) { ('a'..'z').to_a.shuffle.join }
8
8
  let(:code) { -> {} }
@@ -2,7 +2,7 @@
2
2
 
3
3
  require 'spec_helper'
4
4
 
5
- describe Stoplight::Notifier::Base do
5
+ RSpec.describe Stoplight::Notifier::Base do
6
6
  let(:notifier) { described_class.new }
7
7
 
8
8
  it 'is a class' do
@@ -3,7 +3,7 @@
3
3
  require 'spec_helper'
4
4
  require 'hipchat'
5
5
 
6
- describe Stoplight::Notifier::HipChat do
6
+ RSpec.describe Stoplight::Notifier::HipChat do
7
7
  it 'is a class' do
8
8
  expect(described_class).to be_a(Module)
9
9
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  require 'spec_helper'
4
4
 
5
- describe Stoplight::Notifier::IO do
5
+ RSpec.describe Stoplight::Notifier::IO do
6
6
  it 'is a class' do
7
7
  expect(described_class).to be_a(Module)
8
8
  end
@@ -0,0 +1,55 @@
1
+ # coding: utf-8
2
+
3
+ require 'spec_helper'
4
+ require 'slack-notifier'
5
+
6
+ RSpec.describe Stoplight::Notifier::Slack do
7
+ it 'is a subclass of Base' do
8
+ expect(described_class).to be < Stoplight::Notifier::Base
9
+ end
10
+
11
+ describe '#formatter' do
12
+ it 'is initially the default' do
13
+ expect(described_class.new(nil).formatter)
14
+ .to eql(Stoplight::Default::FORMATTER)
15
+ end
16
+
17
+ it 'reads the formatter' do
18
+ formatter = proc {}
19
+ expect(described_class.new(nil, formatter).formatter).to eql(formatter)
20
+ end
21
+ end
22
+
23
+ describe '#slack_notifier' 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) }
38
+
39
+ before do
40
+ expect(slack).to receive(:ping).with(kind_of(String))
41
+ end
42
+
43
+ it 'returns the message' do
44
+ error = nil
45
+ expect(notifier.notify(light, from_color, to_color, error))
46
+ .to eql(notifier.formatter.call(light, from_color, to_color, error))
47
+ end
48
+
49
+ it 'returns the message with an error' do
50
+ error = ZeroDivisionError.new('divided by 0')
51
+ expect(notifier.notify(light, from_color, to_color, error))
52
+ .to eql(notifier.formatter.call(light, from_color, to_color, error))
53
+ end
54
+ end
55
+ end
@@ -2,7 +2,7 @@
2
2
 
3
3
  require 'spec_helper'
4
4
 
5
- describe Stoplight::Notifier do
5
+ RSpec.describe Stoplight::Notifier do
6
6
  it 'is a module' do
7
7
  expect(described_class).to be_a(Module)
8
8
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  require 'spec_helper'
4
4
 
5
- describe Stoplight::State do
5
+ RSpec.describe Stoplight::State do
6
6
  it 'is a module' do
7
7
  expect(described_class).to be_a(Module)
8
8
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  require 'spec_helper'
4
4
 
5
- describe Stoplight::VERSION do
5
+ RSpec.describe Stoplight::VERSION do
6
6
  it 'is a gem version' do
7
7
  expect(described_class).to be_a(Gem::Version)
8
8
  end
@@ -2,13 +2,13 @@
2
2
 
3
3
  require 'spec_helper'
4
4
 
5
- describe Stoplight do
5
+ RSpec.describe Stoplight do
6
6
  it 'is a module' do
7
7
  expect(described_class).to be_a(Module)
8
8
  end
9
9
  end
10
10
 
11
- describe 'Stoplight' do
11
+ RSpec.describe 'Stoplight' do
12
12
  subject(:light) { Stoplight(name, &code) }
13
13
  let(:name) { ('a'..'z').to_a.shuffle.join }
14
14
  let(:code) { -> {} }
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: stoplight
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Cameron Desautels
@@ -10,146 +10,202 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2015-02-19 00:00:00.000000000 Z
13
+ date: 2015-07-04 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: benchmark-ips
17
17
  requirement: !ruby/object:Gem::Requirement
18
18
  requirements:
19
- - - ~>
19
+ - - "~>"
20
20
  - !ruby/object:Gem::Version
21
- version: '2.1'
21
+ version: '2.2'
22
22
  type: :development
23
23
  prerelease: false
24
24
  version_requirements: !ruby/object:Gem::Requirement
25
25
  requirements:
26
- - - ~>
26
+ - - "~>"
27
27
  - !ruby/object:Gem::Version
28
- version: '2.1'
28
+ version: '2.2'
29
29
  - !ruby/object:Gem::Dependency
30
30
  name: coveralls
31
31
  requirement: !ruby/object:Gem::Requirement
32
32
  requirements:
33
- - - ~>
33
+ - - "~>"
34
34
  - !ruby/object:Gem::Version
35
- version: '0.7'
35
+ version: '0.8'
36
36
  type: :development
37
37
  prerelease: false
38
38
  version_requirements: !ruby/object:Gem::Requirement
39
39
  requirements:
40
- - - ~>
40
+ - - "~>"
41
41
  - !ruby/object:Gem::Version
42
- version: '0.7'
42
+ version: '0.8'
43
43
  - !ruby/object:Gem::Dependency
44
44
  name: fakeredis
45
45
  requirement: !ruby/object:Gem::Requirement
46
46
  requirements:
47
- - - ~>
47
+ - - "~>"
48
48
  - !ruby/object:Gem::Version
49
49
  version: '0.5'
50
50
  type: :development
51
51
  prerelease: false
52
52
  version_requirements: !ruby/object:Gem::Requirement
53
53
  requirements:
54
- - - ~>
54
+ - - "~>"
55
55
  - !ruby/object:Gem::Version
56
56
  version: '0.5'
57
+ - !ruby/object:Gem::Dependency
58
+ name: guard
59
+ requirement: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - "~>"
62
+ - !ruby/object:Gem::Version
63
+ version: '2.12'
64
+ type: :development
65
+ prerelease: false
66
+ version_requirements: !ruby/object:Gem::Requirement
67
+ requirements:
68
+ - - "~>"
69
+ - !ruby/object:Gem::Version
70
+ version: '2.12'
71
+ - !ruby/object:Gem::Dependency
72
+ name: guard-rspec
73
+ requirement: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - "~>"
76
+ - !ruby/object:Gem::Version
77
+ version: '4.6'
78
+ type: :development
79
+ prerelease: false
80
+ version_requirements: !ruby/object:Gem::Requirement
81
+ requirements:
82
+ - - "~>"
83
+ - !ruby/object:Gem::Version
84
+ version: '4.6'
85
+ - !ruby/object:Gem::Dependency
86
+ name: guard-rubocop
87
+ requirement: !ruby/object:Gem::Requirement
88
+ requirements:
89
+ - - "~>"
90
+ - !ruby/object:Gem::Version
91
+ version: '1.2'
92
+ type: :development
93
+ prerelease: false
94
+ version_requirements: !ruby/object:Gem::Requirement
95
+ requirements:
96
+ - - "~>"
97
+ - !ruby/object:Gem::Version
98
+ version: '1.2'
57
99
  - !ruby/object:Gem::Dependency
58
100
  name: hipchat
59
101
  requirement: !ruby/object:Gem::Requirement
60
102
  requirements:
61
- - - ~>
103
+ - - "~>"
62
104
  - !ruby/object:Gem::Version
63
- version: '1.4'
105
+ version: '1.5'
64
106
  type: :development
65
107
  prerelease: false
66
108
  version_requirements: !ruby/object:Gem::Requirement
67
109
  requirements:
68
- - - ~>
110
+ - - "~>"
69
111
  - !ruby/object:Gem::Version
70
- version: '1.4'
112
+ version: '1.5'
71
113
  - !ruby/object:Gem::Dependency
72
114
  name: rake
73
115
  requirement: !ruby/object:Gem::Requirement
74
116
  requirements:
75
- - - ~>
117
+ - - "~>"
76
118
  - !ruby/object:Gem::Version
77
119
  version: '10.4'
78
120
  type: :development
79
121
  prerelease: false
80
122
  version_requirements: !ruby/object:Gem::Requirement
81
123
  requirements:
82
- - - ~>
124
+ - - "~>"
83
125
  - !ruby/object:Gem::Version
84
126
  version: '10.4'
85
127
  - !ruby/object:Gem::Dependency
86
128
  name: redis
87
129
  requirement: !ruby/object:Gem::Requirement
88
130
  requirements:
89
- - - ~>
131
+ - - "~>"
90
132
  - !ruby/object:Gem::Version
91
133
  version: '3.2'
92
134
  type: :development
93
135
  prerelease: false
94
136
  version_requirements: !ruby/object:Gem::Requirement
95
137
  requirements:
96
- - - ~>
138
+ - - "~>"
97
139
  - !ruby/object:Gem::Version
98
140
  version: '3.2'
99
141
  - !ruby/object:Gem::Dependency
100
142
  name: rspec
101
143
  requirement: !ruby/object:Gem::Requirement
102
144
  requirements:
103
- - - ~>
145
+ - - "~>"
104
146
  - !ruby/object:Gem::Version
105
- version: '3.2'
147
+ version: '3.3'
106
148
  type: :development
107
149
  prerelease: false
108
150
  version_requirements: !ruby/object:Gem::Requirement
109
151
  requirements:
110
- - - ~>
152
+ - - "~>"
111
153
  - !ruby/object:Gem::Version
112
- version: '3.2'
154
+ version: '3.3'
113
155
  - !ruby/object:Gem::Dependency
114
156
  name: rubocop
115
157
  requirement: !ruby/object:Gem::Requirement
116
158
  requirements:
117
- - - ~>
159
+ - - "~>"
160
+ - !ruby/object:Gem::Version
161
+ version: '0.32'
162
+ type: :development
163
+ prerelease: false
164
+ version_requirements: !ruby/object:Gem::Requirement
165
+ requirements:
166
+ - - "~>"
167
+ - !ruby/object:Gem::Version
168
+ version: '0.32'
169
+ - !ruby/object:Gem::Dependency
170
+ name: slack-notifier
171
+ requirement: !ruby/object:Gem::Requirement
172
+ requirements:
173
+ - - "~>"
118
174
  - !ruby/object:Gem::Version
119
- version: '0.29'
175
+ version: 1.2.1
120
176
  type: :development
121
177
  prerelease: false
122
178
  version_requirements: !ruby/object:Gem::Requirement
123
179
  requirements:
124
- - - ~>
180
+ - - "~>"
125
181
  - !ruby/object:Gem::Version
126
- version: '0.29'
182
+ version: 1.2.1
127
183
  - !ruby/object:Gem::Dependency
128
184
  name: timecop
129
185
  requirement: !ruby/object:Gem::Requirement
130
186
  requirements:
131
- - - ~>
187
+ - - "~>"
132
188
  - !ruby/object:Gem::Version
133
189
  version: '0.7'
134
190
  type: :development
135
191
  prerelease: false
136
192
  version_requirements: !ruby/object:Gem::Requirement
137
193
  requirements:
138
- - - ~>
194
+ - - "~>"
139
195
  - !ruby/object:Gem::Version
140
196
  version: '0.7'
141
197
  - !ruby/object:Gem::Dependency
142
198
  name: yard
143
199
  requirement: !ruby/object:Gem::Requirement
144
200
  requirements:
145
- - - ~>
201
+ - - "~>"
146
202
  - !ruby/object:Gem::Version
147
203
  version: '0.8'
148
204
  type: :development
149
205
  prerelease: false
150
206
  version_requirements: !ruby/object:Gem::Requirement
151
207
  requirements:
152
- - - ~>
208
+ - - "~>"
153
209
  - !ruby/object:Gem::Version
154
210
  version: '0.8'
155
211
  description: An implementation of the circuit breaker pattern.
@@ -162,7 +218,6 @@ extensions: []
162
218
  extra_rdoc_files: []
163
219
  files:
164
220
  - CHANGELOG.md
165
- - CONTRIBUTING.md
166
221
  - LICENSE.md
167
222
  - README.md
168
223
  - lib/stoplight.rb
@@ -180,6 +235,7 @@ files:
180
235
  - lib/stoplight/notifier/base.rb
181
236
  - lib/stoplight/notifier/hip_chat.rb
182
237
  - lib/stoplight/notifier/io.rb
238
+ - lib/stoplight/notifier/slack.rb
183
239
  - lib/stoplight/state.rb
184
240
  - lib/stoplight/version.rb
185
241
  - spec/spec_helper.rb
@@ -196,6 +252,7 @@ files:
196
252
  - spec/stoplight/notifier/base_spec.rb
197
253
  - spec/stoplight/notifier/hip_chat_spec.rb
198
254
  - spec/stoplight/notifier/io_spec.rb
255
+ - spec/stoplight/notifier/slack_spec.rb
199
256
  - spec/stoplight/notifier_spec.rb
200
257
  - spec/stoplight/state_spec.rb
201
258
  - spec/stoplight/version_spec.rb
@@ -210,12 +267,12 @@ require_paths:
210
267
  - lib
211
268
  required_ruby_version: !ruby/object:Gem::Requirement
212
269
  requirements:
213
- - - '>='
270
+ - - ">="
214
271
  - !ruby/object:Gem::Version
215
272
  version: 1.9.3
216
273
  required_rubygems_version: !ruby/object:Gem::Requirement
217
274
  requirements:
218
- - - '>='
275
+ - - ">="
219
276
  - !ruby/object:Gem::Version
220
277
  version: '0'
221
278
  requirements: []
@@ -239,6 +296,7 @@ test_files:
239
296
  - spec/stoplight/notifier/base_spec.rb
240
297
  - spec/stoplight/notifier/hip_chat_spec.rb
241
298
  - spec/stoplight/notifier/io_spec.rb
299
+ - spec/stoplight/notifier/slack_spec.rb
242
300
  - spec/stoplight/notifier_spec.rb
243
301
  - spec/stoplight/state_spec.rb
244
302
  - spec/stoplight/version_spec.rb
data/CONTRIBUTING.md DELETED
@@ -1,7 +0,0 @@
1
- # Contributing
2
-
3
- 1. **Fork** the repository.
4
- 2. Create a **branch** for your feature (`git checkout -b feature`).
5
- 3. **Commit** your changes (`git commit -a -m 'Feature'`).
6
- 4. **Push** to your branch (`git push origin feature`).
7
- 5. Create a **pull request**.