icy-arctic-fox / spectator

Feature-rich testing framework for Crystal inspired by RSpec.
https://gitlab.com/arctic-fox/spectator
MIT License
101 stars 4 forks source link

stub method(arg1,arg2,...) syntax seems to no longer work in 0.10/master #36

Closed postmodern closed 2 years ago

postmodern commented 2 years ago

After upgrading to spectator 0.10 I noticed that the stub method(arg1, ...) syntax is now being confused as a method call.

Trying stub method(arg1,arg2) { true } gives me the same error, as well.

Spec

require "./spec_helper"
require "../src/command_kit/man"

Spectator.describe CommandKit::Man do
  module TestMan
    class TestCommand
      include CommandKit::Man
    end
  end

  let(command_class) { TestMan::TestCommand }

  subject { command_class.new }

  describe "#man" do
    mock TestMan::TestCommand do
      stub system(command, arg)
    end

    let(man_page) { "foo" }

    it "must call system() with the given man page" do
      expect(subject).to receive(:system).with("man", [man_page])

      subject.man(man_page)
    end

    context "when given the section: keyword argument" do
      let(section) { 7 }

      it "must call system() with the given section number and man page" do
        expect(subject).to receive(:system).with("man", [section.to_s, man_page])

        subject.man(man_page, section: section)
      end
    end
  end
end

Errror

 crystal spec spec/man_spec.cr  --error-trace
error in line 1
Error: while requiring "./spec/man_spec.cr"

In spec/man_spec.cr:4:11

 4 | Spectator.describe CommandKit::Man do
               ^-------
Error: expanding macro

In spec/man_spec.cr:4:1

 4 | Spectator.describe CommandKit::Man do
     ^
Error: expanding macro

There was a problem expanding macro 'describe'

Called macro defined in macro 'macro_140629716498624'

 46 | macro describe(description, *tags, **metadata, &block)

Which expanded to:

 >  1 |         class ::SpectatorTestContext
 >  2 |           describe(CommandKit::Man,  ) do
 >  3 |   module TestMan
 >  4 |     class TestCommand
 >  5 |       include CommandKit::Man
 >  6 |     end
 >  7 |   end
 >  8 |   let(command_class) do
 >  9 |     TestMan::TestCommand
 > 10 |   end
 > 11 |   subject do
 > 12 |     command_class.new
 > 13 |   end
 > 14 |   describe("#man") do
 > 15 |     mock(TestMan::TestCommand) do
 > 16 |       stub(system(command, arg))
 > 17 |     end
 > 18 |     let(man_page) do
 > 19 |       "foo"
 > 20 |     end
 > 21 |     it("must call system() with the given man page") do
 > 22 |       (expect(subject)).to((receive(:system)).with("man", [man_page]))
 > 23 |       subject.man(man_page)
 > 24 |     end
 > 25 |     context("when given the section: keyword argument") do
 > 26 |       let(section) do
 > 27 |         7
 > 28 |       end
 > 29 |       it("must call system() with the given section number and man page") do
 > 30 |         (expect(subject)).to((receive(:system)).with("man", [section.to_s, man_page]))
 > 31 |         subject.man(man_page, section: section)
 > 32 |       end
 > 33 |     end
 > 34 |   end
 > 35 | end
 > 36 |         end
 > 37 |       
Error: expanding macro

In spec/man_spec.cr:15:1

 15 | describe "#man" do
    ^-------
Error: expanding macro

In spec/man_spec.cr:22:1

 22 | it "must call system() with the given man page" do
  ^-
Error: expanding macro

In spec/man_spec.cr:22:1

 22 | it "must call system() with the given man page" do
  ^
Error: expanding macro

There was a problem expanding macro 'it'

Called macro defined in macro 'define_example'

 17 | macro it(what = nil, *tags, **metadata, &block)

