require File.expand_path("../helper", __FILE__)

class DepressionTest < Test::Unit::TestCase
  def setup
    @item = Proc.new do |n, r|
      r ||= {}
      Struct.new(:name, :relations).new(n, r)
    end
  end
  
  test "has items" do
    items = [@item.call(:foo), @item.call(:bar)]
    graph = Depression.new(items)
    assert_equal items, graph.items
    
    assert_raise(NoMethodError) { graph.items = [] }
  end
  
  test "expects items to have a name" do
    assert_raise(RuntimeError) { Depression.new([:foo]).process }
    
    Depression.new([@item.call(:foo)]).process
  end
  
  test "provides a shorthand method for processing items" do
    items = [@item.call(:foo)]
    
    instance = stub("instance")
    Depression.expects(:new).with(items).returns(instance)
    instance.expects(:process)
    instance.expects(:result)
    
    Depression.process(items)
  end
  
  test "resolves simple before/after relations" do
    items = [
      @item.call(:foo, :before => [:baz]),
      @item.call(:bar, :after => [:foo]),
      @item.call(:baz, :after => [:bar]),
      @item.call(:asd, :before => [:foo]),
      @item.call(:sdf, :before => [:foo, :baz], :after => [:asd])
    ]
    
    result = Depression.process(items).map {|i| i.name }
    assert_equal [:asd, :sdf, :foo, :bar, :baz], result
  end
  
  test "resolves greedy before/after relations" do
    items = [
      @item.call(:foo, :before => [:bar]),
      @item.call(:bar, :after => :all),
      @item.call(:baz, :before => :all)
    ]
    
    result = Depression.process(items).map {|i| i.name }
    assert_equal [:baz, :foo, :bar], result
  end
  
  test "detects circular relations" do
    items = [
      @item.call(:foo, :before => [:bar]),
      @item.call(:bar, :before => [:baz]),
      @item.call(:baz, :before => [:asd]),
      @item.call(:asd, :before => [:foo])
    ]
    
    begin
      Depression.process(items)
    rescue => e
    end
    assert e.message =~ /^Circular dep:/
  end
  
  test "drops greedy relations in favor of simple relations" do
    pend("Not yet implemented.")
  end
  
  test "can drop 'older' relations until a circular relation is resolved" do
    pend("Not yet implemented.")
  end
end
