Add four new infrastructure packages with CLI commands: - pkg/config: layered configuration (defaults → file → env → flags) - pkg/crypt: crypto primitives (Argon2id, AES-GCM, ChaCha20, HMAC, checksums) - pkg/plugin: plugin system with GitHub-based install/update/remove - pkg/collect: collection subsystem (GitHub, BitcoinTalk, market, papers, excavate) Fix all golangci-lint issues across the entire codebase (~100 errcheck, staticcheck SA1012/SA1019/ST1005, unused, ineffassign fixes) so that `core go qa` passes with 0 issues. Closes #167, #168, #170, #250, #251, #252, #253, #254, #255, #256 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
133 lines
3.2 KiB
Go
133 lines
3.2 KiB
Go
package collect
|
|
|
|
import (
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
)
|
|
|
|
func TestDispatcher_Emit_Good(t *testing.T) {
|
|
d := NewDispatcher()
|
|
|
|
var received Event
|
|
d.On(EventStart, func(e Event) {
|
|
received = e
|
|
})
|
|
|
|
d.Emit(Event{
|
|
Type: EventStart,
|
|
Source: "test",
|
|
Message: "hello",
|
|
})
|
|
|
|
assert.Equal(t, EventStart, received.Type)
|
|
assert.Equal(t, "test", received.Source)
|
|
assert.Equal(t, "hello", received.Message)
|
|
assert.False(t, received.Time.IsZero(), "Time should be set automatically")
|
|
}
|
|
|
|
func TestDispatcher_On_Good(t *testing.T) {
|
|
d := NewDispatcher()
|
|
|
|
var count int
|
|
handler := func(e Event) { count++ }
|
|
|
|
d.On(EventProgress, handler)
|
|
d.On(EventProgress, handler)
|
|
d.On(EventProgress, handler)
|
|
|
|
d.Emit(Event{Type: EventProgress, Source: "test"})
|
|
assert.Equal(t, 3, count, "All three handlers should be called")
|
|
}
|
|
|
|
func TestDispatcher_Emit_Good_NoHandlers(t *testing.T) {
|
|
d := NewDispatcher()
|
|
|
|
// Should not panic when emitting an event with no handlers
|
|
assert.NotPanics(t, func() {
|
|
d.Emit(Event{
|
|
Type: "unknown-event",
|
|
Source: "test",
|
|
Message: "this should be silently dropped",
|
|
})
|
|
})
|
|
}
|
|
|
|
func TestDispatcher_Emit_Good_MultipleEventTypes(t *testing.T) {
|
|
d := NewDispatcher()
|
|
|
|
var starts, errors int
|
|
d.On(EventStart, func(e Event) { starts++ })
|
|
d.On(EventError, func(e Event) { errors++ })
|
|
|
|
d.Emit(Event{Type: EventStart, Source: "test"})
|
|
d.Emit(Event{Type: EventStart, Source: "test"})
|
|
d.Emit(Event{Type: EventError, Source: "test"})
|
|
|
|
assert.Equal(t, 2, starts)
|
|
assert.Equal(t, 1, errors)
|
|
}
|
|
|
|
func TestDispatcher_Emit_Good_SetsTime(t *testing.T) {
|
|
d := NewDispatcher()
|
|
|
|
var received Event
|
|
d.On(EventItem, func(e Event) {
|
|
received = e
|
|
})
|
|
|
|
before := time.Now()
|
|
d.Emit(Event{Type: EventItem, Source: "test"})
|
|
after := time.Now()
|
|
|
|
assert.True(t, received.Time.After(before) || received.Time.Equal(before))
|
|
assert.True(t, received.Time.Before(after) || received.Time.Equal(after))
|
|
}
|
|
|
|
func TestDispatcher_Emit_Good_PreservesExistingTime(t *testing.T) {
|
|
d := NewDispatcher()
|
|
|
|
customTime := time.Date(2025, 6, 15, 12, 0, 0, 0, time.UTC)
|
|
var received Event
|
|
d.On(EventItem, func(e Event) {
|
|
received = e
|
|
})
|
|
|
|
d.Emit(Event{Type: EventItem, Source: "test", Time: customTime})
|
|
assert.True(t, customTime.Equal(received.Time))
|
|
}
|
|
|
|
func TestDispatcher_EmitHelpers_Good(t *testing.T) {
|
|
d := NewDispatcher()
|
|
|
|
events := make(map[string]Event)
|
|
for _, eventType := range []string{EventStart, EventProgress, EventItem, EventError, EventComplete} {
|
|
et := eventType
|
|
d.On(et, func(e Event) {
|
|
events[et] = e
|
|
})
|
|
}
|
|
|
|
d.EmitStart("s1", "started")
|
|
d.EmitProgress("s2", "progressing", map[string]int{"count": 5})
|
|
d.EmitItem("s3", "got item", nil)
|
|
d.EmitError("s4", "something failed", nil)
|
|
d.EmitComplete("s5", "done", nil)
|
|
|
|
assert.Equal(t, "s1", events[EventStart].Source)
|
|
assert.Equal(t, "started", events[EventStart].Message)
|
|
|
|
assert.Equal(t, "s2", events[EventProgress].Source)
|
|
assert.NotNil(t, events[EventProgress].Data)
|
|
|
|
assert.Equal(t, "s3", events[EventItem].Source)
|
|
assert.Equal(t, "s4", events[EventError].Source)
|
|
assert.Equal(t, "s5", events[EventComplete].Source)
|
|
}
|
|
|
|
func TestNewDispatcher_Good(t *testing.T) {
|
|
d := NewDispatcher()
|
|
assert.NotNil(t, d)
|
|
assert.NotNil(t, d.handlers)
|
|
}
|