I have a library that uses option parser to format the output. The input is a string coming from the code itself, not a shell.
I am using this code to merge the switches given from the user with some predefined switches. The predefined switches are:
- The default hard coded in the module
- If are there any coming from config.exs merge them with the hard coded
If the user provides own switches, they will be merged to the predefined switches
defmodule Clouseau.Switches do
#...
@predefined_switches [
file: true,
full_path: false,
module: true,
line: true,
text: true,
border: false,
colors: false
]
#...
@default_switches Keyword.merge(
@predefined_switches,
Application.get_env(
:clouseau,
:default_switches,
@predefined_switches
)
)
#...
defp apply(switches) do
Keyword.merge(@default_switches, switches)
end
end
The @default_switches
module attribute is set during compile and Application.put_env(:clouseau, :default_switches, file: false)
has no effect.
How can I test that changing the config options changes the behavior of my libray?
So far I came up with this test file.
defmodule SwitchesTest do
use ClouseauCase
setup_all do
# Save current config if exists
env_switches = Application.get_env(:clousau, :default_switches)
# Put new config
Application.put_env(:clouseau, :default_switches, file: false)
# Recompile the file to refresh the @default_switches module attribute
Kernel.ParallelCompiler.compile(["lib/switches.ex"])
# On exit revert :default_switches config
on_exit(fn ->
# If it existed before put back the old one
if env_switches do
Application.put_env(:clouseau, :default_switches, env_switches)
# if didn't exist before just delete the current one
else
Application.delete_env(:clouseau, :default_switches)
end
# Regenerate the @default_switches module attribute
Kernel.ParallelCompiler.compile(["lib/switches.ex"])
end)
end
end
In the setup_all
block I save the current config, recompile the switches module, and on_exit
I revert back whatever config was there and recompile once again the switches module.
This works so far but it shows warnings during the test
warning: redefining module Clouseau.Switches (current version loaded from _build/test/lib/clouseau/ebin/Elixir.Clouseau.Switches.beam)
lib/switches.ex:1
.warning: redefining module Clouseau.Switches (current version defined in memory)
lib/switches.ex:1
Is there any better way to test the config options? Or maybe a better way to design the switches module but avoiding merging the hard coded switches with the configured every time in runtime?