utopia 1.7.1 → 1.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +2 -3
  3. data/README.md +142 -11
  4. data/benchmarks/string_vs_symbol.rb +12 -0
  5. data/lib/utopia/command.rb +16 -13
  6. data/lib/utopia/content.rb +1 -5
  7. data/lib/utopia/content/node.rb +9 -4
  8. data/lib/utopia/{extensions/rack.rb → content/response.rb} +33 -30
  9. data/lib/utopia/content/tag.rb +14 -17
  10. data/lib/utopia/content/transaction.rb +19 -17
  11. data/lib/utopia/controller.rb +29 -8
  12. data/lib/utopia/controller/actions.rb +148 -0
  13. data/lib/utopia/controller/base.rb +9 -49
  14. data/lib/utopia/controller/respond.rb +1 -1
  15. data/lib/utopia/controller/rewrite.rb +9 -1
  16. data/lib/utopia/controller/variables.rb +1 -0
  17. data/lib/utopia/localization.rb +4 -1
  18. data/lib/utopia/middleware.rb +0 -2
  19. data/lib/utopia/path.rb +9 -0
  20. data/lib/utopia/path/matcher.rb +0 -1
  21. data/lib/utopia/redirection.rb +3 -2
  22. data/lib/utopia/session.rb +119 -2
  23. data/lib/utopia/session/lazy_hash.rb +1 -3
  24. data/lib/utopia/setup.rb +73 -0
  25. data/lib/utopia/static.rb +9 -2
  26. data/lib/utopia/version.rb +1 -1
  27. data/setup/examples/wiki/controller.rb +41 -0
  28. data/setup/examples/wiki/edit.xnode +15 -0
  29. data/setup/examples/wiki/index.xnode +10 -0
  30. data/setup/examples/wiki/welcome/content.md +3 -0
  31. data/setup/server/config/environment.yaml +1 -0
  32. data/setup/server/git/hooks/post-receive +4 -5
  33. data/setup/site/Gemfile +5 -0
  34. data/setup/site/config.ru +2 -1
  35. data/setup/site/config/environment.rb +5 -17
  36. data/setup/site/pages/_page.xnode +4 -2
  37. data/setup/site/pages/links.yaml +1 -1
  38. data/setup/site/pages/welcome/index.xnode +33 -15
  39. data/setup/site/public/_static/site.css +72 -4
  40. data/setup/site/tasks/utopia.rake +8 -0
  41. data/spec/utopia/{rack_spec.rb → content/response_spec.rb} +12 -19
  42. data/spec/utopia/content_spec.rb +2 -3
  43. data/spec/utopia/controller/{action_spec.rb → actions_spec.rb} +18 -32
  44. data/spec/utopia/controller/middleware_spec.rb +10 -10
  45. data/spec/utopia/controller/middleware_spec/controller/controller.rb +3 -3
  46. data/spec/utopia/controller/middleware_spec/controller/nested/controller.rb +1 -1
  47. data/spec/utopia/controller/middleware_spec/redirect/controller.rb +1 -1
  48. data/spec/utopia/controller/respond_spec.rb +3 -2
  49. data/spec/utopia/controller/respond_spec/api/controller.rb +2 -2
  50. data/spec/utopia/controller/respond_spec/errors/controller.rb +1 -1
  51. data/spec/utopia/controller/rewrite_spec.rb +1 -1
  52. data/spec/utopia/controller/sequence_spec.rb +12 -16
  53. data/spec/utopia/exceptions/handler_spec/controller.rb +2 -2
  54. data/spec/utopia/performance_spec/config.ru +1 -0
  55. data/spec/utopia/session_spec.rb +34 -1
  56. data/spec/utopia/session_spec.ru +3 -3
  57. data/spec/utopia/setup_spec.rb +2 -2
  58. data/utopia.gemspec +2 -2
  59. metadata +18 -12
  60. data/lib/utopia/controller/action.rb +0 -116
  61. data/lib/utopia/session/encrypted_cookie.rb +0 -118
@@ -1,10 +1,10 @@
1
1
 
2
2
  on 'flat' do
3
- success! content: "flat"
3
+ succeed! content: "flat"
4
4
  end
5
5
 
6
6
  on '**/hello-world' do
7
- success! content: @hello_world
7
+ succeed! content: @hello_world
8
8
  end
