weeks of bullshit

This commit is contained in:
Relism
2026-04-17 08:18:11 +02:00
parent b5d4481502
commit 9efbe38c0c
157 changed files with 5171 additions and 1273 deletions
@@ -0,0 +1,39 @@
package dev.relism.ext.webbundler;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
import java.nio.file.Files;
import java.nio.file.Path;
import static org.junit.jupiter.api.Assertions.*;
class AssetsSourceTest {
@TempDir
Path tempDir;
@Test
void filesystemSource_loadsAssetsAndIndex() throws Exception {
Path webRoot = tempDir.resolve("web");
Path dist = webRoot.resolve("dist");
Files.createDirectories(dist);
Files.writeString(dist.resolve("index.html"), "<html>ok</html>");
Files.writeString(dist.resolve("app.abcd1234.js"), "console.log(1)");
AssetsSource source = FilesystemAssetsSource.of(Path.of("dist"));
AssetCatalog catalog = source.load(new AssetLoadRequest("/app", "index.html", RuntimeEnvironment.PROD, webRoot));
assertNotNull(catalog.index());
AssetEntry js = catalog.find("/app/app.abcd1234.js");
assertNotNull(js);
assertTrue(js.immutable());
}
@Test
void classpathSource_missingManifestFailsFast() {
AssetsSource source = ClasspathAssetsSource.of("missing-root");
IllegalStateException ex = assertThrows(IllegalStateException.class,
() -> source.load(new AssetLoadRequest("/", "index.html", RuntimeEnvironment.PROD, Path.of("."))));
assertTrue(ex.getMessage().contains("manifest"));
}
}
@@ -0,0 +1,30 @@
package dev.relism.ext.webbundler;
import org.junit.jupiter.api.Test;
import java.util.List;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertThrows;
class CommandSafetyPolicyTest {
@Test
void block_mode_rejectsUnknownBinary() {
WebBundlerConfig cfg = WebBundlerConfig.builder()
.commandSafetyMode(CommandSafetyMode.BLOCK)
.safeCommandRegistry(List.of("npm"))
.build();
CommandSafetyPolicy policy = new CommandSafetyPolicy(cfg);
assertThrows(IllegalStateException.class, () -> policy.check(List.of("sh", "-c", "echo nope")));
}
@Test
void allow_mode_permitsUnknownBinary() {
WebBundlerConfig cfg = WebBundlerConfig.builder()
.commandSafetyMode(CommandSafetyMode.ALLOW)
.safeCommandRegistry(List.of("npm"))
.build();
CommandSafetyPolicy policy = new CommandSafetyPolicy(cfg);
assertDoesNotThrow(() -> policy.check(List.of("custom", "run")));
}
}
@@ -0,0 +1,29 @@
package dev.relism.ext.webbundler;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
import java.nio.file.Files;
import java.nio.file.Path;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
class InstallCacheTest {
@TempDir
Path tempDir;
@Test
void lockHashChanges_areDetected() throws Exception {
Path lockfile = tempDir.resolve("package-lock.json");
Files.writeString(lockfile, "{\"a\":1}");
InstallCache cache = new InstallCache(tempDir);
assertTrue(cache.lockChanged(lockfile));
cache.writeLockHash(lockfile);
assertFalse(cache.lockChanged(lockfile));
Files.writeString(lockfile, "{\"a\":2}");
assertTrue(cache.lockChanged(lockfile));
}
}
@@ -0,0 +1,17 @@
package dev.relism.ext.webbundler;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
class ModeResolverTest {
private final ModeResolver resolver = new ModeResolver();
@Test
void prod_mode_isAlwaysProd() {
WebBundlerConfig cfg = WebBundlerConfig.builder()
.runtimeMode(RuntimeMode.PROD)
.build();
assertEquals(RuntimeEnvironment.PROD, resolver.resolve(cfg));
}
}
@@ -0,0 +1,18 @@
package dev.relism.ext.webbundler;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
class PackageManagerAdapterTest {
@Test
void pnpm_hasFrozenInstallCommand() {
WebBundlerConfig cfg = WebBundlerConfig.builder()
.packageManager(PackageManager.PNPM)
.build();
PackageManagerAdapter adapter = new PackageManagerAdapter(cfg);
assertTrue(adapter.installCommand().get(0).startsWith("pnpm"));
assertEquals("--frozen-lockfile", adapter.installCommand().get(2));
}
}
@@ -0,0 +1,58 @@
package dev.relism.ext.webbundler;
import org.junit.jupiter.api.Test;
import java.nio.file.Path;
import java.util.List;
import static org.junit.jupiter.api.Assertions.*;
class WebBundlerConfigTest {
@Test
void defaults_areSane() {
WebBundlerConfig cfg = WebBundlerConfig.builder().build();
assertEquals(RuntimeMode.AUTODETECT, cfg.runtimeMode());
assertEquals(OperationMode.ORCHESTRATE_ONLY, cfg.operationMode());
assertEquals(InstallPolicy.AUTO_IF_LOCK_HASH_CHANGED, cfg.installPolicy());
assertEquals(LoggingMode.MERGED, cfg.loggingMode());
assertEquals(CommandSafetyMode.WARN, cfg.commandSafetyMode());
}
@Test
void packageManager_setsLockfileInWatchList() {
WebBundlerConfig cfg = WebBundlerConfig.builder()
.packageManager(PackageManager.PNPM)
.build();
assertTrue(cfg.watchList().contains("pnpm-lock.yaml"));
}
@Test
void basePath_isNormalized() {
WebBundlerConfig cfg = WebBundlerConfig.builder().basePath("app/").build();
assertEquals("/app", cfg.basePath());
}
@Test
void invalidPort_throws() {
assertThrows(IllegalArgumentException.class, () ->
WebBundlerConfig.builder().devPort(0).build());
}
@Test
void assetsFromFilesystem_setsFilesystemSource() {
WebBundlerConfig cfg = WebBundlerConfig.builder()
.webRoot(Path.of("frontend"))
.assetsFromFilesystem(Path.of("build"))
.watchList(List.of("package.json"))
.build();
assertTrue(cfg.assetsSource() instanceof FilesystemAssetsSource);
}
@Test
void assetsFromClasspath_setsClasspathSource() {
WebBundlerConfig cfg = WebBundlerConfig.builder()
.assetsFromClasspath("web/dist")
.build();
assertTrue(cfg.assetsSource() instanceof ClasspathAssetsSource);
}
}
@@ -0,0 +1,16 @@
package dev.relism.ext.webbundler;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertThrows;
class WebBundlerExtensionDevGuardTest {
@Test
void classpathSourceInDev_isRejected() {
WebBundlerConfig cfg = WebBundlerConfig.builder()
.assetsFromClasspath("web/dist")
.build();
assertThrows(IllegalStateException.class, () -> WebBundlerExtension.validateDevAssetsSource(cfg));
}
}
@@ -0,0 +1,80 @@
package dev.relism.ext.webbundler;
import dev.relism.extension.FlashApp;
import dev.relism.extension.FlashConfiguration;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
import java.net.ServerSocket;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.file.Files;
import java.nio.file.Path;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
class WebBundlerExtensionIntegrationTest {
@TempDir
Path tempDir;
private FlashApp app;
@AfterEach
void tearDown() {
if (app != null) app.stop();
}
@Test
void prodMode_servesAssetsAndFallback_withoutBreakingBackendRoutes() throws Exception {
Path webRoot = tempDir.resolve("web");
Path dist = webRoot.resolve("dist");
Files.createDirectories(dist);
Files.writeString(dist.resolve("index.html"), "<html>spa</html>");
Files.writeString(dist.resolve("app.js"), "console.log('ok');");
int port;
try (ServerSocket s = new ServerSocket(0)) {
port = s.getLocalPort();
}
WebBundlerConfig config = WebBundlerConfig.builder()
.runtimeMode(RuntimeMode.PROD)
.operationMode(OperationMode.MANAGED)
.webRoot(webRoot)
.assetsFromFilesystem(Path.of("dist"))
.basePath("/app")
.build();
app = FlashApp.create(FlashConfiguration.builder().port(port).host("127.0.0.1").build());
app.install(new WebBundlerExtension(config));
app.get("/api/ping", (req, res) -> "pong");
app.start();
HttpClient client = HttpClient.newHttpClient();
HttpResponse<String> backend = client.send(
HttpRequest.newBuilder(URI.create("http://127.0.0.1:" + port + "/api/ping")).GET().build(),
HttpResponse.BodyHandlers.ofString()
);
assertEquals(200, backend.statusCode());
assertEquals("pong", backend.body());
HttpResponse<String> asset = client.send(
HttpRequest.newBuilder(URI.create("http://127.0.0.1:" + port + "/app/app.js")).GET().build(),
HttpResponse.BodyHandlers.ofString()
);
assertEquals(200, asset.statusCode());
assertTrue(asset.body().contains("console.log"));
HttpResponse<String> fallback = client.send(
HttpRequest.newBuilder(URI.create("http://127.0.0.1:" + port + "/app/some/client/route")).GET().build(),
HttpResponse.BodyHandlers.ofString()
);
assertEquals(200, fallback.statusCode());
assertTrue(fallback.body().contains("spa"));
}
}