trailblazer 1.1.2 → 2.0.0.beta1

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 (86) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +10 -7
  3. data/CHANGES.md +108 -0
  4. data/COMM-LICENSE +91 -0
  5. data/Gemfile +18 -4
  6. data/LICENSE.txt +7 -20
  7. data/README.md +55 -15
  8. data/Rakefile +21 -2
  9. data/draft-1.2.rb +7 -0
  10. data/lib/trailblazer.rb +17 -4
  11. data/lib/trailblazer/dsl.rb +47 -0
  12. data/lib/trailblazer/operation/auto_inject.rb +47 -0
  13. data/lib/trailblazer/operation/builder.rb +18 -18
  14. data/lib/trailblazer/operation/callback.rb +31 -38
  15. data/lib/trailblazer/operation/contract.rb +46 -0
  16. data/lib/trailblazer/operation/controller.rb +45 -27
  17. data/lib/trailblazer/operation/guard.rb +24 -0
  18. data/lib/trailblazer/operation/model.rb +41 -33
  19. data/lib/trailblazer/operation/nested.rb +43 -0
  20. data/lib/trailblazer/operation/params.rb +13 -0
  21. data/lib/trailblazer/operation/persist.rb +13 -0
  22. data/lib/trailblazer/operation/policy.rb +26 -72
  23. data/lib/trailblazer/operation/present.rb +19 -0
  24. data/lib/trailblazer/operation/procedural/contract.rb +15 -0
  25. data/lib/trailblazer/operation/procedural/validate.rb +22 -0
  26. data/lib/trailblazer/operation/pundit.rb +42 -0
  27. data/lib/trailblazer/operation/representer.rb +25 -92
  28. data/lib/trailblazer/operation/rescue.rb +23 -0
  29. data/lib/trailblazer/operation/resolver.rb +18 -24
  30. data/lib/trailblazer/operation/validate.rb +50 -0
  31. data/lib/trailblazer/operation/wrap.rb +37 -0
  32. data/lib/trailblazer/version.rb +1 -1
  33. data/test/{operation/controller_test.rb → controller_test.rb} +8 -4
  34. data/test/docs/auto_inject_test.rb +30 -0
  35. data/test/docs/contract_test.rb +429 -0
  36. data/test/docs/dry_test.rb +31 -0
  37. data/test/docs/guard_test.rb +143 -0
  38. data/test/docs/nested_test.rb +117 -0
  39. data/test/docs/policy_test.rb +2 -0
  40. data/test/docs/pundit_test.rb +109 -0
  41. data/test/docs/representer_test.rb +268 -0
  42. data/test/docs/rescue_test.rb +153 -0
  43. data/test/docs/wrap_test.rb +174 -0
  44. data/test/gemfiles/Gemfile.ruby-1.9 +3 -0
  45. data/test/gemfiles/Gemfile.ruby-2.0 +12 -0
  46. data/test/gemfiles/Gemfile.ruby-2.3 +12 -0
  47. data/test/module_test.rb +22 -15
  48. data/test/operation/builder_test.rb +66 -18
  49. data/test/operation/callback_test.rb +70 -0
  50. data/test/operation/contract_test.rb +385 -15
  51. data/test/operation/dsl/callback_test.rb +18 -30
  52. data/test/operation/dsl/contract_test.rb +209 -19
  53. data/test/operation/dsl/representer_test.rb +42 -15
  54. data/test/operation/guard_test.rb +1 -147
  55. data/test/operation/model_test.rb +105 -0
  56. data/test/operation/params_test.rb +36 -0
  57. data/test/operation/persist_test.rb +44 -0
  58. data/test/operation/pipedream_test.rb +59 -0
  59. data/test/operation/pipetree_test.rb +104 -0
  60. data/test/operation/present_test.rb +24 -0
  61. data/test/operation/pundit_test.rb +104 -0
  62. data/test/{representer_test.rb → operation/representer_test.rb} +58 -42
  63. data/test/operation/resolver_test.rb +34 -70
  64. data/test/operation_test.rb +57 -189
  65. data/test/test_helper.rb +23 -3
  66. data/trailblazer.gemspec +8 -7
  67. metadata +91 -59
  68. data/gemfiles/Gemfile.rails.lock +0 -130
  69. data/gemfiles/Gemfile.reform-2.0 +0 -6
  70. data/gemfiles/Gemfile.reform-2.1 +0 -7
  71. data/lib/trailblazer/autoloading.rb +0 -15
  72. data/lib/trailblazer/endpoint.rb +0 -31
  73. data/lib/trailblazer/operation.rb +0 -175
  74. data/lib/trailblazer/operation/collection.rb +0 -6
  75. data/lib/trailblazer/operation/dispatch.rb +0 -3
  76. data/lib/trailblazer/operation/model/dsl.rb +0 -29
  77. data/lib/trailblazer/operation/model/external.rb +0 -34
  78. data/lib/trailblazer/operation/policy/guard.rb +0 -35
  79. data/lib/trailblazer/operation/uploaded_file.rb +0 -77
  80. data/test/callback_test.rb +0 -104
  81. data/test/collection_test.rb +0 -57
  82. data/test/model_test.rb +0 -148
  83. data/test/operation/external_model_test.rb +0 -71
  84. data/test/operation/policy_test.rb +0 -97
  85. data/test/operation/reject_test.rb +0 -34
  86. data/test/rollback_test.rb +0 -47
