github.com/kaydxh/golang@v0.0.131/tutorial/programming_paradigm/function.options_test.go (about) 1 package tutorial 2 3 import ( 4 "fmt" 5 "testing" 6 "time" 7 ) 8 9 // A ServerOption sets options. 10 type ServerOption interface { 11 apply(*Server) 12 } 13 14 // EmptyServerOption does not alter the configuration. It can be embedded 15 // in another structure to build custom options. 16 // 17 // This API is EXPERIMENTAL. 18 type EmptyServerOption struct{} 19 20 func (EmptyServerOption) apply(*Server) {} 21 22 // ServerOptionFunc wraps a function that modifies Client into an 23 // implementation of the ServerOption interface. 24 type ServerOptionFunc func(*Server) 25 26 func (f ServerOptionFunc) apply(do *Server) { 27 f(do) 28 } 29 30 // sample code for option, default for nothing to change 31 func _ServerOptionWithDefault() ServerOption { 32 return ServerOptionFunc(func(*Server) { 33 // nothing to change 34 }) 35 } 36 func (o *Server) ApplyOptions(options ...ServerOption) *Server { 37 for _, opt := range options { 38 if opt == nil { 39 continue 40 } 41 opt.apply(o) 42 } 43 return o 44 } 45 46 func WithProtocol(protocol string) ServerOption { 47 return ServerOptionFunc(func(s *Server) { 48 s.opts.Protocol = protocol 49 }) 50 } 51 52 func WithTimeout(timeout time.Duration) ServerOption { 53 return ServerOptionFunc(func(s *Server) { 54 s.opts.Timeout = timeout 55 }) 56 } 57 58 func WithMaxConns(maxConns int) ServerOption { 59 return ServerOptionFunc(func(s *Server) { 60 s.opts.MaxConns = maxConns 61 }) 62 } 63 64 type Server struct { 65 Addr string 66 Port int 67 opts struct { 68 Protocol string 69 Timeout time.Duration 70 MaxConns int 71 } 72 } 73 74 func NewServer(addr string, port int, opts ...ServerOption) *Server { 75 s := &Server{ 76 Addr: addr, 77 Port: port, 78 } 79 for _, opt := range opts { 80 s.ApplyOptions(opt) 81 } 82 83 return s 84 } 85 86 func TestNewServer(t *testing.T) { 87 testCases := []struct { 88 Addr string 89 Port int 90 Protocol string 91 Timeout time.Duration 92 MaxConns int 93 }{ 94 { 95 Addr: "127.0.0.1", 96 Port: 10000, 97 Protocol: "tcp", 98 Timeout: time.Second, 99 }, 100 } 101 102 for i, testCase := range testCases { 103 t.Run(fmt.Sprintf("%d", i), func(t *testing.T) { 104 s := NewServer(testCase.Addr, testCase.Port, WithTimeout(testCase.Timeout), WithProtocol(testCase.Protocol)) 105 t.Logf("s: %v", s) 106 }) 107 } 108 }