Skip to content

Commit

Permalink
Add PactValue struct definitions
Browse files Browse the repository at this point in the history
  • Loading branch information
Santiago Botero committed Sep 16, 2022
1 parent e73eb8e commit fbb1b56
Show file tree
Hide file tree
Showing 12 changed files with 315 additions and 0 deletions.
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 "With an invalid list item with invalid value" 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

0 comments on commit fbb1b56

Please sign in to comment.