
ChainOfResponsibility.go
package ChainOfResponsibility import ( "fmt" "io" "strings" ) type ChainLogger interface { Next(string) } type FirstLogger struct { NextChain ChainLogger } func (f *FirstLogger) Next(s string) { fmt.Printf("First logger: %s\n", s) if f.NextChain != nil { f.NextChain.Next(s) } } type SecondLogger struct { NextChain ChainLogger } func (se *SecondLogger) Next(s string) { if strings.Contains(strings.ToLower(s), "hello") { fmt.Printf("Second logger: %s\n", s) if se.NextChain != nil { se.NextChain.Next(s) } return } fmt.Printf("Finishing in second logging\n\n") } type WriterLogger struct { NextChain ChainLogger Writer io.Writer } func (w *WriterLogger) Next(s string) { if w.Writer != nil { w.Writer.Write([]byte("WriterLogger: " + s)) } if w.NextChain != nil { w.NextChain.Next(s) } }
ChainOfResponsibility_test.go
package ChainOfResponsibility import ( "fmt" "strings" "testing" ) type myTestWriter struct { receivedMessage *string } func (m *myTestWriter) Write(p []byte) (int, error) { if m.receivedMessage == nil { m.receivedMessage = new(string) } tempMessage := fmt.Sprintf("%p%s", m.receivedMessage, p) m.receivedMessage = &tempMessage return len(p), nil } func (m *myTestWriter) Next(s string) { m.Write([]byte(s)) } func TestCreateDefaultChain(t *testing.T) { myWriter := myTestWriter{} writerLogger := WriterLogger{Writer: &myWriter} second := SecondLogger{NextChain: &writerLogger} chain := FirstLogger{NextChain: &second} t.Run("3 loggers, 2 of them writes to console, second only if it founds"+ "the world 'hello', third writes to some variable if second found 'hello'", func(t *testing.T) { chain.Next("message that breaks the chain\n") if myWriter.receivedMessage != nil { t.Error("Last link should not receive any message") } chain.Next("Hello\n") if *myWriter.receivedMessage == "" || !strings.Contains(*myWriter.receivedMessage, "Hello") { t.Fatal("Last link did not received expected message") } }) }