9
9
 
10
10
  on '**' do
@@ -20,5 +20,5 @@ on 'redirect' do
20
20
  end
21
21
 
22
22
  on 'index' do
23
- success! content: 'Hello World'
23
+ succeed! content: 'Hello World'
24
24
  end
@@ -1,4 +1,4 @@
1
1
 
2
2
  on 'foobar' do
3
- success! content: "Foobar"
3
+ succeed! content: "Foobar"
4
4
  end
@@ -1,6 +1,6 @@
1
1
 
2
2
  on '**' do |request, path|
3
- #puts "**: #{URI_PATH.inspect}"
3
+ # puts "**: #{URI_PATH.inspect}"
4
4
 
5
5
  if path.include? 'foo'
6
6
  # This should ALWAYS give /redirect
@@ -30,7 +30,8 @@ require 'utopia/controller'
30
30
  module Utopia::Controller::RespondSpec
31
31
  describe Utopia::Controller do
32
32
  class TestController < Utopia::Controller::Base
33
- prepend Utopia::Controller::Respond
33
+ # Request goes from right to left.
34
+ prepend Utopia::Controller::Respond, Utopia::Controller::Actions
34
35
 
35
36
  respond.with("application/json") do |content|
36
37
  JSON::dump(content)
@@ -41,7 +42,7 @@ module Utopia::Controller::RespondSpec
41
42
  end
42
43
 
43
44
  on 'fetch' do |request, path|
44
- success! content: {user_id: 10}
45
+ succeed! content: {user_id: 10}
45
46
  end
46
47
 
47
48
  def self.uri_path
@@ -1,5 +1,5 @@
1
1
 
2
- prepend Respond
2
+ prepend Respond, Actions
3
3
  respond.with_json
4
4
 
5
5
  class VersionedResponse
@@ -23,5 +23,5 @@ end
23
23
  # Accept: application/json;version=1
24
24
  # Accept: application/json;version=2
25
25
  on 'fetch' do
26
- success! content: VersionedResponse.new
26
+ succeed! content: VersionedResponse.new
27
27
  end
@@ -1,5 +1,5 @@
1
1
 
2
- prepend Respond
2
+ prepend Respond, Actions
3
3
 
4
4
  # If the request doesn't match application/json specifically, it would be passed through:
5
5
  respond.with_passthrough
@@ -27,7 +27,7 @@ require 'utopia/controller'
27
27
  module Utopia::Controller::RewriteSpec
28
28
  describe Utopia::Controller do
29
29
  class TestController < Utopia::Controller::Base
30
- prepend Utopia::Controller::Rewrite
30
+ prepend Utopia::Controller::Rewrite, Utopia::Controller::Actions
31
31
 
32
32
  on 'edit' do |request, path|
33
33
  @edit = true
@@ -26,8 +26,10 @@ require 'utopia/controller'
26
26
 
27
27
  module Utopia::Controller::SequenceSpec
28
28
  class TestController < Utopia::Controller::Base
29
+ prepend Utopia::Controller::Actions
30
+
29
31
  on 'success' do
30
- success!
32
+ succeed!
31
33
  end
32
34
 
33
35
  on :failure do
@@ -37,13 +39,11 @@ module Utopia::Controller::SequenceSpec
37
39
  on :variable do |request, path|
38
40
  @variable = :value
39
41
  end
40
-
41
- def self.uri_path
42
- Utopia::Path["/"]
43
- end
44
42
  end
45
43
 
46
44
  class TestIndirectController < Utopia::Controller::Base
45
+ prepend Utopia::Controller::Actions
46
+
47
47
  def initialize
48
48
  @sequence = ""
49
49
  end
@@ -71,10 +71,6 @@ module Utopia::Controller::SequenceSpec
71
71
  on('*') do
72
72
  @sequence << 'F'
73
73
  end
74
-
75
- def self.uri_path
76
- Utopia::Path["/"]
77
- end
78
74
  end
79
75
 
80
76
  describe Utopia::Controller do
@@ -85,13 +81,13 @@ module Utopia::Controller::SequenceSpec
85
81
  controller = TestController.new
86
82
  variables << controller
87
83
 
88
- result = controller.process!(request, Utopia::Path["/success"])
84
+ result = controller.process!(request, Utopia::Path["success"])
89
85
  expect(result).to be == [200, {}, []]
