Path: blob/main/vendor/github.com/google/go-cmp/cmp/report_value.go
2880 views
// Copyright 2019, The Go Authors. All rights reserved.1// Use of this source code is governed by a BSD-style2// license that can be found in the LICENSE file.34package cmp56import "reflect"78// valueNode represents a single node within a report, which is a9// structured representation of the value tree, containing information10// regarding which nodes are equal or not.11type valueNode struct {12parent *valueNode1314Type reflect.Type15ValueX reflect.Value16ValueY reflect.Value1718// NumSame is the number of leaf nodes that are equal.19// All descendants are equal only if NumDiff is 0.20NumSame int21// NumDiff is the number of leaf nodes that are not equal.22NumDiff int23// NumIgnored is the number of leaf nodes that are ignored.24NumIgnored int25// NumCompared is the number of leaf nodes that were compared26// using an Equal method or Comparer function.27NumCompared int28// NumTransformed is the number of non-leaf nodes that were transformed.29NumTransformed int30// NumChildren is the number of transitive descendants of this node.31// This counts from zero; thus, leaf nodes have no descendants.32NumChildren int33// MaxDepth is the maximum depth of the tree. This counts from zero;34// thus, leaf nodes have a depth of zero.35MaxDepth int3637// Records is a list of struct fields, slice elements, or map entries.38Records []reportRecord // If populated, implies Value is not populated3940// Value is the result of a transformation, pointer indirect, of41// type assertion.42Value *valueNode // If populated, implies Records is not populated4344// TransformerName is the name of the transformer.45TransformerName string // If non-empty, implies Value is populated46}47type reportRecord struct {48Key reflect.Value // Invalid for slice element49Value *valueNode50}5152func (parent *valueNode) PushStep(ps PathStep) (child *valueNode) {53vx, vy := ps.Values()54child = &valueNode{parent: parent, Type: ps.Type(), ValueX: vx, ValueY: vy}55switch s := ps.(type) {56case StructField:57assert(parent.Value == nil)58parent.Records = append(parent.Records, reportRecord{Key: reflect.ValueOf(s.Name()), Value: child})59case SliceIndex:60assert(parent.Value == nil)61parent.Records = append(parent.Records, reportRecord{Value: child})62case MapIndex:63assert(parent.Value == nil)64parent.Records = append(parent.Records, reportRecord{Key: s.Key(), Value: child})65case Indirect:66assert(parent.Value == nil && parent.Records == nil)67parent.Value = child68case TypeAssertion:69assert(parent.Value == nil && parent.Records == nil)70parent.Value = child71case Transform:72assert(parent.Value == nil && parent.Records == nil)73parent.Value = child74parent.TransformerName = s.Name()75parent.NumTransformed++76default:77assert(parent == nil) // Must be the root step78}79return child80}8182func (r *valueNode) Report(rs Result) {83assert(r.MaxDepth == 0) // May only be called on leaf nodes8485if rs.ByIgnore() {86r.NumIgnored++87} else {88if rs.Equal() {89r.NumSame++90} else {91r.NumDiff++92}93}94assert(r.NumSame+r.NumDiff+r.NumIgnored == 1)9596if rs.ByMethod() {97r.NumCompared++98}99if rs.ByFunc() {100r.NumCompared++101}102assert(r.NumCompared <= 1)103}104105func (child *valueNode) PopStep() (parent *valueNode) {106if child.parent == nil {107return nil108}109parent = child.parent110parent.NumSame += child.NumSame111parent.NumDiff += child.NumDiff112parent.NumIgnored += child.NumIgnored113parent.NumCompared += child.NumCompared114parent.NumTransformed += child.NumTransformed115parent.NumChildren += child.NumChildren + 1116if parent.MaxDepth < child.MaxDepth+1 {117parent.MaxDepth = child.MaxDepth + 1118}119return parent120}121122123