github.com/shogo82148/goa-v1@v1.6.2/context_test.go (about) 1 package goa_test 2 3 import ( 4 "context" 5 "net/http" 6 "net/url" 7 "time" 8 9 . "github.com/onsi/ginkgo" 10 . "github.com/onsi/gomega" 11 "github.com/shogo82148/goa-v1" 12 ) 13 14 // contextKey is a value for use with context.WithValue. It's used as 15 // a pointer so it fits in an interface{} without allocation. 16 type contextKey struct { 17 name string 18 } 19 20 func (k *contextKey) String() string { return "goa-v1 context value " + k.name } 21 22 var _ = Describe("ResponseData", func() { 23 var data *goa.ResponseData 24 var rw http.ResponseWriter 25 var req *http.Request 26 var params url.Values 27 28 BeforeEach(func() { 29 var err error 30 req, err = http.NewRequest("GET", "google.com", nil) 31 Ω(err).ShouldNot(HaveOccurred()) 32 rw = &TestResponseWriter{Status: 42} 33 params = url.Values{"query": []string{"value"}} 34 ctx := goa.NewContext(context.Background(), rw, req, params) 35 data = goa.ContextResponse(ctx) 36 }) 37 38 Context("SwitchWriter", func() { 39 var rwo http.ResponseWriter 40 41 It("sets the response writer and returns the previous one", func() { 42 Ω(rwo).Should(BeNil()) 43 rwo = data.SwitchWriter(&TestResponseWriter{Status: 43}) 44 Ω(rwo).ShouldNot(BeNil()) 45 Ω(rwo).Should(BeAssignableToTypeOf(&TestResponseWriter{})) 46 trw := rwo.(*TestResponseWriter) 47 Ω(trw.Status).Should(Equal(42)) 48 }) 49 }) 50 51 Context("Write", func() { 52 It("should call WriteHeader(http.StatusOK) if WriteHeader has not yet been called", func() { 53 _, err := data.Write(nil) 54 Ω(err).Should(BeNil()) 55 Ω(data.Status).Should(Equal(http.StatusOK)) 56 }) 57 58 It("should not affect Status if WriteHeader has been called", func() { 59 status := http.StatusBadRequest 60 data.WriteHeader(status) 61 _, err := data.Write(nil) 62 Ω(err).Should(BeNil()) 63 Ω(data.Status).Should(Equal(status)) 64 }) 65 }) 66 67 Context("Context", func() { 68 mergeContext := func(parent, child context.Context) context.Context { 69 req, err := http.NewRequestWithContext(child, "GET", "google.com", nil) 70 Ω(err).Should(BeNil()) 71 return goa.NewContext(parent, &TestResponseWriter{Status: 42}, req, url.Values{}) 72 } 73 Context("Deadline", func() { 74 It("should be empty if the parent and the child have no deadline", func() { 75 ctx := mergeContext(context.Background(), context.Background()) 76 _, ok := ctx.Deadline() 77 Ω(ok).Should(Equal(false)) 78 }) 79 It("should return the parent's deadline if the child have no deadline", func() { 80 deadline := time.Now().Add(time.Second) 81 parent, cancel := context.WithDeadline(context.Background(), deadline) 82 defer cancel() 83 ctx := mergeContext(parent, context.Background()) 84 got, ok := ctx.Deadline() 85 Ω(ok).Should(Equal(true)) 86 Ω(got).Should(BeTemporally("~", deadline, 100*time.Millisecond)) 87 }) 88 It("should return the child's deadline if the parent have no deadline", func() { 89 deadline := time.Now().Add(time.Second) 90 child, cancel := context.WithDeadline(context.Background(), deadline) 91 defer cancel() 92 ctx := mergeContext(context.Background(), child) 93 got, ok := ctx.Deadline() 94 Ω(ok).Should(Equal(true)) 95 Ω(got).Should(BeTemporally("~", deadline, 100*time.Millisecond)) 96 }) 97 It("should return the child's deadline if it is earlier than the parent's one", func() { 98 deadline1 := time.Now().Add(time.Second) 99 child, cancel := context.WithDeadline(context.Background(), deadline1) 100 defer cancel() 101 deadline2 := time.Now().Add(2 * time.Second) 102 parent, cancel := context.WithDeadline(context.Background(), deadline2) 103 defer cancel() 104 105 ctx := mergeContext(parent, child) 106 got, ok := ctx.Deadline() 107 Ω(ok).Should(Equal(true)) 108 Ω(got).Should(BeTemporally("~", deadline1, 100*time.Millisecond)) 109 }) 110 It("should return the parent's deadline if it is earlier than the child's one", func() { 111 deadline1 := time.Now().Add(2 * time.Second) 112 child, cancel := context.WithDeadline(context.Background(), deadline1) 113 defer cancel() 114 deadline2 := time.Now().Add(time.Second) 115 parent, cancel := context.WithDeadline(context.Background(), deadline2) 116 defer cancel() 117 118 ctx := mergeContext(parent, child) 119 got, ok := ctx.Deadline() 120 Ω(ok).Should(Equal(true)) 121 Ω(got).Should(BeTemporally("~", deadline2, 100*time.Millisecond)) 122 }) 123 }) 124 Context("Done", func() { 125 It("should be canceled when the parent is canceled", func() { 126 deadline := time.Now().Add(time.Second) 127 parent, cancel := context.WithDeadline(context.Background(), deadline) 128 defer cancel() 129 130 ctx := mergeContext(parent, context.Background()) 131 select { 132 case <-ctx.Done(): 133 case <-time.After(5 * time.Second): 134 Fail("timeout") 135 } 136 Ω(ctx.Err()).ShouldNot(BeNil()) 137 Ω(time.Now()).Should(BeTemporally("~", deadline, 500*time.Millisecond)) 138 }) 139 It("should be canceled when the child is canceled", func() { 140 deadline := time.Now().Add(time.Second) 141 child, cancel := context.WithDeadline(context.Background(), deadline) 142 defer cancel() 143 144 ctx := mergeContext(context.Background(), child) 145 select { 146 case <-ctx.Done(): 147 case <-time.After(5 * time.Second): 148 Fail("timeout") 149 } 150 Ω(ctx.Err()).ShouldNot(BeNil()) 151 Ω(time.Now()).Should(BeTemporally("~", deadline, 500*time.Millisecond)) 152 }) 153 }) 154 Context("Value", func() { 155 key := &contextKey{"key"} 156 otherKey := &contextKey{"other-key"} 157 It("should return the value associated with the child if it exists", func() { 158 parent := context.WithValue(context.Background(), key, "parent value") 159 child := context.WithValue(context.Background(), key, "child value") 160 ctx := mergeContext(parent, child) 161 Ω(ctx.Value(key)).Should(Equal("child value")) 162 }) 163 It("should return the value associated with the parent if the child associates nothing", func() { 164 parent := context.WithValue(context.Background(), key, "parent value") 165 child := context.WithValue(context.Background(), otherKey, "child value") 166 ctx := mergeContext(parent, child) 167 Ω(ctx.Value(key)).Should(Equal("parent value")) 168 }) 169 }) 170 }) 171 })