Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PactValue types #19

Merged
merged 1 commit into from
Sep 19, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions lib/types/pact_decimal.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
defmodule Kadena.Types.PactDecimal do
@moduledoc """
`PactDecimal` struct definition.
"""

alias Decimal

@behaviour Kadena.Types.Spec

@type t :: %__MODULE__{value: Decimal.t(), raw_value: String.t()}

defstruct [:value, :raw_value]

@impl true
def new(str) when is_binary(str), do: %__MODULE__{value: Decimal.new(str), raw_value: str}
def new(_str), do: {:error, :invalid_decimal}
end
17 changes: 17 additions & 0 deletions lib/types/pact_int.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
defmodule Kadena.Types.PactInt do
@moduledoc """
`PactInt` struct definition.
"""

@behaviour Kadena.Types.Spec

@type t :: %__MODULE__{value: integer(), raw_value: String.t()}

defstruct [:value, :raw_value]

@impl true
def new(value) when is_integer(value),
do: %__MODULE__{value: value, raw_value: to_string(value)}

def new(_value), do: {:error, :invalid_int}
end
22 changes: 22 additions & 0 deletions lib/types/pact_literal.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
defmodule Kadena.Types.PactLiteral do
@moduledoc """
`PactLiteral` struct definition.
"""
alias Kadena.Types.{PactDecimal, PactInt}

@behaviour Kadena.Types.Spec

@type literal :: PactInt.t() | PactDecimal.t() | String.t() | number() | boolean()

@type t :: %__MODULE__{literal: literal()}

defstruct [:literal]

@impl true
def new(%PactInt{} = pact_int), do: %__MODULE__{literal: pact_int}
def new(%PactDecimal{} = pact_decimal), do: %__MODULE__{literal: pact_decimal}
def new(str) when is_binary(str), do: %__MODULE__{literal: str}
def new(number) when is_number(number), do: %__MODULE__{literal: number}
def new(bool) when is_boolean(bool), do: %__MODULE__{literal: bool}
def new(_literal), do: {:error, :invalid_literal}
end
25 changes: 25 additions & 0 deletions lib/types/pact_literals_list.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
defmodule Kadena.Types.PactLiteralsList do
@moduledoc """
`PactLiteralsList` struct definition.
"""
alias Kadena.Types.PactLiteral

@behaviour Kadena.Types.Spec

@type literals :: list(PactLiteral.t())

@type t :: %__MODULE__{list: literals()}

defstruct list: []

@impl true
def new(literals), do: build_list(%__MODULE__{}, literals)

@spec build_list(list :: t(), literals :: literals()) :: t()
defp build_list(list, []), do: list

defp build_list(%__MODULE__{list: list}, [%PactLiteral{} = literal | rest]),
do: build_list(%__MODULE__{list: [literal | list]}, rest)

defp build_list(_list, _literals), do: {:error, :invalid_literal}
end
19 changes: 19 additions & 0 deletions lib/types/pact_value.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
defmodule Kadena.Types.PactValue do
@moduledoc """
`PactValue` structure definition.
"""
alias Kadena.Types.{PactLiteral, PactLiteralsList}

@behaviour Kadena.Types.Spec

@type pact_value :: PactLiteral.t() | PactLiteralsList.t()

@type t :: %__MODULE__{value: pact_value()}

defstruct [:value]

