Module: So::SpecObject

Defined in:
lib/spec_object.rb

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.extended(mod) ⇒ Object



440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
# File 'lib/spec_object.rb', line 440

def self.extended(mod)
  mod.send(:define_singleton_method, :behaviours) do
    @behaviours ||= {}
  end

  mod.send(:define_method, :initialize) do |wrapped|
    @wrapped = wrapped
    @calls = []
  end

  mod.send(:define_method, :method_missing) do |name, *args|
    output = @wrapped.send(name, *args)

    behaviour = mod.behaviours[name]
    if behaviour
      v_args, v_output, expr = behaviour.values_at(:args, :output, :expr)

      expr =
        expr
          .substitute(v_output, output.to_so_expr)
          .substitute(v_args, args.to_so_expr)

      v = expr.evaluate(@calls)
      unless v.kind_of?(Const) && v.value
        puts v.pp(0)
        raise "Problem"
      end
    end

    @calls.push([name, args, output])

    output
  end
end

Instance Method Details

#behaviour(name, &blk) ⇒ Object



484
485
486
487
488
489
490
491
492
493
494
495
# File 'lib/spec_object.rb', line 484

def behaviour(name, &blk)
  args = Variable.new
  output = Variable.new

  expr = DSL.new.instance_exec(args, output, &blk).to_so_expr

  behaviours[name] = {
    args: args,
    output: output,
    expr: expr
  }
end

#specs(cl) ⇒ Object



475
476
477
478
479
480
481
482
# File 'lib/spec_object.rb', line 475

def specs(cl)
  spec = self

  old_new = cl.method(:new)
  cl.send(:define_singleton_method, :new) do |*args|
    spec.new(old_new.call(*args))
  end
end