lunarmodules / luassert

Assertion library for Lua
MIT License
206 stars 77 forks source link

a function returning nothing doesn't match is_nil #37

Closed Tieske closed 11 years ago

Tieske commented 11 years ago
  it("tests returning nothing as nil", function()
    local f1 = function() return nil end
    local f2 = function() return end
    assert.is_nil(f1())
    assert.is_nil(f2())
  end)

fails on the second assertion, becasue f1 returns 1 argument, nil, f2 returns no arguments.

error message is;

tests returning nothing as nil
spec\state_spec.lua:132: Expected objects to be the same. Passed in:
(nil)
Expected:
type nil

Now the error telling (nil) was passed in is a bug. What should it return? Should it pass? (nothing == nil) ? or should the message make clear that no argument was provided?

ajacksified commented 11 years ago

is_nil seems like it's working properly; it did pass in nil. I'm okay with this; it may be expected behavior.

Javscript has separate "undefined" from "null", but this passes:

describe("null", function(){
    it("should be okay with this", function(){
      expect(function(){ }()).toBe(undefined);
      expect().toBe(undefined);
    });
  });

And ruby is okay:

#test_spec.rb
class Thing
  def fn
  end

  def fn_nil
    nil
  end
end

describe Thing, "#nil" do
  it "handles nils" do
    thing = Thing.new
    thing.fn.should eq(nil)
  end

  it "handles nil responses" do
    thing = Thing.new
    thing.fn_nil.should eq(nil)
  end
end

So I think it's okay. It shouldn't throw that type string error, though.

Tieske commented 11 years ago

So I think it's okay. It shouldn't throw that type string error, though.

Sorry my bad, cut & paste error. It actually read type nil, which is correct (updated the initial post). It is the passed in: (nil) part that is incorrect. Should be something like passed in: (nothing, no arguments were provided)

Anyway, I think it warrants a new assertion nothing or is_nothing to check for no return values of functions. Furthermore, the example tests is_nil assertions, but the problem probably is with every assertion.

ajacksified commented 11 years ago

I'm not hugely motivated to build in nothing because the other frameworks handle it as we do, and because in Lua, no return (or not enough returns) is the same thing as nil in the manual (http://www.lua.org/pil/5.1.html).

I'd prefer something like assert.returned_arguments(#, fn()) where # is a configurable number of expected returned arguments (so I could assert that I got 0, or 2, or 3, or whatever.)

If we do that, we should also consider adding in a returned_arguments() and a returned_arguments(#) to spies.

Tieske commented 11 years ago
fn1 = function() return nil end
fn2 = function() return end

print(#{fn1()}, #{fn2()})

returns

0    0

so doesn't work

ajacksified commented 11 years ago

Also, I started adding this in for spies last night, and am currently down a huge rabbit-hole where I'm trying to get all the arguments to display in the output. I'm going to move all of that into a separate pull request and see if I can clean this PR up.

Tieske commented 11 years ago

do you have an example of what you're trying to do?

ajacksified commented 11 years ago

This is related to issue #41; I'll add details there.