Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Elixir - How can you use an alias in doctest?

Tags:

testing

elixir

Is there a way to use a module alias in the doctests? I don't want to have to type out a long name every single time.

defmodule SomeLongModuleName.SubModule do
  alias SomeLongModuleName.SubModule, as: SubModule

  @doc """
      iex> SubModule.method(%{property_a: 1, property_b: 2) # CompileError
      3
  """
  def method(%{property_a: a, property_b: b) do
    a + b
  end
end

The example above shows a situation where I might want to use the alias to avoid long lines. Is it at all possible to use an alias in a doctest?

like image 308
Dylanthepiguy Avatar asked Apr 05 '17 22:04

Dylanthepiguy


People also ask

What does alias do in Elixir?

alias allows you to set up aliases for any given module name. The original List can still be accessed within Stats by the fully-qualified name Elixir.

What is elixir Doctest?

Doctests are specified by an indentation of four spaces followed by the iex> prompt in a documentation string. If a command spans multiple lines, you can use ...> , as in IEx. The expected result should start at the next line after iex> or ...> line(s) and is terminated either by a newline or a new iex> prefix.


4 Answers

There are two ways I can think of to not have to type the module name again and again.

  1. Use interpolation in your docs and use the aliased name:

    defmodule SomeLongModuleName.SubModule do
      alias SomeLongModuleName.SubModule, as: SubModule
    
      @doc """
          iex> #{SubModule}.method(%{property_a: 1, property_b: 2})
          3
      """
      def method(%{property_a: a, property_b: b}) do
        a + b
      end
    end
    
  2. Use just the function name without module and in your call to doctest from your tests, add import: true:

    defmodule SomeLongModuleName.SubModule do
      @doc """
          iex> method(%{property_a: 1, property_b: 2})
          3
      """
      def method(%{property_a: a, property_b: b}) do
        a + b
      end
    end
    
    doctest SomeLongModuleName.SubModule, import: true
    
like image 123
Dogbert Avatar answered Sep 18 '22 14:09

Dogbert


Building on the answer from lab419 and dylanthepiguy:

Module with doctest:

defmodule SomeLongModuleName.SubModule do
  @doc """
      iex> SubModule.add(x, y)
      3
  """
  def add(x, y) do
    x + y
  end
end

Test case for module with doctest:

defmodule SomeLongModuleName.SubModuleTest do
  use ExUnit.Case, async: true

  # Alias the submodule so we don't have to use the fully qualified name 
  alias SomeLongModuleName.SubModule

  doctest SomeLongModuleName.SubModule, import: true
end
like image 27
Jared Knipp Avatar answered Sep 21 '22 14:09

Jared Knipp


As mentioned by dylanthepiguy it is definitely a better solution to put the aliases into the testfile, just before the doctest line.

Instrumenting your code for tests is IMHO a code smell.

Also note that as: Submodule is the default and therefore unnecessary.

like image 24
lab419 Avatar answered Sep 18 '22 14:09

lab419


It turns out you can put a alias SomeLongModuleName.SubModule, as: SubModule line just before the test.

A better solution is to not put too many tests in the docs, and not use an alias. Then, in your test file you can put alias SomeLongModuleName.SubModule, as: SubModule to save.

like image 30
Dylanthepiguy Avatar answered Sep 20 '22 14:09

Dylanthepiguy