decorator.go
package decorator import ( "errors" "fmt" ) type IngredientAdd interface { AddIngredient() (string, error) } type PizzaDecorator struct { Ingredient IngredientAdd } func (p *PizzaDecorator) AddIngredient() (string, error) { return "Pizza with the following ingredients:", nil } type Meat struct { Ingredient IngredientAdd } func (p *Meat) AddIngredient() (string, error) { return "", errors.New("Not implemented yet") } type Onion struct { Ingredient IngredientAdd } func (o *Onion) AddIngredient() (string, error) { if o.Ingredient == nil { return "", errors.New("An IngredientAdd is needed.") } s, err := o.Ingredient.AddIngredient() if err != nil { return "", err } return fmt.Sprintf("%s %s", s, "onion"), nil }
decorator_test.go
package decorator import ( "strings" "testing" ) func TestPizza_AddIngredient(t *testing.T) { pizza := &PizzaDecorator{} pizzaResult, _ := pizza.AddIngredient() expectedText := "Pizza with the following ingredients:" if !strings.Contains(pizzaResult, expectedText) { t.Error("strings.Contains(pizzaResult, expectedText)") } } func TestOnion_AddIngredient(t *testing.T) { onion := &Onion{} onionResult, err := onion.AddIngredient() if err == nil { t.Error(err) } onion = &Onion{&PizzaDecorator{}} onionResult, err = onion.AddIngredient() if err != nil { t.Error(err) } if !strings.Contains(onionResult, "onion") { t.Error(`!strings.Contains(onionResult, "onion")`) } }