moonrope 1.3.3 → 2.0.2

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 (78) hide show
  1. checksums.yaml +5 -5
  2. data/Gemfile +9 -0
  3. data/Gemfile.lock +47 -0
  4. data/MIT-LICENCE +20 -0
  5. data/README.md +24 -0
  6. data/bin/moonrope +28 -0
  7. data/docs/authentication.md +114 -0
  8. data/docs/controllers.md +106 -0
  9. data/docs/exceptions.md +27 -0
  10. data/docs/introduction.md +29 -0
  11. data/docs/structures.md +214 -0
  12. data/example/authentication.rb +50 -0
  13. data/example/controllers/meta_controller.rb +14 -0
  14. data/example/controllers/users_controller.rb +92 -0
  15. data/example/structures/pet_structure.rb +12 -0
  16. data/example/structures/user_structure.rb +35 -0
  17. data/lib/moonrope.rb +5 -4
  18. data/lib/moonrope/action.rb +170 -40
  19. data/lib/moonrope/authenticator.rb +42 -0
  20. data/lib/moonrope/base.rb +67 -6
  21. data/lib/moonrope/controller.rb +4 -2
  22. data/lib/moonrope/doc_context.rb +94 -0
  23. data/lib/moonrope/doc_server.rb +123 -0
  24. data/lib/moonrope/dsl/action_dsl.rb +159 -9
  25. data/lib/moonrope/dsl/authenticator_dsl.rb +35 -0
  26. data/lib/moonrope/dsl/base_dsl.rb +21 -18
  27. data/lib/moonrope/dsl/controller_dsl.rb +60 -9
  28. data/lib/moonrope/dsl/filterable_dsl.rb +27 -0
  29. data/lib/moonrope/dsl/structure_dsl.rb +28 -2
  30. data/lib/moonrope/errors.rb +13 -0
  31. data/lib/moonrope/eval_environment.rb +82 -3
  32. data/lib/moonrope/eval_helpers.rb +47 -8
  33. data/lib/moonrope/eval_helpers/filter_helper.rb +82 -0
  34. data/lib/moonrope/guard.rb +35 -0
  35. data/lib/moonrope/html_generator.rb +65 -0
  36. data/lib/moonrope/param_set.rb +11 -1
  37. data/lib/moonrope/rack_middleware.rb +66 -37
  38. data/lib/moonrope/railtie.rb +31 -14
  39. data/lib/moonrope/request.rb +43 -15
  40. data/lib/moonrope/structure.rb +100 -18
  41. data/lib/moonrope/structure_attribute.rb +39 -0
  42. data/lib/moonrope/version.rb +1 -1
  43. data/moonrope.gemspec +21 -0
  44. data/spec/spec_helper.rb +32 -0
  45. data/spec/specs/action_spec.rb +455 -0
  46. data/spec/specs/base_spec.rb +29 -0
  47. data/spec/specs/controller_spec.rb +31 -0
  48. data/spec/specs/param_set_spec.rb +31 -0
  49. data/templates/basic/_action_form.erb +77 -0
  50. data/templates/basic/_errors_table.erb +32 -0
  51. data/templates/basic/_structure_attributes_list.erb +55 -0
  52. data/templates/basic/action.erb +168 -0
  53. data/templates/basic/assets/lock.svg +3 -0
  54. data/templates/basic/assets/reset.css +101 -0
  55. data/templates/basic/assets/style.css +348 -0
  56. data/templates/basic/assets/tool.svg +4 -0
  57. data/templates/basic/assets/try.js +157 -0
  58. data/templates/basic/authenticator.erb +52 -0
  59. data/templates/basic/controller.erb +20 -0
  60. data/templates/basic/index.erb +114 -0
  61. data/templates/basic/layout.erb +46 -0
  62. data/templates/basic/structure.erb +23 -0
  63. data/test/test_helper.rb +81 -0
  64. data/test/tests/action_access_test.rb +63 -0
  65. data/test/tests/actions_test.rb +524 -0
  66. data/test/tests/authenticators_test.rb +87 -0
  67. data/test/tests/base_test.rb +35 -0
  68. data/test/tests/controllers_test.rb +49 -0
  69. data/test/tests/eval_environment_test.rb +136 -0
  70. data/test/tests/evel_helpers_test.rb +60 -0
  71. data/test/tests/examples_test.rb +11 -0
  72. data/test/tests/helpers_test.rb +97 -0
  73. data/test/tests/param_set_test.rb +44 -0
  74. data/test/tests/rack_middleware_test.rb +131 -0
  75. data/test/tests/request_test.rb +232 -0
  76. data/test/tests/structures_param_extensions_test.rb +159 -0
  77. data/test/tests/structures_test.rb +398 -0
  78. metadata +71 -56
