From 7120c601794628c72961d003b04fe72e733c44d6 Mon Sep 17 00:00:00 2001 From: kaklakariada Date: Sat, 5 Dec 2020 13:09:23 +0100 Subject: [PATCH 1/4] #50 #51: Add current month property --- .../whiterabbit/jfxui/AppState.java | 17 +++++++++----- .../whiterabbit/jfxui/JavaFxApp.java | 2 +- .../jfxui/property/ClockPropertyFactory.java | 14 +++++++++++- .../whiterabbit/jfxui/ui/AppUi.java | 6 ++--- .../whiterabbit/jfxui/testutil/TimeUtil.java | 22 +++++++++---------- .../service/scheduling/PeriodicTrigger.java | 5 +++++ 6 files changed, 45 insertions(+), 21 deletions(-) diff --git a/jfxui/src/main/java/org/itsallcode/whiterabbit/jfxui/AppState.java b/jfxui/src/main/java/org/itsallcode/whiterabbit/jfxui/AppState.java index 888bccfc..4f47426b 100644 --- a/jfxui/src/main/java/org/itsallcode/whiterabbit/jfxui/AppState.java +++ b/jfxui/src/main/java/org/itsallcode/whiterabbit/jfxui/AppState.java @@ -30,19 +30,26 @@ public final class AppState public final SimpleObjectProperty selectedDay = new SimpleObjectProperty<>(null); public final SimpleObjectProperty selectedActivity = new SimpleObjectProperty<>(null); + public final ScheduledProperty currentMonthProperty; public final ScheduledProperty currentDateProperty; - public final ScheduledProperty currentTimeProperty; + public final ScheduledProperty currentSecondProperty; - private AppState(ScheduledProperty currentDateProperty, ScheduledProperty currentTimeProperty) + private AppState(ScheduledProperty currentMonthProperty, + ScheduledProperty currentDateProperty, + ScheduledProperty currentTimeProperty) { + this.currentMonthProperty = currentMonthProperty; this.currentDateProperty = currentDateProperty; - this.currentTimeProperty = currentTimeProperty; + this.currentSecondProperty = currentTimeProperty; } static AppState create(AppService appService) { final ClockPropertyFactory clockPropertyFactory = new ClockPropertyFactory(appService); - return new AppState(clockPropertyFactory.currentDateProperty(), clockPropertyFactory.currentTimeProperty()); + final ScheduledProperty currentMonthProperty = clockPropertyFactory.currentMonthProperty(); + final ScheduledProperty currentDateProperty = clockPropertyFactory.currentDateProperty(); + final ScheduledProperty currentTimeProperty = clockPropertyFactory.currentInstantProperty(); + return new AppState(currentMonthProperty, currentDateProperty, currentTimeProperty); } public Optional getSelectedDay() @@ -58,6 +65,6 @@ public Optional getSelectedActivity() void shutdown() { currentDateProperty.cancel(); - currentTimeProperty.cancel(); + currentSecondProperty.cancel(); } } diff --git a/jfxui/src/main/java/org/itsallcode/whiterabbit/jfxui/JavaFxApp.java b/jfxui/src/main/java/org/itsallcode/whiterabbit/jfxui/JavaFxApp.java index 9bc512e8..09ce13e4 100644 --- a/jfxui/src/main/java/org/itsallcode/whiterabbit/jfxui/JavaFxApp.java +++ b/jfxui/src/main/java/org/itsallcode/whiterabbit/jfxui/JavaFxApp.java @@ -255,7 +255,7 @@ public void startManualInterruption() } JavaFxUtil.runOnFxApplicationThread(() -> { state.interruption.set(appService.startInterruption()); - new InterruptionDialog(primaryStage, state.currentTimeProperty.property(), state.interruption, clock) + new InterruptionDialog(primaryStage, state.currentSecondProperty.property(), state.interruption, clock) .show(); }); } diff --git a/jfxui/src/main/java/org/itsallcode/whiterabbit/jfxui/property/ClockPropertyFactory.java b/jfxui/src/main/java/org/itsallcode/whiterabbit/jfxui/property/ClockPropertyFactory.java index e9a0941e..9bb3c100 100644 --- a/jfxui/src/main/java/org/itsallcode/whiterabbit/jfxui/property/ClockPropertyFactory.java +++ b/jfxui/src/main/java/org/itsallcode/whiterabbit/jfxui/property/ClockPropertyFactory.java @@ -2,6 +2,8 @@ import java.time.Instant; import java.time.LocalDate; +import java.time.LocalTime; +import java.time.YearMonth; import java.util.function.Supplier; import org.apache.logging.log4j.LogManager; @@ -25,16 +27,26 @@ public ClockPropertyFactory(AppService appService) this.appService = appService; } - public ScheduledProperty currentTimeProperty() + public ScheduledProperty currentInstantProperty() { return updatingProperty(PeriodicTrigger.everySecond(), () -> appService.getClock().instant()); } + public ScheduledProperty currentMinuteProperty() + { + return updatingProperty(PeriodicTrigger.everyMinute(), () -> appService.getClock().getCurrentTime()); + } + public ScheduledProperty currentDateProperty() { return updatingProperty(PeriodicTrigger.everyDay(), () -> appService.getClock().getCurrentDate()); } + public ScheduledProperty currentMonthProperty() + { + return updatingProperty(PeriodicTrigger.everyMonth(), () -> appService.getClock().getCurrentYearMonth()); + } + public ScheduledProperty updatingProperty(Trigger trigger, Supplier supplier) { final SimpleObjectProperty property = new SimpleObjectProperty<>(); diff --git a/jfxui/src/main/java/org/itsallcode/whiterabbit/jfxui/ui/AppUi.java b/jfxui/src/main/java/org/itsallcode/whiterabbit/jfxui/ui/AppUi.java index 44ce7c43..74f49180 100644 --- a/jfxui/src/main/java/org/itsallcode/whiterabbit/jfxui/ui/AppUi.java +++ b/jfxui/src/main/java/org/itsallcode/whiterabbit/jfxui/ui/AppUi.java @@ -261,9 +261,9 @@ private Node currentTimeLabel() final Label label = new Label(); label.setId("current-time-label"); label.textProperty().bind(Bindings.createStringBinding(() -> { - final Instant now = state.currentTimeProperty.property().getValue(); + final Instant now = state.currentSecondProperty.property().getValue(); return formatter.formatDateAndTime(now); - }, state.currentTimeProperty.property())); + }, state.currentSecondProperty.property())); return label; } @@ -283,7 +283,7 @@ private Node overtimeLabel() + formatter.format(totalOvertime); } return "Overtime: (no month selected)"; - }, state.currentTimeProperty.property(), state.currentMonth)); + }, state.currentSecondProperty.property(), state.currentMonth)); return label; } diff --git a/jfxui/src/uiTest/java/org/itsallcode/whiterabbit/jfxui/testutil/TimeUtil.java b/jfxui/src/uiTest/java/org/itsallcode/whiterabbit/jfxui/testutil/TimeUtil.java index eb78a486..2710e610 100644 --- a/jfxui/src/uiTest/java/org/itsallcode/whiterabbit/jfxui/testutil/TimeUtil.java +++ b/jfxui/src/uiTest/java/org/itsallcode/whiterabbit/jfxui/testutil/TimeUtil.java @@ -36,6 +36,7 @@ public class TimeUtil private Runnable updateEverySecondRunnable; private Runnable updateEveryMinuteRunnable; private Runnable updateEveryDayRunnable; + private Runnable updateEveryMonthRunnable; private TimeUtil(Clock clockMock, ScheduledExecutorService executorServiceMock) { @@ -139,23 +140,22 @@ private void setCurrentTime(final Instant now) public void captureScheduledRunnables() { final ArgumentCaptor arg = ArgumentCaptor.forClass(Runnable.class); - verify(this.executorServiceMock, times(3)).schedule(arg.capture(), eq(0L), eq(TimeUnit.MILLISECONDS)); + verify(this.executorServiceMock, times(4)).schedule(arg.capture(), eq(0L), eq(TimeUnit.MILLISECONDS)); - this.updateEveryDayRunnable = arg.getAllValues().get(0); - this.updateEverySecondRunnable = arg.getAllValues().get(1); - this.updateEveryMinuteRunnable = arg.getAllValues().get(2); - - LOG.trace("Found callback for seconds: {}", updateEverySecondRunnable); - LOG.trace("Found callback for days: {}", updateEveryDayRunnable); - LOG.trace("Found callback for minutes: {}", updateEveryMinuteRunnable); + this.updateEveryMonthRunnable = arg.getAllValues().get(0); + this.updateEveryDayRunnable = arg.getAllValues().get(1); + this.updateEverySecondRunnable = arg.getAllValues().get(2); + this.updateEveryMinuteRunnable = arg.getAllValues().get(3); assertAll( - () -> assertThat(updateEverySecondRunnable.toString()) - .contains("trigger=PeriodicTrigger [roundToUnit=Seconds]"), + () -> assertThat(updateEveryMonthRunnable.toString()) + .contains("trigger=PeriodicTrigger [roundToUnit=Months]"), () -> assertThat(updateEveryDayRunnable.toString()) .contains("trigger=PeriodicTrigger [roundToUnit=Days]"), () -> assertThat(updateEveryMinuteRunnable.toString()) - .contains("trigger=PeriodicTrigger [roundToUnit=Minutes]")); + .contains("trigger=PeriodicTrigger [roundToUnit=Minutes]"), + () -> assertThat(updateEverySecondRunnable.toString()) + .contains("trigger=PeriodicTrigger [roundToUnit=Seconds]")); } public Clock clock() diff --git a/logic/src/main/java/org/itsallcode/whiterabbit/logic/service/scheduling/PeriodicTrigger.java b/logic/src/main/java/org/itsallcode/whiterabbit/logic/service/scheduling/PeriodicTrigger.java index 9dd3a35f..72f62809 100644 --- a/logic/src/main/java/org/itsallcode/whiterabbit/logic/service/scheduling/PeriodicTrigger.java +++ b/logic/src/main/java/org/itsallcode/whiterabbit/logic/service/scheduling/PeriodicTrigger.java @@ -15,6 +15,11 @@ private PeriodicTrigger(ChronoUnit roundToUnit) this.roundToUnit = roundToUnit; } + public static Trigger everyMonth() + { + return new PeriodicTrigger(ChronoUnit.MONTHS); + } + public static Trigger everyDay() { return new PeriodicTrigger(ChronoUnit.DAYS); From 307e3bbe8a4b0f78477cbd5ce2e2beb12633661b Mon Sep 17 00:00:00 2001 From: kaklakariada Date: Sat, 5 Dec 2020 13:13:54 +0100 Subject: [PATCH 2/4] #50 #51: Add changelog entry --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 32fc6b0a..1c7f8f6a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,10 @@ See [Release](https://github.com/itsallcode/white-rabbit/releases/tag/v1.2.0) / * [#52](https://github.com/itsallcode/white-rabbit/issues/52): Improve keyboard usage for autocomplete text fields, immediately show proposals. * [#54](https://github.com/itsallcode/white-rabbit/issues/54): First added activity has the remainder flag set. +### Fixed + +* [#50](https://github.com/itsallcode/white-rabbit/issues/50), [#51](https://github.com/itsallcode/white-rabbit/issues/51): Switch view when month changes. + ## [1.1.0] 2020-11-29 See [Release](https://github.com/itsallcode/white-rabbit/releases/tag/v1.1.0) / [Milestone](https://github.com/itsallcode/white-rabbit/milestone/2?closed=1) From 723db30bf84d8aaa75eec1d34dd5918dfec710e1 Mon Sep 17 00:00:00 2001 From: kaklakariada Date: Sat, 5 Dec 2020 17:36:32 +0100 Subject: [PATCH 3/4] Revert "#50 #51: Add current month property" This reverts commit 7120c601794628c72961d003b04fe72e733c44d6. --- .../whiterabbit/jfxui/AppState.java | 17 +++++--------- .../whiterabbit/jfxui/JavaFxApp.java | 2 +- .../jfxui/property/ClockPropertyFactory.java | 14 +----------- .../whiterabbit/jfxui/ui/AppUi.java | 6 ++--- .../whiterabbit/jfxui/testutil/TimeUtil.java | 22 +++++++++---------- .../service/scheduling/PeriodicTrigger.java | 5 ----- 6 files changed, 21 insertions(+), 45 deletions(-) diff --git a/jfxui/src/main/java/org/itsallcode/whiterabbit/jfxui/AppState.java b/jfxui/src/main/java/org/itsallcode/whiterabbit/jfxui/AppState.java index 4f47426b..888bccfc 100644 --- a/jfxui/src/main/java/org/itsallcode/whiterabbit/jfxui/AppState.java +++ b/jfxui/src/main/java/org/itsallcode/whiterabbit/jfxui/AppState.java @@ -30,26 +30,19 @@ public final class AppState public final SimpleObjectProperty selectedDay = new SimpleObjectProperty<>(null); public final SimpleObjectProperty selectedActivity = new SimpleObjectProperty<>(null); - public final ScheduledProperty currentMonthProperty; public final ScheduledProperty currentDateProperty; - public final ScheduledProperty currentSecondProperty; + public final ScheduledProperty currentTimeProperty; - private AppState(ScheduledProperty currentMonthProperty, - ScheduledProperty currentDateProperty, - ScheduledProperty currentTimeProperty) + private AppState(ScheduledProperty currentDateProperty, ScheduledProperty currentTimeProperty) { - this.currentMonthProperty = currentMonthProperty; this.currentDateProperty = currentDateProperty; - this.currentSecondProperty = currentTimeProperty; + this.currentTimeProperty = currentTimeProperty; } static AppState create(AppService appService) { final ClockPropertyFactory clockPropertyFactory = new ClockPropertyFactory(appService); - final ScheduledProperty currentMonthProperty = clockPropertyFactory.currentMonthProperty(); - final ScheduledProperty currentDateProperty = clockPropertyFactory.currentDateProperty(); - final ScheduledProperty currentTimeProperty = clockPropertyFactory.currentInstantProperty(); - return new AppState(currentMonthProperty, currentDateProperty, currentTimeProperty); + return new AppState(clockPropertyFactory.currentDateProperty(), clockPropertyFactory.currentTimeProperty()); } public Optional getSelectedDay() @@ -65,6 +58,6 @@ public Optional getSelectedActivity() void shutdown() { currentDateProperty.cancel(); - currentSecondProperty.cancel(); + currentTimeProperty.cancel(); } } diff --git a/jfxui/src/main/java/org/itsallcode/whiterabbit/jfxui/JavaFxApp.java b/jfxui/src/main/java/org/itsallcode/whiterabbit/jfxui/JavaFxApp.java index 09ce13e4..9bc512e8 100644 --- a/jfxui/src/main/java/org/itsallcode/whiterabbit/jfxui/JavaFxApp.java +++ b/jfxui/src/main/java/org/itsallcode/whiterabbit/jfxui/JavaFxApp.java @@ -255,7 +255,7 @@ public void startManualInterruption() } JavaFxUtil.runOnFxApplicationThread(() -> { state.interruption.set(appService.startInterruption()); - new InterruptionDialog(primaryStage, state.currentSecondProperty.property(), state.interruption, clock) + new InterruptionDialog(primaryStage, state.currentTimeProperty.property(), state.interruption, clock) .show(); }); } diff --git a/jfxui/src/main/java/org/itsallcode/whiterabbit/jfxui/property/ClockPropertyFactory.java b/jfxui/src/main/java/org/itsallcode/whiterabbit/jfxui/property/ClockPropertyFactory.java index 9bb3c100..e9a0941e 100644 --- a/jfxui/src/main/java/org/itsallcode/whiterabbit/jfxui/property/ClockPropertyFactory.java +++ b/jfxui/src/main/java/org/itsallcode/whiterabbit/jfxui/property/ClockPropertyFactory.java @@ -2,8 +2,6 @@ import java.time.Instant; import java.time.LocalDate; -import java.time.LocalTime; -import java.time.YearMonth; import java.util.function.Supplier; import org.apache.logging.log4j.LogManager; @@ -27,26 +25,16 @@ public ClockPropertyFactory(AppService appService) this.appService = appService; } - public ScheduledProperty currentInstantProperty() + public ScheduledProperty currentTimeProperty() { return updatingProperty(PeriodicTrigger.everySecond(), () -> appService.getClock().instant()); } - public ScheduledProperty currentMinuteProperty() - { - return updatingProperty(PeriodicTrigger.everyMinute(), () -> appService.getClock().getCurrentTime()); - } - public ScheduledProperty currentDateProperty() { return updatingProperty(PeriodicTrigger.everyDay(), () -> appService.getClock().getCurrentDate()); } - public ScheduledProperty currentMonthProperty() - { - return updatingProperty(PeriodicTrigger.everyMonth(), () -> appService.getClock().getCurrentYearMonth()); - } - public ScheduledProperty updatingProperty(Trigger trigger, Supplier supplier) { final SimpleObjectProperty property = new SimpleObjectProperty<>(); diff --git a/jfxui/src/main/java/org/itsallcode/whiterabbit/jfxui/ui/AppUi.java b/jfxui/src/main/java/org/itsallcode/whiterabbit/jfxui/ui/AppUi.java index 74f49180..44ce7c43 100644 --- a/jfxui/src/main/java/org/itsallcode/whiterabbit/jfxui/ui/AppUi.java +++ b/jfxui/src/main/java/org/itsallcode/whiterabbit/jfxui/ui/AppUi.java @@ -261,9 +261,9 @@ private Node currentTimeLabel() final Label label = new Label(); label.setId("current-time-label"); label.textProperty().bind(Bindings.createStringBinding(() -> { - final Instant now = state.currentSecondProperty.property().getValue(); + final Instant now = state.currentTimeProperty.property().getValue(); return formatter.formatDateAndTime(now); - }, state.currentSecondProperty.property())); + }, state.currentTimeProperty.property())); return label; } @@ -283,7 +283,7 @@ private Node overtimeLabel() + formatter.format(totalOvertime); } return "Overtime: (no month selected)"; - }, state.currentSecondProperty.property(), state.currentMonth)); + }, state.currentTimeProperty.property(), state.currentMonth)); return label; } diff --git a/jfxui/src/uiTest/java/org/itsallcode/whiterabbit/jfxui/testutil/TimeUtil.java b/jfxui/src/uiTest/java/org/itsallcode/whiterabbit/jfxui/testutil/TimeUtil.java index 2710e610..eb78a486 100644 --- a/jfxui/src/uiTest/java/org/itsallcode/whiterabbit/jfxui/testutil/TimeUtil.java +++ b/jfxui/src/uiTest/java/org/itsallcode/whiterabbit/jfxui/testutil/TimeUtil.java @@ -36,7 +36,6 @@ public class TimeUtil private Runnable updateEverySecondRunnable; private Runnable updateEveryMinuteRunnable; private Runnable updateEveryDayRunnable; - private Runnable updateEveryMonthRunnable; private TimeUtil(Clock clockMock, ScheduledExecutorService executorServiceMock) { @@ -140,22 +139,23 @@ private void setCurrentTime(final Instant now) public void captureScheduledRunnables() { final ArgumentCaptor arg = ArgumentCaptor.forClass(Runnable.class); - verify(this.executorServiceMock, times(4)).schedule(arg.capture(), eq(0L), eq(TimeUnit.MILLISECONDS)); + verify(this.executorServiceMock, times(3)).schedule(arg.capture(), eq(0L), eq(TimeUnit.MILLISECONDS)); - this.updateEveryMonthRunnable = arg.getAllValues().get(0); - this.updateEveryDayRunnable = arg.getAllValues().get(1); - this.updateEverySecondRunnable = arg.getAllValues().get(2); - this.updateEveryMinuteRunnable = arg.getAllValues().get(3); + this.updateEveryDayRunnable = arg.getAllValues().get(0); + this.updateEverySecondRunnable = arg.getAllValues().get(1); + this.updateEveryMinuteRunnable = arg.getAllValues().get(2); + + LOG.trace("Found callback for seconds: {}", updateEverySecondRunnable); + LOG.trace("Found callback for days: {}", updateEveryDayRunnable); + LOG.trace("Found callback for minutes: {}", updateEveryMinuteRunnable); assertAll( - () -> assertThat(updateEveryMonthRunnable.toString()) - .contains("trigger=PeriodicTrigger [roundToUnit=Months]"), + () -> assertThat(updateEverySecondRunnable.toString()) + .contains("trigger=PeriodicTrigger [roundToUnit=Seconds]"), () -> assertThat(updateEveryDayRunnable.toString()) .contains("trigger=PeriodicTrigger [roundToUnit=Days]"), () -> assertThat(updateEveryMinuteRunnable.toString()) - .contains("trigger=PeriodicTrigger [roundToUnit=Minutes]"), - () -> assertThat(updateEverySecondRunnable.toString()) - .contains("trigger=PeriodicTrigger [roundToUnit=Seconds]")); + .contains("trigger=PeriodicTrigger [roundToUnit=Minutes]")); } public Clock clock() diff --git a/logic/src/main/java/org/itsallcode/whiterabbit/logic/service/scheduling/PeriodicTrigger.java b/logic/src/main/java/org/itsallcode/whiterabbit/logic/service/scheduling/PeriodicTrigger.java index 72f62809..9dd3a35f 100644 --- a/logic/src/main/java/org/itsallcode/whiterabbit/logic/service/scheduling/PeriodicTrigger.java +++ b/logic/src/main/java/org/itsallcode/whiterabbit/logic/service/scheduling/PeriodicTrigger.java @@ -15,11 +15,6 @@ private PeriodicTrigger(ChronoUnit roundToUnit) this.roundToUnit = roundToUnit; } - public static Trigger everyMonth() - { - return new PeriodicTrigger(ChronoUnit.MONTHS); - } - public static Trigger everyDay() { return new PeriodicTrigger(ChronoUnit.DAYS); From aad81e55e33dd07f26dc30d13ddfe2b4feb09fd0 Mon Sep 17 00:00:00 2001 From: kaklakariada Date: Sat, 5 Dec 2020 18:11:15 +0100 Subject: [PATCH 4/4] #50 #51: Select new month when month changes --- .../whiterabbit/jfxui/ui/AppUi.java | 12 ++++- .../whiterabbit/jfxui/JavaFxAppUiTest.java | 49 +++++++++++++++---- .../whiterabbit/jfxui/testutil/TimeUtil.java | 41 ++++++---------- .../testutil/model/ApplicationHelper.java | 29 ++++++++--- .../jfxui/testutil/model/DayTable.java | 15 +++++- 5 files changed, 102 insertions(+), 44 deletions(-) diff --git a/jfxui/src/main/java/org/itsallcode/whiterabbit/jfxui/ui/AppUi.java b/jfxui/src/main/java/org/itsallcode/whiterabbit/jfxui/ui/AppUi.java index 44ce7c43..c0314312 100644 --- a/jfxui/src/main/java/org/itsallcode/whiterabbit/jfxui/ui/AppUi.java +++ b/jfxui/src/main/java/org/itsallcode/whiterabbit/jfxui/ui/AppUi.java @@ -2,6 +2,7 @@ import javafx.application.Platform; import javafx.beans.binding.Bindings; +import javafx.beans.value.ObservableValue; import javafx.event.ActionEvent; import javafx.event.EventHandler; import javafx.geometry.Insets; @@ -186,8 +187,7 @@ private BorderPane createMainPane() { final Insets insets = new Insets(GAP_PIXEL); final Node daysTable = dayRecordTable.initTable(); - state.currentDateProperty.property() - .addListener((observable, oldValue, newValue) -> dayRecordTable.selectRow(newValue)); + state.currentDateProperty.property().addListener(this::dateChanged); final Node activitiesTab = activitiesTable.initTable(); final Button addActivityButton = button("add-activity-button", "+", "Add activity", e -> app.addActivity()); final Button removeActivityButton = button("remove-activity-button", "-", "Remove activity", @@ -291,6 +291,7 @@ private Node monthDropDownBox() { state.availableMonths.addAll(appService.getAvailableDataYearMonth()); final ComboBox comboBox = new ComboBox<>(state.availableMonths); + comboBox.setId("selected-month-combobox"); state.currentMonth.addListener( (observable, oldValue, newValue) -> comboBox.getSelectionModel().select(newValue.getYearMonth())); @@ -316,5 +317,12 @@ private Button button(String id, String label, String tooltip, EventHandler observable, LocalDate oldDate, LocalDate newDate) { + dayRecordTable.selectRow(newDate); + if(oldDate.getMonth()!=newDate.getMonth()) { + app.loadMonth(YearMonth.from(newDate)); + } + } } } diff --git a/jfxui/src/uiTest/java/org/itsallcode/whiterabbit/jfxui/JavaFxAppUiTest.java b/jfxui/src/uiTest/java/org/itsallcode/whiterabbit/jfxui/JavaFxAppUiTest.java index e9a8bf7d..51dfcbaa 100644 --- a/jfxui/src/uiTest/java/org/itsallcode/whiterabbit/jfxui/JavaFxAppUiTest.java +++ b/jfxui/src/uiTest/java/org/itsallcode/whiterabbit/jfxui/JavaFxAppUiTest.java @@ -1,13 +1,8 @@ package org.itsallcode.whiterabbit.jfxui; -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.assertAll; - -import java.time.Instant; -import java.time.LocalDate; -import java.time.LocalTime; -import java.util.Locale; - +import javafx.scene.control.Labeled; +import javafx.stage.Stage; +import org.itsallcode.whiterabbit.jfxui.testutil.TestUtil; import org.itsallcode.whiterabbit.logic.model.json.JsonDay; import org.itsallcode.whiterabbit.logic.model.json.JsonMonth; import org.junit.jupiter.api.Test; @@ -18,8 +13,11 @@ import org.testfx.framework.junit5.Start; import org.testfx.framework.junit5.Stop; -import javafx.scene.control.Labeled; -import javafx.stage.Stage; +import java.time.*; +import java.util.Locale; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertAll; @ExtendWith(ApplicationExtension.class) class JavaFxAppUiTest extends JavaFxAppUiTestBase @@ -101,6 +99,37 @@ void jsonFileWrittenAfterMinuteTick() () -> assertThat(month.getDays()).extracting(JsonDay::getEnd).containsExactly(end)); } + @Test + void newMonthSelectedWhenMonthChanges() + { + assertAll( + () -> assertThat(app().getSelectedMonth()).isEqualTo(YearMonth.of(2007, Month.DECEMBER)), + () -> app().dayTable().assertDate(0, LocalDate.of(2007, Month.DECEMBER, 1))); + + time().tickDay(LocalDateTime.of(2008, Month.JANUARY, 2, 8, 15, 0)); + + assertAll( + () -> assertThat(app().getSelectedMonth()).isEqualTo(YearMonth.of(2008, Month.JANUARY)), + () -> app().dayTable().assertDate(0, LocalDate.of(2008, Month.JANUARY, 1))); + } + + @Test + void newMonthSelectedUserChangesMonth() + { + time().tickDay(LocalDateTime.of(2008, Month.JANUARY, 2, 8, 15, 0)); + + assertAll( + () -> assertThat(app().getSelectedMonth()).isEqualTo(YearMonth.of(2008, Month.JANUARY)), + () -> app().dayTable().assertDate(0, LocalDate.of(2008, Month.JANUARY, 1))); + + app().setSelectedMonth(YearMonth.of(2007, Month.DECEMBER)); + TestUtil.sleepShort(); + + assertAll( + () -> assertThat(app().getSelectedMonth()).isEqualTo(YearMonth.of(2007, Month.DECEMBER)), + () -> app().dayTable().assertDate(0, LocalDate.of(2007, Month.DECEMBER, 1))); + } + @Override @Start void start(Stage stage) diff --git a/jfxui/src/uiTest/java/org/itsallcode/whiterabbit/jfxui/testutil/TimeUtil.java b/jfxui/src/uiTest/java/org/itsallcode/whiterabbit/jfxui/testutil/TimeUtil.java index eb78a486..5af4755b 100644 --- a/jfxui/src/uiTest/java/org/itsallcode/whiterabbit/jfxui/testutil/TimeUtil.java +++ b/jfxui/src/uiTest/java/org/itsallcode/whiterabbit/jfxui/testutil/TimeUtil.java @@ -1,31 +1,20 @@ package org.itsallcode.whiterabbit.jfxui.testutil; -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.assertAll; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyLong; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import java.time.Clock; -import java.time.Duration; -import java.time.Instant; -import java.time.LocalDate; -import java.time.LocalDateTime; -import java.time.LocalTime; -import java.time.ZoneId; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.mockito.ArgumentCaptor; + +import java.time.*; import java.time.temporal.ChronoUnit; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; import java.util.stream.IntStream; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.mockito.ArgumentCaptor; +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertAll; +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.Mockito.*; public class TimeUtil { @@ -109,7 +98,13 @@ public void tickDay(LocalTime time) { final LocalDateTime now = LocalDateTime.now(clockMock); final LocalDateTime tomorrow = LocalDateTime.of(now.toLocalDate().plusDays(1), time); - final Duration duration = Duration.between(now, tomorrow); + tickDay(tomorrow); + } + + public void tickDay(LocalDateTime nextDay) + { + final LocalDateTime now = LocalDateTime.now(clockMock); + final Duration duration = Duration.between(now, nextDay); addTime(duration); LOG.info("Tick day by {} to {}", duration, clockMock.instant()); this.updateEverySecondRunnable.run(); @@ -145,10 +140,6 @@ public void captureScheduledRunnables() this.updateEverySecondRunnable = arg.getAllValues().get(1); this.updateEveryMinuteRunnable = arg.getAllValues().get(2); - LOG.trace("Found callback for seconds: {}", updateEverySecondRunnable); - LOG.trace("Found callback for days: {}", updateEveryDayRunnable); - LOG.trace("Found callback for minutes: {}", updateEveryMinuteRunnable); - assertAll( () -> assertThat(updateEverySecondRunnable.toString()) .contains("trigger=PeriodicTrigger [roundToUnit=Seconds]"), diff --git a/jfxui/src/uiTest/java/org/itsallcode/whiterabbit/jfxui/testutil/model/ApplicationHelper.java b/jfxui/src/uiTest/java/org/itsallcode/whiterabbit/jfxui/testutil/model/ApplicationHelper.java index fbf87592..bb4624be 100644 --- a/jfxui/src/uiTest/java/org/itsallcode/whiterabbit/jfxui/testutil/model/ApplicationHelper.java +++ b/jfxui/src/uiTest/java/org/itsallcode/whiterabbit/jfxui/testutil/model/ApplicationHelper.java @@ -1,16 +1,18 @@ package org.itsallcode.whiterabbit.jfxui.testutil.model; -import java.time.Duration; - +import javafx.scene.control.Button; +import javafx.scene.control.ComboBox; +import javafx.scene.control.SplitMenuButton; +import javafx.scene.layout.StackPane; +import javafx.stage.Window; +import org.itsallcode.whiterabbit.jfxui.JavaFxUtil; import org.itsallcode.whiterabbit.jfxui.table.activities.ActivityPropertyAdapter; import org.itsallcode.whiterabbit.jfxui.table.days.DayRecordPropertyAdapter; import org.testfx.api.FxRobot; import org.testfx.assertions.api.Assertions; -import javafx.scene.control.Button; -import javafx.scene.control.SplitMenuButton; -import javafx.scene.layout.StackPane; -import javafx.stage.Window; +import java.time.Duration; +import java.time.YearMonth; public class ApplicationHelper { @@ -80,4 +82,19 @@ public AddInterruptionDialog addInterruption() Assertions.assertThat(dialogWindow).isShowing(); return new AddInterruptionDialog(robot, dialogWindow); } + + public YearMonth getSelectedMonth() + { + return getSelectedMonthComboBox().getValue(); + } + + public void setSelectedMonth(YearMonth month) + { + JavaFxUtil.runOnFxApplicationThread(() -> getSelectedMonthComboBox().setValue(month)); + } + + private ComboBox getSelectedMonthComboBox() + { + return robot.lookup("#selected-month-combobox").queryComboBox(); + } } diff --git a/jfxui/src/uiTest/java/org/itsallcode/whiterabbit/jfxui/testutil/model/DayTable.java b/jfxui/src/uiTest/java/org/itsallcode/whiterabbit/jfxui/testutil/model/DayTable.java index b8f75708..3e2c72fe 100644 --- a/jfxui/src/uiTest/java/org/itsallcode/whiterabbit/jfxui/testutil/model/DayTable.java +++ b/jfxui/src/uiTest/java/org/itsallcode/whiterabbit/jfxui/testutil/model/DayTable.java @@ -11,6 +11,7 @@ import org.testfx.api.FxRobot; import java.time.Duration; +import java.time.LocalDate; import java.time.LocalTime; import static org.assertj.core.api.Assertions.assertThat; @@ -46,6 +47,17 @@ public void assertBeginAndEnd(int row, LocalTime begin, LocalTime end) () -> assertThat(getEnd(row)).as("end").isEqualTo(end)); } + public void assertDate(int row, LocalDate expectedDate) + { + assertThat(getDate(row)).isEqualTo(expectedDate); + } + + public LocalDate getDate(int row) + { + final TableCell tableCell = table.getTableCell(row, "date"); + return (LocalDate) tableCell.getItem(); + } + public LocalTime getBegin(int row) { final TableCell tableCell = table.getTableCell(row, "begin"); @@ -94,7 +106,8 @@ public void typeComment(int row, String value) robot.doubleClickOn(getCommentCell(row)).write(value).type(KeyCode.TAB); } - public TableCell getCommentCell(int row) { + public TableCell getCommentCell(int row) + { return table.getTableCell(row, "comment"); }