cuprum-rails 0.1.0 → 0.2.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 (113) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +145 -0
  3. data/DEVELOPMENT.md +20 -0
  4. data/README.md +356 -63
  5. data/lib/cuprum/rails/action.rb +32 -16
  6. data/lib/cuprum/rails/actions/create.rb +62 -15
  7. data/lib/cuprum/rails/actions/destroy.rb +23 -7
  8. data/lib/cuprum/rails/actions/edit.rb +23 -7
  9. data/lib/cuprum/rails/actions/index.rb +30 -10
  10. data/lib/cuprum/rails/actions/middleware/associations/cache.rb +112 -0
  11. data/lib/cuprum/rails/actions/middleware/associations/find.rb +23 -0
  12. data/lib/cuprum/rails/actions/middleware/associations/parent.rb +70 -0
  13. data/lib/cuprum/rails/actions/middleware/associations/query.rb +140 -0
  14. data/lib/cuprum/rails/actions/middleware/associations.rb +12 -0
  15. data/lib/cuprum/rails/actions/middleware/log_request.rb +126 -0
  16. data/lib/cuprum/rails/actions/middleware/log_result.rb +51 -0
  17. data/lib/cuprum/rails/actions/middleware/resources/find.rb +44 -0
  18. data/lib/cuprum/rails/actions/middleware/resources/query.rb +91 -0
  19. data/lib/cuprum/rails/actions/middleware/resources.rb +11 -0
  20. data/lib/cuprum/rails/actions/middleware.rb +13 -0
  21. data/lib/cuprum/rails/actions/new.rb +16 -4
  22. data/lib/cuprum/rails/actions/parameter_validation.rb +60 -0
  23. data/lib/cuprum/rails/actions/resource_action.rb +119 -42
  24. data/lib/cuprum/rails/actions/show.rb +23 -7
  25. data/lib/cuprum/rails/actions/update.rb +70 -22
  26. data/lib/cuprum/rails/actions.rb +11 -7
  27. data/lib/cuprum/rails/collection.rb +27 -47
  28. data/lib/cuprum/rails/command.rb +3 -1
  29. data/lib/cuprum/rails/commands/destroy_one.rb +10 -6
  30. data/lib/cuprum/rails/commands/find_many.rb +8 -1
  31. data/lib/cuprum/rails/commands/find_matching.rb +1 -1
  32. data/lib/cuprum/rails/commands/find_one.rb +8 -0
  33. data/lib/cuprum/rails/commands/insert_one.rb +17 -6
  34. data/lib/cuprum/rails/commands/update_one.rb +16 -5
  35. data/lib/cuprum/rails/constraints/parameters_contract.rb +14 -0
  36. data/lib/cuprum/rails/constraints.rb +10 -0
  37. data/lib/cuprum/rails/controller.rb +12 -2
  38. data/lib/cuprum/rails/controllers/action.rb +100 -0
  39. data/lib/cuprum/rails/controllers/class_methods/actions.rb +33 -7
  40. data/lib/cuprum/rails/controllers/class_methods/configuration.rb +36 -0
  41. data/lib/cuprum/rails/controllers/class_methods/middleware.rb +88 -0
  42. data/lib/cuprum/rails/controllers/class_methods/validations.rb +2 -2
  43. data/lib/cuprum/rails/controllers/configuration.rb +41 -1
  44. data/lib/cuprum/rails/controllers/middleware.rb +59 -0
  45. data/lib/cuprum/rails/controllers.rb +2 -0
  46. data/lib/cuprum/rails/errors/invalid_parameters.rb +55 -0
  47. data/lib/cuprum/rails/errors/invalid_statement.rb +11 -0
  48. data/lib/cuprum/rails/errors/missing_parameter.rb +42 -0
  49. data/lib/cuprum/rails/errors/resource_error.rb +46 -0
  50. data/lib/cuprum/rails/errors.rb +6 -1
  51. data/lib/cuprum/rails/map_errors.rb +29 -1
  52. data/lib/cuprum/rails/query.rb +1 -1
  53. data/lib/cuprum/rails/repository.rb +12 -25
  54. data/lib/cuprum/rails/request.rb +149 -60
  55. data/lib/cuprum/rails/resource.rb +119 -85
  56. data/lib/cuprum/rails/responders/base_responder.rb +78 -0
  57. data/lib/cuprum/rails/responders/html/plural_resource.rb +9 -39
  58. data/lib/cuprum/rails/responders/html/rendering.rb +81 -0
  59. data/lib/cuprum/rails/responders/html/resource.rb +107 -0
  60. data/lib/cuprum/rails/responders/html/singular_resource.rb +9 -38
  61. data/lib/cuprum/rails/responders/html.rb +2 -0
  62. data/lib/cuprum/rails/responders/html_responder.rb +8 -52
  63. data/lib/cuprum/rails/responders/json/resource.rb +3 -3
  64. data/lib/cuprum/rails/responders/json_responder.rb +31 -16
  65. data/lib/cuprum/rails/responders/matching.rb +29 -27
  66. data/lib/cuprum/rails/responders/serialization.rb +11 -9
  67. data/lib/cuprum/rails/responders.rb +1 -0
  68. data/lib/cuprum/rails/responses/head_response.rb +24 -0
  69. data/lib/cuprum/rails/responses/html/redirect_back_response.rb +55 -0
  70. data/lib/cuprum/rails/responses/html/redirect_response.rb +19 -4
  71. data/lib/cuprum/rails/responses/html/render_response.rb +17 -5
  72. data/lib/cuprum/rails/responses/html.rb +6 -2
  73. data/lib/cuprum/rails/responses.rb +1 -0
  74. data/lib/cuprum/rails/result.rb +36 -0
  75. data/lib/cuprum/rails/routes.rb +36 -23
  76. data/lib/cuprum/rails/rspec/contract_helpers.rb +57 -0
  77. data/lib/cuprum/rails/rspec/contracts/action_contracts.rb +754 -0
  78. data/lib/cuprum/rails/rspec/contracts/actions/create_contracts.rb +289 -0
  79. data/lib/cuprum/rails/rspec/contracts/actions/destroy_contracts.rb +164 -0
  80. data/lib/cuprum/rails/rspec/contracts/actions/edit_contracts.rb +73 -0
  81. data/lib/cuprum/rails/rspec/contracts/actions/index_contracts.rb +108 -0
  82. data/lib/cuprum/rails/rspec/contracts/actions/new_contracts.rb +111 -0
  83. data/lib/cuprum/rails/rspec/contracts/actions/show_contracts.rb +72 -0
  84. data/lib/cuprum/rails/rspec/contracts/actions/update_contracts.rb +263 -0
  85. data/lib/cuprum/rails/rspec/contracts/actions.rb +8 -0
  86. data/lib/cuprum/rails/rspec/contracts/command_contracts.rb +479 -0
  87. data/lib/cuprum/rails/rspec/contracts/responder_contracts.rb +232 -0
  88. data/lib/cuprum/rails/rspec/contracts/routes_contracts.rb +363 -0
  89. data/lib/cuprum/rails/rspec/contracts/serializers_contracts.rb +70 -0
  90. data/lib/cuprum/rails/rspec/contracts.rb +8 -0
  91. data/lib/cuprum/rails/rspec/matchers/be_a_result_matcher.rb +64 -0
  92. data/lib/cuprum/rails/rspec/matchers.rb +41 -0
  93. data/lib/cuprum/rails/serializers/base_serializer.rb +60 -0
  94. data/lib/cuprum/rails/serializers/context.rb +84 -0
  95. data/lib/cuprum/rails/serializers/json/active_record_serializer.rb +2 -2
  96. data/lib/cuprum/rails/serializers/json/array_serializer.rb +9 -8
  97. data/lib/cuprum/rails/serializers/json/attributes_serializer.rb +95 -172
  98. data/lib/cuprum/rails/serializers/json/error_serializer.rb +2 -2
  99. data/lib/cuprum/rails/serializers/json/hash_serializer.rb +9 -8
  100. data/lib/cuprum/rails/serializers/json/identity_serializer.rb +3 -3
  101. data/lib/cuprum/rails/serializers/json/properties_serializer.rb +252 -0
  102. data/lib/cuprum/rails/serializers/json.rb +2 -1
  103. data/lib/cuprum/rails/serializers.rb +3 -1
  104. data/lib/cuprum/rails/version.rb +1 -1
  105. data/lib/cuprum/rails.rb +19 -16
  106. metadata +73 -131
  107. data/lib/cuprum/rails/controller_action.rb +0 -121
  108. data/lib/cuprum/rails/errors/missing_parameters.rb +0 -33
  109. data/lib/cuprum/rails/errors/missing_primary_key.rb +0 -46
  110. data/lib/cuprum/rails/errors/undefined_permitted_attributes.rb +0 -34
  111. data/lib/cuprum/rails/rspec/command_contract.rb +0 -460
  112. data/lib/cuprum/rails/rspec/define_route_contract.rb +0 -84
  113. data/lib/cuprum/rails/serializers/json/serializer.rb +0 -66