@@ -0,0 +1,87 @@
1
+ class AuthenticatorsTest < Test::Unit::TestCase
2
+
3
+ def test_that_by_default_actions_dont_have_an_authenticator
4
+ base = Moonrope::Base.new do
5
+ controller :users do
6
+ action :list
7
+ end
8
+ end
9
+ assert_equal :none, (base/:users/:list).authenticator_to_use
10
+ end
11
+
12
+ def test_actions_will_use_default_authenticator
13
+ base = Moonrope::Base.new do
14
+ authenticator :default do
15
+ lookup { true }
16
+ end
17
+ controller :users do
18
+ action :list
19
+ end
20
+ end
21
+ assert_equal :default, (base/:users/:list).authenticator_to_use.name
22
+ end
23
+
24
+ def test_actions_will_use_controller_authenticator
25
+ base = Moonrope::Base.new do
26
+ authenticator :default
27
+ authenticator :controller_specific
28
+ authenticator :action_specific
29
+ controller :animals do
30
+ action :list
31
+ end
32
+ controller :users do
33
+ authenticator :controller_specific
34
+ action :list
35
+ action :show do
36
+ authenticator :action_specific
37
+ end
38
+ end
39
+ end
40
+ assert_equal :default, (base/:animals/:list).authenticator_to_use.name
41
+ assert_equal :controller_specific, (base/:users/:list).authenticator_to_use.name
42
+ assert_equal :action_specific, (base/:users/:show).authenticator_to_use.name
43
+ end
44
+
45
+ def test_that_missing_authenticators_return_not_found
46
+ base = Moonrope::Base.new do
47
+ authenticator :default
48
+ controller :animals do
49
+ authenticator :missing
50
+ action :list
51
+ end
52
+ end
53
+ assert_equal :not_found, (base/:animals/:list).authenticator_to_use
54
+ end
55
+
56
+ def test_authentication_can_be_defined_via_access_rule
57
+ base = Moonrope::Base.new do
58
+ authenticator :some_authenticator
59
+ controller :users do
60
+ action :list do
61
+ access_rule :some_authenticator => :some_rule
62
+ end
63
+ end
64
+ end
65
+ assert_equal :some_authenticator, (base/:users/:list).authenticator
66
+ assert_equal :some_rule, (base/:users/:list).access_rule
67
+ end
68
+
69
+ def test_that_access_rules_can_inherit
70
+ base = Moonrope::Base.new do
71
+ controller :animals do
72
+ action :list
73
+ end
74
+ controller :users do
75
+ access_rule :controller_specific
76
+ action :list
77
+ action :show do
78
+ access_rule :action_specific
79
+ end
80
+ end
81
+ end
82
+ assert_equal :default, (base/:animals/:list).access_rule_to_use
83
+ assert_equal :controller_specific, (base/:users/:list).access_rule_to_use
84
+ assert_equal :action_specific, (base/:users/:show).access_rule_to_use
85
+ end
86
+
87
+ end
@@ -0,0 +1,35 @@
1
+ class ControllersTest < Test::Unit::TestCase
2
+
3
+ def test_basic_definitions
4
+ base = Moonrope::Base.new do
5
+ authenticator :default do
6
+ lookup { :person }
7
+ end
8
+ controller :users do
9
+ action :list
10
+ end
11
+ controller :animals
12
+ structure :user
13
+ structure :animal
14
+ end
15
+
16
+ # Check they are added to the base
17
+ assert_equal 2, base.controllers.size
18
+ assert_equal true, base.controllers.all? { |s| s.is_a?(Moonrope::Controller)}
19
+ assert_equal 2, base.structures.size
20
+ assert_equal true, base.structures.all? { |s| s.is_a?(Moonrope::Structure)}
21
+ assert_equal 1, base.authenticators.size
22
+ assert_equal true, base.authenticators.all? { |_,v| v.is_a?(Moonrope::Authenticator) }
23
+
24
+ # Check they can be accessed
25
+ assert_equal :users, base.controller(:users).name
26
+ assert_equal :animals, base.controller(:animals).name
27
+ assert_equal :user, base.structure(:user).name
28
+ assert_equal :animal, base.structure(:animal).name
29
+
30
+ # Check controllers & actions can be found nicely
31
+ assert_equal :list, (base / :users / :list).name
32
+ assert_equal :user, (base[:user]).name
33
+ end
34
+
35
+ end
@@ -0,0 +1,49 @@
1
+ class ControllersTest < Test::Unit::TestCase
2
+
3
+ def setup
4
+ @base = Moonrope::Base.new
5
+ end
6
+
7
+ def test_controllers_actions_can_be_found_easily
8
+ controller = Moonrope::Controller.new(@base, :users) do
9
+ action :list do
10
+ action { true }
11
+ end
12
+ end
13
+ action = controller / :list
14
+ assert_equal :list, action.name
15
+ assert action.is_a?(Moonrope::Action)
16
+ end
17
+
18
+ def test_controllers_can_have_before_filters
19
+ controller = Moonrope::Controller.new(@base, :users) do
20
+ before { 1 }
21
+ before(:list) { 3 }
22
+ action :list do
23
+ action { true }
24
+ end
25
+
26
+ action :show do
27
+ action { true }
28
+ end
29
+ end
30
+ assert_equal 2, controller.befores.size
31
+ assert_equal 2, controller.before_actions_for(:list).size
32
+ assert_equal 1, controller.before_actions_for(:show).size
33
+ end
34
+
35
+ def test_definining_shared_params
36
+ controller = Moonrope::Controller.new(@base, :users) do
37
+ shared_action :crud do
38
+ param :username
39
+ param :first_name
40
+ error 'SomeError'
41
+ end
42
+ end
43
+
44
+ assert_equal(Hash, controller.shared_actions.class)
45
+ assert_equal(Proc, controller.shared_actions[:crud].class)
46
+
47
+ end
48
+
49
+ end
@@ -0,0 +1,136 @@
1
+ class EvalEnvironmentTest < Test::Unit::TestCase
2
+
3
+ def setup
4
+ @auth_user = User.new(:name => 'Admin User')
5
+ @request = FakeRequest.new(:params => {'page' => '1'}, :version => 2, :identity => @auth_user)
6
+ @environment = Moonrope::EvalEnvironment.new(Moonrope::Base.new, @request, nil, :accessor1 => 'Hello')
7
+ end
8
+
9
+ def test_version
10
+ assert_equal 2, @environment.version
11
+ end
12
+
13
+ def test_params
14
+ assert @environment.params.is_a?(Moonrope::ParamSet)
15
+ assert_equal '1', @environment.params.page
16
+ end
17
+
18
+ def test_accessors
19
+ assert_equal 'Hello', @environment.accessor1
20
+ end
21
+
22
+ def test_identity_access
23
+ assert_equal @auth_user, @environment.identity
24
+ end
25
+
26
+ def test_setting_headers
27
+ @environment.set_header 'Header1', 'A'
28
+ assert_equal 'A', @environment.headers['Header1']
29
+ @environment.set_header 'Header2', 'B'
30
+ assert_equal 'B', @environment.headers['Header2']
31
+ end
32
+
33
+ def test_setting_flags
34
+ @environment.set_flag 'Flag1', 'A'
35
+ assert_equal 'A', @environment.flags['Flag1']
36
+ @environment.set_flag 'Flag2', 'B'
37
+ assert_equal 'B', @environment.flags['Flag2']
38
+ end
39
+
40
+ def test_structure_access
41
+ user_structure = Moonrope::Structure.new(@environment.base, :user) do
42
+ basic { {:id => o.id} }
43
+ end
44
+ structure = @environment.structure(user_structure, User.new)
45
+ assert structure.is_a?(Hash), "structure was not a Hash, was a #{structure.class}"
46
+ end
47
+
48
+ def test_structure_access_with_auto_determination
49
+ user_structure = @environment.base.dsl.structure(:user) do
50
+ basic { {:id => o.id} }
51
+ end
52
+ structure = @environment.structure(UserWithUnderscore.new)
53
+ assert structure.is_a?(Hash), "structure was not a Hash, was a #{structure.class}"
54
+ end
55
+
56
+ def test_structure_for
57
+ user_structure = @environment.base.dsl.structure(:user) do
58
+ basic { {:id => o.id} }
59
+ end
60
+ structure = @environment.structure_for(:user)
61
+ assert_equal structure, user_structure
62
+ end
63
+
64
+ def test_has_structure_for
65
+ user_structure = @environment.base.dsl.structure(:user) do
66
+ basic { {:id => o.id} }
67
+ end
68
+ assert_equal false, @environment.has_structure_for?(:blah)
69
+ assert_equal true, @environment.has_structure_for?(:user)
70
+ end
71
+
72
+ def test_copy_attributes_from_param_set_to_an_object
73
+ base = Moonrope::Base.new
74
+ controller = Moonrope::Controller.new(base, :users) do
75
+ action :save do
76
+ param :username do |object, value|
77
+ object.username = "#{value}!"
78
+ end
79
+ param :id
80
+ end
81
+ end
82
+
83
+ request = FakeRequest.new(:params => {'id' => 123, 'username' => 'adam'})
84
+ env = Moonrope::EvalEnvironment.new(base, request, controller/:save)
85
+ user = User.new
86
+ env.copy_params_to user, :username, :id
87
+ assert_equal user.id, 123
88
+ assert_equal user.username, "adam!"
89
+ end
90
+
91
+ def test_copy_attributes_from_share
92
+ base = Moonrope::Base.new
93
+ controller = Moonrope::Controller.new(base, :users) do
94
+ shared_action :crud do
95
+ param :username
96
+ param :id
97
+ end
98
+ action :save do
99
+ use :crud
100
+ end
101
+ end
102
+
103
+ request = FakeRequest.new(:params => {'id' => 123, 'username' => 'adam'})
104
+ env = Moonrope::EvalEnvironment.new(base, request, controller/:save)
105
+ user = User.new
106
+ env.copy_params_to user, :from => :crud
107
+ assert_equal user.id, 123
108
+ assert_equal user.username, "adam"
109
+ end
110
+
111
+ def test_copy_attribute_from_shared_action_within_shared_action
112
+ base = Moonrope::Base.new
113
+ controller = Moonrope::Controller.new(base, :users) do
114
+ shared_action :private_code do
115
+ param :private_code
116
+ end
117
+ shared_action :crud do
118
+ param :username
119
+ param :id
120
+ use :private_code
121
+ end
122
+ action :save do
123
+ use :crud
124
+ end
125
+ end
126
+
127
+ request = FakeRequest.new(:params => {'id' => 123, 'username' => 'adam', 'private_code' => 'llama'})
128
+ env = Moonrope::EvalEnvironment.new(base, request, controller/:save)
129
+ user = User.new
130
+ env.copy_params_to user, :from => :crud
131
+ assert_equal user.username, "adam"
132
+ assert_equal user.private_code, "llama"
133
+ end
134
+
135
+ end
136
+
@@ -0,0 +1,60 @@
1
+ class EvalHelpersTest < Test::Unit::TestCase
2
+
3
+ def setup
4
+ @environment = Moonrope::EvalEnvironment.new(Moonrope::Base.new, FakeRequest.new(:params => {'page' => 1}))
5
+ @environment.reset
6
+ end
7
+
8
+ def test_errors
9
+ assert_raises Moonrope::Errors::NotFound do
10
+ @environment.error(:not_found, "Page not found")
11
+ end
12
+
13
+ assert_raises Moonrope::Errors::AccessDenied do
14
+ @environment.error(:access_denied, "User not authenticated")
15
+ end
16
+
17
+ assert_raises Moonrope::Errors::ValidationError do
18
+ @environment.error(:validation_error, [{:field => 'user', :message => 'should not be blank'}])
19
+ end
20
+
21
+ assert_raises Moonrope::Errors::ParameterError do
22
+ @environment.error(:parameter_error, [{:field => 'page', :message => 'should be present'}])
23
+ end
24
+
25
+ assert_raises Moonrope::Errors::RequestError do
26
+ @environment.error(:misc_error, "Unknown issue")
27
+ end
28
+ end
29
+
30
+ def test_paginate
31
+ items = PaginationCollection.new
32
+ result = @environment.paginate(items) { |r| r }
33
+ assert result.is_a?(Array)
34
+ assert @environment.flags[:paginated].is_a?(Hash)
35
+ end
36
+
37
+ class PaginationCollection
38
+ def to_a
39
+ [1,2,3,4,5,6]
40
+ end
41
+
42
+ def page(page)
43
+ self
44
+ end
45
+
46
+ def per(max_per_page)
47
+ self
48
+ end
49
+
50
+ def total_pages
51
+ 2
52
+ end
53
+
54
+ def total_count
55
+ 34
56
+ end
57
+ end
58
+
59
+
60
+ end
@@ -0,0 +1,11 @@
1
+ class ExamplesTest < Test::Unit::TestCase
2
+
3
+ def setup
4
+ @base = Moonrope::Base.load(File.expand_path('../../../example', __FILE__))
5
+ end
6
+
7
+ def test_examples_are_valid
8
+ assert_equal 2, @base.controllers.size
9
+ end
10
+
11
+ end
@@ -0,0 +1,97 @@
1
+ class HelpersTest < Test::Unit::TestCase
2
+
3
+ def test_helper_definitions_and_selection
4
+ base = Moonrope::Base.new do
5
+ # A global helper
6
+ helper :say_hello do |name|
7
+ "Hello #{name}!"
8
+ end
9
+
10
+ # A controller specific helper
11
+ controller :users do
12
+ helper :user_helper do |name|
13
+ "Your name is #{name}!"
14
+ end
15
+
16
+ action :action1 do
17
+ action do
18
+ say_hello('David')
19
+ end
20
+ end
21
+
22
+ action :action2 do
23
+ action do
24
+ user_helper('Michael')
25
+ end
26
+ end
27
+
28
+ action :action3 do
29
+ action do
30
+ animal_helper('Bob')
31
+ end
32
+ end
33
+ end
34
+
35
+ # Another controller
36
+ controller :animals do
37
+ helper :animal_helper do |name|
38
+ "Animal name is #{name}"
39
+ end
40
+ end
41
+ end
42
+
43
+ assert_equal 3, base.helpers.size
44
+ assert_equal Moonrope::Helper, base.helper(:say_hello).class
45
+
46
+ # see if the controller-scoped helper is only available to the cobntroller
47
+ assert_equal nil, base.helper(:user_helper)
48
+ assert_equal nil, base.helper(:user_helper, base / :animals)
49
+ assert_equal Moonrope::Helper, base.helper(:user_helper, base/:users).class
50
+
51
+ # see if running the actuions will allow usage of helpers
52
+ result = (base/:users/:action1).execute
53
+ assert_equal "Hello David!", result.data
54
+
55
+ result = (base/:users/:action2).execute
56
+ assert_equal "Your name is Michael!", result.data
57
+
58
+ assert_raises(NoMethodError) { (base/:users/:action3).execute }
59
+ end
60
+
61
+ def test_unloadable_helpers
62
+ base = Moonrope::Base.new
63
+ base.dsl.instance_eval do
64
+ helper :unloadable_helper, :unloadable => false do
65
+ 666
66
+ end
67
+
68
+ helper :normal_helper do
69
+ 111
70
+ end
71
+ end
72
+ # initially they'll both exist
73
+ assert_equal Moonrope::Helper, base.helper(:unloadable_helper).class
74
+ assert_equal Moonrope::Helper, base.helper(:normal_helper).class
75
+ # unload the base
76
+ base.unload
77
+ # now only the unloadable helper remains
78
+ assert_equal Moonrope::Helper, base.helper(:unloadable_helper).class
79
+ assert_equal nil, base.helper(:normal_helper)
80
+ end
81
+
82
+ def test_ensure_helpers_cant_be_double_loaded
83
+ base = Moonrope::Base.new do
84
+ helper :my_helper do
85
+ 123
86
+ end
87
+ end
88
+
89
+ assert_raises Moonrope::Errors::HelperAlreadyDefined do
90
+ base.dsl.instance_eval do
91
+ helper :my_helper do
92
+ end
93
+ end
94
+ end
95
+ end
96
+
97
+ end