所以,這裏有一個有趣的問題,我查看elixir中的模塊屬性文檔,即底部的http://elixir-lang.org/getting-started/module-attributes.html,它提到它們可以用作ExUnit中的方法註釋。使用模塊註釋作爲方法屬性
不幸的是,基本上沒有關於如何實現這一點的信息,並且查看ExUnit代碼讓我迷失了方向。看起來我需要確定最接近該屬性的方法,說它們以某種方式關聯(儘管可能是錯誤的)。
任何想法,我可能會了解這一點?
所以,這裏有一個有趣的問題,我查看elixir中的模塊屬性文檔,即底部的http://elixir-lang.org/getting-started/module-attributes.html,它提到它們可以用作ExUnit中的方法註釋。使用模塊註釋作爲方法屬性
不幸的是,基本上沒有關於如何實現這一點的信息,並且查看ExUnit代碼讓我迷失了方向。看起來我需要確定最接近該屬性的方法,說它們以某種方式關聯(儘管可能是錯誤的)。
任何想法,我可能會了解這一點?
它的工作原理是這樣的。看看ExUnit.Case的源代碼。
首先,查看__using__
宏,因爲它將在測試用例中使用時首先被調用。特別要注意here
Enum.each [:ex_unit_tests, :tag, :describetag, :moduletag, :ex_unit_registered],
&Module.register_attribute(__MODULE__, &1, accumulate: true)
這將註冊@tag
和一堆多個屬性的積累。閱讀Module.register_attribute/3的文檔,你會看到它意味着隨時調用屬性,該值會附加到以前的屬性列表。
然後記test/3
宏,特別here
quote bind_quoted: [var: var, contents: contents, message: message] do
name = ExUnit.Case.register_test(__ENV__, :test, message, [])
def unquote(name)(unquote(var)), do: unquote(contents)
end
注意調用ExUnit.Case.register_test/4
。看着它,特別是here
tag = Module.delete_attribute(mod, :tag)
它獲取的標籤,直到這裏,並刪除它們。並且通過具有標籤,並且測試的名稱,它調用(here)
test = %ExUnit.Test{name: name, case: mod, tags: tags}
Module.put_attribute(mod, :ex_unit_tests, test)
從而節省了與另一個屬性標籤內沿測試。
,最後,請注意這裏
@doc false
defmacro __before_compile__(_) do
quote do
def __ex_unit__(:case) do
%ExUnit.TestCase{name: __MODULE__, tests: @ex_unit_tests}
end
end
end
功能__ex_unit__/1
被稱爲ExUnit.Runner.run_case/3獲得的每一種情況下的內部測試的信息。
你明白了嗎?使用累積屬性,在你的宏內部調用一個函數,該函數總是得到屬性的當前值並清除它,然後對這個值做任何你想要的事情,因爲你知道調用宏時它總是這樣。
我希望已經足夠清楚了,如果您需要更多解釋,請留下評論。
PS。我只是閱讀源代碼來找出這一點。知道它的工作原理令人興奮。
我接受答案,因爲這是非常重要的。我實際上已經想出了這一點,並打開了這個小庫來註釋任何方法。正如你所說的,重要的部分是accumulate:register_attribute的標籤。它的相當不錯,elixir並不真的支持方法註釋,但是這種語言已經足夠讓你自己去做:) – Owen
哦,如果其他人對此感興趣,還有一件事需要提及。 ExUnit要求調用測試宏,它依次檢索並刪除之前定義的屬性。如果我們正在定義一個方法,那麼將不會調用我們可以插入的宏,但幸運的是有一個模塊生命週期方法,我們可以使用@on_defenition(請參閱https://hexdocs.pm/elixir/Module.html) – Owen
你見過這個頁面嗎? http://elixir-lang.org/docs/master/ex_unit/ExUnit.Case.html更具體地說,該頁面的這一部分似乎與您的問題相關:http://elixir-lang.org/docs/master/ex_unit/ ExUnit.Case.html#module-tags在這個頁面上有什麼東西不清楚嗎?你的問題對我來說不是很清楚。 –
我不知道你的表現,我是的ExUnit有@tags作爲功能的註釋,我的問題是他們如何實現這一點。我實際上解決了這個問題,現在我又遇到了另一個問題,即在編譯時能夠對這些註釋做些有用的事情。在這裏我的付出:https://github.com/chrisjowen/annotatable – Owen
好的,然後把我的評論作爲一個跡象,它不是非常清楚你想知道什麼。 –