Source File
report_slices.go
Belonging Package
github.com/google/go-cmp/cmp
package cmp
import (
)
func ( formatOptions) ( *valueNode) bool {
switch {
case .DiffMode != diffUnknown:
return false // Must be formatting in diff mode
case .NumDiff == 0:
return false // No differences detected
case !.ValueX.IsValid() || !.ValueY.IsValid():
return false // Both values must be valid
case .Type.Kind() == reflect.Slice && (.ValueX.Len() == 0 || .ValueY.Len() == 0):
return false // Both slice values have to be non-empty
case .NumIgnored > 0:
return false // Some ignore option was used
case .NumTransformed > 0:
return false // Some transform option was used
case .NumCompared > 1:
return false // More than one comparison was used
switch .Elem().Kind() {
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr,
reflect.Bool, reflect.Float32, reflect.Float64, reflect.Complex64, reflect.Complex128:
default:
return false
}
func ( formatOptions) ( *valueNode) textNode {
assert(.DiffMode == diffUnknown)
, , := .Type, .ValueX, .ValueY
, := reflect.New().Elem(), reflect.New().Elem()
.Set()
.Set()
, = ,
}
if || {
var , , int
= !utf8.ValidString() || !utf8.ValidString()
for , := range + {
if !(unicode.IsPrint() || unicode.IsSpace()) || == utf8.RuneError {
= true
break
}
if == '\n' {
if < - {
= -
}
= + 1
++
}
}
= !
= && >= 4 && <= 1024
}
case :
:= strings.Split(, "\n")
:= strings.Split(, "\n")
= .formatDiffSlice(
reflect.ValueOf(), reflect.ValueOf(), 1, "line",
func( reflect.Value, diffMode) textRecord {
:= formatString(.Index(0).String())
return textRecord{Diff: , Value: textLine()}
},
)
= "\n"
:= true
:= map[string]bool{}
:= map[string]bool{}
var textList
= append(, textRecord{Value: textLine(`"""`), ElideComma: true})
for , := range {
if !.Value.Equal(textEllipsis) {
, := strconv.Unquote(string(.Value.(textLine)))
= strings.TrimPrefix(strings.TrimSuffix(, "\r"), "\r") // trim leading/trailing carriage returns for legacy Windows endline support
:= strings.Map(func( rune) rune {
if unicode.IsSpace() {
return -1 // drop whitespace to avoid visually indistinguishable output
}
return
}, )
:= func( rune) bool {
return unicode.IsPrint() || == '\t' // specially treat tab as printable
}
= !strings.HasPrefix(, `"""`) && !strings.HasPrefix(, "...") && strings.TrimFunc(, ) == ""
switch .Diff {
case diffRemoved:
= && ![]
[] = true
case diffInserted:
= && ![]
[] = true
}
if ! {
break
}
.Value = textLine()
.ElideComma = true
}
if !(.Diff == diffRemoved || .Diff == diffInserted) { // start a new non-adjacent difference group
= map[string]bool{}
= map[string]bool{}
}
= append(, )
}
if := [len()-1]; .Diff == diffIdentical && len(.Value.(textLine)) == 0 {
= [:len()-1] // elide single empty line at the end
}
= append(, textRecord{Value: textLine(`"""`), ElideComma: true})
if {
var textNode = &textWrap{Prefix: "(", Value: , Suffix: ")"}
switch .Kind() {
case reflect.String:
if != reflect.TypeOf(string("")) {
= .FormatType(, )
}
= .WithTypeMode(emitType)
= .FormatType(, )
}
return
}
case :
= .formatDiffSlice(
reflect.ValueOf(), reflect.ValueOf(), 64, "byte",
func( reflect.Value, diffMode) textRecord {
:= formatString(.String())
return textRecord{Diff: , Value: textLine()}
},
)
= ""
case :
= .formatDiffSlice(
reflect.ValueOf(), reflect.ValueOf(), 16, "byte",
func( reflect.Value, diffMode) textRecord {
var []string
for := 0; < .Len(); ++ {
= append(, formatHex(.Index().Uint()))
}
:= strings.Join(, ", ")
:= commentString(fmt.Sprintf("%c|%v|", , formatASCII(.String())))
return textRecord{Diff: , Value: textLine(), Comment: }
},
)
default:
var int
if .Elem().Kind() == reflect.Bool {
= 16
} else {
switch .Elem().Bits() {
case 8:
= 16
case 16:
= 12
case 32:
= 8
default:
= 8
}
}
= .formatDiffSlice(
, , , .Elem().Kind().String(),
func( reflect.Value, diffMode) textRecord {
var []string
for := 0; < .Len(); ++ {
switch .Elem().Kind() {
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
= append(, fmt.Sprint(.Index().Int()))
case reflect.Uint, reflect.Uint16, reflect.Uint32, reflect.Uint64:
= append(, fmt.Sprint(.Index().Uint()))
case reflect.Uint8, reflect.Uintptr:
= append(, formatHex(.Index().Uint()))
case reflect.Bool, reflect.Float32, reflect.Float64, reflect.Complex64, reflect.Complex128:
= append(, fmt.Sprint(.Index().Interface()))
}
}
:= strings.Join(, ", ")
return textRecord{Diff: , Value: textLine()}
},
)
}
if .Kind() == reflect.String {
= .WithTypeMode(emitType)
}
return .FormatType(, )
}
switch .Kind() {
case reflect.String:
= &textWrap{Prefix: "strings.Join(", Value: , Suffix: fmt.Sprintf(", %q)", )}
if != reflect.TypeOf(string("")) {
= .FormatType(, )
}
case reflect.Slice:
= &textWrap{Prefix: "bytes.Join(", Value: , Suffix: fmt.Sprintf(", %q)", )}
if != reflect.TypeOf([]byte(nil)) {
= .FormatType(, )
}
}
return
}
func ( string) string {
:= bytes.Repeat([]byte{'.'}, len())
for := 0; < len(); ++ {
if ' ' <= [] && [] <= '~' {
[] = []
}
}
return string()
}
func ( formatOptions) (
, reflect.Value, int, string,
func(reflect.Value, diffMode) textRecord,
) ( textList) {
:= diff.Difference(.Len(), .Len(), func( int, int) diff.Result {
return diff.BoolResult(.Index().Interface() == .Index().Interface())
})
:= func( reflect.Value, diffMode) int {
:= .Len()
for .Len() > 0 {
:=
if > .Len() {
= .Len()
}
= append(, (.Slice(0, ), ))
= .Slice(, .Len())
}
return - .Len()
}
var int
:= -1
if .LimitVerbosity {
= (1 << .verbosity()) << 2 // 4, 8, 16, 32, 64, etc...
.VerbosityLevel--
}
:= coalesceAdjacentEdits(, )
= coalesceInterveningIdentical(, /4)
:= diffStats{Name: }
for , := range {
if >= 0 && >= {
= .Append()
continue
}
var , int
:= .NumIgnored + .NumIdentical
for < *numContextRecords && + < && != 0 {
++
}
for < *numContextRecords && + < && != len()-1 {
++
}
if -(+) <= && .NumIgnored == 0 {
= - // Avoid pointless coalescing of single equal row
}
(.Slice(0, ), diffIdentical)
if > + {
.NumIdentical -= +
.AppendEllipsis()
}
(.Slice(-, ), diffIdentical)
= .Slice(, .Len())
= .Slice(, .Len())
continue
}
:= len()
:= (.Slice(0, .NumIdentical+.NumRemoved+.NumModified), diffRemoved)
= .Slice(, .Len())
:= (.Slice(0, .NumIdentical+.NumInserted+.NumModified), diffInserted)
= .Slice(, .Len())
+= len() -
}
if .IsZero() {
assert(.Len() == 0 && .Len() == 0)
} else {
.AppendEllipsis()
}
return
}
func ( string, diff.EditScript) ( []diffStats) {
var int // Arbitrary index into which case last occurred
:= func( int) *diffStats {
if != {
= append(, diffStats{Name: })
=
}
return &[len()-1]
}
for , := range {
switch {
case diff.Identity:
(1).NumIdentical++
case diff.UniqueX:
(2).NumRemoved++
case diff.UniqueY:
(2).NumInserted++
case diff.Modified:
(2).NumModified++
}
}
return
}
func ( []diffStats, int) []diffStats {
, := [:0],
for , := range {
if len() >= 2 && .NumDiff() > 0 {
:= &[len()-2] // Unequal group
:= &[len()-1] // Equal group
:= &[] // Unequal group
, := .NumRemoved > 0, .NumInserted > 0
, := .NumRemoved > 0, .NumInserted > 0
if (( || ) && ( || )) && .NumIdentical <= {
* = .Append(*).Append(*)
= [:len()-1] // Truncate off equal group
continue
}
}
= append(, )
}
return
![]() |
The pages are generated with Golds v0.3.2-preview. (GOOS=darwin GOARCH=amd64) Golds is a Go 101 project developed by Tapir Liu. PR and bug reports are welcome and can be submitted to the issue list. Please follow @Go100and1 (reachable from the left QR code) to get the latest news of Golds. |