Skip to content

Commit

Permalink
Remove factory/2 and assoc/3
Browse files Browse the repository at this point in the history
  • Loading branch information
jsteiner committed Nov 12, 2015
1 parent 7bc14ed commit 70a0481
Show file tree
Hide file tree
Showing 7 changed files with 63 additions and 104 deletions.
17 changes: 8 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,27 +36,26 @@ defmodule MyApp.Factory do
# without Ecto
use ExMachina

def factory(:user, _attrs) do
def factory(:user) do
%User{
name: "Jane Smith",
email: sequence(:email, &"email-#{&1}@example.com"),
}
end

def factory(:article, attrs) do
def factory(:article) do
%Article{
title: "Use ExMachina!",
# has_many/has_one associations are inserted when you call `create`
# associations are inserted when you call `create`
comments: [build(:comment)],
# only available in ExMachina.Ecto
author: assoc(attrs, :author, factory: :user),
author: build(:user),
}
end

def factory(:comment, attrs) do
def factory(:comment) do
%Comment{
text: "It's great!",
article: assoc(attrs, :article),
article: build(:article),
}
end
end
Expand Down Expand Up @@ -155,7 +154,7 @@ defining `save_record/1` in your module.
defmodule MyApp.JsonFactory do
use ExMachina

def factory(:user, _attrs) do
def factory(:user) do
%User{name: "John"}
end

Expand All @@ -177,7 +176,7 @@ or `create_json` to return encoded JSON objects.
defmodule MyApp.Factory do
use ExMachina.Ecto, repo: MyApp.Repo

def factory(:user, _attrs) do
def factory(:user) do
%User{name: "John"}
end

