Skip to content

Instantly share code, notes, and snippets.

@idlehands
Last active May 20, 2023 11:28
Show Gist options
  • Save idlehands/f98c35fa46e1eaecc0f55c4313d17eea to your computer and use it in GitHub Desktop.
Save idlehands/f98c35fa46e1eaecc0f55c4313d17eea to your computer and use it in GitHub Desktop.
-info and links
defmodule MyApp.ContextToTestDataGeneratorMappings do
@context_to_test_data_generator_mappings %{
ExampleContext: MyApp.ExampleContextTestDataGenerator,
SecondContext: MyApp.SecondContextTestDataGenerator,
ThirdContext: MyApp.ThirdContextTestDataGenerator
}
def test_data_generator_for(context) do
Map.get(@context_to_test_data_generator_mappings, context, NotATestDataGenerator)
end
end
defmodule MyApp.DataCase do
use ExUnit.CaseTemplate
using(opts) do
test_data_generator =
case Keyword.get(opts, :context) do
{_, _, [context]} ->
MyApp.ContextToTestDataGeneratorMappings.test_data_generator_for(context)
_anything_else ->
MissingTestDataGeneratorContext
end
quote do
# .... all the imports and aliases
alias unquote(test_data_generator), as: TestDataGenerator
end
end
en
defmodule MyApp.ExampleContextTestDataGenerator do
use MyApp.TestDataGeneratorTemplate
alias MyApp.ExampleContextTestDataGenerator.Schemas.{Admin, User}
def admin_factory do
%Admin{}
end
def unregistered_user_factory do
%User{
state: :unregistered,
email: email()
}
end
def registered_user_factory do
%User{
id: uuid(),
dob: dob(),
email: email(),
first_name: first_name(),
last_name: last_name(),
state: :registered,
gender: random_value_from_ecto_enum(User, :gender),
phone_number: phone_number(),
phone_number_country_code: country_code(),
city: city(),
country: country(),
country_code: country_code(),
state: state(),
state_code: state_abbr(),
zip_code: zip_code(),
geo_location: geo_location()
}
end
end
defmodule MyApp.TestDataGeneratorTemplate do
defmacro __using__(_opts) do
quote do
require Ecto
use ExMachina.Ecto, repo: MyApp.Repo
def boolean, do: Enum.random([true, false])
def integer(range \\ 0..3_000), do: Enum.random(range)
def uuid, do: Ecto.UUID.generate()
def url, do: "https://" <> Faker.Internet.domain_name()
def mime_type, do: Faker.Lorem.word()
def device_type, do: sequence("device-")
# location
def city, do: Faker.Address.city()
def country, do: Faker.Address.country()
def state_code, do: Faker.Address.state_abbr()
def state, do: Faker.Address.state()
def zip_code, do: Faker.Address.zip_code()
def geo_location(lon \\ nil, lat \\ nil) do
longitude = lon || integer(1..100) / 1
latitude = lat || integer(1..100) / 1
%Geo.Point{
coordinates: {longitude, latitude},
properties: %{},
srid: 4326
}
end
# people things
def first_name, do: Faker.Person.En.first_name()
def last_name, do: Faker.Person.En.last_name()
def email, do: Faker.Internet.email()
def random_value_from_ecto_enum(schema, enum) when is_atom(schema) and is_atom(enum) do
schema
|> Ecto.Enum.values(enum)
|> Enum.random()
end
def random_value_from_ecto_dot_enum(enum) do
{name, _db_value} = Enum.random(enum.__enum_map__())
name
end
def datetime_in_the_past(offset \\ nil, granularity \\ :second) do
new_offset = offset || Enum.random(10..999_999_999)
DateTime.add(DateTime.utc_now(), -new_offset, granularity)
end
def datetime_in_the_past_unix(offset \\ nil, granularity \\ :second) do
DateTime.to_unix(datetime_in_the_past(offset, granularity), :microsecond)
end
end
end
end
defmodule MyApp.ExampleContext.UserTest do
use MyApp.DataCase, context: ExampleContext
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment