From ab5e46ba625f7f62f99286a3fb48d010a292fa2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Britto?= Date: Fri, 20 May 2016 03:44:02 -0300 Subject: [PATCH] Disable overriding the async tag (#4649) The `async` config is meant to be set only by the time `ExUnit.Case` is used. With these changes we make sure a proper error will be raised if we eventually try to override it, either at the setup step, for the whole case as a moduletag, or as a regular test tag. --- lib/ex_unit/lib/ex_unit/callbacks.ex | 2 +- lib/ex_unit/lib/ex_unit/case.ex | 14 +++++---- lib/ex_unit/test/ex_unit_test.exs | 43 ++++++++++++++++++++++------ 3 files changed, 44 insertions(+), 15 deletions(-) diff --git a/lib/ex_unit/lib/ex_unit/callbacks.ex b/lib/ex_unit/lib/ex_unit/callbacks.ex index 9da33a9f69..5972ce87bc 100644 --- a/lib/ex_unit/lib/ex_unit/callbacks.ex +++ b/lib/ex_unit/lib/ex_unit/callbacks.ex @@ -146,7 +146,7 @@ defmodule ExUnit.Callbacks do ## Helpers - @reserved ~w(case test line file registered)a + @reserved [:case, :file, :line, :test, :async, :registered] @doc false def __merge__(_mod, context, :ok) do diff --git a/lib/ex_unit/lib/ex_unit/case.ex b/lib/ex_unit/lib/ex_unit/case.ex index 21c6631d55..1a05c0b650 100644 --- a/lib/ex_unit/lib/ex_unit/case.ex +++ b/lib/ex_unit/lib/ex_unit/case.ex @@ -119,9 +119,9 @@ defmodule ExUnit.Case do therefore reserved: * `:case` - the test case module - * `:test` - the test name - * `:line` - the line on which the test was defined * `:file` - the file on which the test was defined + * `:line` - the line on which the test was defined + * `:test` - the test name * `:async` - if the test case is in async mode * `:registered` - used for `ExUnit.Case.register_attribute/3` values @@ -191,7 +191,7 @@ defmodule ExUnit.Case do config :logger, backends: [] """ - @reserved [:case, :test, :file, :line, :registered] + @reserved [:case, :file, :line, :test, :async, :registered] @doc false defmacro __using__(opts) do @@ -207,7 +207,6 @@ defmodule ExUnit.Case do Enum.each [:ex_unit_tests, :tag, :moduletag, :ex_unit_registered], &Module.register_attribute(__MODULE__, &1, accumulate: true) - @moduletag async: async @before_compile ExUnit.Case @after_compile ExUnit.Case @ex_unit_async async @@ -326,12 +325,15 @@ defmodule ExUnit.Case do registered_attributes = Module.get_attribute(mod, :ex_unit_registered) registered = Map.new(registered_attributes, &{&1, Module.get_attribute(mod, &1)}) + tag = Module.get_attribute(mod, :tag) + async = Module.get_attribute(mod, :ex_unit_async) + tags = - (tags ++ Module.get_attribute(mod, :tag) ++ moduletag) + (tags ++ tag ++ moduletag) |> normalize_tags |> validate_tags |> Map.put_new(:type, :test) - |> Map.merge(%{line: line, file: file, registered: registered}) + |> Map.merge(%{line: line, file: file, registered: registered, async: async}) test = %ExUnit.Test{name: name, case: mod, tags: tags} Module.put_attribute(mod, :ex_unit_tests, test) diff --git a/lib/ex_unit/test/ex_unit_test.exs b/lib/ex_unit/test/ex_unit_test.exs index ca47a0a313..90ed7181a5 100644 --- a/lib/ex_unit/test/ex_unit_test.exs +++ b/lib/ex_unit/test/ex_unit_test.exs @@ -288,23 +288,30 @@ defmodule ExUnitTest do assert output =~ "2 tests, 1 failure, 1 skipped" end - test "raises on reserved tag in module" do + test "raises on reserved tag :file in module" do assert_raise RuntimeError, "cannot set tag :file because it is reserved by ExUnit", fn -> - defmodule ReservedTag do + defmodule ReservedTagFile do use ExUnit.Case - setup do - {:ok, file: :foo} - end - @tag file: "oops" test "sample", do: :ok end end end - test "raises on reserved tag in setup" do - defmodule ReservedSetupTag do + test "raises on reserved tag :async in module" do + assert_raise RuntimeError, "cannot set tag :async because it is reserved by ExUnit", fn -> + defmodule ReservedTagAsync do + use ExUnit.Case + + @tag async: true + test "sample", do: :ok + end + end + end + + test "raises on reserved tag :file in setup" do + defmodule ReservedSetupTagFile do use ExUnit.Case setup do @@ -323,6 +330,26 @@ defmodule ExUnitTest do assert output =~ "trying to set reserved field :file" end + test "raises on reserved tag :async in setup" do + defmodule ReservedSetupTagAsync do + use ExUnit.Case + + setup do + {:ok, async: true} + end + + test "sample", do: :ok + end + + ExUnit.Server.cases_loaded() + + output = capture_io(fn -> + assert ExUnit.run == %{failures: 1, skipped: 0, total: 1} + end) + + assert output =~ "trying to set reserved field :async" + end + test "does not raise on reserved tag in setup_all (lower priority)" do defmodule ReservedSetupAllTag do use ExUnit.Case