From c2ab218bca225ca4b1bef73a94ef5bc7717165b2 Mon Sep 17 00:00:00 2001 From: Joe Tsai Date: Thu, 20 Jul 2017 17:30:04 -0700 Subject: [PATCH] Elide type assertions on unnamed types 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. --- cmp/compare_test.go | 56 ++++++++++++++++++++++++++++++++++++++++++++- cmp/path.go | 13 +++++------ 2 files changed, 61 insertions(+), 8 deletions(-) diff --git a/cmp/compare_test.go b/cmp/compare_test.go index d7d80d5..2c6d2c1 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/rand" @@ -338,7 +339,9 @@ root: } func transformerTests() []test { - const label = "Transformer/" + type JSON string + + const label = "Transformer" return []test{{ label: label, @@ -399,6 +402,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"]: + -: + +: 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 } }