1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
#[allow(dead_code)]
mod fizzbuzz
{
    pub fn is_fizz(n: i32) -> bool
    {
        n.abs() % 3 == 0 && !is_fizzbuzz(n)
    }

    pub fn is_buzz(n: i32) -> bool
    {
        n.abs() % 5 == 0 && !is_fizzbuzz(n)
    }

    pub fn is_fizzbuzz(n: i32) -> bool
    {
        n.abs() % 15 == 0
    }

    pub fn is_none(n: i32) -> bool
    {
        !is_fizz(n) && !is_buzz(n) && !is_fizzbuzz(n)
    }

    pub fn check(n: i32) -> String
    {
        if is_fizzbuzz(n)
        {
            return "fizzbuzz".to_string();
        }

        if is_fizz(n)
        {
            return "fizz".to_string();
        }

        if is_buzz(n)
        {
            return "buzz".to_string();
        }

        n.to_string()
    }
}

#[cfg(test)]
mod tests {

    use super::*;

    #[test]
    fn detects_fizz()
    {
        assert!(fizzbuzz::is_fizz(3));
        assert!(fizzbuzz::is_fizz(6));
        assert!(!fizzbuzz::is_fizz(15));
    }

    #[test]
    fn detects_buzz()
    {
        assert!(fizzbuzz::is_buzz(5));
        assert!(fizzbuzz::is_buzz(10));
        assert!(!fizzbuzz::is_buzz(15));
    }

    #[test]
    fn detects_fizzbuzz()
    {
        assert!(fizzbuzz::is_fizzbuzz(15));
        assert!(fizzbuzz::is_fizzbuzz(30));
        assert!(!fizzbuzz::is_fizzbuzz(33));
    }

    #[test]
    fn detects_none()
    {
        assert!(fizzbuzz::is_none(17));
        assert!(!fizzbuzz::is_none(3));
        assert!(!fizzbuzz::is_none(5));
        assert!(!fizzbuzz::is_none(15));
    }

    #[test]
    fn checks_from_negative_30_to_positive_30()
    {
        let expected = vec![
            "fizzbuzz", "-29", "-28", "fizz", "-26", "buzz", "fizz", "-23", "-22", "fizz",
            "buzz", "-19", "fizz", "-17", "-16", "fizzbuzz", "-14", "-13", "fizz", "-11",
            "buzz", "fizz", "-8", "-7", "fizz", "buzz", "-4", "fizz", "-2", "-1",
            "fizzbuzz", // 0
            "1", "2", "fizz", "4", "buzz", "fizz", "7", "8", "fizz", "buzz",
            "11", "fizz", "13", "14", "fizzbuzz", "16", "17", "fizz", "19", "buzz",
            "fizz", "22", "23", "fizz", "buzz", "26", "fizz", "28", "29", "fizzbuzz",
        ];

        let mut results: Vec<String> = vec![];

        for n in -30..=30
        {
            results.push(fizzbuzz::check(n));
        }

        assert_eq!(results, expected);
    }
}