diff --git a/pom.xml b/pom.xml index 18006fdd52d6f9d33b1091183cfcd2d8f36050de..820b65c19ff9f448b5246a190e6416443d8b05af 100644 --- a/pom.xml +++ b/pom.xml @@ -3,10 +3,10 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>cz.vsb.fei.java2</groupId> - <artifactId>java2-lab06-v1</artifactId> + <artifactId>java2-lab06-v2</artifactId> <version>0.0.1-SNAPHOST</version> - <name>java2-lab06-v1</name> + <name>java2-lab06-v2</name> <packaging>jar</packaging> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> diff --git a/src/main/java/lab/data/Difficult.java b/src/main/java/lab/data/Difficult.java deleted file mode 100644 index e49d76b1e3fa559ba1eb366ee9091c5eecd1fdaf..0000000000000000000000000000000000000000 --- a/src/main/java/lab/data/Difficult.java +++ /dev/null @@ -1,2 +0,0 @@ -package lab.data; - diff --git a/src/main/java/lab/data/FirstPersonShooter.java b/src/main/java/lab/data/FirstPersonShooter.java index 62b7b3b4c9d1b2f11af405da5e7c8f68a9f1f81b..a1602bd97fb36e4dbbb5d6aa87597a0c0a8d58b5 100644 --- a/src/main/java/lab/data/FirstPersonShooter.java +++ b/src/main/java/lab/data/FirstPersonShooter.java @@ -2,24 +2,20 @@ package lab.data; import java.util.List; -import jakarta.persistence.Entity; import lab.Tools; -import lab.data.PlatformGame.PlatformType; -import lombok.AllArgsConstructor; import lombok.Getter; -import lombok.NoArgsConstructor; import lombok.Setter; import lombok.ToString; @Getter @Setter @ToString(callSuper = true) -public class FirstPersonShooter extends Game{ +public class FirstPersonShooter extends Game { private FPSType fpsType; private int playersCount; - enum FPSType{ + enum FPSType { DEATHMATCH, TEAM_DEATHMATCH, KING_OF_THE_HILL, ASSAULT, BATTLE_ROYALE, INFECTION; } @@ -30,7 +26,8 @@ public class FirstPersonShooter extends Game{ } public static FirstPersonShooter generate() { - return new FirstPersonShooter(null, Tools.randomGameName(), null, Tools.random(FPSType.values()), Tools.random(new Integer[]{1,2,5,10,20,50,100})); + return new FirstPersonShooter(null, Tools.randomGameName(), null, Tools.random(FPSType.values()), + Tools.random(new Integer[] { 1, 2, 5, 10, 20, 50, 100 })); } - + } diff --git a/src/main/java/lab/data/Game.java b/src/main/java/lab/data/Game.java index 4bbec16f7b7ceffe3acbb59fa0da30a7a50428b6..5035ff9f80bf751bfc37c502e852603edd9731d0 100644 --- a/src/main/java/lab/data/Game.java +++ b/src/main/java/lab/data/Game.java @@ -12,7 +12,7 @@ import lombok.ToString; @Setter @ToString @Builder(toBuilder = true) -public class Game implements MyEntity{ +public class Game implements MyEntity { private Long id; private String name; diff --git a/src/main/java/lab/data/PlatformGame.java b/src/main/java/lab/data/PlatformGame.java index 93d146533ce7ebe995144d45f26be109dbf4947a..3508998763bce1c84e9b7afe6802c35d418df6c4 100644 --- a/src/main/java/lab/data/PlatformGame.java +++ b/src/main/java/lab/data/PlatformGame.java @@ -10,23 +10,24 @@ import lombok.ToString; @Getter @Setter @ToString(callSuper = true) -public class PlatformGame extends Game{ +public class PlatformGame extends Game { private boolean retro; private PlatformType platformType; - - enum PlatformType{ + + enum PlatformType { SINGLE_SCREEN, SCROLLING; } - - public PlatformGame(Long id, String name, List<Score> scores, boolean retro, PlatformType platformType) { + + public PlatformGame(Long id, String name, List<Score> scores, boolean retro, PlatformType platformType) { super(id, name, scores); this.retro = retro; this.platformType = platformType; } public static PlatformGame generate() { - return new PlatformGame(null, Tools.randomGameName(), null, Tools.RANDOM.nextBoolean(), Tools.random(PlatformType.values())); + return new PlatformGame(null, Tools.randomGameName(), null, Tools.RANDOM.nextBoolean(), + Tools.random(PlatformType.values())); } } diff --git a/src/main/java/lab/data/Player.java b/src/main/java/lab/data/Player.java index faedbd39736fa009a78260282064886d3c1a764b..1c0bbd3b07eef69a66b3b9d29273ae082034af45 100644 --- a/src/main/java/lab/data/Player.java +++ b/src/main/java/lab/data/Player.java @@ -12,9 +12,8 @@ import lombok.ToString; @Setter @ToString @Builder(toBuilder = true) -public class Player implements MyEntity{ +public class Player implements MyEntity { - private Long id; private String firstName; private String lastName; diff --git a/src/main/java/lab/data/Score.java b/src/main/java/lab/data/Score.java index 314677ec506d27c384a56c98c36045a8674fc4d7..6fc69daf834577aae8a6ec72addb10af36bc6cba 100644 --- a/src/main/java/lab/data/Score.java +++ b/src/main/java/lab/data/Score.java @@ -14,21 +14,21 @@ import lombok.ToString; @Setter @ToString @Builder(toBuilder = true) -public class Score implements MyEntity{ +public class Score implements MyEntity { private Long id; private int points; @Enumerated(EnumType.STRING) - private Difficult level; + private Difficult difficult; private Player player; private Game game; - - + public static Score generate(List<Player> players, List<Game> games) { - return new Score(null, Tools.RANDOM.nextInt(100, 2000), Tools.random(Difficult.values()), Tools.randomElementFrom(players), Tools.randomElementFrom(games)); + return new Score(null, Tools.RANDOM.nextInt(100, 2000), Tools.random(Difficult.values()), + Tools.randomElementFrom(players), Tools.randomElementFrom(games)); } - + public enum Difficult { - EASY, MEDIUM, HARD; + EASY, MEDIUM, HARD; } } diff --git a/src/main/java/lab/storage/JpaConnector.java b/src/main/java/lab/storage/JpaConnector.java index 2115152d0d1394c3f7ba8d662761a902e5cd1e6a..86d139b6700506d38ce5e2060d2307301b2262bf 100644 --- a/src/main/java/lab/storage/JpaConnector.java +++ b/src/main/java/lab/storage/JpaConnector.java @@ -20,17 +20,17 @@ public class JpaConnector { } public<T extends MyEntity> List<T> getAll(Class<T> clazz) { + //TODO return null; } - public void init() { - } - public<T extends MyEntity> T save(T score) { + //TODO return null; } public void delete(List<? extends MyEntity> e) { + //TODO } public void stop() { @@ -39,7 +39,6 @@ public class JpaConnector { } public EntityManager getEntityManager() { - //return entity manager. Type Object is there because of compilation of empty task assignment return em; } @@ -56,6 +55,7 @@ public class JpaConnector { public List<Score> findBy(String partialName, Score.Difficult difficult){ + //TODO return null; } diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java index 60e43a3c1627a4b8c278839704d87e5bcd976798..fbf7190e9eab03aa41ce0ea60adb2e0c01ac86e6 100644 --- a/src/main/java/module-info.java +++ b/src/main/java/module-info.java @@ -5,8 +5,8 @@ module cz.vsb.fei.java2.lab06_module { requires jakarta.persistence; requires com.h2database; requires org.hibernate.orm.core; - requires jakarta.annotation; - + requires static jakarta.annotation; + opens lab.data; } \ No newline at end of file diff --git a/src/test/java/jez04/structure/test/ClassStructureTest.java b/src/test/java/jez04/structure/test/ClassStructureTest.java index b850b1e322800e90cb08cb103b3bf1432cd3000b..cd88aadf97177a474e7057e4662e04d0769a0cf7 100644 --- a/src/test/java/jez04/structure/test/ClassStructureTest.java +++ b/src/test/java/jez04/structure/test/ClassStructureTest.java @@ -1,23 +1,91 @@ package jez04.structure.test; import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.jupiter.api.Assertions.assertTrue; import java.net.URISyntaxException; import java.nio.file.Path; import java.nio.file.Paths; +import java.util.Collections; +import java.util.List; +import java.util.Objects; import org.hamcrest.Matchers; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.MethodOrderer.OrderAnnotation; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Order; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; import cz.vsb.fei.kelvin.unittest.ProjectContains; import cz.vsb.fei.kelvin.unittest.StructureHelper; import cz.vsb.fei.kelvin.unittest.TextFileContains; import cz.vsb.fei.kelvin.unittest.XmlFileContains; +import lab.data.FirstPersonShooter; +import lab.data.Game; +import lab.data.MyEntity; +import lab.data.PlatformGame; +import lab.data.Player; +import lab.data.Score; +import lab.data.Score.Difficult; +import lab.storage.JpaConnector; class ClassStructureTest { StructureHelper helper = StructureHelper.getInstance(ClassStructureTest.class); + // @formatting:off + @ParameterizedTest + @CsvSource({ + "Score.java,@Entity", + "Score.java,@NoArgsConstructor", + "Score.java,@EqualsAndHashCode", + "Score.java,@EqualsAndHashCode\\(onlyExplicitlyIncluded\\s*=\\s*true\\)", + "Score.java,@EqualsAndHashCode\\.Include", + "Score.java,@ManyToOne", + "Game.java,@Entity", + "Game.java,@NoArgsConstructor", + "Game.java,@EqualsAndHashCode", + "Game.java,@EqualsAndHashCode\\(onlyExplicitlyIncluded\\s*=\\s*true\\)", + "Game.java,@EqualsAndHashCode\\.Include", + "Game.java,@OneToMany\\(mappedBy", + "Game.java,@ToString\\.Exclude", + "Player.java,@Entity", + "Player.java,@NoArgsConstructor", + "Player.java,@EqualsAndHashCode", + "Player.java,@EqualsAndHashCode\\(onlyExplicitlyIncluded\\s*=\\s*true\\)", + "Player.java,@EqualsAndHashCode\\.Include", + "Player.java,@OneToMany\\(mappedBy", + "Player.java,@ToString\\.Exclude", + "FirstPersonShooter.java,@Entity", + "FirstPersonShooter.java,@NoArgsConstructor", + "PlatformGame.java,@Entity", + "PlatformGame.java,@NoArgsConstructor", + }) + // @formatting:on + void anotaceTest(String file, String annotation) throws URISyntaxException { + assertThat(TextFileContains.getProjectRoot(getClass()), + new TextFileContains(file, annotation)); + } + + // @formatting:off + @ParameterizedTest + @CsvSource({ + "Game.java,Score_.GAME", + "Player.java, Score_.PLAYER", + }) + // @formatting:on + void mappedByTest(String file, String annotation) throws URISyntaxException { + assertThat(TextFileContains.getProjectRoot(getClass()), + new TextFileContains(file, annotation)); + } + @Test void jakartaAndHibernateAsDependencyTest() throws URISyntaxException { assertThat(TextFileContains.getProjectRoot(getClass()), new XmlFileContains("pom.xml", @@ -44,10 +112,273 @@ class ClassStructureTest { Matchers.endsWith(Paths.get("resources", "META-INF", "persistence.xml").toString())); } - @Test - void useEnumeratedTest() throws URISyntaxException { - assertThat(TextFileContains.getProjectRoot(getClass()), - new TextFileContains("Score.java", "@Enumerated\\(\\s*EnumType.STRING\\s*\\)")); + @TestMethodOrder(OrderAnnotation.class) + @Nested + class JpaConnectorTests { + + private Player player; + private Game game; + private PlatformGame platformGame; + private FirstPersonShooter firstPersonShooter; + private static JpaConnector connector; + + @BeforeAll + static void initAll() { + try { + connector = new JpaConnector(); + } catch (Exception e) { + e.printStackTrace(); + } + } + @BeforeEach + void init() { + player = Player.generate(); + game = Game.generate(); + platformGame = PlatformGame.generate(); + firstPersonShooter = FirstPersonShooter.generate(); + connector.getEntityManager().clear(); + if(connector.getEntityManager().getTransaction().isActive()) { + connector.getEntityManager().getTransaction().rollback(); + } + } + + @AfterAll + static void cleanUpAll() { + connector.stop(); + } + + boolean same(MyEntity e1, MyEntity e2) { + if(e1 instanceof Player p1 && e2 instanceof Player p2) { + return same(p1, p2); + } else if(e1 instanceof PlatformGame pg1 && e2 instanceof PlatformGame pg2) { + return same(pg1, pg2); + } else if(e1 instanceof FirstPersonShooter fps1 && e2 instanceof FirstPersonShooter fps2) { + return same(fps1, fps2); + } else if(e1 instanceof Game g1 && e2 instanceof Game g2) { + return same(g1, g2); + } else if(e1 instanceof Score s1 && e2 instanceof Score s2) { + return same(s1, s2); + } + return false; + } + + private boolean same(Score s1, Score s2) { + // @formatting:off + return s1.getDifficult() == s2.getDifficult() + && s1.getPoints() == s2.getPoints() + && Objects.equals(s1.getId(), s2.getId()) + && Objects.equals(s1.getPlayer().getId(), s2.getPlayer().getId()) + && Objects.equals(s1.getGame().getId(), s2.getGame().getId()); + // @formatting:on + } + + private boolean same(Player p1, Player p2) { + // @formatting:off + return Objects.equals(p1.getId(), p2.getId()) + && Objects.equals(p1.getFirstName(), p2.getFirstName()) + && Objects.equals(p1.getLastName(), p2.getLastName()) + && Objects.equals(p1.getNick(), p2.getNick()) + && same(p1.getScores(), p2.getScores()); + // @formatting:on + } + private boolean same(Game g1, Game g2) { + // @formatting:off + return Objects.equals(g1.getId(), g2.getId()) + && Objects.equals(g1.getName(), g2.getName()) + && same(g1.getScores(), g2.getScores()); + // @formatting:on + } + private boolean same(PlatformGame g1, PlatformGame g2) { + // @formatting:off + return same((Game)g1, (Game)g2) + && Objects.equals(g1.getPlatformType(), g2.getPlatformType()) + && g1.isRetro() == g2.isRetro(); + // @formatting:on + } + private boolean same(FirstPersonShooter g1, FirstPersonShooter g2) { + // @formatting:off + return same((Game)g1, (Game)g2) + && Objects.equals(g1.getFpsType(), g2.getFpsType()) + && g1.getPlayersCount() == g2.getPlayersCount(); + // @formatting:on + } + private boolean same(List<?> l1, List<?> l2) { + if(l1 == null) { + l1 = Collections.emptyList(); + } + if(l2 == null) { + l2 = Collections.emptyList(); + } + return Objects.equals(l1, l2); + } + + private void saveAndReadSame(MyEntity original) { + MyEntity result = connector.save(original); + assertThat(result.getId(), Matchers.notNullValue()); + connector.getEntityManager().clear(); + MyEntity saved = connector.getEntityManager().find(result.getClass(), result.getId()); + assertTrue(same(result, saved), "Saved and readed entities are not same."); + } + + @Test + @Order(100) + void jpaPlayerInsertTest() { + saveAndReadSame(player); + } + + @Test + @Order(120) + void jpaGameInsertTest() { + saveAndReadSame(game); + } + + @Test + @Order(130) + void jpaPlatformGameInsertTest() { + saveAndReadSame(platformGame); + } + + @Test + @Order(140) + void jpaFirstPersonShooterInsertTest() { + saveAndReadSame(firstPersonShooter); + } + + @Test + @Order(150) + void jpaScoreInsertTest() { + saveAndReadSame(Score.generate(connector.getAll(Player.class), connector.getAll(Game.class))); + } + + @Test + @Order(200) + void jpaPlayerReadTest() { + List<Player> savedEntities = connector.getAll(Player.class).stream().toList(); + assertThat(savedEntities, Matchers.not(Matchers.hasSize(0))); + } + + @Test + @Order(210) + void jpaGameReadTest() { + List<Game> savedEntities = connector.getAll(Game.class).stream().toList(); + assertThat(savedEntities, Matchers.not(Matchers.hasSize(0))); + } + @Test + @Order(220) + void jpaPlatformGameReadTest() { + List<PlatformGame> savedEntities = connector.getAll(PlatformGame.class).stream().toList(); + assertThat(savedEntities, Matchers.not(Matchers.hasSize(0))); + } + @Test + @Order(230) + void jpaFirstPersonShooterReadTest() { + List<FirstPersonShooter> savedEntities = connector.getAll(FirstPersonShooter.class).stream().toList(); + assertThat(savedEntities, Matchers.not(Matchers.hasSize(0))); + } + @Test + @Order(240) + void jpaScoreReadTest() { + List<Score> savedEntities = connector.getAll(Score.class).stream().toList(); + assertThat(savedEntities, Matchers.not(Matchers.hasSize(0))); + } + + @Test + @Order(250) + void jpaGameScoresContainScoreTest() { + List<Score> savedEntities = connector.getAll(Score.class).stream().toList(); + for (Score score : savedEntities) { + assertThat(score.getGame().getScores(), Matchers.containsInRelativeOrder(score)); + } + } + @Test + @Order(260) + void jpaPlayerScoresContainScoreTest() { + List<Score> savedEntities = connector.getAll(Score.class).stream().toList(); + for (Score score : savedEntities) { + assertThat(score.getPlayer().getScores(), Matchers.containsInRelativeOrder(score)); + } + } + @Test + @Order(270) + void jpaScoreToStringTest() { + List<Score> savedEntities = connector.getAll(Score.class); + for (Score score : savedEntities) { + assertThat(score.toString(), Matchers.notNullValue()); + } + } + @Test + @Order(280) + void jpaPlayerToStringTest() { + List<Player> savedEntities = connector.getAll(Player.class); + for (Player p : savedEntities) { + assertThat(p.toString(), Matchers.notNullValue()); + } + } + + private void deleteAllAndAssert(Class<? extends MyEntity> clazz) { + List<? extends MyEntity> savedEntities = connector.getAll(clazz); + assertThat(savedEntities, Matchers.not(Matchers.hasSize(0))); + connector.delete(savedEntities); + List<? extends MyEntity> modifiedEntities = connector.getAll(clazz); + assertThat(modifiedEntities, Matchers.hasSize(0)); + } + + @Test + @Order(300) + void jpaScoreDeleteTest() { + deleteAllAndAssert(Score.class); + } + @Test + @Order(310) + void jpaPlayerDeleteTest() { + deleteAllAndAssert(Player.class); + } + + @Test + @Order(320) + void jpaGameDeleteTest() { + deleteAllAndAssert(Game.class); + } + + @Test + @Order(400) + void jpaFindByNullNUllTest() { + connector.save(player); + game.setName("aa-test-bb"); + connector.save(game); + Game g2 = Game.generate(); + g2.setName("aa--bb"); + connector.save(g2); + connector.save(Score.builder().points(100).difficult(Difficult.EASY).player(player).game(game).build()); + connector.save(Score.builder().points(100).difficult(Difficult.HARD).player(player).game(game).build()); + connector.save(Score.builder().points(100).difficult(Difficult.EASY).player(player).game(g2).build()); + connector.save(Score.builder().points(100).difficult(Difficult.HARD).player(player).game(g2).build()); + assertThat(connector.findBy(null, null), Matchers.hasSize(4)); + } + + @Test + @Order(410) + void jpaFindByDiffTest() { + assertThat(connector.findBy(null, Difficult.HARD), Matchers.hasSize(2)); + } + + @Test + @Order(420) + void jpaFindByNameTest() { + assertThat(connector.findBy("test", null), Matchers.hasSize(2)); + } + + @Test + @Order(430) + void jpaFindByNameAndDiffTest() { + assertThat(connector.findBy("test", Difficult.EASY), Matchers.hasSize(1)); + } + + @Test + @Order(440) + void jpaFindByNameAndDiff2Test() { + assertThat(connector.findBy("--", Difficult.HARD), Matchers.hasSize(1)); + } } }