From 662824e038c5f714e83225517835f6a8e0b00b06 Mon Sep 17 00:00:00 2001 From: jenswehner Date: Tue, 29 Jun 2021 10:26:12 +0200 Subject: [PATCH 1/3] reworking the testing --- content/code/R/even_time_difference.R | 12 +++++++++ ...ature_sol.R => even_time_difference_sol.R} | 0 content/code/R/reactor_temperature.R | 16 ----------- content/code/cpp/even_time_difference.cpp | 11 ++++++++ ...e_sol.cpp => even_time_difference_sol.cpp} | 4 +-- content/code/cpp/reactor_temperature.cpp | 15 ----------- ...mperature.f90 => even_time_difference.f90} | 0 ...e_sol.f90 => even_time_difference_sol.f90} | 0 ...temperature.jl => even_time_difference.jl} | 0 ...ure_sol.jl => even_time_difference_sol.jl} | 0 content/code/python/even_time_difference.py | 10 +++++++ .../code/python/even_time_difference_sol.py | 6 +++++ content/code/python/reactor_temperature.py | 10 ------- .../code/python/reactor_temperature_sol.py | 5 ---- content/test-design.md | 27 +++++++++---------- 15 files changed, 54 insertions(+), 62 deletions(-) create mode 100644 content/code/R/even_time_difference.R rename content/code/R/{reactor_temperature_sol.R => even_time_difference_sol.R} (100%) delete mode 100644 content/code/R/reactor_temperature.R create mode 100644 content/code/cpp/even_time_difference.cpp rename content/code/cpp/{reactor_temperature_sol.cpp => even_time_difference_sol.cpp} (80%) delete mode 100644 content/code/cpp/reactor_temperature.cpp rename content/code/fortran/{reactor_temperature.f90 => even_time_difference.f90} (100%) rename content/code/fortran/{reactor_temperature_sol.f90 => even_time_difference_sol.f90} (100%) rename content/code/julia/{reactor_temperature.jl => even_time_difference.jl} (100%) rename content/code/julia/{reactor_temperature_sol.jl => even_time_difference_sol.jl} (100%) create mode 100644 content/code/python/even_time_difference.py create mode 100644 content/code/python/even_time_difference_sol.py delete mode 100644 content/code/python/reactor_temperature.py delete mode 100644 content/code/python/reactor_temperature_sol.py diff --git a/content/code/R/even_time_difference.R b/content/code/R/even_time_difference.R new file mode 100644 index 0000000..6411f0a --- /dev/null +++ b/content/code/R/even_time_difference.R @@ -0,0 +1,12 @@ +#' Check time to now even +#' +#' Checks whether time difference between now and given time in seconds is even +#' +#' @param seconds input time in whole seconds +#' +#' @return returns true or false +check_time_to_now_even <- function(seconds) { + if(seconds < 0) stop('received negative input') + now <- as.integer(format(Sys.time(), '%s')) + return((seconds - now) %% 2 == 0) +} diff --git a/content/code/R/reactor_temperature_sol.R b/content/code/R/even_time_difference_sol.R similarity index 100% rename from content/code/R/reactor_temperature_sol.R rename to content/code/R/even_time_difference_sol.R diff --git a/content/code/R/reactor_temperature.R b/content/code/R/reactor_temperature.R deleted file mode 100644 index 69b16cb..0000000 --- a/content/code/R/reactor_temperature.R +++ /dev/null @@ -1,16 +0,0 @@ -# reactor <- namespace::makeNamespace("reactor") -# assign("max_temperature", 100, env = reactor) -# namespaceExport(reactor, "max_temperature") - -#' Checks whether the temperature is above max_temperature -#' and returns the status. -#' -#' @param temperature_celsius The temperature of the core -#' @return 1 if the temperature is in range, otherwise 0 -check_reactor_temperature <- function(temperature_celsius) { - if (temperature_celsius > reactor::max_temperature) - status <- 1 - else - status <- 0 - status -} diff --git a/content/code/cpp/even_time_difference.cpp b/content/code/cpp/even_time_difference.cpp new file mode 100644 index 0000000..5d43f30 --- /dev/null +++ b/content/code/cpp/even_time_difference.cpp @@ -0,0 +1,11 @@ +#include +#include + +/* Checks whether temperature is above max_temperature and returns a status. */ +bool check_time_to_now_even(int seconds) { + if(seconds<0){ + throw std::runtime_error('received negative input'); + } + auto now = std::chrono::system_clock::now().time_since_epoch(); + return std::chrono::duration_cast(now).count()%seconds ==0; +} diff --git a/content/code/cpp/reactor_temperature_sol.cpp b/content/code/cpp/even_time_difference_sol.cpp similarity index 80% rename from content/code/cpp/reactor_temperature_sol.cpp rename to content/code/cpp/even_time_difference_sol.cpp index 37a1cb6..8215c38 100644 --- a/content/code/cpp/reactor_temperature_sol.cpp +++ b/content/code/cpp/even_time_difference_sol.cpp @@ -1,9 +1,9 @@ // Changing variables included from headers (monkey patching) is not possible in C++. #include -#include "reactor.hpp" -TEST_CASE("Check reactor state", "[reactor_state]") { +TEST_CASE("Check time difference", "[reactor_state]") { REQUIRE(check_reactor_temperature(99) == ReactorState::FINE); REQUIRE(check_reactor_temperature(100) == ReactorState::FINE); REQUIRE(check_reactor_temperature(101) == ReactorState::CRITICAL); +} \ No newline at end of file diff --git a/content/code/cpp/reactor_temperature.cpp b/content/code/cpp/reactor_temperature.cpp deleted file mode 100644 index cbbfee5..0000000 --- a/content/code/cpp/reactor_temperature.cpp +++ /dev/null @@ -1,15 +0,0 @@ -#include "constants.hpp" -/* ^--- Defines the max_temperature constant as: -* namespace constants { -* constexpr double max_temperature = 100.0; -* } -*/ - -enum class ReactorState : int { FINE, CRITICAL }; - -/* Checks whether temperature is above max_temperature and returns a status. */ -ReactorState check_reactor_temperature(double temperature_celsius) { - return temperature_celsius > constants::max_temperature - ? ReactorState::CRITICAL - : ReactorState::FINE; -} diff --git a/content/code/fortran/reactor_temperature.f90 b/content/code/fortran/even_time_difference.f90 similarity index 100% rename from content/code/fortran/reactor_temperature.f90 rename to content/code/fortran/even_time_difference.f90 diff --git a/content/code/fortran/reactor_temperature_sol.f90 b/content/code/fortran/even_time_difference_sol.f90 similarity index 100% rename from content/code/fortran/reactor_temperature_sol.f90 rename to content/code/fortran/even_time_difference_sol.f90 diff --git a/content/code/julia/reactor_temperature.jl b/content/code/julia/even_time_difference.jl similarity index 100% rename from content/code/julia/reactor_temperature.jl rename to content/code/julia/even_time_difference.jl diff --git a/content/code/julia/reactor_temperature_sol.jl b/content/code/julia/even_time_difference_sol.jl similarity index 100% rename from content/code/julia/reactor_temperature_sol.jl rename to content/code/julia/even_time_difference_sol.jl diff --git a/content/code/python/even_time_difference.py b/content/code/python/even_time_difference.py new file mode 100644 index 0000000..22841b5 --- /dev/null +++ b/content/code/python/even_time_difference.py @@ -0,0 +1,10 @@ +import time +def check_time_to_now_even(seconds): + """ + Checks whether time difference between now and given time in seconds is even + """ + if seconds < 0: + raise ValueError('received negative input') + + now=time.time() + return (seconds-now)%2 == 0 \ No newline at end of file diff --git a/content/code/python/even_time_difference_sol.py b/content/code/python/even_time_difference_sol.py new file mode 100644 index 0000000..d0b0b22 --- /dev/null +++ b/content/code/python/even_time_difference_sol.py @@ -0,0 +1,6 @@ +def test_check_time(monkeypatch): + def mocktime(): + return 2 + monkeypatch.setattr(time,"time",mocktime) + assert check_time_to_now_even(0) == 1 + assert check_time_to_now_even(1) == 0 \ No newline at end of file diff --git a/content/code/python/reactor_temperature.py b/content/code/python/reactor_temperature.py deleted file mode 100644 index 7e998f5..0000000 --- a/content/code/python/reactor_temperature.py +++ /dev/null @@ -1,10 +0,0 @@ -def check_reactor_temperature(temperature_celsius): """ - Checks whether temperature is above max_temperature - and returns a status. - """ - from reactor import max_temperature - if temperature_celsius > max_temperature: - status = 1 - else: - status = 0 - return status diff --git a/content/code/python/reactor_temperature_sol.py b/content/code/python/reactor_temperature_sol.py deleted file mode 100644 index d01317c..0000000 --- a/content/code/python/reactor_temperature_sol.py +++ /dev/null @@ -1,5 +0,0 @@ -def test_set_temp(monkeypatch): - monkeypatch.setattr(reactor, "max_temperature", 100) - assert check_reactor_temperature(99) == 0 - assert check_reactor_temperature(100) == 0 # boundary cases easily go wrong - assert check_reactor_temperature(101) == 1 diff --git a/content/test-design.md b/content/test-design.md index bf2cf62..d62b514 100644 --- a/content/test-design.md +++ b/content/test-design.md @@ -337,45 +337,44 @@ This one is not easy to test because the function has an external dependency. ````{tab} Python - ```{literalinclude} code/python/reactor_temperature.py + ```{literalinclude} code/python/even_time_difference.py :language: Python ``` ```` ````{tab} C++ - ```{literalinclude} code/cpp/reactor_temperature.cpp + ```{literalinclude} code/cpp/even_time_difference.cpp :language: c++ ``` ```` ````{tab} R - ```{literalinclude} code/R/reactor_temperature.R + ```{literalinclude} code/R/even_time_difference.R :language: R ``` ```` ````{tab} Julia - ```{literalinclude} code/julia/reactor_temperature.jl + ```{literalinclude} code/julia/even_time_difference.jl :language: julia ``` ```` ````{tab} Fortran - ```{literalinclude} code/fortran/reactor_temperature.f90 + ```{literalinclude} code/fortran/even_time_difference.f90 :language: fortran ``` ```` ````` ``````{solution} -This function depends on the value of -`reactor.max_temperature` so the function is not pure, so testing gets -harder. You could use monkey patching to override the value of -`max_temperature`, and test it with different values. [Monkey +This function depends on the current time, so the function is not pure, so testing gets +harder. You could use monkey patching to replace the time function with another function +, and test it with different values. [Monkey patching](https://en.wikipedia.org/wiki/Monkey_patch) is the concept of artificially changing some other value. @@ -385,35 +384,35 @@ A better solution would probably be to rewrite the function. ````{tab} Python - ```{literalinclude} code/python/reactor_temperature_sol.py + ```{literalinclude} code/python/even_time_difference_sol.py :language: Python ``` ```` ````{tab} C++ - ```{literalinclude} code/cpp/reactor_temperature_sol.cpp + ```{literalinclude} code/cpp/even_time_difference_sol.cpp :language: c++ ``` ```` ````{tab} R - ```{literalinclude} code/R/reactor_temperature_sol.R + ```{literalinclude} code/R/even_time_difference_sol.R :language: R ``` ```` ````{tab} Julia - ```{literalinclude} code/julia/reactor_temperature_sol.jl + ```{literalinclude} code/julia/even_time_difference_sol.jl :language: julia ``` ```` ````{tab} Fortran - ```{literalinclude} code/fortran/reactor_temperature_sol.f90 + ```{literalinclude} code/fortran/even_time_difference_sol.f90 :language: fortran ``` ```` From df2ab420ff83a40575d96b21838b612edad3386a Mon Sep 17 00:00:00 2001 From: jenswehner Date: Tue, 29 Jun 2021 10:41:51 +0200 Subject: [PATCH 2/3] updated C++ --- content/code/cpp/even_time_difference.cpp | 2 +- content/code/cpp/even_time_difference_sol.cpp | 58 +++++++++++++++++-- 2 files changed, 55 insertions(+), 5 deletions(-) diff --git a/content/code/cpp/even_time_difference.cpp b/content/code/cpp/even_time_difference.cpp index 5d43f30..687fdac 100644 --- a/content/code/cpp/even_time_difference.cpp +++ b/content/code/cpp/even_time_difference.cpp @@ -7,5 +7,5 @@ bool check_time_to_now_even(int seconds) { throw std::runtime_error('received negative input'); } auto now = std::chrono::system_clock::now().time_since_epoch(); - return std::chrono::duration_cast(now).count()%seconds ==0; + return (std::chrono::duration_cast(now).count()-seconds)%2 ==0; } diff --git a/content/code/cpp/even_time_difference_sol.cpp b/content/code/cpp/even_time_difference_sol.cpp index 8215c38..704c836 100644 --- a/content/code/cpp/even_time_difference_sol.cpp +++ b/content/code/cpp/even_time_difference_sol.cpp @@ -1,9 +1,59 @@ -// Changing variables included from headers (monkey patching) is not possible in C++. +// Changing variables included from headers (monkey patching) is not possible in C++. Instead we refactor the function to make it pure. +//Another way would be to use templates for dependency injection #include +//Making it pure +bool check_time_to_now_even(int seconds, int current_time) { + if(seconds<0){ + throw std::runtime_error('received negative input'); + } + return (current_time-seconds)%2 ==0; +} + +// Normal invocation +auto now = std::chrono::system_clock::now().time_since_epoch(); +int current_time_seconds=std::chrono::duration_cast(now).count(); +check_time_to_now_even(4,current_time_seconds); + + +TEST_CASE("Check time difference", "[reactor_state]") { + REQUIRE(check_time_to_now_even(1,3) == true); + REQUIRE(check_time_to_now_even(4,5) == false); +} + + +//using templates + +template< class CLOCK> +bool check_time_to_now_even(int seconds){ + if(seconds<0){ + throw std::runtime_error('received negative input'); + } + int current_time=CLOCK.getNowSeconds(); + return (current_time-seconds)%2 ==0; +} + +//Normal invocation +class ChronoClock{ + +int getNowSeconds(){ + auto now = std::chrono::system_clock::now().time_since_epoch(); + return std::chrono::duration_cast(now).count(); +} + +}; + +check_time_to_now_even(3); + +class TestClock{ + +int getNowSeconds(){ + return 3; +} + +}; TEST_CASE("Check time difference", "[reactor_state]") { - REQUIRE(check_reactor_temperature(99) == ReactorState::FINE); - REQUIRE(check_reactor_temperature(100) == ReactorState::FINE); - REQUIRE(check_reactor_temperature(101) == ReactorState::CRITICAL); + REQUIRE(check_time_to_now_even(3) == true); + REQUIRE(check_time_to_now_even(4) == false); } \ No newline at end of file From e8b67a1909c28aa7d0f2365a0a87f8b2815fb41d Mon Sep 17 00:00:00 2001 From: jenswehner Date: Tue, 29 Jun 2021 11:01:09 +0200 Subject: [PATCH 3/3] formatted --- content/code/cpp/even_time_difference_sol.cpp | 61 +++++++++---------- 1 file changed, 28 insertions(+), 33 deletions(-) diff --git a/content/code/cpp/even_time_difference_sol.cpp b/content/code/cpp/even_time_difference_sol.cpp index 704c836..5800fb8 100644 --- a/content/code/cpp/even_time_difference_sol.cpp +++ b/content/code/cpp/even_time_difference_sol.cpp @@ -1,56 +1,51 @@ -// Changing variables included from headers (monkey patching) is not possible in C++. Instead we refactor the function to make it pure. -//Another way would be to use templates for dependency injection +// Changing variables included from headers (monkey patching) is not possible in +// C++. Instead we refactor the function to make it pure. +// Another way would be to use templates for dependency injection #include -//Making it pure +// Making it pure, probably renaming would be a good idea bool check_time_to_now_even(int seconds, int current_time) { - if(seconds<0){ - throw std::runtime_error('received negative input'); - } - return (current_time-seconds)%2 ==0; + if (seconds < 0) { + throw std::runtime_error('received negative input'); + } + return (current_time - seconds) % 2 == 0; } // Normal invocation auto now = std::chrono::system_clock::now().time_since_epoch(); -int current_time_seconds=std::chrono::duration_cast(now).count(); -check_time_to_now_even(4,current_time_seconds); - +int current_time_seconds = + std::chrono::duration_cast(now).count(); +check_time_to_now_even(4, current_time_seconds); TEST_CASE("Check time difference", "[reactor_state]") { - REQUIRE(check_time_to_now_even(1,3) == true); - REQUIRE(check_time_to_now_even(4,5) == false); + REQUIRE(check_time_to_now_even(1, 3) == true); + REQUIRE(check_time_to_now_even(4, 5) == false); } +// using templates -//using templates - -template< class CLOCK> -bool check_time_to_now_even(int seconds){ - if(seconds<0){ - throw std::runtime_error('received negative input'); - } - int current_time=CLOCK.getNowSeconds(); - return (current_time-seconds)%2 ==0; +template bool check_time_to_now_even(int seconds) { + if (seconds < 0) { + throw std::runtime_error('received negative input'); + } + int current_time = CLOCK.getNowSeconds(); + return (current_time - seconds) % 2 == 0; } -//Normal invocation -class ChronoClock{ - -int getNowSeconds(){ - auto now = std::chrono::system_clock::now().time_since_epoch(); - return std::chrono::duration_cast(now).count(); -} +// Normal invocation +class ChronoClock { + int getNowSeconds() { + auto now = std::chrono::system_clock::now().time_since_epoch(); + return std::chrono::duration_cast(now).count(); + } }; check_time_to_now_even(3); -class TestClock{ - -int getNowSeconds(){ - return 3; -} +class TestClock { + int getNowSeconds() { return 3; } }; TEST_CASE("Check time difference", "[reactor_state]") {