routemaster-drain 1.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 (58) hide show
  1. checksums.yaml +7 -0
  2. data/.env.test +6 -0
  3. data/.gitignore +7 -0
  4. data/.gitmodules +3 -0
  5. data/.rspec +3 -0
  6. data/.ruby-version +1 -0
  7. data/.travis.yml +16 -0
  8. data/.yardopts +6 -0
  9. data/Gemfile +17 -0
  10. data/Gemfile.lock +122 -0
  11. data/Guardfile +10 -0
  12. data/LICENSE.txt +22 -0
  13. data/README.md +261 -0
  14. data/Rakefile +1 -0
  15. data/lib/routemaster/cache.rb +133 -0
  16. data/lib/routemaster/config.rb +57 -0
  17. data/lib/routemaster/dirty/filter.rb +49 -0
  18. data/lib/routemaster/dirty/map.rb +63 -0
  19. data/lib/routemaster/dirty/state.rb +33 -0
  20. data/lib/routemaster/drain.rb +5 -0
  21. data/lib/routemaster/drain/basic.rb +40 -0
  22. data/lib/routemaster/drain/caching.rb +43 -0
  23. data/lib/routemaster/drain/mapping.rb +43 -0
  24. data/lib/routemaster/drain/terminator.rb +31 -0
  25. data/lib/routemaster/fetcher.rb +63 -0
  26. data/lib/routemaster/jobs/cache.rb +12 -0
  27. data/lib/routemaster/jobs/cache_and_sweep.rb +16 -0
  28. data/lib/routemaster/middleware/authenticate.rb +59 -0
  29. data/lib/routemaster/middleware/cache.rb +29 -0
  30. data/lib/routemaster/middleware/dirty.rb +33 -0
  31. data/lib/routemaster/middleware/filter.rb +26 -0
  32. data/lib/routemaster/middleware/parse.rb +43 -0
  33. data/lib/routemaster/middleware/root_post_only.rb +18 -0
  34. data/lib/routemaster/redis_broker.rb +42 -0
  35. data/routemaster-drain.gemspec +28 -0
  36. data/spec/routemaster/cache_spec.rb +115 -0
  37. data/spec/routemaster/dirty/filter_spec.rb +77 -0
  38. data/spec/routemaster/dirty/map_spec.rb +122 -0
  39. data/spec/routemaster/dirty/state_spec.rb +41 -0
  40. data/spec/routemaster/drain/basic_spec.rb +37 -0
  41. data/spec/routemaster/drain/caching_spec.rb +47 -0
  42. data/spec/routemaster/drain/mapping_spec.rb +51 -0
  43. data/spec/routemaster/drain/terminator_spec.rb +61 -0
  44. data/spec/routemaster/fetcher_spec.rb +56 -0
  45. data/spec/routemaster/middleware/authenticate_spec.rb +59 -0
  46. data/spec/routemaster/middleware/cache_spec.rb +35 -0
  47. data/spec/routemaster/middleware/dirty_spec.rb +33 -0
  48. data/spec/routemaster/middleware/filter_spec.rb +35 -0
  49. data/spec/routemaster/middleware/parse_spec.rb +69 -0
  50. data/spec/routemaster/middleware/root_post_only_spec.rb +30 -0
  51. data/spec/spec_helper.rb +16 -0
  52. data/spec/support/events.rb +9 -0
  53. data/spec/support/rack_test.rb +23 -0
  54. data/spec/support/uses_dotenv.rb +11 -0
  55. data/spec/support/uses_redis.rb +15 -0
  56. data/spec/support/uses_webmock.rb +12 -0
  57. data/test.rb +17 -0
  58. metadata +247 -0
