rs2322tcp/internal/client/application_test.go
2026-08-11 10:59:46 +02:00

157 lines
4.2 KiB
Go

/*
* ============================================================================
* Projekt.....: rs2322tcp
* Datei.......: internal/client/application_test.go
* Copyright (C) 2026 Dieter Lang
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
* Beschreibung:
* Tests für die Anwendungsschicht des rs2322tcp-Clients.
*
* Die Tests prüfen zunächst den Lebenszyklus der Application, ohne dafür
* eine echte Serververbindung aufbauen zu müssen.
*
* Insbesondere wird sichergestellt, dass eine neu erzeugte Application
* zunächst keinen laufenden Client und keine laufende Runtime besitzt und
* dass Close auch vor einem Start sicher verwendet werden kann.
* ============================================================================
*/
package client
import "testing"
///////////////////////////////////////////////////////////////////////////////
// NewApplication
///////////////////////////////////////////////////////////////////////////////
// TestNewApplicationRejectsEmptyConfigFile verifies that an empty
// configuration-file path is rejected.
func TestNewApplicationRejectsEmptyConfigFile(t *testing.T) {
t.Helper()
application, err := NewApplication("")
if err == nil {
t.Fatal("NewApplication with empty config file returned no error")
}
if application != nil {
t.Fatal("NewApplication with empty config file returned an application")
}
}
// TestNewApplication verifies that a valid configuration-file path creates
// an application without starting it.
func TestNewApplication(t *testing.T) {
t.Helper()
application, err := NewApplication("client.json")
if err != nil {
t.Fatalf("NewApplication: %v", err)
}
if application == nil {
t.Fatal("NewApplication returned nil application")
}
if application.Running() {
t.Fatal("new application reports running")
}
if application.Config() != nil {
t.Fatal("new application returned a configuration")
}
if devices := application.Devices(); len(devices) != 0 {
t.Fatalf(
"new application returned %d devices",
len(devices),
)
}
}
///////////////////////////////////////////////////////////////////////////////
// Close
///////////////////////////////////////////////////////////////////////////////
// TestApplicationCloseBeforeStart verifies that Close can safely be called
// before the application has been started.
func TestApplicationCloseBeforeStart(t *testing.T) {
t.Helper()
application, err := NewApplication("client.json")
if err != nil {
t.Fatalf("NewApplication: %v", err)
}
if err := application.Close(); err != nil {
t.Fatalf("Close before Start: %v", err)
}
if application.Running() {
t.Fatal("application reports running after Close")
}
}
// TestApplicationCloseIsIdempotent verifies that Close can be called more
// than once without producing an error.
func TestApplicationCloseIsIdempotent(t *testing.T) {
t.Helper()
application, err := NewApplication("client.json")
if err != nil {
t.Fatalf("NewApplication: %v", err)
}
if err := application.Close(); err != nil {
t.Fatalf("first Close: %v", err)
}
if err := application.Close(); err != nil {
t.Fatalf("second Close: %v", err)
}
if application.Running() {
t.Fatal("application reports running after repeated Close")
}
}
///////////////////////////////////////////////////////////////////////////////
// Nil receiver
///////////////////////////////////////////////////////////////////////////////
// TestNilApplication verifies that the public lifecycle methods behave
// safely when called on a nil Application receiver.
//
// This is deliberately a small defensive test. The GUI should normally
// never operate on a nil Application.
func TestNilApplication(t *testing.T) {
t.Helper()
var application *Application
if err := application.Start(); err == nil {
t.Fatal("nil Application Start returned no error")
}
if err := application.Reconnect(); err == nil {
t.Fatal("nil Application Reconnect returned no error")
}
if err := application.Close(); err != nil {
t.Fatalf("nil Application Close: %v", err)
}
if application.Running() {
t.Fatal("nil Application reports running")
}
if application.Config() != nil {
t.Fatal("nil Application returned a configuration")
}
if devices := application.Devices(); devices != nil {
t.Fatal("nil Application returned devices")
}
}