Merge branch 'feature-Identificateur' into dev

This commit is contained in:
SylvanCourtiol
2021-05-08 18:16:42 +02:00
10 changed files with 687 additions and 0 deletions
+128
View File
@@ -0,0 +1,128 @@
/*
* Identificateur.java , 08/05/2021
* IUT Rodez 2020-2021, info1
* pas de copyright, aucun droits
*/
package donnees;
/**
* @author Nicolas Caminade
* @author Sylvan Courtiol
* @author Pierre Debas
* @author Heia Dexter
* @author Lucas Vabre
*/
public class Identificateur /* extends Variable */
implements Comparable<Identificateur> {
/** Longueur maximale d'un identificateur (ne prend pas en compte le $) */
public static final int LONGUEUR_MAX = 24;
/** Nom identificateur */
private String nom;
/**
* Instantiation de l'identificateur
* @param identificateur
*/
public Identificateur(String identificateur) {
super();
if(!isIdentificateur(identificateur)) {
throw new IllegalArgumentException(identificateur
+ " n'est pas un identificateur");
}
nom = identificateur;
}
/**
* Prédicat qui vérifie si une chaîne correspond à un identificateur
* <ul>
* <li>Longueur comprise entre 1 et 24 caractères</li>
* <li>N'est pas une chaîne vide</li>
* <li>N'est pas null</li>
* </ul>
* @param aComparer
* @return true si le prédicat est vérifié
* false sinon
*/
public static boolean isIdentificateur(String aComparer) {
return aComparer != null
&& aComparer.length() > 0
&& !removeDollar(aComparer).isBlank()
&& removeDollar(aComparer).length() <= LONGUEUR_MAX
&& isAlphanumerique(removeDollar(aComparer));
}
/**
* Supprime le caractère $ si il est présent en premier dans la chaîne
* @param chaine a modifier
* @return la chaîne modifiée
*/
public static String removeDollar(String chaine) {
if(chaine.charAt(0) == '$') return chaine.substring(1);
return chaine;
}
/**
* Prédicat testant si une chaîne est composée de chiffre ou de lettres
* @param aTester chaîne a tester
* @return true si le prédicat est vérifié
* false sinon
*/
public static boolean isAlphanumerique(String aTester) {
int index;
for (index = 0 ;
index < aTester.length()
&& (isLettre(aTester.charAt(index))
|| isChiffre(aTester.charAt(index)));
index++)
; // Corps vide
return index >= aTester.length();
}
/**
* Prédicat attestant si un caractère est une lettre
* @param aTester caractère a tester
* @return true si le prédicat est vérifié
* false sinon
*/
public static boolean isLettre(char aTester) {
return 'a' <= aTester && aTester <= 'z'
|| 'A' <= aTester && aTester <= 'Z';
}
/**
* Prédicat attestant si un caractère est un chiffre
* @param aTester caractère a tester
* @return true si le prédicat est vérifié
* false sinon
*/
public static boolean isChiffre(char aTester) {
return '0' <= aTester && aTester <= '9';
}
/**
* @return la valeur de nom
*/
public String getNom() {
return nom;
}
/* non javadoc - @see java.lang.Object#toString() */
@Override
public String toString() {
return "Identificateur [nom=" + nom + "]";
}
/* non javadoc - @see java.lang.String#Comparable() */
@Override
public int compareTo(Identificateur aComparer) {
return nom.compareTo(aComparer.getNom());
}
}
+46
View File
@@ -0,0 +1,46 @@
/*
* IdentificateurChaine.java, 08/05/2021
* IUT Rodez 2020-2021, info1
* pas de copyright, aucun droits
*/
package donnees;
/**
* Identificateur de chaîne
* @author Nicolas Caminade
* @author Sylvan Courtiol
* @author Pierre Debas
* @author Heia Dexter
* @author Lucas Vabre
*/
public class IdentificateurChaine extends Identificateur {
/**
* Instantiation d'identificateur de chaîne
* @param identificateur a instancier
* @throws IllegalAccessException si l'identificateur est invalide
*/
public IdentificateurChaine(String identificateur) {
super(identificateur);
if(!isIdentificateurChaine(identificateur)) {
throw new IllegalArgumentException(identificateur
+ " n'est pas un identificateur"
+ " de chaine");
}
}
/**
* Prédicat attestant la validité de l'identificateur
* @param identificateur à tester
* @return true si l'identificateur est bien un identificateur d'entier
* false sinon
*/
private static boolean isIdentificateurChaine(String identificateur) {
return identificateur.length() >= 2
&& identificateur.charAt(0) == '$'
&& isLettre(identificateur.charAt(1));
}
}
+51
View File
@@ -0,0 +1,51 @@
/*
* IdentificateurEntier.java , 08/05/2021
* IUT Rodez 2020-2021, info1
* pas de copyright, aucun droits
*/
package donnees;
/**
* Identificateur d'entier
* @author Nicolas Caminade
* @author Sylvan Courtiol
* @author Pierre Debas
* @author Heia Dexter
* @author Lucas Vabre
*/
public class IdentificateurEntier extends Identificateur {
/**
* Instantiation d'identificateur d'entier
* @param identificateur a instancier
* @throws IllegalAccessException si l'identificateur est invalide
*/
public IdentificateurEntier(String identificateur) {
super(identificateur);
if(!isIdentificateurEntier(identificateur)) {
throw new IllegalArgumentException(identificateur
+ " n'est pas un identificateur"
+ " d'entier");
}
}
/**
* Prédicat attestant la validité de l'identificateur
*
* Un identificateur d'entier est valide si
* - Il contient au maximum 24 caractères
* - Commence obligatoirement par une lettre (majuscule ou minuscule)
* - suivie uniquement de lettres (majuscule ou minuscule) ou de chiffres
*
* @param identificateur à tester
* @return true si l'identificateur est bien un identificateur d'entier
* false sinon
*/
private static boolean isIdentificateurEntier(String identificateur) {
return isLettre(identificateur.charAt(0))
&& isAlphanumerique(identificateur.substring(1));
}
}
+114
View File
@@ -0,0 +1,114 @@
/**
* TestIdentificateur.java 8 mai 2021
* IUT-Rodez info1 2020-2021, pas de droits, pas de copyrights
*/
package donnees.tests;
import static outils.glg.Assertions.*;
import donnees.Identificateur;
/**
* Test de la classe donnees.Identificateur
* @author Nicolas Caminade
* @author Sylvan Courtiol
* @author Pierre Debas
* @author Heia Dexter
* @author Lucas Vabre
*/
public class TestIdentificateur {
/** Jeu d'identificateurs correctement instanciés */
public static final Identificateur[] FIXTURE = {
new Identificateur("b"),
new Identificateur("A"),
new Identificateur("zalpha"),
new Identificateur("Alpha"),
new Identificateur("Alpha5"),
new Identificateur("jeSuisUnTresLongIdentifi"),
new Identificateur("$b"),
new Identificateur("z"),
new Identificateur("$zalpha"),
new Identificateur("$Alpha"),
new Identificateur("$Alpha5"),
new Identificateur("$jeSuisUnTresLongIdentifi")
};
/**
* Test de Identificateur(String identificateur)
*/
public static void testIdentificateurString() {
final String[] INVALIDE = {
null,
"",
// Fait au maximum 24 caractères
"$jeSuisUnTresLongIdentificateur", // 30 char
"$jeSuisUnTresLongIdentific",
// Espaces
"id 3a",
"$id 3a",
" ",
"$ ",
// caractères d'échapements
"\t",
"\n",
"$\t",
"$\n",
// , cas particulier
"$"
};
for(int noJeu = 0 ; noJeu < INVALIDE.length ; noJeu++) {
try {
new Identificateur(INVALIDE[noJeu]);
echec();
} catch (IllegalArgumentException lancee) {
// Test OK
}
}
}
/**
* Test de compareTo(Identificateur aComparer)
*/
public static void testCompareTo() {
final Identificateur REF_MIN = new Identificateur("$AAAAAAAAAAAAAAAAAAAAAAAA");
final Identificateur REF_MAX = new Identificateur("zzzzzzzzzzzzzzzzzzzzzzzz");
for(int noJeu = 0; noJeu < FIXTURE.length; noJeu++) {
assertTrue(FIXTURE[noJeu].compareTo(REF_MIN) >= 0);
assertTrue(FIXTURE[noJeu].compareTo(REF_MAX) <= 0);
assertTrue(FIXTURE[noJeu].compareTo(FIXTURE[noJeu]) == 0);
}
}
/**
* Tests unitaires de toString
*/
public static void testToString() {
final String[] CHAINES_VALIDES = {
"Identificateur [nom=b]",
"Identificateur [nom=A]",
"Identificateur [nom=zalpha]",
"Identificateur [nom=Alpha]",
"Identificateur [nom=Alpha5]",
"Identificateur [nom=jeSuisUnTresLongIdentifi]",
"Identificateur [nom=$b]",
"Identificateur [nom=z]",
"Identificateur [nom=$zalpha]",
"Identificateur [nom=$Alpha]",
"Identificateur [nom=$Alpha5]",
"Identificateur [nom=$jeSuisUnTresLongIdentifi]"
};
for (int noJeu = 0 ; noJeu < CHAINES_VALIDES.length ; noJeu++) {
assertEquivalent(CHAINES_VALIDES[noJeu],
FIXTURE[noJeu].toString());
}
}
}
@@ -0,0 +1,93 @@
/*
* TestIdentificateurChaine.java, 08/05/2021
* IUT Rodez 2020-2021, info1
* pas de copyright, aucun droits
*/
package donnees.tests;
import static outils.glg.Assertions.assertEquivalent;
import static outils.glg.Assertions.echec;
import donnees.IdentificateurChaine;
/**
* Tests unitaires de la classe donnees.IdentificateurEntier
* @author Nicolas Caminade
* @author Sylvan Courtiol
* @author Pierre Debas
* @author Heia Dexter
* @author Lucas Vabre
*/
public class TestIdentificateurChaine {
/** Jeu d'identificateurs de chaîne correctement instanciés */
private static IdentificateurChaine[] FIXTURE = {
new IdentificateurChaine("$a"),
new IdentificateurChaine("$A"),
new IdentificateurChaine("$alpha"),
new IdentificateurChaine("$Alpha"),
new IdentificateurChaine("$Alpha5"),
new IdentificateurChaine("$jeSuisUnTresLongIdentifi")
};
/**
* Tests unitaires du constructeur IdentificateurEntier(String identificateur)
*/
public static void testIdentificateurChaineString() {
final String[] INVALIDE = {
null,
"",
// Commence par une lettre
"9alpha",
" 5alpha",
// Fait au maximum 24 caractères
"$jeSuisUnTresLongIdentificateur", // 30 char
"$jeSuisUnTresLongIdentific",
// Espaces
"id 3a",
"$id 3a",
" ",
"$ ",
// caractères d'échapements
"\t",
"\n",
"$\t",
"$\n",
// , cas particulier
"$",
"$1"
};
for(int noJeu = 0; noJeu < INVALIDE.length ; noJeu++) {
try {
new IdentificateurChaine(INVALIDE[noJeu]);
echec();
} catch (IllegalArgumentException lancee) {
// test OK
}
}
}
/**
* Tests unitaires de getNom()
*/
public static void testGetNom() {
final String[] NOM_VALIDES = {
"$a",
"$A",
"$alpha",
"$Alpha",
"$Alpha5",
"$jeSuisUnTresLongIdentifi"
};
for (int noJeu = 0 ; noJeu < NOM_VALIDES.length ; noJeu++) {
assertEquivalent(NOM_VALIDES[noJeu], FIXTURE[noJeu].getNom());
}
}
}
@@ -0,0 +1,83 @@
/*
* TestIdentificateurEntier.java , 08/05/2021
* IUT Rodez 2020-2021, info1
* pas de copyright, aucun droits
*/
package donnees.tests;
import static outils.glg.Assertions.*;
import donnees.IdentificateurEntier;
/**
* Tests unitaires de la classe donnees.IdentificateurEntier
* @author Nicolas Caminade
* @author Sylvan Courtiol
* @author Pierre Debas
* @author Heia Dexter
* @author Lucas Vabre
*/
public class TestIdentificateurEntier {
/** Jeu d'identificateurs d'entier correctement instanciés */
private static IdentificateurEntier[] FIXTURE = {
new IdentificateurEntier("a"),
new IdentificateurEntier("A"),
new IdentificateurEntier("alpha"),
new IdentificateurEntier("Alpha"),
new IdentificateurEntier("Alpha5"),
new IdentificateurEntier("jeSuisUnTresLongIdentifi")
};
/**
* Tests unitaires du constructeur IdentificateurEntier(String identificateur)
*/
public static void testIdentificateurEntierString() {
final String[] INVALIDE = {
// Commence par une lettre
"9alpha",
" 5alpha",
"$beta",
// Fait au maximum 24 caractères
"jeSuisUnTresLongIdentificateur", // 30 char
"jeSuisUnTresLongIdentific",
// Espaces, caractères d'échapements, cas particulier
"id 3a",
"",
" ",
"\t",
"\n",
null
};
for(int noJeu = 0; noJeu < INVALIDE.length ; noJeu++) {
try {
new IdentificateurEntier(INVALIDE[noJeu]);
echec();
} catch (IllegalArgumentException lancee) {
// test OK
}
}
}
/**
* Tests unitaires de getNom()
*/
public static void testGetNom() {
final String[] NOM_VALIDES = {
"a",
"A",
"alpha",
"Alpha",
"Alpha5",
"jeSuisUnTresLongIdentifi"
};
for (int noJeu = 0 ; noJeu < NOM_VALIDES.length ; noJeu++) {
assertEquivalent(NOM_VALIDES[noJeu], FIXTURE[noJeu].getNom());
}
}
}
+25
View File
@@ -0,0 +1,25 @@
/**
* InterpreteurException.java 7 mai 2021
* IUT Rodez info1 2020-2021, pas de copyright, aucun droit
*/
package outils;
/**
* Exception levée lors d'une erreur dans l'interpreteur LIR.
* (Erreur de syntaxe, erreur de types)
* @author Nicolas Caminade
* @author Sylvan Courtiol
* @author Pierre Debas
* @author Heïa Dexter
* @author Lucas Vabre
*/
public class InterpreteurException extends RuntimeException {
/**
* Une exception de syntaxe expliquée par un message
* @param message explication succincte de cette exception
*/
public InterpreteurException(String message) {
super(message);
}
}
+42
View File
@@ -0,0 +1,42 @@
/*
* Assertions.java 7 avr. 2021
* IUT info1 2020-2021, groupe 2, aucun droit d'auteur
*/
package outils.glg;
/**
* Propositions logiques de test qui propage EchecTest
* si elles ne sont pas vérifiées
* @author info1 202-2021
*/
public class Assertions {
/**
* Assertion vérifiant qu'une expression booléenne est vraie.
* Ce test échoue si elle est fausse
* @param condition expression booléenne à tester
*/
public static void assertTrue(boolean condition) {
if (!condition) {
throw new EchecTest();
}
}
/**
* Assertion testant l'équivalence de 2 objets selon la relation
* d'équivalence de base equals (@see java.lang.Object#equals)
* @param attendu valeur attendue pour le test
* @param obtenu valeur obtenue à tester
*/
public static void assertEquivalent(Object attendu, Object obtenu) {
assertTrue(obtenu.equals(attendu));
}
/**
* Echec systématique de test
* (signaler que une série de test est insuffisante)
*/
public static void echec() {
assertTrue(false);
}
}
+19
View File
@@ -0,0 +1,19 @@
/*
* EchecTest.java 7 avr. 2021
* IUT info1 2020-2021, groupe 2, aucun droit d'auteur
*/
package outils.glg;
/**
* Exception lancée si un test unitaire échoue : comportement obtenu n'étant pas
* le comportement attendu
* @author info1 2020-2021
*/
public class EchecTest extends RuntimeException {
// constructeur par défaut généré par le compilateur
public EchecTest() {
super();
}
}
+86
View File
@@ -0,0 +1,86 @@
/*
* ExecuteurDeTest.java 13 avr. 2021
* IUT info1 2020-2021, groupe 2, aucun droit d'auteur
*/
package outils.glg;
import java.lang.reflect.Method;
/**
* Lanceur de test automatique ("test runner") qui exécute les méthodes de tests
* unitaires d'une classe de test telle que :
* <ul><li>La classe de test doit être instanciable avec des méthodes de tests
* unitaires qui sont des méthodes d'instance</li>
* <li>Les jeux d'essai mis en champ d'instance sont régénérés
* automatiquement à chaque instanciation de la classe de test
* = "fixture de test" (fix picture of test)</li>
* <li>Chaque méthode de test s'exécute dans sa propre instance donc avec
* la fixture remise dans son état initial</li>
* <li>Chaque méthode de test unitaire ne doit tester qu'une seule méthode
* de la classe à tester</li>
* <li>Chaque méthode de test unitaire s'arrête en cas d'échec
* de test (failure) ou de crash (error)</li>
* </ul>
*
* @author info1 2020-2021
*/
public class ExecuteurDeTest {
/** préfixe des méthodes de tests unitaires à lancer */
public final static String PREFIXE_TEST = "test";
/** Code erreur si la ligne de commande est mal formatée */
public static final int ERR_NB_ARGUMENT = 1;
/** Code erreur si la classe de test (argument) n'est pas trouvée */
public static final int ERR_CLASSE_INACCESSIBLE = 2;
/** Message d'aide à l'usage de l'outil */
private static final String MESSAGE_USAGE
= "usage : info1.outils.glg.ExecuteurDeTest nom.complet.de.classe.de.Test";
/**
* Lancement automatique des méthodes de test
* d'une classe de test passée en argument
* @param args nom java complet de la classe de test à exécuter
*/
public static void main(String[] args) {
/* Analyse de la ligne de commande */
if (args.length != 1) {
System.err.println("Nombre d'arguments incorrects");
System.err.println(MESSAGE_USAGE);
System.exit(ERR_NB_ARGUMENT);
}
Class<?> deTest = null;
try {
deTest = Class.forName(args[0]);
} catch (ClassNotFoundException e) {
System.err.println("Classe " + args[0] + " non accessible");
System.err.println(MESSAGE_USAGE);
System.exit(ERR_CLASSE_INACCESSIBLE);
}
/* Lancement des méthodes de tests unitaires */
Method[] aFiltrer = deTest.getDeclaredMethods();
for (Method aExecuter : aFiltrer) {
String nomMethode = aExecuter.getName();
if (nomMethode.startsWith(PREFIXE_TEST)) {
try {
aExecuter.invoke(deTest.getConstructor().newInstance());
/* test Ok */
System.out.println("Réussite de " + nomMethode);
} catch (Exception aAnalyser) {
if (aAnalyser.getCause() instanceof EchecTest) {
System.out.println("Echec de " + nomMethode);
} else {
System.err.println("Crash de " + nomMethode + " : "
+ aAnalyser.getCause().getMessage());
}
}
System.out.println("-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-");
}
}
}
}