trailblazer 2.1.0.beta4 → 2.1.0.beta5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop_todo.yml +194 -502
  3. data/CHANGES.md +4 -0
  4. data/CONTRIBUTING.md +170 -0
  5. data/Gemfile +4 -1
  6. data/README.md +183 -40
  7. data/Rakefile +6 -2
  8. data/lib/trailblazer/version.rb +1 -1
  9. data/lib/trailblazer.rb +3 -12
  10. data/test/{operation/dsl → dsl}/contract_test.rb +2 -2
  11. data/trailblazer.gemspec +3 -3
  12. metadata +17 -63
  13. data/lib/trailblazer/operation/contract.rb +0 -82
  14. data/lib/trailblazer/operation/guard.rb +0 -18
  15. data/lib/trailblazer/operation/model.rb +0 -65
  16. data/lib/trailblazer/operation/nested.rb +0 -91
  17. data/lib/trailblazer/operation/persist.rb +0 -14
  18. data/lib/trailblazer/operation/policy.rb +0 -44
  19. data/lib/trailblazer/operation/pundit.rb +0 -38
  20. data/lib/trailblazer/operation/representer.rb +0 -36
  21. data/lib/trailblazer/operation/rescue.rb +0 -24
  22. data/lib/trailblazer/operation/validate.rb +0 -74
  23. data/lib/trailblazer/operation/wrap.rb +0 -64
  24. data/test/docs/contract_test.rb +0 -545
  25. data/test/docs/dry_test.rb +0 -31
  26. data/test/docs/guard_test.rb +0 -162
  27. data/test/docs/macro_test.rb +0 -36
  28. data/test/docs/model_test.rb +0 -75
  29. data/test/docs/nested_test.rb +0 -300
  30. data/test/docs/policy_test.rb +0 -2
  31. data/test/docs/pundit_test.rb +0 -133
  32. data/test/docs/representer_test.rb +0 -268
  33. data/test/docs/rescue_test.rb +0 -154
  34. data/test/docs/wrap_test.rb +0 -219
  35. data/test/nested_test.rb +0 -293
  36. data/test/operation/contract_test.rb +0 -290
  37. data/test/operation/dsl/representer_test.rb +0 -169
  38. data/test/operation/model_test.rb +0 -54
  39. data/test/operation/persist_test.rb +0 -51
  40. data/test/operation/pundit_test.rb +0 -106
  41. data/test/operation/representer_test.rb +0 -254
data/CHANGES.md CHANGED
@@ -30,6 +30,10 @@ document Task API and define step API
30
30
  deprecate step->(options) ?
31
31
  injectable, per-operation step arguments strategy?
32
32
 
33
+ # 2.1.0.beta5
34
+
35
+ * All macros are now cleanly extracted to `trailblazer-macro` and `trailblazer-macro-contract`.
36
+
33
37
  # 2.1.0.beta4
34
38
 
35
39
  * Simple maintenance release to establish `activity-0.5.0`.