90
86
 
91
- result = controller.process!(request, Utopia::Path["/foo/bar/failure"])
87
+ result = controller.process!(request, Utopia::Path["foo/bar/failure"])
92
88
  expect(result).to be == [400, {}, ["Bad Request"]]
93
89
 
94
- result = controller.process!(request, Utopia::Path["/variable"])
90
+ result = controller.process!(request, Utopia::Path["variable"])
95
91
  expect(result).to be == nil
96
92
  expect(variables.to_hash).to be == {:variable => :value}
97
93
  end
@@ -101,7 +97,7 @@ module Utopia::Controller::SequenceSpec
101
97
  controller = TestIndirectController.new
102
98
  variables << controller
103
99
 
104
- controller.process!(request, Utopia::Path["/user/update"])
100
+ controller.process!(request, Utopia::Path["user/update"])
105
101
  expect(variables['sequence']).to be == 'EA'
106
102
  end
107
103
 
@@ -110,7 +106,7 @@ module Utopia::Controller::SequenceSpec
110
106
  controller = TestIndirectController.new
111
107
  variables << controller
112
108
 
113
- result = controller.process!(request, Utopia::Path["/foo/comment/post"])
109
+ result = controller.process!(request, Utopia::Path["foo/comment/post"])
114
110
  expect(result).to be nil
115
111
  expect(variables['sequence']).to be == 'EB'
116
112
  end
@@ -120,7 +116,7 @@ module Utopia::Controller::SequenceSpec
120
116
  controller = TestIndirectController.new
121
117
  variables << controller
122
118
 
123
- result = controller.process!(request, Utopia::Path["/comment/delete"])
119
+ result = controller.process!(request, Utopia::Path["comment/delete"])
124
120
  expect(result).to be nil
125
121
  expect(variables['sequence']).to be == 'EDC'
126
122
  end
@@ -130,7 +126,7 @@ module Utopia::Controller::SequenceSpec
130
126
  controller = TestIndirectController.new
131
127
  variables << controller
132
128
 
133
- result = controller.process!(request, Utopia::Path["/foo"])
129
+ result = controller.process!(request, Utopia::Path["foo"])
134
130
  expect(result).to be nil
135
131
  expect(variables['sequence']).to be == 'EF'
136
132
  end
@@ -8,9 +8,9 @@ end
8
8
 
9
9
  # The ExceptionHandler middleware will redirect here when an exception occurs. If this also fails, things get ugly.
10
10
  on 'exception' do |request|
11
- if request['fatal']
11
+ if request.params['fatal']
12
12
  raise TharSheBlows.new("Yarrh!")
13
13
  else
14
- success! :content => 'Error Will Robertson', :type => 'text/plain'
14
+ succeed! :content => 'Error Will Robertson', :type => 'text/plain'
15
15
  end
16
16
  end
@@ -1,6 +1,7 @@
1
1
  #!/usr/bin/env rackup
2
2
 
3
3
  require 'utopia'
4
+ require 'json'
4
5
 
5
6
  # use Rack::ContentLength
6
7
  use Utopia::ContentLength
@@ -23,7 +23,6 @@ require 'rack'
23
23
  require 'rack/test'
24
24
 
25
25
  require 'utopia/session'
26
- require 'utopia/session/encrypted_cookie'
27
26
 
28
27
  module Utopia::SessionSpec
29
28
  describe Utopia::Session do
@@ -51,6 +50,40 @@ module Utopia::SessionSpec
51
50
  end
52
51
  end
53
52
 
53
+ describe Utopia::Session do
54
+ include Rack::Test::Methods
55
+
56
+ let(:app) {Rack::Builder.parse_file(File.expand_path('../session_spec.ru', __FILE__)).first}
57
+
58
+ before(:each) do
59
+ # Initial user agent:
60
+ header 'User-Agent', 'A'
61
+
62
+ get "/session-set?key=foo&value=bar"
63
+ end
64
+
65
+ it "should be able to retrive the value if there are no changes" do
66
+ get "/session-get?key=foo"
67
+ expect(last_response.body).to be == "bar"
68
+ end
69
+
70
+ it "should fail if user agent is changed" do
71
+ # Change user agent:
72
+ header 'User-Agent', 'B'
73
+
74
+ get "/session-get?key=foo"
75
+ expect(last_response.body).to be == ""
76
+ end
77
+
78
+ it "should fail if ip address is changed" do
79
+ # Change user agent:
80
+ header 'X-Forwarded-For', '127.0.0.10'
81
+
82
+ get "/session-get?key=foo"
83
+ expect(last_response.body).to be == ""
84
+ end
85
+ end
86
+
54
87
  describe Utopia::Session::LazyHash do
