moonrope 1.3.3 → 2.0.2

Sign up to get free protection for your applications and to get access to all the features.
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