Compare commits

...

60 commits
v0.8.1 ... main

Author SHA1 Message Date
a750c4a7ff chore(deps): update dependency ash to v3.4.6
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2024-09-07 02:23:32 +12:00
e77bd9de2a chore(deps): update dependency ash to v3.4.5
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2024-09-06 06:21:51 +12:00
39bd04b4af chore(deps): update dependency ash to v3.4.4
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2024-09-05 15:21:33 +12:00
13c5619376 chore(deps): update dependency ash to v3.4.3
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2024-09-05 03:19:43 +12:00
585766dd43 chore(deps): update dependency ash to v3.4.2
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2024-09-04 15:19:42 +12:00
3e18763805 chore(deps): update dependency spark to v2.2.23
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2024-08-30 10:20:57 +12:00
5e3aa634ec chore(deps): update dependency spark to v2.2.22
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2024-08-20 14:36:09 +12:00
90aad764f5
chore: unlock unused deps.
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2024-08-17 20:16:44 +12:00
b862125133
chore(deps): update dependency ash to v3.4.1 2024-08-17 20:16:34 +12:00
275110ba13
chore: fix failing test from Spark update
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2024-08-17 19:45:09 +12:00
ffc5407b2c chore(deps): update dependency spark to v2.2.21
Some checks failed
continuous-integration/drone/push Build is failing
continuous-integration/drone/pr Build is failing
renovate/artifacts Artifact file update failure
2024-08-15 22:11:29 +12:00
64d17a44c5 chore(deps): update dependency spark to v2.2.19
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2024-08-14 13:15:51 +12:00
3f17cd9e99 chore(deps): update dependency ash to v3.3.3
All checks were successful
continuous-integration/drone/push Build is passing
2024-08-08 16:32:27 +12:00
3a0ddd207e chore(deps): update dependency spark to v2.2.11
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2024-08-08 16:25:37 +12:00
324e15ca46 chore(deps): update dependency ash to v3.3.0
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2024-07-28 09:29:45 +12:00
43f5360130
chore: remove unused dependencies.
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2024-07-27 15:33:03 +12:00
43535e1d28 chore(deps): update dependency ash to v3.2.6
Some checks failed
continuous-integration/drone/push Build is failing
continuous-integration/drone/pr Build is failing
2024-07-27 06:36:30 +12:00
3bbc2d62a3 chore(deps): update dependency mix_audit to v2.1.4
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2024-07-17 02:32:00 +12:00
975f7335e5 chore(deps): update dependency ash to v3.1.8
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2024-07-15 06:35:47 +12:00
e11660011e chore(deps): update dependency ash to v3.1.7
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2024-07-15 03:39:47 +12:00
01962eb4c9 chore(deps): update dependency ash to v3.1.5
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2024-07-15 01:36:14 +12:00
a217a0fe11 chore(deps): update dependency ash to v3.1.4
Some checks failed
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is failing
2024-07-14 08:36:44 +12:00
60be63d5d2 chore(deps): update dependency earmark to v1.4.47
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2024-07-13 06:39:02 +12:00
8c4e71614d chore(deps): update dependency ash to v3.1.3
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2024-07-12 03:41:39 +12:00
e6df6910c7 chore(deps): update dependency ash to v3.1.2
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2024-07-11 04:35:20 +12:00
f767b723e0 chore(deps): update dependency erlang to v27.0.1
All checks were successful
continuous-integration/drone/push Build is passing
2024-07-11 02:55:57 +12:00
df1f1309e4 chore(deps): update dependency ash to v3.1.1
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2024-07-11 01:39:42 +12:00
7b041d3055 chore(deps): update dependency ash to v3.1.0
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2024-07-10 12:35:00 +12:00
334363db70 chore(deps): update dependency ex_doc to v0.34.2
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2024-07-09 03:43:11 +12:00
5d5edad3e5 chore(deps): update dependency elixir to v1.17.2
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2024-07-07 09:38:21 +12:00
e60facc798 docs: fix typo in related docs (#110)
All checks were successful
continuous-integration/drone/push Build is passing
Reviewed-on: #110
Co-authored-by: James Harton <james@harton.nz>
Co-committed-by: James Harton <james@harton.nz>
2024-07-04 10:29:21 +12:00
8cc0de70c4 chore(deps): update dependency spark to v2.2.7
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2024-07-03 10:35:55 +12:00
3eb46cb485 chore(deps): update dependency spark to v2.2.6
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2024-06-29 10:39:44 +12:00
452f827067 chore(deps): update dependency spark to v2.2.5
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2024-06-26 07:37:37 +12:00
e590e8d9e8 chore(deps): update dependency recase to v0.8.1
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2024-06-25 18:37:11 +12:00
e074b261d2 chore(deps): update dependency ash to v3.0.16
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2024-06-22 07:18:53 +12:00
fbabaa6c93 chore(deps): update dependency spark to v2.2.4
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2024-06-21 06:20:17 +12:00
59ea39c8ab chore(deps): update dependency ex_doc to v0.34.1
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2024-06-21 02:21:25 +12:00
e18319f525 chore(deps): update dependency elixir to v1.17.1
Some checks reported errors
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build encountered an error
2024-06-19 12:23:17 +12:00
957e2845c7 chore(deps): update dependency ash to v3.0.15
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2024-06-19 11:23:38 +12:00
00cdf8106d chore(deps): update dependency ash to v3.0.14
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2024-06-19 04:21:51 +12:00
d756b1ac12 chore(deps): update dependency spark to v2.2.3
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2024-06-18 10:21:11 +12:00
e8fb1bb305 chore(deps): update dependency spark to v2.2.2
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2024-06-18 06:19:26 +12:00
8dd043f13a chore(deps): update dependency ash to v3.0.13
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2024-06-18 04:18:45 +12:00
9a26e7a74b chore(deps): update dependency elixir to v1.17.0
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2024-06-15 13:43:13 +12:00
ccbe9a124f chore(deps): update dependency credo to v1.7.7
All checks were successful
continuous-integration/drone/push Build is passing
2024-06-15 13:27:13 +12:00
5d767a2e91 chore(deps): update dependency ash to v3.0.12
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2024-06-15 12:52:01 +12:00
13bd3c81b7 chore(deps): update dependency ash to v3.0.11
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2024-06-12 03:22:20 +12:00
a874167d10 chore(deps): update dependency spark to v2.1.24
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2024-06-11 03:19:53 +12:00
81b312b172 chore(deps): update dependency spark to v2.1.23
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2024-06-08 02:22:07 +12:00
f9dc1112f0 chore(deps): update dependency ash to v3.0.10
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2024-06-07 06:33:11 +12:00
c5adaf448b chore(deps): update dependency ash to v3.0.9
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2024-06-01 03:18:37 +12:00
85aa3e2f6e chore: release version v0.9.1
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/tag Build is passing
2024-05-30 20:54:44 +00:00
f8480ec8e7 fix: allow auto builds to be replaced by explicit relate commands.
All checks were successful
continuous-integration/drone/push Build is passing
2024-05-31 08:54:03 +12:00
Rebecca Le
d5be51556d bug: Add failing test for auto-build and relate options colliding 2024-05-31 08:54:03 +12:00
ebc07800b4 chore(deps): update dependency ex_doc to v0.34.0
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2024-05-31 01:24:03 +12:00
5368a030dd chore: release version v0.9.0
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/tag Build is passing
2024-05-28 21:51:27 +00:00
ef5d6462b9 feat: Auto build/load factory options. (#83)
All checks were successful
continuous-integration/drone/push Build is passing
New factory DSL options:

1. `auto_build` allows you to provide a list of relationships which must also be built when building that factory.
2. `auto_load` allows you to provide a load statement for relationships and calculations that must be loaded when building that factory.

Reviewed-on: #83
Co-authored-by: James Harton <james@harton.nz>
Co-committed-by: James Harton <james@harton.nz>
2024-05-29 09:50:43 +12:00
f46d9bb6b9 chore(deps): update dependency ash to v3.0.8
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2024-05-29 07:19:14 +12:00
4786ee97e6 chore(deps): update dependency recase to ~> 0.8
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2024-05-28 21:22:06 +12:00
13 changed files with 249 additions and 35 deletions

View file

@ -3,6 +3,8 @@ spark_locals_without_parens = [
after_build: 2,
attribute: 2,
attribute: 3,
auto_build: 1,
auto_load: 1,
before_build: 1,
before_build: 2,
domain: 1,

View file

@ -1,2 +1,2 @@
elixir 1.16.3
erlang 27.0
elixir 1.17.2
erlang 27.0.1

View file

@ -5,6 +5,24 @@ See [Conventional Commits](Https://conventionalcommits.org) for commit guideline
<!-- changelog -->
## [v0.9.1](https://harton.dev/james/smokestack/compare/v0.9.0...v0.9.1) (2024-05-30)
### Bug Fixes:
* allow auto builds to be replaced by explicit relate commands.
## [v0.9.0](https://harton.dev/james/smokestack/compare/v0.8.1...v0.9.0) (2024-05-28)
### Features:
* Auto build/load factory options. (#83)
## [v0.8.1](https://harton.dev/james/smokestack/compare/v0.8.0...v0.8.1) (2024-05-28)

View file

@ -38,7 +38,7 @@ add it directly to your `mix.exs`:
```elixir
def deps do
[
{:smokestack, "~> 0.8.1"},
{:smokestack, "~> 0.9.1"},
]
end
```

View file

@ -54,6 +54,10 @@ Define factories for a resource
* `:variant` (`t:atom/0`) - The name of a factory variant The default value is `:default`.
* `:auto_build` (one or a list of `t:atom/0`) - A list of relationships that should always be built when building this factory The default value is `[]`.
* `:auto_load` - An Ash "load statement" to always apply when building this factory The default value is `[]`.
##### after_build
@ -166,6 +170,8 @@ Define factories for a resource
| Name | Type | Default | Docs |
|------|------|---------|------|
| [`domain`](#smokestack-factory-domain){: #smokestack-factory-domain } | `module` | | The Ash Domain to use when evaluating loads |
| [`auto_build`](#smokestack-factory-auto_build){: #smokestack-factory-auto_build } | `atom \| list(atom)` | `[]` | A list of relationships that should always be built when building this factory |
| [`auto_load`](#smokestack-factory-auto_load){: #smokestack-factory-auto_load } | `atom \| keyword \| list(atom \| keyword)` | `[]` | An Ash "load statement" to always apply when building this factory |
## smokestack.factory.after_build

View file

@ -102,7 +102,7 @@ defmodule Smokestack.RecordBuilder do
{:ok, record_list} <- seed(attr_list, factory) do
record_list
|> maybe_hook(factory)
|> maybe_load(factory, load)
|> maybe_load(factory, List.wrap(load))
end
end
@ -113,7 +113,7 @@ defmodule Smokestack.RecordBuilder do
{:ok, record} <- seed(attrs, factory) do
record
|> maybe_hook(factory)
|> maybe_load(factory, load)
|> maybe_load(factory, List.wrap(load))
end
end
@ -145,13 +145,18 @@ defmodule Smokestack.RecordBuilder do
|> Resource.put_metadata(:variant, factory.variant)
end
defp maybe_load(record_or_records, _factory, []), do: {:ok, record_or_records}
defp maybe_load(record_or_records, %{auto_load: []}, []), do: {:ok, record_or_records}
defp maybe_load(_record_or_records, factory, _load) when is_nil(factory.domain),
do: {:error, "Unable to perform `load` operation without an Domain."}
defp maybe_load(record_or_records, factory, load),
do: Ash.load(record_or_records, load, domain: factory.domain)
defp maybe_load(record_or_records, factory, load) do
load =
factory.auto_load
|> Enum.concat(load)
Ash.load(record_or_records, load, domain: factory.domain)
end
defp maybe_hook(records, factory) when is_list(records) do
Enum.map(records, fn record ->

View file

@ -130,7 +130,7 @@ defmodule Smokestack.RelatedBuilder do
```elixir
author = insert!(Author)
post = insert!(Post, relate: [author: Author])
post = insert!(Post, relate: [author: author])
```
"""
]
@ -145,10 +145,12 @@ defmodule Smokestack.RelatedBuilder do
options
|> Keyword.get(:build, [])
|> List.wrap()
|> Enum.concat(factory.auto_build)
|> Enum.map(fn
{key, value} -> {key, value}
key when is_atom(key) -> {key, []}
end)
|> remove_explicit_relates(options)
|> Enum.reduce_while({:ok, attrs}, fn {relationship, nested_builds}, {:ok, attrs} ->
case build_related(
attrs,
@ -162,6 +164,18 @@ defmodule Smokestack.RelatedBuilder do
end)
end
defp remove_explicit_relates(builds, options) do
relates =
options[:relate]
|> List.wrap()
|> Map.new()
builds
|> Enum.reject(fn {key, _value} ->
is_map_key(relates, key)
end)
end
defp build_related(attrs, relationship, factory, options) do
ash_relationship = Resource.Info.relationship(factory.resource, relationship)
build_related(attrs, relationship, factory, options, ash_relationship)

View file

@ -8,6 +8,8 @@ defmodule Smokestack.Dsl.Factory do
defstruct __identifier__: nil,
after_build: [],
attributes: [],
auto_load: [],
auto_build: [],
before_build: [],
domain: nil,
module: nil,
@ -22,6 +24,8 @@ defmodule Smokestack.Dsl.Factory do
__identifier__: any,
after_build: [AfterBuild.t()],
attributes: [Attribute.t()],
auto_load: [atom] | Keyword.t(),
auto_build: [atom],
before_build: [BeforeBuild.t()],
domain: nil,
module: module,
@ -56,6 +60,18 @@ defmodule Smokestack.Dsl.Factory do
required: false,
doc: "The name of a factory variant",
default: :default
],
auto_build: [
type: {:wrap_list, :atom},
required: false,
doc: "A list of relationships that should always be built when building this factory",
default: []
],
auto_load: [
type: {:wrap_list, {:or, [:atom, :keyword_list]}},
required: false,
doc: "An Ash \"load statement\" to always apply when building this factory",
default: []
]
],
entities: [

View file

@ -9,7 +9,11 @@ defmodule Smokestack.Dsl.Verifier do
@impl true
@spec verify(Dsl.t()) :: :ok | {:error, DslError.t()}
def verify(dsl_state) do
error_info = %{module: Verifier.get_persisted(dsl_state, :module), path: [:smokestack]}
error_info = %{
module: Verifier.get_persisted(dsl_state, :module),
path: [:smokestack],
dsl_state: dsl_state
}
factories =
dsl_state
@ -68,7 +72,9 @@ defmodule Smokestack.Dsl.Verifier do
error_info =
Map.merge(error_info, %{resource: factory.resource, path: [:factory | error_info.path]})
with :ok <- verify_unique_attributes(factory, error_info) do
with :ok <- verify_unique_attributes(factory, error_info),
:ok <- verify_auto_build(factory, error_info),
:ok <- verify_auto_load(factory, error_info) do
factory
|> Map.get(:attributes, [])
|> Enum.filter(&is_struct(&1, Attribute))
@ -186,4 +192,76 @@ defmodule Smokestack.Dsl.Verifier do
)}
end
end
defp verify_auto_build(factory, error_info) do
error_info = %{error_info | path: [:auto_build | error_info.path]}
Enum.reduce_while(factory.auto_build, :ok, fn relationship, :ok ->
error_info = %{error_info | path: [relationship | error_info.path]}
with {:ok, relationship} <- verify_relationship(factory.resource, relationship, error_info),
:ok <- verify_factory_exists(relationship.destination, error_info) do
{:cont, :ok}
else
{:error, error} -> {:halt, {:error, error}}
end
end)
end
defp verify_relationship(resource, relationship, error_info) do
case Info.relationship(resource, relationship) do
nil ->
{:error,
DslError.exception(
module: error_info.module,
path: Enum.reverse(error_info.path),
message:
"The resource `#{inspect(resource)}` has no relationship named `#{inspect(relationship)}`."
)}
relationship ->
{:ok, relationship}
end
end
defp verify_factory_exists(resource, error_info) do
factory_exists? =
error_info.dsl_state
|> Verifier.get_entities([:smokestack])
|> Enum.any?(&(is_struct(&1, Factory) && &1.resource == resource))
if factory_exists? do
:ok
else
{:error,
DslError.exception(
module: error_info.module,
path: Enum.reverse(error_info.path),
message: "No factories defined for resource `#{inspect(resource)}`."
)}
end
end
defp verify_auto_load(factory, error_info) do
error_info = %{error_info | path: [:auto_load | error_info.path]}
Enum.reduce_while(factory.auto_load, :ok, fn load, :ok ->
error_info = %{error_info | path: [load | error_info.path]}
with nil <- Info.calculation(factory.resource, load),
nil <- Info.aggregate(factory.resource, load),
nil <- Info.relationship(factory.resource, load) do
{:halt,
{:error,
DslError.exception(
module: error_info.module,
path: Enum.reverse(error_info.path),
message:
"Expected an aggregate, calculation or relationship named `#{inspect(load)}` on resource `#{inspect(factory.resource)}`"
)}}
else
_ -> {:cont, :ok}
end
end)
end
end

View file

@ -1,7 +1,7 @@
defmodule Smokestack.MixProject do
use Mix.Project
@version "0.8.1"
@version "0.9.1"
@moduledoc """
Test factories for Ash resources.
@ -103,7 +103,7 @@ defmodule Smokestack.MixProject do
{:faker, "~> 0.18", opts},
{:git_ops, "~> 2.6", opts},
{:mix_audit, "~> 2.1", opts},
{:recase, "~> 0.7"},
{:recase, "~> 0.8"},
{:spark, "~> 2.1"}
]
end

View file

@ -1,37 +1,44 @@
%{
"ash": {:hex, :ash, "3.0.7", "6c37e092f53b1b21eb89596f600a652b2a601f84378f44fd5dd1cdec72eb1cc2", [:mix], [{:comparable, "~> 1.0", [hex: :comparable, repo: "hexpm", optional: false]}, {:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:ecto, "~> 3.7", [hex: :ecto, repo: "hexpm", optional: false]}, {:ets, "~> 0.8", [hex: :ets, repo: "hexpm", optional: false]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: false]}, {:picosat_elixir, "~> 0.2", [hex: :picosat_elixir, repo: "hexpm", optional: true]}, {:plug, ">= 0.0.0", [hex: :plug, repo: "hexpm", optional: true]}, {:reactor, ">= 0.8.1 and < 1.0.0-0", [hex: :reactor, repo: "hexpm", optional: false]}, {:simple_sat, ">= 0.1.1 and < 1.0.0-0", [hex: :simple_sat, repo: "hexpm", optional: true]}, {:spark, ">= 2.1.18 and < 3.0.0-0", [hex: :spark, repo: "hexpm", optional: false]}, {:splode, "~> 0.2", [hex: :splode, repo: "hexpm", optional: false]}, {:stream_data, "~> 1.0", [hex: :stream_data, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.1", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "9288ddb50fe727096c6f63fd82c631de2505dcd29bdfa50b5dc13c865f0bf434"},
"ash": {:hex, :ash, "3.4.6", "3210de7f0dff06d30f334fb05da13929779d70d861f95443c88ac4edab5a4500", [:mix], [{:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:ecto, "~> 3.7", [hex: :ecto, repo: "hexpm", optional: false]}, {:ets, "~> 0.8", [hex: :ets, repo: "hexpm", optional: false]}, {:igniter, ">= 0.3.11 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: false]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: false]}, {:owl, "~> 0.11", [hex: :owl, repo: "hexpm", optional: false]}, {:picosat_elixir, "~> 0.2", [hex: :picosat_elixir, repo: "hexpm", optional: true]}, {:plug, ">= 0.0.0", [hex: :plug, repo: "hexpm", optional: true]}, {:reactor, "~> 0.9", [hex: :reactor, repo: "hexpm", optional: false]}, {:simple_sat, ">= 0.1.1 and < 1.0.0-0", [hex: :simple_sat, repo: "hexpm", optional: true]}, {:spark, ">= 2.2.22 and < 3.0.0-0", [hex: :spark, repo: "hexpm", optional: false]}, {:splode, "~> 0.2", [hex: :splode, repo: "hexpm", optional: false]}, {:stream_data, "~> 1.0", [hex: :stream_data, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.1", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "4502b9cc192ac1e68cbbf7e7dd3de4180715190e320bc0a5d477af68d079f006"},
"bunt": {:hex, :bunt, "1.0.0", "081c2c665f086849e6d57900292b3a161727ab40431219529f13c4ddcf3e7a44", [:mix], [], "hexpm", "dc5f86aa08a5f6fa6b8096f0735c4e76d54ae5c9fa2c143e5a1fc7c1cd9bb6b5"},
"comparable": {:hex, :comparable, "1.0.0", "bb669e91cedd14ae9937053e5bcbc3c52bb2f22422611f43b6e38367d94a495f", [:mix], [{:typable, "~> 0.1", [hex: :typable, repo: "hexpm", optional: false]}], "hexpm", "277c11eeb1cd726e7cd41c6c199e7e52fa16ee6830b45ad4cdc62e51f62eb60c"},
"credo": {:hex, :credo, "1.7.6", "b8f14011a5443f2839b04def0b252300842ce7388f3af177157c86da18dfbeea", [:mix], [{:bunt, "~> 0.2.1 or ~> 1.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "146f347fb9f8cbc5f7e39e3f22f70acbef51d441baa6d10169dd604bfbc55296"},
"credo": {:hex, :credo, "1.7.7", "771445037228f763f9b2afd612b6aa2fd8e28432a95dbbc60d8e03ce71ba4446", [:mix], [{:bunt, "~> 0.2.1 or ~> 1.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "8bc87496c9aaacdc3f90f01b7b0582467b69b4bd2441fe8aae3109d843cc2f2e"},
"decimal": {:hex, :decimal, "2.1.1", "5611dca5d4b2c3dd497dec8f68751f1f1a54755e8ed2a966c2633cf885973ad6", [:mix], [], "hexpm", "53cfe5f497ed0e7771ae1a475575603d77425099ba5faef9394932b35020ffcc"},
"dialyxir": {:hex, :dialyxir, "1.4.3", "edd0124f358f0b9e95bfe53a9fcf806d615d8f838e2202a9f430d59566b6b53b", [:mix], [{:erlex, ">= 0.2.6", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "bf2cfb75cd5c5006bec30141b131663299c661a864ec7fbbc72dfa557487a986"},
"doctor": {:hex, :doctor, "0.21.0", "20ef89355c67778e206225fe74913e96141c4d001cb04efdeba1a2a9704f1ab5", [:mix], [{:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}], "hexpm", "a227831daa79784eb24cdeedfa403c46a4cb7d0eab0e31232ec654314447e4e0"},
"earmark": {:hex, :earmark, "1.4.46", "8c7287bd3137e99d26ae4643e5b7ef2129a260e3dcf41f251750cb4563c8fb81", [:mix], [], "hexpm", "798d86db3d79964e759ddc0c077d5eb254968ed426399fbf5a62de2b5ff8910a"},
"earmark_parser": {:hex, :earmark_parser, "1.4.39", "424642f8335b05bb9eb611aa1564c148a8ee35c9c8a8bba6e129d51a3e3c6769", [:mix], [], "hexpm", "06553a88d1f1846da9ef066b87b57c6f605552cfbe40d20bd8d59cc6bde41944"},
"ecto": {:hex, :ecto, "3.11.2", "e1d26be989db350a633667c5cda9c3d115ae779b66da567c68c80cfb26a8c9ee", [:mix], [{:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "3c38bca2c6f8d8023f2145326cc8a80100c3ffe4dcbd9842ff867f7fc6156c65"},
"earmark": {:hex, :earmark, "1.4.47", "7e7596b84fe4ebeb8751e14cbaeaf4d7a0237708f2ce43630cfd9065551f94ca", [:mix], [], "hexpm", "3e96bebea2c2d95f3b346a7ff22285bc68a99fbabdad9b655aa9c6be06c698f8"},
"earmark_parser": {:hex, :earmark_parser, "1.4.40", "f3534689f6b58f48aa3a9ac850d4f05832654fe257bf0549c08cc290035f70d5", [:mix], [], "hexpm", "cdb34f35892a45325bad21735fadb88033bcb7c4c296a999bde769783f53e46a"},
"ecto": {:hex, :ecto, "3.12.2", "bae2094f038e9664ce5f089e5f3b6132a535d8b018bd280a485c2f33df5c0ce1", [:mix], [{:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "492e67c70f3a71c6afe80d946d3ced52ecc57c53c9829791bfff1830ff5a1f0c"},
"erlex": {:hex, :erlex, "0.2.6", "c7987d15e899c7a2f34f5420d2a2ea0d659682c06ac607572df55a43753aa12e", [:mix], [], "hexpm", "2ed2e25711feb44d52b17d2780eabf998452f6efda104877a3881c2f8c0c0c75"},
"ets": {:hex, :ets, "0.9.0", "79c6a6c205436780486f72d84230c6cba2f8a9920456750ddd1e47389107d5fd", [:mix], [], "hexpm", "2861fdfb04bcaeff370f1a5904eec864f0a56dcfebe5921ea9aadf2a481c822b"},
"ex_check": {:hex, :ex_check, "0.16.0", "07615bef493c5b8d12d5119de3914274277299c6483989e52b0f6b8358a26b5f", [:mix], [], "hexpm", "4d809b72a18d405514dda4809257d8e665ae7cf37a7aee3be6b74a34dec310f5"},
"ex_doc": {:hex, :ex_doc, "0.33.0", "690562b153153c7e4d455dc21dab86e445f66ceba718defe64b0ef6f0bd83ba0", [:mix], [{:earmark_parser, "~> 1.4.39", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_c, ">= 0.1.0", [hex: :makeup_c, repo: "hexpm", optional: true]}, {:makeup_elixir, "~> 0.14 or ~> 1.0", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1 or ~> 1.0", [hex: :makeup_erlang, repo: "hexpm", optional: false]}, {:makeup_html, ">= 0.1.0", [hex: :makeup_html, repo: "hexpm", optional: true]}], "hexpm", "3f69adc28274cb51be37d09b03e4565232862a4b10288a3894587b0131412124"},
"ex_doc": {:hex, :ex_doc, "0.34.2", "13eedf3844ccdce25cfd837b99bea9ad92c4e511233199440488d217c92571e8", [:mix], [{:earmark_parser, "~> 1.4.39", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_c, ">= 0.1.0", [hex: :makeup_c, repo: "hexpm", optional: true]}, {:makeup_elixir, "~> 0.14 or ~> 1.0", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1 or ~> 1.0", [hex: :makeup_erlang, repo: "hexpm", optional: false]}, {:makeup_html, ">= 0.1.0", [hex: :makeup_html, repo: "hexpm", optional: true]}], "hexpm", "5ce5f16b41208a50106afed3de6a2ed34f4acfd65715b82a0b84b49d995f95c1"},
"faker": {:hex, :faker, "0.18.0", "943e479319a22ea4e8e39e8e076b81c02827d9302f3d32726c5bf82f430e6e14", [:mix], [], "hexpm", "bfbdd83958d78e2788e99ec9317c4816e651ad05e24cfd1196ce5db5b3e81797"},
"file_system": {:hex, :file_system, "1.0.0", "b689cc7dcee665f774de94b5a832e578bd7963c8e637ef940cd44327db7de2cd", [:mix], [], "hexpm", "6752092d66aec5a10e662aefeed8ddb9531d79db0bc145bb8c40325ca1d8536d"},
"git_cli": {:hex, :git_cli, "0.3.0", "a5422f9b95c99483385b976f5d43f7e8233283a47cda13533d7c16131cb14df5", [:mix], [], "hexpm", "78cb952f4c86a41f4d3511f1d3ecb28edb268e3a7df278de2faa1bd4672eaf9b"},
"git_ops": {:hex, :git_ops, "2.6.1", "cc7799a68c26cf814d6d1a5121415b4f5bf813de200908f930b27a2f1fe9dad5", [:mix], [{:git_cli, "~> 0.2", [hex: :git_cli, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "ce62d07e41fe993ec22c35d5edb11cf333a21ddaead6f5d9868fcb607d42039e"},
"jason": {:hex, :jason, "1.4.1", "af1504e35f629ddcdd6addb3513c3853991f694921b1b9368b0bd32beb9f1b63", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "fbb01ecdfd565b56261302f7e1fcc27c4fb8f32d56eab74db621fc154604a7a1"},
"glob_ex": {:hex, :glob_ex, "0.1.8", "f7ef872877ca2ae7a792ab1f9ff73d9c16bf46ecb028603a8a3c5283016adc07", [:mix], [], "hexpm", "9e39d01729419a60a937c9260a43981440c43aa4cadd1fa6672fecd58241c464"},
"igniter": {:hex, :igniter, "0.3.24", "791a91650ffab9d66b9a3011c66491f767577ad55c363f820cc188554207ee6f", [:mix], [{:glob_ex, "~> 0.1.7", [hex: :glob_ex, repo: "hexpm", optional: false]}, {:inflex, "~> 2.0", [hex: :inflex, repo: "hexpm", optional: false]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}, {:nimble_options, "~> 1.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:owl, "~> 0.9", [hex: :owl, repo: "hexpm", optional: false]}, {:rewrite, "~> 0.9", [hex: :rewrite, repo: "hexpm", optional: false]}, {:sourceror, "~> 1.4", [hex: :sourceror, repo: "hexpm", optional: false]}, {:spitfire, ">= 0.1.3 and < 1.0.0-0", [hex: :spitfire, repo: "hexpm", optional: false]}, {:ucwidth, "~> 0.2", [hex: :ucwidth, repo: "hexpm", optional: false]}], "hexpm", "2e1d336534c6129bae0db043fae650303b96974c0488c290191d6d4c61ec9a9f"},
"inflex": {:hex, :inflex, "2.1.0", "a365cf0821a9dacb65067abd95008ca1b0bb7dcdd85ae59965deef2aa062924c", [:mix], [], "hexpm", "14c17d05db4ee9b6d319b0bff1bdf22aa389a25398d1952c7a0b5f3d93162dd8"},
"iterex": {:hex, :iterex, "0.1.2", "58f9b9b9a22a55cbfc7b5234a9c9c63eaac26d276b3db80936c0e1c60355a5a6", [:mix], [], "hexpm", "2e103b8bcc81757a9af121f6dc0df312c9a17220f302b1193ef720460d03029d"},
"jason": {:hex, :jason, "1.4.4", "b9226785a9aa77b6857ca22832cffa5d5011a667207eb2a0ad56adb5db443b8a", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "c5eb0cab91f094599f94d55bc63409236a8ec69a21a67814529e8d5f6cc90b3b"},
"libgraph": {:hex, :libgraph, "0.16.0", "3936f3eca6ef826e08880230f806bfea13193e49bf153f93edcf0239d4fd1d07", [:mix], [], "hexpm", "41ca92240e8a4138c30a7e06466acc709b0cbb795c643e9e17174a178982d6bf"},
"makeup": {:hex, :makeup, "1.1.2", "9ba8837913bdf757787e71c1581c21f9d2455f4dd04cfca785c70bbfff1a76a3", [:mix], [{:nimble_parsec, "~> 1.2.2 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "cce1566b81fbcbd21eca8ffe808f33b221f9eee2cbc7a1706fc3da9ff18e6cac"},
"makeup_elixir": {:hex, :makeup_elixir, "0.16.2", "627e84b8e8bf22e60a2579dad15067c755531fea049ae26ef1020cad58fe9578", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.2.3 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "41193978704763f6bbe6cc2758b84909e62984c7752b3784bd3c218bb341706b"},
"makeup_erlang": {:hex, :makeup_erlang, "1.0.0", "6f0eff9c9c489f26b69b61440bf1b238d95badae49adac77973cbacae87e3c2e", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "ea7a9307de9d1548d2a72d299058d1fd2339e3d398560a0e46c27dab4891e4d2"},
"mix_audit": {:hex, :mix_audit, "2.1.3", "c70983d5cab5dca923f9a6efe559abfb4ec3f8e87762f02bab00fa4106d17eda", [:make, :mix], [{:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: false]}, {:yaml_elixir, "~> 2.9", [hex: :yaml_elixir, repo: "hexpm", optional: false]}], "hexpm", "8c3987100b23099aea2f2df0af4d296701efd031affb08d0746b2be9e35988ec"},
"mix_audit": {:hex, :mix_audit, "2.1.4", "0a23d5b07350cdd69001c13882a4f5fb9f90fbd4cbf2ebc190a2ee0d187ea3e9", [:make, :mix], [{:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}, {:yaml_elixir, "~> 2.11", [hex: :yaml_elixir, repo: "hexpm", optional: false]}], "hexpm", "fd807653cc8c1cada2911129c7eb9e985e3cc76ebf26f4dd628bb25bbcaa7099"},
"nimble_options": {:hex, :nimble_options, "1.1.1", "e3a492d54d85fc3fd7c5baf411d9d2852922f66e69476317787a7b2bb000a61b", [:mix], [], "hexpm", "821b2470ca9442c4b6984882fe9bb0389371b8ddec4d45a9504f00a66f650b44"},
"nimble_parsec": {:hex, :nimble_parsec, "1.4.0", "51f9b613ea62cfa97b25ccc2c1b4216e81df970acd8e16e8d1bdc58fef21370d", [:mix], [], "hexpm", "9c565862810fb383e9838c1dd2d7d2c437b3d13b267414ba6af33e50d2d1cf28"},
"reactor": {:hex, :reactor, "0.8.2", "b2be82b1c3402537d06a8f85bb1849f72cb6b4be140495cb8956de7aec2fdebd", [:mix], [{:libgraph, "~> 0.16", [hex: :libgraph, repo: "hexpm", optional: false]}, {:spark, "~> 2.0", [hex: :spark, repo: "hexpm", optional: false]}, {:splode, "~> 0.2", [hex: :splode, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.2", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "c35eb23b77cc77ba922af108722ac93257899e35cfdd18882f0e659ad2cac9f3"},
"recase": {:hex, :recase, "0.7.0", "3f2f719f0886c7a3b7fe469058ec539cb7bbe0023604ae3bce920e186305e5ae", [:mix], [], "hexpm", "36f5756a9f552f4a94b54a695870e32f4e72d5fad9c25e61bc4a3151c08a4e0c"},
"sourceror": {:hex, :sourceror, "1.2.1", "b415255ad8bd05f0e859bb3d7ea617f6c2a4a405f2a534a231f229bd99b89f8b", [:mix], [], "hexpm", "e4d97087e67584a7585b5fe3d5a71bf8e7332f795dd1a44983d750003d5e750c"},
"spark": {:hex, :spark, "2.1.22", "a36400eede64c51af578de5fdb5a5aaa3e0811da44bcbe7545fce059bd2a990b", [:mix], [{:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}, {:sourceror, "~> 1.0", [hex: :sourceror, repo: "hexpm", optional: false]}], "hexpm", "f764611d0b15ac132e72b2326539acc11fc4e63baa3e429f541bca292b5f7064"},
"owl": {:hex, :owl, "0.11.0", "2cd46185d330aa2400f1c8c3cddf8d2ff6320baeff23321d1810e58127082cae", [:mix], [{:ucwidth, "~> 0.2", [hex: :ucwidth, repo: "hexpm", optional: true]}], "hexpm", "73f5783f0e963cc04a061be717a0dbb3e49ae0c4bfd55fb4b78ece8d33a65efe"},
"reactor": {:hex, :reactor, "0.9.1", "082f8e9b1fd7586c0a016c2fb533835fec7eaef5ffb0263abb4473106c20b1ca", [:mix], [{:igniter, "~> 0.2", [hex: :igniter, repo: "hexpm", optional: false]}, {:iterex, "~> 0.1", [hex: :iterex, repo: "hexpm", optional: false]}, {:libgraph, "~> 0.16", [hex: :libgraph, repo: "hexpm", optional: false]}, {:spark, "~> 2.0", [hex: :spark, repo: "hexpm", optional: false]}, {:splode, "~> 0.2", [hex: :splode, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.2", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "7191ddf95fdd2b65770a57a2e38dd502a94909e51ac8daf497330e67fc032dc3"},
"recase": {:hex, :recase, "0.8.1", "ab98cd35857a86fa5ca99036f575241d71d77d9c2ab0c39aacf1c9b61f6f7d1d", [:mix], [], "hexpm", "9fd8d63e7e43bd9ea385b12364e305778b2bbd92537e95c4b2e26fc507d5e4c2"},
"rewrite": {:hex, :rewrite, "0.10.5", "6afadeae0b9d843b27ac6225e88e165884875e0aed333ef4ad3bf36f9c101bed", [:mix], [{:glob_ex, "~> 0.1", [hex: :glob_ex, repo: "hexpm", optional: false]}, {:sourceror, "~> 1.0", [hex: :sourceror, repo: "hexpm", optional: false]}], "hexpm", "51cc347a4269ad3a1e7a2c4122dbac9198302b082f5615964358b4635ebf3d4f"},
"sourceror": {:hex, :sourceror, "1.6.0", "9907884e1449a4bd7dbaabe95088ed4d9a09c3c791fb0103964e6316bc9448a7", [:mix], [], "hexpm", "e90aef8c82dacf32c89c8ef83d1416fc343cd3e5556773eeffd2c1e3f991f699"},
"spark": {:hex, :spark, "2.2.23", "78f0a1b0b713a91ad556fe9dc19ec92d977aaa0803cce2e255d90e58b9045c2a", [:mix], [{:igniter, ">= 0.2.6 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: false]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}, {:sourceror, "~> 1.2", [hex: :sourceror, repo: "hexpm", optional: false]}], "hexpm", "a354b5cd7c3f021e3cd1da5a033b7643fe7b3c71c96b96d9f500a742f40c94db"},
"spitfire": {:hex, :spitfire, "0.1.3", "7ea0f544005dfbe48e615ed90250c9a271bfe126914012023fd5e4b6b82b7ec7", [:mix], [], "hexpm", "d53b5107bcff526a05c5bb54c95e77b36834550affd5830c9f58760e8c543657"},
"splode": {:hex, :splode, "0.2.4", "71046334c39605095ca4bed5d008372e56454060997da14f9868534c17b84b53", [:mix], [], "hexpm", "ca3b95f0d8d4b482b5357954fec857abd0fa3ea509d623334c1328e7382044c2"},
"stream_data": {:hex, :stream_data, "1.0.0", "c1380747a4650902732696861d5cb66ad3cb1cc93f31c2c8498bf87cddbabe2d", [:mix], [], "hexpm", "acd53e27c66c617d466f42ec77a7f59e5751f6051583c621ccdb055b9690435d"},
"telemetry": {:hex, :telemetry, "1.2.1", "68fdfe8d8f05a8428483a97d7aab2f268aaff24b49e0f599faa091f1d4e7f61c", [:rebar3], [], "hexpm", "dad9ce9d8effc621708f99eac538ef1cbe05d6a874dd741de2e689c47feafed5"},
"typable": {:hex, :typable, "0.3.0", "0431e121d124cd26f312123e313d2689b9a5322b15add65d424c07779eaa3ca1", [:mix], [], "hexpm", "880a0797752da1a4c508ac48f94711e04c86156f498065a83d160eef945858f8"},
"stream_data": {:hex, :stream_data, "1.1.1", "fd515ca95619cca83ba08b20f5e814aaf1e5ebff114659dc9731f966c9226246", [:mix], [], "hexpm", "45d0cd46bd06738463fd53f22b70042dbb58c384bb99ef4e7576e7bb7d3b8c8c"},
"telemetry": {:hex, :telemetry, "1.3.0", "fedebbae410d715cf8e7062c96a1ef32ec22e764197f70cda73d82778d61e7a2", [:rebar3], [], "hexpm", "7015fc8919dbe63764f4b4b87a95b7c0996bd539e0d499be6ec9d7f3875b79e6"},
"ucwidth": {:hex, :ucwidth, "0.2.0", "1f0a440f541d895dff142275b96355f7e91e15bca525d4a0cc788ea51f0e3441", [:mix], [], "hexpm", "c1efd1798b8eeb11fb2bec3cafa3dd9c0c3647bee020543f0340b996177355bf"},
"yamerl": {:hex, :yamerl, "0.10.0", "4ff81fee2f1f6a46f1700c0d880b24d193ddb74bd14ef42cb0bcf46e81ef2f8e", [:rebar3], [], "hexpm", "346adb2963f1051dc837a2364e4acf6eb7d80097c0f53cbdc3046ec8ec4b4e6e"},
"yaml_elixir": {:hex, :yaml_elixir, "2.9.0", "9a256da867b37b8d2c1ffd5d9de373a4fda77a32a45b452f1708508ba7bbcb53", [:mix], [{:yamerl, "~> 0.10", [hex: :yamerl, repo: "hexpm", optional: false]}], "hexpm", "0cb0e7d4c56f5e99a6253ed1a670ed0e39c13fc45a6da054033928607ac08dfc"},
"yaml_elixir": {:hex, :yaml_elixir, "2.11.0", "9e9ccd134e861c66b84825a3542a1c22ba33f338d82c07282f4f1f52d847bd50", [:mix], [{:yamerl, "~> 0.10", [hex: :yamerl, repo: "hexpm", optional: false]}], "hexpm", "53cc28357ee7eb952344995787f4bb8cc3cecbf189652236e9b163e8ce1bc242"},
}

View file

@ -1,6 +1,7 @@
defmodule Smokestack.DslTest do
use ExUnit.Case, async: true
alias Spark.Error.DslError
alias Support.Author
defmodule Post do
@moduledoc false
@ -18,6 +19,18 @@ defmodule Smokestack.DslTest do
attribute :title, :string
end
relationships do
belongs_to :author, Author
end
calculations do
calculate :title_first_word, :string, expr(title |> string_split() |> at(0))
end
actions do
defaults [:read]
end
end
defmodule Factory do
@ -145,4 +158,63 @@ defmodule Smokestack.DslTest do
assert %Post{__metadata__: %{wat: true}} = AfterBuildFactory.insert!(Post)
end
test "auto builds can be specified in the factory" do
defmodule AutoBuildFactory do
@moduledoc false
use Smokestack
factory Post do
attribute :title, &Faker.Company.catch_phrase/0
auto_build :author
end
factory Author do
attribute :name, &Faker.Internet.email/0
attribute :email, &Faker.Person.name/0
end
end
assert %Post{author: %Author{}} = AutoBuildFactory.insert!(Post)
end
test "auto builds can be overridden at runtime" do
defmodule AutoBuildRelateFactory do
@moduledoc false
use Smokestack
factory Post do
attribute :title, &Faker.Company.catch_phrase/0
auto_build :author
end
factory Author do
attribute :name, &Faker.Internet.email/0
attribute :email, &Faker.Person.name/0
end
end
author = AutoBuildRelateFactory.insert!(Author)
post = AutoBuildRelateFactory.insert!(Post, relate: [author: author])
# The auto-build should not be used - the existing author should be used
assert Ash.count!(Author, domain: Support.Domain) == 1
assert post.author.id == author.id
end
test "auto loads can be specified in the factory" do
defmodule AutoLoadFactory do
@moduledoc false
use Smokestack
factory Post do
attribute :title, &Faker.Company.catch_phrase/0
auto_load :title_first_word
domain Support.Domain
end
end
assert post = AutoLoadFactory.insert!(Post)
assert post.title_first_word == post.title |> String.split(" ") |> List.first()
end
end

View file

@ -78,10 +78,6 @@ defmodule Smokestack.OptionTest do
test "it validates all options" do
assert {:error, error} = insert(Author, sss: 2)
message = Exception.message(error)
assert message =~ "unknown options [:sss]"
for key <- ~w[:variant :load :count :build :relate :attrs] do
assert message =~ key
end
assert message =~ ~r/required :[a-z]+ option not found/
end
end