class ColorsRGBATest < Test::Unit::TestCase
  include TestHelper

  sub_test_case(".new") do
    test("with integer values") do
      c = Colors::RGBA.new(1, 128, 0, 255)
      assert_equal(1/255r, c.red)
      assert_equal(128/255r, c.green)
      assert_equal(0/255r, c.blue)
      assert_equal(255/255r, c.alpha)

      assert_raise(ArgumentError) do
        Colors::RGBA.new(0, 0, 0x100, 0x100)
      end

      assert_raise(ArgumentError) do
        Colors::RGBA.new(0, 0, -1, -1)
      end
    end

    test("with float values") do
      c = Colors::RGBA.new(0.0.next_float, 0.55, 1, 0.9)
      assert_equal(0.0.next_float.to_r, c.red)
      assert_equal(0.55.to_r, c.green)
      assert_equal(1.0.to_r, c.blue)
      assert_equal(0.9.to_r, c.alpha)

      assert_raise(ArgumentError) do
        Colors::RGBA.new(0.0, 0.0, 9.9, 1.0.next_float)
      end

      assert_raise(ArgumentError) do
        Colors::RGBA.new(0, 0, 0, -1.0)
      end
    end

    test("with rational values") do
      c = Colors::RGBA.new(1/1000r, 500/1000r, 1, 999/1000r)
      assert_equal(1/1000r, c.red)
      assert_equal(500/1000r, c.green)
      assert_equal(1r, c.blue)
      assert_equal(999/1000r, c.alpha)

      assert_raise(ArgumentError) do
        Colors::RGBA.new(0, 0, 0, 1001/1000r)
      end

      assert_raise(ArgumentError) do
        Colors::RGBA.new(0, 0, 0, -1/1000r)
      end
    end
  end

  test("#red=") do
    c = Colors::RGBA.new(0, 0, 0, 0)
    c.red = 1r
    assert_equal(1r, c.red)
    c.red = 1.0r
    assert_equal(1r, c.red)
    c.red = 1
    assert_equal(1/255r, c.red)
    assert_raise(ArgumentError) do
      c.red = 1001/1000r
    end
    assert_raise(ArgumentError) do
      c.red = -1/1000r
    end
    assert_raise(ArgumentError) do
      c.red = -0.1
    end
    assert_raise(ArgumentError) do
      c.red = 1.0.next_float
    end
    assert_raise(ArgumentError) do
      c.red = 256
    end
    assert_raise(ArgumentError) do
      c.red = -1
    end
  end

  test("#green=") do
    c = Colors::RGBA.new(0, 0, 0, 0)
    c.green = 1r
    assert_equal(1r, c.green)
    c.green = 1.0r
    assert_equal(1r, c.green)
    c.green = 1
    assert_equal(1/255r, c.green)
    assert_raise(ArgumentError) do
      c.green = 1001/1000r
    end
    assert_raise(ArgumentError) do
      c.green = -1/1000r
    end
    assert_raise(ArgumentError) do
      c.green = -0.1
    end
    assert_raise(ArgumentError) do
      c.green = 1.0.next_float
    end
    assert_raise(ArgumentError) do
      c.green = 256
    end
    assert_raise(ArgumentError) do
      c.green = -1
    end
  end

  test("#blue=") do
    c = Colors::RGBA.new(0, 0, 0, 0)
    c.blue = 1r
    assert_equal(1r, c.blue)
    c.blue = 1.0r
    assert_equal(1r, c.blue)
    c.blue = 1
    assert_equal(1/255r, c.blue)
    assert_raise(ArgumentError) do
      c.blue = 1001/1000r
    end
    assert_raise(ArgumentError) do
      c.blue = -1/1000r
    end
    assert_raise(ArgumentError) do
      c.blue = -0.1
    end
    assert_raise(ArgumentError) do
      c.blue = 1.0.next_float
    end
    assert_raise(ArgumentError) do
      c.blue = 256
    end
    assert_raise(ArgumentError) do
      c.blue = -1
    end
  end

  test("#alpha=") do
    c = Colors::RGBA.new(0, 0, 0, 0)
    c.alpha = 1r
    assert_equal(1r, c.alpha)
    c.alpha = 1.0r
    assert_equal(1r, c.alpha)
    c.alpha = 1
    assert_equal(1/255r, c.alpha)
    assert_raise(ArgumentError) do
      c.alpha = 1001/1000r
    end
    assert_raise(ArgumentError) do
      c.alpha = -1/1000r
    end
    assert_raise(ArgumentError) do
      c.alpha = -0.1
    end
    assert_raise(ArgumentError) do
      c.alpha = 1.0.next_float
    end
    assert_raise(ArgumentError) do
      c.alpha = 256
    end
    assert_raise(ArgumentError) do
      c.alpha = -1
    end
  end

  test("#==") do
    assert { Colors::RGBA.new(0, 0, 0, 0) == Colors::RGBA.new(0, 0, 0, 0) }
    assert { Colors::RGBA.new(0, 0, 0, 1r) == Colors::RGB.new(0, 0, 0) }
  end

  test("!=") do
    assert { Colors::RGBA.new(0, 0, 0, 0) != Colors::RGBA.new(1, 0, 0, 0) }
    assert { Colors::RGBA.new(0, 0, 0, 0) != Colors::RGBA.new(0, 1, 0, 0) }
    assert { Colors::RGBA.new(0, 0, 0, 0) != Colors::RGBA.new(0, 0, 1, 0) }
    assert { Colors::RGBA.new(0, 0, 0, 0) != Colors::RGBA.new(0, 0, 0, 1) }
    assert { Colors::RGBA.new(0, 0, 0, 0) != Colors::RGB.new(0, 0, 0) }
  end

  test("#desaturate") do
    c = Colors::RGBA.new(1r, 1r, 1r, 0.7r).desaturate(0.8)
    assert_instance_of(Colors::RGBA, c)
    assert_near(Colors::HSLA.new(0r, 0.8r, 1r, 0.7r).to_rgba, c)
  end

  sub_test_case(".parse") do
    test("for #rgba") do
      assert_equal(Colors::RGBA.new(0, 0, 0, 0),
                   Colors::RGBA.parse("#0000"))
      assert_equal(Colors::RGBA.new(0x33, 0x66, 0x99, 0xcc),
                   Colors::RGBA.parse("#369c"))
      assert_equal(Colors::RGBA.new(255, 255, 255, 255),
                   Colors::RGBA.parse("#ffff"))
    end

    test("for #rrggbbaa") do
      assert_equal(Colors::RGBA.new(0, 0, 0, 0),
                   Colors::RGBA.parse("#00000000"))
      assert_equal(Colors::RGBA.new(1, 0, 0, 0),
                   Colors::RGBA.parse("#01000000"))
      assert_equal(Colors::RGBA.new(0, 1, 0, 0),
                   Colors::RGBA.parse("#00010000"))
      assert_equal(Colors::RGBA.new(0, 0, 1, 0),
                   Colors::RGBA.parse("#00000100"))
      assert_equal(Colors::RGBA.new(0, 0, 0, 1),
                   Colors::RGBA.parse("#00000001"))
    end

    test("for #rgb") do
      assert_equal(Colors::RGBA.new(0x33, 0x66, 0x99, 0xff),
                   Colors::RGBA.parse("#369"))
    end

    test("for #rrggbb") do
      assert_equal(Colors::RGBA.new(0x33, 0x66, 0x99, 0xff),
                   Colors::RGBA.parse("#336699"))
    end

    test("error cases") do
      assert_raise(ArgumentError) do
        Colors::RGBA.parse(nil)
      end

      assert_raise(ArgumentError) do
        Colors::RGBA.parse(1)
      end

      assert_raise(ArgumentError) do
        Colors::RGBA.parse("")
      end

      assert_raise(ArgumentError) do
        Colors::RGBA.parse("333")
      end

      assert_raise(ArgumentError) do
        Colors::RGBA.parse("#xxx")
      end
    end
  end

  test("#to_hex_string") do
    assert_equal("#00000000",
                 Colors::RGBA.new(0, 0, 0, 0).to_hex_string)
    assert_equal("#ff000000",
                 Colors::RGBA.new(1r, 0, 0, 0).to_hex_string)
    assert_equal("#00ff0000",
                 Colors::RGBA.new(0, 1r, 0, 0).to_hex_string)
    assert_equal("#0000ff00",
                 Colors::RGBA.new(0, 0, 1r, 0).to_hex_string)
    assert_equal("#000000ff",
                 Colors::RGBA.new(0, 0, 0, 1r).to_hex_string)
    assert_equal("#ffffffff",
                 Colors::RGBA.new(1r, 1r, 1r, 1r).to_hex_string)
    assert_equal("#80808080",
                 Colors::RGBA.new(0.5, 0.5, 0.5, 0.5).to_hex_string)
    assert_equal("#33333333",
                 Colors::RGBA.new(0x33, 0x33, 0x33, 0x33).to_hex_string)
  end

  test("to_rgb") do
    black = Colors::RGBA.new(0, 0, 0, 1.0)
    assert_equal(Colors::RGB.new(0, 0, 0),
                 black.to_rgb)

    assert_raise(NotImplementedError) do
      Colors::RGBA.new(0, 0, 0, 0).to_rgb
    end
  end

  test("to_rgba") do
    black = Colors::RGBA.new(0, 0, 0, 1.0)
    assert_same(black, black.to_rgba)
  end

  test("#to_hsl") do
    # black
    assert_equal(Colors::HSL.new(0r, 0r, 0r),
                 Colors::RGB.new(0r, 0r, 0r).to_hsl)
    # red
    assert_equal(Colors::HSL.new(0r, 1r, 0.5r),
                 Colors::RGB.new(1r, 0r, 0r).to_hsl)
    # yellow
    assert_equal(Colors::HSL.new(60r, 1r, 0.5r),
                 Colors::RGB.new(1r, 1r, 0r).to_hsl)
    # green
    assert_equal(Colors::HSL.new(120r, 1r, 0.5r),
                 Colors::RGB.new(0r, 1r, 0r).to_hsl)
    # cyan
    assert_equal(Colors::HSL.new(180r, 1r, 0.5r),
                 Colors::RGB.new(0r, 1r, 1r).to_hsl)
    # blue
    assert_equal(Colors::HSL.new(240r, 1r, 0.5r),
                 Colors::RGB.new(0r, 0r, 1r).to_hsl)
    # magenta
    assert_equal(Colors::HSL.new(300r, 1r, 0.5r),
                 Colors::RGB.new(1r, 0r, 1r).to_hsl)
    # white
    assert_equal(Colors::HSL.new(0r, 0r, 1r),
                 Colors::RGB.new(1r, 1r, 1r).to_hsl)

    assert_raise(NotImplementedError) do
      Colors::RGBA.new(0, 0, 0, 0).to_hsl
    end
  end

  test("#to_hsla") do
    # black
    assert_equal(Colors::HSLA.new(0r, 0r, 0r, 0.8r),
                 Colors::RGBA.new(0r, 0r, 0r, 0.8r).to_hsla)
    # red
    assert_equal(Colors::HSLA.new(0r, 1r, 0.5r, 0.8r),
                 Colors::RGBA.new(1r, 0r, 0r, 0.8r).to_hsla)
    # yellow
    assert_equal(Colors::HSLA.new(60r, 1r, 0.5r, 0.8r),
                 Colors::RGBA.new(1r, 1r, 0r, 0.8r).to_hsla)
    # green
    assert_equal(Colors::HSLA.new(120r, 1r, 0.5r, 0.8r),
                 Colors::RGBA.new(0r, 1r, 0r, 0.8r).to_hsla)
    # cyan
    assert_equal(Colors::HSLA.new(180r, 1r, 0.5r, 0.8r),
                 Colors::RGBA.new(0r, 1r, 1r, 0.8r).to_hsla)
    # blue
    assert_equal(Colors::HSLA.new(240r, 1r, 0.5r, 0.8r),
                 Colors::RGBA.new(0r, 0r, 1r, 0.8r).to_hsla)
    # magenta
    assert_equal(Colors::HSLA.new(300r, 1r, 0.5r, 0.8r),
                 Colors::RGBA.new(1r, 0r, 1r, 0.8r).to_hsla)
    # white
    assert_equal(Colors::HSLA.new(0r, 0r, 1r, 0.8r),
                 Colors::RGBA.new(1r, 1r, 1r, 0.8r).to_hsla)
  end
end
