Skip to content

Commit eb42e79

Browse files
authored
test: add unit tests for MirrorGenerator and CacheFileLocator (#19)
Add JUnit5 unit tests for the two pure internal logic classes (previously only black-box GradleTestKit functional tests existed): - MirrorGenerator.mirrorsFor: central-host mirror rewriting (apache <-> repo1 + GCS) with path preservation; non-central and malformed URLs return empty. - CacheFileLocator.locate/relativePath: group derivation from the URL, repo-prefix stripping (/maven2/), files-2.1 lookup via a @tempdir fixture, and cache-path splitting. Also wire tasks.test to useJUnitPlatform (previously only functionalTest did). 9 tests, all green locally.
1 parent f697c14 commit eb42e79

3 files changed

Lines changed: 140 additions & 0 deletions

File tree

plugin/build.gradle.kts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,11 @@ tasks {
7878
}
7979
}
8080

81+
// Unit tests (plugin/src/test) use JUnit 5, matching the functional-test suite.
82+
tasks.test {
83+
useJUnitPlatform()
84+
}
85+
8186
gradlePlugin {
8287
website = "https://github.com/meshtastic/gradle-flatpak-sources"
8388
vcsUrl = "https://github.com/meshtastic/gradle-flatpak-sources.git"
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/*
2+
* Copyright (c) 2026 Meshtastic LLC
3+
*
4+
* This program is free software: you can redistribute it and/or modify
5+
* it under the terms of the GNU General Public License as published by
6+
* the Free Software Foundation, either version 3 of the License, or
7+
* (at your option) any later version.
8+
*
9+
* This program is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
* GNU General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU General Public License
15+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
16+
*/
17+
package org.meshtastic.flatpak.sources.internal
18+
19+
import java.io.File
20+
import kotlin.test.Test
21+
import kotlin.test.assertEquals
22+
import kotlin.test.assertNull
23+
import org.junit.jupiter.api.io.TempDir
24+
25+
class CacheFileLocatorTest {
26+
27+
@Test
28+
fun `locate finds the cached file, deriving the group from the URL and stripping the repo prefix`(
29+
@TempDir root: File,
30+
) {
31+
// Gradle files-2.1 layout: <group-with-dots>/<artifact>/<version>/<content-sha1>/<filename>
32+
val jar = File(root, "org.example/lib/1.0/deadbeefcafe/lib-1.0.jar")
33+
jar.parentFile.mkdirs()
34+
jar.writeText("artifact bytes")
35+
36+
// The URL carries a `/maven2/` repo prefix that must be stripped; the group is `org.example`.
37+
val found =
38+
CacheFileLocator.locate(root, "https://repo1.maven.org/maven2/org/example/lib/1.0/lib-1.0.jar")
39+
40+
assertEquals(jar.canonicalFile, found?.canonicalFile)
41+
}
42+
43+
@Test
44+
fun `locate returns null when filesRoot is not a directory`() {
45+
assertNull(
46+
CacheFileLocator.locate(File("/no/such/cache/dir"), "https://repo1.maven.org/maven2/a/b/1.0/b-1.0.jar"),
47+
)
48+
}
49+
50+
@Test
51+
fun `locate returns null when the URL has fewer than three path segments`(@TempDir root: File) {
52+
assertNull(CacheFileLocator.locate(root, "https://repo1.maven.org/a/b"))
53+
}
54+
55+
@Test
56+
fun `relativePath splits a full cache path into group, artifact, version, sha1 and filename`(@TempDir root: File) {
57+
val cacheFile = File(root, "org.example/lib/1.0/deadbeefcafe/lib-1.0.jar")
58+
59+
assertEquals(
60+
listOf("org.example", "lib", "1.0", "deadbeefcafe", "lib-1.0.jar"),
61+
CacheFileLocator.relativePath(root, cacheFile),
62+
)
63+
}
64+
65+
@Test
66+
fun `relativePath returns null for a path with fewer than five components`(@TempDir root: File) {
67+
assertNull(CacheFileLocator.relativePath(root, File(root, "a/b/c")))
68+
}
69+
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/*
2+
* Copyright (c) 2026 Meshtastic LLC
3+
*
4+
* This program is free software: you can redistribute it and/or modify
5+
* it under the terms of the GNU General Public License as published by
6+
* the Free Software Foundation, either version 3 of the License, or
7+
* (at your option) any later version.
8+
*
9+
* This program is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
* GNU General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU General Public License
15+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
16+
*/
17+
package org.meshtastic.flatpak.sources.internal
18+
19+
import kotlin.test.Test
20+
import kotlin.test.assertEquals
21+
import kotlin.test.assertTrue
22+
23+
class MirrorGeneratorTest {
24+
25+
@Test
26+
fun `rewrites the repo1 central host to the apache host plus the GCS mirror, preserving the path`() {
27+
val mirrors =
28+
MirrorGenerator.mirrorsFor("https://repo1.maven.org/maven2/org/example/lib/1.0/lib-1.0.jar")
29+
30+
assertEquals(
31+
listOf(
32+
"https://repo.maven.apache.org/maven2/org/example/lib/1.0/lib-1.0.jar",
33+
"https://maven-central.storage-download.googleapis.com/maven2/org/example/lib/1.0/lib-1.0.jar",
34+
),
35+
mirrors,
36+
)
37+
}
38+
39+
@Test
40+
fun `rewrites the apache central host to repo1 plus the GCS mirror`() {
41+
val mirrors =
42+
MirrorGenerator.mirrorsFor("https://repo.maven.apache.org/maven2/a/b/1.0/b-1.0.pom")
43+
44+
assertEquals(
45+
listOf(
46+
"https://repo1.maven.org/maven2/a/b/1.0/b-1.0.pom",
47+
"https://maven-central.storage-download.googleapis.com/maven2/a/b/1.0/b-1.0.pom",
48+
),
49+
mirrors,
50+
)
51+
}
52+
53+
@Test
54+
fun `returns no mirrors for non-central hosts`() {
55+
// Google, JitPack and the Gradle plugin portal have no well-known public mirrors.
56+
assertTrue(MirrorGenerator.mirrorsFor("https://jitpack.io/com/github/x/y/1.0/y-1.0.jar").isEmpty())
57+
assertTrue(MirrorGenerator.mirrorsFor("https://dl.google.com/dl/android/maven2/a/b/1.0/b.aar").isEmpty())
58+
assertTrue(MirrorGenerator.mirrorsFor("https://plugins.gradle.org/m2/p/p.jar").isEmpty())
59+
}
60+
61+
@Test
62+
fun `returns no mirrors for a malformed or hostless URL`() {
63+
assertTrue(MirrorGenerator.mirrorsFor("not a valid url").isEmpty())
64+
assertTrue(MirrorGenerator.mirrorsFor("").isEmpty())
65+
}
66+
}

0 commit comments

Comments
 (0)