New assertion: should.WrapError

ShouldWrap asserts that the first argument (which must be an error
value) 'wraps' the second/final argument (which must also be an error
value). It relies on errors.Is to make the determination.

See https://golang.org/pkg/errors/#Is
diff --git a/messages.go b/messages.go
index 72782b0..178d7e4 100644
--- a/messages.go
+++ b/messages.go
@@ -91,6 +91,8 @@
 	shouldBeError                       = "Expected an error value (but was '%v' instead)!"
 	shouldBeErrorInvalidComparisonValue = "The final argument to this assertion must be a string or an error value (you provided: '%v')."
 
+	shouldWrapInvalidTypes = "The first and last arguments to this assertion must both be error values (you provided: '%v' and '%v')."
+
 	shouldUseTimes           = "You must provide time instances as arguments to this assertion."
 	shouldUseTimeSlice       = "You must provide a slice of time instances as the first argument to this assertion."
 	shouldUseDurationAndTime = "You must provide a duration and a time as arguments to this assertion."
diff --git a/should/should.go b/should/should.go
index a5817ed..b85bf2c 100644
--- a/should/should.go
+++ b/should/should.go
@@ -67,4 +67,5 @@
 	PointTo                = assertions.ShouldPointTo
 	Resemble               = assertions.ShouldResemble
 	StartWith              = assertions.ShouldStartWith
+	Wrap                   = assertions.ShouldWrap
 )
diff --git a/type.go b/type.go
index d2d1dc8..1984fe8 100644
--- a/type.go
+++ b/type.go
@@ -1,6 +1,7 @@
 package assertions
 
 import (
+	"errors"
 	"fmt"
 	"reflect"
 )
@@ -130,5 +131,24 @@
 	return ShouldEqual(fmt.Sprint(actual), fmt.Sprint(expected[0]))
 }
 
+// ShouldWrap asserts that the first argument (which must be an error value)
+// 'wraps' the second/final argument (which must also be an error value).
+// It relies on errors.Is to make the determination (https://golang.org/pkg/errors/#Is).
+func ShouldWrap(actual interface{}, expected ...interface{}) string {
+	if fail := need(1, expected); fail != success {
+		return fail
+	}
+
+	if !isError(actual) || !isError(expected[0]) {
+		return fmt.Sprintf(shouldWrapInvalidTypes, reflect.TypeOf(actual), reflect.TypeOf(expected[0]))
+	}
+
+	if !errors.Is(actual.(error), expected[0].(error)) {
+		return fmt.Sprintf(`Expected error("%s") to wrap error("%s") but it didn't.`, actual, expected[0])
+	}
+
+	return success
+}
+
 func isString(value interface{}) bool { _, ok := value.(string); return ok }
 func isError(value interface{}) bool  { _, ok := value.(error); return ok }
diff --git a/type_test.go b/type_test.go
index 25c3aae..4e0ba33 100644
--- a/type_test.go
+++ b/type_test.go
@@ -3,6 +3,7 @@
 import (
 	"bytes"
 	"errors"
+	"fmt"
 	"io"
 	"net/http"
 )
@@ -88,3 +89,21 @@
 	this.pass(so(error1, ShouldBeError, error1))
 	this.pass(so(error1, ShouldBeError, error1.Error()))
 }
+
+func (this *AssertionsFixture) TestShouldWrapError() {
+	inner := fmt.Errorf("inner")
+	middle := fmt.Errorf("middle(%w)", inner)
+	outer := fmt.Errorf("outer(%w)", middle)
+
+	this.fail(so(outer, ShouldWrap, "too", "many"), "This assertion requires exactly 1 comparison values (you provided 2).")
+	this.fail(so(outer, ShouldWrap), "This assertion requires exactly 1 comparison values (you provided 0).")
+
+	this.fail(so(42, ShouldWrap, 42), "The first and last arguments to this assertion must both be error values (you provided: 'int' and 'int').")
+	this.fail(so(inner, ShouldWrap, 42), "The first and last arguments to this assertion must both be error values (you provided: '*errors.errorString' and 'int').")
+	this.fail(so(42, ShouldWrap, inner), "The first and last arguments to this assertion must both be error values (you provided: 'int' and '*errors.errorString').")
+
+	this.fail(so(inner, ShouldWrap, outer), `Expected error("inner") to wrap error("outer(middle(inner))") but it didn't.`)
+	this.pass(so(middle, ShouldWrap, inner))
+	this.pass(so(outer, ShouldWrap, middle))
+	this.pass(so(outer, ShouldWrap, inner))
+}