Append() method
diff --git a/chain.go b/chain.go
index 04a17f7..d675546 100644
--- a/chain.go
+++ b/chain.go
@@ -59,3 +59,21 @@
return final
}
+
+// Append extends a chain, adding the specified constructors
+// as the last ones in the request flow.
+//
+// Append returns a new chain, leaving the original one untouched.
+//
+// stdChain := alice.New(m1, m2)
+// extChain := stdChain.Append(m3, m4)
+// // requests in stdChain go m1 -> m2
+// // requests in extChain go m1 -> m2 -> m3 -> m4
+func (c Chain) Append(constructors ...Constructor) Chain {
+ newCons := make([]Constructor, len(c.constructors))
+ copy(newCons, c.constructors)
+ newCons = append(newCons, constructors...)
+
+ newChain := New(newCons...)
+ return newChain
+}
diff --git a/chain_test.go b/chain_test.go
index 8c57896..d78b1d9 100644
--- a/chain_test.go
+++ b/chain_test.go
@@ -21,6 +21,10 @@
}
}
+var testApp = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ w.Write([]byte("app\n"))
+})
+
// Tests creating a new chain
func TestNew(t *testing.T) {
c1 := func(h http.Handler) http.Handler {
@@ -40,10 +44,9 @@
func TestThenWorksWithNoMiddleware(t *testing.T) {
assert.NotPanics(t, func() {
chain := New()
- app := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {})
- final := chain.Then(app)
+ final := chain.Then(testApp)
- assert.Equal(t, final, app)
+ assert.Equal(t, final, testApp)
})
}
@@ -56,11 +59,8 @@
t1 := tagMiddleware("t1\n")
t2 := tagMiddleware("t2\n")
t3 := tagMiddleware("t3\n")
- app := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- w.Write([]byte("app\n"))
- })
- chained := New(t1, t2, t3).Then(app)
+ chained := New(t1, t2, t3).Then(testApp)
w := httptest.NewRecorder()
r, err := http.NewRequest("GET", "/", nil)
@@ -72,3 +72,30 @@
assert.Equal(t, w.Body.String(), "t1\nt2\nt3\napp\n")
}
+
+func TestAppendAddsHandlersCorrectly(t *testing.T) {
+ chain := New(tagMiddleware("t1\n"), tagMiddleware("t2\n"))
+ newChain := chain.Append(tagMiddleware("t3\n"), tagMiddleware("t4\n"))
+
+ assert.Equal(t, len(chain.constructors), 2)
+ assert.Equal(t, len(newChain.constructors), 4)
+
+ chained := newChain.Then(testApp)
+
+ w := httptest.NewRecorder()
+ r, err := http.NewRequest("GET", "/", nil)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ chained.ServeHTTP(w, r)
+
+ assert.Equal(t, w.Body.String(), "t1\nt2\nt3\nt4\napp\n")
+}
+
+func TestAppendRespectsImmutability(t *testing.T) {
+ chain := New(tagMiddleware(""))
+ newChain := chain.Append(tagMiddleware(""))
+
+ assert.NotEqual(t, &chain.constructors[0], &newChain.constructors[0])
+}