Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
No results found
Show changes
Commits on Source (2)
Showing
with 368 additions and 188 deletions
......@@ -3,9 +3,9 @@
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-lab09-v2</artifactId>
<artifactId>java2-lab10-v2</artifactId>
<version>0.0.1-SNAPHOST</version>
<name>java2-lab09-v2</name>
<name>java2-lab10-v2</name>
<packaging>jar</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
......
JavaJester;274;HARD
DataDetective;296;HARD
AppArchitect;88;MEDIUM
DataDynamo;186;EASY
AppArchitect;88;MEDIUM
CodeConductor;273;MEDIUM
package lab.data;
public enum Level {
EASY, MEDIUM, HARD;
EASY, MEDIUM, HARD;
public static Level from(String s) {
for (Level l : values()) {
if (l.toString().equals(s)) {
return l;
}
}
return null;
}
}
package lab.game;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Comparator;
......@@ -14,6 +21,8 @@ import lombok.extern.log4j.Log4j2;
@Log4j2
public class Level {
private Object entitiesLock = new Object();
private boolean viewMode;
private double width;
......@@ -51,11 +60,67 @@ public class Level {
}
public void startServer() {
// TODO:
new Thread(() -> {
try (ServerSocket listenSocket = new ServerSocket(4600)) {
while (!Thread.currentThread().isInterrupted()) {
try {
Socket client = listenSocket.accept();
new Thread(() -> handleViewer(client), "Viewer handler").start();
} catch (IOException e) {
e.printStackTrace();
}
}
} catch (IOException e) {
e.printStackTrace();
}
}).start();
}
public void handleViewer(Socket client) {
try (OutputStream outputStream = client.getOutputStream();
ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream)) {
while (!Thread.currentThread().isInterrupted()) {
synchronized (entitiesLock) {
objectOutputStream.reset();
synchronized (entitiesLock) {
objectOutputStream.writeObject(entities);
}
objectOutputStream.flush();
}
sleepForWhile();
}
} catch (IOException e) {
e.printStackTrace();
}
}
private void sleepForWhile() {
try {
Thread.sleep(20);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
public void connectToServer() {
// TODO:
new Thread(() -> {
try (Socket socketToServer = new Socket("localhost", 4600);
InputStream inputStream = socketToServer.getInputStream();
ObjectInputStream objectInputStream = new ObjectInputStream(inputStream)) {
while (!Thread.currentThread().isInterrupted()) {
Object o = objectInputStream.readObject();
if (o instanceof List l) {
synchronized (entitiesLock) {
entities = l;
}
}
}
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}).start();
}
record MonsterDeadLog(LocalDateTime time, MyPoint position) {
......@@ -70,8 +135,10 @@ public class Level {
public void draw(GraphicsContext gc) {
gc.setFill(Color.WHITE);
gc.clearRect(0, 0, width, height);
for (DrawableSimulable entity : entities) {
entity.draw(gc);
synchronized (entitiesLock) {
for (DrawableSimulable entity : entities) {
entity.draw(gc);
}
}
}
......@@ -79,15 +146,17 @@ public class Level {
if (viewMode) {
return;
}
for (DrawableSimulable entity : entities) {
entity.simulate(delay);
synchronized (entitiesLock) {
for (DrawableSimulable entity : entities) {
entity.simulate(delay);
}
detectCollisions();
entities.removeAll(entitiesToRemove);
entities.addAll(entitiesToAdd);
entitiesToAdd.clear();
entitiesToRemove.clear();
entities.sort(Comparator.comparing(DrawableSimulable::getZIndex));
}
detectCollisions();
entities.removeAll(entitiesToRemove);
entities.addAll(entitiesToAdd);
entitiesToAdd.clear();
entitiesToRemove.clear();
entities.sort(Comparator.comparing(DrawableSimulable::getZIndex));
}
private void detectCollisions() {
......
package lab.game;
import java.io.Serial;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
......@@ -14,13 +15,16 @@ import lab.Config;
public class Monster extends WorldEntity implements Collisionable {
@Serial
private static final long serialVersionUID = 4227585479714088964L;
private static Logger log = LogManager.getLogger(Monster.class);
private static final Random RANDOM = new Random();
private static Image image;
private MyPoint speed;
private List<DeadListener> deadListeners = new ArrayList<>();
private transient List<DeadListener> deadListeners = new ArrayList<>();
public Monster(Level level) {
super(level, new MyPoint(0, 0), 100);
......
package lab.game;
import java.io.Serial;
import java.io.Serializable;
import lombok.AllArgsConstructor;
......@@ -7,7 +8,10 @@ import lombok.Getter;
@AllArgsConstructor
@Getter
public class MyDimension {
public class MyDimension implements Serializable {
@Serial
private static final long serialVersionUID = -4053578370437363200L;
private double width;
......
package lab.game;
public class MyPoint {
import java.io.Serial;
import java.io.Serializable;
public class MyPoint implements Serializable {
@Serial
private static final long serialVersionUID = 5131948780897974323L;
public double x;
public double y;
......
package lab.game;
import java.io.Serial;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.image.Image;
public class NicerObstacle extends WorldEntity {
@Serial
private static final long serialVersionUID = -6623353377339746275L;
private static Image image;
public NicerObstacle(Level level, MyPoint position) {
......@@ -12,18 +17,18 @@ public class NicerObstacle extends WorldEntity {
}
private static Image getImage() {
if (image == null) {
if(image == null){
image = new Image(NicerObstacle.class.getResourceAsStream("spike.gif"));
}
return image;
}
public void drawInternal(GraphicsContext gc) {
gc.drawImage(getImage(), position.getX(), position.getY());
}
public void simulate(double delay) {
/* nothing to do */
/*nothing to do*/
}
}
package lab.game;
import java.io.Serial;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.paint.Color;
import lab.Config;
public class Obstacle extends WorldEntity {
@Serial
private static final long serialVersionUID = 3430702588557969248L;
private MyDimension size;
public Obstacle(Level level) {
......@@ -27,7 +31,7 @@ public class Obstacle extends WorldEntity {
}
public void simulate(double delay) {
/* nothing to do */
/*nothing to do*/
}
}
package lab.game;
import java.io.Serial;
import java.util.Random;
import javafx.geometry.Rectangle2D;
......@@ -12,6 +13,9 @@ import lab.Config;
public class Player extends WorldEntity implements Collisionable {
@Serial
private static final long serialVersionUID = -4487836387706082936L;
private static final Random RANDOM = new Random();
private MyPoint speed;
......
package lab.game;
import java.io.Serial;
import java.io.Serializable;
import javafx.scene.canvas.GraphicsContext;
public abstract class WorldEntity implements DrawableSimulable {
public abstract class WorldEntity implements DrawableSimulable, Serializable {
protected final Level level;
@Serial
private static final long serialVersionUID = 2626363250832813659L;
protected transient final Level level;
protected MyPoint position;
private int zIndex;
......@@ -36,5 +42,5 @@ public abstract class WorldEntity implements DrawableSimulable {
public int getZIndex() {
return zIndex;
}
}
......@@ -10,9 +10,12 @@ import javafx.scene.Scene;
import javafx.scene.control.Alert;
import javafx.scene.control.Alert.AlertType;
import javafx.scene.control.ButtonType;
import javafx.stage.Modality;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
import javafx.stage.WindowEvent;
import lab.Config;
import lab.data.Score;
import lab.storage.FileStorage;
import lombok.extern.log4j.Log4j2;
......@@ -27,6 +30,7 @@ import lombok.extern.log4j.Log4j2;
public class App extends Application {
private GameController gameController;
private MainScreenController menuController;
private boolean viewMode;
......@@ -71,6 +75,7 @@ public class App extends Application {
// Construct a main window with a canvas.
FXMLLoader menuLoader = new FXMLLoader(getClass().getResource("/lab/gui/mainScreen.fxml"));
Parent root = menuLoader.load();
menuController = menuLoader.getController();
MainScreenController menuController = menuLoader.getController();
menuController.setApp(this);
Scene scene = new Scene(root);
......@@ -79,6 +84,25 @@ public class App extends Application {
primaryStage.setScene(scene);
}
public Stage createDialogStage(Score score) throws IOException {
Stage dialog = new Stage();
dialog.initStyle(StageStyle.UTILITY);
FXMLLoader editLoader = new FXMLLoader(getClass().getResource("/lab/gui/edit.fxml"));
Parent root = editLoader.load();
EditController editController = editLoader.getController();
editController.setStage(dialog);
editController.setObjectToEdit(score);
editController.setMainScreenController(menuController);
Scene scene = new Scene(root);
URL cssUrl = getClass().getResource("application.css");
scene.getStylesheets().add(cssUrl.toString());
dialog.setScene(scene);
dialog.initModality(Modality.APPLICATION_MODAL);
dialog.initOwner(primaryStage);
return dialog;
}
@Override
public void stop() throws Exception {
if(gameController != null) {
......
package lab.gui;
import java.util.HashMap;
import java.util.Map;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.geometry.HPos;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.GridPane;
import javafx.stage.Stage;
import lab.data.Score;
import lombok.Setter;
/**
*
*/
public class EditController {
private static Logger log = LogManager.getLogger(EditController.class);
@FXML
private Button btnOk;
@FXML
private Button btnCancel;
@FXML
private Label txtTitle;
@FXML
private GridPane content;
private Object data;
private App app;
private Map<String, TextField> nameToTextField = new HashMap<>();
@Setter
private Stage stage;
@Setter
private MainScreenController mainScreenController;
@FXML
void btnOkAction(ActionEvent event) {
//TODO: add code to read values from text fields
mainScreenController.updateData((Score)data);
stage.hide();
}
@FXML
void btnCancelAction(ActionEvent event) {
stage.hide();
}
@FXML
void initialize() {
log.info("Screen initialized.");
}
public void setObjectToEdit(Object data) {
this.data = data;
log.info("data set {}", data);
content.getChildren().clear();
//TODO: code to detect properties and add rows to dialog
}
private void addDialogRow(int rowNumber, String name, String descriptionName, String stringValue,
boolean editable) {
Label label = new Label(descriptionName);
TextField textField = new TextField(stringValue);
textField.setEditable(editable);
nameToTextField.put(name, textField);
content.addRow(rowNumber, label, textField);
GridPane.setHalignment(label, HPos.RIGHT);
}
}
......@@ -13,11 +13,13 @@ import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.SelectionMode;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableRow;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.scene.control.ToggleButton;
import javafx.scene.control.ToggleGroup;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.input.MouseButton;
import lab.Config;
import lab.data.Level;
import lab.data.Score;
......@@ -110,6 +112,11 @@ public class MainScreenController {
this.scores.getItems().addAll(scores);
}
public void updateData(Score score) {
Config.getInstance().getScoreStorageInterface().save(score);
updateScoreTable(Config.getInstance().getScoreStorageInterface().getAll());
}
@FXML
void initialize() {
assert difficult != null : "fx:id=\"difficult\" was not injected: check your FXML file 'mainScreen.fxml'.";
......@@ -123,6 +130,20 @@ public class MainScreenController {
difficultColumn.setCellValueFactory(new PropertyValueFactory<>("level"));
btnDelete.setDisable(true);
scores.setRowFactory(tableView -> {
TableRow<Score> row = new TableRow<>();
row.setOnMouseClicked(event -> {
if (event.getClickCount() >= 2 && event.getButton() == MouseButton.PRIMARY && row.getItem() != null) {
try {
MainScreenController.this.app.createDialogStage(row.getItem()).show();
} catch (IOException e) {
e.printStackTrace();
}
}
});
return row;
});
scores.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
scores.getSelectionModel().getSelectedItems()
.addListener((ListChangeListener.Change<? extends Score> change) ->
......
......@@ -10,6 +10,7 @@ import java.util.Comparator;
import java.util.List;
import java.util.stream.Stream;
import lab.data.Level;
import lab.data.Score;
public class FileStorage implements ScoreStorageInterface {
......@@ -21,7 +22,7 @@ public class FileStorage implements ScoreStorageInterface {
if (Files.exists(Paths.get(SCORE_FILE_NAME))) {
try (Stream<String> lines = Files.lines(Paths.get(SCORE_FILE_NAME))) {
List<Score> result = lines.map(line -> line.split(";"))
.map(parts -> new Score(null, parts[0], Integer.parseInt(parts[1]), null)).toList();
.map(parts -> new Score(null, parts[0], Integer.parseInt(parts[1]), Level.from(parts[2]))).toList();
return new ArrayList<>(result);
} catch (IOException e) {
e.printStackTrace();
......@@ -34,7 +35,7 @@ public class FileStorage implements ScoreStorageInterface {
public List<Score> getFirstTen() {
List<Score> all = getAll();
Collections.sort(all, Comparator.comparing(Score::getPoints).reversed());
return all.subList(0, 10);
return all.subList(0, Math.min(all.size(), 10));
}
@Override
......@@ -51,9 +52,9 @@ public class FileStorage implements ScoreStorageInterface {
}
private void storeAll(List<Score> all) {
List<String> lines = all.stream().map(s -> String.format("%s;%d", s.getName(), s.getPoints())).toList();
List<String> lines = all.stream().map(s -> String.format("%s;%d;%s", s.getName(), s.getPoints(), s.getLevel())).toList();
try {
Files.write(Paths.get(SCORE_FILE_NAME), lines, StandardOpenOption.TRUNCATE_EXISTING);
Files.write(Paths.get(SCORE_FILE_NAME), lines, StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.CREATE);
} catch (IOException e) {
e.printStackTrace();
}
......
......@@ -8,6 +8,7 @@ module cz.vsb.fei.java2.lab03_module {
requires com.h2database;
requires jakarta.persistence;
requires org.hibernate.orm.core;
requires java.desktop;
opens lab.gui to javafx.fxml;
opens lab.data to javafx.base,org.hibernate.orm.core;
......
......@@ -24,6 +24,22 @@ Label {
-fx-background-size: stretch;
}
#content {
-fx-grid-lines-visible: true;
}
#btnOk {
-fx-background-color: RGBA(0.0,255.0,0.0,0.5);
}
#btnCancel {
-fx-background-color: RGBA(150.0,150.0,0.0,0.5);
}
.actionButton:hover {
-fx-text-fill: white;
}
#playButton {
-fx-background-color: RGBA(255.0,0.0,0.0,0.5);
}
......
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.RowConstraints?>
<?import javafx.scene.text.Font?>
<BorderPane fx:id="menuPanel" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" xmlns="http://javafx.com/javafx/21" xmlns:fx="http://javafx.com/fxml/1" fx:controller="lab.gui.EditController">
<bottom>
<HBox BorderPane.alignment="CENTER">
<children>
<Button fx:id="btnCancel" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#btnCancelAction" styleClass="actionButton" text="Cancle" HBox.hgrow="ALWAYS">
<font>
<Font name="System Bold" size="51.0" />
</font>
</Button>
<Button fx:id="btnOk" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#btnOkAction" styleClass="actionButton" text="Ok" HBox.hgrow="ALWAYS">
<font>
<Font name="System Bold" size="51.0" />
</font>
</Button>
</children>
</HBox>
</bottom>
<center>
<GridPane fx:id="content" BorderPane.alignment="CENTER">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" vgrow="NEVER" />
</rowConstraints>
</GridPane>
</center>
<top>
<Label fx:id="txtTitle" text="Title" BorderPane.alignment="CENTER">
<font>
<Font name="System Bold" size="48.0" />
</font>
</Label>
</top>
</BorderPane>
......@@ -2,176 +2,40 @@ package jez04.structure.test;
import static org.hamcrest.MatcherAssert.assertThat;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.net.URISyntaxException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Objects;
import java.util.regex.Pattern;
import org.hamcrest.Matchers;
import org.junit.jupiter.api.AfterEach;
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.Level;
import lab.data.Score;
import lab.storage.JpaConnector;
class ClassStructureTest {
StructureHelper helper = StructureHelper.getInstance(ClassStructureTest.class);
@Test
void jakartaAndHibernateAsDependencyTest() throws URISyntaxException {
assertThat(TextFileContains.getProjectRoot(getClass()), new XmlFileContains("pom.xml",
"/project/dependencies/dependency/artifactId[text() = 'jakarta.persistence-api']"));
assertThat(TextFileContains.getProjectRoot(getClass()), new XmlFileContains("pom.xml",
"/project/dependencies/dependency/artifactId[text() = 'hibernate-core']"));
// @formatter:off
@ParameterizedTest
@CsvSource({
"Score.java,@MyEdit,4",
"EditController.java,Introspector.getBeanInfo,1",
"EditController.java,BeanInfo,1",
"EditController.java,PropertyDescriptor,1",
"EditController.java,getDeclaredField,1",
"EditController.java,getAnnotation,1",
"EditController.java,\\.readOnly\\(\\),1",
"EditController.java,\\.visible\\(\\),1",
"MyEdit.java,@interface,1",
"MyEdit.java,@Retention,1",
"MyEdit.java,RetentionPolicy\\.RUNTIME,1",
"MyEdit.java,readOnly\\(\\),1",
"MyEdit.java,visible\\(\\),1",
"msg(_.*)?\\.properties,points,2",
})
// @formatter:on
void anotaceTest(String file, String annotation, int count) throws URISyntaxException {
assertThat(TextFileContains.getProjectRoot(getClass()), new TextFileContains(file, annotation).count(count).useRegExpForName(true));
}
@Test
void jakartaInModulInfoTest() throws URISyntaxException {
assertThat(TextFileContains.getProjectRoot(getClass()),
new TextFileContains("module-info.java", "jakarta.persistence;"));
assertThat(TextFileContains.getProjectRoot(getClass()),
new TextFileContains("module-info.java", "opens\\s+lab.data;|opens\\s+lab.data\\s+to\\s+javafx.base,org.hibernate.orm.core;"));
}
@Test
void pesistenceXmlTest() throws URISyntaxException {
ProjectContains projectContains = new ProjectContains("persistence.xml");
assertThat(TextFileContains.getProjectRoot(getClass()), projectContains);
assertThat(projectContains.getFoundFiles(), Matchers.not(Matchers.hasSize(0)));
Path persistenceXml = projectContains.getFoundFiles().getFirst();
assertThat(persistenceXml.toAbsolutePath().toString(),
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 Score template = new Score(null, "Tester", 100, Level.EASY);
private JpaConnector connector;
@BeforeEach
void init() {
connector = new JpaConnector();
}
@AfterEach
void cleanUp() {
connector.stop();
}
boolean same(Score s1, Score s2) {
return s1.getLevel() == s2.getLevel() && s1.getPoints() == s2.getPoints()
&& Objects.equals(s1.getName(), s2.getName());
}
@Test
@Order(100)
void jpaScoreInsertTest() {
Score savedScore = connector.save(template);
assertThat(savedScore.getId(), Matchers.notNullValue());
}
@Test
@Order(200)
void jpaScoreReadTest() {
List<Score> savedScores = connector.getAll().stream().filter(s -> same(s, template)).toList();
assertThat(savedScores, Matchers.not(Matchers.hasSize(0)));
}
@Test
@Order(250)
void jpaReadSortedTest() {
for (int i = 0; i < 20; i++) {
connector.save(template.toBuilder().points(i).build());
}
List<Score> result = connector.getFirstTen();
assertThat(result, Matchers.hasSize(10));
for (int i = 0; i < result.size()-1; i++) {
assertThat(result.get(i).getPoints(), Matchers.greaterThanOrEqualTo(result.get(i+1).getPoints()));
}
}
@Test
@Order(300)
void jpaScoreModifyTest() {
List<Score> savedScores = connector.getAll().stream().filter(s -> same(s, template)).toList();
List<Long> savedIds = savedScores.stream().map(Score::getId).toList();
assertThat(savedScores, Matchers.not(Matchers.hasSize(0)));
for (Score score : savedScores) {
score.setLevel(Level.HARD);
connector.save(score);
}
List<Score> modifiedScores = connector.getAll().stream().filter(s -> savedIds.contains(s.getId())).toList();
assertThat(modifiedScores, Matchers.not(Matchers.hasSize(0)));
List<Score> originalDataScores = connector.getAll().stream().filter(s -> same(s, template)).toList();
assertThat(originalDataScores, Matchers.hasSize(0));
}
@Test
@Order(400)
void jpaScoreDeleteTest() {
template.setLevel(Level.HARD);
List<Score> savedScores = connector.getAll().stream().filter(s -> same(s, template)).toList();
List<Long> savedIds = savedScores.stream().map(Score::getId).toList();
assertThat(savedScores, Matchers.not(Matchers.hasSize(0)));
connector.delete(savedScores);
List<Score> modifiedScores = connector.getAll().stream().filter(s -> savedIds.contains(s.getId())).toList();
assertThat(modifiedScores, Matchers.hasSize(0));
List<Score> originalDataScores = connector.getAll().stream().filter(s -> same(s, template)).toList();
assertThat(originalDataScores, Matchers.hasSize(0));
}
@Test
@Order(400)
void jpaMergeTest() {
connector.save(template);
connector.find(template.getId());
Score copy = template.toBuilder().points(500).build();
Score result = connector.save(copy);
assertThat(result, Matchers.not(Matchers.sameInstance(copy)));
}
@Test
@Order(500)
void jpamodifyNoPersistNoMergeTest() throws URISyntaxException, IOException, IllegalAccessException, InvocationTargetException, NoSuchMethodException, SecurityException {
template.setName("aaa");
connector.save(template);
connector.modifyNoPersistOrMerge(template.getId(), score -> score.setName("ok"));
Object em = connector.getEntityManager();
em.getClass().getMethod("clear").invoke(em);
assertThat(connector.find(template.getId()).getName(), Matchers.equalTo("ok"));
TextFileContains textFileContains = new TextFileContains("JpaConnector.java",
"void\\s+modifyNoPersistOrMerge[\\s\\S]*}").multiline(true);
assertThat(TextFileContains.getProjectRoot(ClassStructureTest.class), textFileContains);
Path score = textFileContains.getFoundFiles().getFirst();
String src = Files.readString(score);
String method = Pattern.compile("void\\s+modifyNoPersistOrMerge[\\s\\S]*}").matcher(src).results().findFirst().get().group();
assertThat(method, Matchers.not(Matchers.containsString("persist")));
assertThat(method, Matchers.not(Matchers.containsString("merge")));
}
}
}