@@ -1,84 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'cuprum/rails/rspec'
4
-
5
- module Cuprum::Rails::RSpec
6
- # Contract asserting that a Routes object defines the given route.
7
- DEFINE_ROUTE_CONTRACT = lambda \
8
- do |action_name:, path:, member_action: false, wildcards: {}|
9
- describe "##{action_name}_path" do
10
- let(:method_name) { "#{action_name}_path" }
11
- let(:expected) do
12
- next path unless member_action
13
-
14
- primary_key_name = entity.class.primary_key
15
- primary_key_value = entity[primary_key_name]
16
-
17
- path.sub(':id', primary_key_value.to_s)
18
- end
19
-
20
- define_method(:route_helper) do
21
- scoped = wildcards.empty? ? routes : routes.with_wildcards(wildcards)
22
-
23
- if member_action
24
- scoped.send(method_name, entity)
25
- else
26
- scoped.send(method_name)
27
- end
28
- end
29
-
30
- it 'should define the helper method' do
31
- if member_action
32
- expect(routes).to respond_to(method_name).with(1).argument
33
- else
34
- expect(routes).to respond_to(method_name).with(0).arguments
35
- end
36
- end
37
-
38
- it 'should return the route path' do
39
- expect(route_helper).to be == expected
40
- end
41
-
42
- if member_action
43
- describe 'when the entity is nil' do
44
- let(:entity) { nil }
45
- let(:error_message) { 'missing wildcard :id' }
46
-
47
- it 'should raise an exception' do
48
- expect { route_helper }
49
- .to raise_error(
50
- described_class::MissingWildcardError,
51
- error_message
52
- )
53
- end
54
- end
55
- end
56
-
57
- wildcards.each do |key, _|
58
- wildcard = key.to_s.end_with?('_id') ? key.intern : :"#{key}_id"
59
-
60
- describe "when the #{wildcard.inspect} wildcard is undefined" do
61
- let(:error_message) { "missing wildcard #{wildcard.inspect}" }
62
-
63
- define_method(:route_helper) do
64
- scoped = routes.with_wildcards(wildcards.except(key))
65
-
66
- if member_action
67
- scoped.send(method_name, entity)
68
- else
69
- scoped.send(method_name)
70
- end
71
- end
72
-
73
- it 'should raise an exception' do
74
- expect { route_helper }
75
- .to raise_error(
76
- described_class::MissingWildcardError,
77
- error_message
78
- )
79
- end
80
- end
81
- end
82
- end
83
- end
84
- end
@@ -1,66 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'cuprum/rails/serializers/json'
4
-
5
- module Cuprum::Rails::Serializers::Json
6
- # Converts objects or data structures to JSON based on configured serializers.
7
- class Serializer
8
- # Error class used when a serializer calls itself.
9
- class RecursiveSerializerError < StandardError; end
10
-
11
- # Error class used when there is no matching serializer for the object.
12
- class UndefinedSerializerError < StandardError; end
13
-
14
- # @return [Cuprum::Rails::Serializers::Json::Serializer] a cached instance
15
- # of the serializer.
16
- def self.instance
17
- @instance ||= new
18
- end
19
-
20
- # Converts the object to JSON using the given serializers.
21
- #
22
- # First, #call finds the best serializer from the :serializers Hash. This is
23
- # done by walking up the object class's ancestors to find the closest
24
- # ancestor which is a key in the :serializers Hash. The corresponding value
25
- # is then called with the object.
26
- #
27
- # @param object [Object] The object to convert to JSON.
28
- # @param serializers [Hash<Class, #call>] The serializers for different
29
- # object types.
30
- #
31
- # @return [Object] a JSON-compatible representation of the object.
32
- #
33
- # @raise RecursiveSerializerError if the serializer would create an infinite
34
- # loop, e.g. by calling itself.
35
- # @raise UndefinedSerializerError if there is no matching serializer for
36
- # the object.
37
- def call(object, serializers:)
38
- serializer = handle_recursion!(object) do
39
- serializer_for(object: object, serializers: serializers)
40
- end
41
-
42
- serializer.call(object, serializers: serializers)
43
- end
44
-
45
- private
46
-
47
- def handle_recursion!(object)
48
- serializer = yield
49
-
50
- return serializer unless instance_of?(serializer.class)
51
-
52
- raise RecursiveSerializerError,
53
- "invalid serializer for #{object.class.name} - recursive calls to" \
54
- " #{self.class.name}#call"
55
- end
56
-
57
- def serializer_for(object:, serializers:)
58
- object.class.ancestors.each do |ancestor|
59
- return serializers[ancestor] if serializers.key?(ancestor)
60
- end
61
-
62
- raise UndefinedSerializerError,
63
- "no serializer defined for #{object.class.name}"
64
- end
65
- end
66
- end