trailblazer 0.2.2 → 0.3.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 (43) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +1 -3
  3. data/CHANGES.md +33 -0
  4. data/Gemfile +4 -1
  5. data/README.md +171 -166
  6. data/Rakefile +10 -2
  7. data/gemfiles/Gemfile.rails.lock +42 -11
  8. data/lib/trailblazer/autoloading.rb +4 -3
  9. data/lib/trailblazer/endpoint.rb +40 -0
  10. data/lib/trailblazer/operation.rb +15 -8
  11. data/lib/trailblazer/operation/collection.rb +7 -0
  12. data/lib/trailblazer/operation/controller.rb +30 -22
  13. data/lib/trailblazer/operation/controller/active_record.rb +6 -2
  14. data/lib/trailblazer/operation/crud.rb +3 -5
  15. data/lib/trailblazer/operation/dispatch.rb +29 -0
  16. data/lib/trailblazer/operation/representer.rb +41 -5
  17. data/lib/trailblazer/operation/responder.rb +2 -2
  18. data/lib/trailblazer/operation/uploaded_file.rb +4 -4
  19. data/lib/trailblazer/operation/worker.rb +8 -10
  20. data/lib/trailblazer/rails/railtie.rb +10 -7
  21. data/lib/trailblazer/version.rb +1 -1
  22. data/test/collection_test.rb +56 -0
  23. data/test/crud_test.rb +23 -1
  24. data/test/dispatch_test.rb +63 -0
  25. data/test/operation_test.rb +84 -125
  26. data/test/rails/controller_test.rb +51 -0
  27. data/test/rails/endpoint_test.rb +86 -0
  28. data/test/rails/fake_app/cells.rb +2 -2
  29. data/test/rails/fake_app/config.rb +1 -1
  30. data/test/rails/fake_app/controllers.rb +27 -0
  31. data/test/rails/fake_app/models.rb +10 -1
  32. data/test/rails/fake_app/rails_app.rb +15 -1
  33. data/test/rails/fake_app/song/operations.rb +38 -2
  34. data/test/rails/fake_app/views/bands/index.html.erb +1 -0
  35. data/test/rails/fake_app/views/songs/another_view.html.erb +2 -0
  36. data/test/representer_test.rb +126 -0
  37. data/test/responder_test.rb +2 -4
  38. data/test/rollback_test.rb +47 -0
  39. data/test/test_helper.rb +43 -1
  40. data/test/uploaded_file_test.rb +4 -4
  41. data/test/worker_test.rb +13 -9
  42. data/trailblazer.gemspec +7 -3
  43. metadata +68 -29
@@ -10,8 +10,7 @@ class Song
10
10
  include Responder
11
11
 
12
12
  def process(params)
13
- invalid!(self) if params == false
14
- self
13
+ invalid! if params == false
15
14
  end
16
15
  end
17
16
  end
@@ -26,8 +25,7 @@ module MyApp
26
25
  model Song
27
26
 
28
27
  def process(params)
29
- invalid!(self) if params == false
30
- self
28
+ invalid! if params == false
31
29
  end
32
30
  end
33
31
  end
