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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
|
/**
* Copyright (C) 2022 Adrien Hopkins
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package sevenUnitsGUI;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static sevenUnitsGUI.StandardDisplayRules.fixedDecimals;
import static sevenUnitsGUI.StandardDisplayRules.fixedPrecision;
import static sevenUnitsGUI.StandardDisplayRules.getStandardRule;
import static sevenUnitsGUI.StandardDisplayRules.uncertaintyBased;
import java.util.Objects;
import java.util.stream.Stream;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import sevenUnits.utils.UncertainDouble;
import sevenUnitsGUI.StandardDisplayRules.FixedDecimals;
import sevenUnitsGUI.StandardDisplayRules.FixedPrecision;
import sevenUnitsGUI.StandardDisplayRules.UncertaintyBased;
/**
* Tests that ensure the rounding rules work as intended.
*
* @since v0.4.0
* @since 2022-07-17
*/
class RoundingTest {
// rounding rules to test
private static final FixedDecimals ZERO_DECIMALS = fixedDecimals(0);
private static final FixedDecimals TWO_DECIMALS = fixedDecimals(2);
private static final FixedDecimals SIX_DECIMALS = fixedDecimals(6);
private static final FixedPrecision ONE_SIG_FIG = fixedPrecision(1);
private static final FixedPrecision THREE_SIG_FIGS = fixedPrecision(3);
private static final FixedPrecision TWELVE_SIG_FIGS = fixedPrecision(12);
private static final UncertaintyBased UNCERTAINTY_BASED = uncertaintyBased();
// numbers to test rounding with
private static final UncertainDouble INPUT1 = UncertainDouble.of(12.3456789,
0.0);
private static final UncertainDouble INPUT2 = UncertainDouble.of(300.9,
0.005);
private static final UncertainDouble INPUT3 = UncertainDouble.of(12345432.1,
0.0);
private static final UncertainDouble INPUT4 = UncertainDouble.of(0.00001234,
0.000001);
/**
* @return arguments for
* {@link #testFixedDecimalRounding(UncertainDouble, String, String, String)}
* @since v0.4.0
* @since 2022-07-17
*/
private static final Stream<Arguments> fixedDecimalRoundingExamples() {
// input, zero decimal string, two decimal string, six decimal string
return Stream.of(Arguments.of(INPUT1, "12", "12.35", "12.345679"),
Arguments.of(INPUT2, "301", "300.90", "300.900000"),
Arguments.of(INPUT3, "12345432", "12345432.10", "12345432.100000"),
Arguments.of(INPUT4, "0", "0.00", "0.000012"));
}
/**
* @return arguments for
* {@link #testFixedPrecisionRounding(UncertainDouble, String, String, String)}
* @since v0.4.0
* @since 2022-07-17
*/
private static final Stream<Arguments> fixedPrecisionRoundingExamples() {
// input, one sig fig string, three s.f. string, six s.f. string
return Stream.of(Arguments.of(INPUT1, "1E+1", "12.3", "12.3456789000"),
Arguments.of(INPUT2, "3E+2", "301", "300.900000000"),
Arguments.of(INPUT3, "1E+7", "1.23E+7", "12345432.1000"),
Arguments.of(INPUT4, "0.00001", "0.0000123", "0.0000123400000000"));
}
/**
* @return arguments for
* {@link #testUncertaintyRounding(UncertainDouble, String)}
* @since v0.4.0
* @since 2022-07-17
*/
private static final Stream<Arguments> uncertaintyRoundingExamples() {
// input, uncertainty rounding string
return Stream.of(Arguments.of(INPUT1, "12.3456789"),
Arguments.of(INPUT2, "300.900"),
Arguments.of(INPUT3, "1.23454321E7"),
Arguments.of(INPUT4, "0.0000123"));
}
/**
* Test for {@link FixedDecimals#decimalPlaces()} and
* {@link FixedPrecision#significantFigures()}.
*
* @since v0.4.0
* @since 2022-07-17
*/
@Test
void testDataMethods() {
// ensure # of decimal places can be accessed
assertEquals(0, ZERO_DECIMALS.decimalPlaces(),
"ZERO_DECIMALS has " + ZERO_DECIMALS.decimalPlaces() + " decimals");
assertEquals(2, TWO_DECIMALS.decimalPlaces(),
"TWO_DECIMALS has " + TWO_DECIMALS.decimalPlaces() + " decimals");
assertEquals(6, SIX_DECIMALS.decimalPlaces(),
"SIX_DECIMALS has " + SIX_DECIMALS.decimalPlaces() + " decimals");
// ensure # of sig figs can be accessed
assertEquals(1, ONE_SIG_FIG.significantFigures(), "ONE_SIG_FIG has "
+ ONE_SIG_FIG.significantFigures() + " significant figures");
assertEquals(3, THREE_SIG_FIGS.significantFigures(), "THREE_SIG_FIGS has "
+ THREE_SIG_FIGS.significantFigures() + " significant figures");
assertEquals(12, TWELVE_SIG_FIGS.significantFigures(),
"TWELVE_SIG_FIGS has " + TWELVE_SIG_FIGS.significantFigures()
+ " significant figures");
}
/**
* Tests that the rounding methods' equals() methods work.
*
* @since v0.4.0
* @since 2022-07-17
*/
@Test
void testEquals() {
// basic equals tests
assertTrue(ZERO_DECIMALS.equals(ZERO_DECIMALS),
"ZERO_DECIMALS does not equal itself");
assertFalse(TWO_DECIMALS.equals(SIX_DECIMALS),
"TWO_DECIMALS == SIX_DECIMALS");
assertTrue(Objects.equals(fixedDecimals(0), fixedDecimals(0)),
"FixedDecimals.equals() depends on something other than decimal places.");
assertTrue(ONE_SIG_FIG.equals(ONE_SIG_FIG),
"ONE_SIG_FIG does not equal itself");
assertFalse(THREE_SIG_FIGS.equals(TWELVE_SIG_FIGS),
"THREE_SIG_FIGS == TWELVE_SIG_FIGS");
assertTrue(Objects.equals(fixedPrecision(1), fixedPrecision(1)),
"FixedPrecision.equals() depends on something other than significant figures.");
// test that FixedDecimals is never equal to FixedPrecision
// this unlikely argument is the test - the equals should return false!
@SuppressWarnings("unlikely-arg-type")
final boolean differentRulesEqual = Objects.equals(fixedDecimals(4),
fixedPrecision(4));
assertFalse(differentRulesEqual, "fixedDecimals(4) == fixedPrecision(4)");
}
/**
* Ensures that fixed decimal rounding works as expected
*
* @param input number to test
* @param zeroDecimalString expected string for zero decimal places
* @param twoDecimalString expected string for two decimal places
* @param sixDecimalString expected string for six decimal places
* @since 2022-07-17
*/
@ParameterizedTest
@MethodSource("fixedDecimalRoundingExamples")
void testFixedDecimalRounding(UncertainDouble input,
String zeroDecimalString, String twoDecimalString,
String sixDecimalString) {
// test the three rounding rules against the provided strings
assertEquals(zeroDecimalString, ZERO_DECIMALS.apply(input),
"ZERO_DECIMALS rounded " + input + " as "
+ ZERO_DECIMALS.apply(input) + " (should be "
+ zeroDecimalString + ")");
assertEquals(twoDecimalString, TWO_DECIMALS.apply(input),
"TWO_DECIMALS rounded " + input + " as " + TWO_DECIMALS.apply(input)
+ " (should be " + twoDecimalString + ")");
assertEquals(sixDecimalString, SIX_DECIMALS.apply(input),
"TWO_DECIMALS rounded " + input + " as " + SIX_DECIMALS.apply(input)
+ " (should be " + sixDecimalString + ")");
}
/**
* Ensures that fixed precision rounding works as expected
*
* @param input number to test
* @param oneSigFigString expected string for one significant figure
* @param threeSigFigString expected string for three significant figures
* @param twelveSigFigString expected string for twelve significant figures
* @since v0.4.0
* @since 2022-07-17
*/
@ParameterizedTest
@MethodSource("fixedPrecisionRoundingExamples")
void testFixedPrecisionRounding(UncertainDouble input,
String oneSigFigString, String threeSigFigString,
String twelveSigFigString) {
// test the three rounding rules against the provided strings
assertEquals(oneSigFigString, ONE_SIG_FIG.apply(input),
"ONE_SIG_FIG rounded " + input + " as " + ONE_SIG_FIG.apply(input)
+ " (should be " + oneSigFigString + ")");
assertEquals(threeSigFigString, THREE_SIG_FIGS.apply(input),
"THREE_SIG_FIGS rounded " + input + " as "
+ THREE_SIG_FIGS.apply(input) + " (should be "
+ threeSigFigString + ")");
assertEquals(twelveSigFigString, TWELVE_SIG_FIGS.apply(input),
"TWELVE_SIG_FIGS rounded " + input + " as "
+ TWELVE_SIG_FIGS.apply(input) + " (should be "
+ twelveSigFigString + ")");
}
/**
* Tests that {@link StandardDisplayRules#getStandardRule} gets rounding
* rules as intended.
*
* @since v0.4.0
* @since 2022-07-17
*/
@Test
void testGetStandardRule() {
assertEquals(ZERO_DECIMALS, getStandardRule("Round to 0 decimal places"));
assertEquals(THREE_SIG_FIGS,
getStandardRule("Round to 3 significant figures"));
assertEquals(UNCERTAINTY_BASED,
getStandardRule("Uncertainty-Based Rounding"));
assertThrows(IllegalArgumentException.class,
() -> getStandardRule("Not a rounding rule"));
}
/**
* Tests that the rounding methods' equals() methods work.
*
* @since v0.4.0
* @since 2022-07-17
*/
@Test
void testHashCode() {
assertEquals(ZERO_DECIMALS.hashCode(), ZERO_DECIMALS.hashCode());
assertEquals(ONE_SIG_FIG.hashCode(), ONE_SIG_FIG.hashCode());
assertEquals(UNCERTAINTY_BASED.hashCode(), UNCERTAINTY_BASED.hashCode());
}
/**
* Tests that the {@code toString()} methods of the three rounding rule
* classes work correctly.
*
* @since v0.4.0
* @since 2022-07-17
*/
@Test
void testToString() {
assertEquals("Round to 0 decimal places", ZERO_DECIMALS.toString());
assertEquals("Round to 3 significant figures", THREE_SIG_FIGS.toString());
assertEquals("Uncertainty-Based Rounding", UNCERTAINTY_BASED.toString());
}
/**
* Tests that Uncertainty Rounding works as expected
*
* @param input input number
* @param output expected output string
* @since v0.4.0
* @since 2022-07-17
*/
@ParameterizedTest
@MethodSource("uncertaintyRoundingExamples")
void testUncertaintyRounding(UncertainDouble input, String output) {
assertEquals(output, UNCERTAINTY_BASED.apply(input),
() -> String.format(
"Uncertainty Rounding rounded %s as %s (should be %s)", input,
UNCERTAINTY_BASED.apply(input), output));
}
}
|