syntropy 0.10.1 → 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.10.1
4
+ version: '0.12'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sharon Rosner
@@ -43,28 +43,42 @@ dependencies:
43
43
  requirements:
44
44
  - - '='
45
45
  - !ruby/object:Gem::Version
46
- version: '2.4'
46
+ version: '2.8'
47
47
  type: :runtime
48
48
  prerelease: false
49
49
  version_requirements: !ruby/object:Gem::Requirement
50
50
  requirements:
51
51
  - - '='
52
52
  - !ruby/object:Gem::Version
53
- version: '2.4'
53
+ version: '2.8'
54
+ - !ruby/object:Gem::Dependency
55
+ name: papercraft
56
+ requirement: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - '='
59
+ - !ruby/object:Gem::Version
60
+ version: '1.4'
61
+ type: :runtime
62
+ prerelease: false
63
+ version_requirements: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - '='
66
+ - !ruby/object:Gem::Version
67
+ version: '1.4'
54
68
  - !ruby/object:Gem::Dependency
55
69
  name: qeweney
56
70
  requirement: !ruby/object:Gem::Requirement
57
71
  requirements:
58
72
  - - '='
59
73
  - !ruby/object:Gem::Version
60
- version: '0.21'
74
+ version: '0.22'
61
75
  type: :runtime
62
76
  prerelease: false
63
77
  version_requirements: !ruby/object:Gem::Requirement
64
78
  requirements:
65
79
  - - '='
66
80
  - !ruby/object:Gem::Version
67
- version: '0.21'
81
+ version: '0.22'
68
82
  - !ruby/object:Gem::Dependency
69
83
  name: tp2
70
84
  requirement: !ruby/object:Gem::Requirement
@@ -198,7 +212,7 @@ files:
198
212
  - lib/syntropy/markdown.rb
199
213
  - lib/syntropy/module.rb
200
214
  - lib/syntropy/request_extensions.rb
201
- - lib/syntropy/router.rb
215
+ - lib/syntropy/routing_tree.rb
202
216
  - lib/syntropy/rpc_api.rb
203
217
  - lib/syntropy/side_run.rb
204
218
  - lib/syntropy/version.rb
@@ -218,6 +232,7 @@ files:
218
232
  - test/app/bar.rb
219
233
  - test/app/baz.rb
220
234
  - test/app/index.html
235
+ - test/app/params/[foo].rb
221
236
  - test/app/tmp.rb
222
237
  - test/app_custom/_site.rb
223
238
  - test/app_multi_site/_site.rb
@@ -227,12 +242,13 @@ files:
227
242
  - test/run.rb
228
243
  - test/test_app.rb
229
244
  - test/test_connection_pool.rb
245
+ - test/test_errors.rb
230
246
  - test/test_file_watch.rb
231
247
  - test/test_module.rb
232
- - test/test_router.rb
248
+ - test/test_request_extensions.rb
249
+ - test/test_routing_tree.rb
233
250
  - test/test_rpc_api.rb
234
251
  - test/test_side_run.rb
235
- - test/test_validation.rb
236
252
  homepage: https://github.com/noteflakes/syntropy
237
253
  licenses:
238
254
  - MIT