✨ Add basic implementation of “info window”
authorDavid Roden <github-a8in@qsheltier.de>
Sat, 25 Jan 2025 23:14:00 +0000 (00:14 +0100)
committerDavid Roden <github-a8in@qsheltier.de>
Sun, 26 Jan 2025 10:03:52 +0000 (11:03 +0100)
server/src/main/java/de/qsheltier/msta/Server.java
server/src/test/java/de/qsheltier/msta/ServerTest.java

index 1924744..16c2ade 100644 (file)
@@ -139,7 +139,7 @@ public class Server implements Closeable {
                                                        .filter(window -> !lastOpenWindows.contains(window))
                                                        .toList();
                                        openWindows.stream()
-                                                       .map(window -> createEvent("new-window"))
+                                                       .map(window -> createEvent("new-window", new Pair("id", window.getName())))
                                                        .forEach(writeLine);
 
                                        var openFrames = allWindows.stream()
@@ -148,7 +148,7 @@ public class Server implements Closeable {
                                                        .filter(frame -> !lastOpenFrames.contains(frame))
                                                        .toList();
                                        openFrames.stream()
-                                                       .map(frame -> createEvent("new-frame"))
+                                                       .map(frame -> createEvent("new-frame", new Pair("id", frame.getName())))
                                                        .forEach(writeLine);
 
                                        lastOpenWindows.addAll(openWindows);
@@ -162,19 +162,30 @@ public class Server implements Closeable {
                        }).start();
                        String line;
                        while ((line = inputReader.readLine()) != null) {
-                               if (line.equalsIgnoreCase("shutdown")) {
+                               var words = stream(line.split(" ")).toList();
+                               if (words.getFirst().equalsIgnoreCase("shutdown")) {
                                        shutdownHook.run();
                                        break;
                                }
+                               if (words.getFirst().equalsIgnoreCase("info") && (words.size() == 3) && words.get(1).equalsIgnoreCase("window")) {
+                                       var windowName = words.get(2);
+                                       stream(Window.getWindows()).filter(window -> window.getName().equals(windowName))
+                                                       .forEach(window -> writeLine.accept(createMessage(new Pair("info", "window"), new Pair("id", window.getName()))));
+                               }
                        }
                } finally {
                        finished.set(true);
                }
        }
 
-       private String createEvent(String name) {
+       private String createEvent(String name, Pair... parameters) {
+               return createMessage(new Pair("event", name), parameters);
+       }
+
+       private String createMessage(Pair messageName, Pair... parameters) {
                Map<String, Object> reply = new HashMap<>();
-               reply.put("event", name);
+               reply.put(messageName.first, messageName.second);
+               stream(parameters).forEach(pair -> reply.put(pair.first, pair.second));
                try {
                        return objectMapper.writeValueAsString(reply);
                } catch (JsonProcessingException e) {
@@ -187,4 +198,16 @@ public class Server implements Closeable {
        private final Runnable shutdownHook;
        private final AtomicBoolean closed = new AtomicBoolean(false);
 
+       private static class Pair {
+
+               public Pair(String first, String second) {
+                       this.first = first;
+                       this.second = second;
+               }
+
+               private final String first;
+               private final String second;
+
+       }
+
 }
index 059160f..e850046 100644 (file)
@@ -1,5 +1,6 @@
 package de.qsheltier.msta;
 
+import com.fasterxml.jackson.databind.ObjectMapper;
 import java.awt.Frame;
 import java.awt.Window;
 import java.io.BufferedReader;
@@ -17,6 +18,7 @@ import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.Timeout;
 
 import static com.spotify.hamcrest.jackson.JsonMatchers.isJsonStringMatching;
+import static com.spotify.hamcrest.jackson.JsonMatchers.jsonMissing;
 import static com.spotify.hamcrest.jackson.JsonMatchers.jsonObject;
 import static com.spotify.hamcrest.jackson.JsonMatchers.jsonText;
 import static java.nio.charset.StandardCharsets.UTF_8;
@@ -114,6 +116,28 @@ public class ServerTest {
                }
        }
 
+       @Test
+       @Timeout(value = 5, unit = TimeUnit.SECONDS, threadMode = SEPARATE_THREAD)
+       public void windowInfoContainsButtonInfo() throws Throwable {
+               var window = new Window(null);
+               window.setVisible(true);
+               try {
+                       connectToServer(verifyConnectedEvent((reader, writer) -> {
+                               var reply = objectMapper.readTree(reader.get());
+                               assertThat(reply, jsonObject().where("event", jsonText("new-window")).where("id", not(jsonMissing())));
+                               var windowName = reply.get("id").asText();
+                               writer.accept("info window " + windowName);
+                               reply = objectMapper.readTree(reader.get());
+                               assertThat(reply, jsonObject()
+                                               .where("info", jsonText("window"))
+                                               .where("id", jsonText(windowName))
+                               );
+                       }));
+               } finally {
+                       window.setVisible(false);
+               }
+       }
+
        private static ThrowingBiConsumer<Supplier<String>, Consumer<String>> verifyConnectedEvent(ThrowingBiConsumer<Supplier<String>, Consumer<String>> connectionConsumer) {
                return (reader, writer) -> {
                        assertThat(reader.get(), isJsonStringMatching(jsonObject().where("event", jsonText("connected"))));
@@ -149,6 +173,8 @@ public class ServerTest {
                }
        }
 
+       private final ObjectMapper objectMapper = new ObjectMapper();
+
        private interface ThrowingBiConsumer<A, B> {
                void accept(A a, B b) throws Exception;
        }