1Code.require_file "../../../installer/test/mix_helper.exs", __DIR__
2
3defmodule Phoenix.DupContext do
4end
5
6defmodule Mix.Tasks.Phx.Gen.ContextTest do
7  use ExUnit.Case
8  import MixHelper
9  alias Mix.Tasks.Phx.Gen
10  alias Mix.Phoenix.{Context, Schema}
11
12  setup do
13    Mix.Task.clear()
14    :ok
15  end
16
17  test "new context", config do
18    in_tmp_project config.test, fn ->
19      schema = Schema.new("Blog.Post", "posts", [], [])
20      context = Context.new("Blog", schema, [])
21
22      assert %Context{
23        alias: Blog,
24        base_module: Phoenix,
25        basename: "blog",
26        module: Phoenix.Blog,
27        web_module: PhoenixWeb,
28        schema: %Mix.Phoenix.Schema{
29          alias: Post,
30          human_plural: "Posts",
31          human_singular: "Post",
32          module: Phoenix.Blog.Post,
33          plural: "posts",
34          singular: "post"
35        }} = context
36
37      assert String.ends_with?(context.dir, "lib/phoenix/blog")
38      assert String.ends_with?(context.file, "lib/phoenix/blog/blog.ex")
39      assert String.ends_with?(context.test_file, "test/phoenix/blog/blog_test.exs")
40      assert String.ends_with?(context.schema.file, "lib/phoenix/blog/post.ex")
41    end
42  end
43
44  test "new nested context", config do
45    in_tmp_project config.test, fn ->
46      schema = Schema.new("Site.Blog.Post", "posts", [], [])
47      context = Context.new("Site.Blog", schema, [])
48
49      assert %Context{
50        alias: Site.Blog,
51        base_module: Phoenix,
52        basename: "blog",
53        module: Phoenix.Site.Blog,
54        web_module: PhoenixWeb,
55        schema: %Mix.Phoenix.Schema{
56          alias: Post,
57          human_plural: "Posts",
58          human_singular: "Post",
59          module: Phoenix.Site.Blog.Post,
60          plural: "posts",
61          singular: "post"
62        }} = context
63
64      assert String.ends_with?(context.dir, "lib/phoenix/site/blog")
65      assert String.ends_with?(context.file, "lib/phoenix/site/blog/blog.ex")
66      assert String.ends_with?(context.test_file, "test/phoenix/site/blog/blog_test.exs")
67      assert String.ends_with?(context.schema.file, "lib/phoenix/site/blog/post.ex")
68    end
69  end
70
71  test "new existing context", config do
72    in_tmp_project config.test, fn ->
73      File.mkdir_p!("lib/phoenix/blog")
74      File.write!("lib/phoenix/blog/blog.ex", """
75      defmodule Phoenix.Blog do
76      end
77      """)
78
79      schema = Schema.new("Blog.Post", "posts", [], [])
80      context = Context.new("Blog", schema, [])
81      assert Context.pre_existing?(context)
82      refute Context.pre_existing_tests?(context)
83
84      File.mkdir_p!("test/phoenix/blog")
85      File.write!(context.test_file, """
86      defmodule Phoenix.BlogTest do
87      end
88      """)
89      assert Context.pre_existing_tests?(context)
90    end
91  end
92
93  test "invalid mix arguments", config do
94    in_tmp_project config.test, fn ->
95      assert_raise Mix.Error, ~r/Expected the context, "blog", to be a valid module name/, fn ->
96        Gen.Context.run(~w(blog Post posts title:string))
97      end
98
99      assert_raise Mix.Error, ~r/Expected the schema, "posts", to be a valid module name/, fn ->
100        Gen.Context.run(~w(Post posts title:string))
101      end
102
103      assert_raise Mix.Error, ~r/The context and schema should have different names/, fn ->
104        Gen.Context.run(~w(Blog Blog blogs))
105      end
106
107      assert_raise Mix.Error, ~r/Invalid arguments/, fn ->
108        Gen.Context.run(~w(Blog.Post posts))
109      end
110
111      assert_raise Mix.Error, ~r/Invalid arguments/, fn ->
112        Gen.Context.run(~w(Blog Post))
113      end
114    end
115  end
116
117  test "generates context and handles existing contexts", config do
118    in_tmp_project config.test, fn ->
119      Gen.Context.run(~w(Blog Post posts slug:unique title:string))
120
121      assert_file "lib/phoenix/blog/post.ex", fn file ->
122        assert file =~ "field :title, :string"
123      end
124
125      assert_file "lib/phoenix/blog/blog.ex", fn file ->
126        assert file =~ "def get_post!"
127        assert file =~ "def list_posts"
128        assert file =~ "def create_post"
129        assert file =~ "def update_post"
130        assert file =~ "def delete_post"
131        assert file =~ "def change_post"
132      end
133
134      assert_file "test/phoenix/blog/blog_test.exs", fn file ->
135        assert file =~ "use Phoenix.DataCase"
136        assert file =~ "describe \"posts\" do"
137        assert file =~ "def post_fixture(attrs \\\\ %{})"
138      end
139
140      assert [path] = Path.wildcard("priv/repo/migrations/*_create_posts.exs")
141      assert_file path, fn file ->
142        assert file =~ "create table(:posts)"
143        assert file =~ "add :title, :string"
144        assert file =~ "create unique_index(:posts, [:slug])"
145      end
146
147      Gen.Context.run(~w(Blog Comment comments title:string))
148      assert_file "lib/phoenix/blog/comment.ex", fn file ->
149        assert file =~ "field :title, :string"
150      end
151
152      assert_file "test/phoenix/blog/blog_test.exs", fn file ->
153        assert file =~ "use Phoenix.DataCase"
154        assert file =~ "describe \"comments\" do"
155        assert file =~ "def comment_fixture(attrs \\\\ %{})"
156      end
157
158      assert [path] = Path.wildcard("priv/repo/migrations/*_create_comments.exs")
159      assert_file path, fn file ->
160        assert file =~ "create table(:comments)"
161        assert file =~ "add :title, :string"
162      end
163
164      assert_file "lib/phoenix/blog/blog.ex", fn file ->
165        assert file =~ "def get_comment!"
166        assert file =~ "def list_comments"
167        assert file =~ "def create_comment"
168        assert file =~ "def update_comment"
169        assert file =~ "def delete_comment"
170        assert file =~ "def change_comment"
171      end
172    end
173  end
174
175  test "generates context with no schema", config do
176    in_tmp_project config.test, fn ->
177      Gen.Context.run(~w(Blog Post posts title:string --no-schema))
178
179      refute_file "lib/phoenix/blog/post.ex"
180
181      assert_file "lib/phoenix/blog/blog.ex", fn file ->
182        assert file =~ "def get_post!"
183        assert file =~ "def list_posts"
184        assert file =~ "def create_post"
185        assert file =~ "def update_post"
186        assert file =~ "def delete_post"
187        assert file =~ "def change_post"
188        assert file =~ "raise \"TODO\""
189      end
190
191      assert_file "test/phoenix/blog/blog_test.exs", fn file ->
192        assert file =~ "use Phoenix.DataCase"
193        assert file =~ "describe \"posts\" do"
194        assert file =~ "def post_fixture(attrs \\\\ %{})"
195      end
196
197      assert Path.wildcard("priv/repo/migrations/*_create_posts.exs") == []
198    end
199  end
200end
201