require './spec/spec_helper'

RSpec.describe Saper::Actions::FindFirst do
  
  subject do
    Saper::Actions::FindFirst.new("//p")
  end
  
  let :string do
    "<html><body><div><p>test</p></div></body></html>"
  end
  
  let :html do
    Saper::Items::HTML.new(string)
  end
  
  let :json do
    Saper::Items::JSON.new('{"p":{"a":0}}')
  end
  
  context ".type" do
    it "returns find_first" do
      expect(described_class.type).to eq 'find_first'
    end
  end
  
  context ".accepts?(:atom)" do
    it "returns false" do
      expect(described_class.accepts?(:atom)).to be false
    end
  end
  
  context ".accepts?(:document)" do
    it "returns false" do
      expect(described_class.accepts?(:document)).to be false
    end
  end
  
  context ".accepts?(:html)" do
    it "returns true" do
      expect(described_class.accepts?(:html)).to be true
    end
  end
  
  context ".accepts?(:json)" do
    it "returns true" do
      expect(described_class.accepts?(:json)).to be true
    end
  end
  
  context ".accepts?(:markdown)" do
    it "returns false" do
      expect(described_class.accepts?(:markdown)).to be false
    end
  end
  
  context ".accepts?(:nothing)" do
    it "returns false" do
      expect(described_class.accepts?(:nothing)).to be false
    end
  end
  
  context ".accepts?(:text)" do
    it "returns false" do
      expect(described_class.accepts?(:text)).to be false
    end
  end
  
  context ".accepts?(:time)" do
    it "returns false" do
      expect(described_class.accepts?(:time)).to be false
    end
  end
  
  context ".accepts?(:url)" do
    it "returns false" do
      expect(described_class.accepts?(:url)).to be false
    end
  end
  
  context ".accepts?(:xml)" do
    it "returns true" do
      expect(described_class.accepts?(:xml)).to be true
    end
  end
  
  context ".output_for(:atom)" do
    it "returns :nothing" do
      expect(described_class.output_for(:atom)).to be :nothing
    end
  end
  
  context ".output_for(:document)" do
    it "returns :nothing" do
      expect(described_class.output_for(:document)).to be :nothing
    end
  end
  
  context ".output_for(:html)" do
    it "returns :html" do
      expect(described_class.output_for(:html)).to be :html
    end
  end
  
  context ".output_for(:json)" do
    it "returns :json" do
      expect(described_class.output_for(:json)).to be :json
    end
  end
  
  context ".output_for(:markdown)" do
    it "returns :nothing" do
      expect(described_class.output_for(:markdown)).to be :nothing
    end
  end
  
  context ".output_for(:text)" do
    it "returns :nothing" do
      expect(described_class.output_for(:text)).to be :nothing
    end
  end
  
  context ".output_for(:time)" do
    it "returns :nothing" do
      expect(described_class.output_for(:time)).to be :nothing
    end
  end
  
  context ".output_for(:url)" do
    it "returns :nothing" do
      expect(described_class.output_for(:url)).to be :nothing
    end
  end
  
  context ".output_for(:xml)" do
    it "returns :xml" do
      expect(described_class.output_for(:xml)).to be :xml
    end
  end
  
  context ".returns_multiple_items?" do
    it "returns false" do
      expect(described_class.returns_multiple_items?).to be false
    end
  end
  
  context ".new(nil)" do
    it "raises InvalidArgument" do
      expect { described_class.new(nil) }.to raise_error Saper::Errors::InvalidArgument
    end
  end
  
  context ".new(Numeric)" do
    it "raises InvalidArgument" do
      expect { described_class.new(1) }.to raise_error Saper::Errors::InvalidArgument
    end
  end
  
  context ".new(Hash)" do
    it "raises InvalidArgument" do
      expect { described_class.new({}) }.to raise_error Saper::Errors::InvalidArgument
    end
  end
  
  context ".new(Array)" do
    it "raises InvalidArgument" do
      expect { described_class.new([]) }.to raise_error Saper::Errors::InvalidArgument
    end
  end
  
  context ".new(CSS)" do
    it "raises no errors" do
      expect { described_class.new("a") }.to_not raise_error
    end
  end
  
  context ".new(Saper::Arguments::XPath)" do
    it "raises no errors" do
      expect { described_class.new(Saper::Arguments::XPath.new(:value => "a")) }.to_not raise_error
    end
  end
  
  context "#run(nil)" do
    it "raises InvalidInput" do
      expect { subject.run(nil) }.to raise_error Saper::Errors::InvalidInput
    end
  end
  
  context "#run(String)" do
    it "returns HTML instance" do
      expect(subject.run(string)).to be_a Saper::Items::HTML
    end
    it "returns valid output" do
      expect(subject.run(string)).to eq '<p>test</p>'
    end
  end
  
  context "#run(HTML)" do
    it "returns HTML instance" do
      expect(subject.run(html)).to be_a Saper::Items::HTML
    end
    it "returns valid output" do
      expect(subject.run(html)).to eq '<p>test</p>'
    end
  end
  
  context "#run(JSON)" do
    it "returns JSON instance" do
      expect(subject.run(json)).to be_a Saper::Items::JSON
    end
    it "returns valid output" do
      expect(subject.run(json)).to eq({ "a" => 0 })
    end
  end
  
end
