From 5e1c53f0c96baa739788a32baaa8026ed7c68008 Mon Sep 17 00:00:00 2001 From: Rob Watson Date: Tue, 4 Mar 2025 18:30:59 +0100 Subject: [PATCH] test(integration): test app --- app/app.go | 3 +++ app/integration_test.go | 51 +++++++++++++++++++++++++++++++++++++++++ terminal/terminal.go | 5 ++++ 3 files changed, 59 insertions(+) create mode 100644 app/integration_test.go diff --git a/app/app.go b/app/app.go index 33aeeb4..4b7a909 100644 --- a/app/app.go +++ b/app/app.go @@ -12,12 +12,14 @@ import ( "git.netflux.io/rob/octoplex/mediaserver" "git.netflux.io/rob/octoplex/multiplexer" "git.netflux.io/rob/octoplex/terminal" + "github.com/gdamore/tcell/v2" ) // RunParams holds the parameters for running the application. type RunParams struct { Config config.Config DockerClient container.DockerClient + Screen tcell.Screen ClipboardAvailable bool BuildInfo domain.BuildInfo Logger *slog.Logger @@ -29,6 +31,7 @@ func Run(ctx context.Context, params RunParams) error { logger := params.Logger ui, err := terminal.StartUI(ctx, terminal.StartParams{ + Screen: params.Screen, ClipboardAvailable: params.ClipboardAvailable, BuildInfo: params.BuildInfo, Logger: logger.With("component", "ui"), diff --git a/app/integration_test.go b/app/integration_test.go new file mode 100644 index 0000000..1d35d09 --- /dev/null +++ b/app/integration_test.go @@ -0,0 +1,51 @@ +//go:build integration + +package app_test + +import ( + "context" + "testing" + "time" + + "git.netflux.io/rob/octoplex/app" + "git.netflux.io/rob/octoplex/config" + "git.netflux.io/rob/octoplex/domain" + "git.netflux.io/rob/octoplex/testhelpers" + dockerclient "github.com/docker/docker/client" + "github.com/gdamore/tcell/v2" + "github.com/stretchr/testify/require" +) + +func TestIntegration(t *testing.T) { + ctx, cancel := context.WithCancel(t.Context()) + defer cancel() + + logger := testhelpers.NewTestLogger() + dockerClient, err := dockerclient.NewClientWithOpts(dockerclient.FromEnv) + require.NoError(t, err) + + done := make(chan struct{}) + go func() { + require.NoError(t, app.Run(ctx, app.RunParams{ + Config: config.Config{}, + DockerClient: dockerClient, + Screen: tcell.NewSimulationScreen(""), + ClipboardAvailable: false, + BuildInfo: domain.BuildInfo{Version: "0.0.1", GoVersion: "go1.16.3"}, + Logger: logger, + })) + + done <- struct{}{} + }() + + // For now, just launch the app and wait for a few seconds. + // This is mostly useful to verify there are no obvious data races (when + // running with -race). + // See https://github.com/rivo/tview/wiki/Concurrency. + // + // TODO: test more user journeys. + time.Sleep(time.Second * 5) + cancel() + + <-done +} diff --git a/terminal/terminal.go b/terminal/terminal.go index 9ed2f9b..1933c00 100644 --- a/terminal/terminal.go +++ b/terminal/terminal.go @@ -42,6 +42,7 @@ type StartParams struct { Logger *slog.Logger ClipboardAvailable bool BuildInfo domain.BuildInfo + Screen tcell.Screen } const defaultChanSize = 64 @@ -53,6 +54,10 @@ func StartUI(ctx context.Context, params StartParams) (*UI, error) { app := tview.NewApplication() + // Allow the tcell screen to be overridden for integration tests. If + // params.Screen is nil, the real terminal is used. + app.SetScreen(params.Screen) + sidebar := tview.NewFlex() sidebar.SetDirection(tview.FlexRow)