Skip to content

Commit

Permalink
all tests run.
Browse files Browse the repository at this point in the history
remove unit tests from docs, those are already covered.
  • Loading branch information
apotonick committed Jan 23, 2025
1 parent 2aa43e5 commit f7eb479
Show file tree
Hide file tree
Showing 2 changed files with 4 additions and 320 deletions.
319 changes: 0 additions & 319 deletions test/docs/suite_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -246,327 +246,8 @@ class Create < Trailblazer::Operation
assert_equal %{{:params=>{:content=>\"Stock up beer\", :duration=>999}, :current_user=>Module}}, Ctx({current_user: Module, params: {duration: 999}}, exclude: [:title]).inspect
end
end # SongOperation_OMIT_KEY_Test

class Test < Minitest::Spec
def call
run
@failures
end

Trailblazer::Test::Assertion.module!(self, suite: true)
end

it "gives colored error messages for {assert_pass} and {assert_fail}" do
test =
Class.new(Test) {
# What are we passing into the operation?
let(:default_ctx) do
{
params: {
song: { # Note the {song} key here!
band: "Rancid",
title: "Timebomb",
}
}
}
end

# What will the model look like after running the operation?
let(:expected_attributes) do
{
band: "Rancid",
title: "Timebomb",
}
end

let(:operation) { DocsSuiteAssertionsTest::Song::Operation::Create }
let(:key_in_params) { :song }

# Assertion fails since {:title} doesn't have errors set.
it { assert_fail( {band: ""}, [:band, :title] ) } #1

# 2) Assertion fails because {title}s don't match.
it { assert_pass( {title: "Ruby Soho"}, {title: "ruby soho"} ) }

# Assertion fails because validation error.
it { assert_pass( {band: ""}, {title: "Ruby Soho"} ) }

# Test if block is called
it do #4
assert_pass( {band: "Millencolin"}, {band: "Millencolin"} ) do |result|
@_m = result[:model].inspect
end
end

it do #5
assert_fail({band: ""}, [:band]) do |result|
assert_nil result[:model].title
@_m = result[:"contract.default"].errors.messages.inspect
end
end

# Test: Block shouldn't be called when assertions before failed.
it do #6
assert_pass( {band: "Millencolin"}, {band: "NOFX"} ) do |result|
@_m = result[:model].inspect
end
end

# Can we override all let() options?
# Do {assert_fail} and {assert_pass} both return {result}?
# Can we use OPs without `contract.errors`?
class Overrider < Trailblazer::Operation
step ->(ctx, params:, **) { ctx[:model] = Song.new(params[:band], params[:title], params[:duration]) }
step ->(ctx, **) { puts ctx.inspect;true }
step ->(ctx, model:, **) { model.band.size > 0 } # pseudo validation
fail ->(ctx, **) { ctx[:"contract.default"] = Struct.new(:errors).new(Struct.new(:messages).new({band: [1]})) }
end
it do #7
@result = assert_pass( {band: "NOFX"}, {band: "NOFX"}, operation: Overrider, key_in_params: false, expected_attributes: {title: "The Brews", duration: 99}, default_ctx: {params: {duration: 99, title: "The Brews"}} )
end
it do #8
@result = assert_fail?( {band: ""}, [:band], operation: Overrider, key_in_params: false, expected_attributes: {title: "The Brews", duration: 99}, default_ctx: {params: {duration: 99, title: "The Brews", band: "NOFX"}} )
end

# Allow passing injection variables etc.
it do #9
current_user = "Lola"
@result_1 = assert_pass( Ctx({current_user: current_user, params: {band: "Rancid"}}, key_in_params: false, default_ctx: {params: {title: "Timebomb"}}), {band: "Rancid"}, operation: Overrider, key_in_params: false )
end

# 10) Assertion errors because of valid input.
it { assert_fail( {band: "NOFX"}, {title: "The Brews"} ) }

# 11) We use wtf?
it { assert_pass?( {title: "Ruby Soho"}, {title: "Ruby Soho"} ) }
# 12) we DON'T use wtf?
it { assert_pass( {title: "Ruby Soho"}, {title: "Ruby Soho"} ) }
# 13) assert_fail uses wtf?
it { assert_fail?( {title: ""}, [:title] ) }
# 14) assert_fail DOESN'T use {wtf?} per default
it { assert_fail( {title: ""}, [:title] ) }

# 15) Assertion errors because errors don't match
it { assert_fail( {title: "Ruby Soho", band: nil}, {band: "here is an error"} ) }

# 16) {assert_pass} returns result
it { @result = assert_pass( {}, {} ) }
# 17) {assert_pass} with block returns result
it { @result = assert_pass( {}, {} ) { |result| assert result } }
# 18) {assert_fail} returns result
it { @result = assert_fail( {band: ""}, [:band] ) }
# 19) {assert_fail} with block returns result
it { @result = assert_fail( {band: ""}, [:band] ) { |result| assert result } }

# DISCUSS: do we want to allow this keyword interface for {#assert_pass}?
# # 20) {assert_pass} with expected_attributes as kwargs
# it { @result = assert_pass( {}, title: "Cocktails") }
# # 21) {assert_pass?} with wtf?
# it { @result = assert_pass?( {}, title: "Cocktails") }

} # Test

test_1 = test.new(:test_0001_anonymous)
failures = test_1.()

# {assert_fail} sees less errors than the user specified: The errors are colored.
failures[0].inspect.must_equal %{#<Minitest::Assertion: Actual contract errors: \e[33m{:band=>["must be filled"]}\e[0m.
Expected: [:band, :title]
Actual: [:band]>}

assert_equal 1, failures.size





test_2 = test.new(:test_0002_anonymous)
failures = test_2.()

# {assert_pass} complains because {title} doesn't match
failures[0].inspect.must_equal %{#<Minitest::Assertion: Property [title] mismatch.
Expected: "ruby soho"
Actual: "Ruby Soho">}

assert_equal 1, failures.size






test_3 = test.new(:test_0003_anonymous)
failures = test_3.()

# {assert_pass} complains because {title} doesn't match
failures[0].inspect.must_equal %{#<Minitest::Assertion: {Trailblazer::Test::Testing::Song::Operation::Create} failed: \e[33m{:band=>[\"must be filled\"]}\e[0m.
Expected: true
Actual: false>}



# You can see {ctx[:"contract.default"]} in the {#assert_pass} block.
test_4 = test.new(:test_0004_anonymous)
failures = test_4.()

failures[0].must_equal nil
test_4.instance_variable_get(:@_m).must_equal %{#<struct Trailblazer::Test::Testing::Song band=\"Millencolin\", title=\"Timebomb\", duration=nil>}
assert_equal 3, test_4.instance_variable_get(:@assertions)
# pass block is not run when assertion failed before
test_6 = test.new(:test_0006_anonymous)
failures = test_6.()
assert_equal 2, test_6.instance_variable_get(:@assertions)
failures[0].inspect.must_equal %{#<Minitest::Assertion: Property [band] mismatch.
Expected: "NOFX"
Actual: "Millencolin">}
assert_nil test_6.instance_variable_get(:@_m) # no block called.

# You can see {ctx[:"contract.default"]} in the {#assert_fail} block.
test_5 = test.new(:test_0005_anonymous)
failures = test_5.()

assert_nil failures[0]
assert_equal test_5.instance_variable_get(:@_m), %({:band=>[\"must be filled\"]})
assert_equal 3, test_5.instance_variable_get(:@assertions)

# Can we override all let() options?
test_7 = test.new(:test_0007_anonymous)
failures = test_7.()

assert_nil failures[0]
assert_equal 1, test_7.instance_variable_get(:@assertions)
assert_equal %{#<struct Trailblazer::Test::Testing::Song band=\"NOFX\", title=\"The Brews\", duration=99>}, test_7.instance_variable_get(:@result)[:model].inspect
# same for assert_fail
test_8 = test.new(:test_0008_anonymous)
failures = test_8.()

assert_equal %{nil}, failures[0].inspect
assert_equal 2, test_8.instance_variable_get(:@assertions)
assert_equal %{#<struct Trailblazer::Test::Testing::Song band=\"\", title=\"The Brews\", duration=99>}, test_8.instance_variable_get(:@result)[:model].inspect

test_9 = test.new(:test_0009_anonymous)
failures = test_9.()

assert_equal %{nil}, failures[0].inspect
assert_equal 1, test_9.instance_variable_get(:@assertions)
assert_equal %{<Result:true #<Trailblazer::Context::Container wrapped_options={:params=>{:title=>\"Timebomb\", :band=>\"Rancid\"}, :current_user=>\"Lola\"} mutable_options={:model=>#<struct Trailblazer::Test::Testing::Song band=\"Rancid\", title=\"Timebomb\", duration=nil>}> >},
test_9.instance_variable_get(:@result_1).inspect

# When the operation passes but it should fail.
test_10 = test.new(:test_0010_anonymous)
failures = test_10.()

assert_equal %{#<Minitest::Assertion: {Trailblazer::Test::Testing::Song::Operation::Create} didn't fail, it passed.
Expected: false
Actual: true>}, failures[0].inspect
assert_equal 1, test_10.instance_variable_get(:@assertions)
# assert_nil test_10.instance_variable_get(:@result_1)

# {assert_pass} uses wtf?.
test_11 = test.new(:test_0011_anonymous)
output = capture_io do
failures = test_11.()
end

assert_equal %(Trailblazer::Test::Testing::Song::Operation::Create
|-- \e[32mStart.default\e[0m
|-- \e[32mmodel.build\e[0m
|-- \e[32mcontract.build\e[0m
|-- contract.default.validate
| |-- \e[32mStart.default\e[0m
| |-- \e[32mcontract.default.params_extract\e[0m
| |-- \e[32mcontract.default.call\e[0m
| `-- End.success
|-- \e[32mparse_duration\e[0m
|-- \e[32mpersist.save\e[0m
`-- End.success
),
output.join("")
assert_nil failures[0]
assert_equal 1, test_11.instance_variable_get(:@assertions)
# {assert_pass} DOES NOT use wtf? per default.
test_12 = test.new(:test_0012_anonymous)
output = capture_io { failures = test_12.() }

assert_equal %{}, output.join("")
assert_nil failures[0]
assert_equal 1, test_12.instance_variable_get(:@assertions)
test_13 = test.new(:test_0013_anonymous)
output = capture_io { failures = test_13.() }

assert_equal %(Trailblazer::Test::Testing::Song::Operation::Create
|-- \e[32mStart.default\e[0m
|-- \e[32mmodel.build\e[0m
|-- \e[32mcontract.build\e[0m
|-- contract.default.validate
| |-- \e[32mStart.default\e[0m
| |-- \e[32mcontract.default.params_extract\e[0m
| |-- \e[33mcontract.default.call\e[0m
| `-- End.failure
`-- End.failure
), output.join("")
assert_nil failures[0]
assert_equal 2, test_13.instance_variable_get(:@assertions)
test_14 = test.new(:test_0014_anonymous)
output = capture_io { failures = test_14.() }

assert_equal %{}, output.join("")
assert_nil failures[0]
assert_equal 2, test_14.instance_variable_get(:@assertions)

test_15 = test.new(:test_0015_anonymous)
output = capture_io { failures = test_15.() }

assert_equal %{}, output.join("")
failures[0].inspect.must_equal %{#<Minitest::Assertion: Actual contract errors: \e[33m{:band=>[\"must be filled\"]}\e[0m.
Expected: {:band=>[\"here is an error\"]}
Actual: {:band=>[\"must be filled\"]}>}
assert_equal 2, test_14.instance_variable_get(:@assertions)

test_16 = test.new(:test_0016_anonymous)
output = capture_io { failures = test_16.() }
assert_equal %{}, output.join("")
assert_nil failures[0]
assert_equal 1, test_16.instance_variable_get(:@assertions)
assert_equal %{Trailblazer::Operation::Railway::Result}, test_16.instance_variable_get(:@result).class.inspect

test_17 = test.new(:test_0017_anonymous)
output = capture_io { failures = test_17.() }
assert_equal %{}, output.join("")
assert_nil failures[0]
assert_equal 2, test_17.instance_variable_get(:@assertions)
assert_equal %{Trailblazer::Operation::Railway::Result}, test_16.instance_variable_get(:@result).class.inspect

test_18 = test.new(:test_0018_anonymous)
output = capture_io { failures = test_18.() }
assert_equal %{}, output.join("")
assert_nil failures[0]
assert_equal 2, test_18.instance_variable_get(:@assertions)
assert_equal %{Trailblazer::Operation::Railway::Result}, test_18.instance_variable_get(:@result).class.inspect

test_19 = test.new(:test_0019_anonymous)
output = capture_io { failures = test_19.() }
assert_equal %{}, output.join("")
assert_nil failures[0]
assert_equal 3, test_19.instance_variable_get(:@assertions)
assert_equal %{Trailblazer::Operation::Railway::Result}, test_19.instance_variable_get(:@result).class.inspect

# DISCUSS: do we want to allow this keyword interface for {#assert_pass}?
# test_20 = test.new(:test_0020_anonymous)
# output = capture_io { failures = test_20.() }
# assert_equal %{}, output.join("")
# assert_nil failures[0]

# test_21 = test.new(:test_0021_anonymous)
# output = capture_io { failures = test_21.() }
# assert_equal %{}, output.join("")
# assert_nil failures[0]
end
end




# include Trailblazer::Test::Operation::PolicyAssertions

# #:policy_fail-block
Expand Down
5 changes: 4 additions & 1 deletion test/suite_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -343,10 +343,13 @@ def model(ctx, params:, **)
Nothing_configured_test = describe "you can use Suite without setting anything, by passing everything manually" do
# 01
# allows to pass the entire context without any automatic merging
# provides all class directives (let()) as options, like {:options}
it do
@result = assert_pass Ctx(Memo::VALID_INPUT, merge: false),
{title: "TODO", content: "Stock up beer"},
operation: Trailblazer::Test::Testing::Memo::Operation::Create, default_ctx: {}
operation: Trailblazer::Test::Testing::Memo::Operation::Create, default_ctx: {id: 1}

assert_equal @result[:model].id, 1 # test that {:default_ctx} is used.
end

# 02
Expand Down

0 comments on commit f7eb479

Please sign in to comment.