syntropy 0.11 → 0.12

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.
@@ -0,0 +1,427 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'helper'
4
+ require 'syntropy/routing_tree'
5
+
6
+ class RoutingTreeTest < Minitest::Test
7
+ FILE_TREE = {
8
+ 'site': {
9
+
10
+ '[org]': {
11
+ 'index.rb': '',
12
+ '[repo]': {
13
+ '_error.rb': '',
14
+ 'index.rb': '',
15
+ 'commits': {
16
+ 'index.rb': ''
17
+ },
18
+ 'issues': {
19
+ '_hook.rb': '',
20
+ '[id]': {
21
+ 'index.rb': ''
22
+ },
23
+ 'index.rb': ''
24
+ },
25
+ '_layout.rb': ''
26
+ }
27
+ },
28
+ '_error.rb': '',
29
+ '_hook.rb': '',
30
+ 'about.md': '',
31
+ 'index.rb': '',
32
+ 'api+.rb': '',
33
+ 'assets': {
34
+ 'img': {
35
+ 'foo.jpg': ''
36
+ },
37
+ 'css': {
38
+ 'style.css': ''
39
+ }
40
+ },
41
+ 'posts': {
42
+ '[id].rb': '',
43
+ 'index.rb': ''
44
+ },
45
+
46
+ 'old': {
47
+ 'index.html': '',
48
+ 'baz.html': ''
49
+ }
50
+ }
51
+ }
52
+
53
+ def setup
54
+ @root_dir = "/tmp/#{__FILE__.gsub('/', '-')}-#{SecureRandom.hex}"
55
+ make_tmp_file_tree(@root_dir, FILE_TREE)
56
+ @rt = Syntropy::RoutingTree.new(root_dir: File.join(@root_dir, 'site'), mount_path: '/docs')
57
+ end
58
+
59
+ def test_compute_clean_url_path
60
+ c = ->(fn) { @rt.send(:compute_clean_url_path, fn) }
61
+ assert_equal '/', c.(File.join(@rt.root_dir, '/index.rb'))
62
+ assert_equal '/about', c.(File.join(@rt.root_dir, '/about.md'))
63
+ assert_equal '/[org]', c.(File.join(@rt.root_dir, '/[org]'))
64
+ assert_equal '/favicon.ico', c.(File.join(@rt.root_dir, '/favicon.ico'))
65
+ assert_equal '/assets/style.css', c.(File.join(@rt.root_dir, '/assets/style.css'))
66
+ assert_equal '/foo.js', c.(File.join(@rt.root_dir, '/foo.js'))
67
+ end
68
+
69
+ def test_routing_tree_generation
70
+ root = @rt.root
71
+ assert_equal '/docs', root[:path]
72
+ assert_nil root[:parent]
73
+ assert_nil root[:param]
74
+ assert_nil root[:target]
75
+ assert_equal ['[]', 'about', 'api', 'assets', 'old', 'posts'], root[:children].keys.sort_by(&:to_s)
76
+
77
+ entry = @rt.static_map['/docs']
78
+ assert_equal File.join(@rt.root_dir, 'index.rb'), entry[:target][:fn]
79
+
80
+ about = root[:children]['about']
81
+ assert_equal '/docs/about', about[:path]
82
+ assert_equal root, about[:parent]
83
+ assert_equal File.join(@rt.root_dir, 'about.md'), about[:target][:fn]
84
+ assert_nil about[:children]
85
+
86
+ org = root[:children]['[]']
87
+ assert_equal '/docs/[org]', org[:path]
88
+ assert_equal 'org', org[:param]
89
+ refute_nil org[:target]
90
+ assert_equal File.join(@rt.root_dir, '[org]/index.rb'), org[:target][:fn]
91
+ assert_equal ['[]'], org[:children].keys.sort_by(&:to_s)
92
+
93
+ repo = org[:children]['[]']
94
+ assert_equal org, repo[:parent]
95
+ assert_equal '/docs/[org]/[repo]', repo[:path]
96
+ assert_equal 'repo', repo[:param]
97
+ assert_equal File.join(@rt.root_dir, '[org]/[repo]/index.rb'), repo[:target][:fn]
98
+ assert_equal ['commits', 'issues'], repo[:children].keys.sort_by(&:to_s)
99
+
100
+ issues = repo[:children]['issues']
101
+ assert_equal repo, issues[:parent]
102
+ assert_equal '/docs/[org]/[repo]/issues', issues[:path]
103
+ assert_nil issues[:param]
104
+ assert_equal File.join(@rt.root_dir, '[org]/[repo]/issues/index.rb'), issues[:target][:fn]
105
+ assert_equal ['[]'], issues[:children].keys.sort_by(&:to_s)
106
+
107
+ id = issues[:children]['[]']
108
+ assert_equal issues, id[:parent]
109
+ assert_equal '/docs/[org]/[repo]/issues/[id]', id[:path]
110
+ assert_equal 'id', id[:param]
111
+ assert_equal File.join(@rt.root_dir, '[org]/[repo]/issues/[id]/index.rb'), id[:target][:fn]
112
+ assert_equal [], id[:children].keys.sort_by(&:to_s)
113
+
114
+ posts = root[:children]['posts']
115
+ assert_equal root, posts[:parent]
116
+ assert_equal '/docs/posts', posts[:path]
117
+ assert_nil posts[:target]
118
+ assert_equal ['[]'], posts[:children].keys.sort_by(&:to_s)
119
+
120
+ id = posts[:children]['[]']
121
+ assert_equal posts, id[:parent]
122
+ assert_equal '/docs/posts/[id]', id[:path]
123
+ assert_equal 'id', id[:param]
124
+ assert_equal File.join(@rt.root_dir, 'posts/[id].rb'), id[:target][:fn]
125
+ assert_nil id[:children]
126
+
127
+ old = root[:children]['old']
128
+ refute_nil old
129
+ assert_nil old[:target]
130
+
131
+ # static files are not added to the routing tree, so the assets entry has no children
132
+ assets = root[:children]['assets']
133
+ refute_nil assets
134
+ assert_nil assets[:target]
135
+ end
136
+
137
+ def test_static_map
138
+ map = @rt.static_map
139
+ assert_equal 7, map.size
140
+
141
+ keys = map.keys.sort
142
+ assert_equal [
143
+ '/docs', '/docs/about', '/docs/assets/css/style.css',
144
+ '/docs/assets/img/foo.jpg', '/docs/old', '/docs/old/baz', '/docs/posts'
145
+ ], keys
146
+
147
+ o = map['/docs/assets/css/style.css']
148
+ assert_equal File.join(@rt.root_dir, 'assets/css/style.css'), o[:target][:fn]
149
+
150
+ o = map['/docs/assets/img/foo.jpg']
151
+ assert_equal File.join(@rt.root_dir, 'assets/img/foo.jpg'), o[:target][:fn]
152
+
153
+ o = map['/docs/old/baz']
154
+ assert_equal File.join(@rt.root_dir, 'old/baz.html'), o[:target][:fn]
155
+
156
+ o = map['/docs/posts']
157
+ assert_equal File.join(@rt.root_dir, 'posts/index.rb'), o[:target][:fn]
158
+ refute_nil o[:parent]
159
+ assert_equal '/docs', o[:parent][:path]
160
+
161
+ o = map['/docs/old/baz']
162
+ assert_equal File.join(@rt.root_dir, 'old/baz.html'), o[:target][:fn]
163
+
164
+ o = map['/docs/old']
165
+ assert_equal File.join(@rt.root_dir, 'old/index.html'), o[:target][:fn]
166
+ refute_nil o[:parent]
167
+ assert_equal '/docs', o[:parent][:path]
168
+
169
+ o = map['/docs']
170
+ assert_equal File.join(@rt.root_dir, 'index.rb'), o[:target][:fn]
171
+
172
+ o = map['/docs/about']
173
+ assert_equal File.join(@rt.root_dir, 'about.md'), o[:target][:fn]
174
+ end
175
+
176
+ def test_dynamic_map
177
+ map = @rt.dynamic_map
178
+ assert_equal 7, map.size
179
+
180
+ keys = map.keys.sort
181
+ assert_equal [
182
+ '/docs/[org]', '/docs/[org]/[repo]', '/docs/[org]/[repo]/commits',
183
+ '/docs/[org]/[repo]/issues', '/docs/[org]/[repo]/issues/[id]',
184
+ '/docs/api+', '/docs/posts/[id]'
185
+ ], keys
186
+
187
+ # all entries in dynamic map should have targets
188
+ assert_equal [], map.values.select { !it[:target] }
189
+
190
+ # all entries should a path equal to the key
191
+ assert_equal ({}), map.select { |k, v| k != v[:path] }
192
+
193
+ assert_equal [
194
+ '[org]/index.rb',
195
+ '[org]/[repo]/index.rb',
196
+ '[org]/[repo]/commits/index.rb',
197
+ '[org]/[repo]/issues/index.rb',
198
+ '[org]/[repo]/issues/[id]/index.rb',
199
+ 'api+.rb',
200
+ 'posts/[id].rb'
201
+ ].map { File.join(@rt.root_dir, it) }, keys.map { map[it][:target][:fn] }
202
+ end
203
+
204
+ def test_router_proc
205
+ router = @rt.router_proc
206
+
207
+ params = {}
208
+ route = router.('/docs/df/p2/issues/14', params)
209
+ assert_equal ({ 'org' => 'df', 'repo' => 'p2', 'id' => '14'}), params
210
+ refute_nil route
211
+ assert_equal '/docs/[org]/[repo]/issues/[id]', route[:path]
212
+
213
+ route = router.('/foo', {})
214
+ assert_nil route
215
+
216
+ route = router.('/abc/../def', {})
217
+ assert_nil route
218
+
219
+ route = router.('/assets', {})
220
+ assert_nil route
221
+
222
+ route = router.('/docs/assets', {})
223
+ assert_nil route
224
+
225
+ route = router.('/docs/assets/foo', {})
226
+ assert_nil route
227
+
228
+ route = router.('/docs/assets/img', {})
229
+ assert_nil route
230
+
231
+ route = router.('/docs/assets/foo/bar.jpg', {})
232
+ assert_nil route
233
+
234
+ route = router.('/docs/assets/img/foo.jpg', {})
235
+ assert_equal File.join(@rt.root_dir, 'assets/img/foo.jpg'), route[:target][:fn]
236
+
237
+ route = router.('/docs/assets/img/bar.jpg', {})
238
+ assert_nil route
239
+
240
+ route = router.('/docs/about', {})
241
+ assert_equal File.join(@rt.root_dir, 'about.md'), route[:target][:fn]
242
+
243
+ route = router.('/docs/foo', params = {})
244
+ assert_equal File.join(@rt.root_dir, '[org]/index.rb'), route[:target][:fn]
245
+ assert_equal 'foo', params['org']
246
+
247
+ route = router.('/docs/foo/bar', params = {})
248
+ assert_equal File.join(@rt.root_dir, '[org]/[repo]/index.rb'), route[:target][:fn]
249
+ assert_equal 'foo', params['org']
250
+ assert_equal 'bar', params['repo']
251
+
252
+ route = router.('/docs/bar/baz/commits', params = {})
253
+ assert_equal File.join(@rt.root_dir, '[org]/[repo]/commits/index.rb'), route[:target][:fn]
254
+ assert_equal 'bar', params['org']
255
+ assert_equal 'baz', params['repo']
256
+
257
+ route = router.('/docs/foo/bar/issues', params = {})
258
+ assert_equal File.join(@rt.root_dir, '[org]/[repo]/issues/index.rb'), route[:target][:fn]
259
+ assert_equal 'foo', params['org']
260
+ assert_equal 'bar', params['repo']
261
+
262
+ route = router.('/docs/bar/baz/issues/14', params = {})
263
+ assert_equal File.join(@rt.root_dir, '[org]/[repo]/issues/[id]/index.rb'), route[:target][:fn]
264
+ assert_equal 'bar', params['org']
265
+ assert_equal 'baz', params['repo']
266
+ assert_equal '14', params['id']
267
+
268
+ route = router.('/docs/foo/bar/issues/14/blah', {})
269
+ assert_nil route
270
+
271
+ route = router.('/docs/foo/bar/baz', {})
272
+ assert_nil route
273
+
274
+ route = router.('/docs/api', {})
275
+ assert_equal File.join(@rt.root_dir, 'api+.rb'), route[:target][:fn]
276
+
277
+ route = router.('/docs/api/foo/bar', {})
278
+ assert_equal File.join(@rt.root_dir, 'api+.rb'), route[:target][:fn]
279
+
280
+ route = router.('/docs/api/foo/bar', {})
281
+ assert_equal File.join(@rt.root_dir, 'api+.rb'), route[:target][:fn]
282
+
283
+ route = router.('/docs/posts', {})
284
+ assert_equal File.join(@rt.root_dir, 'posts/index.rb'), route[:target][:fn]
285
+
286
+ route = router.('/docs/posts/foo', params = {})
287
+ assert_equal File.join(@rt.root_dir, 'posts/[id].rb'), route[:target][:fn]
288
+ assert_equal 'foo', params['id']
289
+ end
290
+
291
+ def test_route_error_handler
292
+ e = @rt.dynamic_map['/docs/[org]']
293
+ target = @rt.route_error_handler(e)
294
+ assert_kind_of Hash, target
295
+ assert_equal :module, target[:kind]
296
+ assert_equal File.join(@rt.root_dir, '_error.rb'), target[:fn]
297
+
298
+ e = @rt.dynamic_map['/docs/api+']
299
+ target = @rt.route_error_handler(e)
300
+ assert_equal :module, target[:kind]
301
+ assert_equal File.join(@rt.root_dir, '_error.rb'), target[:fn]
302
+
303
+ e = @rt.dynamic_map['/docs/[org]/[repo]']
304
+ target = @rt.route_error_handler(e)
305
+ assert_equal :module, target[:kind]
306
+ assert_equal File.join(@rt.root_dir, '[org]/[repo]/_error.rb'), target[:fn]
307
+ end
308
+
309
+ def test_route_hooks
310
+ e = @rt.dynamic_map['/docs/[org]']
311
+ hooks = @rt.route_hooks(e)
312
+ assert_equal [
313
+ { kind: :module, fn: File.join(@rt.root_dir, '_hook.rb') }
314
+ ], hooks
315
+
316
+ e = @rt.dynamic_map['/docs/api+']
317
+ hooks = @rt.route_hooks(e)
318
+ assert_equal [
319
+ { kind: :module, fn: File.join(@rt.root_dir, '_hook.rb') }
320
+ ], hooks
321
+
322
+ e = @rt.dynamic_map['/docs/[org]/[repo]']
323
+ hooks = @rt.route_hooks(e)
324
+ assert_equal [
325
+ { kind: :module, fn: File.join(@rt.root_dir, '_hook.rb') }
326
+ ], hooks
327
+
328
+ e = @rt.dynamic_map['/docs/[org]/[repo]/issues']
329
+ hooks = @rt.route_hooks(e)
330
+ assert_equal [
331
+ { kind: :module, fn: File.join(@rt.root_dir, '_hook.rb') },
332
+ { kind: :module, fn: File.join(@rt.root_dir, '[org]/[repo]/issues/_hook.rb') }
333
+ ], hooks
334
+
335
+ e = @rt.dynamic_map['/docs/[org]/[repo]/issues/[id]']
336
+ hooks = @rt.route_hooks(e)
337
+ assert_equal [
338
+ { kind: :module, fn: File.join(@rt.root_dir, '_hook.rb') },
339
+ { kind: :module, fn: File.join(@rt.root_dir, '[org]/[repo]/issues/_hook.rb') }
340
+ ], hooks
341
+ end
342
+
343
+ def test_routing_root_mounted
344
+ rt = Syntropy::RoutingTree.new(root_dir: File.join(@root_dir, 'site'), mount_path: '/')
345
+ router = rt.router_proc
346
+
347
+ # pp rt.root
348
+ # puts
349
+
350
+ route = router.('/docs/df/p2/issues/14', {})
351
+ assert_nil route
352
+
353
+ params = {}
354
+ route = router.('/df/p2/issues/14', params)
355
+ refute_nil route
356
+ assert_equal ({ 'org' => 'df', 'repo' => 'p2', 'id' => '14'}), params
357
+ assert_equal '/[org]/[repo]/issues/[id]', route[:path]
358
+
359
+ route = router.('/assets', {})
360
+ assert_nil route
361
+
362
+ route = router.('/assets/foo', {})
363
+ assert_nil route
364
+
365
+ route = router.('/assets/img', {})
366
+ assert_nil route
367
+
368
+ route = router.('/assets/foo/bar.jpg', {})
369
+ assert_nil route
370
+
371
+ route = router.('/assets/img/foo.jpg', {})
372
+ assert_equal File.join(@rt.root_dir, 'assets/img/foo.jpg'), route[:target][:fn]
373
+
374
+ route = router.('/assets/img/bar.jpg', {})
375
+ assert_nil route
376
+
377
+ route = router.('/about', {})
378
+ assert_equal File.join(@rt.root_dir, 'about.md'), route[:target][:fn]
379
+
380
+ route = router.('/foo', params = {})
381
+ assert_equal File.join(@rt.root_dir, '[org]/index.rb'), route[:target][:fn]
382
+ assert_equal 'foo', params['org']
383
+
384
+ route = router.('/foo/bar', params = {})
385
+ assert_equal File.join(@rt.root_dir, '[org]/[repo]/index.rb'), route[:target][:fn]
386
+ assert_equal 'foo', params['org']
387
+ assert_equal 'bar', params['repo']
388
+
389
+ route = router.('/bar/baz/commits', params = {})
390
+ assert_equal File.join(@rt.root_dir, '[org]/[repo]/commits/index.rb'), route[:target][:fn]
391
+ assert_equal 'bar', params['org']
392
+ assert_equal 'baz', params['repo']
393
+
394
+ route = router.('/foo/bar/issues', params = {})
395
+ assert_equal File.join(@rt.root_dir, '[org]/[repo]/issues/index.rb'), route[:target][:fn]
396
+ assert_equal 'foo', params['org']
397
+ assert_equal 'bar', params['repo']
398
+
399
+ route = router.('/bar/baz/issues/14', params = {})
400
+ assert_equal File.join(@rt.root_dir, '[org]/[repo]/issues/[id]/index.rb'), route[:target][:fn]
401
+ assert_equal 'bar', params['org']
402
+ assert_equal 'baz', params['repo']
403
+ assert_equal '14', params['id']
404
+
405
+ route = router.('/foo/bar/issues/14/blah', {})
406
+ assert_nil route
407
+
408
+ route = router.('/foo/bar/baz', {})
409
+ assert_nil route
410
+
411
+ route = router.('/api', {})
412
+ assert_equal File.join(@rt.root_dir, 'api+.rb'), route[:target][:fn]
413
+
414
+ route = router.('/api/foo/bar', {})
415
+ assert_equal File.join(@rt.root_dir, 'api+.rb'), route[:target][:fn]
416
+
417
+ route = router.('/api/foo/bar', {})
418
+ assert_equal File.join(@rt.root_dir, 'api+.rb'), route[:target][:fn]
419
+
420
+ route = router.('/posts', {})
421
+ assert_equal File.join(@rt.root_dir, 'posts/index.rb'), route[:target][:fn]
422
+
423
+ route = router.('/posts/foo', params = {})
424
+ assert_equal File.join(@rt.root_dir, 'posts/[id].rb'), route[:target][:fn]
425
+ assert_equal 'foo', params['id']
426
+ end
427
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: syntropy
3
3
  version: !ruby/object:Gem::Version
