package ovh.gasser.newshapes; import org.junit.jupiter.api.Test; import ovh.gasser.newshapes.attributes.SelectionAttributes; import ovh.gasser.newshapes.shapes.SCircle; import ovh.gasser.newshapes.shapes.SRectangle; import ovh.gasser.newshapes.shapes.STriangle; import ovh.gasser.newshapes.ui.listeners.SelectionListener; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.List; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; import static org.junit.jupiter.api.Assertions.*; class SelectionTest { @Test void testIsEmptyInitially() { Selection selection = new Selection(); assertTrue(selection.isEmpty()); } @Test void testAdd() { Selection selection = new Selection(); SCircle circle = SCircle.create(0, 0, 50); selection.add(circle); assertFalse(selection.isEmpty()); assertEquals(1, selection.getSelectedShapes().size()); assertTrue(selection.getSelectedShapes().contains(circle)); // Verify shape is marked as selected SelectionAttributes attrs = (SelectionAttributes) circle.getAttributes(SelectionAttributes.ID); assertNotNull(attrs); assertTrue(attrs.selected); } @Test void testAddAll() { Selection selection = new Selection(); SCircle circle1 = SCircle.create(0, 0, 50); SRectangle rect = SRectangle.create(10, 10, 100, 50); STriangle triangle = STriangle.create(50, 50, 30, java.awt.Color.BLACK, java.awt.Color.BLACK); List shapes = Arrays.asList(circle1, rect, triangle); selection.addAll(shapes); assertEquals(3, selection.getSelectedShapes().size()); assertTrue(selection.getSelectedShapes().contains(circle1)); assertTrue(selection.getSelectedShapes().contains(rect)); assertTrue(selection.getSelectedShapes().contains(triangle)); } @Test void testClear() { Selection selection = new Selection(); SCircle circle = SCircle.create(0, 0, 50); SRectangle rect = SRectangle.create(10, 10, 100, 50); selection.add(circle); selection.add(rect); assertFalse(selection.isEmpty()); assertEquals(2, selection.getSelectedShapes().size()); selection.clear(); assertTrue(selection.isEmpty()); assertEquals(0, selection.getSelectedShapes().size()); // Verify shapes are marked as unselected SelectionAttributes circleAttrs = (SelectionAttributes) circle.getAttributes(SelectionAttributes.ID); SelectionAttributes rectAttrs = (SelectionAttributes) rect.getAttributes(SelectionAttributes.ID); assertNotNull(circleAttrs); assertNotNull(rectAttrs); assertFalse(circleAttrs.selected); assertFalse(rectAttrs.selected); } @Test void testGetSelectedShapesReturnsCopy() { Selection selection = new Selection(); SCircle circle = SCircle.create(0, 0, 50); selection.add(circle); List copy = selection.getSelectedShapes(); // Try to modify the copy assertThrows(UnsupportedOperationException.class, () -> copy.add(SCircle.create(10, 10, 20))); // Original should be unchanged assertEquals(1, selection.getSelectedShapes().size()); } @Test void testAddListener() { Selection selection = new Selection(); AtomicBoolean listenerNotified = new AtomicBoolean(false); AtomicInteger notificationCount = new AtomicInteger(0); SelectionListener listener = (selectedShapes) -> { listenerNotified.set(true); notificationCount.incrementAndGet(); }; selection.addListener(listener); // Adding a shape should notify listener SCircle circle = SCircle.create(0, 0, 50); selection.add(circle); assertTrue(listenerNotified.get()); assertEquals(1, notificationCount.get()); // Adding another shape should notify listener again SRectangle rect = SRectangle.create(10, 10, 100, 50); selection.add(rect); assertEquals(2, notificationCount.get()); // Clearing should notify listener selection.clear(); assertEquals(3, notificationCount.get()); } @Test void testNullAddAllDoesNothing() { Selection selection = new Selection(); // Should not throw assertDoesNotThrow(() -> selection.addAll(null)); // Selection should still be empty assertTrue(selection.isEmpty()); } }