eldr 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.rspec +3 -0
- data/.rubocop.yml +28 -0
- data/.rubocop_todo.yml +15 -0
- data/.travis.yml +3 -0
- data/DUCK.md +15 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +89 -0
- data/LICENSE +20 -0
- data/README.md +876 -0
- data/Rakefile +9 -0
- data/TODOS +3 -0
- data/eldr.gemspec +36 -0
- data/examples/README.md +7 -0
- data/examples/action_objects.ru +28 -0
- data/examples/app.ru +75 -0
- data/examples/builder.ru +24 -0
- data/examples/custom_response.ru +23 -0
- data/examples/errors.ru +16 -0
- data/examples/hello_world.ru +8 -0
- data/examples/inheritance.ru +22 -0
- data/examples/multiple_apps.ru +30 -0
- data/examples/rails_style_routing.ru +14 -0
- data/examples/rendering_templates.ru +38 -0
- data/examples/views/cats.slim +1 -0
- data/lib/eldr/app.rb +146 -0
- data/lib/eldr/builder.rb +60 -0
- data/lib/eldr/configuration.rb +37 -0
- data/lib/eldr/matcher.rb +36 -0
- data/lib/eldr/recognizer.rb +35 -0
- data/lib/eldr/route.rb +92 -0
- data/lib/eldr/version.rb +3 -0
- data/lib/eldr.rb +1 -0
- data/spec/app_spec.rb +194 -0
- data/spec/builder_spec.rb +11 -0
- data/spec/configuration_spec.rb +29 -0
- data/spec/examples/action_objects_spec.rb +18 -0
- data/spec/examples/builder_spec.rb +16 -0
- data/spec/examples/custom_response_spec.rb +17 -0
- data/spec/examples/errors_spec.rb +18 -0
- data/spec/examples/example_app_spec.rb +98 -0
- data/spec/examples/hello_world_spec.rb +17 -0
- data/spec/examples/inheritance_spec.rb +23 -0
- data/spec/examples/multiple_apps_spec.rb +31 -0
- data/spec/examples/rails_style_routing_spec.rb +17 -0
- data/spec/examples/rendering_templates_spec.rb +26 -0
- data/spec/matcher_spec.rb +21 -0
- data/spec/readme_definitions.yml +28 -0
- data/spec/readme_spec.rb +117 -0
- data/spec/recognizer_spec.rb +32 -0
- data/spec/route_spec.rb +131 -0
- data/spec/spec_helper.rb +14 -0
- metadata +252 -0
data/lib/eldr/route.rb
ADDED
@@ -0,0 +1,92 @@
|
|
1
|
+
module Eldr
|
2
|
+
class Route
|
3
|
+
attr_accessor :name, :app, :capture, :order, :options, :handler
|
4
|
+
attr_accessor :before_filters, :after_filters, :to
|
5
|
+
|
6
|
+
def initialize(verb: :get, path: '/', name: nil, options: {}, handler: nil, app: nil)
|
7
|
+
@path, @verb = path, verb.to_s.upcase
|
8
|
+
|
9
|
+
@app = app
|
10
|
+
@capture = {}
|
11
|
+
@before_filters = []
|
12
|
+
@after_filters = []
|
13
|
+
@name = name
|
14
|
+
|
15
|
+
merge_with_options!(options)
|
16
|
+
|
17
|
+
@handler = handler
|
18
|
+
@handler ||= @to
|
19
|
+
end
|
20
|
+
|
21
|
+
def call(env, app: nil)
|
22
|
+
# TODO: Investigate
|
23
|
+
# maybe if we passed this around between methods it would be more perfomant
|
24
|
+
# than setting the accessor?
|
25
|
+
@app = app
|
26
|
+
|
27
|
+
app.class.before_filters[:all].each { |filter| app.instance_exec(env, &filter) } if app
|
28
|
+
@before_filters.each { |filter| app.instance_exec(env, &filter) }
|
29
|
+
|
30
|
+
resp = response(env)
|
31
|
+
|
32
|
+
app.class.after_filters[:all].each { |filter| app.instance_exec(env, &filter) } if app
|
33
|
+
@after_filters.each { |filter| app.instance_exec(env, &filter) }
|
34
|
+
|
35
|
+
resp
|
36
|
+
end
|
37
|
+
|
38
|
+
def response(env)
|
39
|
+
if @handler.is_a? Proc
|
40
|
+
app.instance_exec(env, &@handler)
|
41
|
+
elsif @handler.is_a? String
|
42
|
+
rails_style_response(env)
|
43
|
+
else
|
44
|
+
@handler.call(env)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def rails_style_response(env)
|
49
|
+
controller, method = @handler.split('#')
|
50
|
+
|
51
|
+
obj = Object.const_get(controller).new
|
52
|
+
|
53
|
+
if method
|
54
|
+
obj.send(method.to_sym, env)
|
55
|
+
else
|
56
|
+
obj.call(env)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def merge_with_options!(options)
|
61
|
+
@options = {} unless @options
|
62
|
+
options.each_pair do |key, value|
|
63
|
+
accessor?(key) ? __send__("#{key}=", value) : (@options[key] = value)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def accessor?(key)
|
68
|
+
respond_to?("#{key}=") && respond_to?(key)
|
69
|
+
end
|
70
|
+
|
71
|
+
def matcher
|
72
|
+
@matcher ||= Matcher.new(path, capture: @capture)
|
73
|
+
end
|
74
|
+
|
75
|
+
def match(pattern)
|
76
|
+
matcher.match(pattern)
|
77
|
+
end
|
78
|
+
|
79
|
+
def path(*args)
|
80
|
+
return @path if args.empty?
|
81
|
+
params = args[0]
|
82
|
+
params.delete(:captures)
|
83
|
+
matcher.expand(params)
|
84
|
+
end
|
85
|
+
|
86
|
+
def params(pattern)
|
87
|
+
params = matcher.handler.params(pattern)
|
88
|
+
params ||= {}
|
89
|
+
params
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
data/lib/eldr/version.rb
ADDED
data/lib/eldr.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require_relative 'eldr/app'
|
data/spec/app_spec.rb
ADDED
@@ -0,0 +1,194 @@
|
|
1
|
+
describe Eldr::App do
|
2
|
+
it 'has methods for all the http verbs' do
|
3
|
+
%w(DELETE GET HEAD OPTIONS PATCH POST PUT).each do |verb|
|
4
|
+
expect(Eldr::App.respond_to? verb.downcase.to_sym).to eq(true)
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
describe '.inherited' do
|
9
|
+
it 'inherits middleware' do
|
10
|
+
bob = Class.new(Eldr::App)
|
11
|
+
middleware = Class.new
|
12
|
+
expect(bob.builder.middleware.length).to eq(0)
|
13
|
+
|
14
|
+
bob.use middleware
|
15
|
+
expect(bob.builder.middleware.length).to eq(1)
|
16
|
+
|
17
|
+
# TODO Check that is is the actual class we wanted
|
18
|
+
inherited = Class.new(bob)
|
19
|
+
expect(inherited.builder.middleware.length).to eq(1)
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'inherits configuration' do
|
23
|
+
bob = Class.new(Eldr::App)
|
24
|
+
bob.set(:bob, 'what about him?')
|
25
|
+
|
26
|
+
inherited = Class.new(bob)
|
27
|
+
expect(inherited.configuration.bob).to eq('what about him?')
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe '.new' do
|
32
|
+
it 'returns a new instance of Eldr::Builder' do
|
33
|
+
expect(Eldr::App.new).to be_instance_of Eldr::Builder
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe '.set' do
|
38
|
+
it 'sets configurations values' do
|
39
|
+
bob = Class.new(Eldr::App)
|
40
|
+
bob.set(:bob, 'what about him?')
|
41
|
+
|
42
|
+
expect(bob.config.bob).to eq('what about him?')
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
describe '.before' do
|
47
|
+
it 'adds a before filter' do
|
48
|
+
bob = Class.new(Eldr::App)
|
49
|
+
bob.before {}
|
50
|
+
bob.before(:cats) { }
|
51
|
+
expect(bob.before_filters[:all].length).to eq(1)
|
52
|
+
expect(bob.before_filters[:cats].length).to eq(1)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
describe '.after' do
|
57
|
+
it 'adds an before filter' do
|
58
|
+
bob = Class.new(Eldr::App)
|
59
|
+
bob.after {}
|
60
|
+
bob.after(:cats) { }
|
61
|
+
expect(bob.after_filters[:all].length).to eq(1)
|
62
|
+
expect(bob.after_filters[:cats].length).to eq(1)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
describe '.add' do
|
67
|
+
it 'adds a route to self.routes' do
|
68
|
+
bob = Class.new(Eldr::App)
|
69
|
+
expect(bob.routes[:get].length).to eq(0)
|
70
|
+
bob.add(verb: :get, path: '/', handler: proc {})
|
71
|
+
expect(bob.routes[:get].length).to eq(1)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
describe '.call' do
|
76
|
+
let(:env) do
|
77
|
+
Rack::MockRequest.env_for('/', {:method => :get})
|
78
|
+
end
|
79
|
+
|
80
|
+
it 'creates a new builder instance runs in and returns a response' do
|
81
|
+
bob = Class.new(Eldr::App)
|
82
|
+
expect(bob.call(env)).to eq([404, {}, [""]])
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
describe '#recognize' do
|
87
|
+
let(:resp_proc) { proc { [200, {}, ['Hello Bob!']] } }
|
88
|
+
subject(:app) do
|
89
|
+
bob = Class.new(Eldr::App)
|
90
|
+
bob.get '/cats', resp_proc
|
91
|
+
bob._new
|
92
|
+
end
|
93
|
+
|
94
|
+
let(:env) do
|
95
|
+
Rack::MockRequest.env_for('/cats', {:method => :get})
|
96
|
+
end
|
97
|
+
|
98
|
+
it 'recognizes and returns a route for a given pattern' do
|
99
|
+
expect(app.recognize(env).first.handler).to eq(resp_proc)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
describe '#call' do
|
104
|
+
subject(:app) do
|
105
|
+
Class.new(Eldr::App)
|
106
|
+
end
|
107
|
+
|
108
|
+
let(:env) do
|
109
|
+
Rack::MockRequest.env_for('/cats', {:method => :get})
|
110
|
+
end
|
111
|
+
|
112
|
+
it 'duplicates and runs call! on the duplicate' do
|
113
|
+
expect_any_instance_of(app).to receive(:call!)
|
114
|
+
app._new.call(env)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
describe '#call!' do
|
119
|
+
subject(:app) do
|
120
|
+
bob = Class.new(Eldr::App)
|
121
|
+
bob.get '/cats/:id', name: :cats do
|
122
|
+
[200, {}, ['Hello Bob!']]
|
123
|
+
end
|
124
|
+
|
125
|
+
bob.get '/defer' do
|
126
|
+
throw :pass
|
127
|
+
end
|
128
|
+
|
129
|
+
bob.get '/defer' do
|
130
|
+
[200, {}, ['Hello From Deferred!']]
|
131
|
+
end
|
132
|
+
|
133
|
+
class Error < StandardError
|
134
|
+
def call(_env)
|
135
|
+
[500, {}, ['']]
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
bob.get '/error' do
|
140
|
+
raise Error
|
141
|
+
end
|
142
|
+
|
143
|
+
bob._new
|
144
|
+
end
|
145
|
+
|
146
|
+
let(:env) do
|
147
|
+
Rack::MockRequest.env_for('/cats/bob', {:method => :get})
|
148
|
+
end
|
149
|
+
|
150
|
+
let(:env_defer) do
|
151
|
+
Rack::MockRequest.env_for('/defer', {:method => :get})
|
152
|
+
end
|
153
|
+
|
154
|
+
let(:env_error) do
|
155
|
+
Rack::MockRequest.env_for('/error', {:method => :get})
|
156
|
+
end
|
157
|
+
|
158
|
+
let(:env_error) do
|
159
|
+
Rack::MockRequest.env_for('/error', {:method => :get})
|
160
|
+
end
|
161
|
+
|
162
|
+
let(:env_not_found) do
|
163
|
+
Rack::MockRequest.env_for('/god', {:method => :get})
|
164
|
+
end
|
165
|
+
|
166
|
+
it 'sets eldr.route' do
|
167
|
+
app.call!(env)
|
168
|
+
expect(app.env['eldr.route'].name).to eq(:cats)
|
169
|
+
end
|
170
|
+
|
171
|
+
it 'sets eldr.params' do
|
172
|
+
app.call!(env)
|
173
|
+
expect(app.env['eldr.params']['id']).to eq('bob')
|
174
|
+
end
|
175
|
+
|
176
|
+
context 'when passing/deferring' do
|
177
|
+
it 'calls the next matching route' do
|
178
|
+
expect(app.call!(env_defer).to_a[2].first).to eq('Hello From Deferred!')
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
context 'when raising an error' do
|
183
|
+
it 'catches the error and returns a response' do
|
184
|
+
expect(app.call!(env_error).first).to eq(500)
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
context 'when route does not exist' do
|
189
|
+
it 'returns a 404' do
|
190
|
+
expect(app.call!(env_not_found).first).to eq(404)
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
194
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
describe Eldr::Builder do
|
2
|
+
describe '#use' do
|
3
|
+
it 'supports passing an array of middleware' do
|
4
|
+
builder = Eldr::Builder.new
|
5
|
+
builder.use Class.new
|
6
|
+
builder_2 = Eldr::Builder.new
|
7
|
+
builder_2.use builder.middleware
|
8
|
+
expect(builder_2.middleware).to eq(builder.middleware)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
describe Eldr::Configuration do
|
2
|
+
describe '#initialize' do
|
3
|
+
it 'sets defaults' do
|
4
|
+
expect(Eldr::Configuration.new().lock).to eq(false)
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
describe '#set' do
|
9
|
+
let(:config) { Eldr::Configuration.new }
|
10
|
+
|
11
|
+
it 'sets a configuration value in #table' do
|
12
|
+
config.set(:bob, 'what about him?')
|
13
|
+
expect(config.bob).to eq('what about him?')
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe '#method_missing' do
|
18
|
+
let(:config) { Eldr::Configuration.new }
|
19
|
+
|
20
|
+
it 'returns a value from #table' do
|
21
|
+
config.set(:bob, 'what about him?')
|
22
|
+
expect(config.bob).to eq('what about him?')
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'returns nil as a default' do
|
26
|
+
expect(config.franklin).to eq(nil)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
describe "ActionObjectsExample" do
|
2
|
+
let(:app) do
|
3
|
+
path = File.expand_path("../../examples/action_objects.ru", File.dirname(__FILE__))
|
4
|
+
Rack::Builder.parse_file(path).first
|
5
|
+
end
|
6
|
+
|
7
|
+
let(:rt) do
|
8
|
+
Rack::Test::Session.new(app)
|
9
|
+
end
|
10
|
+
|
11
|
+
describe 'GET /cats/bob' do
|
12
|
+
it 'returns bob' do
|
13
|
+
response = rt.get '/cats/bob'
|
14
|
+
expect(response.body).to eq('Found cat named Bob!')
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
describe 'BuilderExample' do
|
2
|
+
let(:app) do
|
3
|
+
path = File.expand_path("../../examples/builder.ru", File.dirname(__FILE__))
|
4
|
+
Rack::Builder.parse_file(path).first
|
5
|
+
end
|
6
|
+
|
7
|
+
let(:rt) do
|
8
|
+
Rack::Test::Session.new(app)
|
9
|
+
end
|
10
|
+
|
11
|
+
describe 'GET /' do
|
12
|
+
it 'does some counting using middleware' do
|
13
|
+
expect(rt.get('/').body).to eq('1')
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
describe 'CustomResponseExample' do
|
2
|
+
let(:app) do
|
3
|
+
path = File.expand_path("../../examples/custom_response.ru", File.dirname(__FILE__))
|
4
|
+
Rack::Builder.parse_file(path).first
|
5
|
+
end
|
6
|
+
|
7
|
+
let(:rt) do
|
8
|
+
Rack::Test::Session.new(app)
|
9
|
+
end
|
10
|
+
|
11
|
+
describe 'GET /' do
|
12
|
+
it 'returns hello world' do
|
13
|
+
response = rt.get '/'
|
14
|
+
expect(response.body).to eq('Hello World Custom!')
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
describe 'ErrorsExample' do
|
2
|
+
let(:app) do
|
3
|
+
path = File.expand_path("../../examples/errors.ru", File.dirname(__FILE__))
|
4
|
+
Rack::Builder.parse_file(path).first
|
5
|
+
end
|
6
|
+
|
7
|
+
let(:rt) do
|
8
|
+
Rack::Test::Session.new(app)
|
9
|
+
end
|
10
|
+
|
11
|
+
describe 'GET /' do
|
12
|
+
it 'returns an error' do
|
13
|
+
response = rt.get '/'
|
14
|
+
expect(response.body).to eq('Bad Data')
|
15
|
+
expect(response.status).to eq(500)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
describe "ExampleApp" do
|
2
|
+
it 'does not pollute the base class with routes' do
|
3
|
+
expect(Eldr::App.routes[:get].length).to eq(0)
|
4
|
+
end
|
5
|
+
|
6
|
+
let(:app) do
|
7
|
+
path = File.expand_path("../../examples/app.ru", File.dirname(__FILE__))
|
8
|
+
Rack::Builder.parse_file(path).first
|
9
|
+
end
|
10
|
+
|
11
|
+
let(:rt) do
|
12
|
+
Rack::Test::Session.new(app)
|
13
|
+
end
|
14
|
+
|
15
|
+
describe 'GET /posts' do
|
16
|
+
it 'returns a 200 status' do
|
17
|
+
response = rt.get '/posts'
|
18
|
+
expect(response.status).to eq(200)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe 'POST /posts' do
|
23
|
+
it 'returns a 201 status' do
|
24
|
+
response = rt.post '/posts'
|
25
|
+
expect(response.status).to eq(201)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe 'PUT /posts' do
|
30
|
+
it 'returns a 200 status' do
|
31
|
+
response = rt.put '/posts'
|
32
|
+
expect(response.status).to eq(200)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe 'DELETE /posts' do
|
37
|
+
it 'returns a 201 status' do
|
38
|
+
response = rt.delete '/posts'
|
39
|
+
expect(response.status).to eq(201)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
describe 'GET /state' do
|
44
|
+
it 'does not maintain state between requests' do
|
45
|
+
response = rt.get '/state'
|
46
|
+
expect(response.body).to eq('1')
|
47
|
+
|
48
|
+
response = rt.get '/state'
|
49
|
+
expect(response.body).to eq('1')
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
describe 'before and after filters GET /' do
|
54
|
+
it 'comes out in the correct order' do
|
55
|
+
order = []
|
56
|
+
|
57
|
+
cats = Class.new(Eldr::App)
|
58
|
+
cats.after { order << :after }
|
59
|
+
cats.before { order << :before }
|
60
|
+
|
61
|
+
cats.get'/' do
|
62
|
+
order << :action
|
63
|
+
Rack::Response.new("Cats!", 200)
|
64
|
+
end
|
65
|
+
|
66
|
+
app_a = cats.new
|
67
|
+
|
68
|
+
app_b = Rack::Builder.new do
|
69
|
+
run app_a
|
70
|
+
end
|
71
|
+
|
72
|
+
rt2 = Rack::Test::Session.new(app_b)
|
73
|
+
rt2.get '/'
|
74
|
+
expect(order).to eq([:before, :action, :after])
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
describe 'GET /raises-an-error' do
|
79
|
+
it 'returns a 404 status' do
|
80
|
+
response = rt.get '/raises-an-error'
|
81
|
+
expect(response.status).to eq(404)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
describe 'GET /defer' do
|
86
|
+
it 'defers a route' do
|
87
|
+
response = rt.get '/deferred'
|
88
|
+
expect(response.body).to eq('Deferred!')
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
describe 'GET /posts/:id' do
|
93
|
+
it 'returns a posts id' do
|
94
|
+
response = rt.get '/posts/bob'
|
95
|
+
expect(response.body).to eq('bob')
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
describe 'HelloWorldExample' do
|
2
|
+
let(:app) do
|
3
|
+
path = File.expand_path("../../examples/hello_world.ru", File.dirname(__FILE__))
|
4
|
+
Rack::Builder.parse_file(path).first
|
5
|
+
end
|
6
|
+
|
7
|
+
let(:rt) do
|
8
|
+
Rack::Test::Session.new(app)
|
9
|
+
end
|
10
|
+
|
11
|
+
describe 'GET /' do
|
12
|
+
it 'returns hello world' do
|
13
|
+
response = rt.get '/'
|
14
|
+
expect(response.body).to eq('Hello World!')
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
describe 'InheritedApp' do
|
2
|
+
let(:app) do
|
3
|
+
path = File.expand_path("../../examples/inheritance.ru", File.dirname(__FILE__))
|
4
|
+
Rack::Builder.parse_file(path).first
|
5
|
+
end
|
6
|
+
|
7
|
+
let(:rt) do
|
8
|
+
Rack::Test::Session.new(app)
|
9
|
+
end
|
10
|
+
|
11
|
+
describe 'GET /' do
|
12
|
+
it 'counts using counter middleware' do
|
13
|
+
response = rt.get '/'
|
14
|
+
expect(response.body).to eq('1')
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe '.configuration#bob' do
|
19
|
+
it 'returns "what about him?"' do
|
20
|
+
expect(app.configuration.bob).to eq('what about him?')
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
describe 'MultipleAppsExample' do
|
2
|
+
let(:app) do
|
3
|
+
path = File.expand_path("../../examples/multiple_apps.ru", File.dirname(__FILE__))
|
4
|
+
Rack::Builder.parse_file(path).first
|
5
|
+
end
|
6
|
+
|
7
|
+
let(:rt) do
|
8
|
+
Rack::Test::Session.new(app)
|
9
|
+
end
|
10
|
+
|
11
|
+
describe 'GET /' do
|
12
|
+
it 'returns hello world' do
|
13
|
+
response = rt.get '/'
|
14
|
+
expect(response.body).to eq('Hello World EXAMPLE!')
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe 'GET /cats' do
|
19
|
+
it 'returns cats' do
|
20
|
+
response = rt.get '/cats'
|
21
|
+
expect(response.body).to eq('Hello Cats!')
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe 'GET /dogs' do
|
26
|
+
it 'returns dogs' do
|
27
|
+
response = rt.get '/dogs'
|
28
|
+
expect(response.body).to eq('Hello Dogs!')
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
describe 'RailsStyleRoutingExample' do
|
2
|
+
let(:app) do
|
3
|
+
path = File.expand_path("../../examples/rails_style_routing.ru", File.dirname(__FILE__))
|
4
|
+
Rack::Builder.parse_file(path).first
|
5
|
+
end
|
6
|
+
|
7
|
+
let(:rt) do
|
8
|
+
Rack::Test::Session.new(app)
|
9
|
+
end
|
10
|
+
|
11
|
+
describe 'GET /cats' do
|
12
|
+
it 'returns a greeting from cats' do
|
13
|
+
response = rt.get '/cats'
|
14
|
+
expect(response.body).to eq('Hello from all the Cats!')
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
describe 'RenderingTemplatesExample' do
|
2
|
+
let(:app) do
|
3
|
+
path = File.expand_path("../../examples/rendering_templates.ru", File.dirname(__FILE__))
|
4
|
+
Rack::Builder.parse_file(path).first
|
5
|
+
end
|
6
|
+
|
7
|
+
let(:rt) do
|
8
|
+
Rack::Test::Session.new(app)
|
9
|
+
end
|
10
|
+
|
11
|
+
describe 'GET /cats' do
|
12
|
+
it "should return a template" do
|
13
|
+
response = rt.get '/cats'
|
14
|
+
file_path = File.expand_path("../../examples/views/cats.slim", File.dirname(__FILE__))
|
15
|
+
expect(response.body).to eq Tilt.new(file_path).render()
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe 'GET /no-template' do
|
20
|
+
it 'returns 404' do
|
21
|
+
response = rt.get '/no-template'
|
22
|
+
expect(response.status).to eq(404)
|
23
|
+
expect(response.body).to eq('Template Not Found')
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
describe Eldr::Matcher do
|
2
|
+
describe '#match' do
|
3
|
+
let(:matcher) { Eldr::Matcher.new('/cats/:id') }
|
4
|
+
|
5
|
+
context 'when pattern matches' do
|
6
|
+
it 'returns MatchData' do
|
7
|
+
expect(matcher.match('/cats/bob')).to be_instance_of MatchData
|
8
|
+
end
|
9
|
+
|
10
|
+
it 'returns the splats' do
|
11
|
+
expect(matcher.match('/cats/bob')[:id]).to eq('bob')
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
context 'when pattern does not match' do
|
16
|
+
it 'returns nil' do
|
17
|
+
expect(matcher.match('/dogs/bob')).to be_nil
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
has_hook: true
|
2
|
+
links_to_badges: true
|
3
|
+
has_simple_example: true
|
4
|
+
are_rack_apps: true
|
5
|
+
installation_instructions: true
|
6
|
+
features_list: true
|
7
|
+
has_quickstart: true
|
8
|
+
quickstart:
|
9
|
+
has_rundown: true
|
10
|
+
templates: true
|
11
|
+
helpers: true
|
12
|
+
rails_style_routing: true
|
13
|
+
rails_style_responses: true
|
14
|
+
rails_style_requests: true
|
15
|
+
extensions: true
|
16
|
+
builder: true
|
17
|
+
redirects: true
|
18
|
+
handlers:
|
19
|
+
call: true
|
20
|
+
any_object: true
|
21
|
+
action_objects: true
|
22
|
+
action_objects_example: true
|
23
|
+
testing: true
|
24
|
+
has_rack_loop: true
|
25
|
+
mentions_examples_folder: true
|
26
|
+
has_help: true
|
27
|
+
has_license: true
|
28
|
+
has_contributing: true
|