context: provide String methods.  The Strings show the functions called
to construct the context left-to-right.  External implementations of the
Context interface may break the chain, but establishing this pattern now
may encourage them to do the right thing.

LGTM=bcmills
R=bcmills
CC=golang-codereviews
https://golang.org/cl/116430044
diff --git a/context/context.go b/context/context.go
index ffbdd83..554e14d 100644
--- a/context/context.go
+++ b/context/context.go
@@ -38,6 +38,7 @@
 
 import (
 	"errors"
+	"fmt"
 	"sync"
 	"time"
 )
@@ -289,6 +290,10 @@
 	return c.err
 }
 
+func (c *cancelCtx) String() string {
+	return fmt.Sprintf("%v.WithCancel", c.Context)
+}
+
 // cancel closes c.done, cancels each of c's children, and, if
 // removeFromParent is true, removes c from its parent's children.
 func (c *cancelCtx) cancel(removeFromParent bool, err error) {
@@ -369,6 +374,10 @@
 	return c.deadline, true
 }
 
+func (c *timerCtx) String() string {
+	return fmt.Sprintf("%v.WithDeadline(%s [%s])", c.cancelCtx.Context, c.deadline, c.deadline.Sub(time.Now()))
+}
+
 func (c *timerCtx) cancel(removeFromParent bool, err error) {
 	c.cancelCtx.cancel(removeFromParent, err)
 	c.mu.Lock()
@@ -410,6 +419,10 @@
 	key, val interface{}
 }
 
+func (c *valueCtx) String() string {
+	return fmt.Sprintf("%v.WithValue(%#v, %#v)", c.Context, c.key, c.val)
+}
+
 func (c *valueCtx) Value(key interface{}) interface{} {
 	if c.key == key {
 		return c.val
diff --git a/context/context_test.go b/context/context_test.go
index 2342a86..c1a4de5 100644
--- a/context/context_test.go
+++ b/context/context_test.go
@@ -8,6 +8,7 @@
 	"fmt"
 	"math/rand"
 	"runtime"
+	"strings"
 	"sync"
 	"testing"
 	"time"
@@ -30,8 +31,8 @@
 		t.Errorf("<-c.Done() == %v want nothing (it should block)", x)
 	default:
 	}
-	if s := fmt.Sprint(c); s != "context.Background" {
-		t.Errorf(`Background.String = %q want "context.Background"`, s)
+	if got, want := fmt.Sprint(c), "context.Background"; got != want {
+		t.Errorf("Background().String() = %q want %q", got, want)
 	}
 }
 
@@ -45,13 +46,18 @@
 		t.Errorf("<-c.Done() == %v want nothing (it should block)", x)
 	default:
 	}
-	if s := fmt.Sprint(c); s != "context.TODO" {
-		t.Errorf(`TODO.String = %q want "context.TODO"`, s)
+	if got, want := fmt.Sprint(c), "context.TODO"; got != want {
+		t.Errorf("TODO().String() = %q want %q", got, want)
 	}
 }
 
 func TestWithCancel(t *testing.T) {
 	c1, cancel := WithCancel(Background())
+
+	if got, want := fmt.Sprint(c1), "context.Background.WithCancel"; got != want {
+		t.Errorf("c1.String() = %q want %q", got, want)
+	}
+
 	o := otherContext{c1}
 	c2, _ := WithCancel(o)
 	contexts := []Context{c1, o, c2}
@@ -72,7 +78,7 @@
 	}
 
 	cancel()
-	time.Sleep(100 * time.Millisecond) // let cancellation propagate
+	time.Sleep(100 * time.Millisecond) // let cancelation propagate
 
 	for i, c := range contexts {
 		select {
@@ -236,6 +242,9 @@
 
 func TestDeadline(t *testing.T) {
 	c, _ := WithDeadline(Background(), time.Now().Add(100*time.Millisecond))
+	if got, prefix := fmt.Sprint(c), "context.Background.WithDeadline("; !strings.HasPrefix(got, prefix) {
+		t.Errorf("c.String() = %q want prefix %q", got, prefix)
+	}
 	testDeadline(c, 200*time.Millisecond, t)
 
 	c, _ = WithDeadline(Background(), time.Now().Add(100*time.Millisecond))
@@ -250,6 +259,9 @@
 
 func TestTimeout(t *testing.T) {
 	c, _ := WithTimeout(Background(), 100*time.Millisecond)
+	if got, prefix := fmt.Sprint(c), "context.Background.WithDeadline("; !strings.HasPrefix(got, prefix) {
+		t.Errorf("c.String() = %q want prefix %q", got, prefix)
+	}
 	testDeadline(c, 200*time.Millisecond, t)
 
 	c, _ = WithTimeout(Background(), 100*time.Millisecond)
@@ -262,12 +274,12 @@
 	testDeadline(c, 200*time.Millisecond, t)
 }
 
-func TestCancelledTimeout(t *testing.T) {
+func TestCanceledTimeout(t *testing.T) {
 	c, _ := WithTimeout(Background(), 200*time.Millisecond)
 	o := otherContext{c}
 	c, cancel := WithTimeout(o, 400*time.Millisecond)
 	cancel()
-	time.Sleep(100 * time.Millisecond) // let cancellation propagate
+	time.Sleep(100 * time.Millisecond) // let cancelation propagate
 	select {
 	case <-c.Done():
 	default:
@@ -304,6 +316,10 @@
 	c1 := WithValue(Background(), k1, "c1k1")
 	check(c1, "c1", "c1k1", "", "")
 
+	if got, want := fmt.Sprint(c1), `context.Background.WithValue(1, "c1k1")`; got != want {
+		t.Errorf("c.String() = %q want %q", got, want)
+	}
+
 	c2 := WithValue(c1, k2, "c2k2")
 	check(c2, "c2", "c1k1", "c2k2", "")
 
@@ -487,17 +503,14 @@
 		switch rand.Intn(3) {
 		case 0:
 			v := new(value)
-			t.Logf("WithValue(%p, %p)", v, v)
 			ctx = WithValue(ctx, v, v)
 			vals = append(vals, v)
 		case 1:
 			var cancel CancelFunc
-			t.Logf("WithCancel")
 			ctx, cancel = WithCancel(ctx)
 			cancels = append(cancels, cancel)
 		case 2:
 			var cancel CancelFunc
-			t.Logf("WithTimeout")
 			ctx, cancel = WithTimeout(ctx, timeout)
 			cancels = append(cancels, cancel)
 			numTimers++
@@ -515,6 +528,10 @@
 		errorf("ctx should not be canceled yet")
 	default:
 	}
+	if s, prefix := fmt.Sprint(ctx), "context.Background."; !strings.HasPrefix(s, prefix) {
+		t.Errorf("ctx.String() = %q want prefix %q", s, prefix)
+	}
+	t.Log(ctx)
 	checkValues("before cancel")
 	if testTimeout {
 		select {