mirror of
https://github.com/Xevion/go-ha.git
synced 2025-12-06 15:15:14 -06:00
196 lines
4.0 KiB
Go
196 lines
4.0 KiB
Go
package gomeassistant
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func TestAppClose(t *testing.T) {
|
|
// Create a new app with minimal configuration
|
|
app := &App{
|
|
ctx: context.Background(),
|
|
ctxCancel: func() {}, // No-op cancel function for test
|
|
}
|
|
|
|
// Test that Close() doesn't panic
|
|
err := app.Close()
|
|
if err != nil {
|
|
t.Errorf("Close() returned error: %v", err)
|
|
}
|
|
}
|
|
|
|
func TestAppCloseWithContext(t *testing.T) {
|
|
// Create a context with cancel function
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
|
|
app := &App{
|
|
ctx: ctx,
|
|
ctxCancel: cancel,
|
|
}
|
|
|
|
// Test that Close() cancels the context
|
|
err := app.Close()
|
|
if err != nil {
|
|
t.Errorf("Close() returned error: %v", err)
|
|
}
|
|
|
|
// Verify context was cancelled
|
|
select {
|
|
case <-ctx.Done():
|
|
// Context was cancelled as expected
|
|
default:
|
|
t.Error("Context was not cancelled by Close()")
|
|
}
|
|
}
|
|
|
|
func TestAppCloseWithTimeout(t *testing.T) {
|
|
// Create a context with timeout
|
|
ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond)
|
|
defer cancel()
|
|
|
|
app := &App{
|
|
ctx: ctx,
|
|
ctxCancel: cancel,
|
|
}
|
|
|
|
// Test that Close() works with timeout context
|
|
err := app.Close()
|
|
if err != nil {
|
|
t.Errorf("Close() returned error: %v", err)
|
|
}
|
|
}
|
|
|
|
func TestAppCleanup(t *testing.T) {
|
|
// Test the legacy Cleanup method
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
|
|
app := &App{
|
|
ctx: ctx,
|
|
ctxCancel: cancel,
|
|
}
|
|
|
|
// Test that Cleanup() doesn't panic
|
|
app.Cleanup()
|
|
|
|
// Verify context was cancelled
|
|
select {
|
|
case <-ctx.Done():
|
|
// Context was cancelled as expected
|
|
default:
|
|
t.Error("Context was not cancelled by Cleanup()")
|
|
}
|
|
}
|
|
|
|
func TestAppGetService(t *testing.T) {
|
|
// Test GetService method
|
|
app := &App{
|
|
service: &Service{},
|
|
}
|
|
|
|
service := app.GetService()
|
|
if service == nil {
|
|
t.Error("GetService() returned nil")
|
|
}
|
|
}
|
|
|
|
func TestAppGetState(t *testing.T) {
|
|
// Test GetState method
|
|
app := &App{
|
|
state: &StateImpl{},
|
|
}
|
|
|
|
state := app.GetState()
|
|
if state == nil {
|
|
t.Error("GetState() returned nil")
|
|
}
|
|
}
|
|
|
|
func TestAppWithNilFields(t *testing.T) {
|
|
// Test app with nil fields to ensure no panics
|
|
app := &App{}
|
|
|
|
// Test Close with nil fields
|
|
err := app.Close()
|
|
if err != nil {
|
|
t.Errorf("Close() returned error: %v", err)
|
|
}
|
|
|
|
// Test Cleanup with nil fields
|
|
app.Cleanup()
|
|
|
|
// Test GetService with nil service
|
|
service := app.GetService()
|
|
if service != nil {
|
|
t.Error("GetService() should return nil when service is nil")
|
|
}
|
|
|
|
// Test GetState with nil state
|
|
state := app.GetState()
|
|
// When state is nil, GetState returns a typed nil (*StateImpl)
|
|
// This is the correct behavior - the interface is not nil but the value is nil
|
|
_ = state // Just ensure it doesn't panic
|
|
}
|
|
|
|
func TestAppWithWebsocketConnection(t *testing.T) {
|
|
// Test app with WebSocket connection (mocked)
|
|
app := &App{
|
|
ctx: context.Background(),
|
|
ctxCancel: func() {},
|
|
conn: nil, // In real test, this would be a mock WebSocket
|
|
}
|
|
|
|
// Test that Close() handles nil connection gracefully
|
|
err := app.Close()
|
|
if err != nil {
|
|
t.Errorf("Close() returned error: %v", err)
|
|
}
|
|
}
|
|
|
|
func TestAppRegisterMethods(t *testing.T) {
|
|
// Test that register methods don't panic with empty app
|
|
app := &App{
|
|
entityListeners: make(map[string][]*EntityListener),
|
|
eventListeners: make(map[string][]*EventListener),
|
|
}
|
|
|
|
// Test registering empty schedules
|
|
app.RegisterSchedules()
|
|
|
|
// Test registering empty intervals
|
|
app.RegisterIntervals()
|
|
|
|
// Test registering empty entity listeners
|
|
app.RegisterEntityListeners()
|
|
|
|
// Test registering empty event listeners
|
|
app.RegisterEventListeners()
|
|
}
|
|
|
|
func TestAppContextCancellation(t *testing.T) {
|
|
// Test that context cancellation works properly
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
|
|
app := &App{
|
|
ctx: ctx,
|
|
ctxCancel: cancel,
|
|
}
|
|
|
|
// Cancel context manually
|
|
cancel()
|
|
|
|
// Verify context is done
|
|
select {
|
|
case <-ctx.Done():
|
|
// Expected
|
|
default:
|
|
t.Error("Context should be cancelled")
|
|
}
|
|
|
|
// Test Close after manual cancellation
|
|
err := app.Close()
|
|
if err != nil {
|
|
t.Errorf("Close() returned error: %v", err)
|
|
}
|
|
}
|