@@ -0,0 +1,47 @@
1
+ require "test_helper"
2
+
3
+ # TODO: rollback for composed operations: this is basically implemented already as every operation knows how to rollback.
4
+ # however, this has to be run for composed operations.
5
+ # we can also add Transaction and Lock for real uniqueness validators, etc.
6
+ #
7
+ # i am keen to try integrating https://github.com/collectiveidea/interactor organizers!
8
+ module Trailblazer::Operation::Rollback
9
+ def run(params)
10
+ begin
11
+ super
12
+ rescue
13
+ rollback!(params, $!)
14
+ [false, self]
15
+ end
16
+ end
17
+ end
18
+
19
+ class RollbackTest < MiniTest::Spec
20
+ class ExceptionalOperation < Trailblazer::Operation
21
+ include Rollback
22
+
23
+ def process(params)
24
+ @_params = params
25
+ raise # something happens.
26
+ end
27
+
28
+ attr_reader :_params, :_rollback_args
29
+
30
+ def rollback!(params, exception)
31
+ @_rollback_args = [params, exception]
32
+ end
33
+ end
34
+
35
+ module Comparable
36
+ def ==(other)
37
+ self.class == other.class
38
+ end
39
+ end
40
+
41
+ it do
42
+ op = ExceptionalOperation.("amazing")
43
+ op._params.must_equal "amazing"
44
+
45
+ op._rollback_args.must_equal ["amazing", RuntimeError.new.extend(Comparable)]
46
+ end
47
+ end
data/test/test_helper.rb CHANGED
@@ -1,5 +1,32 @@
1
1
  require 'trailblazer'
2
2
  require 'minitest/autorun'
3
+ require 'active_record'
4
+ require 'database_cleaner'
5
+
6
+ require 'fileutils'
7
+ FileUtils::mkdir_p '/tmp/uploads'
8
+
9
+ # ActiveRecord Connection
10
+ # ActiveRecord::Base.logger = Logger.new(STDERR)
11
+ ActiveRecord::Base.logger = false
12
+ ActiveRecord::Base.establish_connection(
13
+ adapter: "sqlite3",
14
+ database: ":memory:"
15
+ )
16
+
17
+ # Dot not show Active Record Migrations
18
+ ActiveRecord::Migration.verbose = false
19
+ ActiveRecord::Schema.define do
20
+ create_table :things do |table|
21
+ table.column :title, :string
22
+ table.column :active, :boolean, default: true
23
+ end
24
+
25
+ create_table(:bands) do |table|
26
+ table.column :name, :string
27
+ table.column :locality, :string
28
+ end
29
+ end
3
30
 
4
31
  module TmpUploads
5
32
  extend ActiveSupport::Concern
@@ -12,4 +39,19 @@ end
12
39
 
13
40
  MiniTest::Spec.class_eval do
14
41
  include TmpUploads
15
- end
42
+ end
43
+
44
+ # Database Cleaning
45
+ DatabaseCleaner.strategy = :transaction
46
+ DatabaseCleaner.clean_with(:truncation)
47
+
48
+ class MiniTest::Spec
49
+ before :each do
50
+ DatabaseCleaner.start
51
+ end
52
+
53
+ after :each do
54
+ DatabaseCleaner.clean
55
+ end
56
+ end
57
+
@@ -13,9 +13,9 @@ class UploadedFileTest < MiniTest::Spec
13
13
  }
14
14
 
15
15
  let (:upload) { ActionDispatch::Http::UploadedFile.new(
16
- :tempfile => tempfile,
17
- :filename => "apotomo.png",
18
- :type => "image/png")
16
+ tempfile: tempfile,
17
+ filename: "apotomo.png",
18
+ type: "image/png")
19
19
  }
20
20
 
21
21
  describe "#to_hash" do
@@ -69,7 +69,7 @@ class UploadedFileTest < MiniTest::Spec
69
69
  describe "with custom tmp directory" do
70
70
  describe "#to_hash" do
71
71
  before {
72
- @uploaded = Trailblazer::Operation::UploadedFile.new(upload, :tmp_dir => tmp_dir)
72
+ @uploaded = Trailblazer::Operation::UploadedFile.new(upload, tmp_dir: tmp_dir)
73
73
  @subject = @uploaded.to_hash[:tempfile_path]
74
74
  }
75
75
 
data/test/worker_test.rb CHANGED
@@ -28,7 +28,7 @@ class WorkerTest < MiniTest::Spec
28
28
 
29
29
  # test basic worker functionality.
30
30
  describe "with sidekiq" do
31
- before { @res = Operation.run(:title => "Dragonfly") }
31
+ before { @res = Operation.run(title: "Dragonfly") }
32
32
 
