diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 9c7004e4db0..529ad42bf91 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -37,3 +37,124 @@ jobs:
- name: Build ${{ matrix.java-version }}
run: mvn -B clean test
+ - name: Rick Roll On Fail
+ if: failure()
+ run: |
+ echo ""
+ cat .github/workflows/rickroll.txt
+
+
+ # Build complet du projet sans exécuter les tests
+ # On compile tous les modules Maven (-DskipTests) sans lancer les tests.
+ - name: build tous les modules
+ run: mvn clean install -DskipTests
+
+
+
+ # Télécharger l'ancien score de mutation du module 'core'
+ # On télécharge l'artefact du précédent pipeline afin de récupérer
+ # le score de mutation précédent (Prec_Score). Cela permet de comparer
+ # le nouveau score avec l’ancien.
+ #
+ # workflow_search: true → cherche dans les workflows précédents
+ # workflow_conclusion: success → seulement les workflows réussis
+ # continue-on-error: true → évite les erreurs lors du tout premier run,
+ # où aucun artefact n’existe encore.
+ - name: Download core-artefact
+ id: download-core-artifact
+ uses: dawidd6/action-download-artifact@v11
+ with:
+ github_token: ${{secrets.GITHUB_TOKEN}}
+ workflow: build.yml
+ workflow_search: true
+ workflow_conclusion: success
+ name: core-artefact-${{ matrix.java-version }}
+ path: core-artefact/
+ continue-on-error: true
+
+ # Exécuter PIT Mutation Testing sur le module 'core'
+ # On génère le rapport PIT pour le module core.
+ # On extrait le pourcentage des mutations "Killed" (score PIT).
+ # On compare le score actuel avec le score stocké dans l’artefact
+ # précédent.
+ # Si le score a baissé -> échec du workflow (exit 1).
+ #
+ # Le fichier "Prec_Score" est mis à jour.
+ - name: Run pitest on core module
+ run: |
+ mvn clean test-compile -pl core org.pitest:pitest-maven:mutationCoverage | tee core/core-score
+
+ Core_Score=$(grep -A15 Statistics core/core-score | grep Killed | grep -oP '\(\K[0-9]+')
+ echo "le score de mutation pour le module core est $Core_Score%"
+
+ if [ -f core-artefact/Prec_Score ]; then
+ Prev_Score=$(cat core-artefact/Prec_Score)
+ else
+ Prev_Score=0
+ fi
+
+ if [ "$Core_Score" -lt "$Prev_Score" ]; then
+ echo "Le score de mutation dans le module core a baisse $Prev_Score% ---> $Core_Score%"
+ exit 1
+ fi
+ echo "ancien score: $Prev_Score%, nouveau_score: $Core_Score%"
+ echo "$Core_Score" > ./Prec_Score
+
+
+
+ # Upload du nouveau score PIT pour le module core
+ # Cela permet d’utiliser ce score lors du prochain pipeline.
+ - name: 'Upload precedent core-score'
+ uses: actions/upload-artifact@v4
+ with:
+ name: core-artefact-${{ matrix.java-version }}
+ path: ./Prec_Score
+
+
+
+ # Télécharger l’ancien score du module reader-gtfs
+ - name: Download reader-artefact
+ id: download-reader-artifact
+ uses: dawidd6/action-download-artifact@v11
+ with:
+ github_token: ${{secrets.GITHUB_TOKEN}}
+ workflow: build.yml
+ workflow_search: true
+ workflow_conclusion: success
+ name: reader-artefact-${{ matrix.java-version }}
+ path: reader-artefact/
+ continue-on-error: true
+
+
+
+ # Exécuter PIT sur le module reader-gtfs
+ - name: Run pitest on reader-gtfs module
+ run: |
+ mvn clean test-compile -pl reader-gtfs org.pitest:pitest-maven:mutationCoverage | tee reader-gtfs/reader-score
+
+ Reader_Score=$(grep -A15 Statistics reader-gtfs/reader-score | grep Killed | grep -oP '\(\K[0-9]+')
+ echo "le score de mutation pour le module reader-gtfs est $Reader_Score%"
+
+ if [ -f reader-artefact/Prec_Score_gtfs ]; then
+ Prev_Score=$(cat reader-artefact/Prec_Score_gtfs)
+ else
+ Prev_Score=0
+ fi
+
+ if [ "$Reader_Score" -lt "$Prev_Score" ]; then
+ echo "Le score de mutation dans le module core a baisse $Prev_Score% ---> $Reader_Score%"
+ exit 1
+ fi
+
+ echo "ancien score: $Prev_Score%, nouveau_score: $Reader_Score%"
+ echo "$Reader_Score" > ./Prec_Score_gtfs
+
+
+ # Upload du nouveau score PIT reader-gtfs
+ - name: 'Upload preccedent reader-score'
+ uses: actions/upload-artifact@v4
+ with:
+ name: reader-artefact-${{ matrix.java-version }}
+ path: ./Prec_Score_gtfs
+
+
diff --git a/.github/workflows/rickroll.txt b/.github/workflows/rickroll.txt
new file mode 100644
index 00000000000..8393f97b488
--- /dev/null
+++ b/.github/workflows/rickroll.txt
@@ -0,0 +1,25 @@
+⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⢿⡿⣿⣿⡿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⣻⣻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣟⡽⣯⣻⣻⡽⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⢿⣻⣻
+⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⢿⡿⣿⣿⣿⣿⣿⣿⡿⣻⣻⣻⣻⣻⣻⡽⣯⣟⢷⠍⠟⠉⠛⢿⢿⣻⣻⢿⣿⣿⣯⣻⡽⣯⣻⣻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣻⢯
+⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣻⣻⣻⣻⡟⡅⠀⠀⠀⠠⠀⠀⠆⡹⣻⣻⡽⣯⣻⡽⣯⣻⡽⣻⣻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣻⣻⣻
+⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣻⣿⡟⡛⡜⡜⣎⢦⢶⣖⡴⡀⠠⣿⣿⣿⣟⣟⣟⣟⣟⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣻⣻⣻⣻
+⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣻⣻⢆⢭⢎⢎⢞⡝⣝⡽⡽⡣⢂⣟⢯⢯⢯⣿⣻⣻⡽⣻⡽⣻⣻⣿⣿⣿⣿⣿⣿⣿⡿⣟⣿⣿⣿⣿⣻
+⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⣟⢧⡒⡔⢆⢯⢎⠚⡜⡇⣼⣿⣿⣯⣻⣻⣻⣻⢯⣿⣿⣻⣻⣻⣻⢿⣿⣿⣿⣿⡿⣻⣻⣻⣟⣿⣿
+⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⢹⢧⢣⢣⠡⡋⡯⣫⢯⡹⣹⣿⣿⣿⣿⣯⣻⣻⣻⣿⣿⣻⣻⣻⣿⣟⣟⢿⣿⣿⣿⣿⣻⢿⣿⣿⣿
+⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠧⢣⢢⢌⣍⡹⡽⣹⣽⣿⣿⣿⣿⣿⡽⣯⣻⢯⣻⢯⣻⣻⣿⣿⣿⣿⣻⣻⣻⣻⢿⢿⣿⣿⣿⣿
+⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣟⡽⣍⢎⢎⢝⢏⢏⣝⢿⣿⣿⣿⣿⣿⣿⣻⡽⣯⣻⣻⣿⣿⣟⢿⣿⢿⣻⣻⣿⣿⢿⣿⣿⣿⣿⣿⣿
+⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⢿⣿⣿⣟⣟⣟⡜⡜⡜⡝⡭⣫⢫⠂⢫⣿⣿⣿⣟⢯⣻⣻⣻⡽⣻⣿⣿⣿⣟⣿⣿⣿⣻⣟⣟⣿⣿⣿⣿⣿⣿⣿
+⣿⣿⣿⣿⢿⡿⣿⢿⡿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⢿⣿⣿⣿⡿⡽⡻⡿⣇⢣⢣⠱⡱⡱⣽⣿⠀⠀⠀⠀⠐⢉⠍⡛⢿⢯⣻⣻⣿⣿⡿⣿⣿⣿⣿⣟⣟⣿⣿⣿⣿⣿⣿⣿⣿
+⣿⣿⣿⣿⣿⣿⣿⣿⣟⢿⣿⣿⣿⡿⣿⣿⣟⢿⣻⣻⡿⣏⢋⠀⠀⠀⣹⣻⡇⢣⠱⣥⣻⣿⡿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢹⣿⣿⣻⣿⣿⣿⣟⣟⣟⡽⣻⣿⡿⡿⣿⣿⣿
+⣿⣿⣿⣿⣿⢿⣿⣿⣿⢿⣻⣿⢿⣿⣿⢿⣻⣻⣻⡃⠀⠀⠀⠀⠀⠀⠠⠠⡣⢢⠱⡉⠙⠛⠄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⣻⡽⣻⣿⢯⣻⣿⣿⢯⣻⣿⣿⣿⣿⣿⣿
+⣿⣿⣿⣿⢿⣻⣻⣿⣟⣟⣟⣿⣿⣿⣿⣿⡿⣟⣟⠄⠀⠀⠀⠀⠀⠀⠀⢀⢆⡑⠡⠉⠋⠖⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⣿⣻⢯⣻⡽⣻⣻⡿⣯⢿⣿⣿⣿⣿⣿
+⣿⣻⣟⣟⣿⣿⣿⣿⣟⣟⣟⣟⣿⣿⣿⣿⣟⣟⡽⡄⠀⠀⠀⠀⠀⠀⠀⢀⠁⣯⠚⠹⠶⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢿⣿⣻⢯⢯⣻⣿⣿⣻⣻⣻⣿⣿⣿⣿⣿
+⣿⣟⢿⣿⣿⣿⣿⣿⣻⣿⡿⣻⣻⣿⣿⣿⢿⣻⢯⠀⠀⠀⠀⠀⠀⠀⠀⠀⠛⣟⠖⡖⡤⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢻⢿⣻⣿⣻⣿⣿⣿⣿⣿⣻⢯⣻⣻⣻
+⣿⣻⣻⣿⣿⣿⣿⣻⣽⣿⣿⣟⣟⢿⣿⣿⡿⣻⣻⠀⠀⠀⠀⠀⠀⠀⠀⠀⢦⢢⣠⣀⠀⠀⠀⠀⠩⡛⡝⡜⡖⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⢿⣿⣻⣿⣿⣿⣿⣿⣿⣿⣿⣿
+⣿⣻⣻⣻⣿⣿⡿⣻⣿⣿⣻⣻⣿⣿⡿⣿⣻⣻⣻⠀⠀⠀⠀⠀⠀⠀⠀⠀⡀⡜⠈⠁⠀⠀⠀⠀⠀⠌⣌⢎⡜⡜⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⣻⣿⣿⡿⣟⢿⣿⣿⣿
+⣟⣿⣿⣿⡽⡽⡽⣻⣹⡽⣿⣿⣿⣻⣻⣻⣻⡽⣻⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⢢⠣⠒⠀⠀⠀⠀⠀⠀⠎⢎⢎⢎⢎⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣟⡽⣿⣿⣻⣻⣻⢿⣿⣿
+⣿⣿⢿⣿⣯⣫⣏⢯⣫⣿⣿⣿⣿⣟⣟⣟⣟⡽⡽⠀⡀⠀⠀⠀⠀⢀⢀⠀⠰⡰⠤⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠂⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⡝⡽⡽⣿⣿⣿⣻⡝⡽
+⣯⣯⣯⣯⢯⣫⢫⣻⡿⣻⣿⣿⣿⣿⣿⣻⡽⡽⣭⠂⠀⡰⡱⠡⠢⢂⠆⠀⢠⠰⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⢯⢫⣫⡿⣻⣿⣿⣿⣻⡹
+⡿⡿⣻⣻⣻⢭⣚⢧⢫⣻⣿⣿⡿⡽⡽⡽⡽⣹⣝⢇⠄⠀⠀⠄⠄⠄⡐⠀⠄⡐⠐⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡝⣝⡽⣹⢽⢯⡻⣻⣟⢯⢫⣚⣟⣟⣟⣟⣟⣟⡝
+⣯⣻⡽⣯⣻⡜⡵⡽⣎⢭⣻⡝⡽⣽⡽⣝⣝⣝⡝⣗⢭⢎⠀⠀⠂⠂⠀⠀⠀⡐⠐⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣹⣝⣝⡝⣝⡽⡽⡹⣚⠵⡭⢯⢯⢯⣻⡽⡽⣣
+⣟⣟⡽⣯⢯⢎⢎⢯⣏⡗⡝⣝⡽⣻⢯⣫⢫⢫⣫⣻⢯⡳⡱⡱⡱⠀⠀⠀⠀⠠⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠐⡝⡝⡝⣝⡝⡝⡭⣫⢫⢭⣚⣝⣝⣝⡽⣹⣹⢧
+⢏⠯⢫⢫⢫⢪⢎⢯⢏⠳⡹⡹⣻⡿⡯⣫⢫⡹⡹⡽⡽⡹⡸⡜⡄⠀⠀⢀⢂⠄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡭⡭⣫⡹⡹⡭⣫⢫⢫⣚⡜⡝⡝⣝⣝⢽⡹⡭
\ No newline at end of file
diff --git a/core/pom.xml b/core/pom.xml
index 64725606c10..478c31874a2 100644
--- a/core/pom.xml
+++ b/core/pom.xml
@@ -164,6 +164,27 @@
false
+
+ org.pitest
+ pitest-maven
+ 1.20.2
+
+
+ com.graphhopper.util.GHUtility
+ com.graphhopper.util.ArrayUtil
+
+
+ com.graphhopper.util.GHUtilityTest
+ com.graphhopper.util.ArrayUtilTest
+
+ 0
+
+ HTML
+ XML
+
+ 4
+
+
diff --git a/core/src/test/java/com/graphhopper/util/ArrayUtilTest.java b/core/src/test/java/com/graphhopper/util/ArrayUtilTest.java
index f22d8a81580..aa8e674493e 100644
--- a/core/src/test/java/com/graphhopper/util/ArrayUtilTest.java
+++ b/core/src/test/java/com/graphhopper/util/ArrayUtilTest.java
@@ -21,10 +21,13 @@
import com.carrotsearch.hppc.IntArrayList;
import org.junit.jupiter.api.Test;
+import java.util.ArrayList;
import java.util.Arrays;
+import java.util.List;
import java.util.Random;
import static com.carrotsearch.hppc.IntArrayList.from;
+import static com.graphhopper.util.ArrayUtil.*;
import static org.junit.jupiter.api.Assertions.*;
class ArrayUtilTest {
@@ -178,4 +181,111 @@ public void testMerge() {
int[] b = {3, 7, 9, 10, 11, 12, 15, 20, 21, 26};
assertEquals(from(2, 3, 6, 7, 8, 9, 10, 11, 12, 15, 20, 21, 26), from(ArrayUtil.merge(a, b)));
}
+
+
+
+
+ /**
+ * TestSublist0
+ * Vérifie qu'une liste vide n a pas de sous liste.
+ * tentative d’extraction d’une sous liste de la liste vide.
+ * une erreur est attendue.
+ */
+ @Test
+ public void TestSublist0() {
+ int[] a = {};
+ IntArrayList aj = IntArrayList.from(a);
+ assertThrows(Error.class, () -> subList(aj, 3, 5));
+
+ }
+
+ /**
+ * TestSublist1
+ * Vérifie que le tableau retournee est correct.
+ * tentative d’extraction d’une sous liste d'une liste donnee
+ * le tableau b1 est attendu
+ */
+ @Test
+ public void TestSublist1() {
+ int[] a = {1,2,3,4,5,6,7,8,9,10};
+ int[] b = {4,5};
+ IntArrayList a1 = IntArrayList.from(a);
+ IntArrayList b1 = IntArrayList.from(b);
+ assertEquals(b1, subList(a1, 3, 5));
+ }
+
+
+ /**
+ * TestSublist2
+ * Vérifie que le tableau retournee est correct.
+ * tentative d’extraction d’une sous liste etant donne que fromIndex et toIndex sont egaux
+ * le tableau b1 est attendu
+ */
+ @Test
+ public void TestSublist2() {
+ int[] a = {1,2,3,4,5,6,7,8,9,10};
+ int[] b = {};
+ IntArrayList a1 = IntArrayList.from(a);
+ IntArrayList b1 = IntArrayList.from(b);
+ assertEquals(b1, subList(a1, 0, 0));
+ }
+
+ /**
+ * testApplyOrder2
+ * Vérifie si le tableau (order)passe en argument est plus grand que le premier tableau (a) une exeption est levee.
+ * un IllegalArgumentException est attendue.
+ */
+ @Test
+ public void testApplyOrder2() {
+ int[] a = {1,2,3,4,5,6,7,8,9,10};
+ int[] b = {1,2,3,4,5,6,7,8,9,10,11};
+ assertThrows(IllegalArgumentException.class, () -> applyOrder(a, b));
+ }
+
+
+ /**
+ * calcSortOrder2
+ * Vérifie si le parametre (length)passe en argument est plus grand que la taille des tableaux une exeption est levee.
+ * un IllegalArgumentException est attendue.
+ */
+ @Test
+ public void testCalcSortOrder2(){
+ int[] a = {1,2,3,4,5,6,7,8,9,10};
+ int[] b = {12,42,387,41,45,69,71,58,98,10};
+ assertThrows(IllegalArgumentException.class, () -> calcSortOrder(a, b, 11));
+
+ }
+
+
+ /**
+ * calcSortOrder3
+ * Vérifie que si les deux tableaux sont de tailles inegales une exeption est levee.
+ * un IllegalArgumentException est attendue.
+ */
+ @Test
+ public void testCalcSortOrder3(){
+ int[] a = {1,2,3,4,5,6,7,8,9,10,11};
+ int[] b = {12,42,387,41,45,69,71,58,98,10};
+ IntArrayList a1 = IntArrayList.from(a);
+ IntArrayList b1 = IntArrayList.from(b);
+ assertThrows(IllegalArgumentException.class, () -> calcSortOrder(a1, b1));
+
+ }
+
+
+
+ /**
+ * TestremoveConsecutiveDuplicates
+ * Vérifie que end est inferieur a zero, une exeption est levee.
+ * un IllegalArgumentException est attendue.
+ */
+ @Test
+ public void TestremoveConsecutiveDuplicates(){
+ int[] a = {1,2,3,4,5,6,7,8,9,10};
+ int b = -1;
+ assertThrows(IllegalArgumentException.class, () -> ArrayUtil.removeConsecutiveDuplicates(a, b));
+
+ }
+
+
}
diff --git a/core/src/test/java/com/graphhopper/util/DownloaderTest.java b/core/src/test/java/com/graphhopper/util/DownloaderTest.java
new file mode 100644
index 00000000000..a8f86237ad7
--- /dev/null
+++ b/core/src/test/java/com/graphhopper/util/DownloaderTest.java
@@ -0,0 +1,44 @@
+package com.graphhopper.util;
+
+import org.junit.jupiter.api.Test;
+import static org.junit.jupiter.api.Assertions.*;
+
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import java.io.*;
+import java.net.HttpURLConnection;
+import static org.mockito.Mockito.*;
+import com.graphhopper.util.Downloader.*;
+
+@ExtendWith(MockitoExtension.class)
+public class DownloaderTest {
+
+ @InjectMocks
+ Downloader downloader;
+
+ @Mock
+ HttpURLConnection connection;
+
+
+ /**
+ * fetchTestNullInputStream
+ * Vérifie que la méthode fetch lance une IOException lorsque
+ * getInputStream() retourne null quand readErrorStreamNoException = false
+ * Données choisies : mock de HttpURLConnection qui renvoie null quand on fait appel
+ * a getInputStream()
+ * La sortie attendue est une IOException
+ */
+ @Test
+ public void fetchTestNullInputStream(){
+ boolean readErrorStreamNoException = false;
+ try {
+ when(connection.getInputStream()).thenReturn(null);
+ assertThrows(IOException.class, ()-> downloader.fetch(connection, readErrorStreamNoException));
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+}
diff --git a/core/src/test/java/com/graphhopper/util/GHUtilityTest.java b/core/src/test/java/com/graphhopper/util/GHUtilityTest.java
index 7d918cf1544..082650caa4c 100644
--- a/core/src/test/java/com/graphhopper/util/GHUtilityTest.java
+++ b/core/src/test/java/com/graphhopper/util/GHUtilityTest.java
@@ -16,6 +16,13 @@
* limitations under the License.
*/
package com.graphhopper.util;
+import com.graphhopper.routing.ev.*;
+import com.graphhopper.routing.util.AccessFilter;
+import com.graphhopper.routing.util.EdgeFilter;
+import com.graphhopper.routing.util.EncodingManager;
+import com.graphhopper.storage.*;
+
+import static com.graphhopper.util.GHUtility.getCommonNode;
import com.graphhopper.coll.GHIntLongHashMap;
import org.junit.jupiter.api.Test;
@@ -27,6 +34,53 @@
*/
public class GHUtilityTest {
+ protected BooleanEncodedValue carAccessEnc = new SimpleBooleanEncodedValue("car_access", true);
+ protected DecimalEncodedValue carSpeedEnc = new DecimalEncodedValueImpl("car_speed", 5, 5, false);
+ protected BooleanEncodedValue footAccessEnc = new SimpleBooleanEncodedValue("foot_access", true);
+ protected DecimalEncodedValue footSpeedEnc = new DecimalEncodedValueImpl("foot_speed", 4, 1, true);
+ protected String defaultGraphLoc = "./target/graphstorage/default";
+ protected BaseGraph graph;
+ EdgeFilter carOutFilter = AccessFilter.outEdges(carAccessEnc);
+ EdgeFilter carInFilter = AccessFilter.inEdges(carAccessEnc);
+ EdgeExplorer carOutExplorer;
+ EdgeExplorer carInExplorer;
+ EdgeExplorer carAllExplorer;
+
+
+
+ protected EncodingManager createEncodingManager() {
+ return new EncodingManager.Builder()
+ .add(carAccessEnc).add(carSpeedEnc)
+ .add(footAccessEnc).add(footSpeedEnc)
+ .add(RoadClass.create())
+ .build();
+ }
+ protected EncodingManager encodingManager = createEncodingManager();
+ protected int defaultSize = 100;
+
+ public BaseGraph createGHStorage(String location, boolean enabled3D) {
+ // reduce segment size in order to test the case where multiple segments come into the game
+ BaseGraph gs = newGHStorage(new RAMDirectory(location), enabled3D, defaultSize / 2);
+ gs.create(defaultSize);
+ return gs;
+ }
+
+ protected BaseGraph createGHStorage() {
+ BaseGraph g = createGHStorage(defaultGraphLoc, false);
+ carOutExplorer = g.createEdgeExplorer(carOutFilter);
+ carInExplorer = g.createEdgeExplorer(carInFilter);
+ carAllExplorer = g.createEdgeExplorer();
+ return g;
+ }
+
+ protected BaseGraph newGHStorage(Directory dir, boolean enabled3D) {
+ return newGHStorage(dir, enabled3D, -1);
+ }
+
+ protected BaseGraph newGHStorage(Directory dir, boolean enabled3D, int segmentSize) {
+ return new BaseGraph.Builder(encodingManager).setDir(dir).set3D(enabled3D).setSegmentSize(segmentSize).build();
+ }
+
@Test
public void testEdgeStuff() {
assertEquals(2, GHUtility.createEdgeKey(1, false));
@@ -64,4 +118,115 @@ public void testZeroValue() {
// assertEquals(1, map2.get(2));
// assertEquals(-1, map2.get(3));
}
+
+ /**
+ * testCommonNodeTrue1
+ * Vérifie que getCommonNode détecte correctement un nœud commun entre deux arêtes.
+ * lorsque le noeud en commun est la base node
+ * Données choisies : arêtes (0->1) et (0->2) partagent le nœud 0.
+ * le nœud commun est 0, qui est le de départ de edge1 et edge2.
+ */
+ @Test
+ public void testCommonNodeTrue1() {
+ BaseGraph graph = createGHStorage();
+ EdgeIteratorState edge1 = graph.edge(0, 1); // Edge 0->1
+ EdgeIteratorState edge2 = graph.edge(edge1.getBaseNode(), 2); // Edge 0->2
+ assertEquals(0, (getCommonNode(graph, edge1.getEdge(), edge2.getEdge())));
+
+ }
+
+ /**
+ * testCommonNodeTrue2
+ * Vérifie que getCommonNode détecte correctement un nœud commun entre deux arêtes.
+ * lorsque le noeud en commun est adjacent
+ * Données choisies : arêtes (0->1) et (2->1) partagent le nœud 1.
+ * le nœud commun est 1, qui est le nœud d’arrivée de edge1 et de départ de edge2.
+ */
+ @Test
+ public void testCommonNodeTrue2() {
+ BaseGraph graph = createGHStorage();
+ EdgeIteratorState edge1 = graph.edge(0, 1); // Edge 0->1
+ EdgeIteratorState edge2 = graph.edge(2, edge1.getAdjNode()); // Edge 2->1
+ assertEquals(1, (getCommonNode(graph, edge1.getEdge(), edge2.getEdge())));
+
+ }
+
+
+ /**
+ * testCommonNodeFalse
+ * Vérifie que getCommonNode lance une exception si les arêtes ne partagent aucun nœud.
+ * Données choisies : arêtes (0->1) et (2->3) n’ont aucun nœud en commun
+ * IllegalArgumentException attendue car aucun nœud commun.
+ */
+ @Test
+ public void testCommonNodeFalse() {
+ BaseGraph graph = createGHStorage();
+ EdgeIteratorState edge1 = graph.edge(0, 1); // Edge 0-1
+ EdgeIteratorState edge2 = graph.edge(edge1.getBaseNode(), 2); // Edge 0-2
+ EdgeIteratorState edge3 = graph.edge(edge2.getAdjNode(),3); //2-3
+ assertThrows(IllegalArgumentException.class, ()-> getCommonNode(graph, edge1.getEdge(), edge3.getEdge()));
+
+ }
+
+
+ /**
+ * TestCircularEdge
+ * Vérifie que l’insertion d’une arête circulaire (0->0) est interdite.
+ * tentative d’ajout d’une arête de 0 vers 0.
+ * IllegalArgumentException attendue car les arêtes circulaires sont invalides, getCommonNode retournera une exection.
+ */
+ @Test
+ public void TestCircularEdge() {
+ BaseGraph graph = createGHStorage();
+ EdgeIteratorState edge2 = graph.edge(0, 1); // Edge 1-2
+ assertThrows(IllegalArgumentException.class, () -> getCommonNode(graph, graph.edge(0, 0).getEdge(), edge2.getEdge()));
+
+ }
+
+
+ /**
+ * TestEdgeThatFormACircle
+ * Vérifie que getCommonNode rejette les arêtes formant un cycle.
+ * Données choisies : arêtes (0->1) et (1->0) forment un cycle.
+ * IllegalArgumentException attendue car les cycles ne sont pas autorisés.
+ * return
+ */
+ @Test
+ public void TestEdgeThatFormACircle() {
+ BaseGraph graph = createGHStorage();
+ EdgeIteratorState edge1 = graph.edge(0, 1);
+ EdgeIteratorState edge2 = graph.edge(1, 0);
+ assertThrows(IllegalArgumentException.class, () -> getCommonNode(graph, edge1.getEdge(), edge2.getEdge()));
+ }
+
+
+ /**
+ * testCommonNodeWithNonExistentEdge
+ * Vérifie que getCommonNode rejette une arête inexistante.
+ * Données choisies : arête valide (0->1) et identifiant d’arête inexistant (14).
+ * IllegalArgumentException attendue car l’arête 14 n’existe pas.
+ */
+ @Test
+ public void testCommonNodeWithNonExistentEdge() {
+ BaseGraph graph = createGHStorage();
+ EdgeIteratorState e1 = graph.edge(0, 1);
+ assertThrows(IllegalArgumentException.class, () -> getCommonNode(graph, e1.getEdge(), 14));
+ }
+
+
+ /**
+ * testCommonNodeSymmetry
+ * Vérifie que getCommonNode est symétrique : l’ordre des arêtes ne change pas le résultat.
+ * Données choisies : arêtes (0->1) et (1->2) partagent le nœud 1.
+ * le nœud commun est le même peu importe l’ordre des arêtes.
+ */
+ @Test
+ public void testCommonNodeSymmetry() {
+ BaseGraph graph = createGHStorage();
+ EdgeIteratorState e1 = graph.edge(0, 1);
+ EdgeIteratorState e2 = graph.edge(1, 2);
+ assertEquals(getCommonNode(graph, e1.getEdge(), e2.getEdge()), getCommonNode(graph, e2.getEdge(), e1.getEdge()));
+ }
+
+
}
diff --git a/ift3913_rapport/tache2_DIABATE_POLZIN.pdf b/ift3913_rapport/tache2_DIABATE_POLZIN.pdf
new file mode 100644
index 00000000000..d6236c5bae1
Binary files /dev/null and b/ift3913_rapport/tache2_DIABATE_POLZIN.pdf differ
diff --git a/ift3913_rapport/tache3.pdf b/ift3913_rapport/tache3.pdf
new file mode 100644
index 00000000000..3b5bbe5693f
Binary files /dev/null and b/ift3913_rapport/tache3.pdf differ
diff --git a/ift3913_rapport/tache3_rapport.md b/ift3913_rapport/tache3_rapport.md
new file mode 100644
index 00000000000..01a6b450d93
--- /dev/null
+++ b/ift3913_rapport/tache3_rapport.md
@@ -0,0 +1,119 @@
+# Tâche 3 - Rapport - MOUSSA DIABATE & POLZIN
+
+Cette tâche portait sur les Github Actions et sur l'utilisation de mocks, grâce à la librairie Mockito.
+
+## Modification du workflow - ajout de Github Actions
+
+Une action permettant de ne pas accepter un "git push" dont le score de mutation est inférieur au score précédent a été ajoutée.
+Pour trouver les scores précédents, nous utilisons les balises : "workflow_search: true" qui va chercher dans les résultats précédents et "workflow_conclusion: success" qui permet de filtrer uniquement les workflow qui ont fonctionnés. Le premier run n'a par définition pas de workflow qui le précède, on utilise alors "continue-on-error: true" pour ce premier tour.
+
+On aimerai désormais générer le score PIT et en extraire les données pertinentes, ici le nombre de mutations tuées, cela grâce à un script shell :
+
+ mvn clean test-compile -pl core org.pitest:pitest-maven:mutationCoverage | tee core/core-score
+
+ Core_Score=$(grep -A15 Statistics core/core-score | grep Killed | grep -oP '\(\K[0-9]+')
+ echo "le score de mutation pour le module core est $Core_Score%"
+
+ if [ -f core-artefact/Prec_Score ]; then
+ Prev_Score=$(cat core-artefact/Prec_Score)
+ else
+ Prev_Score=0
+ fi
+
+ if [ "$Core_Score" -lt "$Prev_Score" ]; then
+ echo "Le score de mutation dans le module core a baisse $Prev_Score% ---> $Core_Score%"
+ exit 1
+ fi
+ echo "ancien score: $Prev_Score%, nouveau_score: $Core_Score%"
+ echo "$Core_Score" > ./Prec_Score
+
+Ce script permet dans un premier temps d'extraire le score de mutation, puis de le comparer au score juste précédent et de prendre une décision en fonction du résultat. Si le score est inférieur, on sort avec "exit 1". Sinon, l'ancien score est mit à jour et prend la valeur du score de mutation calculé.
+
+Ce script ne fonctionne que sur le module "core". Un second script, similaire à celui-ci, permettra de faire la même chose pour le module "reader-gtfs".
+
+Il ne faut pas non plus oublier les artefacts et les mettre à jour : exemple pour le module "core" :
+
+ - name: 'Upload precedent core-score'
+ uses: actions/upload-artifact@v4
+ with:
+ name: core-artefact-${{ matrix.java-version }}
+ path: ./Prec_Score
+
+
+## Mockito
+
+Nous avons utilisé cette librairie dans les classes "HelperTest.java" du module web-api ainsi que "DownloaderTest.java" de la classe "Util" du module "Core".
+Le mock est incontournable pour tester certaines situations. Ici, nous l'utilisons pour tester une fonction qui efface tout un dossier. Nous ne voulons pas effectivement éliminer tous les fichiers, ni en créer expressément pour cette fonction, alors nous utilisons des mocks :
+
+ @InjectMocks
+ Helper helper;
+ @Mock
+ File directory;
+ @Mock
+ File f1;
+ @Mock
+ File f2;
+ @Mock
+ File f3;
+
+ @Test
+ public void testRemoveDirectory() {
+ when(f1.exists()).thenReturn(true);
+ when(f1.delete()).thenReturn(true);
+
+ when(f2.exists()).thenReturn(true);
+ when(f2.delete()).thenReturn(true);
+
+ when(f3.exists()).thenReturn(true);
+ when(f3.delete()).thenReturn(true);
+
+ when(directory.exists()).thenReturn(true);
+ when(directory.delete()).thenReturn(true);
+
+ File[] list = {f1, f2, f3};
+
+ when(directory.isDirectory()).thenReturn(true);
+ when(directory.listFiles()).thenReturn(list);
+
+ assertTrue(removeDir(directory));
+ }
+
+Nous avons besoin de la vraie classe Helper mais allons utiliser des faux paramètres d'entrées de fonctions comme "removeDir" qui attend un paramètre File (pouvant être un dossier). En quelques lignes seulement, nous ne craignons pas avoir effacé des fichiers importants du projet.
+
+De la même manière :
+
+ @InjectMocks
+ Downloader downloader;
+
+ @Mock
+ HttpURLConnection connection;
+
+ @Test
+ public void fetchTestNullInputStream(){
+ boolean readErrorStreamNoException = false;
+ try {
+ when(connection.getInputStream()).thenReturn(null);
+ assertThrows(IOException.class, ()-> downloader.fetch(connection, readErrorStreamNoException));
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+On met en place le mock, on lui dit comment réagir face aux évènements et on vérifie que l'on a bien la réponse attendue. Ici, nous voulons tester le cas où l'utilisateur n'entre rien ou en tout cas une donnée erronée (when(connection.getInputStream()).thenReturn(null)), on s'attend alors à une exception.
+
+## Rickroll
+
+Le but de cette sous tâche est de rickroll l'utilisateur lorsqu'il "git push" et qu'au moins un test ne fonctionne pas.
+
+ - name: Build ${{ matrix.java-version }}
+ run: mvn -B clean test
+
+ - name: Rick Roll On Fail
+ if: failure()
+ run: |
+ echo ""
+ cat .github/workflows/rickroll.txt
+
+Donc lorsqu'un utilisateur push, une suite d'action sont effectuées, en commençant par lancer tous les tests. Au départ, nous avions mit "continue-on-error: true" car nous ne voulions pas que lorsqu'un test fail le reste des tests soient ignorés. Or cela ne change rien, alors en voici une version simplifiée.
+
+On retrouve effectivement un fichier rickroll.txt dans le dossier workflow, il s'agit d'un ASCII Art de Rick Astley. On retrouve ce portrait dans les logs des actions de Github. Le gif en revanche est affiché par URL seulement (comme ci-dessus).
diff --git a/pom.xml b/pom.xml
index dddb459a61e..f05f1eca838 100644
--- a/pom.xml
+++ b/pom.xml
@@ -170,6 +170,26 @@
junit-jupiter-params
test
+
+ com.github.javafaker
+ javafaker
+ 1.0.2
+
+
+
+ org.mockito
+ mockito-junit-jupiter
+ 5.19.0
+ test
+
+
+
+ org.mockito
+ mockito-core
+ 5.20.0
+ test
+
+
@@ -215,6 +235,35 @@
maven-antrun-plugin
1.8
+
+
+
+
+ org.pitest
+ pitest-maven
+ LATEST
+
+
+
+ com.graphhopper.util.ArrayUtil
+ com.graphhopper.util.GHUtility
+ com.graphhopper.gtfs.Transfers
+
+
+
+ com.graphhopper.util.ArrayUtilTest
+ com.graphhopper.util.GHUtilityTest
+ com.graphhopper.gtfs.TransfersTest
+
+
+
+
+ org.pitest
+ pitest-junit5-plugin
+ 1.2.0
+
+
+
diff --git a/reader-gtfs/files/sample-feed/transfers.txt b/reader-gtfs/files/sample-feed/transfers.txt
index d2d082358bb..9c8305e9601 100644
--- a/reader-gtfs/files/sample-feed/transfers.txt
+++ b/reader-gtfs/files/sample-feed/transfers.txt
@@ -2,3 +2,4 @@ from_stop_id,to_stop_id,from_route_id,to_route_id,transfer_type,min_transfer_tim
BEATTY_AIRPORT,BEATTY_AIRPORT,,,2,660
BEATTY_AIRPORT,BEATTY_AIRPORT,,AB,2,0
BEATTY_AIRPORT,BEATTY_AIRPORT,AB,,2,1200
+BULLFROG,BULLFROG,AB,,1,100
diff --git a/reader-gtfs/pom.xml b/reader-gtfs/pom.xml
index 391b10897bd..508377fbe07 100644
--- a/reader-gtfs/pom.xml
+++ b/reader-gtfs/pom.xml
@@ -85,6 +85,27 @@
@{argLine} -Xmx1200m -Xms1200m -Duser.language=en
+
+ org.pitest
+ pitest-maven
+ 1.20.3
+
+
+ org.pitest
+ pitest-junit5-plugin
+ 1.2.3
+
+
+
+
+ com.graphhopper.gtfs.Transfers
+
+
+ com.graphhopper.gtfs.TransfersTest
+
+ true
+
+
diff --git a/reader-gtfs/src/main/java/com/graphhopper/gtfs/Transfers.java b/reader-gtfs/src/main/java/com/graphhopper/gtfs/Transfers.java
index eaef34c3ccd..6baabd9d2db 100644
--- a/reader-gtfs/src/main/java/com/graphhopper/gtfs/Transfers.java
+++ b/reader-gtfs/src/main/java/com/graphhopper/gtfs/Transfers.java
@@ -123,7 +123,7 @@ List getTransfersFromStop(String fromStopId, String fromRouteId) {
final List allOutboundTransfers = transfersFromStop.getOrDefault(fromStopId, Collections.emptyList());
final Map> byToStop = allOutboundTransfers.stream()
.filter(t -> t.transfer_type == 0 || t.transfer_type == 2)
- .filter(t -> t.from_route_id == null || fromRouteId.equals(t.from_route_id))
+ .filter(t -> t.from_route_id == null || (fromRouteId != null && fromRouteId.equals(t.from_route_id)))
.collect(Collectors.groupingBy(t -> t.to_stop_id));
final List result = new ArrayList<>();
byToStop.forEach((toStop, transfers) -> {
diff --git a/reader-gtfs/src/test/java/com/graphhopper/gtfs/TransfersTest.java b/reader-gtfs/src/test/java/com/graphhopper/gtfs/TransfersTest.java
index 6ab180d5da9..ac212663859 100644
--- a/reader-gtfs/src/test/java/com/graphhopper/gtfs/TransfersTest.java
+++ b/reader-gtfs/src/test/java/com/graphhopper/gtfs/TransfersTest.java
@@ -18,7 +18,6 @@
package com.graphhopper.gtfs;
-
import com.conveyal.gtfs.GTFSFeed;
import com.conveyal.gtfs.model.Transfer;
import org.junit.jupiter.api.Assertions;
@@ -26,8 +25,12 @@
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInstance;
+import com.github.javafaker.Faker;
+
import java.io.File;
import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
import static org.junit.jupiter.api.Assertions.*;
@@ -79,4 +82,77 @@ public void testInternalTransfersByToRouteIfRouteSpecific() {
assertEquals("ABBFC", transfersToStop.get(4).from_route_id);
}
+
+ /// We here assure that the filter is working as expected, excluding transfer_type = 1.
+ @Test
+ public void testFiltersGetTransfersFromStop() {
+ // 1st TEST : transfer_type=1 not included : BULLFROG,BULLFROG,AB,,1,100
+ // Line added in transfers.txt, if changed the test won't pass
+ // .filter(t -> t.transfer_type == 0 || t.transfer_type == 2) => FALSE
+ // .filter(t -> t.from_route_id == null || fromRouteId.equals(t.from_route_id)) => FALSE
+ assertEquals(Collections.emptyList(), sampleFeed.getTransfersFromStop("BULLFROG", "BULLFROG"));
+ }
+
+ /// We assure that if fromStopID is wrong, not an existing stop or a null argument,
+ /// the function will return an empty list, as allOutboundTransfers is empty from the beginning.
+ @Test
+ public void testGetTransfersFromStopNotExistingFromStopID() {
+ // 2nd TEST : not an existing fromStopID, or even null
+ assertEquals(Collections.emptyList(), sampleFeed.getTransfersFromStop("TOTO", "AB"));
+ assertEquals(Collections.emptyList(), sampleFeed.getTransfersFromStop(null, "TOTO"));
+ assertEquals(Collections.emptyList(), sampleFeed.getTransfersFromStop("TOTO", null));
+ assertEquals(Collections.emptyList(), sampleFeed.getTransfersFromStop(null, null));
+ }
+
+ @Test
+ public void testGetTransfersFromStopNotExistingFromRouteID() {
+ // 3rd TEST : not an existing fromRouteID, but existing FromStopID
+ assertNotEquals(Collections.emptyList(), sampleFeed.getTransfersFromStop("BEATTY_AIRPORT", null));
+ // if fromRouteId == null, the program fails (fromRouteId.equals in the filter) !
+ assertNotEquals(Collections.emptyList(), sampleFeed.getTransfersFromStop("BEATTY_AIRPORT", "titi"));
+ }
+
+ @Test
+ public void testGetTransfersFromStopGetExistingToStop() {
+ // 4th test : testing different fromRouteId, transfers always existing if valid fromStopId
+ List existingFromRouteID = sampleFeed.getTransfersFromStop("BEATTY_AIRPORT", "AB");
+ List notExistingFromRouteID = sampleFeed.getTransfersFromStop("BEATTY_AIRPORT", "TOTO");
+ assertNotEquals(Collections.emptyList(), existingFromRouteID);
+ assertNotEquals(Collections.emptyList(), notExistingFromRouteID);
+ // fromRouteId can be an imaginary route but cannot be null. We can admit coming from an unknown route as a valid case
+ assertNotEquals(existingFromRouteID, notExistingFromRouteID);
+ }
+
+ @Test
+ public void testWithFaker() {
+ Faker faker = new Faker();
+
+ // arrange
+
+ // initialization of random values
+ String randomRouteId = faker.letterify("RANDOM_????");
+ String knownStopId = "BEATTY_AIRPORT";
+ Transfers transfers = sampleFeed;
+
+ // act
+
+ // real stop, random route.
+ List randomTransfers = transfers.getTransfersFromStop(knownStopId, randomRouteId);
+
+ // asserts
+
+ // as seen before, it should return a non-empty transfer list
+ assertNotEquals(Collections.emptyList(), randomTransfers);
+
+ // every transfer came from the same stop.
+ assertTrue(randomTransfers.stream()
+ .allMatch(t -> knownStopId.equals(t.from_stop_id)),
+ "Every transfers must come from " + knownStopId);
+
+ // Just to know what was created.
+ System.out.println("Random route: " + randomRouteId);
+ System.out.println("Generated transfers: " + randomTransfers.size());
+ }
+
}
+
\ No newline at end of file
diff --git a/web-api/src/test/java/com/graphhopper/util/HelperTest.java b/web-api/src/test/java/com/graphhopper/util/HelperTest.java
index 2e73363f032..e460fef8814 100644
--- a/web-api/src/test/java/com/graphhopper/util/HelperTest.java
+++ b/web-api/src/test/java/com/graphhopper/util/HelperTest.java
@@ -18,18 +18,72 @@
package com.graphhopper.util;
import org.junit.jupiter.api.Test;
-
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
import java.util.Locale;
import static com.graphhopper.util.Helper.UTF_CS;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertThrows;
+import static com.graphhopper.util.Helper.removeDir;
+import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.Mockito.when;
/**
* @author Peter Karich
*/
+@ExtendWith(MockitoExtension.class)
public class HelperTest {
+ @InjectMocks
+ Helper helper;
+ @Mock
+ File directory;
+ @Mock
+ File f1;
+ @Mock
+ File f2;
+ @Mock
+ File f3;
+
+
+ /**
+ * testRemoveDirectory
+ * Verifie que removeDir supprime correctement un repertoire contenant plusieurs fichiers.
+ * Données choisies :
+ * - Répertoire simule contenant trois fichiers (f1, f2, f3).
+ * - Chaque fichier existe et peut être supprime (delete() = true).
+ * - Le repertoire lui-même existe et peut etre supprimé.
+ * Resultat attendu :
+ * - removeDir(directory) retourne true puisque tous les fichiers et le repertoire
+ * sont supprimes avec succes.
+ */
+ @Test
+ public void testRemoveDirectory() {
+ when(f1.exists()).thenReturn(true);
+ when(f1.delete()).thenReturn(true);
+
+ when(f2.exists()).thenReturn(true);
+ when(f2.delete()).thenReturn(true);
+
+ when(f3.exists()).thenReturn(true);
+ when(f3.delete()).thenReturn(true);
+
+ when(directory.exists()).thenReturn(true);
+ when(directory.delete()).thenReturn(true);
+
+ File[] list = {f1, f2, f3};
+
+ when(directory.isDirectory()).thenReturn(true);
+ when(directory.listFiles()).thenReturn(list);
+
+ assertTrue(removeDir(directory));
+ }
+
@Test
public void testElevation() {
assertEquals(9034.1, Helper.uIntToEle(Helper.eleToUInt(9034.1)), .1);
diff --git a/web-api/src/test/java/com/graphhopper/util/PMapTest.java b/web-api/src/test/java/com/graphhopper/util/PMapTest.java
index cb4f4fe4c30..7775ca33853 100644
--- a/web-api/src/test/java/com/graphhopper/util/PMapTest.java
+++ b/web-api/src/test/java/com/graphhopper/util/PMapTest.java
@@ -81,6 +81,9 @@ public void nameAndProperties() {
public void empty() {
assertTrue(new PMap("").toMap().isEmpty());
assertTrue(new PMap("name").toMap().isEmpty());
+
+ // creating an invalid test to rick roll ;)
+ assertFalse(new PMap("name").toMap().isEmpty());
}
}