require File.expand_path("#{File.dirname(__FILE__)}/../../spec_helper")

module RR
module Expectations
  describe ArgumentEqualityExpectation, "with HashIncluding argument" do
    attr_reader :expectation, :expected_hash

    before do
      @expected_hash = {:texas => "Austin", :maine => "Augusta"}
    end

    describe "#exact_match?" do
      before do
        @expectation = ArgumentEqualityExpectation.new(hash_including(expected_hash))
      end

      it "returns true when passed in a HashIncluding matcher with the same hash" do
        expect(expectation).to be_exact_match(RR::WildcardMatchers::HashIncluding.new(expected_hash))
      end

      it "returns false when passed in a HashIncluding matcher with a different argument list" do
        expectation.should_not be_exact_match(RR::WildcardMatchers::HashIncluding.new(:foo => 1))
      end

      it "returns false otherwise" do
        expectation.should_not be_exact_match("hello")
        expectation.should_not be_exact_match(:hello)
        expectation.should_not be_exact_match(1)
        expectation.should_not be_exact_match(nil)
        expectation.should_not be_exact_match(true)
        expectation.should_not be_exact_match()
      end
    end

    describe "#wildcard_match?" do
      before do
        @expectation = ArgumentEqualityExpectation.new(hash_including(expected_hash))
      end

      it "returns true when hash contains same key/values as the expectation" do
        expect(expectation).to be_wildcard_match(expected_hash)
      end

      it "returns true when hash contains at least expectation's key/values" do
        expect(expectation).to be_wildcard_match(expected_hash.merge(:oregon => "Salem"))
      end

      it "returns true when passed the same hash, even after the original is modified" do
        original_expected_hash = expected_hash.clone
        expected_hash[:texas] = nil
        expect(expectation).to be_wildcard_match(original_expected_hash)
      end

      it "returns true even if one of the expectation's values is nil" do
        expectation = ArgumentEqualityExpectation.new(hash_including(:foo => nil))
        expect(expectation).to be_wildcard_match({:foo => nil})
      end

      it "returns false when hash matches only some required key/values" do
        expectation.should_not be_wildcard_match({:texas => "Austin"})
      end

      it "returns false when hash matches all the keys but not all the values" do
        expectation.should_not be_wildcard_match({:texas => "Austin", :maine => "Portland"})
      end

      it "returns false when passed a hash that matches all values but not all keys" do
        expectation.should_not be_wildcard_match({:texas => "Austin", :georgia => "Augusta"})
      end

      it "returns true when an exact match" do
        expect(expectation).to be_wildcard_match(hash_including(expected_hash))
      end

      it "returns false when not passed correct number of arguments" do
        expectation.should_not be_wildcard_match()
        expectation.should_not be_wildcard_match(:a, :b)
      end
    end
  end
end
end
