aboutsummaryrefslogtreecommitdiff
path: root/cmp
diff options
context:
space:
mode:
authorJoe Tsai <joetsai@digital-static.net>2017-09-27 13:40:59 -0700
committerGitHub <noreply@github.com>2017-09-27 13:40:59 -0700
commitf46009a0a1e3526b07f548b2f80f73a4d2d32716 (patch)
tree0a8f94963202dc6dc9b51f61f81f9c3eb2fa9324 /cmp
parentef1ad5f71f8f469505d1c9853a7493042115dcfa (diff)
downloadgo-cmp-f46009a0a1e3526b07f548b2f80f73a4d2d32716.tar.gz
Elide type assertions on unnamed types (#21)
Many of the powerful uses of Transformers produces a significant amount of interfaces to anonymous types. For example, a generic JSON unmarshaler can unmarshal into a map[string]interface{} or []interface{}. However, the printing of these type assertions can be really noisy. Thus, elide type assertions for these cases.
Diffstat (limited to 'cmp')
-rw-r--r--cmp/compare_test.go56
-rw-r--r--cmp/path.go13
2 files changed, 61 insertions, 8 deletions
diff --git a/cmp/compare_test.go b/cmp/compare_test.go
index 36a4ecf..c60262c 100644
--- a/cmp/compare_test.go
+++ b/cmp/compare_test.go
@@ -7,6 +7,7 @@ package cmp_test
import (
"bytes"
"crypto/md5"
+ "encoding/json"
"fmt"
"io"
"math"
@@ -357,7 +358,9 @@ root:
}
func transformerTests() []test {
- const label = "Transformer/"
+ type JSON string
+
+ const label = "Transformer"
return []test{{
label: label,
@@ -418,6 +421,57 @@ func transformerTests() []test {
λ({int}):
-: "string"
+: 1`,
+ }, {
+ label: label,
+ x: JSON(`{
+ "firstName": "John",
+ "lastName": "Smith",
+ "age": 25,
+ "isAlive": true,
+ "address": {
+ "city": "Los Angeles",
+ "postalCode": "10021-3100",
+ "state": "CA",
+ "streetAddress": "21 2nd Street"
+ },
+ "phoneNumbers": [{
+ "type": "home",
+ "number": "212 555-4321"
+ },{
+ "type": "office",
+ "number": "646 555-4567"
+ },{
+ "number": "123 456-7890",
+ "type": "mobile"
+ }],
+ "children": []
+ }`),
+ y: JSON(`{"firstName":"John","lastName":"Smith","isAlive":true,"age":25,
+ "address":{"streetAddress":"21 2nd Street","city":"New York",
+ "state":"NY","postalCode":"10021-3100"},"phoneNumbers":[{"type":"home",
+ "number":"212 555-1234"},{"type":"office","number":"646 555-4567"},{
+ "type":"mobile","number":"123 456-7890"}],"children":[],"spouse":null}`),
+ opts: []cmp.Option{
+ cmp.Transformer("ParseJSON", func(s JSON) (m map[string]interface{}) {
+ if err := json.Unmarshal([]byte(s), &m); err != nil {
+ panic(err)
+ }
+ return m
+ }),
+ },
+ wantDiff: `
+ParseJSON({cmp_test.JSON})["address"]["city"]:
+ -: "Los Angeles"
+ +: "New York"
+ParseJSON({cmp_test.JSON})["address"]["state"]:
+ -: "CA"
+ +: "NY"
+ParseJSON({cmp_test.JSON})["phoneNumbers"][0]["number"]:
+ -: "212 555-4321"
+ +: "212 555-1234"
+ParseJSON({cmp_test.JSON})["spouse"]:
+ -: <non-existent>
+ +: interface {}(nil)`,
}}
}
diff --git a/cmp/path.go b/cmp/path.go
index 0c2eb33..76d73f7 100644
--- a/cmp/path.go
+++ b/cmp/path.go
@@ -150,13 +150,12 @@ func (pa Path) GoString() string {
ssPost = append(ssPost, ")")
continue
case *typeAssertion:
- // Elide type assertions immediately following a transform to
- // prevent overly verbose path printouts.
- // Some transforms return interface{} because of Go's lack of
- // generics, but typically take in and return the exact same
- // concrete type. Other times, the transform creates an anonymous
- // struct, which will be very verbose to print.
- if _, ok := nextStep.(*transform); ok {
+ // As a special-case, elide type assertions on anonymous types
+ // since they are typically generated dynamically and can be very
+ // verbose. For example, some transforms return interface{} because
+ // of Go's lack of generics, but typically take in and return the
+ // exact same concrete type.
+ if s.Type().PkgPath() == "" {
continue
}
}