aboutsummaryrefslogtreecommitdiffstats
path: root/ui-desktop/src/test/java/market/guess/ui/desktop
diff options
context:
space:
mode:
Diffstat (limited to 'ui-desktop/src/test/java/market/guess/ui/desktop')
-rw-r--r--ui-desktop/src/test/java/market/guess/ui/desktop/AnimTest.java70
-rw-r--r--ui-desktop/src/test/java/market/guess/ui/desktop/AppStateTest.java499
-rw-r--r--ui-desktop/src/test/java/market/guess/ui/desktop/ChartsTest.java32
-rw-r--r--ui-desktop/src/test/java/market/guess/ui/desktop/FormatTest.java29
4 files changed, 630 insertions, 0 deletions
diff --git a/ui-desktop/src/test/java/market/guess/ui/desktop/AnimTest.java b/ui-desktop/src/test/java/market/guess/ui/desktop/AnimTest.java
new file mode 100644
index 0000000..1a39ba1
--- /dev/null
+++ b/ui-desktop/src/test/java/market/guess/ui/desktop/AnimTest.java
@@ -0,0 +1,70 @@
1package market.guess.ui.desktop;
2
3import static org.junit.jupiter.api.Assertions.assertEquals;
4
5import market.guess.ui.desktop.components.graphic.GraphicHelper;
6import market.guess.ui.desktop.components.graphic.MarketChartGraphic;
7import market.guess.ui.desktop.components.graphic.Motion;
8import market.guess.ui.desktop.components.graphic.SparklineGraphic;
9import org.junit.jupiter.api.Test;
10
11/**
12 * The handoff requires "animations off" to show the frozen final frame, fully legible and never
13 * blank. Since every graphic renders as a function of progress, that contract is exactly: at
14 * progress 1, every driver lands on its designed end value.
15 */
16class AnimTest {
17 private static final double[] BAR1 = {0, .35, .30, 1, .60, .6, 1, .35};
18
19 @Test
20 void keyframesHoldTheirEndValue() {
21 assertEquals(.35, GraphicHelper.at(0, BAR1), 1e-9);
22 assertEquals(1.0, GraphicHelper.at(.30, BAR1), 1e-9);
23 assertEquals(.35, GraphicHelper.at(1, BAR1), 1e-9);
24 assertEquals(.675, GraphicHelper.at(.15, BAR1), 1e-9); // interpolates linearly between stops
25 assertEquals(.35, Motion.at(0, BAR1), 1e-9);
26 }
27
28 @Test
29 void ridersEndOnTheLastPointOfTheirPath() {
30 assertEquals(
31 MarketChartGraphic.YES_CURVE[6],
32 MarketChartGraphic.rideCurve(MarketChartGraphic.YES_CURVE, 1)[0],
33 1e-6);
34 assertEquals(
35 MarketChartGraphic.YES_CURVE[7],
36 MarketChartGraphic.rideCurve(MarketChartGraphic.YES_CURVE, 1)[1],
37 1e-6);
38
39 int last = SparklineGraphic.SPARK.length;
40 assertEquals(
41 SparklineGraphic.SPARK[last - 2],
42 SparklineGraphic.ridePolyline(SparklineGraphic.SPARK, 1)[0],
43 1e-6);
44 assertEquals(
45 SparklineGraphic.SPARK[last - 1],
46 SparklineGraphic.ridePolyline(SparklineGraphic.SPARK, 1)[1],
47 1e-6);
48 }
49
50 @Test
51 void ridersStartOnTheFirstPointOfTheirPath() {
52 assertEquals(
53 MarketChartGraphic.YES_CURVE[0],
54 MarketChartGraphic.rideCurve(MarketChartGraphic.YES_CURVE, 0)[0],
55 1e-6);
56 assertEquals(
57 MarketChartGraphic.YES_CURVE[1],
58 MarketChartGraphic.rideCurve(MarketChartGraphic.YES_CURVE, 0)[1],
59 1e-6);
60
61 assertEquals(
62 SparklineGraphic.SPARK[0],
63 SparklineGraphic.ridePolyline(SparklineGraphic.SPARK, 0)[0],
64 1e-6);
65 assertEquals(
66 SparklineGraphic.SPARK[1],
67 SparklineGraphic.ridePolyline(SparklineGraphic.SPARK, 0)[1],
68 1e-6);
69 }
70}
diff --git a/ui-desktop/src/test/java/market/guess/ui/desktop/AppStateTest.java b/ui-desktop/src/test/java/market/guess/ui/desktop/AppStateTest.java
new file mode 100644
index 0000000..dbb1762
--- /dev/null
+++ b/ui-desktop/src/test/java/market/guess/ui/desktop/AppStateTest.java
@@ -0,0 +1,499 @@
1package market.guess.ui.desktop;
2
3import static org.junit.jupiter.api.Assertions.assertEquals;
4import static org.junit.jupiter.api.Assertions.assertNotNull;
5import static org.junit.jupiter.api.Assertions.assertTrue;
6
7import java.math.BigDecimal;
8import java.nio.file.Path;
9import java.util.concurrent.atomic.AtomicBoolean;
10import market.guess.api.CatalogContext;
11import market.guess.model.event.CommissionTiming;
12import market.guess.model.event.CreateEventRequest;
13import market.guess.model.event.MechanismType;
14import market.guess.ui.desktop.components.AppTab;
15import market.guess.ui.desktop.components.ModalDialog;
16import org.junit.jupiter.api.BeforeEach;
17import org.junit.jupiter.api.Test;
18
19class AppStateTest {
20 private AppState state;
21 private CatalogContext catalog;
22 private ServiceEngine engine;
23
24 @BeforeEach
25 void setUp() {
26 engine = new ServiceEngine();
27 var path = Path.of("test-data/ex-2/small.xml");
28 var res = engine.getCatalogContext().loadEvents(path);
29 assertTrue(res.isSuccess(), "Loading small.xml should succeed");
30 catalog = engine.getCatalogContext();
31 state = new AppState(engine);
32 state.setLoadedFile(path.toString());
33 state.refreshData();
34 }
35
36 @Test
37 void reactivePropertiesNotifyListeners() {
38 AtomicBoolean skinChanged = new AtomicBoolean(false);
39 state.skinProperty().addListener((obs, oldVal, newVal) -> skinChanged.set(true));
40 state.setSkin(Skin.CATPPUCCIN);
41 assertTrue(skinChanged.get());
42 assertEquals(Skin.CATPPUCCIN, state.getSkin());
43
44 AtomicBoolean tabChanged = new AtomicBoolean(false);
45 state.activeTabProperty().addListener((obs, oldVal, newVal) -> tabChanged.set(true));
46 state.setActiveTab(AppTab.USERS);
47 assertTrue(tabChanged.get());
48 assertEquals(AppTab.USERS, state.getActiveTab());
49
50 AtomicBoolean dialogChanged = new AtomicBoolean(false);
51 state.dialogProperty().addListener((obs, oldVal, newVal) -> dialogChanged.set(true));
52 state.setDialog(ModalDialog.CREATE_EVENT);
53 assertTrue(dialogChanged.get());
54 assertEquals(ModalDialog.CREATE_EVENT, state.getDialog());
55 }
56
57 @Test
58 void selectedEventUpdatesWhenIdChanges() {
59 assertNotNull(state.getSelectedEvent());
60
61 // Add a new event
62 var req =
63 new CreateEventRequest(
64 "New Test Event",
65 "Test Description",
66 MechanismType.LMSR,
67 5,
68 CommissionTiming.ON_PURCHASE,
69 "Avrum",
70 150,
71 null,
72 java.util.List.of("YES", "NO"),
73 true);
74 var res = catalog.createEvent(req);
75 assertTrue(res.isSuccess(), "Create event should succeed: " + res.getMessage());
76 state.refreshData();
77
78 String newId = res.getData().summary().key();
79 state.setSelectedEventId(newId);
80 assertEquals(newId, state.getSelectedEvent().id);
81 assertEquals("New Test Event", state.getSelectedEvent().name);
82 }
83
84 @Test
85 void actingUserUpdatesWhenNameChanges() {
86 assertNotNull(state.getActingUser());
87 assertEquals("Avrum", state.getActingUserName());
88
89 state.setActingUserName("Menash");
90 assertNotNull(state.getActingUser());
91 assertEquals("Menash", state.getActingUser().name);
92 }
93
94 @Test
95 void createEventWithFullParameters() {
96 var req =
97 new CreateEventRequest(
98 "Summit 2026",
99 "Will the summit take place?",
100 MechanismType.ORDER_BOOK,
101 10,
102 CommissionTiming.ON_CLOSE,
103 "Avrum",
104 null,
105 new BigDecimal("2.50"),
106 java.util.List.of("YES", "NO"),
107 false);
108 var res = catalog.createEvent(req);
109 assertTrue(res.isSuccess(), "Create event should succeed: " + res.getMessage());
110 var detail = res.getData();
111 assertEquals("Summit 2026", detail.summary().name());
112 assertEquals(MechanismType.ORDER_BOOK, detail.summary().mechanism());
113 assertEquals(10, detail.summary().commissionPercent());
114 assertEquals(CommissionTiming.ON_CLOSE, detail.summary().commissionTiming());
115 }
116
117 @Test
118 void testServiceEngineAndXmlLoad() {
119 assertEquals(2, state.getEvents().size());
120 assertEquals(3, state.getUsers().size());
121 assertNotNull(state.getActingUser());
122 }
123
124 @Test
125 void testLmsrTradingAndUpdate() {
126 var openRes = catalog.openEvent("1");
127 assertTrue(openRes.isSuccess(), "Opening event 1 should succeed: " + openRes.getMessage());
128 state.refreshData();
129
130 var evBefore = state.event("1");
131 assertNotNull(evBefore);
132 System.out.println(
133 "Before trade: yesPrice=" + evBefore.yesPrice + ", noPrice=" + evBefore.noPrice);
134
135 var orderRes =
136 engine.getMarketContext().placeOrder("Avrum", "1", "YES", "BUY", evBefore.yesPrice, 20);
137 assertTrue(orderRes.isSuccess(), "Place order should succeed: " + orderRes.getMessage());
138
139 state.refreshData();
140 var evAfter = state.event("1");
141 assertEquals(new BigDecimal("0.55"), evAfter.yesPrice);
142 assertEquals(new BigDecimal("0.45"), evAfter.noPrice);
143 assertEquals(new BigDecimal("0.55"), state.getSelectedEvent().yesPrice);
144
145 System.out.println("=== LMSR EVENT AFTER TRADE ===");
146 System.out.println("evAfter.trades.size() = " + evAfter.trades.size());
147 for (var t : evAfter.trades) {
148 System.out.println(
149 " Trade: n="
150 + t.n()
151 + ", user="
152 + t.user()
153 + ", option="
154 + t.option()
155 + ", yes="
156 + t.yesOption()
157 + ", shares="
158 + t.shares()
159 + ", paid="
160 + t.paid());
161 }
162 System.out.println("evAfter.participants.size() = " + evAfter.participants.size());
163 for (var p : evAfter.participants) {
164 System.out.println(
165 " Participant: user="
166 + p.user()
167 + ", tag="
168 + p.tag()
169 + ", yes="
170 + p.yes()
171 + ", no="
172 + p.no()
173 + ", val="
174 + p.value()
175 + ", fees="
176 + p.fees());
177 }
178 var avrum = state.user("Avrum");
179 System.out.println("Avrum events size: " + avrum.events.size());
180 for (var ue : avrum.events) {
181 System.out.println(
182 " userEvent: name="
183 + ue.eventName()
184 + ", role="
185 + ue.role()
186 + ", yes="
187 + ue.yes()
188 + ", no="
189 + ue.no());
190 }
191 System.out.println("Avrum balanceHistory size: " + avrum.balanceHistory.size());
192 for (var cp : avrum.balanceHistory) {
193 System.out.println(" BalancePoint: x=" + cp.x() + ", y=" + cp.y());
194 }
195 assertTrue(avrum.balanceHistory.size() >= 2);
196 assertTrue(avrum.balanceHistory.get(0).x() > 1_000_000_000);
197
198 // Avrum sells 10 YES shares in LMSR
199 var sellRes = engine.getMarketContext().placeOrder("Avrum", "1", "YES", "SELL", null, 10);
200 assertTrue(
201 sellRes.isSuccess(), "Place LMSR sell order should succeed: " + sellRes.getMessage());
202 state.refreshData();
203
204 var evAfterSell = state.event("1");
205 var avrumParticipant =
206 evAfterSell.participants.stream()
207 .filter(p -> p.user().equals("Avrum"))
208 .findFirst()
209 .orElseThrow();
210 assertEquals(10, avrumParticipant.yes(), "Avrum should hold 10 YES shares after selling 10");
211 assertEquals(10, evAfterSell.yesShares, "Event circulating YES shares should be 10");
212 assertEquals(2, evAfterSell.trades.size(), "Event should have 2 trades recorded");
213
214 var avrumAfterSell = state.user("Avrum");
215 var avrumEv =
216 avrumAfterSell.events.stream()
217 .filter(e -> e.eventId().equals("1"))
218 .findFirst()
219 .orElseThrow();
220 assertEquals(10, avrumEv.yes(), "Avrum user event row should show 10 shares");
221 }
222
223 @Test
224 void testOrderBookTradingAndParticipants() {
225 var openRes = catalog.openEvent("2");
226 assertTrue(openRes.isSuccess());
227 state.refreshData();
228
229 var ev2 = state.event("2");
230 System.out.println("=== ORDER BOOK EVENT BEFORE TRADE ===");
231 System.out.println("ev2.participants.size() = " + ev2.participants.size());
232 for (var p : ev2.participants) {
233 System.out.println(
234 " Participant: user="
235 + p.user()
236 + ", tag="
237 + p.tag()
238 + ", yes="
239 + p.yes()
240 + ", no="
241 + p.no()
242 + ", val="
243 + p.value()
244 + ", fees="
245 + p.fees());
246 }
247
248 // Avrum (MM) quotes his minted YES shares; opening the event doesn't do it for him.
249 var quote =
250 engine
251 .getMarketContext()
252 .placeOrder("Avrum", "2", "YES", "SELL", new BigDecimal("0.50"), 100);
253 assertTrue(quote.isSuccess(), "Avrum quote should succeed: " + quote.getMessage());
254
255 // Menash buys 20 YES @ 0.50 on event 2
256 var res =
257 engine
258 .getMarketContext()
259 .placeOrder("Menash", "2", "YES", "BUY", new BigDecimal("0.50"), 20);
260 assertTrue(res.isSuccess(), "Menash place order should succeed: " + res.getMessage());
261 state.refreshData();
262
263 var ev2After = state.event("2");
264 System.out.println("=== ORDER BOOK EVENT AFTER TRADE ===");
265 System.out.println("ev2After.trades.size() = " + ev2After.trades.size());
266 for (var t : ev2After.trades) {
267 System.out.println(
268 " Trade: n="
269 + t.n()
270 + ", user="
271 + t.user()
272 + ", option="
273 + t.option()
274 + ", yes="
275 + t.yesOption()
276 + ", shares="
277 + t.shares()
278 + ", paid="
279 + t.paid());
280 }
281 System.out.println("ev2After.participants.size() = " + ev2After.participants.size());
282 for (var p : ev2After.participants) {
283 System.out.println(
284 " Participant: user="
285 + p.user()
286 + ", tag="
287 + p.tag()
288 + ", yes="
289 + p.yes()
290 + ", no="
291 + p.no()
292 + ", val="
293 + p.value()
294 + ", fees="
295 + p.fees());
296 }
297 var menash = state.user("Menash");
298 System.out.println("Menash events size: " + menash.events.size());
299 for (var ue : menash.events) {
300 System.out.println(
301 " Menash userEvent: name="
302 + ue.eventName()
303 + ", role="
304 + ue.role()
305 + ", yes="
306 + ue.yes()
307 + ", no="
308 + ue.no());
309 }
310
311 // Menash SELLS 10 YES @ 0.40 (better price than Avrum's 0.50)
312 var sellRes =
313 engine
314 .getMarketContext()
315 .placeOrder("Menash", "2", "YES", "SELL", new BigDecimal("0.40"), 10);
316 assertTrue(sellRes.isSuccess(), "Menash sell order should succeed: " + sellRes.getMessage());
317 state.refreshData();
318
319 // Tikva BUYS 10 YES @ 0.50 (crosses Menash's 0.40 ask!)
320 var tikvaBuy =
321 engine
322 .getMarketContext()
323 .placeOrder("Tikva", "2", "YES", "BUY", new BigDecimal("0.50"), 10);
324 assertTrue(tikvaBuy.isSuccess());
325 state.refreshData();
326
327 var ev2AfterSell = state.event("2");
328 System.out.println("=== ORDER BOOK EVENT AFTER SELL TRADE ===");
329 System.out.println("ev2AfterSell.trades.size() = " + ev2AfterSell.trades.size());
330 for (var t : ev2AfterSell.trades) {
331 System.out.println(
332 " Trade: n="
333 + t.n()
334 + ", user="
335 + t.user()
336 + ", option="
337 + t.option()
338 + ", yes="
339 + t.yesOption()
340 + ", shares="
341 + t.shares()
342 + ", paid="
343 + t.paid());
344 }
345 var domainEv2 = engine.getCatalogContext().getEvent("2");
346 System.out.println("Domain event 2 trades count: " + domainEv2.getData());
347 long mShares0 =
348 engine.getCatalogContext().getEvent("2").getData().participants().stream()
349 .filter(p -> p.user().equals("Menash"))
350 .findFirst()
351 .get()
352 .yes();
353 System.out.println("Menash YES shares in ParticipantDTO: " + mShares0);
354 System.out.println("ev2AfterSell.participants.size() = " + ev2AfterSell.participants.size());
355 for (var p : ev2AfterSell.participants) {
356 System.out.println(
357 " Participant: user="
358 + p.user()
359 + ", tag="
360 + p.tag()
361 + ", yes="
362 + p.yes()
363 + ", no="
364 + p.no()
365 + ", val="
366 + p.value()
367 + ", fees="
368 + p.fees());
369 }
370 menash = state.user("Menash");
371 for (var ue : menash.events) {
372 System.out.println(
373 " Menash userEvent after sell: name="
374 + ue.eventName()
375 + ", role="
376 + ue.role()
377 + ", yes="
378 + ue.yes()
379 + ", no="
380 + ue.no());
381 }
382
383 var menashP =
384 ev2AfterSell.participants.stream()
385 .filter(p -> p.user().equals("Menash"))
386 .findFirst()
387 .orElseThrow();
388 assertEquals(10, menashP.yes(), "Menash should have 10 YES shares after selling 10 of 20");
389 var tikvaP =
390 ev2AfterSell.participants.stream()
391 .filter(p -> p.user().equals("Tikva"))
392 .findFirst()
393 .orElseThrow();
394 assertEquals(10, tikvaP.yes(), "Tikva should have 10 YES shares after buying 10");
395 var avrumP =
396 ev2AfterSell.participants.stream()
397 .filter(p -> p.user().equals("Avrum"))
398 .findFirst()
399 .orElseThrow();
400 assertEquals(80, avrumP.yes(), "Avrum (MM) should have 80 YES shares");
401 assertEquals(2, ev2AfterSell.trades.size(), "Order book event should have 2 trades");
402 }
403
404 @Test
405 void testEventsTabControllerProgressBar() throws Exception {
406 try {
407 javafx.application.Platform.startup(() -> {});
408 } catch (IllegalStateException ignored) {
409 }
410
411 var loader = new javafx.fxml.FXMLLoader(getClass().getResource("controllers/events_tab.fxml"));
412 javafx.scene.Parent root = loader.load();
413 market.guess.ui.desktop.controllers.EventsTabController ctrl = loader.getController();
414
415 ctrl.init(state);
416 ctrl.refresh();
417
418 var field =
419 market.guess.ui.desktop.controllers.EventsTabController.class.getDeclaredField(
420 "lmsrYesProgressBar");
421 field.setAccessible(true);
422 javafx.scene.control.ProgressBar pb = (javafx.scene.control.ProgressBar) field.get(ctrl);
423
424 assertEquals(0.5, pb.getProgress(), 0.001);
425
426 // Switch to event 2 (Order Book)
427 state.setSelectedEventId("2");
428 // Switch back to event 1 (LMSR)
429 state.setSelectedEventId("1");
430 assertEquals(0.5, pb.getProgress(), 0.001);
431
432 // Open event 1
433 catalog.openEvent("1");
434 state.refreshData();
435 assertEquals(0.5, pb.getProgress(), 0.001);
436
437 // Trade 20 YES on event 1
438 var res =
439 engine
440 .getMarketContext()
441 .placeOrder("Avrum", "1", "YES", "BUY", state.event("1").yesPrice, 20);
442 assertTrue(res.isSuccess());
443 state.refreshData();
444 assertEquals(0.55, pb.getProgress(), 0.001);
445
446 root.getStyleClass().add("gm-root");
447 javafx.scene.Scene scene = new javafx.scene.Scene(root);
448 scene.getStylesheets().add(getClass().getResource("theme.css").toExternalForm());
449 root.applyCss();
450 root.layout();
451
452 javafx.scene.Node track = pb.lookup(".track");
453 javafx.scene.Node bar = pb.lookup(".bar");
454 assertNotNull(track);
455 assertNotNull(bar);
456 if (bar instanceof javafx.scene.layout.Region rBar) {
457 assertEquals(0.0, rBar.getPadding().getTop(), 0.001);
458 assertEquals(0.0, rBar.getPadding().getBottom(), 0.001);
459 assertNotNull(rBar.getBackground());
460 assertEquals(1, rBar.getBackground().getFills().size());
461 assertEquals(0.0, rBar.getBackground().getFills().get(0).getInsets().getTop(), 0.001);
462 }
463 if (track instanceof javafx.scene.layout.Region rTrack) {
464 assertEquals(0.0, rTrack.getPadding().getTop(), 0.001);
465 assertEquals(0.0, rTrack.getPadding().getBottom(), 0.001);
466 assertNotNull(rTrack.getBackground());
467 }
468 }
469
470 @Test
471 void testEventDataAndUserDataEquals() {
472 var ev1 = state.event("1");
473 assertNotNull(ev1);
474 var ev1Copy =
475 new market.guess.ui.desktop.model.EventData(
476 ev1.id,
477 ev1.num,
478 ev1.name,
479 ev1.desc,
480 ev1.type,
481 ev1.status,
482 ev1.mm,
483 ev1.feePercent,
484 ev1.feeMode,
485 ev1.contract.doubleValue(),
486 ev1.liquidityB,
487 ev1.baseValueD);
488 assertEquals(ev1, ev1Copy);
489 assertEquals(ev1.hashCode(), ev1Copy.hashCode());
490
491 var u1 = state.user("Avrum");
492 assertNotNull(u1);
493 var u1Copy =
494 new market.guess.ui.desktop.model.UserData(
495 "Avrum", u1.role, u1.balance.doubleValue(), u1.blocked, u1.isMm);
496 assertEquals(u1, u1Copy);
497 assertEquals(u1.hashCode(), u1Copy.hashCode());
498 }
499}
diff --git a/ui-desktop/src/test/java/market/guess/ui/desktop/ChartsTest.java b/ui-desktop/src/test/java/market/guess/ui/desktop/ChartsTest.java
new file mode 100644
index 0000000..c5cb280
--- /dev/null
+++ b/ui-desktop/src/test/java/market/guess/ui/desktop/ChartsTest.java
@@ -0,0 +1,32 @@
1package market.guess.ui.desktop;
2
3import static org.junit.jupiter.api.Assertions.assertEquals;
4import static org.junit.jupiter.api.Assertions.assertTrue;
5
6import market.guess.ui.desktop.util.Charts;
7import org.junit.jupiter.api.Test;
8
9class ChartsTest {
10
11 @Test
12 void testToEpochSecondFromIndex() {
13 double t0 = Charts.toEpochSecond(0);
14 double t1 = Charts.toEpochSecond(1);
15 double t2 = Charts.toEpochSecond(2);
16
17 assertEquals(Charts.BASE_TIME, t0, 1e-6);
18 assertEquals(Charts.BASE_TIME + 1800, t1, 1e-6);
19 assertEquals(Charts.BASE_TIME + 3600, t2, 1e-6);
20 }
21
22 @Test
23 void testToEpochSecondIdempotentForTimestamps() {
24 long epoch = 1_700_000_000L;
25 assertEquals(epoch, Charts.toEpochSecond(epoch), 1e-6);
26 }
27
28 @Test
29 void testBaseTimeIsReasonable() {
30 assertTrue(Charts.BASE_TIME > 1_700_000_000L);
31 }
32}
diff --git a/ui-desktop/src/test/java/market/guess/ui/desktop/FormatTest.java b/ui-desktop/src/test/java/market/guess/ui/desktop/FormatTest.java
new file mode 100644
index 0000000..956a322
--- /dev/null
+++ b/ui-desktop/src/test/java/market/guess/ui/desktop/FormatTest.java
@@ -0,0 +1,29 @@
1package market.guess.ui.desktop;
2
3import static org.junit.jupiter.api.Assertions.assertEquals;
4
5import java.math.BigDecimal;
6import market.guess.ui.desktop.util.Format;
7import org.junit.jupiter.api.Test;
8
9class FormatTest {
10
11 @Test
12 void testMoneyFormatting() {
13 assertEquals("$0.00", Format.money((BigDecimal) null));
14 assertEquals("$0.00", Format.money(BigDecimal.ZERO));
15 assertEquals("$0.50", Format.money(new BigDecimal("0.50")));
16 assertEquals("$123.45", Format.money(new BigDecimal("123.45")));
17 assertEquals("-$5.00", Format.money(new BigDecimal("-5.00")));
18 assertEquals("$100.00", Format.money(100.0));
19 assertEquals("-$2.50", Format.money(-2.50));
20 }
21
22 @Test
23 void testProbFormatting() {
24 assertEquals("0.50", Format.prob(0.50));
25 assertEquals("0.75", Format.prob(0.751));
26 assertEquals("0.00", Format.prob(0.00));
27 assertEquals("1.00", Format.prob(1.00));
28 }
29}