# Tests

* To change a function into a test function, add `#[test]` on the line before `fn`.
* You can run the test using command `cargo test`.
* By convention, test functions reside in a module named `tests`, which is usually placed at the bottom of the file containing the code to be tested.
* We can check panics adding `#[should_panic]` attributes.
* References:
  * [How to Write Tests](https://doc.rust-lang.org/book/ch11-01-writing-tests.html)

## tests1.rs

```rust
// Tests are important to ensure that your code does what you think it should
// do.

fn is_even(n: i64) -> bool {
    n % 2 == 0
}

fn main() {
    // You can optionally experiment here.
}

#[cfg(test)]
mod tests {
    // Import `is_even`. You can use a wildcard to import everything in
    // the outer module.
    use super::is_even;

    #[test]
    fn you_can_assert() {
        // Test the function `is_even` with some values.
        assert!(is_even(10));
        assert!(!is_even(5));
    }
}
```

* In this exercise we need to test the functions `is_even` using `assert!`.
* Assert macro accept `bool` type, will success if value `true` and fails/panics when value is `false`.
* So we need to add two cases for even and odd input like this.

  ```rust
  assert!(is_even(10)); // expect true
  assert!(!is_even(5)); // expect false
  ```

## test2.rs

```rust
// Calculates the power of 2 using a bit shift.
// `1 << n` is equivalent to "2 to the power of n".
fn power_of_2(n: u8) -> u64 {
    1 << n
}

fn main() {
    // You can optionally experiment here.
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn you_can_assert_eq() {
        // Test the function `power_of_2` with some values.
        assert_eq!(power_of_2(0), 1);
        assert_eq!(power_of_2(1), 2);
        assert_eq!(power_of_2(2), 4);
        assert_eq!(power_of_2(3), 8);
    }
}
```

* Similar like previous exercise we need to add test cases for function `power_of_2`.
* But this time using `assert_eq`.
  * It will assert if given two values are equal.
  * If not it will fail/panic.
* So let's add the test cases like this:

  ```rust
  assert_eq!(power_of_2(0), 1);
  assert_eq!(power_of_2(1), 2);
  assert_eq!(power_of_2(2), 4);
  assert_eq!(power_of_2(3), 8);
  ```

## tests3.rs

```rust
struct Rectangle {
    width: i32,
    height: i32,
}

impl Rectangle {
    // Don't change this function.
    fn new(width: i32, height: i32) -> Self {
        if width <= 0 || height <= 0 {
            // Returning a `Result` would be better here. But we want to learn
            // how to test functions that can panic.
            panic!("Rectangle width and height must be positive");
        }

        Rectangle { width, height }
    }
}

fn main() {
    // You can optionally experiment here.
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn correct_width_and_height() {
        // This test should check if the rectangle has the size that we
        // pass to its constructor.
        let rect = Rectangle::new(10, 20);
        assert_eq!(rect.width, 10); // Check width
        assert_eq!(rect.height, 20); // Check height
    }

    // This test should check if the program panics when we try to create
    // a rectangle with negative width.
    #[test]
    #[should_panic]
    fn negative_width() {
        let _rect = Rectangle::new(-10, 10);
    }

    // This test should check if the program panics when we try to create
    // a rectangle with negative height.
    #[test]
    #[should_panic]
    fn negative_height() {
        let _rect = Rectangle::new(10, -10);
    }
}
```

* First task in this exercise is to fix `assert_eq!` in test function `correct_width_and_height()`.
* We just need to put correct fields like this:

  ```rust
  assert_eq!(rect.width, 10); // Check width
  assert_eq!(rect.height, 20); // Check height
  ```
* Second have test functions `negative_width` and `negative_height` that check if we give negative value when calling `Rectangle::new` it should panic.
* We can check panics adding `#[should_panic]` attributes.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://bagus-cahyono.gitbook.io/programming-notes/rust/rustlings_exercise/17_tests.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
