require 'spec_helper'

RSpec.describe Prawn::SVG::Properties do
  subject { Prawn::SVG::Properties.new }

  describe "#load_default_stylesheet" do
    it "loads in the defaults and returns self" do
      expect(subject.load_default_stylesheet).to eq subject
      expect(subject.font_family).to eq 'sans-serif'
    end
  end

  describe "#set" do
    it "sets a property" do
      result = subject.set('color', 'red')
      expect(result).to be
      expect(subject.color).to eq 'red'
    end

    it "handles property names that are not lower case" do
      result = subject.set('COLor', 'red')
      expect(result).to be
      expect(subject.color).to eq 'red'
    end

    it "right-cases and strips keywords" do
      subject.set('stroke-linecap', ' Round ')
      expect(subject.stroke_linecap).to eq 'round'
    end

    it "doesn't right-case values that aren't recognised as keywords" do
      subject.set('color', 'Red')
      expect(subject.color).to eq 'Red'
    end

    it "sets a 'keyword restricted' property to its default if the value doesn't match a keyword" do
      subject.set('stroke-linecap', 'invalid')
      expect(subject.stroke_linecap).to eq 'butt'
    end
  end

  describe "#load_hash" do
    it "uses #set to load in a hash of properties" do
      subject.load_hash("stroke" => "blue", "fill" => "green", 'stroke-linecap' => "Round")
      expect(subject.stroke).to eq 'blue'
      expect(subject.fill).to eq 'green'
      expect(subject.stroke_linecap).to eq 'round'
    end
  end

  describe "#compute_properties" do
    let(:other) { Prawn::SVG::Properties.new }

    it "auto-inherits inheritable properties when the property is not supplied" do
      subject.set('color', 'green')
      subject.compute_properties(other)
      expect(subject.color).to eq 'green'
    end

    it "doesn't auto-inherit non-inheritable properties" do
      subject.set('display', 'none')
      subject.compute_properties(other)
      expect(subject.display).to eq 'inline'
    end

    it "inherits non-inheritable properties when specifically asked to" do
      subject.set('display', 'none')
      other.set('display', 'inherit')
      subject.compute_properties(other)
      expect(subject.display).to eq 'none'
    end

    it "uses the new property value" do
      subject.set('color', 'green')
      other.set('color', 'red')
      subject.compute_properties(other)
      expect(subject.color).to eq 'red'
    end

    describe "font size" do
      before do
        subject.font_size = "15"
        other.font_size = font_size
      end

      context "when given a % as a font-size" do
        let(:font_size) { "120%" }

        it "calculates the new font size" do
          subject.compute_properties(other)
          expect(subject.font_size).to eq "18.0"
        end
      end

      context "when given 'larger' as a font-size" do
        let(:font_size) { "larger" }

        it "calculates the new font size" do
          subject.compute_properties(other)
          expect(subject.font_size).to eq "19.0"
        end
      end

      context "when given 'smaller' as a font-size" do
        let(:font_size) { "smaller" }

        it "calculates the new font size" do
          subject.compute_properties(other)
          expect(subject.font_size).to eq "11.0"
        end
      end

      context "when given a value in 'em' as a font-size" do
        let(:font_size) { "2.5em" }

        it "calculates the new font size" do
          subject.compute_properties(other)
          expect(subject.font_size).to eq "37.5"
        end
      end

      context "when given a value in 'rem' as a font-size" do
        let(:font_size) { "2.5rem" }

        it "calculates the new font size" do
          subject.compute_properties(other)
          expect(subject.font_size).to eq "40.0"
        end
      end

      context "when given a value in 'px' as a font-size" do
        let(:font_size) { "19.5px" }

        it "uses the font size specified" do
          subject.compute_properties(other)
          expect(subject.font_size).to eq "19.5"
        end
      end

      context "when given a value in 'pt' as a font-size" do
        let(:font_size) { "19.5pt" }

        it "uses the font size specified" do
          subject.compute_properties(other)
          expect(subject.font_size).to eq "19.5"
        end
      end

      context "when given a value without units as a font-size" do
        let(:font_size) { "19.5" }

        it "uses the font size specified" do
          subject.compute_properties(other)
          expect(subject.font_size).to eq "19.5"
        end
      end

      context "when given the keyword 'inherit' as a font-size" do
        let(:font_size) { "inherit" }

        it "uses the font size specified by the parent" do
          subject.compute_properties(other)
          expect(subject.font_size).to eq "15"
        end
      end
    end
  end

  describe "#numerical_font_size" do
    context "when the font size is a number" do
      before { subject.font_size = "16.5" }

      it "returns the number as a float" do
        expect(subject.numerical_font_size).to eq 16.5
      end
    end

    context "when the font size is one of the keyword size specifiers" do
      before { subject.font_size = "x-large" }

      it "returns the font size number corresponding with the keyword" do
        expect(subject.numerical_font_size).to eq 24
      end
    end
  end
end