33
33
  it { @res.kind_of?(String).must_equal true } # for now, we return the job from sidekiq.
34
34
  it { Operation.jobs[0]["args"].must_equal([{"title"=>"Dragonfly"}]) }
@@ -36,7 +36,7 @@ class WorkerTest < MiniTest::Spec
36
36
  end
37
37
 
38
38
  # without sidekiq, we don't have indifferent_access automatically.
39
- it { NoBackgroundOperation.run(:title => "Dragonfly").must_equal "I was working hard on {:title=>\"Dragonfly\"}. title:Dragonfly \"title\"=>" }
39
+ it { NoBackgroundOperation.run(title: "Dragonfly").must_equal "I was working hard on {:title=>\"Dragonfly\"}. title:Dragonfly \"title\"=>" }
40
40
 
41
41
 
42
42
  # test manual serialisation (to be done with UploadedFile etc automatically).
@@ -44,7 +44,7 @@ class WorkerTest < MiniTest::Spec
44
44
  include Worker
45
45
 
46
46
  def self.serializable(params)
47
- {:wrap => params}
47
+ {wrap: params}
48
48
  end
49
49
 
50
50
  def deserializable(params)
@@ -53,7 +53,7 @@ class WorkerTest < MiniTest::Spec
53
53
  end
54
54
 
55
55
  describe "with serialization in sidekiq" do
56
- before { @res = SerializingOperation.run(:title => "Dragonfly") }
56
+ before { @res = SerializingOperation.run(title: "Dragonfly") }
57
57
 
58
58
  it { @res.kind_of?(String).must_equal true } # for now, we return the job from sidekiq.
59
59
  it { SerializingOperation.jobs[0]["args"].must_equal([{"wrap"=>{"title"=>"Dragonfly"}}]) }
@@ -68,9 +68,9 @@ class WorkerFileMarshallerTest < MiniTest::Spec
68
68
  tmp.write File.open("test/fixtures/#{name}").read
69
69
 
70
70
  ActionDispatch::Http::UploadedFile.new(
71
- :tempfile => tmp,
72
- :filename => name,
73
- :type => "image/png")
71
+ tempfile: tmp,
72
+ filename: name,
73
+ type: "image/png")
74
74
  end
75
75
 
76
76
  class Operation < Trailblazer::Operation
@@ -87,8 +87,10 @@ class WorkerFileMarshallerTest < MiniTest::Spec
87
87
  include Worker::FileMarshaller # should be ContractFileMarshaller
88
88
 
89
89
  def process(params)
90
- params
90
+ @params = params
91
91
  end
92
+
93
+ attr_reader :params
92
94
  end
93
95
 
94
96
  # TODO: no image
@@ -104,7 +106,9 @@ class WorkerFileMarshallerTest < MiniTest::Spec
104
106
 
105
107
  args["album"]["image"]["filename"].must_equal "cells.png"
106
108
 
107
- _, params = Operation.perform_one # deserialize.
109
+ _, op = Operation.perform_one # deserialize.
110
+
111
+ params = op.params
108
112
 
109
113
  params["title"].must_equal("Dragonfly")
110
114
  params[:title].must_equal("Dragonfly") # must allow indifferent_access.
data/trailblazer.gemspec CHANGED
@@ -20,14 +20,18 @@ Gem::Specification.new do |spec|
20
20
 
21
21
  spec.add_dependency "actionpack", '>= 3.0.0' # this framework works on Rails.
22
22
  spec.add_dependency "uber", ">= 0.0.10" # no builder inheritance.
23
- spec.add_dependency "representable", ">= 2.1.1", "<2.2.0" # Representable::apply.
24
- spec.add_dependency "reform", "~> 1.2.0"
23
+ # spec.add_dependency "representable", ">= 2.1.1", "<2.3.0" # Representable::apply.
24
+ spec.add_dependency "reform", ">= 1.2.0"
25
25
 