@@ -1,130 +0,0 @@
1
- PATH
2
- remote: ../
3
- specs:
4
- trailblazer (0.2.2)
5
- actionpack (>= 3.0.0)
6
- reform (>= 1.2.0)
7
- uber (>= 0.0.10)
8
-
9
- GEM
10
- remote: http://rubygems.org/
11
- specs:
12
- actionmailer (4.1.1)
13
- actionpack (= 4.1.1)
14
- actionview (= 4.1.1)
15
- mail (~> 2.5.4)
16
- actionpack (4.1.1)
17
- actionview (= 4.1.1)
18
- activesupport (= 4.1.1)
19
- rack (~> 1.5.2)
20
- rack-test (~> 0.6.2)
21
- actionview (4.1.1)
22
- activesupport (= 4.1.1)
23
- builder (~> 3.1)
24
- erubis (~> 2.7.0)
25
- activemodel (4.1.1)
26
- activesupport (= 4.1.1)
27
- builder (~> 3.1)
28
- activerecord (4.1.1)
29
- activemodel (= 4.1.1)
30
- activesupport (= 4.1.1)
31
- arel (~> 5.0.0)
32
- activesupport (4.1.1)
33
- i18n (~> 0.6, >= 0.6.9)
34
- json (~> 1.7, >= 1.7.7)
35
- minitest (~> 5.1)
36
- thread_safe (~> 0.1)
37
- tzinfo (~> 1.1)
38
- arel (5.0.1.20140414130214)
39
- builder (3.2.2)
40
- celluloid (0.16.0)
41
- timers (~> 4.0.0)
42
- connection_pool (2.0.0)
43
- disposable (0.0.9)
44
- representable (~> 2.0)
45
- uber
46
- erubis (2.7.0)
47
- hitimes (1.2.2)
48
- i18n (0.6.11)
49
- json (1.8.1)
50
- mail (2.5.4)
51
- mime-types (~> 1.16)
52
- treetop (~> 1.4.8)
53
- mime-types (1.25.1)
54
- mini_portile (0.6.2)
55
- minitest (5.4.2)
56
- multi_json (1.11.0)
57
- nokogiri (1.6.6.2)
58
- mini_portile (~> 0.6.0)
59
- polyglot (0.3.5)
60
- rack (1.5.2)
61
- rack-test (0.6.2)
62
- rack (>= 1.0)
63
- rails (4.1.1)
64
- actionmailer (= 4.1.1)
65
- actionpack (= 4.1.1)
66
- actionview (= 4.1.1)
67
- activemodel (= 4.1.1)
68
- activerecord (= 4.1.1)
69
- activesupport (= 4.1.1)
70
- bundler (>= 1.3.0, < 2.0)
71
- railties (= 4.1.1)
72
- sprockets-rails (~> 2.0)
73
- railties (4.1.1)
74
- actionpack (= 4.1.1)
75
- activesupport (= 4.1.1)
76
- rake (>= 0.8.7)
77
- thor (>= 0.18.1, < 2.0)
78
- rake (10.3.2)
79
- redis (3.1.0)
80
- redis-namespace (1.5.1)
81
- redis (~> 3.0, >= 3.0.4)
82
- reform (1.2.6)
83
- activemodel
84
- disposable (~> 0.0.5)
85
- representable (~> 2.1.0)
86
- uber (~> 0.0.11)
87
- representable (2.1.8)
88
- multi_json
89
- nokogiri
90
- uber (~> 0.0.7)
91
- responders (1.1.2)
92
- railties (>= 3.2, < 4.2)
93
- sidekiq (3.1.4)
94
- celluloid (>= 0.15.2)
95
- connection_pool (>= 2.0.0)
96
- json
97
- redis (>= 3.0.6)
98
- redis-namespace (>= 1.3.1)
99
- sprockets (3.1.0)
100
- rack (~> 1.0)
101
- sprockets-rails (2.3.1)
102
- actionpack (>= 3.0)
103
- activesupport (>= 3.0)
104
- sprockets (>= 2.8, < 4.0)
105
- sqlite3 (1.3.9)
106
- thor (0.19.1)
107
- thread_safe (0.3.4)
108
- timers (4.0.1)
109
- hitimes
110
- treetop (1.4.15)
111
- polyglot
112
- polyglot (>= 0.3.1)
113
- tzinfo (1.2.2)
114
- thread_safe (~> 0.1)
115
- uber (0.0.13)
116
-
117
- PLATFORMS
118
- ruby
119
-
120
- DEPENDENCIES
121
- activerecord
122
- bundler
123
- minitest
124
- rails
125
- railties
126
- rake
127
- responders
128
- sidekiq (~> 3.1.0)
129
- sqlite3
130
- trailblazer!
@@ -1,6 +0,0 @@
1
- source "http://rubygems.org"
2
-
3
- gemspec path: '../'
4
-
5
- gem "reform", "~> 2.0.5"
6
- gem "multi_json"
@@ -1,7 +0,0 @@
1
- source "http://rubygems.org"
2
-
3
- gemspec path: '../'
4
-
5
- gem "reform", github: "apotonick/reform" #"~> 2.1.0.rc1"
6
- gem "roar", github: "apotonick/roar" # "1.1.0"
7
- gem "multi_json"
@@ -1,15 +0,0 @@
1
- Trailblazer.class_eval do
2
- autoload :NotAuthorizedError, "trailblazer/operation/policy"
3
- end
4
-
5
- Trailblazer::Operation.class_eval do
6
- autoload :Controller, "trailblazer/operation/controller"
7
- autoload :Model, "trailblazer/operation/model"
8
- autoload :Collection, "trailblazer/operation/collection"
9
- autoload :Dispatch, "trailblazer/operation/dispatch" # TODO: remove in 1.2.
10
- autoload :Callback, "trailblazer/operation/callback"
11
- autoload :Module, "trailblazer/operation/module"
12
- autoload :Representer,"trailblazer/operation/representer"
13
- autoload :Policy, "trailblazer/operation/policy"
14
- autoload :Resolver, "trailblazer/operation/resolver"
15
- end
@@ -1,31 +0,0 @@
1
- module Trailblazer
2
- # Encapsulates HTTP-specific logic needed before running an operation.
3
- # Right now, all this does is #document_body! which figures out whether or not to pass the request body
4
- # into params, so the operation can use a representer to deserialize the original document.
5
- # To be used in Hanami, Roda, Rails, etc.
6
- class Endpoint
7
- def initialize(operation_class, params, request, options)
8
- @operation_class = operation_class
9
- @params = params
10
- @request = request
11
- @is_document = options[:is_document]
12
- end
13
-
14
- def call
15
- document_body! if @is_document
16
- yield @params# Create.run(params)
17
- end
18
-
19
- private
20
- attr_reader :params, :operation_class, :request
21
-
22
- def document_body!
23
- # this is what happens:
24
- # respond_with Comment::Update::JSON.run(params.merge(comment: request.body.string))
25
- concept_name = operation_class.model_class.to_s.underscore # this could be renamed to ::concept_class soon.
26
- request_body = request.body.respond_to?(:string) ? request.body.string : request.body.read
27
-
28
- params.merge!(concept_name => request_body)
29
- end
30
- end
31
- end
@@ -1,175 +0,0 @@
1
- require "reform"
2
-
3
- module Trailblazer
4
- class Operation
5
- require "trailblazer/operation/builder"
6
- extend Builder # imports ::builder_class and ::build_operation.
7
-
8
- extend Uber::InheritableAttr
9
- inheritable_attr :contract_class
10
- self.contract_class = Reform::Form.clone
11
-
12
- class << self
13
- def run(params, &block) # Endpoint behaviour
14
- res, op = build_operation(params).run
15
-
16
- if block_given?
17
- yield op if res
18
- return op
19
- end
20
-
21
- [res, op]
22
- end
23
-
24
- # Like ::run, but yield block when invalid.
25
- def reject(*args)
26
- res, op = run(*args)
27
- yield op if res == false
28
- op
29
- end
30
-
31
- # ::call only returns the Operation instance (or whatever was returned from #validate).
32
- # This is useful in tests or in irb, e.g. when using Op as a factory and you already know it's valid.
33
- def call(params)
34
- build_operation(params, raise_on_invalid: true).run.last
35
- end
36
-
37
- def [](*args) # TODO: remove in 1.2.
38
- warn "[Trailblazer] Operation[] is deprecated. Please use Operation.() and have a nice day."
39
- call(*args)
40
- end
41
-
42
- # Runs #setup! but doesn't process the operation.
43
- def present(params)
44
- build_operation(params)
45
- end
46
-
47
- # This is a DSL method. Use ::contract_class and ::contract_class= for the explicit version.
48
- # Op.contract #=> returns contract class
49
- # Op.contract do .. end # defines contract
50
- # Op.contract CommentForm # copies (and subclasses) external contract.
51
- # Op.contract CommentForm do .. end # copies and extends contract.
52
- def contract(constant=nil, &block)
53
- return contract_class unless constant or block_given?
54
-
55
- self.contract_class= Class.new(constant) if constant
56
- contract_class.class_eval(&block) if block_given?
57
- end
58
- end
59
-
60
-
61
- def initialize(params, options={})
62
- @options = options
63
- @valid = true
64
-
65
- setup!(params) # assign/find the model
66
- end
67
-
68
- # Operation.run(body: "Fabulous!") #=> [true, <Comment body: "Fabulous!">]
69
- def run
70
- process(@params)
71
-
72
- [valid?, self]
73
- end
74
-
75
- attr_reader :model
76
-
77
- def errors
78
- contract.errors
79
- end
80
-
81
- def valid?
82
- @valid
83
- end
84
-
85
- def contract(*args)
86
- contract!(*args)
87
- end
88
-
89
- private
90
- module Setup
91
- attr_writer :model
92
-
93
- def setup!(params)
94
- params = assign_params!(params)
95
- setup_params!(params)
96
- build_model!(params)
97
- params # TODO: test me.
98
- end
99
-
100
- def assign_params!(params)
101
- @params = params!(params)
102
- end
103
-
104
- # Overwrite #params! if you need to change its structure, by returning a new params object
105
- # from this method.
106
- # This is helpful if you don't want to change the original via #setup_params!.
107
- def params!(params)
108
- params
109
- end
110
-
111
- def setup_params!(params)
112
- end
113
-
114
- def build_model!(*args)
115
- assign_model!(*args) # @model = ..
116
- setup_model!(*args)
117
- end
118
-
119
- def assign_model!(*args)
120
- @model = model!(*args)
121
- end
122
-
123
- # Implement #model! to find/create your operation model (if required).
124
- def model!(params)
125
- end
126
-
127
- # Override to add attributes that can be infered from params.
128
- def setup_model!(params)
129
- end
130
- end
131
- include Setup
132
-
133
- def validate(params, model=nil, contract_class=nil)
134
- contract!(model, contract_class)
135
-
136
- if @valid = validate_contract(params)
137
- yield contract if block_given?
138
- else
139
- raise!(contract)
140
- end
141
-
142
- @valid
143
- end
144
-
145
- def validate_contract(params)
146
- contract.validate(params)
147
- end
148
-
149
- def invalid!(result=self)
150
- @valid = false
151
- result
152
- end
153
-
154
- # When using Op.(), an invalid contract will raise an exception.
155
- def raise!(contract)
156
- raise InvalidContract.new(contract.errors.to_s) if @options[:raise_on_invalid]
157
- end
158
-
159
- # Instantiate the contract, either by using the user's contract passed into #validate
160
- # or infer the Operation contract.
161
- def contract_for(model=nil, contract_class=nil)
162
- model ||= self.model
163
- contract_class ||= self.class.contract_class
164
-
165
- contract_class.new(model)
166
- end
167
-
168
- def contract!(*args)
169
- @contract ||= contract_for(*args)
170
- end
171
-
172
- class InvalidContract < RuntimeError
173
- end
174
- end
175
- end
@@ -1,6 +0,0 @@
1
- module Trailblazer::Operation::Collection
2
- # Collection does not produce a contract.
3
- def present
4
- self
5
- end
6
- end
@@ -1,3 +0,0 @@
1
- require "trailblazer/operation/callback"
2
- # TODO: deprecate this module.
3
- Trailblazer::Operation::Dispatch = Trailblazer::Operation::Callback
@@ -1,29 +0,0 @@
1
- class Trailblazer::Operation
2
- module Model
3
- # Imports ::model and ::action into an operation.
4
- module DSL
5
- def self.extended(extender)
6
- extender.extend Uber::InheritableAttr
7
- extender.inheritable_attr :config
8
- extender.config = {}
9
- end
10
-
11
- def model(name, action=nil)
12
- self.config[:model] = name
13
- action(action) if action # coolest line ever.
14
- end
15
-
16
- def action(name)
17
- self.config[:action] = name
18
- end
19
-
20
- def action_name # considered private.
21
- self.config[:action] or :create
22
- end
23
-
24
- def model_class # considered private.
25
- self.config[:model] or raise "[Trailblazer] You didn't call Operation::model."
26
- end
27
- end
28
- end
29
- end
@@ -1,34 +0,0 @@
1
- require "trailblazer/operation/model"
2
-
3
- class Trailblazer::Operation
4
- module Model
5
- # Builds (finds or creates) the model _before_ the operation is instantiated.
6
- # Passes the model instance into the builder with the following signature.
7
- #
8
- # builds ->(model, params)
9
- #
10
- # The initializer will now expect you to pass the model in via options[:model]. This
11
- # happens automatically when coming from a builder.
12
- module External
13
- def self.included(includer)
14
- includer.extend Model::DSL
15
- includer.extend Model::BuildModel
16
- includer.extend ClassMethods
17
- end
18
-
19
- def assign_model!(*) # i don't like to "disable" the `@model =` like this but it's the simplest for now.
20
- @model = @options[:model]
21
- end
22
-
23
-
24
- module ClassMethods
25
- private
26
- def build_operation(params, options={}) # TODO: merge with Resolver::build_operation.
27
- model = model!(params)
28
- build_operation_class(model, params). # calls builds->(model, params).
29
- new(params, options.merge(model: model))
30
- end
31
- end
32
- end
33
- end
34
- end