55
88
  it "should load hash when required" do
56
89
  loaded = false
@@ -1,5 +1,5 @@
1
1
 
2
- use Utopia::Session::EncryptedCookie, secret: "97111cabf4c1a5e85b8029cf7c61aa44424fc24a"
2
+ use Utopia::Session, secret: "97111cabf4c1a5e85b8029cf7c61aa44424fc24a"
3
3
 
4
4
  run lambda { |env|
5
5
  request = Rack::Request.new(env)
@@ -9,11 +9,11 @@ run lambda { |env|
9
9
 
10
10
  [200, {}, []]
11
11
  elsif env[Rack::PATH_INFO] =~ /session-set/
12
- env['rack.session'][request[:key]] = request[:value]
12
+ env['rack.session'][request.params['key']] = request.params['value']
13
13
 
14
14
  [200, {}, []]
15
15
  elsif env[Rack::PATH_INFO] =~ /session-get/
16
- [200, {}, [env['rack.session'][request[:key]]]]
16
+ [200, {}, [env['rack.session'][request.params['key']]]]
17
17
  else
18
18
  [404, {}, []]
19
19
  end
@@ -22,6 +22,8 @@ require 'fileutils'
22
22
 
23
23
  RSpec.describe "utopia executable" do
24
24
  let(:utopia) {File.expand_path("../../bin/utopia", __dir__)}
25
+ let(:gemspec) {Gem::Specification.load File.expand_path("../../utopia.gemspec", __dir__)}
26
+ let(:package_path) {File.expand_path("../../pkg/#{gemspec.file_name}", __dir__)}
25
27
 
26
28
  before(:all) do
27
29
  # We need to build a package to test deployment:
@@ -42,8 +44,6 @@ RSpec.describe "utopia executable" do
42
44
  end
43
45
 
44
46
  def install_packages(dir)
45
- package_path = File.expand_path("../../pkg/utopia-#{Utopia::VERSION}.gem", __dir__)
46
-
47
47
  # We do a bit of a hack here to ensure the package is available:
48
48
  FileUtils.mkpath File.join(dir, "vendor/cache")
49
49
  FileUtils.cp package_path, File.join(dir, "vendor/cache")
@@ -22,7 +22,7 @@ Gem::Specification.new do |spec|
22
22
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
23
23
  spec.require_paths = ['lib']
24
24
 
25
- spec.required_ruby_version = '~> 2.0'
25
+ spec.required_ruby_version = '~> 2.2'
26
26
 
27
27
  spec.add_dependency 'trenni', '~> 1.6'
28
28
  spec.add_dependency 'mime-types', '~> 3.0'
@@ -31,7 +31,7 @@ Gem::Specification.new do |spec|
31
31
 
32
32
  spec.add_dependency 'rack', '~> 2.0'
33
33
 
34
- spec.add_dependency 'http-accept', '~> 1.4'
34
+ spec.add_dependency 'http-accept', '~> 1.6'
35
35
 
36
36
  spec.add_dependency 'mail', '~> 2.6'
37
37
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: utopia
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.7.1
4
+ version: 1.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Samuel Williams
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-10-03 00:00:00.000000000 Z
11
+ date: 2016-10-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: trenni
@@ -72,14 +72,14 @@ dependencies:
72
72
  requirements:
73
73
  - - "~>"
74
74
  - !ruby/object:Gem::Version
75
- version: '1.4'
75
+ version: '1.6'
76
76
  type: :runtime
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
- version: '1.4'
82
+ version: '1.6'
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: mail
85
85
  requirement: !ruby/object:Gem::Requirement
@@ -183,6 +183,7 @@ files:
183
183
  - README.md
184
184
  - Rakefile
185
185
  - benchmarks/hash_vs_openstruct.rb
186
+ - benchmarks/string_vs_symbol.rb
186
187
  - benchmarks/struct_vs_class.rb
187
188
  - bin/utopia
188
189
  - ext/utopia/xnode/fast_scanner/extconf.rb
@@ -194,11 +195,12 @@ files:
194
195
  - lib/utopia/content/links.rb
195
196
  - lib/utopia/content/markup.rb
196
197
  - lib/utopia/content/node.rb
198
+ - lib/utopia/content/response.rb
197
199
  - lib/utopia/content/tag.rb
198
200
  - lib/utopia/content/transaction.rb
199
201
  - lib/utopia/content_length.rb
200
202
  - lib/utopia/controller.rb
201
- - lib/utopia/controller/action.rb
203
+ - lib/utopia/controller/actions.rb
202
204
  - lib/utopia/controller/base.rb
203
205
  - lib/utopia/controller/respond.rb
204
206
  - lib/utopia/controller/rewrite.rb
@@ -208,7 +210,6 @@ files:
208
210
  - lib/utopia/exceptions/mailer.rb
209
211
  - lib/utopia/extensions/array.rb
210
212
  - lib/utopia/extensions/date.rb
211
- - lib/utopia/extensions/rack.rb
212
213
  - lib/utopia/http.rb
213
214
  - lib/utopia/locale.rb
214
215
  - lib/utopia/localization.rb
@@ -217,8 +218,8 @@ files:
217
218
  - lib/utopia/path/matcher.rb
218
219
  - lib/utopia/redirection.rb
219
220
  - lib/utopia/session.rb
220
- - lib/utopia/session/encrypted_cookie.rb
221
221
  - lib/utopia/session/lazy_hash.rb
222
+ - lib/utopia/setup.rb
222
223
  - lib/utopia/static.rb
223
224
  - lib/utopia/tags/deferred.rb
224
225
  - lib/utopia/tags/environment.rb
@@ -228,6 +229,11 @@ files:
228
229
  - materials/utopia.png
229
230
  - materials/utopia.svg
230
231
  - setup/.bowerrc
232
+ - setup/examples/wiki/controller.rb
233
+ - setup/examples/wiki/edit.xnode
234
+ - setup/examples/wiki/index.xnode
235
+ - setup/examples/wiki/welcome/content.md
236
+ - setup/server/config/environment.yaml
231
237
  - setup/server/git/hooks/post-receive
232
238
  - setup/site/.bowerrc
233
239
  - setup/site/Gemfile
@@ -276,6 +282,7 @@ files:
276
282
  - spec/utopia/content/node/related/foo.ja.xnode
277
283
  - spec/utopia/content/node/related/links.yaml
278
284
  - spec/utopia/content/node_spec.rb
285
+ - spec/utopia/content/response_spec.rb
279
286
  - spec/utopia/content_spec.rb
280
287
  - spec/utopia/content_spec.ru
281
288
  - spec/utopia/content_spec/_heading.xnode
@@ -285,7 +292,7 @@ files:
285
292
  - spec/utopia/content_spec/index.xnode
286
293
  - spec/utopia/content_spec/node/index.xnode
287
294
  - spec/utopia/content_spec/test.xnode
288
- - spec/utopia/controller/action_spec.rb
295
+ - spec/utopia/controller/actions_spec.rb
289
296
  - spec/utopia/controller/middleware_spec.rb
290
297
  - spec/utopia/controller/middleware_spec.ru
291
298
  - spec/utopia/controller/middleware_spec/controller/controller.rb
@@ -333,7 +340,6 @@ files:
333
340
  - spec/utopia/performance_spec/pages/links.yaml
334
341
  - spec/utopia/performance_spec/pages/welcome/index.xnode
335
342
  - spec/utopia/rack_helper.rb
336
- - spec/utopia/rack_spec.rb
337
343
  - spec/utopia/redirection_spec.rb
338
344
  - spec/utopia/redirection_spec.ru
339
345
  - spec/utopia/session_spec.rb
@@ -354,7 +360,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
354
360
  requirements:
355
361
  - - "~>"
356
362
  - !ruby/object:Gem::Version
357
- version: '2.0'
363
+ version: '2.2'
358
364
  required_rubygems_version: !ruby/object:Gem::Requirement
359
365
  requirements:
360
366
  - - ">="
@@ -393,6 +399,7 @@ test_files:
393
399
  - spec/utopia/content/node/related/foo.ja.xnode
394
400
  - spec/utopia/content/node/related/links.yaml
395
401
  - spec/utopia/content/node_spec.rb
402
+ - spec/utopia/content/response_spec.rb
396
403
  - spec/utopia/content_spec.rb
397
404
  - spec/utopia/content_spec.ru
398
405
  - spec/utopia/content_spec/_heading.xnode
@@ -402,7 +409,7 @@ test_files:
402
409
  - spec/utopia/content_spec/index.xnode
403
410
  - spec/utopia/content_spec/node/index.xnode
404
411
  - spec/utopia/content_spec/test.xnode
405
- - spec/utopia/controller/action_spec.rb
412
+ - spec/utopia/controller/actions_spec.rb
406
413
  - spec/utopia/controller/middleware_spec.rb
407
414
  - spec/utopia/controller/middleware_spec.ru
408
415
  - spec/utopia/controller/middleware_spec/controller/controller.rb
@@ -450,7 +457,6 @@ test_files:
450
457
  - spec/utopia/performance_spec/pages/links.yaml
451
458
  - spec/utopia/performance_spec/pages/welcome/index.xnode
452
459
  - spec/utopia/rack_helper.rb
453
- - spec/utopia/rack_spec.rb
454
460
  - spec/utopia/redirection_spec.rb
455
461
  - spec/utopia/redirection_spec.ru
456
462
  - spec/utopia/session_spec.rb
@@ -1,116 +0,0 @@
1
- # Copyright, 2014, by Samuel G. D. Williams. <http://www.codeotaku.com>
2
- #
3
- # Permission is hereby granted, free of charge, to any person obtaining a copy
4
- # of this software and associated documentation files (the "Software"), to deal
5
- # in the Software without restriction, including without limitation the rights
6
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
- # copies of the Software, and to permit persons to whom the Software is
8
- # furnished to do so, subject to the following conditions:
9
- #
10
- # The above copyright notice and this permission notice shall be included in
11
- # all copies or substantial portions of the Software.
12
- #
13
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
- # THE SOFTWARE.
20
-
21
- module Utopia
22
- class Controller
23
- class Action < Hash
24
- def initialize(options = {}, &block)
25
- @options = options
26
- @callback = block
27
-
28
- super()
29
- end
30
-
31
- attr_accessor :callback, :options
32
-
33
- def callback?
34
- @callback != nil
35
- end
36
-
37
- def indirect?
38
- @options[:indirect]
39
- end
40
-
41
- def eql? other
42
- super and @callback.eql? other.callback and @options.eql? other.options
43
- end
44
-
45
- def hash
46
- [super, @callback, @options].hash
47
- end
48
-
49
- def == other
50
- super and @callback == other.callback and @options == other.options
51
- end
52
-
53
- protected
54
-
55
- def append(path, index, actions = [])
56
- # ** is greedy, it always matches if possible:
57
- if match_all = self[:**]
58
- # Match all remaining input:
59
- actions << match_all if match_all.callback?
60
- end
61
-
62
- if index < path.size
63
- name = path[index].to_sym
64
-
65
- if match_name = self[name]
66
- # Match the exact name:
67
- match_name.append(path, index+1, actions)
68
- end
69
-
70
- if match_one = self[:*]
71
- # Match one input:
72
- match_one.append(path, index+1, actions)
73
- end
74
- else
75
- # Got to end, matched completely:
76
- actions << self if self.callback?
77
- end
78
- end
79
-
80
- public
81
-
82
- # relative_path = 2014/mr-potato
83
- # actions => {:** => A}
84
- def select(relative_path)
85
- [].tap do |actions|
86
- append(relative_path.reverse, 0, actions)
87
- end
88
- end
89
-
90
- def define(path, **options, &callback)
91
- current = self
92
-
93
- path.reverse_each do |name|
94
- current = (current[name.to_sym] ||= Action.new)
95
- end
96
-
97
- current.options = options
98
- current.callback = callback
99
-
100
- return current
101
- end
102
-
103
- def call(controller, *arguments)
104
- controller.instance_exec(*arguments, self, &@callback)
105
- end
106
-
107
- def inspect
108
- if callback?
109
- "<action " + super + ":#{callback.source_location}(#{options})>"
110
- else
111
- "<action " + super + ">"
112
- end
113
- end
114
- end
115
- end
116
- end