26
- spec.add_development_dependency "bundler", "~> 1.3"
26
+ spec.add_development_dependency "bundler"
27
27
  spec.add_development_dependency "rake"
28
28
  spec.add_development_dependency "minitest"
29
29
  # spec.add_development_dependency "minitest-spec-rails" # TODO: can anyone make this work (test/rails).
30
30
  spec.add_development_dependency "sidekiq", "~> 3.1.0"
31
31
  spec.add_development_dependency "rails"
32
32
  spec.add_development_dependency "sqlite3"
33
+ spec.add_development_dependency "responders"
34
+ spec.add_development_dependency "database_cleaner"
35
+
36
+ spec.add_development_dependency "roar"
33
37
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: trailblazer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nick Sutterer
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-01-22 00:00:00.000000000 Z
11
+ date: 2015-06-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: actionpack
@@ -38,54 +38,34 @@ dependencies:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: 0.0.10
41
- - !ruby/object:Gem::Dependency
42
- name: representable
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - ">="
46
- - !ruby/object:Gem::Version
47
- version: 2.1.1
48
- - - "<"
49
- - !ruby/object:Gem::Version
50
- version: 2.2.0
51
- type: :runtime
52
- prerelease: false
53
- version_requirements: !ruby/object:Gem::Requirement
54
- requirements:
55
- - - ">="
56
- - !ruby/object:Gem::Version
57
- version: 2.1.1
58
- - - "<"
59
- - !ruby/object:Gem::Version
60
- version: 2.2.0
61
41
  - !ruby/object:Gem::Dependency
62
42
  name: reform
63
43
  requirement: !ruby/object:Gem::Requirement
64
44
  requirements:
65
- - - "~>"
45
+ - - ">="
66
46
  - !ruby/object:Gem::Version
67
47
  version: 1.2.0
68
48
  type: :runtime
69
49
  prerelease: false
70
50
  version_requirements: !ruby/object:Gem::Requirement
71
51
  requirements:
72
- - - "~>"
52
+ - - ">="
73
53
  - !ruby/object:Gem::Version
74
54
  version: 1.2.0
75
55
  - !ruby/object:Gem::Dependency
76
56
  name: bundler
77
57
  requirement: !ruby/object:Gem::Requirement
78
58
  requirements:
79
- - - "~>"
59
+ - - ">="
80
60
  - !ruby/object:Gem::Version
81
- version: '1.3'
61
+ version: '0'
82
62
  type: :development
83
63
  prerelease: false
84
64
  version_requirements: !ruby/object:Gem::Requirement
85
65
  requirements:
86
- - - "~>"
66
+ - - ">="
87
67
  - !ruby/object:Gem::Version
88
- version: '1.3'
68
+ version: '0'
89
69
  - !ruby/object:Gem::Dependency
90
70
  name: rake
91
71
  requirement: !ruby/object:Gem::Requirement
@@ -156,6 +136,48 @@ dependencies:
156
136
  - - ">="
157
137
  - !ruby/object:Gem::Version
158
138
  version: '0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: responders
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
153
+ - !ruby/object:Gem::Dependency
154
+ name: database_cleaner
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - ">="
158
+ - !ruby/object:Gem::Version
159
+ version: '0'
160
+ type: :development
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - ">="
165
+ - !ruby/object:Gem::Version
166
+ version: '0'
167
+ - !ruby/object:Gem::Dependency
168
+ name: roar
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - ">="
172
+ - !ruby/object:Gem::Version
173
+ version: '0'
174
+ type: :development
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - ">="
179
+ - !ruby/object:Gem::Version
180
+ version: '0'
159
181
  description: A high-level, modular architecture for Rails with domain and form objects,
160
182
  view models, twin decorators and representers.
161
183
  email:
@@ -179,21 +201,27 @@ files:
179
201
  - gemfiles/Gemfile.rails.lock
180
202
  - lib/trailblazer.rb
