Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rewriting reactor test #180

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions content/code/R/even_time_difference.R
Original file line number Diff line number Diff line change
@@ -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)
}
16 changes: 0 additions & 16 deletions content/code/R/reactor_temperature.R

This file was deleted.

11 changes: 11 additions & 0 deletions content/code/cpp/even_time_difference.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#include <chrono>
#include <stdexcept>

/* 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<std::chrono::seconds>(now).count()-seconds)%2 ==0;
}
54 changes: 54 additions & 0 deletions content/code/cpp/even_time_difference_sol.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// 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 <catch2/catch.hpp>

// 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;
}

// Normal invocation
auto now = std::chrono::system_clock::now().time_since_epoch();
int current_time_seconds =
std::chrono::duration_cast<std::chrono::seconds>(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<std::chrono::seconds>(now).count();
}
};

check_time_to_now_even<ChronoClock>(3);

class TestClock {

int getNowSeconds() { return 3; }
};

TEST_CASE("Check time difference", "[reactor_state]") {
REQUIRE(check_time_to_now_even<TestClock>(3) == true);
REQUIRE(check_time_to_now_even<TestClock>(4) == false);
}
15 changes: 0 additions & 15 deletions content/code/cpp/reactor_temperature.cpp

This file was deleted.

9 changes: 0 additions & 9 deletions content/code/cpp/reactor_temperature_sol.cpp

This file was deleted.

10 changes: 10 additions & 0 deletions content/code/python/even_time_difference.py
Original file line number Diff line number Diff line change
@@ -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
6 changes: 6 additions & 0 deletions content/code/python/even_time_difference_sol.py
Original file line number Diff line number Diff line change
@@ -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
10 changes: 0 additions & 10 deletions content/code/python/reactor_temperature.py

This file was deleted.

5 changes: 0 additions & 5 deletions content/code/python/reactor_temperature_sol.py

This file was deleted.

27 changes: 13 additions & 14 deletions content/test-design.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand All @@ -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
```
````
Expand Down