require File.join(__FILE__.gsub(/(.*)?\/spec\/.*$/, '\1'), 'spec/spec_helper')

describe Rtml::Widgets::ElementBuilder do
  context "with an existing document" do
    before :each do
      Rtml::Document.new(:name => "Test Document", :empty => true).save!
      @doc = Rtml::Document.find_by_name("Test Document")
    end

    it "should make sure to assign a parent to each element" do
      @doc.build :tml do
        build :screen do

        end
      end

      screen = ((@doc / "tml").first / "screen").first
      screen.parent.should be_kind_of(Rtml::Dom::Element)
      screen.parent.parent.should be_kind_of(Rtml::Document)
    end

    it "should only allow the root element to be built at the root level only once" do
      # cannot add a tag that doesn't exist.
      assert_raises Rtml::Errors::RulesViolationError do
        @doc.build :some_completely_invalid_tag do
          # . . .
        end
      end

      # cannot add a non-root tag.
      assert_raises Rtml::Errors::RulesViolationError do
        @doc.build :p do # a valid but illegal tag
          # . . .
        end
      end

      # rules.root is probably :tml, but let's allow some flexibility.
      @doc.build @doc.rules.root

      # shouldn't be able to add the root twice.
      assert_raises Rtml::Errors::RulesViolationError do
        @doc.build @doc.rules.root do
          # . . .
        end
      end
    end

    it "should not allow addition of elements out of order" do
      root = @doc.build @doc.rules.root

      head = root.build :head do
        base
        defaults
        link
        error
      end

      (root / 'head').first.elements.collect { |c| c.name }.should == %w(base link defaults error)

      root.elements.should have(1).element
      head.elements.should have(4).elements
    end
  end

  context "with a new document" do
    before :each do
      @doc = Rtml::Document.new(:empty => true)
    end

    it "should make sure to assign a parent to each element" do
      @doc.build :tml do
        build :screen do

        end
      end

      screen = ((@doc / "tml").first / "screen").first
      screen.parent.should be_kind_of(Rtml::Dom::Element)
      screen.parent.parent.should be_kind_of(Rtml::Document)
    end

    it "should only allow the root element to be built at the root level only once" do
      # cannot add a tag that doesn't exist.
      assert_raises Rtml::Errors::RulesViolationError do
        @doc.build :some_completely_invalid_tag do
          # . . .
        end
      end

      # cannot add a non-root tag.
      assert_raises Rtml::Errors::RulesViolationError do
        @doc.build :p do # a valid but illegal tag
          # . . .
        end
      end

      # rules.root is probably :tml, but let's allow some flexibility.
      @doc.build @doc.rules.root

      # shouldn't be able to add the root twice.
      assert_raises Rtml::Errors::RulesViolationError do
        @doc.build @doc.rules.root do
          # . . .
        end
      end
    end

    it "should not allow addition of elements out of order" do
      root = @doc.build @doc.rules.root

      head = root.build :head do
        base
        defaults
        link
        error
      end

      (root / 'head').first.elements.collect { |c| c.name }.should == %w(base link defaults error)

      root.elements.should have(1).element
      head.elements.should have(4).elements
    end
  end
end