test(utils): 添加事件驱动模型测试

- 在 sqrt_test.go 中添加了 fastSqr1 测试函数,用于测试事件驱动模型
- 新增了 Event 和 Uint32AsyncEvent 类型用于测试
- 更新了 go.work、go.mod 和
This commit is contained in:
2025-08-05 16:10:18 +08:00
parent bbbec5dff0
commit cd7583ba05
32 changed files with 1789 additions and 0 deletions

View File

@@ -0,0 +1,37 @@
package audit
import (
"fmt"
"strings"
"github.com/badu/bus"
"github.com/badu/bus/test_scenarios/fire-and-forget/events"
)
type ServiceImpl struct {
sb *strings.Builder
}
func NewAuditService(sb *strings.Builder) ServiceImpl {
result := ServiceImpl{sb: sb}
bus.Sub(result.OnUserRegisteredEvent)
bus.SubCancel(result.OnSMSRequestEvent)
bus.SubCancel(result.OnSMSSentEvent)
return result
}
// OnUserRegisteredEvent is classic event handler
func (s *ServiceImpl) OnUserRegisteredEvent(event events.UserRegisteredEvent) {
// we can save audit data here
}
// OnSMSRequestEvent is a pub-unsub type, we have to return 'false' to continue listening for this kind of events
func (s *ServiceImpl) OnSMSRequestEvent(event events.SMSRequestEvent) bool {
return false
}
// OnSMSSentEvent is a pub-unsub type where we give up on listening after receiving first message
func (s *ServiceImpl) OnSMSSentEvent(event events.SMSSentEvent) bool {
s.sb.WriteString(fmt.Sprintf("audit event : an sms was %s sent to %s with message %s\n", event.Status, event.Request.Number, event.Request.Message))
return true // after first event, audit will give up listening for events
}

View File

@@ -0,0 +1,36 @@
package events
type UserRegisteredEvent struct {
UserName string
Phone string
}
func (e UserRegisteredEvent) Async() bool {
return true
}
type SMSRequestEvent struct {
Number string
Message string
}
func (e SMSRequestEvent) Async() bool {
return true
}
type SMSSentEvent struct {
Request SMSRequestEvent
Status string
}
func (e SMSSentEvent) Async() bool {
return true
}
type DummyEvent struct {
AlteredAsync bool
}
func (e *DummyEvent) Async() bool {
return e.AlteredAsync
}

View File

@@ -0,0 +1,49 @@
package fire_and_forget
import (
"context"
"fmt"
"strings"
"testing"
"time"
"github.com/badu/bus"
"github.com/badu/bus/test_scenarios/fire-and-forget/audit"
"github.com/badu/bus/test_scenarios/fire-and-forget/events"
"github.com/badu/bus/test_scenarios/fire-and-forget/notifications"
"github.com/badu/bus/test_scenarios/fire-and-forget/users"
)
func OnDummyEvent(event *events.DummyEvent) {
fmt.Println("dummy event async ?", event.Async())
}
func TestUserRegistration(t *testing.T) {
var sb strings.Builder
userSvc := users.NewService(&sb)
notifications.NewSmsService(&sb)
notifications.NewEmailService(&sb)
audit.NewAuditService(&sb)
bus.Sub(OnDummyEvent)
userSvc.RegisterUser(context.Background(), "Badu", "+40742222222")
<-time.After(500 * time.Millisecond)
userSvc.RegisterUser(context.Background(), "Adina", "+40743333333")
<-time.After(500 * time.Millisecond)
const expecting = "user Badu has registered - sending welcome email message\n" +
"sms sent requested for number +40742222222 with message Badu your user account was created. Check your email for instructions\n" +
"audit event : an sms was successfully sent sent to +40742222222 with message Badu your user account was created. Check your email for instructions\n" +
"user Adina has registered - sending welcome email message\n" +
"sms sent requested for number +40743333333 with message Adina your user account was created. Check your email for instructions\n"
got := sb.String()
if got != expecting {
t.Fatalf("expecting :\n%s but got : \n%s", expecting, got)
}
}

View File

@@ -0,0 +1,27 @@
package notifications
import (
"fmt"
"strings"
"github.com/badu/bus"
"github.com/badu/bus/test_scenarios/fire-and-forget/events"
)
type EmailServiceImpl struct {
sb *strings.Builder
}
func NewEmailService(sb *strings.Builder) EmailServiceImpl {
result := EmailServiceImpl{sb: sb}
bus.Sub(result.OnUserRegisteredEvent)
return result
}
func (s *EmailServiceImpl) OnUserRegisteredEvent(e events.UserRegisteredEvent) {
s.sb.WriteString(fmt.Sprintf("user %s has registered - sending welcome email message\n", e.UserName))
bus.Pub(events.SMSRequestEvent{
Number: e.Phone,
Message: fmt.Sprintf("%s your user account was created. Check your email for instructions", e.UserName),
})
}

View File

@@ -0,0 +1,27 @@
package notifications
import (
"fmt"
"strings"
"github.com/badu/bus"
"github.com/badu/bus/test_scenarios/fire-and-forget/events"
)
type SmsServiceImpl struct {
sb *strings.Builder
}
func NewSmsService(sb *strings.Builder) SmsServiceImpl {
result := SmsServiceImpl{sb: sb}
bus.Sub(result.OnSMSSendRequest)
return result
}
func (s *SmsServiceImpl) OnSMSSendRequest(event events.SMSRequestEvent) {
s.sb.WriteString(fmt.Sprintf("sms sent requested for number %s with message %s\n", event.Number, event.Message))
bus.Pub(events.SMSSentEvent{
Request: event,
Status: "successfully sent",
})
}

View File

@@ -0,0 +1,25 @@
package users
import (
"context"
"strings"
"github.com/badu/bus"
"github.com/badu/bus/test_scenarios/fire-and-forget/events"
)
type ServiceImpl struct {
sb *strings.Builder
c int
}
func NewService(sb *strings.Builder) ServiceImpl {
result := ServiceImpl{sb: sb}
return result
}
func (s *ServiceImpl) RegisterUser(ctx context.Context, name, phone string) {
s.c++
bus.Pub(events.UserRegisteredEvent{UserName: name, Phone: phone})
bus.Pub(&events.DummyEvent{AlteredAsync: s.c%2 == 0}) // nobody listens on this one
}