181
203
  - lib/trailblazer/autoloading.rb
204
+ - lib/trailblazer/endpoint.rb
182
205
  - lib/trailblazer/operation.rb
206
+ - lib/trailblazer/operation/collection.rb
183
207
  - lib/trailblazer/operation/controller.rb
184
208
  - lib/trailblazer/operation/controller/active_record.rb
185
209
  - lib/trailblazer/operation/crud.rb
210
+ - lib/trailblazer/operation/dispatch.rb
186
211
  - lib/trailblazer/operation/representer.rb
187
212
  - lib/trailblazer/operation/responder.rb
188
213
  - lib/trailblazer/operation/uploaded_file.rb
189
214
  - lib/trailblazer/operation/worker.rb
190
215
  - lib/trailblazer/rails/railtie.rb
191
216
  - lib/trailblazer/version.rb
217
+ - test/collection_test.rb
192
218
  - test/crud_test.rb
219
+ - test/dispatch_test.rb
193
220
  - test/fixtures/apotomo.png
194
221
  - test/fixtures/cells.png
195
222
  - test/operation_test.rb
196
223
  - test/rails/controller_test.rb
224
+ - test/rails/endpoint_test.rb
197
225
  - test/rails/fake_app/app-cells/.gitkeep
198
226
  - test/rails/fake_app/cells.rb
199
227
  - test/rails/fake_app/config.rb
@@ -201,10 +229,14 @@ files:
201
229
  - test/rails/fake_app/models.rb
202
230
  - test/rails/fake_app/rails_app.rb
203
231
  - test/rails/fake_app/song/operations.rb
232
+ - test/rails/fake_app/views/bands/index.html.erb
204
233
  - test/rails/fake_app/views/bands/show.html.erb
234
+ - test/rails/fake_app/views/songs/another_view.html.erb
205
235
  - test/rails/fake_app/views/songs/new.html.erb
206
236
  - test/rails/test_helper.rb
237
+ - test/representer_test.rb
207
238
  - test/responder_test.rb
239
+ - test/rollback_test.rb
208
240
  - test/test_helper.rb
209
241
  - test/uploaded_file_test.rb
210
242
  - test/worker_test.rb
@@ -229,16 +261,19 @@ required_rubygems_version: !ruby/object:Gem::Requirement
229
261
  version: '0'
230
262
  requirements: []
231
263
  rubyforge_project:
232
- rubygems_version: 2.2.2
264
+ rubygems_version: 2.4.8
233
265
  signing_key:
234
266
  specification_version: 4
235
267
  summary: A new architecture for Rails.
236
268
  test_files:
269
+ - test/collection_test.rb
237
270
  - test/crud_test.rb
271
+ - test/dispatch_test.rb
238
272
  - test/fixtures/apotomo.png
239
273
  - test/fixtures/cells.png
240
274
  - test/operation_test.rb
241
275
  - test/rails/controller_test.rb
276
+ - test/rails/endpoint_test.rb
242
277
  - test/rails/fake_app/app-cells/.gitkeep
243
278
  - test/rails/fake_app/cells.rb
244
279
  - test/rails/fake_app/config.rb
@@ -246,10 +281,14 @@ test_files:
246
281
  - test/rails/fake_app/models.rb
247
282
  - test/rails/fake_app/rails_app.rb
248
283
  - test/rails/fake_app/song/operations.rb
284
+ - test/rails/fake_app/views/bands/index.html.erb
249
285
  - test/rails/fake_app/views/bands/show.html.erb
286
+ - test/rails/fake_app/views/songs/another_view.html.erb
250
287
  - test/rails/fake_app/views/songs/new.html.erb
251
288
  - test/rails/test_helper.rb
289
+ - test/representer_test.rb
252
290
  - test/responder_test.rb
291
+ - test/rollback_test.rb
253
292
  - test/test_helper.rb
254
293
  - test/uploaded_file_test.rb
255
294
  - test/worker_test.rb