Which expanded to:

 >  1 |         
 >  2 |         
 >  3 | 
 >  4 |         _spectator_metadata(__temp_36, :metadata,  )
 >  5 |         _spectator_metadata(__temp_67, __temp_36,  )
 >  6 | 
 >  7 |         
 >  8 |           
 >  9 | 
 > 10 |           private def __temp_68() : Nil
 > 11 |             (expect(subject)).to((receive(:system)).with("man", [man_page]))
 > 12 | subject.man(man_page)
 > 13 | 
 > 14 |           end
 > 15 | 
 > 16 |           ::Spectator::DSL::Builder.add_example(
 > 17 |             _spectator_example_name("must call system() with the given man page"),
 > 18 |             ::Spectator::Location.new("/data/home/postmodern/code/crystal/commit_kit.cr/spec/man_spec.cr", 22, 26),
 > 19 |             -> { new.as(::Spectator::Context) },
 > 20 |             __temp_67
 > 21 |           ) do |example|
 > 22 |             example.with_context(SpectatorTestContext::Group__temp_51::Group__temp_57) do
 > 23 |               
 > 24 |                 __temp_68
 > 25 |               
 > 26 |             end
 > 27 |           end
 > 28 | 
 > 29 |         
 > 30 |       
Error: instantiating 'Spectator::Example#with_context(SpectatorTestContext::Group__temp_51::Group__temp_57.class)'

In spec/man_spec.cr:22:1

 22 | it "must call system() with the given man page" do
  ^
Error: expanding macro

There was a problem expanding macro 'it'

Called macro defined in macro 'define_example'

 17 | macro it(what = nil, *tags, **metadata, &block)

Which expanded to:

 >  1 |         
 >  2 |         
 >  3 | 
 >  4 |         _spectator_metadata(__temp_36, :metadata,  )
 >  5 |         _spectator_metadata(__temp_67, __temp_36,  )
 >  6 | 
 >  7 |         
 >  8 |           
 >  9 | 
 > 10 |           private def __temp_68() : Nil
 > 11 |             (expect(subject)).to((receive(:system)).with("man", [man_page]))
 > 12 | subject.man(man_page)
 > 13 | 
 > 14 |           end
 > 15 | 
 > 16 |           ::Spectator::DSL::Builder.add_example(
 > 17 |             _spectator_example_name("must call system() with the given man page"),
 > 18 |             ::Spectator::Location.new("/data/home/postmodern/code/crystal/commit_kit.cr/spec/man_spec.cr", 22, 26),
 > 19 |             -> { new.as(::Spectator::Context) },
 > 20 |             __temp_67
 > 21 |           ) do |example|
 > 22 |             example.with_context(SpectatorTestContext::Group__temp_51::Group__temp_57) do
 > 23 |               
 > 24 |                 __temp_68
 > 25 |               
 > 26 |             end
 > 27 |           end
 > 28 | 
 > 29 |         
 > 30 |       
Error: instantiating 'Spectator::Example#with_context(SpectatorTestContext::Group__temp_51::Group__temp_57.class)'

In spec/man_spec.cr:22:1

 22 | it "must call system() with the given man page" do
  ^
Error: expanding macro

There was a problem expanding macro 'it'

Called macro defined in macro 'define_example'

 17 | macro it(what = nil, *tags, **metadata, &block)

Which expanded to:

 >  1 |         
 >  2 |         
 >  3 | 
 >  4 |         _spectator_metadata(__temp_36, :metadata,  )
 >  5 |         _spectator_metadata(__temp_67, __temp_36,  )
 >  6 | 
 >  7 |         
 >  8 |           
 >  9 | 
 > 10 |           private def __temp_68() : Nil
 > 11 |             (expect(subject)).to((receive(:system)).with("man", [man_page]))
 > 12 | subject.man(man_page)
 > 13 | 
 > 14 |           end
 > 15 | 
 > 16 |           ::Spectator::DSL::Builder.add_example(
 > 17 |             _spectator_example_name("must call system() with the given man page"),
 > 18 |             ::Spectator::Location.new("/data/home/postmodern/code/crystal/commit_kit.cr/spec/man_spec.cr", 22, 26),
 > 19 |             -> { new.as(::Spectator::Context) },
 > 20 |             __temp_67
 > 21 |           ) do |example|
 > 22 |             example.with_context(SpectatorTestContext::Group__temp_51::Group__temp_57) do
 > 23 |               
 > 24 |                 __temp_68
 > 25 |               
 > 26 |             end
 > 27 |           end
 > 28 | 
 > 29 |         
 > 30 |       
Error: instantiating '__temp_68()'

In spec/man_spec.cr:24:9

 24 | 
              ^--
Error: instantiating 'SpectatorTestContext::Group__temp_51::TestMan::TestCommand#man(String)'

In src/command_kit/man.cr:36:9

 36 | system("man", [section.to_s, page])
      ^-----
