From 63c165f02499f6e2f04f7ec92a21848c4e14024e Mon Sep 17 00:00:00 2001 From: bouclyma Date: Wed, 11 Dec 2024 10:36:30 +0100 Subject: [PATCH] =?UTF-8?q?feat(message):=20Cr=C3=A9ation=20de=20la=20clas?= =?UTF-8?q?se=20Message,=20m=C3=A9thodes=20pour=20g=C3=A9n=C3=A9rer=20du?= =?UTF-8?q?=20JSON=20=C3=A0=20partir=20de=20l'objet=20et=20inversement?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- chat/pom.xml | 6 + chat/src/main/java/module-info.java | 1 + chat/src/main/java/rtgre/modeles/Message.java | 57 +++++++ .../test/java/rtgre/modeles/MessageTest.java | 158 ++++++++++++++++++ 4 files changed, 222 insertions(+) create mode 100644 chat/src/main/java/rtgre/modeles/Message.java create mode 100644 chat/src/test/java/rtgre/modeles/MessageTest.java diff --git a/chat/pom.xml b/chat/pom.xml index a61a9a2..c2f4ad0 100644 --- a/chat/pom.xml +++ b/chat/pom.xml @@ -54,8 +54,14 @@ ${junit.version} test + + org.json + json + 20240303 + + diff --git a/chat/src/main/java/module-info.java b/chat/src/main/java/module-info.java index d4b00e4..b4e5b23 100644 --- a/chat/src/main/java/module-info.java +++ b/chat/src/main/java/module-info.java @@ -5,6 +5,7 @@ module rtgre.chat { requires java.desktop; requires javafx.swing; requires net.synedra.validatorfx; + requires org.json; opens rtgre.chat to javafx.fxml; diff --git a/chat/src/main/java/rtgre/modeles/Message.java b/chat/src/main/java/rtgre/modeles/Message.java new file mode 100644 index 0000000..685c86a --- /dev/null +++ b/chat/src/main/java/rtgre/modeles/Message.java @@ -0,0 +1,57 @@ +package rtgre.modeles; +import org.json.JSONObject; + + +public class Message { + /** + * Un message décrit sous la forme : + * @serialField : String to: Le destinataire + * @serialField : String body: le corps du message + */ + protected String to; + protected String body; + + public Message(String to, String body) { + + this.to = to; + this.body = body; + } + + public String getTo() { + return to; + } + + public String getBody() { + return body; + } + + @Override + public String toString() { + return "Message{" + + "to=" + to + + ", body=" + body + + '}'; + } + + public JSONObject toJsonObject() { + /** + * Transforme le message courant en objet JSON + */ + return new JSONObject("{to:%s,body:%s}".formatted( this.to, this.body)); + } + + public String toJson() { + /** + * Transforme l'objet courant en String JSON + */ + return toJsonObject().toString(); + } + + public static Message fromJson(JSONObject json) { + /** + * Crée un objet message à partir d'un objet JSON + * @param: JSONObject json: l'objet JSON à transformer + */ + return new Message(json.getString("to"), json.getString("body")); + } +} diff --git a/chat/src/test/java/rtgre/modeles/MessageTest.java b/chat/src/test/java/rtgre/modeles/MessageTest.java new file mode 100644 index 0000000..3efcd8a --- /dev/null +++ b/chat/src/test/java/rtgre/modeles/MessageTest.java @@ -0,0 +1,158 @@ +package rtgre.modeles; + +import org.json.JSONObject; +import org.junit.jupiter.api.*; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.params.provider.Arguments.arguments; + +class MessageTest { + + static Class classe = Message.class; + static String module = "rtgre.modeles"; + + + @DisplayName("01-Structure") + @Nested + class StructureTest { + static List constructeursSignatures; + static List methodesSignatures; + + @BeforeAll + static void init() { + Constructor[] constructeurs = classe.getConstructors(); + constructeursSignatures = Arrays.stream(constructeurs).map(Constructor::toString).collect(Collectors.toList()); + Method[] methodes = classe.getDeclaredMethods(); + methodesSignatures = Arrays.stream(methodes).map(Method::toString).collect(Collectors.toList()); + } + + /** + * Attributs + */ + static Stream attributsProvider() { + return Stream.of( + arguments("to", "java.lang.String", Modifier.PROTECTED), + arguments("body", "java.lang.String", Modifier.PROTECTED) + ); + } + + @DisplayName("Déclaration des attributs : nom, type et visibilité") + @ParameterizedTest + @MethodSource("attributsProvider") + void testDeclarationAttributs(String nom, String type, int modifier) throws NoSuchFieldException { + Field field = classe.getDeclaredField(nom); + Assertions.assertEquals(type, field.getType().getName(), + "Type " + nom + " erroné : doit être " + type); + Assertions.assertEquals(modifier, field.getModifiers(), + "Visibilité " + nom + " erronée : doit être " + modifier); + + } + + /** + * Constructeurs + */ + static Stream constructeursProvider() { + return Stream.of( + arguments("public %s.Message(java.lang.String,java.lang.String)") + ); + } + + @DisplayName("Déclaration des constructeurs (base)") + @ParameterizedTest + @MethodSource("constructeursProvider") + void testConstructeurs(String signature) { + Assertions.assertTrue(constructeursSignatures.contains(String.format(signature, module)), + String.format("Constructeur non déclaré : doit être %s\nalors que sont déclarés %s", + signature, constructeursSignatures)); + + } + + /** + * Méthodes + */ + static Stream methodesProvider() { + return Stream.of( + arguments("getTo", "public java.lang.String %s.Message.getTo()"), + arguments("getBody", "public java.lang.String %s.Message.getBody()"), + arguments("toString", "public java.lang.String %s.Message.toString()"), + arguments("toJsonObject", "public org.json.JSONObject %s.Message.toJsonObject()"), + arguments("toJSON", "public java.lang.String %s.Message.toJson()"), + arguments("fromJson", "public static %s.Message %s.Message.fromJson(org.json.JSONObject)") + ); + } + + @DisplayName("Déclaration des méthodes (base)") + @ParameterizedTest + @MethodSource("methodesProvider") + void testDeclarationMethodes(String nom, String signature) { + Assertions.assertTrue(methodesSignatures.contains(String.format(signature, module, module)), + String.format("Méthode non déclarée : doit être %s\nalors que sont déclarés %s", + signature, methodesSignatures)); + } + + } + + @DisplayName("02-Instanciation et getters") + @Test + void testGetToBody() { + String erreur = "Getter erroné"; + Message m = new Message("riri", "bonjour"); + assertEquals("riri", m.getTo(), erreur); + assertEquals("bonjour", m.getBody(), erreur); + } + + + @Test + @DisplayName("03-Représentation textuelle") + void testToString() { + Message m = new Message("riri", "bonjour"); + assertEquals("Message{to=riri, body=bonjour}", m.toString(), "Représentation textuelle erronée"); + } + + @Nested + @DisplayName("04-Représentation JSON") + class JSONTest { + + + @Test + @DisplayName("Objet JSON") + void testClesToJSONObject() { + Message m = new Message("riri", "bonjour"); + JSONObject obj = m.toJsonObject(); + Assertions.assertTrue(obj.has("to"), "Clé manquante"); + Assertions.assertTrue(obj.has("body"), "Clé manquante"); + + } + + + @Test + @DisplayName("Sérialisation de la représentation JSON") + void testToJson() { + Message m = new Message("riri", "bonjour"); + String chaine = m.toJson(); + Assertions.assertTrue(chaine.contains("\"to\":\"riri\""), "to erroné dans " + m); + Assertions.assertTrue(chaine.contains("\"body\":\"bonjour\""), "body erroné dans " + m); + } + + @Test + @DisplayName("Instanciation à partir d'un objet JSON") + void testMessageFromJSON() { + JSONObject json = new JSONObject("{\"to\":\"riri\",\"body\":\"bonjour\"}"); + Message m = Message.fromJson(json); + Assertions.assertEquals("riri", m.getTo(), "Constructeur erroné"); + Assertions.assertEquals("bonjour", m.getBody(), "Constructeur erroné"); + } + } +} \ No newline at end of file