1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7 #include "RollingNumber.h"
8
9 #include "mozilla/Assertions.h"
10
11 #include <cstdint>
12 #include <gtest/gtest.h>
13 #include <type_traits>
14
15 using RN8 = mozilla::RollingNumber<uint8_t>;
16
TEST(RollingNumber,Value)17 TEST(RollingNumber, Value)
18 {
19 // Value type should reflect template argument.
20 static_assert(std::is_same_v<RN8::ValueType, uint8_t>);
21
22 // Default init to 0.
23 const RN8 n;
24 // Access through Value().
25 EXPECT_EQ(0, n.Value());
26
27 // Conversion constructor.
28 RN8 n42{42};
29 EXPECT_EQ(42, n42.Value());
30
31 // Copy Constructor.
32 RN8 n42Copied{n42};
33 EXPECT_EQ(42, n42Copied.Value());
34
35 // Assignment construction.
36 RN8 n42Assigned = n42;
37 EXPECT_EQ(42, n42Assigned.Value());
38
39 // Assignment.
40 n42 = n;
41 EXPECT_EQ(0, n42.Value());
42 }
43
TEST(RollingNumber,Operations)44 TEST(RollingNumber, Operations)
45 {
46 RN8 n;
47 EXPECT_EQ(0, n.Value());
48
49 RN8 nPreInc = ++n;
50 EXPECT_EQ(1, n.Value());
51 EXPECT_EQ(1, nPreInc.Value());
52
53 RN8 nPostInc = n++;
54 EXPECT_EQ(2, n.Value());
55 EXPECT_EQ(1, nPostInc.Value());
56
57 RN8 nPreDec = --n;
58 EXPECT_EQ(1, n.Value());
59 EXPECT_EQ(1, nPreDec.Value());
60
61 RN8 nPostDec = n--;
62 EXPECT_EQ(0, n.Value());
63 EXPECT_EQ(1, nPostDec.Value());
64
65 RN8 nPlus = n + 10;
66 EXPECT_EQ(0, n.Value());
67 EXPECT_EQ(10, nPlus.Value());
68
69 n += 20;
70 EXPECT_EQ(20, n.Value());
71
72 RN8 nMinus = n - 2;
73 EXPECT_EQ(20, n.Value());
74 EXPECT_EQ(18, nMinus.Value());
75
76 n -= 5;
77 EXPECT_EQ(15, n.Value());
78
79 uint8_t diff = nMinus - n;
80 EXPECT_EQ(3, diff);
81
82 // Overflows.
83 n = RN8(0);
84 EXPECT_EQ(0, n.Value());
85 n--;
86 EXPECT_EQ(255, n.Value());
87 n++;
88 EXPECT_EQ(0, n.Value());
89 n -= 10;
90 EXPECT_EQ(246, n.Value());
91 n += 20;
92 EXPECT_EQ(10, n.Value());
93 }
94
TEST(RollingNumber,Comparisons)95 TEST(RollingNumber, Comparisons)
96 {
97 uint8_t i = 0;
98 do {
99 RN8 n{i};
100 EXPECT_EQ(i, n.Value());
101 EXPECT_TRUE(n == n);
102 EXPECT_FALSE(n != n);
103 EXPECT_FALSE(n < n);
104 EXPECT_TRUE(n <= n);
105 EXPECT_FALSE(n > n);
106 EXPECT_TRUE(n >= n);
107
108 RN8 same = n;
109 EXPECT_TRUE(n == same);
110 EXPECT_FALSE(n != same);
111 EXPECT_FALSE(n < same);
112 EXPECT_TRUE(n <= same);
113 EXPECT_FALSE(n > same);
114 EXPECT_TRUE(n >= same);
115
116 #ifdef DEBUG
117 // In debug builds, we are only allowed a quarter of the type range.
118 const uint8_t maxDiff = 255 / 4;
119 #else
120 // In non-debug builds, we can go half-way up or down the type range, and
121 // still conserve the expected ordering.
122 const uint8_t maxDiff = 255 / 2;
123 #endif
124 for (uint8_t add = 1; add <= maxDiff; ++add) {
125 RN8 bigger = n + add;
126 EXPECT_FALSE(n == bigger);
127 EXPECT_TRUE(n != bigger);
128 EXPECT_TRUE(n < bigger);
129 EXPECT_TRUE(n <= bigger);
130 EXPECT_FALSE(n > bigger);
131 EXPECT_FALSE(n >= bigger);
132 }
133
134 for (uint8_t sub = 1; sub <= maxDiff; ++sub) {
135 RN8 smaller = n - sub;
136 EXPECT_FALSE(n == smaller);
137 EXPECT_TRUE(n != smaller);
138 EXPECT_FALSE(n < smaller);
139 EXPECT_FALSE(n <= smaller);
140 EXPECT_TRUE(n > smaller);
141 EXPECT_TRUE(n >= smaller);
142 }
143
144 ++i;
145 } while (i != 0);
146 }
147