diff --git a/test/docs/suite_test.rb b/test/docs/suite_test.rb index 242f955..1b33d75 100644 --- a/test/docs/suite_test.rb +++ b/test/docs/suite_test.rb @@ -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 %{#["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 %{#} - - 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 %{#[\"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 %{#} - 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 %{#} - 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 %{#}, 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 %{#}, 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 %{{:title=>\"Timebomb\", :band=>\"Rancid\"}, :current_user=>\"Lola\"} mutable_options={:model=>#}> >}, - 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 %{#}, 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 %{#[\"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 diff --git a/test/suite_test.rb b/test/suite_test.rb index 0d6d277..8ba8585 100644 --- a/test/suite_test.rb +++ b/test/suite_test.rb @@ -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