104 lines
		
	
	
		
			2.1 KiB
		
	
	
	
		
			Go
		
	
	
	
			
		
		
	
	
			104 lines
		
	
	
		
			2.1 KiB
		
	
	
	
		
			Go
		
	
	
	
package testhelper
 | 
						|
 | 
						|
import (
 | 
						|
	"bytes"
 | 
						|
	"fmt"
 | 
						|
	"io"
 | 
						|
	"math"
 | 
						|
	"strings"
 | 
						|
 | 
						|
	"github.com/aryann/difflib"
 | 
						|
)
 | 
						|
 | 
						|
func Diff(want, got string, context int) (string, bool) {
 | 
						|
	records := difflib.Diff(
 | 
						|
		strings.Split(want, "\n"),
 | 
						|
		strings.Split(got, "\n"),
 | 
						|
	)
 | 
						|
 | 
						|
	w := &bytes.Buffer{}
 | 
						|
 | 
						|
	changed := checkAndPrintRecords(w, records, context)
 | 
						|
 | 
						|
	return w.String(), changed
 | 
						|
}
 | 
						|
 | 
						|
func checkAndPrintRecords(w io.Writer, records []difflib.DiffRecord, context int) bool {
 | 
						|
	var changed bool
 | 
						|
	if context >= 0 {
 | 
						|
		distances := calculateDistances(records)
 | 
						|
		omitting := false
 | 
						|
		for i, diff := range records {
 | 
						|
			if diff.Delta != difflib.Common {
 | 
						|
				changed = true
 | 
						|
			}
 | 
						|
			if distances[i] > context {
 | 
						|
				if !omitting {
 | 
						|
					fmt.Fprintln(w, "...")
 | 
						|
					omitting = true
 | 
						|
				}
 | 
						|
			} else {
 | 
						|
				omitting = false
 | 
						|
				fmt.Fprintln(w, formatRecord(diff))
 | 
						|
			}
 | 
						|
		}
 | 
						|
	} else {
 | 
						|
		for _, diff := range records {
 | 
						|
			if diff.Delta != difflib.Common {
 | 
						|
				changed = true
 | 
						|
			}
 | 
						|
			fmt.Fprintln(w, formatRecord(diff))
 | 
						|
		}
 | 
						|
	}
 | 
						|
	return changed
 | 
						|
}
 | 
						|
 | 
						|
func formatRecord(diff difflib.DiffRecord) string {
 | 
						|
	var prefix string
 | 
						|
	switch diff.Delta {
 | 
						|
	case difflib.RightOnly:
 | 
						|
		prefix = "+ "
 | 
						|
	case difflib.LeftOnly:
 | 
						|
		prefix = "- "
 | 
						|
	case difflib.Common:
 | 
						|
		prefix = "  "
 | 
						|
	}
 | 
						|
 | 
						|
	return prefix + diff.Payload
 | 
						|
}
 | 
						|
 | 
						|
// Shamelessly and thankfully copied from https://github.com/databus23/helm-diff/blob/99b8474af7726ca6f57b37b0b8b8f3cd36c991e8/diff/diff.go#L116
 | 
						|
func calculateDistances(diffs []difflib.DiffRecord) map[int]int {
 | 
						|
	distances := map[int]int{}
 | 
						|
 | 
						|
	// Iterate forwards through diffs, set 'distance' based on closest 'change' before this line
 | 
						|
	change := -1
 | 
						|
	for i, diff := range diffs {
 | 
						|
		if diff.Delta != difflib.Common {
 | 
						|
			change = i
 | 
						|
		}
 | 
						|
		distance := math.MaxInt32
 | 
						|
		if change != -1 {
 | 
						|
			distance = i - change
 | 
						|
		}
 | 
						|
		distances[i] = distance
 | 
						|
	}
 | 
						|
 | 
						|
	// Iterate backwards through diffs, reduce 'distance' based on closest 'change' after this line
 | 
						|
	change = -1
 | 
						|
	for i := len(diffs) - 1; i >= 0; i-- {
 | 
						|
		diff := diffs[i]
 | 
						|
		if diff.Delta != difflib.Common {
 | 
						|
			change = i
 | 
						|
		}
 | 
						|
		if change != -1 {
 | 
						|
			distance := change - i
 | 
						|
			if distance < distances[i] {
 | 
						|
				distances[i] = distance
 | 
						|
			}
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	return distances
 | 
						|
}
 |