dimanche 23 juillet 2017

Expecting Lambdas in RSpec

I have a simple class:

class Maybe
  def initialize(value, maybe_klass = Maybe)
    @value = value
    @maybe_klass = maybe_klass
  end

  attr_reader :value

  def map(function)
    return self if value.nil?
    return maybe_klass.new(compose(value, function)) if value.is_a? Proc
    maybe_klass.new(function.curry.call(*value))
  end

  private

  attr_reader :maybe_klass

  def compose(f, g)
    lambda { |*args| f.call(g.call(*args))  }
  end
end

I'm trying to test it like this:

it 'creates a new wrapped function that does both of the functions combined' do
  maybe_double = double Maybe
  add_four = ->(x) { x + 4 }
  maybe = Maybe.new(add_four, maybe_double)
  composed_lambda = ->(*args) { maybe.value.call(add_four.call(*args)) }
  expect(maybe_double).to receive(:new).with(composed_lambda)
  maybe.map(add_four)
end

This test does not work- undefined method '+' for #<Proc:0x007fdd0b269e78>

I think the composed lambda is being evaluated before I need it to be, but I'm not sure. What should I expect the double's initialize method to be called with? Is this even the correct way to approach testing this class? I feel like I'm too closely mimicking the internals of the class with the composed_lambda variable, but I'm not sure what else to expect instead.

Aucun commentaire:

Enregistrer un commentaire