Skip to content

Commit

Permalink
[prmr#508] Added notification limit when overshooting the main window…
Browse files Browse the repository at this point in the history
…, improved testing speed
  • Loading branch information
ArthusWQZ committed Dec 8, 2023
1 parent cf22508 commit 0886307
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 8 deletions.
6 changes: 6 additions & 0 deletions src/org/jetuml/gui/Notification.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,12 @@ public interface Notification
*/
void show(Runnable pCleanUpCallback);

/**
* Close the stage of the Notification object (to end it prematurely).
* Useful when the notifications go beyond the window.
*/
void close();

/**
* Move the Notification object to the desired position on the screen.
*
Expand Down
6 changes: 6 additions & 0 deletions src/org/jetuml/gui/NotificationService.java
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,12 @@ public void updateNotificationPosition()
{
notification.setPosition(x, y);
y = y - notification.getHeight() - NOTIFICATION_DISPLAY_SPACING;

if (y < aMainStage.getY())
{
notification.close();
aNotifications.remove(notification);
}
}
}

Expand Down
10 changes: 10 additions & 0 deletions src/org/jetuml/gui/ToastNotification.java
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,16 @@ public void run()
fadeInTimeline.play();
}

/**
* Close the stage of the Notification object (to end it prematurely).
* Useful when the notifications go beyond the window.
*/
@Override
public void close()
{
aStage.close();
}

/**
* Moves the Notification object to the desired position on the screen.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;

import java.lang.reflect.Field;
import java.util.ArrayList;
Expand Down Expand Up @@ -139,7 +140,7 @@ void testNoteEdgeFromClassToPoint() throws InterruptedException, ReflectiveOpera
diagram().addRootNode(aPointNode);
aNoteEdge.connect(aClassNode, aPointNode);
diagram().addEdge(aNoteEdge);
Platform.runLater(() -> assertFalse(aValidator.isValid()));
Platform.runLater(aValidator::isValid);
waitForRunLater();
@SuppressWarnings("unchecked")
List<Notification> notificationList = (List<Notification>) aListField.get(aNotificationService);
Expand Down
55 changes: 48 additions & 7 deletions test/org/jetuml/gui/TestNotificationService.java
Original file line number Diff line number Diff line change
Expand Up @@ -82,10 +82,15 @@ public static void closeStage() throws InterruptedException {
}

@BeforeEach
public void resetList() throws ReflectiveOperationException
public void resetListAndProperties() throws ReflectiveOperationException
{
ArrayList<Notification> newList = new ArrayList<>();
aListField.set(aNotificationService, newList);

aStage.setHeight(695.5);
aStage.setWidth(1125.0);
aStage.setX(220.5);
aStage.setY(220.5);
}

@Test
Expand Down Expand Up @@ -135,8 +140,8 @@ public void testNotificationPosition() throws InterruptedException, ReflectiveOp
@Test
public void testNotificationPositionWhenStageMoved() throws InterruptedException, ReflectiveOperationException
{
aStage.setX(0.5);
Platform.runLater(() -> {
aStage.setX(0.5);
aNotificationService.spawnNotification("This is a test error notification.", ToastNotification.Type.ERROR);
aNotificationService.spawnNotification("This is a test info notification.", ToastNotification.Type.INFO);
});
Expand All @@ -151,8 +156,7 @@ public void testNotificationPositionWhenStageMoved() throws InterruptedException
double stage1X = stage1.getX();
double stage2X = stage2.getX();

Platform.runLater(() -> aStage.setX(200));
waitForRunLater();
aStage.setX(200);

assertTrue(stage1.getX() > stage1X);
assertTrue(stage2.getX() > stage2X);
Expand All @@ -163,8 +167,8 @@ public void testNotificationPositionWhenStageMoved() throws InterruptedException
@Test
public void testNotificationPositionWhenStageResized() throws InterruptedException, ReflectiveOperationException
{
aStage.setHeight(600);
Platform.runLater(() -> {
aStage.setHeight(600);
aNotificationService.spawnNotification("This is a test error notification.", ToastNotification.Type.ERROR);
aNotificationService.spawnNotification("This is a test info notification.", ToastNotification.Type.INFO);
});
Expand All @@ -179,8 +183,7 @@ public void testNotificationPositionWhenStageResized() throws InterruptedExcepti
double stage1Y = stage1.getY();
double stage2Y = stage2.getY();

Platform.runLater(() -> aStage.setHeight(300));
waitForRunLater();
aStage.setHeight(300);

assertNotEquals(stage1.getY(), stage1Y);
assertNotEquals(stage2.getY(), stage2Y);
Expand Down Expand Up @@ -210,4 +213,42 @@ public void testNotificationPositionWhenRemoval() throws InterruptedException, R
assertTrue(stage1.getY() > stage1Y);
}

/*
If the notifications overshoot the main window, the oldest ones are removed to keep
the whole notification stack in the frame.
*/
@Test
public void testNotificationDeletionWhenWindowBorderReached() throws InterruptedException, ReflectiveOperationException
{
Field notificationSpacingField = NotificationService.class.getDeclaredField("NOTIFICATION_DISPLAY_SPACING");
notificationSpacingField.setAccessible(true);
Field notificationYMarginField = NotificationService.class.getDeclaredField("NOTIFICATION_DISPLAY_Y_MARGIN");
notificationYMarginField.setAccessible(true);

@SuppressWarnings("unchecked")
int notificationSpacing = (int) notificationSpacingField.get(null);
@SuppressWarnings("unchecked")
int yMargin = (int) notificationYMarginField.get(null);

Platform.runLater(() -> {
ToastNotification errorNotification = new ToastNotification("This is a test error notification.", ToastNotification.Type.ERROR, aStage);
ToastNotification infoNotification = new ToastNotification("This is a test info notification.", ToastNotification.Type.INFO, aStage);

aNotificationService.spawnNotification(errorNotification);
aNotificationService.spawnNotification(infoNotification);

// Let's compute the necessary height of the main window to fit two notifications
double height = yMargin + notificationSpacing*2 + errorNotification.getHeight() + infoNotification.getHeight()+1;
aStage.setHeight(height);

aNotificationService.spawnNotification("This is a test error notification.", ToastNotification.Type.ERROR);
aNotificationService.spawnNotification("This is a test info notification.", ToastNotification.Type.INFO);
});
waitForRunLater();

@SuppressWarnings("unchecked")
ArrayList<Notification> notificationList = (ArrayList<Notification>) aListField.get(aNotificationService);

assertEquals(2, notificationList.size());
}
}

0 comments on commit 0886307

Please sign in to comment.