el 0.5.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.
- 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
|