Phase 1 — Bug fixes (7 bugs): - Bug 1: Pulsar mode data loss — always persist to SQLite regardless of mode - Bug 2: PulsarSend closing TCP client — use independent resetPulsarProducer() - Bug 3: Greedy regex — use non-greedy (?s)ZCZC.*?NNNN - Bug 4: Data after NNNN discarded — keep remaining buffer data - Bug 5: strings.Index > 0 boundary — use strings.Contains - Bug 6: Variable shadowing in PulsarSend — use = not := - Bug 7: Accept failure nil panic — add continue + retry logic Phase 2 — Architecture restructuring: - Split utils/ into config/, serial/, telegram/, storage/, transport/ - Define Sender, Repository, Reader interfaces - Introduce app/ layer with context.Context lifecycle - Replace spinlock with sync.Mutex - Unified Config struct replaces 15+ global vars Phase 3 — Testing & tooling: - telegram/parser_test.go (7 test cases) - storage/store_test.go (5 test cases) - transport/transport_test.go (4 test cases) - Taskfile: add test, test-race, test-cover tasks - Go version: 1.15 -> 1.21
98 lines
1.9 KiB
Go
98 lines
1.9 KiB
Go
package storage
|
|
|
|
import (
|
|
"os"
|
|
"testing"
|
|
)
|
|
|
|
func TestStore_InsertAndCount(t *testing.T) {
|
|
dbFile := "test_telegram.db"
|
|
defer os.Remove(dbFile)
|
|
|
|
s, err := New(dbFile, true)
|
|
if err != nil {
|
|
t.Fatalf("New() failed: %v", err)
|
|
}
|
|
defer s.Close()
|
|
|
|
if err := s.Insert("ZCZC TEST NNNN"); err != nil {
|
|
t.Fatalf("Insert() failed: %v", err)
|
|
}
|
|
|
|
count, err := s.CountUnprocessed()
|
|
if err != nil {
|
|
t.Fatalf("CountUnprocessed() failed: %v", err)
|
|
}
|
|
if count != 1 {
|
|
t.Errorf("expected 1 unprocessed, got %d", count)
|
|
}
|
|
}
|
|
|
|
func TestStore_LoadUnprocessed(t *testing.T) {
|
|
dbFile := "test_load.db"
|
|
defer os.Remove(dbFile)
|
|
|
|
s, err := New(dbFile, true)
|
|
if err != nil {
|
|
t.Fatalf("New() failed: %v", err)
|
|
}
|
|
defer s.Close()
|
|
|
|
s.Insert("ZCZC MSG1 NNNN")
|
|
s.Insert("ZCZC MSG2 NNNN")
|
|
|
|
telegrams, err := s.LoadUnprocessed()
|
|
if err != nil {
|
|
t.Fatalf("LoadUnprocessed() failed: %v", err)
|
|
}
|
|
if len(telegrams) != 2 {
|
|
t.Errorf("expected 2 telegrams, got %d", len(telegrams))
|
|
}
|
|
}
|
|
|
|
func TestStore_MarkProcessed(t *testing.T) {
|
|
dbFile := "test_mark.db"
|
|
defer os.Remove(dbFile)
|
|
|
|
s, err := New(dbFile, true)
|
|
if err != nil {
|
|
t.Fatalf("New() failed: %v", err)
|
|
}
|
|
defer s.Close()
|
|
|
|
s.Insert("ZCZC TEST NNNN")
|
|
|
|
telegrams, _ := s.LoadUnprocessed()
|
|
if len(telegrams) != 1 {
|
|
t.Fatalf("expected 1 telegram, got %d", len(telegrams))
|
|
}
|
|
|
|
if err := s.MarkProcessed(telegrams[0].ID); err != nil {
|
|
t.Fatalf("MarkProcessed() failed: %v", err)
|
|
}
|
|
|
|
count, _ := s.CountUnprocessed()
|
|
if count != 0 {
|
|
t.Errorf("expected 0 unprocessed after marking, got %d", count)
|
|
}
|
|
}
|
|
|
|
func TestStore_Empty(t *testing.T) {
|
|
dbFile := "test_empty.db"
|
|
defer os.Remove(dbFile)
|
|
|
|
s, err := New(dbFile, true)
|
|
if err != nil {
|
|
t.Fatalf("New() failed: %v", err)
|
|
}
|
|
defer s.Close()
|
|
|
|
telegrams, err := s.LoadUnprocessed()
|
|
if err != nil {
|
|
t.Fatalf("LoadUnprocessed() failed: %v", err)
|
|
}
|
|
if len(telegrams) != 0 {
|
|
t.Errorf("expected 0 telegrams, got %d", len(telegrams))
|
|
}
|
|
}
|