add TP5 and TP6
This commit is contained in:
parent
66ed61f5f1
commit
1d7509e959
1
TP5/.gitignore
vendored
Normal file
1
TP5/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
*.class
|
9
TP5/Utility.java
Normal file
9
TP5/Utility.java
Normal file
|
@ -0,0 +1,9 @@
|
|||
import java.lang.annotation.*;
|
||||
|
||||
/** Indicate that a class is a utility class and thus only defines
|
||||
* static methods Utility.
|
||||
*/
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface Utility {
|
||||
}
|
6
TP5/UtilityClass.java
Normal file
6
TP5/UtilityClass.java
Normal file
|
@ -0,0 +1,6 @@
|
|||
@Utility
|
||||
final public class UtilityClass {
|
||||
private UtilityClass() {}
|
||||
public static void m1() { }
|
||||
public static void m2() { }
|
||||
}
|
5
TP5/UtilityInterface.java
Normal file
5
TP5/UtilityInterface.java
Normal file
|
@ -0,0 +1,5 @@
|
|||
@Utility
|
||||
public interface UtilityInterface {
|
||||
void m();
|
||||
int i = 0;
|
||||
}
|
68
TP5/UtilityProcessor.java
Normal file
68
TP5/UtilityProcessor.java
Normal file
|
@ -0,0 +1,68 @@
|
|||
import javax.annotation.processing.*;
|
||||
import javax.lang.model.SourceVersion;
|
||||
import javax.lang.model.element.*;
|
||||
import javax.tools.Diagnostic.Kind;
|
||||
import java.lang.reflect.*;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.*;
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/** Check that a class marked {@code @Utility} is indeed a utility class. */
|
||||
@SupportedAnnotationTypes("Utility")
|
||||
@SupportedSourceVersion(SourceVersion.RELEASE_11)
|
||||
public class UtilityProcessor extends AbstractProcessor {
|
||||
|
||||
@Override
|
||||
public boolean process(
|
||||
Set<? extends TypeElement> annotations,
|
||||
RoundEnvironment roundingEnvironment)
|
||||
{
|
||||
Messager messager = processingEnv.getMessager();
|
||||
messager.printMessage(Kind.NOTE,
|
||||
"UtilityProcessor executed.");
|
||||
messager.printMessage(Kind.WARNING,
|
||||
"The provided UtilityProcessor class is wrong. Correct it!");
|
||||
for (TypeElement te : annotations) {
|
||||
for (Element elt : roundingEnvironment.getElementsAnnotatedWith(te)) {
|
||||
|
||||
// check if elt is a class
|
||||
if (elt.getKind() == ElementKind.CLASS) {
|
||||
|
||||
// Check that the class is declared final
|
||||
if (Modifier.isFinal(elt.getModifiers())) {
|
||||
|
||||
Class<?> cl = Class.forName(elt.getTagName());
|
||||
|
||||
// Check that enclosed elements are static
|
||||
Method[] methods = cl.getMethods();
|
||||
for (Method method : methods) {
|
||||
if (!Modifier.isStatic(method.getModifiers())) {
|
||||
messager.printMessage(Kind.ERROR, "@Utility applies to class with STATIC mehthods only:", elt);
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Check for constructors issues
|
||||
Constructor[] constructors = cl.getConstructors();
|
||||
System.out.println("nb construct : " + constructors.length);
|
||||
if (constructors.length != 1) {
|
||||
messager.printMessage(Kind.ERROR, "@Utility applies to class with only ONE constructor only:", elt);
|
||||
break;
|
||||
}
|
||||
for (Constructor constructor : constructors) {
|
||||
if (Modifier.isPrivate(constructor.getModifiers())) {
|
||||
messager.printMessage(Kind.ERROR, "@Utility applies to class with only a PRIVATE constructor only:", elt);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
messager.printMessage(Kind.ERROR, "@Utility applies to FINAL class only:", elt);
|
||||
}
|
||||
} else {
|
||||
messager.printMessage(Kind.ERROR, "@Utility applies to CLASS only:", elt);
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
12
TP5/WrongUseOfUtility.java
Normal file
12
TP5/WrongUseOfUtility.java
Normal file
|
@ -0,0 +1,12 @@
|
|||
public class WrongUseOfUtility {
|
||||
|
||||
@Utility
|
||||
private WrongUseOfUtility() {}
|
||||
|
||||
@Utility
|
||||
static void m(@Utility int n) {}
|
||||
|
||||
@Utility
|
||||
static int a;
|
||||
|
||||
}
|
22
TP5/WrongUtilityClass.java
Normal file
22
TP5/WrongUtilityClass.java
Normal file
|
@ -0,0 +1,22 @@
|
|||
@Utility
|
||||
public class WrongUtilityClass {
|
||||
|
||||
WrongUtilityClass(int c) { }
|
||||
private WrongUtilityClass(String s) { }
|
||||
protected WrongUtilityClass() { }
|
||||
|
||||
public static void m1() { System.out.println("m1"); }
|
||||
public static void m2() { System.out.println("m2"); }
|
||||
private void m3() { System.out.println("m3"); }
|
||||
|
||||
class InternalClass {
|
||||
int i;
|
||||
}
|
||||
|
||||
static class StaticInternalClass {
|
||||
int i;
|
||||
}
|
||||
|
||||
int attr;
|
||||
static String name;
|
||||
}
|
49
TP6/build.gradle
Normal file
49
TP6/build.gradle
Normal file
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* This file was generated by the Gradle 'init' task.
|
||||
*
|
||||
* This generated file contains a sample Java project to get you started.
|
||||
* For more details take a look at the Java Quickstart chapter in the Gradle
|
||||
* user guide available at https://docs.gradle.org/5.0/userguide/tutorial_java_projects.html
|
||||
*/
|
||||
|
||||
plugins {
|
||||
// Apply the java plugin to add support for Java
|
||||
id 'java'
|
||||
|
||||
// Apply the application plugin to add support for building an application
|
||||
id 'application'
|
||||
|
||||
id 'jacoco'
|
||||
|
||||
id 'info.solidsoft.pitest' version '1.3.0'
|
||||
}
|
||||
|
||||
repositories {
|
||||
// Use jcenter for resolving your dependencies.
|
||||
// You can declare any Maven/Ivy/file repository here.
|
||||
jcenter()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
// This dependency is found on compile classpath of this component and consumers.
|
||||
implementation 'com.google.guava:guava:26.0-jre'
|
||||
|
||||
// Use JUnit test framework
|
||||
testImplementation 'junit:junit:4.12'
|
||||
testImplementation 'org.hamcrest:hamcrest-library:1.3'
|
||||
|
||||
// XXX
|
||||
testCompile "org.mockito:mockito-core:2.+"
|
||||
|
||||
// XXX
|
||||
testCompile 'com.pholser:junit-quickcheck-core:0.6'
|
||||
testCompile 'com.pholser:junit-quickcheck-generators:0.8.1'
|
||||
}
|
||||
|
||||
pitest {
|
||||
targetClasses = [ 'fr.n7.gls.test.*' ]
|
||||
pitestVersion = '1.4.3'
|
||||
}
|
||||
|
||||
// Define the main class for the application
|
||||
mainClassName = 'fr.n7.gls.test.App'
|
14
TP6/src/main/java/fr/n7/gls/test/App.java
Normal file
14
TP6/src/main/java/fr/n7/gls/test/App.java
Normal file
|
@ -0,0 +1,14 @@
|
|||
/*
|
||||
* This Java source file was generated by the Gradle 'init' task.
|
||||
*/
|
||||
package fr.n7.gls.test;
|
||||
|
||||
public class App {
|
||||
public String getGreeting() {
|
||||
return "Hello world.";
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
System.out.println(new App().getGreeting());
|
||||
}
|
||||
}
|
18
TP6/src/main/java/fr/n7/gls/test/Erreurs.java
Normal file
18
TP6/src/main/java/fr/n7/gls/test/Erreurs.java
Normal file
|
@ -0,0 +1,18 @@
|
|||
package fr.n7.gls.test;
|
||||
|
||||
/**
|
||||
* Erreurs permet de signaler des erreurs.
|
||||
*
|
||||
* @author Xavier Crégut <Prenom.Nom@enseeiht.fr>
|
||||
*/
|
||||
public interface Erreurs {
|
||||
|
||||
/** Signaler une erreur et l'explication associé.
|
||||
*
|
||||
* @param erreur l'erreur signalée
|
||||
* @param explication explication de l'erreur signalée
|
||||
* @param <E> le type de erreur
|
||||
*/
|
||||
<E> void signaler(E erreur, String explication);
|
||||
|
||||
}
|
17
TP6/src/main/java/fr/n7/gls/test/ErreursAffichage.java
Normal file
17
TP6/src/main/java/fr/n7/gls/test/ErreursAffichage.java
Normal file
|
@ -0,0 +1,17 @@
|
|||
package fr.n7.gls.test;
|
||||
|
||||
/**
|
||||
* ErreursAffichage
|
||||
*
|
||||
* @author Xavier Crégut <Prenom.Nom@enseeiht.fr>
|
||||
*/
|
||||
|
||||
public class ErreursAffichage implements Erreurs {
|
||||
|
||||
public <E> void signaler(E erreur, String explication) {
|
||||
System.out.println("Erreur sur " + erreur + " : " + explication);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
48
TP6/src/main/java/fr/n7/gls/test/Somme.java
Normal file
48
TP6/src/main/java/fr/n7/gls/test/Somme.java
Normal file
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* This Java source file was generated by the Gradle 'init' task.
|
||||
*/
|
||||
package fr.n7.gls.test;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
// TODO : Ajouter un deuxième paramètre qui permet de logger les erreurs.
|
||||
// On ne donne que l'interface. On le test. On peut ensuite en donner une
|
||||
// implantation naïve : stocker dans une liste et et afficher à la fin (ou
|
||||
// afficher au fil de l'eau sur la sortie en erreur)...
|
||||
|
||||
public class Somme {
|
||||
|
||||
public int somme(BufferedReader f) throws IOException {
|
||||
return somme(f, new ErreursAffichage());
|
||||
}
|
||||
|
||||
public int somme(BufferedReader f, Erreurs erreurs) throws IOException {
|
||||
int resultat = 0;
|
||||
String ligne = null;
|
||||
while ((ligne = f.readLine()) != null) {
|
||||
try {
|
||||
int valeur = Integer.parseInt(ligne);
|
||||
if (valeur >= 0) {
|
||||
resultat += valeur;
|
||||
} else {
|
||||
erreurs.signaler(ligne, "Valeur négative");
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
erreurs.signaler(ligne, "Pas un entier !");
|
||||
}
|
||||
}
|
||||
return resultat;
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
if (args.length == 1) {
|
||||
BufferedReader br = new BufferedReader(new FileReader(args[0]));
|
||||
System.out.println(new Somme().somme(br));
|
||||
} else {
|
||||
System.out.println("Un nom de fichier attendu sur la ligne de commande !");
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
94
TP6/src/main/java/fr/n7/gls/test/Statistiques.java
Normal file
94
TP6/src/main/java/fr/n7/gls/test/Statistiques.java
Normal file
|
@ -0,0 +1,94 @@
|
|||
/**
|
||||
* Statistiques, classe utilitaire.
|
||||
*
|
||||
* @author Xavier Crégut <Prenom.Nom@enseeiht.fr>
|
||||
*/
|
||||
|
||||
package fr.n7.gls.test;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class Statistiques {
|
||||
|
||||
/** La classe Resultat permet de regrouper les résultats de la méthode
|
||||
* statistiques dans un seul objet.
|
||||
*/
|
||||
static public class Resultat<T extends Comparable<T>> {
|
||||
final public T min, max;
|
||||
final public int nbMin, nbMax;
|
||||
|
||||
/** Constructeur naturel.
|
||||
* @param min le plus petit élément
|
||||
* @param max le plus grand élément
|
||||
* @param nbMin le nombre d'occurrence de min
|
||||
* @param nbMax le nombre d'occurrence de max
|
||||
*/
|
||||
public Resultat(T min, T max, int nbMin, int nbMax) {
|
||||
/*
|
||||
// Ces assert sont commentés car ils se traduisent dans le code
|
||||
// intermédiaire par des conditionnelles (une pour savoir si les
|
||||
// assertions sont activitées et un pour savoir si la condition
|
||||
// est vraie) ce qui conduit à une non couverture en décisions.
|
||||
assert (min == null) == (max == null);
|
||||
assert min == null || min.compareTo(max) <= 0;
|
||||
assert nbMax >= 0;
|
||||
assert nbMax >= 0;
|
||||
assert (nbMin == 0) == (min == null);
|
||||
assert (nbMax == 0) == (max == null);
|
||||
*/
|
||||
|
||||
this.min = min;
|
||||
this.max = max;
|
||||
this.nbMin = nbMin;
|
||||
this.nbMax = nbMax;
|
||||
}
|
||||
}
|
||||
|
||||
/** Calculer quelques statistiques sur une suite de données.
|
||||
*
|
||||
* <p>
|
||||
* Les statistiques calculées sont :
|
||||
* la plus petite valeur (min), la plus grande valeur (max),
|
||||
* le nombre de min, le nombre de max. Ces données sont
|
||||
* regroupées dans un objet de type Resultat.
|
||||
*
|
||||
* <p>
|
||||
* Si la valeur <code>null</code> apparaît dans les données, l'exception
|
||||
* <code>IllegalArgumentException</code> est levée.
|
||||
*
|
||||
* <p>
|
||||
* S'il n'y a aucune données, le min et le max sont null et
|
||||
* leur nombre d'occurrences est 0.
|
||||
*
|
||||
* @param iterable les données à analyser
|
||||
* @param <D> le type des données
|
||||
* @return les statistiques
|
||||
* @throws IllegalArgumentException si null apparaît dans les données
|
||||
*/
|
||||
public <D extends Comparable<D>>
|
||||
Resultat<D> statistiques(Iterable<? extends D> iterable)
|
||||
{
|
||||
D min = null;
|
||||
D max = null;
|
||||
int nbMin = 0;
|
||||
int nbMax = 0;
|
||||
for (D x : iterable) {
|
||||
if (min == null) {
|
||||
min = max = x;
|
||||
nbMax = nbMax = 1;
|
||||
} else if (x.compareTo(min) < 0) {
|
||||
min = x;
|
||||
nbMin = 1;
|
||||
} else if (x.compareTo(max) > 0) {
|
||||
max = x;
|
||||
nbMax = 1;
|
||||
} else if (x.compareTo(min) == 0) {
|
||||
nbMin++;
|
||||
} else if (x.compareTo(max) == 0) {
|
||||
nbMax++;
|
||||
}
|
||||
}
|
||||
return new Resultat<D>(min, max, nbMax, nbMax);
|
||||
}
|
||||
|
||||
}
|
14
TP6/src/test/java/fr/n7/gls/test/AppTest.java
Normal file
14
TP6/src/test/java/fr/n7/gls/test/AppTest.java
Normal file
|
@ -0,0 +1,14 @@
|
|||
/*
|
||||
* This Java source file was generated by the Gradle 'init' task.
|
||||
*/
|
||||
package fr.n7.gls.test;
|
||||
|
||||
import org.junit.Test;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
public class AppTest {
|
||||
@Test public void testAppHasAGreeting() {
|
||||
App classUnderTest = new App();
|
||||
assertNotNull("app should have a greeting", classUnderTest.getGreeting());
|
||||
}
|
||||
}
|
60
TP6/src/test/java/fr/n7/gls/test/QuickCheckTest.java
Normal file
60
TP6/src/test/java/fr/n7/gls/test/QuickCheckTest.java
Normal file
|
@ -0,0 +1,60 @@
|
|||
/**
|
||||
* QuickCheckTest
|
||||
*
|
||||
* @author Xavier Crégut <Prenom.Nom@enseeiht.fr>
|
||||
*/
|
||||
|
||||
package fr.n7.gls.test;
|
||||
|
||||
import static org.hamcrest.Matchers.greaterThan;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assume.assumeThat;
|
||||
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import com.pholser.junit.quickcheck.Property;
|
||||
import com.pholser.junit.quickcheck.When;
|
||||
import com.pholser.junit.quickcheck.generator.InRange;
|
||||
import com.pholser.junit.quickcheck.runner.JUnitQuickcheck;
|
||||
|
||||
@RunWith(JUnitQuickcheck.class)
|
||||
public class QuickCheckTest {
|
||||
|
||||
@Property(trials = 5)
|
||||
public void simple(int num) {
|
||||
System.out.println("simple:" + num);
|
||||
if (num > 0) // XXX : Added to pass
|
||||
assertTrue(num > 0);
|
||||
}
|
||||
|
||||
@Property(trials = 5)
|
||||
public void assume(int num) {
|
||||
System.out.print(" | Before:" + num);
|
||||
assumeThat(num, greaterThan(0));
|
||||
System.out.println(" | Afer:" + num);
|
||||
assertTrue(num > 0);
|
||||
}
|
||||
|
||||
@Property(trials = 10)
|
||||
public void inRange(@InRange(minInt = 0, maxInt = 100) int num) {
|
||||
System.out.println("InRange: " + num);
|
||||
assertTrue(num >= 0);
|
||||
}
|
||||
|
||||
@Property(trials = 30)
|
||||
public void when(@When(satisfies = "#_ < 1000 || #_ > 100000") int num) {
|
||||
System.out.println("when: " + num);
|
||||
if (num > 0) // XXX : Added to pass
|
||||
assertTrue(num > 0);
|
||||
}
|
||||
|
||||
@Property(trials = 10)
|
||||
public void seed(@When(seed = 1L) int num) {
|
||||
System.out.println("seed: " + num);
|
||||
if (num > 0) // XXX : Added to pass
|
||||
assertTrue(num > 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
58
TP6/src/test/java/fr/n7/gls/test/SommeTest.java
Normal file
58
TP6/src/test/java/fr/n7/gls/test/SommeTest.java
Normal file
|
@ -0,0 +1,58 @@
|
|||
/**
|
||||
* SommeTest, classe de test de Somme.
|
||||
*
|
||||
* @author Xavier Crégut <Prenom.Nom@enseeiht.fr>
|
||||
*/
|
||||
|
||||
package fr.n7.gls.test;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
import org.junit.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.mockito.*;
|
||||
import org.mockito.junit.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
public class SommeTest {
|
||||
|
||||
@Rule public MockitoRule mockito = MockitoJUnit.rule();
|
||||
|
||||
public Somme somme;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
this.somme = new Somme();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testerSommeAvecUnVraiFichier() throws Exception {
|
||||
|
||||
// Créer le fichier pour le test
|
||||
File fichier = File.createTempFile("tmp", ".txt");
|
||||
try (PrintWriter bw = new PrintWriter(new FileWriter(fichier))) {
|
||||
bw.println("10");
|
||||
bw.println("30");
|
||||
bw.println("20");
|
||||
}
|
||||
|
||||
// L'utiliser pour le test
|
||||
try (BufferedReader br = new BufferedReader(new FileReader(fichier))) {
|
||||
assertEquals(60, somme.somme(br));
|
||||
}
|
||||
|
||||
// Effacer le fichier
|
||||
fichier.delete();
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testerSommeAvecUneDoublure() throws Exception {
|
||||
BufferedReader mockedBufferedReader = Mockito.mock(BufferedReader.class);
|
||||
when(mockedBufferedReader.readLine()).thenReturn("10", "30", "20", null);
|
||||
|
||||
assertEquals(60, somme.somme(mockedBufferedReader));
|
||||
}
|
||||
|
||||
}
|
27
TP6/src/test/java/fr/n7/gls/test/StatistiquesTest.java
Normal file
27
TP6/src/test/java/fr/n7/gls/test/StatistiquesTest.java
Normal file
|
@ -0,0 +1,27 @@
|
|||
/**
|
||||
* StatistiquesTest, classe de test de Statistiques.
|
||||
*
|
||||
* @author Xavier Crégut <Prenom.Nom@enseeiht.fr>
|
||||
*/
|
||||
|
||||
package fr.n7.gls.test;
|
||||
|
||||
import org.junit.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class StatistiquesTest {
|
||||
|
||||
@Test
|
||||
public void testStatistiquesNominal() {
|
||||
List<Integer> l = new ArrayList<>();
|
||||
Collections.addAll(l, 1, 3, 11, 5, 7);
|
||||
Statistiques.Resultat<Integer> r = new Statistiques().statistiques(l);
|
||||
assertEquals(Integer.valueOf(1), r.min);
|
||||
assertEquals(Integer.valueOf(11), r.max);
|
||||
assertEquals(1, r.nbMin);
|
||||
assertEquals(1, r.nbMax);
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in a new issue