Skip to content

Commit

Permalink
feat: Add sigil
Browse files Browse the repository at this point in the history
  • Loading branch information
tlux committed Sep 16, 2019
1 parent dd7898a commit 4619df6
Show file tree
Hide file tree
Showing 3 changed files with 191 additions and 0 deletions.
43 changes: 43 additions & 0 deletions lib/tint/sigil.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
defmodule Tint.Sigil do
@moduledoc """
A module providing a sigil to build colors in a certain colorspace.
"""

alias Tint.HSV
alias Tint.RGB

@separator ","

@doc """
A sigil to build a color.
"""
@spec sigil_K(String.t(), [char]) :: Tint.color()
def sigil_K(str, []) do
RGB.from_hex!(str)
end

def sigil_K(str, [?r]) do
apply(RGB, :new, extract_args(str, 3))
end

def sigil_K(str, [?h]) do
apply(HSV, :new, extract_args(str, 3))
end

defp extract_args(str, expected_count) do
args =
str
|> String.split(@separator)
|> Enum.map(&String.trim/1)

args_count = length(args)

if args_count != expected_count do
raise ArgumentError,
"Invalid number of args: #{args_count} " <>
"(expected #{expected_count})"
end

args
end
end
73 changes: 73 additions & 0 deletions test/tint/rgb_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,79 @@ defmodule Tint.RGBTest do
end
end

describe "euclidean_distance/2" do
test "get Euclidean distance for two colors" do
assert RGB.euclidean_distance(
RGB.from_hex!("#FFFFFF"),
RGB.from_hex!("#000000")
) == 441.6729559300637

assert RGB.euclidean_distance(
RGB.from_hex!("#000000"),
RGB.from_hex!("#FFFFFF")
) == 441.6729559300637

assert RGB.euclidean_distance(
RGB.from_hex!("#FF0000"),
RGB.from_hex!("#FC0000")
) == 3.0

assert RGB.euclidean_distance(
RGB.from_hex!("#FFCC00"),
RGB.from_hex!("#FCFFCC")
) == 210.2997860198626
end
end

describe "euclidean_distance/3" do
# TODO
end

describe "nearest/2" do
test "is nil when palette is empty" do
color = RGB.from_hex!("#FF0000")

palette = [
RGB.from_hex!("#FCFF00"),
RGB.from_hex!("#CCFF00"),
RGB.from_hex!("#CC0000"),
RGB.from_hex!("#FC0000"),
RGB.from_hex!("#00CCFF"),
RGB.from_hex!("#000FFF")
]

assert RGB.nearest(color, []) ==
RGB.nearest(color, [], &RGB.human_euclidean_distance/2)

assert RGB.nearest(color, palette) ==
RGB.nearest(color, palette, &RGB.human_euclidean_distance/2)
end
end

describe "nearest/3" do
test "is nil when palette is empty" do
color = RGB.from_hex!("#FF0000")

assert RGB.nearest(color, [], &RGB.human_euclidean_distance/2) == nil
end

test "get nearest color" do
color = RGB.from_hex!("#FF0000")

palette = [
RGB.from_hex!("#FCFF00"),
RGB.from_hex!("#CCFF00"),
RGB.from_hex!("#CC0000"),
RGB.from_hex!("#FC0000"),
RGB.from_hex!("#00CCFF"),
RGB.from_hex!("#000FFF")
]

assert RGB.nearest(color, palette, &RGB.human_euclidean_distance/2) ==
RGB.from_hex!("#FC0000")
end
end

describe "to_hex/1" do
test "convert RGB color struct to hex code" do
assert RGB.to_hex(RGB.new(0, 0, 0)) == "#000000"
Expand Down
75 changes: 75 additions & 0 deletions test/tint/sigil_test.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
defmodule Tint.SigilTest do
use ExUnit.Case, async: true

import Tint.Sigil

alias Tint.HSV
alias Tint.OutOfRangeError
alias Tint.RGB

describe "hex code" do
test "success" do
assert ~K[#FFCC00] == RGB.from_hex!("#FFCC00")
end

test "error" do
assert_raise ArgumentError, "Invalid hex code: invalid", fn ->
~K[invalid]
end
end
end

describe "RGB color" do
test "success" do
assert ~K(123,45,67)r == RGB.new(123, 45, 67)
assert ~K(123, 45, 67)r == RGB.new(123, 45, 67)
end

test "error when value out of range" do
assert_raise OutOfRangeError, "Value 256 is out of range [0,255]", fn ->
~K(256,128,0)r
end
end

test "raise when invalid number of args" do
assert_raise ArgumentError,
"Invalid number of args: 5 (expected 3)",
fn ->
~K(255, 0,, 255,)r
end

assert_raise ArgumentError,
"Invalid number of args: 2 (expected 3)",
fn ->
~K(255,0)r
end
end
end

describe "HSV color" do
test "success" do
assert ~K(123,0.45,0.67)h == HSV.new(123, 0.45, 0.67)
assert ~K(123, 0.45, 0.67)h == HSV.new(123, 0.45, 0.67)
end

test "error when value out of range" do
assert_raise OutOfRangeError, "Value 361 is out of range [0,360)", fn ->
~K(361,0,1)h
end
end

test "raise when invalid number of args" do
assert_raise ArgumentError,
"Invalid number of args: 5 (expected 3)",
fn ->
~K(255, 0,, 1,)h
end

assert_raise ArgumentError,
"Invalid number of args: 2 (expected 3)",
fn ->
~K(255,1)h
end
end
end
end

0 comments on commit 4619df6

Please sign in to comment.