@impl true
def new(%PactLiteral{} = literal), do: %__MODULE__{value: literal}
def new(%PactLiteralsList{} = literal_list), do: %__MODULE__{value: literal_list}
def new(_value), do: {:error, :invalid_value}
end
1 change: 1 addition & 0 deletions mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ defmodule Kadena.MixProject do
defp deps do
[
{:credo, "~> 1.6", only: [:dev, :test], runtime: false},
{:decimal, "~> 2.0"},
{:dialyxir, "~> 1.0", only: [:dev, :test], runtime: false},
{:ex_doc, "~> 0.24", only: :dev, runtime: false}
]
Expand Down
1 change: 1 addition & 0 deletions mix.lock
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
%{
"bunt": {:hex, :bunt, "0.2.1", "e2d4792f7bc0ced7583ab54922808919518d0e57ee162901a16a1b6664ef3b14", [:mix], [], "hexpm", "a330bfb4245239787b15005e66ae6845c9cd524a288f0d141c148b02603777a5"},
"credo": {:hex, :credo, "1.6.7", "323f5734350fd23a456f2688b9430e7d517afb313fbd38671b8a4449798a7854", [:mix], [{:bunt, "~> 0.2.1", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2.8", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "41e110bfb007f7eda7f897c10bf019ceab9a0b269ce79f015d54b0dcf4fc7dd3"},
"decimal": {:hex, :decimal, "2.0.0", "a78296e617b0f5dd4c6caf57c714431347912ffb1d0842e998e9792b5642d697", [:mix], [], "hexpm", "34666e9c55dea81013e77d9d87370fe6cb6291d1ef32f46a1600230b1d44f577"},
"dialyxir": {:hex, :dialyxir, "1.2.0", "58344b3e87c2e7095304c81a9ae65cb68b613e28340690dfe1a5597fd08dec37", [:mix], [{:erlex, ">= 0.2.6", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "61072136427a851674cab81762be4dbeae7679f85b1272b6d25c3a839aff8463"},
"earmark_parser": {:hex, :earmark_parser, "1.4.26", "f4291134583f373c7d8755566122908eb9662df4c4b63caa66a0eabe06569b0a", [:mix], [], "hexpm", "48d460899f8a0c52c5470676611c01f64f3337bad0b26ddab43648428d94aabc"},
"erlex": {:hex, :erlex, "0.2.6", "c7987d15e899c7a2f34f5420d2a2ea0d659682c06ac607572df55a43753aa12e", [:mix], [], "hexpm", "2ed2e25711feb44d52b17d2780eabf998452f6efda104877a3881c2f8c0c0c75"},
Expand Down
28 changes: 28 additions & 0 deletions test/types/pact_decimal_test.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
defmodule Kadena.Types.PactDecimalTest do
@moduledoc """
`PactDecimal` struct definition tests.
"""

use ExUnit.Case

alias Kadena.Types.PactDecimal

describe "new/1" do
test "with a valid value" do
expected_value = Decimal.new("4.3333333")
%PactDecimal{value: ^expected_value, raw_value: "4.3333333"} = PactDecimal.new("4.3333333")
end

test "with a nil value" do
{:error, :invalid_decimal} = PactDecimal.new(nil)
end

test "with an atom value" do
{:error, :invalid_decimal} = PactDecimal.new(:atom)
end

test "with an empty list" do
{:error, :invalid_decimal} = PactDecimal.new([])
end
end
end
27 changes: 27 additions & 0 deletions test/types/pact_int_test.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
defmodule Kadena.Types.PactIntTest do
@moduledoc """
`PactInt` struct definition tests.
"""

use ExUnit.Case

alias Kadena.Types.PactInt

describe "new/1" do
test "with a valid integer" do
%PactInt{value: 500, raw_value: "500"} = PactInt.new(500)
end

test "with a nil value" do
{:error, :invalid_int} = PactInt.new(nil)
end

test "with an atom value" do
{:error, :invalid_int} = PactInt.new(:atom)
end

test "with an empty list" do
{:error, :invalid_int} = PactInt.new([])
end
end
end
45 changes: 45 additions & 0 deletions test/types/pact_literal_test.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
defmodule Kadena.Types.PactLiteralTest do
@moduledoc """
`PactLiteral` struct definition tests.
"""

use ExUnit.Case

alias Kadena.Types.{PactDecimal, PactInt, PactLiteral}

describe "new/1" do
test "with a valid string literal" do
%PactLiteral{literal: "string"} = PactLiteral.new("string")
end

test "with a valid number literal" do
%PactLiteral{literal: 123} = PactLiteral.new(123)
end

test "with a valid PactInt literal" do
pact_int = PactInt.new(123)
%PactLiteral{literal: ^pact_int} = PactLiteral.new(pact_int)
end

test "with a valid PactDecimal literal" do
pact_decimal = PactDecimal.new("4.634")
%PactLiteral{literal: ^pact_decimal} = PactLiteral.new(pact_decimal)
end

test "with a valid boolean literal" do
%PactLiteral{literal: true} = PactLiteral.new(true)
end

test "with a nil literal" do
{:error, :invalid_literal} = PactLiteral.new(nil)
end

test "with an atom literal" do
{:error, :invalid_literal} = PactLiteral.new(:atom)
end

test "with an empty list literal" do
{:error, :invalid_literal} = PactLiteral.new([])
end
end
end
43 changes: 43 additions & 0 deletions test/types/pact_literals_list_test.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
defmodule Kadena.Types.PactLiteralsListTest do
@moduledoc """
`PactLiteralsList` struct definition tests.
"""

use ExUnit.Case

alias Kadena.Types.{PactDecimal, PactInt, PactLiteral, PactLiteralsList}

describe "new/1" do
test "with a valid list" do
literal_string = PactLiteral.new("string")
literal_int = 123 |> PactInt.new() |> PactLiteral.new()
literal_decimal = "2.3333" |> PactDecimal.new() |> PactLiteral.new()
literal_boolean = PactLiteral.new(true)

literals_list = [literal_string, literal_int, literal_decimal, literal_boolean]
reversed_literals_list = [literal_boolean, literal_decimal, literal_int, literal_string]
%PactLiteralsList{list: ^reversed_literals_list} = PactLiteralsList.new(literals_list)
end

test "with an empty list value" do
%PactLiteralsList{list: []} = PactLiteralsList.new([])
end

test "with a nil value" do
{:error, :invalid_literal} = PactLiteralsList.new(nil)
end

test "with an atom value" do
{:error, :invalid_literal} = PactLiteralsList.new(:atom)
end

test "with a list of nil" do
{:error, :invalid_literal} = PactLiteralsList.new([nil])
end

test "when the list has invalid values" do
invalid_literals_list = [PactLiteral.new(true), :atom]
{:error, :invalid_literal} = PactLiteralsList.new(invalid_literals_list)
end
end
end
70 changes: 70 additions & 0 deletions test/types/pact_value_test.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
defmodule Kadena.Types.PactValueTest do
@moduledoc """
`PactValue` struct definition tests.
"""

use ExUnit.Case

alias Kadena.Types.{PactDecimal, PactInt, PactLiteral, PactLiteralsList, PactValue}

describe "new/1" do
setup do
literal_string = PactLiteral.new("string")
literal_int = 123 |> PactInt.new() |> PactLiteral.new()
literal_decimal = "2.3333" |> PactDecimal.new() |> PactLiteral.new()
literal_boolean = PactLiteral.new(true)

literal_list =
PactLiteralsList.new([literal_string, literal_int, literal_decimal, literal_boolean])

%{
literal_string: literal_string,
literal_int: literal_int,
literal_decimal: literal_decimal,
literal_boolean: literal_boolean,
literal_list: literal_list
}
end

test "with a valid string", %{literal_string: literal_string} do
%PactValue{value: ^literal_string} = PactValue.new(literal_string)
end

test "with a valid PactInt", %{literal_int: literal_int} do
%PactValue{value: ^literal_int} = PactValue.new(literal_int)
end

test "with a valid PactDecimal", %{literal_decimal: literal_decimal} do
%PactValue{value: ^literal_decimal} = PactValue.new(literal_decimal)
end

test "with a valid boolean", %{literal_boolean: literal_boolean} do
%PactValue{value: ^literal_boolean} = PactValue.new(literal_boolean)
end

test "with a valid PactLiteralList", %{literal_list: literal_list} do
%PactValue{value: ^literal_list} = PactValue.new(literal_list)
end

test "with an invalid list" do
{:error, :invalid_value} =
["string", :atom, true] |> PactLiteralsList.new() |> PactValue.new()
end

test "with a nil value" do
{:error, :invalid_value} = PactValue.new(nil)
end

test "with an atom value" do
{:error, :invalid_value} = PactValue.new(:atom)
end

test "with a list of nil" do
{:error, :invalid_value} = PactValue.new([nil])
end

test "with empty list value" do
{:error, :invalid_value} = PactValue.new([])
end
end
end