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.
- checksums.yaml +4 -4
- data/.travis.yml +1 -3
- data/CHANGES.md +33 -0
- data/Gemfile +4 -1
- data/README.md +171 -166
- data/Rakefile +10 -2
- data/gemfiles/Gemfile.rails.lock +42 -11
- data/lib/trailblazer/autoloading.rb +4 -3
- data/lib/trailblazer/endpoint.rb +40 -0
- data/lib/trailblazer/operation.rb +15 -8
- data/lib/trailblazer/operation/collection.rb +7 -0
- data/lib/trailblazer/operation/controller.rb +30 -22
- data/lib/trailblazer/operation/controller/active_record.rb +6 -2
- data/lib/trailblazer/operation/crud.rb +3 -5
- data/lib/trailblazer/operation/dispatch.rb +29 -0
- data/lib/trailblazer/operation/representer.rb +41 -5
- data/lib/trailblazer/operation/responder.rb +2 -2
- data/lib/trailblazer/operation/uploaded_file.rb +4 -4
- data/lib/trailblazer/operation/worker.rb +8 -10
- data/lib/trailblazer/rails/railtie.rb +10 -7
- data/lib/trailblazer/version.rb +1 -1
- data/test/collection_test.rb +56 -0
- data/test/crud_test.rb +23 -1
- data/test/dispatch_test.rb +63 -0
- data/test/operation_test.rb +84 -125
- data/test/rails/controller_test.rb +51 -0
- data/test/rails/endpoint_test.rb +86 -0
- data/test/rails/fake_app/cells.rb +2 -2
- data/test/rails/fake_app/config.rb +1 -1
- data/test/rails/fake_app/controllers.rb +27 -0
- data/test/rails/fake_app/models.rb +10 -1
- data/test/rails/fake_app/rails_app.rb +15 -1
- data/test/rails/fake_app/song/operations.rb +38 -2
- data/test/rails/fake_app/views/bands/index.html.erb +1 -0
- data/test/rails/fake_app/views/songs/another_view.html.erb +2 -0
- data/test/representer_test.rb +126 -0
- data/test/responder_test.rb +2 -4
- data/test/rollback_test.rb +47 -0
- data/test/test_helper.rb +43 -1
- data/test/uploaded_file_test.rb +4 -4
- data/test/worker_test.rb +13 -9
- data/trailblazer.gemspec +7 -3
- metadata +68 -29
data/test/responder_test.rb
CHANGED
@@ -10,8 +10,7 @@ class Song
|
|
10
10
|
include Responder
|
11
11
|
|
12
12
|
def process(params)
|
13
|
-
invalid!
|
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!
|
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
|
+
|
data/test/uploaded_file_test.rb
CHANGED
@@ -13,9 +13,9 @@ class UploadedFileTest < MiniTest::Spec
|
|
13
13
|
}
|
14
14
|
|
15
15
|
let (:upload) { ActionDispatch::Http::UploadedFile.new(
|
16
|
-
:
|
17
|
-
:
|
18
|
-
:
|
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, :
|
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(:
|
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(:
|
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
|
-
{:
|
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(:
|
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
|
-
:
|
72
|
-
:
|
73
|
-
:
|
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
|
-
_,
|
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.
|
24
|
-
spec.add_dependency "reform", "
|
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"
|
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.
|
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-
|
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: '
|
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: '
|
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.
|
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
|