Curated library of 38 atomic skills, 7 personas, and 1 orchestrator for Elixir and Phoenix development. Organized by category: fundamentals, phoenix, database, testing, auth, infrastructure, quality, security, integrations, tooling, frameworks, personas, and orchestration. Covers core Elixir patterns, Phoenix LiveView, Ecto, OTP, Oban, testing, security, deployment, real-time, and modern tooling (Req, Swoosh, Cachex, Broadway, Ash).
73
91%
Does it follow best practices?
Impact
—
No eval scenarios have been run
Advisory
Suggest reviewing before use
min_length: 1 or integer(1..100) when shrunk cases expose invalid generator inputs# mix.exs
defp deps do
[
{:stream_data, "~> 1.0", only: :test}
]
enddefmodule MyApp.StringUtilsTest do
use ExUnit.Case, async: true
use ExUnitProperties
property "reversing a string twice returns the original" do
check all string <- string(:ascii) do
assert string |> String.reverse() |> String.reverse() == string
end
end
property "length of reversed string equals original length" do
check all string <- string(:ascii) do
assert String.length(String.reverse(string)) == String.length(string)
end
end
end# Combine multiple generators with one_of
one_of([constant(:a), constant(:b), constant(:c)])
one_of([integer(), string(:ascii), boolean()])
# Compose generators with gen all
gen all x <- integer(0..100),
y <- integer(0..100),
x != y do
{x, y}
end
# Non-empty collections
list_of(integer(), min_length: 1)
map_of(string(:alphanumeric), integer())# Generate a valid email
def email_generator do
gen all name <- string(:alphanumeric, min_length: 3),
domain <- string(:alphanumeric, min_length: 3) do
"#{name}@#{domain}.com"
end
end
# Generate a user struct
def user_generator do
gen all email <- email_generator(),
age <- integer(18..120) do
%User{email: email, age: age}
end
end
# Use in tests
property "users have valid emails" do
check all user <- user_generator() do
assert user.email =~ ~r/@.*\.com$/
assert user.age >= 18 and user.age <= 120
end
enddefmodule MyApp.SortingTest do
use ExUnit.Case, async: true
use ExUnitProperties
property "sorted list is ordered" do
check all list <- list_of(integer()) do
sorted = Enum.sort(list)
sorted
|> Enum.chunk_every(2, 1, :discard)
|> Enum.each(fn [a, b] -> assert a <= b end)
end
end
property "sorted list contains same elements" do
check all list <- list_of(integer()) do
assert Enum.sort(list) |> Enum.frequencies() == Enum.frequencies(list)
end
end
endproperty "no list contains its own length as element" do
check all list <- list_of(integer()) do
# This will fail and shrink to a minimal example
refute list |> Enum.member?(length(list))
end
end
# StreamData will find and report:
# Failed with generated values: [0]
# (shrunk from something like [1, 5, 0, 3, 2])check all with appropriate generatorsmix test test/my_test.exs** (ExUnit.AssertionError)
Failed with generated values (after 3 successful runs):
* Clause: list <- list_of(integer())
Generated: [0]
(shrunk from [42, -7, 0, 15])min_length: 1, integer(1..100)); if it reveals a real bug, fix the implementation| Predecessor | This Skill | Successor |
|---|---|---|
| testing-essentials | property-based-testing | None (standalone) |