trailblazer 0.2.2 → 0.3.0

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