Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(53)

Unified Diff: common/errors/tags_test.go

Issue 2951393002: [errors] de-specialize Transient in favor of Tags. (Closed)
Patch Set: copyright Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: common/errors/tags_test.go
diff --git a/common/errors/tags_test.go b/common/errors/tags_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..1ae01b6ae0bec43f53c6accdc7e2dadf5660c58c
--- /dev/null
+++ b/common/errors/tags_test.go
@@ -0,0 +1,149 @@
+// Copyright 2017 The LUCI Authors. All rights reserved.
+// Use of this source code is governed under the Apache License, Version 2.0
+// that can be found in the LICENSE file.
+
+package errors
+
+import (
+ stdErr "errors"
+ "testing"
+
+ . "github.com/smartystreets/goconvey/convey"
+)
+
+type customInt int
+
+func TestTags(t *testing.T) {
+ t.Parallel()
+
+ aBoolTag := NewBoolTag("errors.testing tag")
+ aValueTag := NewTagger("errors.testing value tag")
+ aStringTag := NewTagger("errors.testing string tag", func(v interface{}) {
+ _ = v.(string)
+ })
+ aCustomIntTag := NewTagger("errors.testing string tag", func(v interface{}) {
+ _ = v.(customInt)
+ })
+
+ Convey("Tags", t, func() {
+ Convey(`have unique tagKey values`, func() {
+ tagSet := map[tagKey]struct{}{}
+ tagSet[aBoolTag.(tagKey)] = struct{}{}
+ tagSet[aValueTag.(tagKey)] = struct{}{}
+ tagSet[aStringTag.(tagKey)] = struct{}{}
+ tagSet[aCustomIntTag.(tagKey)] = struct{}{}
+ So(tagSet, ShouldHaveLength, 4)
+ })
+
+ Convey(`can be applied to errors`, func() {
+ Convey(`at creation time`, func() {
+ err := New("I am an error", aBoolTag, aValueTag.With(100))
+ So(aBoolTag.In(err), ShouldBeTrue)
+ d, ok := aValueTag.ValueIn(err)
+ So(ok, ShouldBeTrue)
+ So(d, ShouldEqual, 100)
+
+ d, _ = aBoolTag.ValueIn(err)
+ So(d, ShouldBeNil)
+
+ So(aStringTag.In(err), ShouldBeFalse)
+ So(aCustomIntTag.In(err), ShouldBeFalse)
+ })
+
+ Convey(`added to existing errors`, func() {
+ err := New("I am an error")
+ err2 := aCustomIntTag.With(customInt(236)).Apply(err)
+ err2 = aBoolTag.Apply(err2)
+
+ d, ok := aCustomIntTag.ValueIn(err2)
+ So(ok, ShouldBeTrue)
+ So(d, ShouldEqual, customInt(236))
+ So(aBoolTag.In(err2), ShouldBeTrue)
+
+ So(aCustomIntTag.In(err), ShouldBeFalse)
+ So(aBoolTag.In(err), ShouldBeFalse)
+ })
+
+ Convey(`added to stdlib errors`, func() {
+ err := stdErr.New("I am an error")
+ err2 := aStringTag.With("hi").Apply(err)
+
+ d, ok := aStringTag.ValueIn(err2)
+ So(ok, ShouldBeTrue)
+ So(d, ShouldEqual, "hi")
+
+ So(aStringTag.In(err), ShouldBeFalse)
+ })
+
+ Convey(`multiple applications has the last one win`, func() {
+ err := New("I am an error")
+ err = aStringTag.With("hi").Apply(err)
+ err = aStringTag.With("there").Apply(err)
+ err = aStringTag.With("winner").Apply(err)
+
+ d, ok := aStringTag.ValueIn(err)
+ So(ok, ShouldBeTrue)
+ So(d, ShouldEqual, "winner")
+
+ Convey(`muliterrors are first to last`, func() {
+ err = NewMultiError(
+ New("a", aStringTag.With("hi"), aBoolTag),
+ New("b", aValueTag.With("there"), aStringTag.With("no")),
+ New("c", aValueTag.With("nope"), aStringTag.With("nopers")),
+ )
+
+ So(aBoolTag.In(err), ShouldBeTrue)
+
+ d, ok := aStringTag.ValueIn(err)
+ So(ok, ShouldBeTrue)
+ So(d, ShouldEqual, "hi")
+
+ d, ok = aValueTag.ValueIn(err)
+ So(ok, ShouldBeTrue)
+ So(d, ShouldEqual, "there")
+
+ Convey(`and all the correct values show up with GetTags`, func() {
+ tags := GetTags(err)
+ So(tags, ShouldContainKey, aValueTag)
+ So(tags, ShouldContainKey, aStringTag)
+ So(tags, ShouldContainKey, aBoolTag)
+ So(tags, ShouldNotContainKey, aCustomIntTag)
+
+ So(tags[aValueTag], ShouldEqual, "there")
+ So(tags[aStringTag], ShouldEqual, "hi")
+ So(tags[aBoolTag], ShouldBeNil)
+ })
+ })
+ })
+ })
+
+ Convey(`only allow simple values`, func() {
+ Convey(`numbers, strings OK`, func() {
+ aValueTag.With("hi")
+ aValueTag.With(100)
+ aValueTag.With(false)
+ aValueTag.With(34.100)
+ aValueTag.With(12 + 100i)
+ })
+
+ Convey(`no structs, etc.`, func() {
+ So(func() { aValueTag.With(struct{}{}) }, ShouldPanic)
+ So(func() { aValueTag.With([]int{}) }, ShouldPanic)
+ So(func() { aValueTag.With(func() {}) }, ShouldPanic)
+ So(func() { aValueTag.With(make(chan int)) }, ShouldPanic)
+ So(func() { aValueTag.With([10]byte{}) }, ShouldPanic)
+ So(func() { aValueTag.With(map[int]int{}) }, ShouldPanic)
+ So(func() { aValueTag.With(&struct{}{}) }, ShouldPanic)
+ })
+
+ Convey(`and custom validators can add additional constriants`, func() {
+ aStringTag.With("sup")
+ So(func() { aStringTag.With(100) }, ShouldPanic)
+
+ aCustomIntTag.With(customInt(100))
+ So(func() { aCustomIntTag.With(100) }, ShouldPanic)
+ So(func() { aCustomIntTag.With("hi") }, ShouldPanic)
+ })
+ })
+ })
+}

Powered by Google App Engine
This is Rietveld 408576698