utopia 1.7.1 → 1.8.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.
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