4
- version: '0.11'
4
+ version: '0.12'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sharon Rosner
@@ -71,14 +71,14 @@ dependencies:
71
71
  requirements:
72
72
  - - '='
73
73
  - !ruby/object:Gem::Version
74
- version: '0.21'
74
+ version: '0.22'
75
75
  type: :runtime
76
76
  prerelease: false
77
77
  version_requirements: !ruby/object:Gem::Requirement
78
78
  requirements:
79
79
  - - '='
80
80
  - !ruby/object:Gem::Version
81
- version: '0.21'
81
+ version: '0.22'
82
82
  - !ruby/object:Gem::Dependency
83
83
  name: tp2
84
84
  requirement: !ruby/object:Gem::Requirement
@@ -212,7 +212,7 @@ files:
212
212
  - lib/syntropy/markdown.rb
213
213
  - lib/syntropy/module.rb
214
214
  - lib/syntropy/request_extensions.rb
215
- - lib/syntropy/router.rb
215
+ - lib/syntropy/routing_tree.rb
216
216
  - lib/syntropy/rpc_api.rb
217
217
  - lib/syntropy/side_run.rb
218
218
  - lib/syntropy/version.rb
@@ -232,6 +232,7 @@ files:
232
232
  - test/app/bar.rb
233
233
  - test/app/baz.rb
234
234
  - test/app/index.html
235
+ - test/app/params/[foo].rb
235
236
  - test/app/tmp.rb
236
237
  - test/app_custom/_site.rb
237
238
  - test/app_multi_site/_site.rb
@@ -241,12 +242,13 @@ files:
241
242
  - test/run.rb
242
243
  - test/test_app.rb
243
244
  - test/test_connection_pool.rb
245
+ - test/test_errors.rb
244
246
  - test/test_file_watch.rb
245
247
  - test/test_module.rb
246
- - test/test_router.rb
248
+ - test/test_request_extensions.rb
249
+ - test/test_routing_tree.rb
247
250
  - test/test_rpc_api.rb
248
251
  - test/test_side_run.rb
249
- - test/test_validation.rb
250
252
  homepage: https://github.com/noteflakes/syntropy
251
253
  licenses:
252
254
  - MIT