Error: instantiating 'system(String, Array(String))'

In spec/man_spec.cr:6:11

 6 | class TestCommand
           ^
Error: expanding macro

There was a problem expanding macro 'stub'

Called macro defined in lib/spectator/src/spectator/mocks/stubs.cr:3:13

 3 | private macro stub(definition, *types, _file = __FILE__, _line = __LINE__, return_type = :undefined, &block)

Which expanded to:

 >  1 |       
 >  2 | 
 >  3 |       
 >  4 | 
 >  5 |       def system(command, arg)
 >  6 |         if (__temp_60 = ::Spectator::Harness.current?)
 >  7 |           __temp_61 = ::Spectator::Mocks::GenericArguments.create(command, arg)
 >  8 |           __temp_62 = ::Spectator::Mocks::MethodCall.new(:system, __temp_61)
 >  9 |           __temp_60.mocks.record_call(self, __temp_62)
 > 10 |           if (__temp_63 = __temp_60.mocks.find_stub(self, __temp_62))
 > 11 |             return __temp_63.call!(__temp_61) { system }
 > 12 |           end
 > 13 | 
 > 14 |           
 > 15 |             system
 > 16 |           
 > 17 |         else
 > 18 |           system
 > 19 |         end
 > 20 |       end
 > 21 | 
 > 22 |       def system(command, arg)
 > 23 |         if (__temp_60 = ::Spectator::Harness.current?)
 > 24 |           __temp_61 = ::Spectator::Mocks::GenericArguments.create(command, arg)
 > 25 |           __temp_62 = ::Spectator::Mocks::MethodCall.new(:system, __temp_61)
 > 26 |           __temp_60.mocks.record_call(self, __temp_62)
 > 27 |           if (__temp_63 = __temp_60.mocks.find_stub(self, __temp_62))
 > 28 |             return __temp_63.call!(__temp_61) { system { |*__temp_64| yield *__temp_64 } }
 > 29 |           end
 > 30 | 
 > 31 |           
 > 32 |             system do |*__temp_65|
 > 33 |               yield *__temp_65
 > 34 |             end
 > 35 |           
 > 36 |         else
 > 37 |           system do |*__temp_65|
 > 38 |             yield *__temp_65
 > 39 |           end
 > 40 |         end
 > 41 |       end
 > 42 |     
Error: wrong number of arguments for 'SpectatorTestContext::Group__temp_51::TestMan::TestCommand#system' (given 0, expected 2)

Overloads are:
 - SpectatorTestContext::Group__temp_51::TestMan::TestCommand#system(command, arg)
 - SpectatorTestContext::Group__temp_51::TestMan::TestCommand#system(command, arg, &block)

shards.yml

development_dependencies:
  spectator:
    gitlab: arctic-fox/spectator
      # branch: master
    version: "~> 0.10"
postmodern commented 2 years ago

I've also tried stub system, command, args and stub system, command, args : Bool, stub :system, commamd, args, stub :system, command, args : Bool syntax, but none of those successfully catch calls to #system.

CommandKit::Man
  #man
No manual entry for foo
    must call system() with the given man page
    when given the section: keyword argument
No manual entry for foo in section 7
      must call system() with the given section number and man page

Failures:

  1) CommandKit::Man#man must call system() with the given man page
     Failure: subject did not receive #system("man", ["foo"]) : Nil at spec/man_spec.cr:23 at least once with any arguments

       expected: At least once with any arguments
       received: 0 time(s)

     # spec/man_spec.cr:23

  2) CommandKit::Man#man when given the section: keyword argument must call system() with the given section number and man page
     Failure: subject did not receive #system("man", ["7", "foo"]) : Nil at spec/man_spec.cr:32 at least once with any arguments

       expected: At least once with any arguments
       received: 0 time(s)

     # spec/man_spec.cr:32

Finished in 50.21 milliseconds
2 examples, 2 failures
icy-arctic-fox commented 2 years ago

Are you trying to stub the top-level #system method or is there a #system method in CommandKit::Man? If the former, then I think I found an issue in the generated stub. It was calling system with no arguments when it should have forwarded them - hence the error: wrong number of arguments. I've pushed something that might fix this to master.

postmodern commented 2 years ago

I'm stubbing the top-level #system. Updated and specs pass now, thanks!