If Elixir was a more traditional object oriented language, I would probably do something simple like this:
static class DateManager {
public static timeOffsetSeconds = 0;
#if DEVELOPMENT
public static getTimeSeconds(){
return System.system_time(:second) + timeOffsetSeconds;
}
#else
public static getTimeSeconds(){
return System.system_time(:second);
}
#endif
}
Then in a development build, when one calls the following code, it is easy to simulate time moving forward for all modules that rely on the getTimeSeconds()
function:
runInitialFunction(); //depends internally on DateManager.getTimeSeconds()
DateManager.timeOffsetSeconds += 60*60; //move "system time" forward an hour
runSecondFunction(); //depends internally on DateManager.getTimeSeconds()
Compiler flags like above will even omit the “offset” function so it can’t be theoretically hijacked or abused in any way (won’t exist in real system).
We don’t have any easy manner of “state” however in Elixir without starting a GenServer or cache like ets or mnesia. I don’t want to get into the habit of starting random otherwise empty GenServers/ets/mnesia stores just so I can have “state” based functions like this. Not likely correct and while not terribly wasteful, I doubt this is intended.
Though it does seem possible as a simple hack. One can create one GenServer or ets entry for each “static” class that must hold some state on Application startup and register the PID or know the ets entry name. Perhaps simplest would be to make an ets entry for time offset. But then we don’t have compiler flags so in the real development you are wasting time going to the ets to check for a 0 value offset constantly.
Without re-writing every function everywhere to take a time_offset
input variable (which seems like also bad practice), what would be the simplest way to accomplish the above?
If I have something like the following that my modules are using to get time:
defmodule TimeManager do
def get_time_seconds() do
System.system_time(:second)
end
end
Is there any easy and safe way to introduce a step forward effect to it as needed in my tests?