Skip to content
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
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,16 @@ Once we've created a backup child we want to keep track of it, so we refine the

An application using outstanding would update expected, then do work based on what is outstanding given actual.Outstanding can be further processed (by your code) to detemine next action based on your priority of goals not met, constraints, business rules, etc.

## Acknowledgements

Thanks to Ilja Tkachuk for [comparable](https://github.com/coingaming/comparable) which was an exemplar.

Kudos to the [Elixir Core Team](https://elixir-lang.org/) for [elixir] https://github.com/elixir-lang/elixir 🚀

## Links
[Diffo.dev] (https://www.diffo.dev))
[`Ash Outstanding` docs](https://hexdocs.pm/ash_outstanding).

Documentation can be generated with [ExDoc](https://github.com/elixir-lang/ex_doc)
and published on [HexDocs](https://hexdocs.pm). Once published, the docs can
be found at <https://hexdocs.pm/outstanding>.
Expand Down
4 changes: 3 additions & 1 deletion lib/outstand.ex
Original file line number Diff line number Diff line change
Expand Up @@ -1394,6 +1394,8 @@ defmodule Outstand do
DateTime
iex> Outstand.type_of(~D[2025-02-25])
Date
iex> Outstand.type_of(self())
Other
```
"""
@spec type_of(any()) :: module()
Expand All @@ -1414,7 +1416,7 @@ defmodule Outstand do
is_list(term) -> List
is_map(term) -> Map
is_tuple(term) -> Tuple
true -> Any
true -> Other
end
end
end
Expand Down
2 changes: 1 addition & 1 deletion lib/outstanding.ex
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ defprotocol Outstanding do
@moduledoc """
Protocol for comparing expected and actual, highlighting outstanding expectations unmet by actual
"""
@fallback_to_any true
@fallback_to_any false
@type t :: Outstanding.t()
@type result :: nil | Outstanding.t()

Expand Down
18 changes: 0 additions & 18 deletions lib/outstanding/any.ex

This file was deleted.

14 changes: 14 additions & 0 deletions lib/outstanding/date.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
use Outstand

defoutstanding expected :: Date, actual :: Any do
if expected == nil or Outstand.type_of(actual) != Date do
expected
else
case Date.compare(expected, actual) do
:eq ->
nil
_ ->
expected
end
end
end
14 changes: 14 additions & 0 deletions lib/outstanding/date_time.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
use Outstand

defoutstanding expected :: DateTime, actual :: Any do
if expected == nil or Outstand.type_of(actual) != DateTime do
expected
else
case DateTime.compare(expected, actual) do
:eq ->
nil
_ ->
expected
end
end
end
14 changes: 14 additions & 0 deletions lib/outstanding/naive_date_time.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
use Outstand

defoutstanding expected :: NaiveDateTime, actual :: Any do
if expected == nil or Outstand.type_of(actual) != NaiveDateTime do
expected
else
case NaiveDateTime.compare(expected, actual) do
:eq ->
nil
_ ->
expected
end
end
end
14 changes: 14 additions & 0 deletions lib/outstanding/time.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
use Outstand

defoutstanding expected :: Time, actual :: Any do
if expected == nil or Outstand.type_of(actual) != Time do
expected
else
case Time.compare(expected, actual) do
:eq ->
nil
_ ->
expected
end
end
end
8 changes: 4 additions & 4 deletions mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,18 @@ defmodule Outstanding.MixProject do
deps: deps(),
# ex_doc
name: "Outstanding",
source_url: "https://github.com/matt-beanland/outstanding",
source_url: "https://github.com/diffo-dev/outstanding",
homepage_url: "https://diffo.dev/diffo/outstanding",
docs: [main: "readme", extras: ["README.md"]],
# hex.pm stuff
description: "Outstanding (a.k.a extent expected realised by actual) Elixir protocol",
description: "Elixir protocol calculating outstanding from expected and actual",
package: [
licenses: ["MIT"],
files: ["lib", "mix.exs", "README*", "VERSION*"],
maintainers: ["Matt Beanland"],
links: %{
"GitHub" => "https://github.com/matt-beanland/outstanding",
"Author's home page" => "https://diffo.dev"
"GitHub" => "https://github.com/diffo-dev/outstanding",
"Author's home page" => "https://www.diffo.dev"
}
]
]
Expand Down
27 changes: 0 additions & 27 deletions test/any_test.exs

This file was deleted.

16 changes: 16 additions & 0 deletions test/date_test.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
defmodule Outstanding.DateTest do
use ExUnit.Case
use Outstand

@now DateTime.utc_now() |> DateTime.to_naive()
@future DateTime.utc_now() |> DateTime.add(1, :day)|> DateTime.to_date()
@past DateTime.utc_now() |> DateTime.add(-1, :day) |> DateTime.to_date()

gen_something_outstanding_test("value outstanding, future", @now, @future)
gen_something_outstanding_test("value outstanding, past", @now, @past)
gen_something_outstanding_test("value outstanding, nil", @now, nil)
gen_nothing_outstanding_test("realized", @now, @now)
gen_result_outstanding_test("value result, future", @now, @future, @now)
gen_result_outstanding_test("value result, past", @now, @past, @now)
gen_result_outstanding_test("value result, nil", @now, nil, @now)
end
16 changes: 16 additions & 0 deletions test/date_time_test.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
defmodule Outstanding.DateTimeTest do
use ExUnit.Case
use Outstand

@now DateTime.utc_now()
@future DateTime.utc_now() |> DateTime.add(1, :day)
@past DateTime.utc_now() |> DateTime.add(-1, :day)

gen_something_outstanding_test("value outstanding, future", @now, @future)
gen_something_outstanding_test("value outstanding, past", @now, @past)
gen_something_outstanding_test("value outstanding, nil", @now, nil)
gen_nothing_outstanding_test("realized", @now, @now)
gen_result_outstanding_test("value result, future", @now, @future, @now)
gen_result_outstanding_test("value result, past", @now, @past, @now)
gen_result_outstanding_test("value result, nil", @now, nil, @now)
end
16 changes: 16 additions & 0 deletions test/naive_date_time_test.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
defmodule Outstanding.NaiveDateTimeTest do
use ExUnit.Case
use Outstand

@now DateTime.utc_now() |> DateTime.to_naive()
@future DateTime.utc_now() |> DateTime.add(1, :day)|> DateTime.to_naive()
@past DateTime.utc_now() |> DateTime.add(-1, :day) |> DateTime.to_naive()

gen_something_outstanding_test("value outstanding, future", @now, @future)
gen_something_outstanding_test("value outstanding, past", @now, @past)
gen_something_outstanding_test("value outstanding, nil", @now, nil)
gen_nothing_outstanding_test("realized", @now, @now)
gen_result_outstanding_test("value result, future", @now, @future, @now)
gen_result_outstanding_test("value result, past", @now, @past, @now)
gen_result_outstanding_test("value result, nil", @now, nil, @now)
end
38 changes: 38 additions & 0 deletions test/struct_test.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
defmodule Outstanding.StructTest do
use ExUnit.Case
use Outstand

@v0 :value0
@v1 :value1
@v2 :value2

defmodule XYZ do
defstruct [:x, :y, :z]
end

defoutstanding expected :: XYZ, actual :: Any do
case {expected, actual} do
{nil, nil} ->
nil
{_, ^expected} ->
nil
{%name{}, %name{}} ->
expected
|> Map.from_struct()
|> Outstanding.outstanding(Map.from_struct(actual))
|> Outstand.map_to_struct(name)
{_, _} ->
# not an exact match so default to outstanding
expected
end
end

gen_something_outstanding_test("key outstanding", %XYZ{x: @v0, y: @v1}, %XYZ{x: @v0, z: @v1})
gen_something_outstanding_test("value outstanding", %XYZ{x: @v0, y: @v1, z: @v2}, %XYZ{x: @v1, y: @v1, z: @v2})
gen_nothing_outstanding_test("realized", %XYZ{x: @v0, y: @v1, z: @v2}, %XYZ{x: @v0, y: @v1, z: @v2})
gen_nothing_outstanding_test("realized, no z expectation", %XYZ{x: @v0, y: @v1}, %XYZ{x: @v0, y: @v1})
gen_nothing_outstanding_test("realized, nil z expectation", %XYZ{x: @v0, y: @v1, z: nil}, %XYZ{x: @v0, y: @v1})
gen_nothing_outstanding_test("realized, extra item", %XYZ{x: @v0, y: @v1}, %XYZ{x: @v0, y: @v1, z: @v1})
gen_result_outstanding_test("key result", %XYZ{x: @v0, y: @v1}, %XYZ{x: @v0, z: @v1}, %XYZ{y: @v1})
gen_result_outstanding_test("value result", %XYZ{x: @v0, y: @v1}, %XYZ{x: @v1, y: @v1}, %XYZ{x: @v0})
end
16 changes: 16 additions & 0 deletions test/time_test.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
defmodule Outstanding.TimeTest do
use ExUnit.Case
use Outstand

@now DateTime.utc_now() |> DateTime.to_time()
@future DateTime.utc_now() |> DateTime.add(1, :hour)|> DateTime.to_time()
@past DateTime.utc_now() |> DateTime.add(-1, :hour) |> DateTime.to_time()

gen_something_outstanding_test("value outstanding, future", @now, @future)
gen_something_outstanding_test("value outstanding, past", @now, @past)
gen_something_outstanding_test("value outstanding, nil", @now, nil)
gen_nothing_outstanding_test("realized", @now, @now)
gen_result_outstanding_test("value result, future", @now, @future, @now)
gen_result_outstanding_test("value result, past", @now, @past, @now)
gen_result_outstanding_test("value result, nil", @now, nil, @now)
end