From afac14a4bbd22ccdf048a9c9345d9ffe0b465765 Mon Sep 17 00:00:00 2001 From: Vlad Nitu Date: Sun, 10 Jul 2022 02:23:57 +0300 Subject: [PATCH 1/8] Added mockito dependency into pom.xml file Took 11 minutes --- pom.xml | 7 +++++++ src/test/java/TileTest.java | 2 ++ 2 files changed, 9 insertions(+) create mode 100644 src/test/java/TileTest.java diff --git a/pom.xml b/pom.xml index de19852d..7035f612 100644 --- a/pom.xml +++ b/pom.xml @@ -56,6 +56,13 @@ AppleJavaExtensions 1.4 + + + org.mockito + mockito-core + 4.6.1 + test + diff --git a/src/test/java/TileTest.java b/src/test/java/TileTest.java new file mode 100644 index 00000000..9a7142ea --- /dev/null +++ b/src/test/java/TileTest.java @@ -0,0 +1,2 @@ +package PACKAGE_NAME;public class TileTest { +} From 0949dbf0cd9f78f133267bddea227778a4eaac24 Mon Sep 17 00:00:00 2001 From: Vlad Nitu Date: Sun, 10 Jul 2022 02:24:14 +0300 Subject: [PATCH 2/8] Unit tested Tile.java class --- src/test/java/TileTest.java | 49 ++++++++++++++++++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/src/test/java/TileTest.java b/src/test/java/TileTest.java index 9a7142ea..97552d22 100644 --- a/src/test/java/TileTest.java +++ b/src/test/java/TileTest.java @@ -1,2 +1,49 @@ -package PACKAGE_NAME;public class TileTest { +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import processing.core.PImage; +import processing.core.PVector; +import project_16x16.Tileset; +import project_16x16.components.Tile; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.mockito.Mockito.mock; + +public class TileTest { + + private Tile tile; + private PImage image; + + + @BeforeEach + void setup() { + image = mock(PImage.class); + tile = new Tile(1, "tile", image, Tile.TileType.BACKGROUND); + } + + @Test + void constructorTest() { + assertNotNull(tile); + } + @Test + void getIDTest() { + assertEquals(tile.getID(), 1); + } + @Test + void getNameTest() { + assertEquals(tile.getName(), "tile"); + } + @Test + void getPImageTest() { + assertEquals(tile.getPImage(), image); + } + @Test + void getTileTypeTest() { + assertEquals(tile.getTileType(), Tile.TileType.BACKGROUND); + } + @Test + void getPositionTest() { + PVector vector = new PVector(Tileset.TILESETWIDTH, 0); // as ID = 1 + assertEquals(tile.getPosition(), vector); + } } From 07de5e813de7661be0cdcfa7ec5938c71513e060 Mon Sep 17 00:00:00 2001 From: Vlad Nitu Date: Tue, 12 Jul 2022 20:35:23 +0200 Subject: [PATCH 3/8] Solved conflict keeping your changes Took 2 minutes --- src/test/java/TileTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/TileTest.java b/src/test/java/TileTest.java index 97552d22..0f5ab19f 100644 --- a/src/test/java/TileTest.java +++ b/src/test/java/TileTest.java @@ -27,7 +27,7 @@ void constructorTest() { } @Test void getIDTest() { - assertEquals(tile.getID(), 1); + assertEquals(tile.getId(), 1); } @Test void getNameTest() { From a0c3bd8cdf722e9994dbbbe8594b4ba8dbe6ce44 Mon Sep 17 00:00:00 2001 From: Danilo Migliarino Date: Sat, 27 Jul 2024 12:24:57 +0200 Subject: [PATCH 4/8] Moved TileTest.java under project_16x16.components package. --- src/test/java/{ => project_16x16/components}/TileTest.java | 1 + 1 file changed, 1 insertion(+) rename src/test/java/{ => project_16x16/components}/TileTest.java (97%) diff --git a/src/test/java/TileTest.java b/src/test/java/project_16x16/components/TileTest.java similarity index 97% rename from src/test/java/TileTest.java rename to src/test/java/project_16x16/components/TileTest.java index 0f5ab19f..7dc1ad1c 100644 --- a/src/test/java/TileTest.java +++ b/src/test/java/project_16x16/components/TileTest.java @@ -1,3 +1,4 @@ +package project_16x16.components; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import processing.core.PImage; From 611866faaaa442f56dc2db74bec585bc4affbc1e Mon Sep 17 00:00:00 2001 From: Danilo Migliarino Date: Sat, 27 Jul 2024 14:38:18 +0200 Subject: [PATCH 5/8] Added formatting rules description and applied to TileTest.java --- CONTRIBUTING.md | 4 + .../project_16x16/components/TileTest.java | 85 ++++++++++--------- 2 files changed, 49 insertions(+), 40 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 7333d671..6c67c94a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -116,6 +116,10 @@ It is recommended to create a commit every time you complete a task: That's it for the Source tree setup! Now, you are ready to [open up the code editor](wiki). Don't forget to come back to this file when you are ready to know about [the Process of Making Changes](#the-process-of-making-changes). ## The Process of Making Changes +### Before starting coding... formatting rules! +Having a codebase formatted consistently makes things easier. Code will be easier to understand for new contributors and the risk of mistakes will be reduced. +Make sure to configure your IDE so that it uses **Eclipse_formatter.xml** file rules. You can also tell your IDE to automatically format the code before each save action. It is importanto to make sure that the code is formatted before any commit. + ### Issues You are now ready to contribute! Github represents tasks as issues. You can find all of the issues [here](https://github.com/Stephcraft/Project-16x16/issues) or in the **Issues** tab of the repository. If you found a bug, would like to add a feature or simply do not find something interesting to contribute to, then you can [create your own issue](https://github.com/Stephcraft/Project-16x16/issues/new). diff --git a/src/test/java/project_16x16/components/TileTest.java b/src/test/java/project_16x16/components/TileTest.java index 7dc1ad1c..ccba1c65 100644 --- a/src/test/java/project_16x16/components/TileTest.java +++ b/src/test/java/project_16x16/components/TileTest.java @@ -1,50 +1,55 @@ package project_16x16.components; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.mockito.Mockito.mock; + import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; + import processing.core.PImage; import processing.core.PVector; import project_16x16.Tileset; -import project_16x16.components.Tile; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.mockito.Mockito.mock; public class TileTest { - private Tile tile; - private PImage image; - - - @BeforeEach - void setup() { - image = mock(PImage.class); - tile = new Tile(1, "tile", image, Tile.TileType.BACKGROUND); - } - - @Test - void constructorTest() { - assertNotNull(tile); - } - @Test - void getIDTest() { - assertEquals(tile.getId(), 1); - } - @Test - void getNameTest() { - assertEquals(tile.getName(), "tile"); - } - @Test - void getPImageTest() { - assertEquals(tile.getPImage(), image); - } - @Test - void getTileTypeTest() { - assertEquals(tile.getTileType(), Tile.TileType.BACKGROUND); - } - @Test - void getPositionTest() { - PVector vector = new PVector(Tileset.TILESETWIDTH, 0); // as ID = 1 - assertEquals(tile.getPosition(), vector); - } + private Tile tile; + private PImage image; + + @BeforeEach + void setup() { + image = mock(PImage.class); + tile = new Tile(1, "tile", image, Tile.TileType.BACKGROUND); + } + + @Test + void constructorTest() { + assertNotNull(tile); + } + + @Test + void getIDTest() { + assertEquals(tile.getId(), 1); + } + + @Test + void getNameTest() { + assertEquals(tile.getName(), "tile"); + } + + @Test + void getPImageTest() { + assertEquals(tile.getPImage(), image); + } + + @Test + void getTileTypeTest() { + assertEquals(tile.getTileType(), Tile.TileType.BACKGROUND); + } + + @Test + void getPositionTest() { + PVector vector = new PVector(Tileset.TILESETWIDTH, 0); // as ID = 1 + assertEquals(tile.getPosition(), vector); + } } From ca40eaa1bc9f85abb3b7c73279b44f121ab33681 Mon Sep 17 00:00:00 2001 From: Danilo Migliarino Date: Sat, 27 Jul 2024 18:22:52 +0200 Subject: [PATCH 6/8] Refactored tests. --- src/test/java/project_16x16/OptionsTest.java | 10 ++--- .../project_16x16/components/TileTest.java | 26 ++++++------- .../multiplayer/MultiplayerTest.java | 37 +++++++++---------- 3 files changed, 35 insertions(+), 38 deletions(-) diff --git a/src/test/java/project_16x16/OptionsTest.java b/src/test/java/project_16x16/OptionsTest.java index b1334b1e..37d561eb 100644 --- a/src/test/java/project_16x16/OptionsTest.java +++ b/src/test/java/project_16x16/OptionsTest.java @@ -6,12 +6,10 @@ import org.junit.jupiter.api.Test; -import project_16x16.Options; - -public class OptionsTest { +class OptionsTest { @Test - public void callingSaveWithIntShouldUpdateOptions() { + void callingSaveWithIntShouldUpdateOptions() { int expected = 5; Preferences options = Preferences.userNodeForPackage(Options.class); @@ -21,7 +19,7 @@ public void callingSaveWithIntShouldUpdateOptions() { } @Test - public void callingSaveWithFloatShouldUpdateOptions() { + void callingSaveWithFloatShouldUpdateOptions() { float expected = 5.5f; Preferences options = Preferences.userNodeForPackage(Options.class); @@ -31,7 +29,7 @@ public void callingSaveWithFloatShouldUpdateOptions() { } @Test - public void callingSaveWithBooleanShouldUpdateOptions() { + void callingSaveWithBooleanShouldUpdateOptions() { Preferences options = Preferences.userNodeForPackage(Options.class); Options.save(Options.Option.testKey, true); diff --git a/src/test/java/project_16x16/components/TileTest.java b/src/test/java/project_16x16/components/TileTest.java index ccba1c65..2f4da259 100644 --- a/src/test/java/project_16x16/components/TileTest.java +++ b/src/test/java/project_16x16/components/TileTest.java @@ -11,7 +11,7 @@ import processing.core.PVector; import project_16x16.Tileset; -public class TileTest { +class TileTest { private Tile tile; private PImage image; @@ -23,33 +23,33 @@ void setup() { } @Test - void constructorTest() { + void callingConstructor_shouldNotFail() { assertNotNull(tile); } @Test - void getIDTest() { - assertEquals(tile.getId(), 1); + void callingGetId_shouldReturnExpected() { + assertEquals(1, tile.getId()); } @Test - void getNameTest() { - assertEquals(tile.getName(), "tile"); + void callingGetName_shouldReturnExpected() { + assertEquals("tile", tile.getName()); } @Test - void getPImageTest() { - assertEquals(tile.getPImage(), image); + void callingGetPImage_shouldReturnExpected() { + assertEquals(image, tile.getPImage()); } @Test - void getTileTypeTest() { - assertEquals(tile.getTileType(), Tile.TileType.BACKGROUND); + void callingGetTileType_shouldReturnExpected() { + assertEquals(Tile.TileType.BACKGROUND, tile.getTileType()); } @Test - void getPositionTest() { - PVector vector = new PVector(Tileset.TILESETWIDTH, 0); // as ID = 1 - assertEquals(tile.getPosition(), vector); + void callingGetPosition_shouldReturnExpected() { + PVector vector = new PVector(Tileset.TILESETWIDTH, 0); + assertEquals(vector, tile.getPosition()); } } diff --git a/src/test/java/project_16x16/multiplayer/MultiplayerTest.java b/src/test/java/project_16x16/multiplayer/MultiplayerTest.java index 756a0b85..fe625532 100644 --- a/src/test/java/project_16x16/multiplayer/MultiplayerTest.java +++ b/src/test/java/project_16x16/multiplayer/MultiplayerTest.java @@ -22,19 +22,18 @@ import processing.net.Client; import processing.net.Server; import project_16x16.SideScroller; -import project_16x16.multiplayer.Multiplayer; @ExtendWith(MockitoExtension.class) -public class MultiplayerTest { +class MultiplayerTest { @Mock private SideScroller player; @Test - public void callingConstructorAsServer_ok() { + void callingConstructorAsServer_ok() { ConnectException ce = null; try { - Multiplayer multiplayer = new Multiplayer(player, false); + new Multiplayer(player, false); } catch (ConnectException e) { ce = e; @@ -44,10 +43,10 @@ public void callingConstructorAsServer_ok() { } @Test - public void callingConstructorAsClient_ok() { + void callingConstructorAsClient_ok() { ConnectException ce = null; try { - Multiplayer multiplayer = new Multiplayer(player, true); + new Multiplayer(player, true); } catch (ConnectException e) { ce = e; @@ -57,13 +56,13 @@ public void callingConstructorAsClient_ok() { } @Test - public void callingConstructorAsServer_raisesException() { + void callingConstructorAsServer_raisesException() { ConnectException ce = null; try (MockedConstruction mocked = mockConstruction(Server.class, (mock, context) -> { when(mock.active()).thenReturn(false); })) { try { - Multiplayer multiplayer = new Multiplayer(player, true); + new Multiplayer(player, true); } catch (ConnectException e) { ce = e; @@ -74,13 +73,13 @@ public void callingConstructorAsServer_raisesException() { } @Test - public void callingConstructorAsClient_raisesException() { + void callingConstructorAsClient_raisesException() { ConnectException ce = null; try (MockedConstruction mocked = mockConstruction(Client.class, (mock, context) -> { when(mock.active()).thenReturn(false); })) { try { - Multiplayer multiplayer = new Multiplayer(player, false); + new Multiplayer(player, false); } catch (ConnectException e) { ce = e; @@ -91,7 +90,7 @@ public void callingConstructorAsClient_raisesException() { } @Test - public void callingReadDataAsServerWithNoClient_returnsNullData() { + void callingReadDataAsServerWithNoClient_returnsNullData() { ConnectException ce = null; JSONObject data = null; try (MockedConstruction mocked = mockConstruction(Server.class, (mock, context) -> { @@ -112,7 +111,7 @@ public void callingReadDataAsServerWithNoClient_returnsNullData() { } @Test - public void callingReadDataAsServerWithClient_returnsData() { + void callingReadDataAsServerWithClient_returnsData() { ConnectException ce = null; JSONObject data = null; @@ -138,7 +137,7 @@ public void callingReadDataAsServerWithClient_returnsData() { } @Test - public void callingReadDataAsClientWithNoAvailableData_returnsNullData() { + void callingReadDataAsClientWithNoAvailableData_returnsNullData() { ConnectException ce = null; JSONObject data = null; try (MockedConstruction client = mockConstruction(Client.class, (mock, context) -> { @@ -159,7 +158,7 @@ public void callingReadDataAsClientWithNoAvailableData_returnsNullData() { } @Test - public void callingReadDataAsClient_returnsData() { + void callingReadDataAsClient_returnsData() { ConnectException ce = null; JSONObject data = null; try (MockedConstruction client = mockConstruction(Client.class, (mock, context) -> { @@ -182,7 +181,7 @@ public void callingReadDataAsClient_returnsData() { } @Test - public void callingWriteDataAsServer() { + void callingWriteDataAsServer() { ConnectException ce = null; try (MockedConstruction mocked = mockConstruction(Server.class, (mock, context) -> { when(mock.active()).thenReturn(true); @@ -203,7 +202,7 @@ public void callingWriteDataAsServer() { } @Test - public void callingWriteDataAsClient() { + void callingWriteDataAsClient() { ConnectException ce = null; try (MockedConstruction mocked = mockConstruction(Client.class, (mock, context) -> { when(mock.active()).thenReturn(true); @@ -224,7 +223,7 @@ public void callingWriteDataAsClient() { } @Test - public void callingWriteDataAsClientNotActive_doNotWrites() { + void callingWriteDataAsClientNotActive_doNotWrites() { ConnectException ce = null; try (MockedConstruction mocked = mockConstruction(Client.class, (mock, context) -> { when(mock.active()).thenReturn(true); @@ -246,7 +245,7 @@ public void callingWriteDataAsClientNotActive_doNotWrites() { } @Test - public void callingExitAsServer() { + void callingExitAsServer() { ConnectException ce = null; try (MockedConstruction mocked = mockConstruction(Server.class, (mock, context) -> { when(mock.active()).thenReturn(true); @@ -267,7 +266,7 @@ public void callingExitAsServer() { } @Test - public void callingExitAsClient() { + void callingExitAsClient() { ConnectException ce = null; try (MockedConstruction mocked = mockConstruction(Client.class, (mock, context) -> { when(mock.active()).thenReturn(true); From 1f1fb86d93e31714d68023578c4ab7d9352d441c Mon Sep 17 00:00:00 2001 From: Danilo Migliarino Date: Mon, 2 Dec 2024 00:10:15 +0100 Subject: [PATCH 7/8] Added AudioTest and refactored static Audio class methods. --- pom.xml | 18 +- src/main/java/project_16x16/Audio.java | 34 ++- src/main/java/project_16x16/SideScroller.java | 18 +- .../components/AnimationComponent.java | 4 +- .../java/project_16x16/entities/Player.java | 4 +- .../project_16x16/factory/AudioFactory.java | 21 ++ .../project_16x16/scene/AudioSettings.java | 11 +- .../project_16x16/scene/GameplayScene.java | 4 +- .../java/project_16x16/scene/MainMenu.java | 10 +- src/test/java/project_16x16/AudioTest.java | 286 ++++++++++++++++++ 10 files changed, 359 insertions(+), 51 deletions(-) create mode 100644 src/main/java/project_16x16/factory/AudioFactory.java create mode 100644 src/test/java/project_16x16/AudioTest.java diff --git a/pom.xml b/pom.xml index 9ba2644e..abb9b943 100644 --- a/pom.xml +++ b/pom.xml @@ -54,18 +54,12 @@ AppleJavaExtensions 1.4 - - org.mockito - mockito-junit-jupiter - 4.6.1 - test - - - org.mockito - mockito-inline - 4.6.1 - test - + + org.mockito + mockito-junit-jupiter + 5.14.2 + test + diff --git a/src/main/java/project_16x16/Audio.java b/src/main/java/project_16x16/Audio.java index dc3c8b7b..19c25fae 100644 --- a/src/main/java/project_16x16/Audio.java +++ b/src/main/java/project_16x16/Audio.java @@ -7,7 +7,7 @@ import ddf.minim.Minim; /** - * Provides static methods for playing game audio: background music and sound + * Provides methods for playing game audio: background music and sound * effects. * * @author micycle1 @@ -20,7 +20,7 @@ public final class Audio { private static float gainBGM = 0; private static float gainSFX = 0; - private static Minim minim; + private Minim minim; /** * Background music, which are referenced as enums. @@ -58,16 +58,20 @@ public String getPath() { } } - private static final HashMap SFX_MAP = new HashMap<>(); // could load from json - private static final HashMap BGM_MAP = new HashMap<>(); // could load from json + private HashMap SFX_MAP = new HashMap<>(); // could load from json + private HashMap BGM_MAP = new HashMap<>(); // could load from json + protected Minim createMinim(SideScroller sideScroller) { + return new Minim(sideScroller); + } + /** * Call during setup to instantiate a connection to Minim (the audio backend). * * @param s */ - public static void assignApplet(SideScroller sideScroller) { - minim = new Minim(sideScroller); + public void assignApplet(SideScroller sideScroller) { + minim = createMinim(sideScroller); for (SFX sfx : SFX.values()) { AudioSample sample = minim.loadSample(sfx.getPath()); if (sample != null) { @@ -98,7 +102,7 @@ public static void assignApplet(SideScroller sideScroller) { * @see #play(SFX, float) * @see ddf.minim.AudioSample#trigger() */ - public static void play(SFX sound) { + public void play(SFX sound) { if (SFX_MAP.containsKey(sound)) { SFX_MAP.get(sound).trigger(); } @@ -116,7 +120,7 @@ public static void play(SFX sound) { * @see #play(SFX) * @see ddf.minim.AudioSample#trigger() */ - public static void play(SFX sound, float gain) { + public void play(SFX sound, float gain) { if (SFX_MAP.containsKey(sound)) { SFX_MAP.get(sound).setGain(gain); SFX_MAP.get(sound).trigger(); @@ -134,7 +138,7 @@ public static void play(SFX sound, float gain) { * @param sound BGM track * @see #play(BGM, float) */ - public static void play(BGM sound) { + public void play(BGM sound) { if (BGM_MAP.get(sound).isPlaying()) { return; } @@ -162,7 +166,7 @@ public static void play(BGM sound) { * @param gain gain, in decibels (where negative is quieter). Default = 0. * @see #play(BGM) */ - public static void play(BGM sound, float gain) { + public void play(BGM sound, float gain) { if (BGM_MAP.containsKey(sound)) { BGM_MAP.get(sound).setGain(gain); play(sound); @@ -177,7 +181,7 @@ public static void play(BGM sound, float gain) { * * @param gain gain, in decibels (where negative is quieter). Default = 0. */ - public static void setGainBGM(float gain) { + public void setGainBGM(float gain) { gainBGM = gain; BGM_MAP.values().forEach(sound -> sound.setGain(gainBGM)); } @@ -187,7 +191,7 @@ public static void setGainBGM(float gain) { * * @param gain gain, in decibels (where negative is quieter). Default = 0. */ - public static void setGainSFX(float gain) { + public void setGainSFX(float gain) { gainSFX = gain; SFX_MAP.values().forEach(sound -> sound.setGain(gainSFX)); } @@ -195,7 +199,7 @@ public static void setGainSFX(float gain) { /** * Global mute. */ - public static void mute() { + public void mute() { SFX_MAP.values().forEach(sound -> sound.mute()); BGM_MAP.values().forEach(sound -> sound.mute()); } @@ -203,7 +207,7 @@ public static void mute() { /** * Global unmute. */ - public static void unMute() { + public void unMute() { SFX_MAP.values().forEach(sound -> sound.unmute()); BGM_MAP.values().forEach(sound -> sound.unmute()); } @@ -214,7 +218,7 @@ public static void unMute() { * * @see Minim#stop() */ - public static void exit() { + public void exit() { minim.stop(); } diff --git a/src/main/java/project_16x16/SideScroller.java b/src/main/java/project_16x16/SideScroller.java index aca5997c..ade900d0 100644 --- a/src/main/java/project_16x16/SideScroller.java +++ b/src/main/java/project_16x16/SideScroller.java @@ -9,21 +9,27 @@ import javafx.scene.transform.Scale; import javafx.stage.Stage; import javafx.stage.WindowEvent; - import processing.core.PApplet; import processing.core.PFont; import processing.core.PSurface; import processing.core.PVector; - import processing.event.MouseEvent; import processing.javafx.PSurfaceFX; - import project_16x16.Options.Option; import project_16x16.components.AnimationComponent; import project_16x16.entities.Player; +import project_16x16.factory.AudioFactory; import project_16x16.multiplayer.Multiplayer; -import project_16x16.scene.*; +import project_16x16.scene.AudioSettings; +import project_16x16.scene.GameplayScene; import project_16x16.scene.GameplayScene.GameModes; +import project_16x16.scene.MainMenu; +import project_16x16.scene.MultiplayerClientMenu; +import project_16x16.scene.MultiplayerHostMenu; +import project_16x16.scene.MultiplayerMenu; +import project_16x16.scene.PScene; +import project_16x16.scene.PauseMenu; +import project_16x16.scene.Settings; import project_16x16.ui.Notifications; /** @@ -157,7 +163,7 @@ protected PSurface initSurface() { */ private void closeWindowEvent(WindowEvent event) { try { - Audio.exit(); + AudioFactory.getInstance().exit(); game.exit(); } finally { stage.close(); @@ -188,7 +194,7 @@ public void setup() { load(); AnimationComponent.assignApplet(this); Notifications.assignApplet(this); - Audio.assignApplet(this); + AudioFactory.getInstance().assignApplet(this); // Create scene sceneHistory = new ArrayDeque<>(); diff --git a/src/main/java/project_16x16/components/AnimationComponent.java b/src/main/java/project_16x16/components/AnimationComponent.java index f20fcd99..1eac13ad 100644 --- a/src/main/java/project_16x16/components/AnimationComponent.java +++ b/src/main/java/project_16x16/components/AnimationComponent.java @@ -6,9 +6,9 @@ import org.apache.commons.collections.map.MultiValueMap; import processing.core.PImage; -import project_16x16.Audio; import project_16x16.Audio.SFX; import project_16x16.SideScroller; +import project_16x16.factory.AudioFactory; /** * The Animation Class @@ -84,7 +84,7 @@ public PImage animate() { } Collection coll = (Collection) sounds.get((int) currentFrame); // TODO high overhead? if (coll != null) { - coll.forEach(sound -> Audio.play(sound)); + coll.forEach(sound -> AudioFactory.getInstance().play(sound)); } return frame; } diff --git a/src/main/java/project_16x16/entities/Player.java b/src/main/java/project_16x16/entities/Player.java index 7ce94f21..cc4a9858 100644 --- a/src/main/java/project_16x16/entities/Player.java +++ b/src/main/java/project_16x16/entities/Player.java @@ -6,7 +6,6 @@ import processing.core.PImage; import processing.core.PVector; import processing.data.JSONObject; -import project_16x16.Audio; import project_16x16.Audio.SFX; import project_16x16.Constants; import project_16x16.Options; @@ -15,6 +14,7 @@ import project_16x16.Tileset; import project_16x16.Utility; import project_16x16.components.AnimationComponent; +import project_16x16.factory.AudioFactory; import project_16x16.objects.CollidableObject; import project_16x16.objects.EditableObject; import project_16x16.projectiles.Swing; @@ -204,7 +204,7 @@ private void handleKeyboardInput() { state.flying = true; state.jumping = true; velocity.y -= speedJump; - Audio.play(SFX.JUMP); + AudioFactory.getInstance().play(SFX.JUMP); if (state.dashing) { state.dashing = false; velocity.y *= 1.2f; diff --git a/src/main/java/project_16x16/factory/AudioFactory.java b/src/main/java/project_16x16/factory/AudioFactory.java new file mode 100644 index 00000000..59d9fcf2 --- /dev/null +++ b/src/main/java/project_16x16/factory/AudioFactory.java @@ -0,0 +1,21 @@ +package project_16x16.factory; + +import project_16x16.Audio; + +public class AudioFactory { + + private static Audio audio; + + public static Audio getInstance() { + if (audio == null) { + audio = new Audio(); + } + + return audio; + } + + public static Audio createInstance() { + return new Audio(); + } + +} diff --git a/src/main/java/project_16x16/scene/AudioSettings.java b/src/main/java/project_16x16/scene/AudioSettings.java index 126b55a8..3285358b 100644 --- a/src/main/java/project_16x16/scene/AudioSettings.java +++ b/src/main/java/project_16x16/scene/AudioSettings.java @@ -1,14 +1,13 @@ package project_16x16.scene; -import processing.core.PApplet; import processing.core.PConstants; import processing.event.KeyEvent; import processing.event.MouseEvent; -import project_16x16.Audio; import project_16x16.Constants; import project_16x16.Options; import project_16x16.Options.Option; import project_16x16.SideScroller; +import project_16x16.factory.AudioFactory; import project_16x16.ui.Button; import project_16x16.ui.Notifications; import project_16x16.ui.Slider; @@ -79,8 +78,8 @@ void mouseDragged(MouseEvent e) { volumeSFX.update(); float volBGM = 20 * (float) Math.log(volumeBGM.getValue()); float volSFX = 20 * (float) Math.log(volumeSFX.getValue()); - Audio.setGainBGM(volBGM); - Audio.setGainSFX(volSFX); + AudioFactory.getInstance().setGainBGM(volBGM); + AudioFactory.getInstance().setGainSFX(volSFX); } @Override @@ -90,8 +89,8 @@ void mouseReleased(MouseEvent e) { if (quit.hover()) { // revert sound changes if menu is quit - Audio.setGainBGM(originalVolumeBGM); - Audio.setGainSFX(originalVolumeSFX); + AudioFactory.getInstance().setGainBGM(originalVolumeBGM); + AudioFactory.getInstance().setGainSFX(originalVolumeSFX); game.returnScene(); return; } diff --git a/src/main/java/project_16x16/scene/GameplayScene.java b/src/main/java/project_16x16/scene/GameplayScene.java index 3728be51..d4b11e20 100644 --- a/src/main/java/project_16x16/scene/GameplayScene.java +++ b/src/main/java/project_16x16/scene/GameplayScene.java @@ -12,7 +12,6 @@ import processing.data.JSONArray; import processing.data.JSONObject; import processing.event.MouseEvent; -import project_16x16.Audio; import project_16x16.Audio.BGM; import project_16x16.Options; import project_16x16.SideScroller; @@ -22,6 +21,7 @@ import project_16x16.components.Tile; import project_16x16.components.Tile.TileType; import project_16x16.entities.Player; +import project_16x16.factory.AudioFactory; import project_16x16.multiplayer.Multiplayer; import project_16x16.objects.BackgroundObject; import project_16x16.objects.CollidableObject; @@ -202,7 +202,7 @@ private void setup() { public void switchTo() { super.switchTo(); ((PauseMenu) GameScenes.PAUSE_MENU.getScene()).switched = false; - Audio.play(BGM.TEST1); + AudioFactory.getInstance().play(BGM.TEST1); } /** diff --git a/src/main/java/project_16x16/scene/MainMenu.java b/src/main/java/project_16x16/scene/MainMenu.java index 4282d3b6..3cc8a81b 100644 --- a/src/main/java/project_16x16/scene/MainMenu.java +++ b/src/main/java/project_16x16/scene/MainMenu.java @@ -8,14 +8,12 @@ import processing.core.PGraphics; import processing.event.KeyEvent; import processing.event.MouseEvent; - -import project_16x16.SideScroller; -import project_16x16.Utility; -import project_16x16.Audio; import project_16x16.Audio.BGM; import project_16x16.Constants; +import project_16x16.SideScroller; import project_16x16.SideScroller.GameScenes; -import project_16x16.scene.PScene; +import project_16x16.Utility; +import project_16x16.factory.AudioFactory; import project_16x16.ui.Button; /** @@ -72,7 +70,7 @@ public MainMenu(SideScroller a) { @Override public void switchTo() { super.switchTo(); - Audio.play(BGM.TEST3); + AudioFactory.getInstance().play(BGM.TEST3); } @Override diff --git a/src/test/java/project_16x16/AudioTest.java b/src/test/java/project_16x16/AudioTest.java new file mode 100644 index 00000000..7ea98317 --- /dev/null +++ b/src/test/java/project_16x16/AudioTest.java @@ -0,0 +1,286 @@ +package project_16x16; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.atLeastOnce; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.mockConstruction; +import static org.mockito.Mockito.mockStatic; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import java.util.HashMap; +import java.util.List; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockedConstruction; +import org.mockito.MockedStatic; +import org.mockito.Spy; +import org.mockito.junit.jupiter.MockitoExtension; + +import ddf.minim.AudioPlayer; +import ddf.minim.AudioSample; +import ddf.minim.Minim; +import project_16x16.Audio.BGM; +import project_16x16.Audio.SFX; + +@ExtendWith(MockitoExtension.class) +class AudioTest { + + @InjectMocks + @Spy + Audio audio; + + @Mock + Minim minim; + + @Mock + HashMap SFX_MAP; + + @Mock + HashMap BGM_MAP; + + @Mock + AudioPlayer player; + + @Mock + AudioSample sample; + + @Mock + SideScroller sideScroller; + + @Test + void onAssignAppletShouldPopulateSFXMap() { + doReturn(minim).when(audio).createMinim(sideScroller); + when(minim.loadSample(any())).thenReturn(sample); + + audio.assignApplet(sideScroller); + + verify(SFX_MAP, atLeastOnce()).put(any(), any()); + } + + @Test + void onAssignAppletShouldPopulateBGMMap() { + doReturn(minim).when(audio).createMinim(sideScroller); + when(minim.loadFile(any())).thenReturn(player); + + audio.assignApplet(sideScroller); + + verify(BGM_MAP, atLeastOnce()).put(any(), any()); + } + + @Test + void onAssignAppletShouldNotPopulateSFXMap() { + try (MockedConstruction minim = mockConstruction(Minim.class)) { + try (MockedStatic sfx = mockStatic(SFX.class)) { + sfx.when(() -> SFX.values()).thenReturn(new SFX[0]); + + audio.assignApplet(sideScroller); + + verify(SFX_MAP, never()).put(any(), any()); + } + } + } + + @Test + void onAssignAppletShouldNotPopulateBGMMap() { + try (MockedConstruction minim = mockConstruction(Minim.class)) { + try (MockedStatic bgm = mockStatic(BGM.class)) { + bgm.when(() -> BGM.values()).thenReturn(new BGM[0]); + + audio.assignApplet(sideScroller); + + verify(BGM_MAP, never()).put(any(), any()); + } + } + } + + @Test + void onPlayKnownSFXShouldPlay() { + when(SFX_MAP.containsKey(any())).thenReturn(true); + when(SFX_MAP.get(any())).thenReturn(sample); + + audio.play(SFX.ATTACK); + + verify(sample).trigger(); + } + + @Test + void onPlayUnknownSFXShouldNotPlay() { + when(SFX_MAP.containsKey(any())).thenReturn(false); + + audio.play(SFX.ATTACK); + + verify(SFX_MAP, never()).get(any()); + } + + @Test + void onPlayKnownSFXShouldSetGainAndPlay() { + when(SFX_MAP.containsKey(any())).thenReturn(true); + when(SFX_MAP.get(any())).thenReturn(sample); + + audio.play(SFX.ATTACK, 0f); + + verify(sample).setGain(0f); + verify(sample).trigger(); + } + + @Test + void onPlayUnknownSFXShouldNotSetGainAndPlay() { + when(SFX_MAP.containsKey(any())).thenReturn(false); + + audio.play(SFX.ATTACK, 0f); + + verify(SFX_MAP, never()).get(any()); + } + + @Test + void onPlayNotAlreadyPlayingShouldTryNotPauseAllAndNotPlay() { + AudioPlayer anotherPlayer = mock(AudioPlayer.class); + + when(BGM_MAP.get(any())).thenReturn(player); + when(BGM_MAP.values()).thenReturn(List.of(anotherPlayer)); + when(BGM_MAP.containsKey(any())).thenReturn(false); + + when(player.isPlaying()).thenReturn(false); + when(anotherPlayer.isPlaying()).thenReturn(false); + + audio.play(BGM.TEST0); + + verify(player, never()).setGain(0f); + verify(player, never()).loop(); + } + + @Test + void onPlayNotAlreadyPlayingShouldNotPauseAllAndNotPlay() { + when(BGM_MAP.get(any())).thenReturn(player); + when(BGM_MAP.values()).thenReturn(List.of()); + when(BGM_MAP.containsKey(any())).thenReturn(false); + + when(player.isPlaying()).thenReturn(false); + + audio.play(BGM.TEST0); + + verify(player, never()).setGain(0f); + verify(player, never()).loop(); + } + + @Test + void onPlayNotAlreadyPlayingShouldPauseAllAndPlay() { + AudioPlayer anotherPlayer = mock(AudioPlayer.class); + + when(BGM_MAP.get(any())).thenReturn(player); + when(BGM_MAP.values()).thenReturn(List.of(anotherPlayer)); + when(BGM_MAP.containsKey(any())).thenReturn(true); + + when(player.isPlaying()).thenReturn(false); + when(anotherPlayer.isPlaying()).thenReturn(true); + + audio.play(BGM.TEST0); + + verify(anotherPlayer, atLeastOnce()).pause(); + verify(anotherPlayer, atLeastOnce()).rewind(); + + verify(player).setGain(0f); + verify(player).loop(); + } + + @Test + void onPlayAlreadyPlayingShouldDoNothing() { + when(BGM_MAP.get(any())).thenReturn(player); + when(player.isPlaying()).thenReturn(true); + + audio.play(BGM.TEST0); + + verify(BGM_MAP, never()).values(); + } + + @Test + void onPlayKnownSoundShouldPlay() { + BGM sound = BGM.TEST0; + + when(BGM_MAP.containsKey(sound)).thenReturn(true); + when(BGM_MAP.get(sound)).thenReturn(player); + + audio.play(sound, 0f); + + verify(player, atLeastOnce()).setGain(0f); + } + + @Test + void onPlayUnknownSoundShouldNotPlay() { + BGM sound = BGM.TEST0; + + when(BGM_MAP.containsKey(sound)).thenReturn(false); + + audio.play(sound, 0f); + + verify(BGM_MAP, never()).get(sound); + } + + @Test + void onSetGainBGMShouldSetGain() { + doNothing().when(player).setGain(0f); + + when(BGM_MAP.values()).thenReturn(List.of(player)); + + audio.setGainBGM(0f); + + verify(player).setGain(0f); + } + + @Test + void onSetGainSFXShouldSetGain() { + doNothing().when(sample).setGain(0f); + + when(SFX_MAP.values()).thenReturn(List.of(sample)); + + audio.setGainSFX(0f); + + verify(sample).setGain(0f); + } + + @Test + void onMuteShouldNotPlay() { + doNothing().when(sample).mute(); + doNothing().when(player).mute(); + + when(SFX_MAP.values()).thenReturn(List.of(sample)); + when(BGM_MAP.values()).thenReturn(List.of(player)); + + audio.mute(); + + verify(sample).mute(); + verify(player).mute(); + } + + @Test + void onUnMuteShouldPlay() { + doNothing().when(sample).unmute(); + doNothing().when(player).unmute(); + + when(SFX_MAP.values()).thenReturn(List.of(sample)); + when(BGM_MAP.values()).thenReturn(List.of(player)); + + audio.unMute(); + + verify(sample).unmute(); + verify(player).unmute(); + } + + @Test + void onExitMinimShouldStop() { + doNothing().when(minim).stop(); + + audio.exit(); + + verify(minim).stop(); + } + +} + From 692fb85403651081a207e366eef1b0812bb85657 Mon Sep 17 00:00:00 2001 From: "Danilo M." Date: Mon, 2 Dec 2024 15:48:51 +0100 Subject: [PATCH 8/8] Update maven-build-exe.yml --- .github/workflows/maven-build-exe.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/maven-build-exe.yml b/.github/workflows/maven-build-exe.yml index 57cd9584..2f32f0d0 100644 --- a/.github/workflows/maven-build-exe.yml +++ b/.github/workflows/maven-build-exe.yml @@ -24,7 +24,7 @@ jobs: cache: maven - name: Build with Maven run: mvn -B -Pexe package --file pom.xml - - uses: actions/upload-artifact@v2 + - uses: actions/upload-artifact@v4 with: name: Project16x16.exe path: target/*.exe