@@ -0,0 +1,59 @@
1
+ require 'spec_helper'
2
+ require 'spec/support/rack_test'
3
+ require 'spec/support/events'
4
+ require 'routemaster/middleware/authenticate'
5
+ require 'json'
6
+
7
+ describe Routemaster::Middleware::Authenticate do
8
+ let(:app) { described_class.new(ErrorRackApp.new, options) }
9
+ let(:listener) { double 'listener', on_authenticate: nil }
10
+ let(:options) {{ uuid: 'demo' }}
11
+
12
+ def perform
13
+ post '/whatever'
14
+ end
15
+
16
+ before { Wisper.subscribe(listener, scope: described_class.name, prefix: true) }
17
+ after { Wisper::GlobalListeners.clear }
18
+
19
+ context 'with valid credentials' do
20
+ before { authorize 'demo', 'x' }
21
+
22
+ it 'passes' do
23
+ perform
24
+ expect(last_response.status).to eq(501) # 501 from ErrorRackApp
25
+ end
26
+
27
+ it 'broadcasts :authenticate :succeeded' do
28
+ expect(listener).to receive(:on_authenticate).with(:succeeded, anything)
29
+ perform
30
+ end
31
+ end
32
+
33
+ context 'with invalid credentials' do
34
+ before { authorize 'h4xx0r', 'x' }
35
+
36
+ it 'fails' do
37
+ perform
38
+ expect(last_response.status).to eq(403)
39
+ end
40
+
41
+ it 'broadcasts :authenticate :failed' do
42
+ expect(listener).to receive(:on_authenticate).with(:failed, anything)
43
+ perform
44
+ end
45
+ end
46
+
47
+ context 'without credentials' do
48
+ it 'fails' do
49
+ perform
50
+ expect(last_response.status).to eq(401)
51
+ end
52
+
53
+ it 'broadcasts :authenticate :missing' do
54
+ expect(listener).to receive(:on_authenticate).with(:missing, anything)
55
+ perform
56
+ end
57
+ end
58
+ end
59
+
@@ -0,0 +1,35 @@
1
+ require 'spec_helper'
2
+ require 'spec/support/rack_test'
3
+ require 'routemaster/middleware/cache'
4
+
5
+ describe Routemaster::Middleware::Cache do
6
+
7
+ # busts the cache for each dirty url
8
+
9
+ let(:terminator) { ErrorRackApp.new }
10
+ let(:app) { described_class.new(terminator, **options) }
11
+ let(:resque) { double 'resque', enqueue_to: nil }
12
+ let(:cache) { double 'cache', bust: nil }
13
+ let(:options) {{ cache: cache, resque: resque }}
14
+
15
+ let(:perform) do
16
+ post '/whatever', '', 'routemaster.dirty' => payload
17
+ end
18
+
19
+ describe '#call' do
20
+ let(:payload) { ['https://example.com/1'] }
21
+
22
+ it 'busts the cache' do
23
+ expect(cache).to receive(:bust).with(payload.first)
24
+ perform
25
+ end
26
+
27
+ it 'queues a fetch job' do
28
+ expect(resque).to receive(:enqueue_to).with('routemaster', anything, 'https://example.com/1')
29
+ perform
30
+ end
31
+ end
32
+ end
33
+
34
+
35
+
@@ -0,0 +1,33 @@
1
+ require 'spec_helper'
2
+ require 'spec/support/rack_test'
3
+ require 'spec/support/events'
4
+ require 'routemaster/middleware/dirty'
5
+
6
+ describe Routemaster::Middleware::Dirty do
7
+ let(:terminator) { ErrorRackApp.new }
8
+ let(:app) { described_class.new(terminator, options) }
9
+
10
+ def perform(payload = nil)
11
+ post '/whatever', '', 'routemaster.payload' => payload
12
+ end
13
+
14
+ describe '#call' do
15
+ let(:map) { double 'dirty_map' }
16
+ let(:options) {{ dirty_map: map }}
17
+ let(:handler) { double }
18
+
19
+ it 'marks the dirty map on events' do
20
+ expect(map).to receive(:mark).exactly(:twice)
21
+ perform([make_event(1), make_event(2)])
22
+ end
23
+
24
+ it 'stores dirty URLs in the environment' do
25
+ allow(map).to receive(:mark).and_return(true, false)
26
+ perform([make_event(1), make_event(1)])
27
+ expect(terminator.last_env['routemaster.dirty']).to eq(['https://example.com/stuff/1'])
28
+ end
29
+ end
30
+ end
31
+
32
+
33
+
@@ -0,0 +1,35 @@
1
+ require 'spec_helper'
2
+ require 'spec/support/rack_test'
3
+ require 'spec/support/events'
4
+ require 'routemaster/middleware/filter'
5
+ require 'json'
6
+
7
+ describe Routemaster::Middleware::Filter do
8
+ let(:terminator) { ErrorRackApp.new }
9
+ let(:app) { described_class.new(terminator, **options) }
10
+
11
+ let(:perform) do
12
+ post '/whatever', '', 'routemaster.payload' => payload
13
+ end
14
+
15
+ describe '#call' do
16
+ let(:filter) { double('filter') }
17
+ let(:options) {{ filter:filter }}
18
+ let(:payload) { [make_event(1)] }
19
+
20
+ it 'calls the filter' do
21
+ expect(filter).to receive(:run).with(payload)
22
+ perform
23
+ end
24
+
25
+ it 'puts filtered events in the environment' do
26
+ allow(filter).to receive(:run).with(payload).and_return(:foo)
27
+ perform
28
+ expect(terminator.last_env['routemaster.payload']).to eq(:foo)
29
+ end
30
+ end
31
+ end
32
+
33
+
34
+
35
+
@@ -0,0 +1,69 @@
1
+ require 'spec_helper'
2
+ require 'spec/support/rack_test'
3
+ require 'spec/support/events'
4
+ require 'routemaster/middleware/parse'
5
+
6
+ describe Routemaster::Middleware::Parse do
7
+ let(:terminator) { ErrorRackApp.new }
8
+ let(:app) { described_class.new(terminator) }
9
+ let(:payload) { [make_event(1), make_event(2)].to_json }
10
+ let(:env) {{ 'CONTENT_TYPE' => 'application/json' }}
11
+ let(:perform) { post '/whatever', payload, env }
12
+
13
+ describe '#call' do
14
+ context 'correct MIME and JSON' do
15
+ it 'yields to next middleware' do
16
+ perform
17
+ expect(last_response.status).to eq(501)
18
+ end
19
+
20
+ it 'passes data in env' do
21
+ perform
22
+ expect(terminator.last_env['routemaster.payload']).to eq([make_event(1), make_event(2)])
23
+ end
24
+ end
25
+
26
+ context 'with bad MIME' do
27
+ let(:env) {{ 'CONTENT_TYPE' => 'text/plain' }}
28
+ it 'returns 415' do
29
+ perform
30
+ expect(last_response.status).to eq(415)
31
+ end
32
+
33
+ it 'does not pass any data' do
34
+ expect(terminator.last_env).not_to include('routemaster.payload')
35
+ end
36
+ end
37
+
38
+ context 'bad JSON' do
39
+ let(:payload) { '[{ "key": "gibberish' }
40
+
41
+ it 'returns 400' do
42
+ perform
43
+ expect(last_response.status).to eq(400)
44
+ end
45
+
46
+ it 'does not pass any data' do
47
+ expect(terminator.last_env).not_to include('routemaster.payload')
48
+ end
49
+ end
50
+
51
+ # context 'no body'
52
+ context 'correct JSON, bad format' do
53
+ let(:payload) { '[{ "type": "noop", "topic":"widgets", "t":123 }]' }
54
+
55
+ it 'returns 400' do
56
+ perform
57
+ expect(last_response.status).to eq(400)
58
+ end
59
+
60
+ it 'does not pass any data' do
61
+ expect(terminator.last_env).not_to include('routemaster.payload')
62
+ end
63
+ end
64
+
65
+ end
66
+ end
67
+
68
+
69
+
@@ -0,0 +1,30 @@
1
+ require 'spec_helper'
2
+ require 'spec/support/rack_test'
3
+ require 'spec/support/events'
4
+ require 'routemaster/middleware/root_post_only'
5
+
6
+ describe Routemaster::Middleware::RootPostOnly do
7
+ let(:terminator) { ErrorRackApp.new }
8
+ let(:app) { described_class.new(terminator) }
9
+
10
+ describe '#call' do
11
+ it 'passes for POST to root' do
12
+ post '/'
13
+ expect(last_response.status).to eq(501)
14
+ end
15
+
16
+ it '405s on non-POST' do
17
+ get '/'
18
+ expect(last_response.status).to eq(405)
19
+ end
20
+
21
+ it '404s on non-root path' do
22
+ get '/why_not_even'
23
+ expect(last_response.status).to eq(404)
24
+ end
25
+ end
26
+ end
27
+
28
+
29
+
30
+
@@ -0,0 +1,16 @@
1
+ # This file was generated by the `rspec --init` command. Conventionally, all
2
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
3
+ # Require this file using `require "spec_helper"` to ensure that it is only
4
+ # loaded once.
5
+ #
6
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
7
+ RSpec.configure do |config|
8
+ config.run_all_when_everything_filtered = true
9
+ config.raise_errors_for_deprecations!
10
+
11
+ # Run specs in random order to surface order dependencies. If you find an
12
+ # order dependency and want to debug it, you can fix the order by providing
13
+ # the seed, which is printed after each run.
14
+ # --seed 1234
15
+ config.order = 'random'
16
+ end
@@ -0,0 +1,9 @@
1
+ module RspecSupportEvents
2
+ def make_event(index)
3
+ { 'topic' => 'stuff', 'type' => 'create', 'url' => "https://example.com/stuff/#{index}", 't' => 1234 }
4
+ end
5
+ end
6
+
7
+ RSpec.configure { |c| c.include RspecSupportEvents }
8
+
9
+
@@ -0,0 +1,23 @@
1
+ ENV['RACK_ENV'] = 'test'
2
+
3
+ require 'rspec'
4
+ require 'rack/test'
5
+
6
+ class ErrorRackApp
7
+ attr_reader :last_env
8
+
9
+ def initialize
10
+ @last_env = {}
11
+ end
12
+
13
+ def call(env)
14
+ @last_env = env
15
+ [501, {}, 'fake app']
16
+ end
17
+ end
18
+
19
+
20
+ RSpec.configure do |conf|
21
+ conf.include Rack::Test::Methods
22
+ end
23
+
@@ -0,0 +1,11 @@
1
+ require 'redis'
2
+ require 'dotenv'
3
+
4
+ module RspecSupportUsesDotenv
5
+ def uses_dotenv
6
+ before(:all) { Dotenv.load!('.env.test') }
7
+ end
8
+ end
9
+
10
+ RSpec.configure { |c| c.extend RspecSupportUsesDotenv }
11
+
@@ -0,0 +1,15 @@
1
+ require 'redis'
2
+ require 'spec/support/uses_dotenv'
3
+ require 'routemaster/config'
4
+
5
+ module RspecSupportUsesRedis
6
+ def uses_redis
7
+ uses_dotenv
8
+
9
+ let(:redis) { Routemaster::Config.drain_redis }
10
+ before { Routemaster::Config.cache_redis.flushdb }
11
+ before { Routemaster::Config.drain_redis.flushdb }
12
+ end
13
+ end
14
+
15
+ RSpec.configure { |c| c.extend RspecSupportUsesRedis }
@@ -0,0 +1,12 @@
1
+ require 'webmock/rspec'
2
+
3
+ module RspecSupportUsesWebmock
4
+ def uses_webmock
5
+ before(:all) { WebMock.enable! }
6
+ after(:all) { WebMock.disable! }
7
+ end
8
+ end
9
+
10
+ RSpec.configure { |c| c.extend RspecSupportUsesWebmock }
11
+ WebMock.disable!
12
+
data/test.rb ADDED
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env ruby
2
+
3
+
4
+ require 'rubygems'
5
+ require 'bundler/setup'
6
+ require 'dotenv'
7
+ require 'pry'
8
+ require 'routemaster/cache'
9
+ # require 'routemaster/client/openssl'
10
+
11
+
12
+ Dotenv.load
13
+ Routemaster::Config.cache_redis.flushdb
14
+ $url = 'https://blackhole.dev/api/widgets/123'
15
+ $cache = Routemaster::Cache.new
16
+
17
+ binding.pry
metadata ADDED
@@ -0,0 +1,247 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: routemaster-drain
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Julien Letessier
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-09-09 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: faraday
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: faraday_middleware
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: net-http-persistent
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rack
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: wisper
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: hashie
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: redis-namespace
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: resque
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: thread
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :runtime
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ description:
140
+ email:
141
+ - julien.letessier@gmail.com
142
+ executables: []
143
+ extensions: []
144
+ extra_rdoc_files: []
145
+ files:
146
+ - ".env.test"
147
+ - ".gitignore"
148
+ - ".gitmodules"
149
+ - ".rspec"
150
+ - ".ruby-version"
151
+ - ".travis.yml"
152
+ - ".yardopts"
153
+ - Gemfile
154
+ - Gemfile.lock
155
+ - Guardfile
156
+ - LICENSE.txt
157
+ - README.md
158
+ - Rakefile
159
+ - lib/routemaster/cache.rb
160
+ - lib/routemaster/config.rb
161
+ - lib/routemaster/dirty/filter.rb
162
+ - lib/routemaster/dirty/map.rb
163
+ - lib/routemaster/dirty/state.rb
164
+ - lib/routemaster/drain.rb
165
+ - lib/routemaster/drain/basic.rb
166
+ - lib/routemaster/drain/caching.rb
167
+ - lib/routemaster/drain/mapping.rb
168
+ - lib/routemaster/drain/terminator.rb
169
+ - lib/routemaster/fetcher.rb
170
+ - lib/routemaster/jobs/cache.rb
171
+ - lib/routemaster/jobs/cache_and_sweep.rb
172
+ - lib/routemaster/middleware/authenticate.rb
173
+ - lib/routemaster/middleware/cache.rb
174
+ - lib/routemaster/middleware/dirty.rb
175
+ - lib/routemaster/middleware/filter.rb
176
+ - lib/routemaster/middleware/parse.rb
177
+ - lib/routemaster/middleware/root_post_only.rb
178
+ - lib/routemaster/redis_broker.rb
179
+ - routemaster-drain.gemspec
180
+ - spec/routemaster/cache_spec.rb
181
+ - spec/routemaster/dirty/filter_spec.rb
182
+ - spec/routemaster/dirty/map_spec.rb
183
+ - spec/routemaster/dirty/state_spec.rb
184
+ - spec/routemaster/drain/basic_spec.rb
185
+ - spec/routemaster/drain/caching_spec.rb
186
+ - spec/routemaster/drain/mapping_spec.rb
187
+ - spec/routemaster/drain/terminator_spec.rb
188
+ - spec/routemaster/fetcher_spec.rb
189
+ - spec/routemaster/middleware/authenticate_spec.rb
190
+ - spec/routemaster/middleware/cache_spec.rb
191
+ - spec/routemaster/middleware/dirty_spec.rb
192
+ - spec/routemaster/middleware/filter_spec.rb
193
+ - spec/routemaster/middleware/parse_spec.rb
194
+ - spec/routemaster/middleware/root_post_only_spec.rb
195
+ - spec/spec_helper.rb
196
+ - spec/support/events.rb
197
+ - spec/support/rack_test.rb
198
+ - spec/support/uses_dotenv.rb
199
+ - spec/support/uses_redis.rb
200
+ - spec/support/uses_webmock.rb
201
+ - test.rb
202
+ homepage: http://github.com/HouseTrip/routemaster_drain
203
+ licenses:
204
+ - MIT
205
+ metadata: {}
206
+ post_install_message:
207
+ rdoc_options: []
208
+ require_paths:
209
+ - lib
210
+ required_ruby_version: !ruby/object:Gem::Requirement
211
+ requirements:
212
+ - - ">="
213
+ - !ruby/object:Gem::Version
214
+ version: '0'
215
+ required_rubygems_version: !ruby/object:Gem::Requirement
216
+ requirements:
217
+ - - ">="
218
+ - !ruby/object:Gem::Version
219
+ version: '0'
220
+ requirements: []
221
+ rubyforge_project:
222
+ rubygems_version: 2.2.2
223
+ signing_key:
224
+ specification_version: 4
225
+ summary: Event receiver for the Routemaster bus
226
+ test_files:
227
+ - spec/routemaster/cache_spec.rb
228
+ - spec/routemaster/dirty/filter_spec.rb
229
+ - spec/routemaster/dirty/map_spec.rb
230
+ - spec/routemaster/dirty/state_spec.rb
231
+ - spec/routemaster/drain/basic_spec.rb
232
+ - spec/routemaster/drain/caching_spec.rb
233
+ - spec/routemaster/drain/mapping_spec.rb
234
+ - spec/routemaster/drain/terminator_spec.rb
235
+ - spec/routemaster/fetcher_spec.rb
236
+ - spec/routemaster/middleware/authenticate_spec.rb
237
+ - spec/routemaster/middleware/cache_spec.rb
238
+ - spec/routemaster/middleware/dirty_spec.rb
239
+ - spec/routemaster/middleware/filter_spec.rb
240
+ - spec/routemaster/middleware/parse_spec.rb
241
+ - spec/routemaster/middleware/root_post_only_spec.rb
242
+ - spec/spec_helper.rb
243
+ - spec/support/events.rb
244
+ - spec/support/rack_test.rb
245
+ - spec/support/uses_dotenv.rb
246
+ - spec/support/uses_redis.rb
247
+ - spec/support/uses_webmock.rb