data/CONTRIBUTING.md ADDED
@@ -0,0 +1,170 @@
1
+ # Contributing to Trailblazer
2
+ Trailblazer is an open source project and we would love you to help us make it better.
3
+
4
+ ## Questions/Help
5
+ If our [guides][guides] nor [docs][api-docs] can help you figure things out, and you're stuck, refrain from posting questions on github issues, and please just find us on the [trailblazer gitter chat][chat] and drop us a line.
6
+
7
+ Keep in mind when asking questions though, an example will get you help faster than anything else you do.
8
+
9
+ If you file an issue with a question, it will be closed. We're not trying to be mean, don't get us wrong, we're just trying to stay sane.
10
+
11
+ ## Reporting Issues
12
+ A well formatted issue is appreciated, and goes a long way in helping us help you.
13
+
14
+ * Make sure you have a [GitHub account](https://github.com/signup/free)
15
+ * Submit a [Github issue][issues-link] by:
16
+ * Clearly describing the issue
17
+ * Provide a descriptive summary
18
+ * Provide sample code where possible (preferably in the form of a test, in a [Gist][gist] for bonus points)
19
+ * Explain the expected behavior
20
+ * Explain the actual behavior
21
+ * Provide steps to reproduce the actual behavior
22
+ * Provide your application's complete `Gemfile.lock` as text (in a [Gist][gist] for bonus points)
23
+ * Any relevant stack traces
24
+
25
+ If you provide code, make sure it is formatted with the triple backticks (\`).
26
+
27
+ At this point, we'd love to tell you how long it will take for us to respond, but we just don't know.
28
+
29
+ ## Pull requests
30
+ We accept pull requests to Trailblazer for:
31
+
32
+ * Adding documentation
33
+ * Fixing bugs
34
+ * Adding new features
35
+
36
+ Not all features proposed will be added but we are open to having a conversation about a feature you are championing.
37
+
38
+ ###Here's a quick guide:
39
+ #### Fork the Project
40
+ Fork the [project repository][project-repo-link] on Github and check out your copy.
41
+
42
+ ```
43
+ git clone https://github.com/YOUR_HANDLE/trailblazer.git
44
+ cd trailblazer
45
+ git remote add upstream https://github.com/trailblazer/trailblazer.git
46
+ ```
47
+
48
+ #### Create a Topic Branch
49
+ Make sure your fork is up-to-date and create a topic branch for your feature or bug fix.
50
+ ```
51
+ git checkout master
52
+ git pull upstream master
53
+ git checkout -b my-feature-branch
54
+ ```
55
+
56
+ #### Bundle and Test
57
+ Run bundle install/update to gather any and all dependencies. Run the tests. This is to make sure your starting point works.
58
+
59
+ ```
60
+ bundle install
61
+ bundle exec rake
62
+ ```
63
+
64
+ #### Write Tests
65
+ Try to write a test that reproduces the problem you're trying to fix or describes a feature that you want to build. Add to [test][test-link].
66
+
67
+ We definitely appreciate pull requests that highlight or reproduce a problem, even without a fix.
68
+
69
+ #### Write Code
70
+ Implement your feature or bug fix.
71
+
72
+ Ruby style is enforced with [RuboCop](https://github.com/bbatsov/rubocop), run `bundle exec rubocop` and fix any style issues highlighted.
73
+
74
+ Make sure that `bundle exec rake` completes without errors.
75
+
76
+ #### Write Documentation
77
+ Document any external behavior in the [README](README.md).
78
+
79
+ #### Commit Changes
80
+ Make sure git knows your name and email address:
81
+
82
+ ```
83
+ git config --global user.name "Your Name"
84
+ git config --global user.email "contributor@example.com"
85
+ ```
86
+
87
+ Writing good commit logs is important. A commit log should describe what has changed and why, but be brief.
88
+
89
+ ```
90
+ git add your_filename.rb (File names to add content from, or fileglobs e.g. *.rb)
91
+ git commit
92
+ ```
93
+
94
+ #### Push
95
+ ```
96
+ git push origin my-feature-branch
97
+ ```
98
+
99
+ #### Make a Pull Request
100
+ Go to https://github.com/YOUR_GH_HANDLE/trailblazer and select your feature branch. Click the 'Pull Request' button and fill out the form. Pull requests are usually reviewed within a few days, but no need to rush us if it takes longer.
101
+
102
+ #### Rebase
103
+ If you've been working on a change for a while, rebase with upstream/master.
104
+
105
+ ```
106
+ git fetch upstream
107
+ git rebase upstream/master
108
+ git push origin my-feature-branch -f
109
+ ```
110
+
111
+ #### Update CHANGELOG Again
112
+ Update the [CHANGELOG](CHANGELOG.md) with the pull request number. A typical entry looks as follows.
113
+
114
+ ```
115
+ * [#123](https://github.com/trailblazer/trailblazer/pull/123): Your brief description - [@your_gh_handle](https://github.com/your_gh_handle).
116
+ ```
117
+
118
+ Amend your previous commit and force push the changes.
119
+
120
+ ```
121
+ git commit --amend
122
+ git push origin my-feature-branch -f
123
+ ```
124
+
125
+ #### Check on Your Pull Request
126
+ Go back to your pull request after a few minutes and see whether it passed muster with Travis-CI. Everything should look green, otherwise fix issues and amend your commit as described above.
127
+
128
+ ## Releasing
129
+
130
+ When you have release rights, please follow these rules.
131
+
132
+ * When tagging a commit for a release, use the format `vX.X.X` for the tag, e.g. `git tag v2.1.0`.
133
+ * The tagged commit **must contain the line** "Releasing vX.X.X" so it can be quickly spotted later in the commit list.
134
+
135
+ #### What now?
136
+ At this point you're waiting on us. Expect a conversation regarding your pull request; Questions, clarifications, and so on.
137
+
138
+ Some things that will increase the chance that your pull request is accepted:
139
+ * Use Trailblazer idioms and follow the Trailblazer idealogy
140
+ * Include tests that fail without your code, and pass with it
141
+ * Update the documentation, guides, etc.
142
+
143
+ ## What do we need help with?
144
+ ### Helping others!
145
+ There are a lot of questions from people as they get started using Trailblazer. If you could **please do the following things**, that would really help:
146
+
147
+ - Hang out on [the chat][chat]
148
+ - Watch the [trailblazer repositories][repositories] for issues or requests that you could help with
149
+
150
+ ### Contributing to community
151
+ - Create Macros!
152
+ - Write blog posts!
153
+ - Record screencasts
154
+ - Write examples.
155
+
156
+ ### Contributing to the core
157
+ - Tests are always helpful!
158
+ - Any of the issues in GitHub, let us know if you have some time to fix one.
159
+
160
+ ## Thank You
161
+ Please do know that we really appreciate and value your time and work.
162
+
163
+ [gist]: https://gist.github.com
164
+ [guides]: https://www.trailblazer.to
165
+ [api-docs]: https://www.trailblazer.to/api-docs
166
+ [chat]: https://gitter.im/trailblazer/chat
167
+ [repositories]: https://github.com/trailblazer
168
+ [test-link]: https://github.com/trailblazer/trailblazer/tree/master/test
169
+ [project-repo-link]: https://github.com/trailblazer/trailblazer
170
+ [issues-link]: https://www.github.com/trailblazer/trailblazer/issues
data/Gemfile CHANGED
@@ -14,13 +14,16 @@ gem "dry-auto_inject"
14
14
  gem "dry-matcher"
15
15
  gem "dry-validation"
16
16
 
17
+ # gem "trailblazer-operation", path: "../operation"
18
+ gem "trailblazer-macro", github: "trailblazer/trailblazer-macro"
19
+ gem "trailblazer-macro-contract", github: "trailblazer/trailblazer-macro-contract"
17
20
  gem "trailblazer-operation", path: "../operation"
18
21
  # gem "trailblazer-operation", github: "trailblazer/trailblazer-operation"
19
22
 
20
23
  gem "minitest-line"
21
24
 
22
25
  gem "rubocop", require: false
23
- # gem "trailblazer-activity", path: "../trailblazer-circuit"
26
+ gem "trailblazer-activity", path: "../trailblazer-circuit"
24
27
  # gem "trailblazer-activity", github: "trailblazer/trailblazer-activity"
25
28
  # gem "trailblazer-activity", path: "../trailblazer-circuit"
26
29
  # gem "trailblazer-activity", github: "trailblazer/trailblazer-activity"
data/README.md CHANGED
@@ -42,7 +42,7 @@ Trailblazer offers you a new, more intuitive file layout in applications.
42
42
  ```
43
43
  app
44
44
  ├── concepts
45
- │ ├── comment
45
+ │ ├── song
46
46
  │ │ ├── operation
47
47
  │ │ │ ├── create.rb
48
48
  │ │ │ ├── update.rb
@@ -55,7 +55,7 @@ app
55
55
  │ │ ├── view
56
56
  │ │ │ ├── show.haml
57
57
  │ │ │ ├── index.rb
58
- │ │ │ ├── comment.css.sass
58
+ │ │ │ ├── song.css.sass
59
59
  ```
60
60
 
61
61
  Instead of grouping by technology, classes and views are structured by *concept*, and then by technology. A concept can relate to a model, or can be a completely abstract concern such as `invoicing`.
@@ -81,7 +81,7 @@ Trailblazer uses Rails routing to map URLs to controllers, because it works.
81
81
 
82
82
  ```ruby
83
83
  Rails.application.routes.draw do
84
- resources :comments
84
+ resources :songs
85
85
  end
86
86
  ```
87
87
 
@@ -90,9 +90,9 @@ end
90
90
  Controllers are lean endpoints for HTTP. They do not contain any business logic. Actions immediately dispatch to an operation.
91
91
 
92
92
  ```ruby
93
- class CommentsController < ApplicationController
93
+ class SongsController < ApplicationController
94
94
  def create
95
- run Comment::Create # Comment::Create is an operation class.
95
+ run Song::Create # Song::Create is an operation class.
96
96
  end
97
97
  end
98
98
  ```
@@ -100,10 +100,10 @@ end
100
100
  The `#run` method invokes the operation. It allows you to run a conditional block of logic if the operation was successful.
101
101
 
102
102
  ```ruby
103
- class CommentsController < ApplicationController
103
+ class SongsController < ApplicationController
104
104
  def create
105
- run Comment::Create do |op|
106
- return redirect_to(comment_path op.model) # success!
105
+ run Song::Create do |op|
106
+ return redirect_to(song_path op.model) # success!
107
107
  end
108
108
 
109
109
  render :new # invalid. re-render form.
@@ -126,7 +126,7 @@ Operations don't know about HTTP or the environment. You could use an operation
126
126
  An operation is not just a monolithic replacement for your business code. It's a simple orchestrator between the form objects, models, your business code and all other layers needed to get the job done.
127
127
 
128
128
  ```ruby
129
- class Comment::Create < Trailblazer::Operation
129
+ class Song::Create < Trailblazer::Operation
130
130
  step :process!
131
131
 
132
132
  def process!(options)
@@ -140,44 +140,188 @@ Operations only need to define and implement steps, like the `#process!` steps.
140
140
  You cannot instantiate them per design. The only way to invoke them is `call`.
141
141
 
142
142
  ```ruby
143
- Comment::Create.call(whatever: "goes", in: "here")
143
+ Song::Create.call(whatever: "goes", in: "here")
144
144
  # same as
145
- Comment::Create.(whatever: "goes", in: "here")
145
+ Song::Create.(whatever: "goes", in: "here")
146
146
  ```
147
147
 
148
148
  Their high degree of encapsulation makes them a [replacement for test factories](#test), too.
149
149
 
150
150
  [Learn more.](http://trailblazer.to/gems/operation)
151
151
 
152
- ## Validation
152
+ ### Contract
153
+ The Contract Macro, covers the contracts for Trailblazer, they are basically Reform objects that you can define and validate inside an operation. Reform is a fantastic tool for deserializing and validating deeply nested hashes, and then, when valid, writing those to the database using your persistence layer such as ActiveRecord.
153
154
 
154
- In Trailblazer, an operation (usually) has a form object which is simply a `Reform::Form` class. All the [API documented in Reform](https://github.com/apotonick/reform) can be applied and used.
155
+ ```ruby
156
+ # app/concepts/song/contract/create.rb
157
+ module Song::Contract
158
+ class Create < Reform::Form
159
+ property :title
160
+ property :length
161
+
162
+ validates :title, length: 2..33
163
+ validates :length, numericality: true
164
+ end
165
+ end
166
+ ```
155
167
 
156
- Validations can also be implemented in pure Dry-validation.
168
+ The Contract then gets hooked into the operation. using this Macro.
169
+ ```ruby
170
+ # app/concepts/song/operation/create.rb
171
+ class Song::Create < Trailblazer::Operation
172
+ step Model( Song, :new )
173
+ step Contract::Build( constant: Song::Contract::Create )
174
+ step Contract::Validate()
175
+ step Contract::Persist()
176
+ end
177
+ ```
178
+ As you can see, using contracts consists of five steps.
157
179
 
158
- The operation makes use of the form object using the `#validate` method.
180
+ Define the contract class (or multiple of them) for the operation.
181
+ Plug the contract creation into the operation’s pipe using Contract::Build.
182
+ Run the contract’s validation for the params using Contract::Validate.
183
+ If successful, write the sane data to the model(s). This will usually happen in the Contract::Persist macro.
184
+ After the operation has been run, interpret the result. For instance, a controller calling an operation will render a erroring form for invalid input.
159
185
 
186
+ Here’s what the result would look like after running the Create operation with invalid data.
160
187
  ```ruby
161
- class Comment::Create < Trailblazer::Operation
162
- extend Contract::DSL
188
+ result = Song::Create.( title: "A" )
189
+ result.success? #=> false
190
+ result["contract.default"].errors.messages
191
+ #=> {:title=>["is too short (minimum is 2 characters)"], :length=>["is not a number"]}
192
+ ```
163
193
 
164
- contract do
165
- # this is a Reform::Form class!
166
- property :body, validates: {presence: true}
167
- end
194
+ #### Build
195
+ The Contract::Build macro helps you to instantiate the contract. It is both helpful for a complete workflow, or to create the contract, only, without validating it, e.g. when presenting the form.
196
+ ```ruby
197
+ class Song::New < Trailblazer::Operation
198
+ step Model( Song, :new )
199
+ step Contract::Build( constant: Song::Contract::Create )
200
+ end
201
+ ```
202
+
203
+ This macro will grab the model from options["model"] and pass it into the contract’s constructor. The contract is then saved in options["contract.default"].
204
+ ```ruby
205
+ result = Song::New.()
206
+ result["model"] #=> #<struct Song title=nil, length=nil>
207
+ result["contract.default"]
208
+ #=> #<Song::Contract::Create model=#<struct Song title=nil, length=nil>>
209
+ ```
210
+ The Build macro accepts the :name option to change the name from default.
168
211
 
169
- step Model( Comment, :new )
170
- step Contract::Build()
171
- step Contract::Validate( key: :comment )
212
+ #### Validation
213
+ The Contract::Validate macro is responsible for validating the incoming params against its contract. That means you have to use Contract::Build beforehand, or create the contract yourself. The macro will then grab the params and throw then into the contract’s validate (or call) method.
214
+
215
+ ```ruby
216
+ class Song::ValidateOnly < Trailblazer::Operation
217
+ step Model( Song, :new )
218
+ step Contract::Build( constant: Song::Contract::Create )
219
+ step Contract::Validate()
220
+ end
221
+ ```
222
+ Depending on the outcome of the validation, it either stays on the right track, or deviates to left, skipping the remaining steps.
223
+ ```ruby
224
+ result = Song::ValidateOnly.({}) # empty params
225
+ result.success? #=> false
226
+ ```
227
+
228
+ Note that Validate really only validates the contract, nothing is written to the model, yet. You need to push data to the model manually, e.g. with Contract::Persist.
229
+ ```ruby
230
+ result = Song::ValidateOnly.({ title: "Rising Force", length: 13 })
231
+
232
+ result.success? #=> true
233
+ result["model"] #=> #<struct Song title=nil, length=nil>
234
+ result["contract.default"].title #=> "Rising Force"
235
+ ```
236
+
237
+ Validate will use options["params"] as the input. You can change the nesting with the :key option.
238
+
239
+ Internally, this macro will simply call Form#validate on the Reform object.
240
+
241
+ Note: Reform comes with sophisticated deserialization semantics for nested forms, it might be worth reading a bit about Reform to fully understand what you can do in the Validate step.
242
+
243
+ ##### Key
244
+ Per default, Contract::Validate will use options["params"] as the data to be validated. Use the key: option if you want to validate a nested hash from the original params structure.
245
+ ```ruby
246
+ class Song::Create < Trailblazer::Operation
247
+ step Model( Song, :new )
248
+ step Contract::Build( constant: Song::Contract::Create )
249
+ step Contract::Validate( key: "song" )
172
250
  step Contract::Persist( )
173
251
  end
174
252
  ```
175
253
 
176
- The contract (aka _form_) is defined in the `::contract` block. You can implement nested forms, default values, validations, and everything else Reform provides.
254
+ This automatically extracts the nested "song" hash.
255
+ ```ruby
256
+ result = Song::Create.({ "song" => { title: "Rising Force", length: 13 } })
257
+ result.success? #=> true
258
+ ```
259
+
260
+ If that key isn’t present in the params hash, the operation fails before the actual validation.
261
+ ```ruby
262
+ result = Song::Create.({ title: "Rising Force", length: 13 })
263
+ result.success? #=> false
264
+ ```
265
+
266
+ Note: String vs. symbol do matter here since the operation will simply do a hash lookup using the key you provided.
267
+
268
+ #### Persist
269
+ To push validated data from the contract to the model(s), use Persist. Like Validate, this requires a contract to be set up beforehand.
270
+ ```ruby
271
+ class Song::Create < Trailblazer::Operation
272
+ step Model( Song, :new )
273
+ step Contract::Build( constant: Song::Contract::Create )
274
+ step Contract::Validate()
275
+ step Contract::Persist()
276
+ end
277
+ ```
278
+
279
+ After the step, the contract’s attribute values are written to the model, and the contract will call save on the model.
280
+ ```ruby
281
+ result = Song::Create.( title: "Rising Force", length: 13 )
282
+ result.success? #=> true
283
+ result["model"] #=> #<Song title="Rising Force", length=13>
284
+ ```
285
+
286
+ You can also configure the Persist step to call sync instead of Reform’s save.
287
+ ```ruby
288
+ step Persist( method: :sync )
289
+ ```
290
+ This will only write the contract’s data to the model without calling save on it.
291
+
292
+ ##### Name
293
+ Explicit naming for the contract is possible, too.
294
+ ```ruby
295
+
296
+ class Song::Create < Trailblazer::Operation
297
+ step Model( Song, :new )
298
+ step Contract::Build( name: "form", constant: Song::Contract::Create )
299
+ step Contract::Validate( name: "form" )
300
+ step Contract::Persist( name: "form" )
301
+ end
302
+ ```
177
303
 
178
- In the `#process` method you can define your business logic.
304
+ You have to use the name: option to tell each step what contract to use. The contract and its result will now use your name instead of default.
305
+ ```ruby
306
+ result = Song::Create.({ title: "A" })
307
+ result["contract.form"].errors.messages #=> {:title=>["is too short (minimum is 2 ch...
308
+ ```
179
309
 
180
- [Learn more.](http://trailblazer.to/gems/operation/2.0/contract.html)
310
+ Use this if your operation has multiple contracts.
311
+
312
+ #### Result Object
313
+ The operation will store the validation result for every contract in its own result object.
314
+
315
+ The path is result.contract.#{name}.
316
+ ```ruby
317
+ result = Create.({ length: "A" })
318
+
319
+ result["result.contract.default"].success? #=> false
320
+ result["result.contract.default"].errors #=> Errors object
321
+ result["result.contract.default"].errors.messages #=> {:length=>["is not a number"]}
322
+ ```
323
+
324
+ Each result object responds to success?, failure?, and errors, which is an Errors object.
181
325
 
182
326
  ## Models
183
327
 
@@ -186,7 +330,7 @@ Models for persistence can be implemented using any ORM you fancy, for instance
186
330
  In Trailblazer, models are completely empty. They solely contain associations and finders. No business logic is allowed in models.
187
331
 
188
332
  ```ruby
189
- class Comment < ActiveRecord::Base
333
+ class Song < ActiveRecord::Base
190
334
  belongs_to :thing
191
335
 
192
336
  scope :latest, lambda { all.limit(9).order("id DESC") }
@@ -200,9 +344,9 @@ Only operations and views/cells can access models directly.
200
344
  You can abort running an operation using a policy. "[Pundit](https://github.com/elabs/pundit)-style" policy classes define the rules.
201
345
 
202
346
  ```ruby
203
- class Comment::Policy
204
- def initialize(user, comment)
205
- @user, @comment = user, comment
347
+ class Song::Policy
348
+ def initialize(user, song)
349
+ @user, @song = user, song
206
350
  end
207
351
 
208
352
  def create?
@@ -214,8 +358,8 @@ end
214
358
  The rule is enabled via the `::policy` call.
215
359
 
216
360
  ```ruby
217
- class Comment::Create < Trailblazer::Operation
218
- step Policy( Comment::Policy, :create? )
361
+ class Song::Create < Trailblazer::Operation
362
+ step Policy( Song::Policy, :create? )
219
363
  end
220
364
  ```
221
365
 
@@ -233,9 +377,9 @@ More complex UI logic happens in _View Models_ as found in [Cells](https://githu
233
377
  The operation's form object can be rendered in views, too.
234
378
 
235
379
  ```ruby
236
- class CommentsController < ApplicationController
380
+ class SongsController < ApplicationController
237
381
  def new
238
- form Comment::Create # will assign the form object to @form.
382
+ form Song::Create # will assign the form object to @form.
239
383
  end
240
384
  end
241
385
  ```
@@ -255,12 +399,12 @@ Operations can use representers from [Roar](https://github.com/apotonick/roar) t
255
399
  Representers can be inferred automatically from your contract, then may be refined, e.g. with hypermedia or a format like `JSON-API`.
256
400
 
257
401
  ```ruby
258
- class Comment::Create < Trailblazer::Operation
402
+ class Song::Create < Trailblazer::Operation
259
403
  representer do
260
404
  # inherited :body
261
405
  include Roar::JSON::HAL
262
406
 
263
- link(:self) { comment_path(represented.id) }
407
+ link(:self) { song_path(represented.id) }
264
408
  end
265
409
  end
266
410
  ```
@@ -276,8 +420,8 @@ In Trailblazer, you only have operation unit tests and integration smoke tests t
276
420
  Operations completely replace the need for leaky factories.
277
421
 
278
422
  ```ruby
279
- describe Comment::Update do
280
- let(:comment) { Comment::Create.(comment: {body: "[That](http://trailblazer.to)!"}) }
423
+ describe Song::Update do
424
+ let(:song) { Song::Create.(song: {body: "[That](http://trailblazer.to)!"}) }
281
425
  end
282
426
  ```
283
427
 
@@ -302,4 +446,3 @@ gem "trailblazer-cells"
302
446
  ```
303
447
 
304
448
  Cells is _not_ required per default! Add it if you use it, which is highly recommended.
305
-
data/Rakefile CHANGED
@@ -2,7 +2,7 @@ require "bundler/gem_tasks"
2
2
  require "rake/testtask"
3
3
  require "rubocop/rake_task"
4
4
 
5
- task :default => [:test]
5
+ task :default => %i[test rubocop]
6
6
 
7
7
  Rake::TestTask.new(:test) do |test|
8
8
  test.libs << 'test'
@@ -16,4 +16,8 @@ Rake::TestTask.new(:testdep) do |test|
16
16
  test.verbose = true
17
17
  end
18
18
 
19
- RuboCop::RakeTask.new
19
+ RuboCop::RakeTask.new(:rubocop) do |task|
20
+ task.patterns = ['lib/**/*.rb', 'test/**/*.rb']
21
+ task.options << "--display-cop-names"
22
+ task.fail_on_error = false
23
+ end
@@ -1,3 +1,3 @@
1
1
  module Trailblazer
2
- VERSION = "2.1.0.beta4"
2
+ VERSION = "2.1.0.beta5"
3
3
  end
data/lib/trailblazer.rb CHANGED
@@ -6,17 +6,8 @@ require "trailblazer/dsl"
6
6
  require "trailblazer/task"
7
7
 
8
8
  require "trailblazer/operation/deprecations"
9
-
10
- require "trailblazer/operation/model"
11
- require "trailblazer/operation/contract"
12
- require "trailblazer/operation/validate"
13
- require "trailblazer/operation/representer"
14
- require "trailblazer/operation/policy"
15
- require "trailblazer/operation/pundit"
16
- require "trailblazer/operation/guard"
17
- require "trailblazer/operation/persist"
18
- require "trailblazer/operation/nested"
19
- require "trailblazer/operation/wrap"
20
- require "trailblazer/operation/rescue"
21
9
  require "trailblazer/operation/inject"
22
10
  require "trailblazer/operation/input_output"
11
+
12
+ require "trailblazer/macro"
13
+ require "trailblazer/macro/contract"
@@ -38,7 +38,7 @@ class DslContractTest < MiniTest::Spec
38
38
  end
39
39
 
40
40
  # no inheritance with setter.
41
- it { CreateOrFind["contract.default.class"].must_be_nil }
41
+ it { CreateOrFind["contract.default.class"].must_equal nil }
42
42
 
43
43
  # ---
44
44
  # Op::contract Constant
@@ -197,7 +197,7 @@ class DslContractTest < MiniTest::Spec
197
197
  form.sync
198
198
 
199
199
  song.genre.must_equal "Punkrock"
200
- song.band.must_be_nil
200
+ song.band.must_equal nil
201
201
  end
202
202
  end
203
203
 
data/trailblazer.gemspec CHANGED
@@ -17,10 +17,10 @@ Gem::Specification.new do |spec|
17
17
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
18
  spec.require_paths = ["lib"]
19
19
 
20
- spec.add_dependency "trailblazer-operation", ">= 0.2.3", "< 0.3.0"
21
- spec.add_dependency "trailblazer-activity", ">= 0.4.3", "< 0.6.0"
20
+ spec.add_dependency "trailblazer-operation", ">= 0.2.4", "< 0.3.0"
21
+ spec.add_dependency "trailblazer-macro", ">= 2.1.0.beta2", "< 2.2.0"
22
+ spec.add_dependency "trailblazer-macro-contract", ">= 2.1.0.beta2", "< 2.2.0"
22
23
 
23
- spec.add_dependency "reform", ">= 2.2.0", "< 3.0.0"
24
24
  spec.add_dependency "declarative"
25
25
 
26
26
  spec.add_development_dependency "activemodel" # for Reform::AM::V