Qqwy

Qqwy

TypeCheck Core Team

Doctests: defining a struct in your doctest

I am working on the MapDiff library, so it works better when structs are passed to it.

I wrote the following two doctests:

  iex> defmodule Foo do
  ...>  defstruct a: 1, b: 2, c: 3
  ...> end
  ...> MapDiff.diff(%Foo{}, %Foo{a: 3})
  %{changed: :map_change, struct_name: Foo,
    value: %{a: %{added: 3, changed: :primitive_change, removed: 1},
      b: %{changed: :equal, value: 2}, c: %{changed: :equal, value: 3}}}

and:

  iex> defmodule Bar do
  ...> defstruct a: 1, b: 2, c: 3
  ...> end
  ...> defmodule Baz do
  ...> defstruct a: "foo", b: "bar", z: "baz"
  ...> end
  ...> MapDiff.diff(%Bar{}, %Baz{})
  %{added: %Baz{a: "foo", b: "bar", z: "baz"}, changed: :primitive_change,
    removed: %Bar{a: 1, b: 2, c: 3}}

However, this will not compile. When running mix test, the following error is thrown:

Compiling 1 file (.ex)
** (CompileError) (for doctest at) lib/map_diff.ex:105: MapDiffTest.Foo.__struct__/1 is undefined, cannot expand struct MapDiffTest.Foo
    (stdlib) lists.erl:1354: :lists.mapfoldl/3
    test/map_diff_test.exs:3: anonymous fn/3 in :elixir_compiler_1.__MODULE__/1
    (elixir) lib/enum.ex:1755: Enum."-reduce/3-lists^foldl/2-0-"/3
    test/map_diff_test.exs:3: (module)

I think that this is the case because Elixir tries to evaluate the outcome value decoupled from the example, which means that Foo, Bar and Baz (and their respective __struct__/1 implementations) are not in scope.

Now, how can these doctests be rewritten so:

  • they compile.
  • it is clear to people that Foo, Bar and Baz are normal structs they could define themselves?

Marked As Solved

vic

vic

Asdf Core Team

I guess the best would be to define those example structs somewhere like in test/support then just add a comment about their structure on your docs (indent the code four spaces so that it gets properly highlighted as elixir code) and then just import them for doctest:

@doc """
   For example suppose you define the following structs:

     defmodule Bar do
       defstruct a: 1, b: 2, c: 3
     end

      defmodule Baz do
        defstruct a: "foo", b: "bar", z: "baz"
      end   
   

       iex> import Foo
       iex> import Bar
       iex> MapDiff.diff(%Foo{}, %Bar{})
       %{added: %Baz ....}
"""

Also Liked

Qqwy

Qqwy

TypeCheck Core Team

Yes! This solution works wonderfully :slight_smile: .

I ended up simply defining the structs in the tests/map_diff_test.exs file, inside the MapDiffTest module, before doctest MapDiff is being called, because it seemed the most clear (as long as the code does not become much longer.)

Thank you very much :blush:!

Where Next?

Popular in Questions Top

senggen
Erlang/OTP 25 [erts-13.2.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] 15:22:35.803 [error] gen_event {lager_file_backend...
New
yawaramin
In the Dialyzer docs ( http://erlang.org/doc/man/dialyzer.html#requesting-or-suppressing-warnings-in-source-files ), there is a way to tu...
New
joaquinalcerro
Hi there, I am working with Ecto-Postgresql and I need to call all of the records from a specific table but the table has 40,000 record...
New
New
fireproofsocks
I’m working on defining a simple Ecto schema for a table (in PostGres), but I don’t see where I can define a column as NOT NULL. Conside...
New
vertexbuffer
Hello, can anybody help here..? I have a list of players and I what to delete an element, but every for loop the list is reverting to ori...
New
kostonstyle
Hi all I want to have a unix time, from the current time plus 1 hour. DateTime.now + 1 hour How to get it in elixir? Thanks
New
romenigld
I am trying to run a deploy with docker and I successfully runned with this command: docker build -t romenigld/blog-prod . but when I t...
New
vrod
I am using the Starship cross-shell prompt – it seems pretty nice, but I get some errors: [WARN] - (starship::utils): Executing command ...
New
jay1
Why is it that the mnesia database isn’t the most preferred database for use in Elixir/Phoenix?
New

Other popular topics Top

senggen
Erlang/OTP 25 [erts-13.2.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] 15:22:35.803 [error] gen_event {lager_file_backend...
New
sergio_101
I am VERY much an elixir newbie. I have taken one elixir course and one phoenix course on Udemy. During that course, I saw the instructor...
New
_russellb
I want to try my hand at web scraping. What tools/libraries do I need to use. I’m hoping to turn this into something professional so don’...
New
quazar
How to set Jason to encode all fields in ecto schema, I don’t care about security and implementing only is taking long list of attributes...
New
polypush135
As many of you may have realized by now (sorry for all the posts here) I’ve been working on a db problem where I’m trying to aggregate a ...
New
ashish173
I am using Ecto timestamps with postgres, I can see the timestamps() use the :naive_dateime but for my use case I wanted to store the ti...
New
fayddelight
I tried installing elixir 1.11.2 erlang 23.3.4 via asdf in my zsh shell. Enabled the versions locally and globally. When I list them ...
New
fireproofsocks
Forgive me if this is obvious, but how does one delete a database record WITHOUT selecting it first? https://hexdocs.pm/ecto/Ecto.Repo.h...
New
baxterw3b
Hi guys, i’m new in the Elixir world, and i have to say, that i love it! i’m having some problem to understand anonymous functions with ...
New
siddhant3030
Hi, I have to write a raw query for one of my project. But till now I have used ecto queries and don’t have much experience writing raw ...
New

We're in Beta

About us Mission Statement