Expand Down
31 changes: 23 additions & 8 deletions lib/ex_machina.ex
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,10 @@ defmodule ExMachina do
The factory and assoc macros have been removed. Please use regular
functions instead.
def factory(#{factory_name}, attrs) do
def factory(#{factory_name}) do
%{
...
some_assoc: assoc(attrs, :some_assoc)
some_assoc: build(:some_assoc)
...
}
end
Expand All @@ -93,7 +93,7 @@ defmodule ExMachina do
## Examples
def factory(:user, _attrs) do
def factory(:user) do
%{
# Will generate "[email protected]" then "[email protected]", etc.
email: sequence(:email, &"me-\#{&1}@foo.com")
Expand All @@ -107,7 +107,7 @@ defmodule ExMachina do
## Example
def factory(:user, _attrs) do
def factory(:user) do
%{name: "John Doe", admin: false}
end
Expand All @@ -116,7 +116,7 @@ defmodule ExMachina do
"""
def build(module, factory_name, attrs \\ %{}) do
attrs = Enum.into(attrs, %{})
module.factory(factory_name, attrs) |> Map.merge(attrs)
module.factory(factory_name) |> Map.merge(attrs)
end

@doc """
Expand Down Expand Up @@ -205,10 +205,25 @@ defmodule ExMachina do
@doc """
Raises a helpful error if no factory is defined.
"""
def factory(factory_name, _attrs) do
def factory(factory_name) do
raise UndefinedFactory, factory_name
end

def factory(factory_name, _) do
raise """
Use of factory/2 has been removed. Please use factory/1 instead.
belongs_to associations can be defined with build.
def factory(#{factory_name}) do
%{
...
some_assoc: build(:some_assoc)
...
}
end
"""
end

@doc """
Saves a record when `create` is called. Uses Ecto if using ExMachina.Ecto
Expand All @@ -223,7 +238,7 @@ defmodule ExMachina do
defmodule MyApp.Factory do
use ExMachina.Ecto, repo: MyApp.Repo
def factory(:user, _attrs) do
def factory(:user) do
%User{name: "John"}
end
end
Expand All @@ -235,7 +250,7 @@ defmodule ExMachina do
# Note, we are not using ExMachina.Ecto
use ExMachina
def factory(:user, _attrs) do
def factory(:user) do
%User{name: "John"}
end
Expand Down
47 changes: 13 additions & 34 deletions lib/ex_machina/ecto.ex
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,18 @@ defmodule ExMachina.Ecto do
ExMachina.Ecto.save_record(__MODULE__, @repo, record)
end

defp assoc(attrs, factory_name, opts \\ []) do
ExMachina.Ecto.assoc(__MODULE__, attrs, factory_name, opts)
defp assoc(_, factory_name, _) do
raise """
assoc/3 has been removed. Please use build instead. Built records will be automatically saved when you call create.
def factory(#{factory_name}) do
%{
...
some_assoc: build(:some_assoc)
...
}
end
"""
end
end
else
Expand Down Expand Up @@ -46,7 +56,7 @@ defmodule ExMachina.Ecto do
## Example
def factory(:user, _attrs) do
def factory(:user) do
%MyApp.User{name: "John Doe", admin: false}
end
Expand All @@ -68,37 +78,6 @@ defmodule ExMachina.Ecto do
raise ArgumentError, "#{inspect record} is not an Ecto model. Use `build` instead."
end

@doc """
Gets a factory from the passed in attrs, or builds if none is present
## Examples
attrs = %{user: %{name: "Someone"}}
# Returns attrs.user
assoc(attrs, :user)
attrs = %{}
# Builds and returns new instance based on :user factory
assoc(attrs, :user)
attrs = %{}
# Builds and returns new instance based on :user factory
assoc(attrs, :author, factory: :user)
"""
def assoc(module, attrs, factory_name, opts \\ []) do
case Map.get(attrs, factory_name) do
nil -> build_assoc(module, factory_name, opts)
record -> record
end
end

defp build_assoc(module, _factory_name, factory: factory_name) do
ExMachina.build(module, factory_name)
end
defp build_assoc(module, factory_name, _opts) do
ExMachina.build(module, factory_name)
end

defp get_assocs(%{__struct__: struct}) do
for a <- struct.__schema__(:associations) do
{a, struct.__schema__(:association, a)}
Expand Down
4 changes: 2 additions & 2 deletions test/ex_machina/ecto_embeds_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,14 @@ defmodule ExMachina.EctoEmbedsTest do
defmodule Factory do
use ExMachina.Ecto, repo: TestRepo

def factory(:settings, _attrs) do
def factory(:settings) do
%Settings{
email_signature: "Mr. John Doe",
send_emails: true
}
end

def factory(:user, _attrs) do
def factory(:user) do
%User{
name: "John Doe",
admin: false,
Expand Down
10 changes: 5 additions & 5 deletions test/ex_machina/ecto_has_many_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ defmodule ExMachina.EctoHasManyTest do
defmodule Factory do
use ExMachina.Ecto, repo: TestRepo

def factory(:package, _attrs) do
def factory(:package) do
%Package{
description: "Package that just got ordered",
statuses: [
Expand All @@ -38,7 +38,7 @@ defmodule ExMachina.EctoHasManyTest do
}
end

def factory(:shipped_package, _attrs) do
def factory(:shipped_package) do
%Package{
description: "Package that got shipped",
statuses: [
Expand All @@ -49,16 +49,16 @@ defmodule ExMachina.EctoHasManyTest do
}
end

def factory(:package_status, _attrs) do
def factory(:package_status) do
%PackageStatus{
status: "ordered"
}
end

def factory(:invoice, attrs) do
def factory(:invoice) do
%Invoice{
title: "Invoice for shipped package",
package: assoc(attrs, :package, factory: :shipped_package)
package: build(:shipped_package)
}
end
end
Expand Down
52 changes: 9 additions & 43 deletions test/ex_machina/ecto_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -38,37 +38,37 @@ defmodule ExMachina.EctoTest do
defmodule Factory do
use ExMachina.Ecto, repo: TestRepo

def factory(:user, _attrs) do
def factory(:user) do
%User{
name: "John Doe",
admin: false
}
end

def factory(:user_map, _attrs) do
def factory(:user_map) do
%{
id: 3,
name: "John Doe",
admin: false
}
end

def factory(:article, attrs) do
def factory(:article) do
%Article{
title: "My Awesome Article",
author: assoc(attrs, :author, factory: :user)
author: build(:user)
}
end

def factory(:comment, attrs) do
def factory(:comment) do
%Comment{
body: "Great article!",
article: assoc(attrs, :article),
user: assoc(attrs, :user)
article: build(:article),
user: build(:user)
}
end

def factory(:company_account, _attrs) do
def factory(:company_account) do
%CompanyAccount{
name: "BigBizAccount",
user: build(:user)
Expand Down Expand Up @@ -170,42 +170,8 @@ defmodule ExMachina.EctoTest do
end
end

test "assoc/3 returns the passed in key if it exists" do
existing_account = %{id: 1, plan_type: "free"}
attrs = %{account: existing_account}

assert ExMachina.Ecto.assoc(Factory, attrs, :account) == existing_account
end

test "assoc/3 does not insert a record if it exists" do
existing_account = %{id: 1, plan_type: "free"}
attrs = %{account: existing_account}

ExMachina.Ecto.assoc(Factory, attrs, :account)

assert TestRepo.all(User) == []
end

test "assoc/3 builds and returns a factory if one was not in attrs" do
attrs = %{}

user = ExMachina.Ecto.assoc(Factory, attrs, :user)

refute TestRepo.one(User)
assert user.name == "John Doe"
refute user.admin
end

test "assoc/3 can specify a factory for the association" do
attrs = %{}

account = ExMachina.Ecto.assoc(Factory, attrs, :account, factory: :user)

assert account == Factory.build(:user)
refute TestRepo.one(User)
end

test "can use assoc/3 in a factory to override associations" do
test "passed in attrs can override associations" do
my_article = Factory.create(:article, title: "So Deep")

comment = Factory.create(:comment, article: my_article)
Expand Down
6 changes: 3 additions & 3 deletions test/ex_machina_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@ defmodule ExMachinaTest do
defmodule Factory do
use ExMachina

def factory(:user, _attrs) do
def factory(:user) do
%{
id: 3,
name: "John Doe",
admin: false
}
end

def factory(:email, _attrs) do
def factory(:email) do
%{
email: sequence(:email, &"me-#{&1}@foo.com")
}
Expand All @@ -27,7 +27,7 @@ defmodule ExMachinaTest do
defmodule NoSaveFunction do
use ExMachina

def factory(:foo, _attrs) do
def factory(:foo) do
%{foo: :bar}
end
end
Expand Down

0 comments on commit 70a0481

Please sign in to comment.