trailblazer 2.0.7 → 2.1.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 +5 -5
- data/.gitignore +1 -0
- data/.rubocop-https---raw-githubusercontent-com-trailblazer-meta-master-rubocop-yml +101 -0
- data/.rubocop.yml +20 -0
- data/.rubocop_todo.yml +556 -0
- data/.travis.yml +6 -10
- data/CHANGES.md +83 -1
- data/COMM-LICENSE +46 -75
- data/CONTRIBUTING.md +179 -0
- data/Gemfile +0 -27
- data/{LICENSE.txt → LICENSE} +4 -4
- data/README.md +39 -138
- data/Rakefile +2 -19
- data/lib/trailblazer.rb +3 -17
- data/lib/trailblazer/version.rb +3 -1
- data/test/test_helper.rb +12 -3
- data/trailblazer.gemspec +10 -14
- metadata +22 -147
- data/doc/Trb-The-Stack.png +0 -0
- data/doc/operation-2017.png +0 -0
- data/doc/trb.jpg +0 -0
- data/lib/trailblazer/dsl.rb +0 -47
- data/lib/trailblazer/operation/auto_inject.rb +0 -47
- data/lib/trailblazer/operation/callback.rb +0 -35
- data/lib/trailblazer/operation/contract.rb +0 -46
- data/lib/trailblazer/operation/guard.rb +0 -18
- data/lib/trailblazer/operation/model.rb +0 -60
- data/lib/trailblazer/operation/module.rb +0 -29
- data/lib/trailblazer/operation/nested.rb +0 -113
- data/lib/trailblazer/operation/persist.rb +0 -10
- data/lib/trailblazer/operation/policy.rb +0 -35
- data/lib/trailblazer/operation/procedural/contract.rb +0 -15
- data/lib/trailblazer/operation/procedural/validate.rb +0 -22
- data/lib/trailblazer/operation/pundit.rb +0 -38
- data/lib/trailblazer/operation/representer.rb +0 -31
- data/lib/trailblazer/operation/rescue.rb +0 -21
- data/lib/trailblazer/operation/test.rb +0 -17
- data/lib/trailblazer/operation/validate.rb +0 -68
- data/lib/trailblazer/operation/wrap.rb +0 -25
- data/test/docs/auto_inject_test.rb +0 -30
- data/test/docs/contract_test.rb +0 -525
- data/test/docs/dry_test.rb +0 -31
- data/test/docs/fast_test.rb +0 -164
- data/test/docs/guard_test.rb +0 -169
- data/test/docs/macro_test.rb +0 -36
- data/test/docs/model_test.rb +0 -75
- data/test/docs/nested_test.rb +0 -334
- data/test/docs/operation_test.rb +0 -408
- data/test/docs/policy_test.rb +0 -2
- data/test/docs/pundit_test.rb +0 -133
- data/test/docs/representer_test.rb +0 -268
- data/test/docs/rescue_test.rb +0 -154
- data/test/docs/wrap_test.rb +0 -183
- data/test/gemfiles/Gemfile.ruby-1.9 +0 -3
- data/test/gemfiles/Gemfile.ruby-2.0 +0 -12
- data/test/gemfiles/Gemfile.ruby-2.3 +0 -12
- data/test/module_test.rb +0 -100
- data/test/operation/callback_test.rb +0 -70
- data/test/operation/contract_test.rb +0 -420
- data/test/operation/dsl/callback_test.rb +0 -106
- data/test/operation/dsl/contract_test.rb +0 -294
- data/test/operation/dsl/representer_test.rb +0 -169
- data/test/operation/model_test.rb +0 -60
- data/test/operation/params_test.rb +0 -36
- data/test/operation/persist_test.rb +0 -44
- data/test/operation/pipedream_test.rb +0 -59
- data/test/operation/pipetree_test.rb +0 -104
- data/test/operation/present_test.rb +0 -24
- data/test/operation/pundit_test.rb +0 -104
- data/test/operation/representer_test.rb +0 -254
- data/test/operation/resolver_test.rb +0 -47
- data/test/operation_test.rb +0 -143
data/test/docs/dry_test.rb
DELETED
@@ -1,31 +0,0 @@
|
|
1
|
-
require "test_helper"
|
2
|
-
require "dry/container"
|
3
|
-
|
4
|
-
class DryContainerTest < Minitest::Spec
|
5
|
-
Song = Struct.new(:id, :title)
|
6
|
-
|
7
|
-
class MyContract < Reform::Form
|
8
|
-
property :title
|
9
|
-
validates :title, length: 2..33
|
10
|
-
end
|
11
|
-
|
12
|
-
my_container = Dry::Container.new
|
13
|
-
my_container.register("contract.default.class", MyContract)
|
14
|
-
# my_container.namespace("contract") do
|
15
|
-
# register("create") { Array }
|
16
|
-
# end
|
17
|
-
|
18
|
-
#---
|
19
|
-
#- dependency injection
|
20
|
-
#- with Dry-container
|
21
|
-
class Create < Trailblazer::Operation
|
22
|
-
step Model( Song, :new )
|
23
|
-
step Contract::Build()
|
24
|
-
step Contract::Validate()
|
25
|
-
step Contract::Persist( method: :sync )
|
26
|
-
end
|
27
|
-
#:key end
|
28
|
-
|
29
|
-
it { Create.({ title: "A" }, {}, my_container).inspect("model").must_equal %{<Result:false [#<struct DryContainerTest::Song id=nil, title=nil>] >} }
|
30
|
-
it { Create.({ title: "Anthony's Song" }, {}, my_container).inspect("model").must_equal %{<Result:true [#<struct DryContainerTest::Song id=nil, title="Anthony's Song">] >} }
|
31
|
-
end
|
data/test/docs/fast_test.rb
DELETED
@@ -1,164 +0,0 @@
|
|
1
|
-
require "test_helper"
|
2
|
-
|
3
|
-
class DocsFailFastOptionTest < Minitest::Spec
|
4
|
-
Song = Struct.new(:id, :title) do
|
5
|
-
def self.find_by(id); nil end
|
6
|
-
end
|
7
|
-
|
8
|
-
class MyContract < Reform::Form
|
9
|
-
end
|
10
|
-
|
11
|
-
|
12
|
-
#:ffopt
|
13
|
-
class Update < Trailblazer::Operation
|
14
|
-
step Model( Song, :find_by )
|
15
|
-
failure :abort!, fail_fast: true
|
16
|
-
step Contract::Build( constant: MyContract )
|
17
|
-
step Contract::Validate( )
|
18
|
-
failure :handle_invalid_contract! # won't be executed if #abort! is executed.
|
19
|
-
|
20
|
-
def abort!(options, params:, **)
|
21
|
-
options["result.model.song"] = "Something went wrong with ID #{params[:id]}!"
|
22
|
-
end
|
23
|
-
# ..
|
24
|
-
end
|
25
|
-
#:ffopt end
|
26
|
-
|
27
|
-
it { Update.(id: 1).inspect("result.model.song", "contract.default").must_equal %{<Result:false [\"Something went wrong with ID 1!\", nil] >} }
|
28
|
-
it do
|
29
|
-
#:ffopt-res
|
30
|
-
result = Update.(id: 1)
|
31
|
-
result["result.model.song"] #=> "Something went wrong with ID 1!"
|
32
|
-
#:ffopt-res end
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
class DocsFailFastOptionWithStepTest < Minitest::Spec
|
37
|
-
Song = Class.new do
|
38
|
-
def self.find_by(*); Object end
|
39
|
-
end
|
40
|
-
|
41
|
-
#:ffopt-step
|
42
|
-
class Update < Trailblazer::Operation
|
43
|
-
step :empty_id?, fail_fast: true
|
44
|
-
step Model( Song, :find_by )
|
45
|
-
failure :handle_empty_db! # won't be executed if #empty_id? returns falsey.
|
46
|
-
|
47
|
-
def empty_id?(options, params:, **)
|
48
|
-
params[:id] # returns false if :id missing.
|
49
|
-
end
|
50
|
-
end
|
51
|
-
#:ffopt-step end
|
52
|
-
|
53
|
-
it { Update.({ id: nil }).inspect("model").must_equal %{<Result:false [nil] >} }
|
54
|
-
it { Update.({ id: 1 }).inspect("model").must_equal %{<Result:true [Object] >} }
|
55
|
-
it do
|
56
|
-
#:ffopt-step-res
|
57
|
-
result = Update.({ id: nil })
|
58
|
-
|
59
|
-
result.failure? #=> true
|
60
|
-
result["model"] #=> nil
|
61
|
-
#:ffopt-step-res end
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
class DocsPassFastWithStepOptionTest < Minitest::Spec
|
66
|
-
Song = Struct.new(:id, :title) do
|
67
|
-
def self.find_by(id); nil end
|
68
|
-
end
|
69
|
-
|
70
|
-
class MyContract < Reform::Form
|
71
|
-
end
|
72
|
-
|
73
|
-
#:pfopt-step
|
74
|
-
class Update < Trailblazer::Operation
|
75
|
-
step Model( Song, :find_by )
|
76
|
-
failure :abort!, fail_fast: true
|
77
|
-
step Contract::Build( constant: MyContract )
|
78
|
-
step Contract::Validate( )
|
79
|
-
failure :handle_invalid_contract! # won't be executed if #abort! is executed.
|
80
|
-
|
81
|
-
def abort!(options, params:, **)
|
82
|
-
options["result.model.song"] = "Something went wrong with ID #{params[:id]}!"
|
83
|
-
end
|
84
|
-
# ..
|
85
|
-
end
|
86
|
-
#:pfopt-step end
|
87
|
-
|
88
|
-
it { Update.(id: 1).inspect("result.model.song", "contract.default").must_equal %{<Result:false [\"Something went wrong with ID 1!\", nil] >} }
|
89
|
-
it do
|
90
|
-
#:pfopt-step-res
|
91
|
-
result = Update.(id: 1)
|
92
|
-
result["result.model.song"] #=> "Something went wrong with ID 1!"
|
93
|
-
#:pfopt-step-res end
|
94
|
-
end
|
95
|
-
end
|
96
|
-
|
97
|
-
class DocsFailFastMethodTest < Minitest::Spec
|
98
|
-
Song = Struct.new(:id, :title) do
|
99
|
-
def self.find_by(id); nil end
|
100
|
-
end
|
101
|
-
|
102
|
-
#:ffmeth
|
103
|
-
class Update < Trailblazer::Operation
|
104
|
-
step :filter_params! # emits fail_fast!
|
105
|
-
step Model( Song, :find_by )
|
106
|
-
failure :handle_fail!
|
107
|
-
|
108
|
-
def filter_params!(options, params:, **)
|
109
|
-
unless params[:id]
|
110
|
-
options["result.params"] = "No ID in params!"
|
111
|
-
return Railway.fail_fast!
|
112
|
-
end
|
113
|
-
end
|
114
|
-
|
115
|
-
def handle_fail!(options, **)
|
116
|
-
options["my.status"] = "Broken!"
|
117
|
-
end
|
118
|
-
end
|
119
|
-
#:ffmeth end
|
120
|
-
|
121
|
-
it { Update.({}).inspect("result.params", "my.status").must_equal %{<Result:false [\"No ID in params!\", nil] >} }
|
122
|
-
it do
|
123
|
-
#:ffmeth-res
|
124
|
-
result = Update.(id: 1)
|
125
|
-
result["result.params"] #=> "No ID in params!"
|
126
|
-
result["my.status"] #=> nil
|
127
|
-
#:ffmeth-res end
|
128
|
-
end
|
129
|
-
end
|
130
|
-
|
131
|
-
class DocsPassFastMethodTest < Minitest::Spec
|
132
|
-
Song = Struct.new(:id, :title) do
|
133
|
-
def save; end
|
134
|
-
end
|
135
|
-
|
136
|
-
class MyContract < Reform::Form
|
137
|
-
end
|
138
|
-
|
139
|
-
#:pfmeth
|
140
|
-
class Create < Trailblazer::Operation
|
141
|
-
step Model( Song, :new )
|
142
|
-
step :empty_model! # emits pass_fast!
|
143
|
-
step Contract::Build( constant: MyContract )
|
144
|
-
# ..
|
145
|
-
|
146
|
-
def empty_model!(options, is_empty:, model:, **)
|
147
|
-
return unless is_empty
|
148
|
-
model.save
|
149
|
-
Railway.pass_fast!
|
150
|
-
end
|
151
|
-
end
|
152
|
-
#:pfmeth end
|
153
|
-
|
154
|
-
it { Create.({ title: "Tyrant"}, "is_empty" => true).inspect("model").must_equal %{<Result:true [#<struct DocsPassFastMethodTest::Song id=nil, title=nil>] >} }
|
155
|
-
it do
|
156
|
-
#:pfmeth-res
|
157
|
-
result = Create.({}, "is_empty" => true)
|
158
|
-
result["model"] #=> #<Song id=nil, title=nil>
|
159
|
-
#:pfmeth-res end
|
160
|
-
end
|
161
|
-
end
|
162
|
-
|
163
|
-
# fail!
|
164
|
-
# pass!
|
data/test/docs/guard_test.rb
DELETED
@@ -1,169 +0,0 @@
|
|
1
|
-
require "test_helper"
|
2
|
-
|
3
|
-
#--
|
4
|
-
# with proc
|
5
|
-
class DocsGuardProcTest < Minitest::Spec
|
6
|
-
# test without KWs, only options.
|
7
|
-
class Update < Trailblazer::Operation
|
8
|
-
step Policy::Guard( ->(options) { options["params"][:pass] } )
|
9
|
-
step ->(options, *) { options["x"] = true }
|
10
|
-
end
|
11
|
-
|
12
|
-
it { Update.(pass: false)["x"].must_equal nil }
|
13
|
-
it { Update.(pass: true)["x"].must_equal true }
|
14
|
-
# TODO: test excp when current_user not available
|
15
|
-
|
16
|
-
#:proc
|
17
|
-
class Create < Trailblazer::Operation
|
18
|
-
step Policy::Guard( ->(options, params:, **) { params[:pass] } )
|
19
|
-
#~pipeonly
|
20
|
-
step :process
|
21
|
-
|
22
|
-
def process(*)
|
23
|
-
self["x"] = true
|
24
|
-
end
|
25
|
-
#~pipeonly end
|
26
|
-
end
|
27
|
-
#:proc end
|
28
|
-
|
29
|
-
it { Create.(pass: false)["x"].must_equal nil }
|
30
|
-
it { Create.(pass: true)["x"].must_equal true }
|
31
|
-
|
32
|
-
#- result object, guard
|
33
|
-
it { Create.(pass: true)["result.policy.default"].success?.must_equal true }
|
34
|
-
it { Create.(pass: false)["result.policy.default"].success?.must_equal false }
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
#---
|
40
|
-
#- Guard inheritance
|
41
|
-
class New < Create
|
42
|
-
step Policy::Guard( ->(options, current_user:, **) { current_user } ), override: true
|
43
|
-
end
|
44
|
-
|
45
|
-
it { New["pipetree"].inspect.must_equal %{[>operation.new,>policy.default.eval,>process]} }
|
46
|
-
end
|
47
|
-
|
48
|
-
#---
|
49
|
-
# with Callable
|
50
|
-
class DocsGuardTest < Minitest::Spec
|
51
|
-
#:callable
|
52
|
-
class MyGuard
|
53
|
-
include Uber::Callable
|
54
|
-
|
55
|
-
def call(options, params:, **)
|
56
|
-
params[:pass]
|
57
|
-
end
|
58
|
-
end
|
59
|
-
#:callable end
|
60
|
-
|
61
|
-
#:callable-op
|
62
|
-
class Create < Trailblazer::Operation
|
63
|
-
step Policy::Guard( MyGuard.new )
|
64
|
-
#~pipe-only
|
65
|
-
step :process
|
66
|
-
def process(*); self[:x] = true; end
|
67
|
-
#~pipe-only end
|
68
|
-
end
|
69
|
-
#:callable-op end
|
70
|
-
|
71
|
-
it { Create.(pass: false)[:x].must_equal nil }
|
72
|
-
it { Create.(pass: true)[:x].must_equal true }
|
73
|
-
end
|
74
|
-
|
75
|
-
#---
|
76
|
-
# with method
|
77
|
-
class DocsGuardMethodTest < Minitest::Spec
|
78
|
-
#:method
|
79
|
-
class Create < Trailblazer::Operation
|
80
|
-
step Policy::Guard( :pass? )
|
81
|
-
|
82
|
-
def pass?(options, params:, **)
|
83
|
-
params[:pass]
|
84
|
-
end
|
85
|
-
#~pipe-onlyy
|
86
|
-
step :process
|
87
|
-
def process(*); self["x"] = true; end
|
88
|
-
#~pipe-onlyy end
|
89
|
-
end
|
90
|
-
#:method end
|
91
|
-
|
92
|
-
it { Create.(pass: false).inspect("x").must_equal %{<Result:false [nil] >} }
|
93
|
-
it { Create.(pass: true).inspect("x").must_equal %{<Result:true [true] >} }
|
94
|
-
end
|
95
|
-
|
96
|
-
#---
|
97
|
-
# with name:
|
98
|
-
class DocsGuardNamedTest < Minitest::Spec
|
99
|
-
#:name
|
100
|
-
class Create < Trailblazer::Operation
|
101
|
-
step Policy::Guard( ->(options, current_user:, **) { current_user }, name: :user )
|
102
|
-
# ...
|
103
|
-
end
|
104
|
-
#:name end
|
105
|
-
|
106
|
-
it { Create.({}, "current_user" => nil )["result.policy.user"].success?.must_equal false }
|
107
|
-
it { Create.({}, "current_user" => Module)["result.policy.user"].success?.must_equal true }
|
108
|
-
|
109
|
-
it {
|
110
|
-
#:name-result
|
111
|
-
result = Create.({}, "current_user" => true)
|
112
|
-
result["result.policy.user"].success? #=> true
|
113
|
-
#:name-result end
|
114
|
-
}
|
115
|
-
end
|
116
|
-
|
117
|
-
#---
|
118
|
-
# dependency injection
|
119
|
-
class DocsGuardInjectionTest < Minitest::Spec
|
120
|
-
#:di-op
|
121
|
-
class Create < Trailblazer::Operation
|
122
|
-
step Policy::Guard( ->(options, current_user:, **) { current_user == Module } )
|
123
|
-
end
|
124
|
-
#:di-op end
|
125
|
-
|
126
|
-
it { Create.({}, "current_user" => Module).inspect("").must_equal %{<Result:true [nil] >} }
|
127
|
-
it {
|
128
|
-
result =
|
129
|
-
#:di-call
|
130
|
-
Create.({},
|
131
|
-
"current_user" => Module,
|
132
|
-
"policy.default.eval" => Trailblazer::Operation::Policy::Guard.build(->(options) { false })
|
133
|
-
)
|
134
|
-
#:di-call end
|
135
|
-
result.inspect("").must_equal %{<Result:false [nil] >} }
|
136
|
-
end
|
137
|
-
|
138
|
-
#---
|
139
|
-
# missing current_user throws exception
|
140
|
-
class DocsGuardMissingKeywordTest < Minitest::Spec
|
141
|
-
class Create < Trailblazer::Operation
|
142
|
-
step Policy::Guard( ->(options, current_user:, **) { current_user == Module } )
|
143
|
-
end
|
144
|
-
|
145
|
-
it { assert_raises(ArgumentError) { Create.() } }
|
146
|
-
it { Create.({}, "current_user" => Module).success?.must_equal true }
|
147
|
-
end
|
148
|
-
|
149
|
-
#---
|
150
|
-
# before:
|
151
|
-
class DocsGuardPositionTest < Minitest::Spec
|
152
|
-
#:before
|
153
|
-
class Create < Trailblazer::Operation
|
154
|
-
step :model!
|
155
|
-
step Policy::Guard( :authorize! ),
|
156
|
-
before: :model!
|
157
|
-
end
|
158
|
-
#:before end
|
159
|
-
|
160
|
-
it { Create["pipetree"].inspect.must_equal %{[>operation.new,>policy.default.eval,>model!]} }
|
161
|
-
it do
|
162
|
-
#:before-pipe
|
163
|
-
puts Create["pipetree"].inspect(style: :rows) #=>
|
164
|
-
# 0 ========================>operation.new
|
165
|
-
# 1 ==================>policy.default.eval
|
166
|
-
# 2 ===============================>model!
|
167
|
-
#:before-pipe end
|
168
|
-
end
|
169
|
-
end
|
data/test/docs/macro_test.rb
DELETED
@@ -1,36 +0,0 @@
|
|
1
|
-
require "test_helper"
|
2
|
-
|
3
|
-
class DocsMacroTest < Minitest::Spec
|
4
|
-
#:simple
|
5
|
-
module Macro
|
6
|
-
def self.MyPolicy(allowed_role: "admin")
|
7
|
-
step = ->(input, options) { options["current_user"].type == allowed_role }
|
8
|
-
|
9
|
-
[ step, name: "my_policy.#{allowed_role}" ] # :before, :replace, etc. work, too.
|
10
|
-
end
|
11
|
-
end
|
12
|
-
#:simple end
|
13
|
-
|
14
|
-
#:simple-op
|
15
|
-
class Create < Trailblazer::Operation
|
16
|
-
step Macro::MyPolicy( allowed_role: "manager" )
|
17
|
-
# ..
|
18
|
-
end
|
19
|
-
#:simple-op end
|
20
|
-
|
21
|
-
=begin
|
22
|
-
it do
|
23
|
-
#:simple-pipe
|
24
|
-
puts Create["pipetree"].inspect(style: :rows) #=>
|
25
|
-
0 ========================>operation.new
|
26
|
-
1 ====================>my_policy.manager
|
27
|
-
#:simple-pipe end
|
28
|
-
end
|
29
|
-
=end
|
30
|
-
|
31
|
-
it { Create["pipetree"].inspect.must_equal %{[>operation.new,>my_policy.manager]} }
|
32
|
-
end
|
33
|
-
|
34
|
-
# injectable option
|
35
|
-
# nested pipe
|
36
|
-
# using macros in macros
|
data/test/docs/model_test.rb
DELETED
@@ -1,75 +0,0 @@
|
|
1
|
-
require "test_helper"
|
2
|
-
|
3
|
-
class DocsModelTest < Minitest::Spec
|
4
|
-
Song = Struct.new(:id, :title) do
|
5
|
-
def self.find_by(id:nil)
|
6
|
-
id.nil? ? nil : new(id)
|
7
|
-
end
|
8
|
-
|
9
|
-
def self.[](id)
|
10
|
-
id.nil? ? nil : new(id+99)
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
#:op
|
15
|
-
class Create < Trailblazer::Operation
|
16
|
-
step Model( Song, :new )
|
17
|
-
# ..
|
18
|
-
end
|
19
|
-
#:op end
|
20
|
-
|
21
|
-
it do
|
22
|
-
#:create
|
23
|
-
result = Create.({})
|
24
|
-
result["model"] #=> #<struct Song id=nil, title=nil>
|
25
|
-
#:create end
|
26
|
-
|
27
|
-
result["model"].inspect.must_equal %{#<struct DocsModelTest::Song id=nil, title=nil>}
|
28
|
-
end
|
29
|
-
|
30
|
-
#:update
|
31
|
-
class Update < Trailblazer::Operation
|
32
|
-
step Model( Song, :find_by )
|
33
|
-
# ..
|
34
|
-
end
|
35
|
-
#:update end
|
36
|
-
|
37
|
-
it do
|
38
|
-
#:update-ok
|
39
|
-
result = Update.({ id: 1 })
|
40
|
-
result["model"] #=> #<struct Song id=1, title="Roxanne">
|
41
|
-
#:update-ok end
|
42
|
-
|
43
|
-
result["model"].inspect.must_equal %{#<struct DocsModelTest::Song id=1, title=nil>}
|
44
|
-
end
|
45
|
-
|
46
|
-
it do
|
47
|
-
#:update-fail
|
48
|
-
result = Update.({})
|
49
|
-
result["model"] #=> nil
|
50
|
-
result.success? #=> false
|
51
|
-
#:update-fail end
|
52
|
-
|
53
|
-
result["model"].must_be_nil
|
54
|
-
result.success?.must_equal false
|
55
|
-
end
|
56
|
-
|
57
|
-
#:show
|
58
|
-
class Show < Trailblazer::Operation
|
59
|
-
step Model( Song, :[] )
|
60
|
-
# ..
|
61
|
-
end
|
62
|
-
#:show end
|
63
|
-
|
64
|
-
it do
|
65
|
-
result = Show.({ id: 1 })
|
66
|
-
|
67
|
-
#:show-ok
|
68
|
-
result = Show.({ id: 1 })
|
69
|
-
result["model"] #=> #<struct Song id=1, title="Roxanne">
|
70
|
-
#:show-ok end
|
71
|
-
|
72
|
-
result.success?.must_equal true
|
73
|
-
result["model"].inspect.must_equal %{#<struct DocsModelTest::Song id=100, title=nil>}
|
74
|
-
end
|
75
|
-
end
|