diff --git a/pkg/channels/irc/irc_test.go b/pkg/channels/irc/irc_test.go index 9ac3042c3..1eb23176b 100644 --- a/pkg/channels/irc/irc_test.go +++ b/pkg/channels/irc/irc_test.go @@ -1,163 +1,163 @@ -package irc - -import ( - "reflect" - "testing" - - "github.com/sipeed/picoclaw/pkg/bus" - "github.com/sipeed/picoclaw/pkg/config" -) - -func TestNewIRCChannel(t *testing.T) { - msgBus := bus.NewMessageBus() - - t.Run("missing server", func(t *testing.T) { - cfg := config.IRCConfig{Nick: "bot"} - _, err := NewIRCChannel(cfg, msgBus) - if err == nil { - t.Error("expected error for missing server, got nil") - } - }) - - t.Run("missing nick", func(t *testing.T) { - cfg := config.IRCConfig{Server: "irc.example.com:6667"} - _, err := NewIRCChannel(cfg, msgBus) - if err == nil { - t.Error("expected error for missing nick, got nil") - } - }) - - t.Run("valid config", func(t *testing.T) { - cfg := config.IRCConfig{ - Server: "irc.example.com:6667", - Nick: "testbot", - Channels: []string{"#test"}, - } - ch, err := NewIRCChannel(cfg, msgBus) - if err != nil { - t.Fatalf("unexpected error: %v", err) - } - if ch.Name() != "irc" { - t.Errorf("Name() = %q, want %q", ch.Name(), "irc") - } - if ch.IsRunning() { - t.Error("new channel should not be running") - } - }) - - t.Run("normalizes auto join channels", func(t *testing.T) { - cfg := config.IRCConfig{ - Server: "irc.example.com:6667", - Nick: "testbot", - Channels: []string{" general ", "#already", "&ops", "+local", "!safe", "", "news"}, - } - ch, err := NewIRCChannel(cfg, msgBus) - if err != nil { - t.Fatalf("unexpected error: %v", err) - } - - want := config.FlexibleStringSlice{"#general", "#already", "&ops", "+local", "!safe", "#news"} - if !reflect.DeepEqual(ch.config.Channels, want) { - t.Fatalf("Channels = %#v, want %#v", ch.config.Channels, want) - } - }) -} - -func TestExtractHost(t *testing.T) { - tests := []struct { - server string - want string - }{ - {"irc.libera.chat:6697", "irc.libera.chat"}, - {"localhost:6667", "localhost"}, - {"irc.example.com", "irc.example.com"}, - {"", ""}, - } - - for _, tt := range tests { - t.Run(tt.server, func(t *testing.T) { - got := extractHost(tt.server) - if got != tt.want { - t.Errorf("extractHost(%q) = %q, want %q", tt.server, got, tt.want) - } - }) - } -} - -func TestNickMentionedAt(t *testing.T) { - tests := []struct { - name string - content string - nick string - want int - }{ - {"colon prefix", "bot: hello", "bot", 0}, - {"comma prefix", "bot, hello", "bot", 0}, - {"case insensitive", "BOT: hello", "bot", 0}, - {"word boundary mid", "hey bot what's up", "bot", 4}, - {"no mention", "hello world", "bot", -1}, - {"substring mismatch", "robotics are cool", "bot", -1}, - {"nick at end", "hello bot", "bot", 6}, - {"empty content", "", "bot", -1}, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got := nickMentionedAt(tt.content, tt.nick) - if got != tt.want { - t.Errorf("nickMentionedAt(%q, %q) = %d, want %d", tt.content, tt.nick, got, tt.want) - } - }) - } -} - -func TestIsBotMentioned(t *testing.T) { - tests := []struct { - name string - content string - nick string - want bool - }{ - {"colon prefix", "bot: hello", "bot", true}, - {"comma prefix", "bot, hello", "bot", true}, - {"case insensitive", "BOT: hello", "bot", true}, - {"word boundary mid", "hey bot what's up", "bot", true}, - {"no mention", "hello world", "bot", false}, - {"substring mismatch", "robotics are cool", "bot", false}, - {"nick at end", "hello bot", "bot", true}, - {"empty content", "", "bot", false}, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got := isBotMentioned(tt.content, tt.nick) - if got != tt.want { - t.Errorf("isBotMentioned(%q, %q) = %v, want %v", tt.content, tt.nick, got, tt.want) - } - }) - } -} - -func TestStripBotMention(t *testing.T) { - tests := []struct { - name string - content string - nick string - want string - }{ - {"colon prefix", "bot: hello there", "bot", "hello there"}, - {"comma prefix", "bot, help me", "bot", "help me"}, - {"case insensitive", "BOT: hello", "bot", "hello"}, - {"no prefix match", "hello bot", "bot", "hello bot"}, - {"only prefix", "bot:", "bot", ""}, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got := stripBotMention(tt.content, tt.nick) - if got != tt.want { - t.Errorf("stripBotMention(%q, %q) = %q, want %q", tt.content, tt.nick, got, tt.want) - } - }) - } -} +package irc + +import ( + "reflect" + "testing" + + "github.com/sipeed/picoclaw/pkg/bus" + "github.com/sipeed/picoclaw/pkg/config" +) + +func TestNewIRCChannel(t *testing.T) { + msgBus := bus.NewMessageBus() + + t.Run("missing server", func(t *testing.T) { + cfg := config.IRCConfig{Nick: "bot"} + _, err := NewIRCChannel(cfg, msgBus) + if err == nil { + t.Error("expected error for missing server, got nil") + } + }) + + t.Run("missing nick", func(t *testing.T) { + cfg := config.IRCConfig{Server: "irc.example.com:6667"} + _, err := NewIRCChannel(cfg, msgBus) + if err == nil { + t.Error("expected error for missing nick, got nil") + } + }) + + t.Run("valid config", func(t *testing.T) { + cfg := config.IRCConfig{ + Server: "irc.example.com:6667", + Nick: "testbot", + Channels: []string{"#test"}, + } + ch, err := NewIRCChannel(cfg, msgBus) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + if ch.Name() != "irc" { + t.Errorf("Name() = %q, want %q", ch.Name(), "irc") + } + if ch.IsRunning() { + t.Error("new channel should not be running") + } + }) + + t.Run("normalizes auto join channels", func(t *testing.T) { + cfg := config.IRCConfig{ + Server: "irc.example.com:6667", + Nick: "testbot", + Channels: []string{" general ", "#already", "&ops", "+local", "!safe", "", "news"}, + } + ch, err := NewIRCChannel(cfg, msgBus) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + + want := config.FlexibleStringSlice{"#general", "#already", "&ops", "+local", "!safe", "#news"} + if !reflect.DeepEqual(ch.config.Channels, want) { + t.Fatalf("Channels = %#v, want %#v", ch.config.Channels, want) + } + }) +} + +func TestExtractHost(t *testing.T) { + tests := []struct { + server string + want string + }{ + {"irc.libera.chat:6697", "irc.libera.chat"}, + {"localhost:6667", "localhost"}, + {"irc.example.com", "irc.example.com"}, + {"", ""}, + } + + for _, tt := range tests { + t.Run(tt.server, func(t *testing.T) { + got := extractHost(tt.server) + if got != tt.want { + t.Errorf("extractHost(%q) = %q, want %q", tt.server, got, tt.want) + } + }) + } +} + +func TestNickMentionedAt(t *testing.T) { + tests := []struct { + name string + content string + nick string + want int + }{ + {"colon prefix", "bot: hello", "bot", 0}, + {"comma prefix", "bot, hello", "bot", 0}, + {"case insensitive", "BOT: hello", "bot", 0}, + {"word boundary mid", "hey bot what's up", "bot", 4}, + {"no mention", "hello world", "bot", -1}, + {"substring mismatch", "robotics are cool", "bot", -1}, + {"nick at end", "hello bot", "bot", 6}, + {"empty content", "", "bot", -1}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := nickMentionedAt(tt.content, tt.nick) + if got != tt.want { + t.Errorf("nickMentionedAt(%q, %q) = %d, want %d", tt.content, tt.nick, got, tt.want) + } + }) + } +} + +func TestIsBotMentioned(t *testing.T) { + tests := []struct { + name string + content string + nick string + want bool + }{ + {"colon prefix", "bot: hello", "bot", true}, + {"comma prefix", "bot, hello", "bot", true}, + {"case insensitive", "BOT: hello", "bot", true}, + {"word boundary mid", "hey bot what's up", "bot", true}, + {"no mention", "hello world", "bot", false}, + {"substring mismatch", "robotics are cool", "bot", false}, + {"nick at end", "hello bot", "bot", true}, + {"empty content", "", "bot", false}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := isBotMentioned(tt.content, tt.nick) + if got != tt.want { + t.Errorf("isBotMentioned(%q, %q) = %v, want %v", tt.content, tt.nick, got, tt.want) + } + }) + } +} + +func TestStripBotMention(t *testing.T) { + tests := []struct { + name string + content string + nick string + want string + }{ + {"colon prefix", "bot: hello there", "bot", "hello there"}, + {"comma prefix", "bot, help me", "bot", "help me"}, + {"case insensitive", "BOT: hello", "bot", "hello"}, + {"no prefix match", "hello bot", "bot", "hello bot"}, + {"only prefix", "bot:", "bot", ""}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := stripBotMention(tt.content, tt.nick) + if got != tt.want { + t.Errorf("stripBotMention(%q, %q) = %q, want %q", tt.content, tt.nick, got, tt.want) + } + }) + } +}