el 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/.travis.yml +6 -0
- data/Gemfile +5 -0
- data/LICENSE +19 -0
- data/README.md +77 -0
- data/Rakefile +47 -0
- data/docs/Assets.md +157 -0
- data/docs/CRUD.md +255 -0
- data/docs/CacheManager.md +66 -0
- data/docs/ContentHelpers.md +64 -0
- data/docs/TagFactory.md +201 -0
- data/el.gemspec +23 -0
- data/lib/el.rb +11 -0
- data/lib/el/assets.rb +126 -0
- data/lib/el/cache.rb +96 -0
- data/lib/el/constants.rb +21 -0
- data/lib/el/content_helpers.rb +61 -0
- data/lib/el/crud.rb +239 -0
- data/lib/el/ipcm.rb +67 -0
- data/lib/el/tag_factory.rb +180 -0
- data/lib/el/utils.rb +37 -0
- data/test/assets/master.css +1 -0
- data/test/assets/master.js +1 -0
- data/test/assets/master.png +0 -0
- data/test/helpers.rb +14 -0
- data/test/ipcm/config.ru +25 -0
- data/test/ipcm/view/compiler_test.erb +1 -0
- data/test/setup.rb +11 -0
- data/test/sprockets/app.css +5 -0
- data/test/sprockets/app.js +7 -0
- data/test/sprockets/ui.css +3 -0
- data/test/sprockets/ui.js +5 -0
- data/test/test__assets.rb +276 -0
- data/test/test__cache.rb +145 -0
- data/test/test__content_helpers.rb +41 -0
- data/test/test__crud.rb +269 -0
- data/test/test__ipcm.rb +127 -0
- data/test/test__sprockets.rb +101 -0
- data/test/test__tag_factory.rb +170 -0
- metadata +124 -0
data/test/test__cache.rb
ADDED
@@ -0,0 +1,145 @@
|
|
1
|
+
module ELTest__cache
|
2
|
+
|
3
|
+
class App < E
|
4
|
+
|
5
|
+
before do
|
6
|
+
if key = params[:__clear_cache__]
|
7
|
+
key == '*' ? clear_cache! : clear_cache!(key)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def index
|
12
|
+
end
|
13
|
+
|
14
|
+
def heavy_io
|
15
|
+
cache do
|
16
|
+
content
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def heavy_render
|
21
|
+
banners = cache 'banners' do
|
22
|
+
params[:banners] || content
|
23
|
+
end
|
24
|
+
items = cache 'items' do
|
25
|
+
params[:items] || content
|
26
|
+
end
|
27
|
+
[banners, items].join '/'
|
28
|
+
end
|
29
|
+
|
30
|
+
def clear_cache_by_regexp
|
31
|
+
updated = false
|
32
|
+
if key = params[:key]
|
33
|
+
clear_cache! /#{key}/
|
34
|
+
end
|
35
|
+
cache :clear_cache_by_regexp do
|
36
|
+
updated = true
|
37
|
+
end
|
38
|
+
updated
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
def content
|
43
|
+
::Digest::MD5.hexdigest rand(1024**1024).to_s
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
Spec.new App do
|
49
|
+
|
50
|
+
io = get :heavy_io
|
51
|
+
expect(io.status) == 200
|
52
|
+
|
53
|
+
a, b = [], []
|
54
|
+
10.times do
|
55
|
+
get :heavy_io
|
56
|
+
a << io.body
|
57
|
+
b << last_response.body
|
58
|
+
end
|
59
|
+
expect(a) == b
|
60
|
+
|
61
|
+
render = get :heavy_render
|
62
|
+
expect(render.status) == 200
|
63
|
+
|
64
|
+
a, b = [], []
|
65
|
+
10.times do
|
66
|
+
get :heavy_render
|
67
|
+
a << render.body
|
68
|
+
b << last_response.body
|
69
|
+
end
|
70
|
+
expect(a) == b
|
71
|
+
|
72
|
+
Should 'clear ALL cache' do
|
73
|
+
get :__clear_cache__ => '*'
|
74
|
+
|
75
|
+
get :heavy_io
|
76
|
+
refute(last_response.body) == io.body
|
77
|
+
|
78
|
+
get :heavy_render
|
79
|
+
refute(last_response.body) == render.body
|
80
|
+
end
|
81
|
+
|
82
|
+
Should 'clear cache by exact match keys' do
|
83
|
+
|
84
|
+
banners, items = 2.times.map { rand.to_s }
|
85
|
+
Should 'clear and store new cache' do
|
86
|
+
get :__clear_cache__ => '*'
|
87
|
+
|
88
|
+
render = get :heavy_render, :banners => banners, :items => items
|
89
|
+
expect(render.body) == [banners, items].join('/')
|
90
|
+
|
91
|
+
a, b = [], []
|
92
|
+
10.times do
|
93
|
+
get :heavy_render, :banners => rand.to_s, :items => rand.to_s
|
94
|
+
a << render.body
|
95
|
+
b << last_response.body
|
96
|
+
end
|
97
|
+
expect(a) == b
|
98
|
+
end
|
99
|
+
|
100
|
+
new_banners, new_items = 2.times.map { rand.to_s }
|
101
|
+
Context 'updating banners' do
|
102
|
+
get :__clear_cache__ => :banners
|
103
|
+
|
104
|
+
get :heavy_render, :banners => new_banners, :items => rand.to_s
|
105
|
+
expect(last_response.body) == [new_banners, items].join('/')
|
106
|
+
end
|
107
|
+
|
108
|
+
Context 'updating items' do
|
109
|
+
get :__clear_cache__ => :items
|
110
|
+
|
111
|
+
get :heavy_render, :banners => rand.to_s, :items => new_items
|
112
|
+
expect(last_response.body) == [new_banners, new_items].join('/')
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
Should 'clear by given regexp' do
|
117
|
+
|
118
|
+
get :clear_cache_by_regexp
|
119
|
+
expect(last_response.body) == 'true'
|
120
|
+
|
121
|
+
get :clear_cache_by_regexp
|
122
|
+
expect(last_response.body) == 'false'
|
123
|
+
|
124
|
+
%w[
|
125
|
+
clear
|
126
|
+
cache
|
127
|
+
by
|
128
|
+
regexp
|
129
|
+
clear_cache
|
130
|
+
clear_cache_by
|
131
|
+
clear_cache_by_regexp
|
132
|
+
].each do |key|
|
133
|
+
get :clear_cache_by_regexp, :key => key
|
134
|
+
expect(last_response.body) == 'true'
|
135
|
+
end
|
136
|
+
|
137
|
+
%w[foo bar baz].each do |key|
|
138
|
+
get :clear_cache_by_regexp, :key => key
|
139
|
+
expect(last_response.body) == 'false'
|
140
|
+
end
|
141
|
+
|
142
|
+
end
|
143
|
+
|
144
|
+
end
|
145
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module ELTest__content_helpers
|
2
|
+
|
3
|
+
Spec.new self do
|
4
|
+
include EL::TagFactory
|
5
|
+
include EL::ContentHelpers
|
6
|
+
|
7
|
+
Testing :content_for do
|
8
|
+
content_for :assets do
|
9
|
+
js_tag :jquery
|
10
|
+
end
|
11
|
+
|
12
|
+
is(content_for? :assets).kind_of? Proc
|
13
|
+
is(content_for? :blah).nil?
|
14
|
+
|
15
|
+
expected_html = '<script src="jquery.js" type="text/javascript"></script>'
|
16
|
+
does(yield_content :assets).match? expected_html
|
17
|
+
|
18
|
+
content_for :account do |name, email|
|
19
|
+
form_tag! do
|
20
|
+
input_tag(value: name) +
|
21
|
+
input_tag(value: email)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
expected_html = '<form><input value="foo"><input value="foo@bar.com"></form>'
|
26
|
+
does(yield_content :account, :foo, 'foo@bar.com').match? expected_html
|
27
|
+
end
|
28
|
+
|
29
|
+
Testing :capture_html do
|
30
|
+
html = capture_html do
|
31
|
+
js_tag(:jquery) +
|
32
|
+
css_tag(:ui)
|
33
|
+
end
|
34
|
+
|
35
|
+
expected_html = '<script src="jquery.js" type="text/javascript"></script>'
|
36
|
+
expected_html << '<link href="ui.css" media="all" type="text/css" rel="stylesheet">'
|
37
|
+
does(html).match? expected_html
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
end
|
data/test/test__crud.rb
ADDED
@@ -0,0 +1,269 @@
|
|
1
|
+
module ELTest__crud
|
2
|
+
|
3
|
+
class Resource
|
4
|
+
|
5
|
+
attr_reader :objects
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@objects = {}
|
9
|
+
end
|
10
|
+
|
11
|
+
def get id
|
12
|
+
@objects[id.to_i]
|
13
|
+
end
|
14
|
+
|
15
|
+
def create object
|
16
|
+
if obj_id = object.delete('id')
|
17
|
+
object[:id] = obj_id.to_i
|
18
|
+
end
|
19
|
+
id = @objects.size + 1
|
20
|
+
def object.destroy
|
21
|
+
self['__objects__'].delete self['__id__']
|
22
|
+
end
|
23
|
+
@objects[id] = object.update('__objects__' => @objects, '__id__' => id)
|
24
|
+
end
|
25
|
+
|
26
|
+
def [] key
|
27
|
+
@objects[key.to_i]
|
28
|
+
end
|
29
|
+
|
30
|
+
def keys
|
31
|
+
@objects.keys
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
class ResourceWithErrors < Resource
|
36
|
+
def create object
|
37
|
+
id = (@objects.size + 1).to_s
|
38
|
+
@objects[id] = HashWithErrors[object.merge('__id__' => id)]
|
39
|
+
end
|
40
|
+
|
41
|
+
class HashWithErrors < Hash
|
42
|
+
def errors
|
43
|
+
error = 'someErrorOccurred'
|
44
|
+
# alternating returned error type
|
45
|
+
# cause various resources may throw errors of various types
|
46
|
+
rand(1000) % 2 == 0 ?
|
47
|
+
[error] :
|
48
|
+
rand(1000) % 2 == 0 ? {:error => [error]} : error
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
RESOURCE = Resource.new
|
54
|
+
PRIVATE_RESOURCE = Resource.new
|
55
|
+
|
56
|
+
class App < E
|
57
|
+
map '/'
|
58
|
+
|
59
|
+
crudifier = lambda do |obj|
|
60
|
+
case
|
61
|
+
when rq.post?, rq.put?, rq.patch?
|
62
|
+
obj && obj['__id__']
|
63
|
+
when rq.head?
|
64
|
+
response.headers['Last-Modified'] = params[:lm]
|
65
|
+
else
|
66
|
+
obj.inspect
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
crudify RESOURCE, :exclude => ['excluded_param', 'skip_this'], &crudifier
|
71
|
+
crudify PRIVATE_RESOURCE, :private, &crudifier
|
72
|
+
|
73
|
+
setup :post_private, :put_private, :patch_private, :delete_private do
|
74
|
+
auth do |u, p|
|
75
|
+
[u, p] == ['user', 'pass']
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
Spec.new App do
|
81
|
+
|
82
|
+
def update request_method
|
83
|
+
lambda do
|
84
|
+
key = RESOURCE.keys.last
|
85
|
+
record = RESOURCE[key].dup
|
86
|
+
name = rand.to_s
|
87
|
+
|
88
|
+
send request_method, key, :name => name, :excluded_param => 'blah', :skip_this => 'doh'
|
89
|
+
|
90
|
+
updated_record = RESOURCE[last_response.body]
|
91
|
+
expect(updated_record).is_a? Hash
|
92
|
+
refute(updated_record['name']) == record['name']
|
93
|
+
is(updated_record['excluded_param']).nil?
|
94
|
+
is(updated_record['skip_this']).nil?
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
Testing :public_CRUD do
|
99
|
+
map App.base_url
|
100
|
+
|
101
|
+
Test 'create and update' do
|
102
|
+
Should 'create new records' do
|
103
|
+
0.upto(5).each do
|
104
|
+
name = rand.to_s
|
105
|
+
rsp = post :name => name
|
106
|
+
id = rsp.body
|
107
|
+
is(id.to_i) > 0
|
108
|
+
end
|
109
|
+
|
110
|
+
And 'update last record by PUT', &update(:put)
|
111
|
+
And 'update last record by PATCH', &update(:patch)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
Test :get do
|
116
|
+
RESOURCE.keys.each do |key|
|
117
|
+
get key
|
118
|
+
expect(last_response.body) =~ /"name"=>"#{RESOURCE[key]['name']}"/
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
Test :head do
|
123
|
+
RESOURCE.keys.each do |key|
|
124
|
+
last_modified = Time.now.rfc2822.to_s
|
125
|
+
rsp = head key, :lm => last_modified
|
126
|
+
expect(rsp.body) == ''
|
127
|
+
expect(rsp.header['Last-Modified']) == last_modified
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
Test :delete do
|
132
|
+
RESOURCE.keys.each do |key|
|
133
|
+
delete key
|
134
|
+
expect(last_response.status) == 200
|
135
|
+
end
|
136
|
+
expect(RESOURCE.keys.size) == 0
|
137
|
+
end
|
138
|
+
|
139
|
+
Test :options do
|
140
|
+
rsp = options
|
141
|
+
expect(rsp.body) == 'GET, POST, PUT, HEAD, DELETE, OPTIONS, PATCH, TRACE'
|
142
|
+
end
|
143
|
+
|
144
|
+
end
|
145
|
+
|
146
|
+
Testing :private_CRUD do
|
147
|
+
|
148
|
+
map App.route :private
|
149
|
+
|
150
|
+
Test :options do
|
151
|
+
rsp = options
|
152
|
+
expect(rsp.body) == 'GET, HEAD, OPTIONS, TRACE'
|
153
|
+
|
154
|
+
authorize 'user', 'pass'
|
155
|
+
rsp = options
|
156
|
+
expect(rsp.body) == 'GET, POST, PUT, HEAD, DELETE, OPTIONS, PATCH, TRACE'
|
157
|
+
end
|
158
|
+
|
159
|
+
reset_app!
|
160
|
+
|
161
|
+
Should 'require authorization on C/U/D' do
|
162
|
+
|
163
|
+
rsp = post
|
164
|
+
expect(rsp.status) == 401
|
165
|
+
|
166
|
+
rsp = put rand
|
167
|
+
expect(rsp.status) == 401
|
168
|
+
|
169
|
+
rsp = patch rand
|
170
|
+
expect(rsp.status) == 401
|
171
|
+
|
172
|
+
rsp = delete rand
|
173
|
+
expect(rsp.status) == 401
|
174
|
+
|
175
|
+
end
|
176
|
+
|
177
|
+
Should 'grant access and create items' do
|
178
|
+
|
179
|
+
authorize 'user', 'pass'
|
180
|
+
|
181
|
+
Should 'create an item' do
|
182
|
+
name = rand.to_s
|
183
|
+
rsp = post :name => name
|
184
|
+
id = rsp.body
|
185
|
+
is(id.to_i) > 0
|
186
|
+
|
187
|
+
Then 'update created item' do
|
188
|
+
new_name = rand.to_s
|
189
|
+
patch id, :name => new_name
|
190
|
+
|
191
|
+
get id
|
192
|
+
refute(last_response.body) =~ /"name"=>"#{name}"/
|
193
|
+
expect(last_response.body) =~ /"name"=>"#{new_name}"/
|
194
|
+
|
195
|
+
And 'finally delete it' do
|
196
|
+
delete id
|
197
|
+
expect(last_response.status) == 200
|
198
|
+
is(PRIVATE_RESOURCE.keys).empty?
|
199
|
+
end
|
200
|
+
|
201
|
+
end
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
class DefaultPrimaryKey < E
|
209
|
+
map :/
|
210
|
+
|
211
|
+
crudify Resource.new
|
212
|
+
end
|
213
|
+
|
214
|
+
class CustomPrimaryKey < E
|
215
|
+
map :/
|
216
|
+
|
217
|
+
crudify Resource.new, :pkey => 'obj_id'
|
218
|
+
end
|
219
|
+
|
220
|
+
class BuiltinErrorHandler < E
|
221
|
+
map :/
|
222
|
+
|
223
|
+
crudify ResourceWithErrors.new
|
224
|
+
end
|
225
|
+
|
226
|
+
class BuiltinErrorHandlerWithCustomStatusCode < E
|
227
|
+
map :/
|
228
|
+
|
229
|
+
crudify ResourceWithErrors.new, :halt_with => 501
|
230
|
+
end
|
231
|
+
|
232
|
+
Spec.new self do
|
233
|
+
|
234
|
+
Testing DefaultPrimaryKey do
|
235
|
+
app DefaultPrimaryKey.mount
|
236
|
+
|
237
|
+
obj_id = rand(1000).to_s
|
238
|
+
post :id => obj_id
|
239
|
+
expect(last_response.status) == 200
|
240
|
+
check(last_response.body) == obj_id
|
241
|
+
end
|
242
|
+
|
243
|
+
Testing CustomPrimaryKey do
|
244
|
+
app CustomPrimaryKey.mount
|
245
|
+
|
246
|
+
obj_id = rand(1000).to_s
|
247
|
+
post :obj_id => obj_id
|
248
|
+
expect(last_response.status) == 200
|
249
|
+
check(last_response.body) == obj_id
|
250
|
+
end
|
251
|
+
|
252
|
+
Testing BuiltinErrorHandler do
|
253
|
+
app BuiltinErrorHandler.mount
|
254
|
+
|
255
|
+
post :foo => :bar
|
256
|
+
is(last_response.status) == 500
|
257
|
+
does(last_response.body) =~ /someErrorOccurred/
|
258
|
+
end
|
259
|
+
|
260
|
+
Testing BuiltinErrorHandlerWithCustomStatusCode do
|
261
|
+
app BuiltinErrorHandlerWithCustomStatusCode.mount
|
262
|
+
|
263
|
+
post :foo => :bar
|
264
|
+
is(last_response.status) == 501
|
265
|
+
expect(last_response.body) =~ /someErrorOccurred/
|
266
|
+
end
|
267
|
+
end
|
268
|
+
|
269
|
+
end
|