How to use String method of diff Package

Best Got code snippet using diff.String

diff.go

Source:diff.go Github

copy

Full Screen

...688		// Edges are the best.689		return 6690	}691	// Each port of this function behaves slightly differently due to subtle differences in each language's definition of things like 'whitespace'.  Since this function's purpose is largely cosmetic, the choice has been made to use each language's native features rather than force total conformity.692	rune1, _ := utf8.DecodeLastRuneInString(one)693	rune2, _ := utf8.DecodeRuneInString(two)694	char1 := string(rune1)695	char2 := string(rune2)696	nonAlphaNumeric1 := nonAlphaNumericRegex.MatchString(char1)697	nonAlphaNumeric2 := nonAlphaNumericRegex.MatchString(char2)698	whitespace1 := nonAlphaNumeric1 && whitespaceRegex.MatchString(char1)699	whitespace2 := nonAlphaNumeric2 && whitespaceRegex.MatchString(char2)700	lineBreak1 := whitespace1 && linebreakRegex.MatchString(char1)701	lineBreak2 := whitespace2 && linebreakRegex.MatchString(char2)702	blankLine1 := lineBreak1 && blanklineEndRegex.MatchString(one)703	blankLine2 := lineBreak2 && blanklineEndRegex.MatchString(two)704	if blankLine1 || blankLine2 {705		// Five points for blank lines.706		return 5707	} else if lineBreak1 || lineBreak2 {708		// Four points for line breaks.709		return 4710	} else if nonAlphaNumeric1 && !whitespace1 && whitespace2 {711		// Three points for end of sentences.712		return 3713	} else if whitespace1 || whitespace2 {714		// Two points for whitespace.715		return 2716	} else if nonAlphaNumeric1 || nonAlphaNumeric2 {717		// One point for non-alphanumeric.718		return 1719	}720	return 0721}722// DiffCleanupSemanticLossless looks for single edits surrounded on both sides by equalities which can be shifted sideways to align the edit to a word boundary.723// E.g: The c<ins>at c</ins>ame. -> The <ins>cat </ins>came.724func (dmp *DiffMatchPatch) DiffCleanupSemanticLossless(diffs []Diff) []Diff {725	pointer := 1726	// Intentionally ignore the first and last element (don't need checking).727	for pointer < len(diffs)-1 {728		if diffs[pointer-1].Type == DiffEqual &&729			diffs[pointer+1].Type == DiffEqual {730			// This is a single edit surrounded by equalities.731			equality1 := diffs[pointer-1].Text732			edit := diffs[pointer].Text733			equality2 := diffs[pointer+1].Text734			// First, shift the edit as far left as possible.735			commonOffset := dmp.DiffCommonSuffix(equality1, edit)736			if commonOffset > 0 {737				commonString := edit[len(edit)-commonOffset:]738				equality1 = equality1[0 : len(equality1)-commonOffset]739				edit = commonString + edit[:len(edit)-commonOffset]740				equality2 = commonString + equality2741			}742			// Second, step character by character right, looking for the best fit.743			bestEquality1 := equality1744			bestEdit := edit745			bestEquality2 := equality2746			bestScore := diffCleanupSemanticScore(equality1, edit) +747				diffCleanupSemanticScore(edit, equality2)748			for len(edit) != 0 && len(equality2) != 0 {749				_, sz := utf8.DecodeRuneInString(edit)750				if len(equality2) < sz || edit[:sz] != equality2[:sz] {751					break752				}753				equality1 += edit[:sz]754				edit = edit[sz:] + equality2[:sz]755				equality2 = equality2[sz:]756				score := diffCleanupSemanticScore(equality1, edit) +757					diffCleanupSemanticScore(edit, equality2)758				// The >= encourages trailing rather than leading whitespace on edits.759				if score >= bestScore {760					bestScore = score761					bestEquality1 = equality1762					bestEdit = edit763					bestEquality2 = equality2764				}765			}766			if diffs[pointer-1].Text != bestEquality1 {767				// We have an improvement, save it back to the diff.768				if len(bestEquality1) != 0 {769					diffs[pointer-1].Text = bestEquality1770				} else {771					diffs = splice(diffs, pointer-1, 1)772					pointer--773				}774				diffs[pointer].Text = bestEdit775				if len(bestEquality2) != 0 {776					diffs[pointer+1].Text = bestEquality2777				} else {778					diffs = append(diffs[:pointer+1], diffs[pointer+2:]...)779					pointer--780				}781			}782		}783		pointer++784	}785	return diffs786}787// DiffCleanupEfficiency reduces the number of edits by eliminating operationally trivial equalities.788func (dmp *DiffMatchPatch) DiffCleanupEfficiency(diffs []Diff) []Diff {789	changes := false790	// Stack of indices where equalities are found.791	type equality struct {792		data int793		next *equality794	}795	var equalities *equality796	// Always equal to equalities[equalitiesLength-1][1]797	lastequality := ""798	pointer := 0 // Index of current position.799	// Is there an insertion operation before the last equality.800	preIns := false801	// Is there a deletion operation before the last equality.802	preDel := false803	// Is there an insertion operation after the last equality.804	postIns := false805	// Is there a deletion operation after the last equality.806	postDel := false807	for pointer < len(diffs) {808		if diffs[pointer].Type == DiffEqual { // Equality found.809			if len(diffs[pointer].Text) < dmp.DiffEditCost &&810				(postIns || postDel) {811				// Candidate found.812				equalities = &equality{813					data: pointer,814					next: equalities,815				}816				preIns = postIns817				preDel = postDel818				lastequality = diffs[pointer].Text819			} else {820				// Not a candidate, and can never become one.821				equalities = nil822				lastequality = ""823			}824			postIns = false825			postDel = false826		} else { // An insertion or deletion.827			if diffs[pointer].Type == DiffDelete {828				postDel = true829			} else {830				postIns = true831			}832			// Five types to be split:833			// <ins>A</ins><del>B</del>XY<ins>C</ins><del>D</del>834			// <ins>A</ins>X<ins>C</ins><del>D</del>835			// <ins>A</ins><del>B</del>X<ins>C</ins>836			// <ins>A</del>X<ins>C</ins><del>D</del>837			// <ins>A</ins><del>B</del>X<del>C</del>838			var sumPres int839			if preIns {840				sumPres++841			}842			if preDel {843				sumPres++844			}845			if postIns {846				sumPres++847			}848			if postDel {849				sumPres++850			}851			if len(lastequality) > 0 &&852				((preIns && preDel && postIns && postDel) ||853					((len(lastequality) < dmp.DiffEditCost/2) && sumPres == 3)) {854				insPoint := equalities.data855				// Duplicate record.856				diffs = splice(diffs, insPoint, 0, Diff{DiffDelete, lastequality})857				// Change second copy to insert.858				diffs[insPoint+1].Type = DiffInsert859				// Throw away the equality we just deleted.860				equalities = equalities.next861				lastequality = ""862				if preIns && preDel {863					// No changes made which could affect previous entry, keep going.864					postIns = true865					postDel = true866					equalities = nil867				} else {868					if equalities != nil {869						equalities = equalities.next870					}871					if equalities != nil {872						pointer = equalities.data873					} else {874						pointer = -1875					}876					postIns = false877					postDel = false878				}879				changes = true880			}881		}882		pointer++883	}884	if changes {885		diffs = dmp.DiffCleanupMerge(diffs)886	}887	return diffs888}889// DiffCleanupMerge reorders and merges like edit sections. Merge equalities.890// Any edit section can move as long as it doesn't cross an equality.891func (dmp *DiffMatchPatch) DiffCleanupMerge(diffs []Diff) []Diff {892	// Add a dummy entry at the end.893	diffs = append(diffs, Diff{DiffEqual, ""})894	pointer := 0895	countDelete := 0896	countInsert := 0897	commonlength := 0898	textDelete := []rune(nil)899	textInsert := []rune(nil)900	for pointer < len(diffs) {901		switch diffs[pointer].Type {902		case DiffInsert:903			countInsert++904			textInsert = append(textInsert, []rune(diffs[pointer].Text)...)905			pointer++906			break907		case DiffDelete:908			countDelete++909			textDelete = append(textDelete, []rune(diffs[pointer].Text)...)910			pointer++911			break912		case DiffEqual:913			// Upon reaching an equality, check for prior redundancies.914			if countDelete+countInsert > 1 {915				if countDelete != 0 && countInsert != 0 {916					// Factor out any common prefixies.917					commonlength = commonPrefixLength(textInsert, textDelete)918					if commonlength != 0 {919						x := pointer - countDelete - countInsert920						if x > 0 && diffs[x-1].Type == DiffEqual {921							diffs[x-1].Text += string(textInsert[:commonlength])922						} else {923							diffs = append([]Diff{Diff{DiffEqual, string(textInsert[:commonlength])}}, diffs...)924							pointer++925						}926						textInsert = textInsert[commonlength:]927						textDelete = textDelete[commonlength:]928					}929					// Factor out any common suffixies.930					commonlength = commonSuffixLength(textInsert, textDelete)931					if commonlength != 0 {932						insertIndex := len(textInsert) - commonlength933						deleteIndex := len(textDelete) - commonlength934						diffs[pointer].Text = string(textInsert[insertIndex:]) + diffs[pointer].Text935						textInsert = textInsert[:insertIndex]936						textDelete = textDelete[:deleteIndex]937					}938				}939				// Delete the offending records and add the merged ones.940				if countDelete == 0 {941					diffs = splice(diffs, pointer-countInsert,942						countDelete+countInsert,943						Diff{DiffInsert, string(textInsert)})944				} else if countInsert == 0 {945					diffs = splice(diffs, pointer-countDelete,946						countDelete+countInsert,947						Diff{DiffDelete, string(textDelete)})948				} else {949					diffs = splice(diffs, pointer-countDelete-countInsert,950						countDelete+countInsert,951						Diff{DiffDelete, string(textDelete)},952						Diff{DiffInsert, string(textInsert)})953				}954				pointer = pointer - countDelete - countInsert + 1955				if countDelete != 0 {956					pointer++957				}958				if countInsert != 0 {959					pointer++960				}961			} else if pointer != 0 && diffs[pointer-1].Type == DiffEqual {962				// Merge this equality with the previous one.963				diffs[pointer-1].Text += diffs[pointer].Text964				diffs = append(diffs[:pointer], diffs[pointer+1:]...)965			} else {966				pointer++967			}968			countInsert = 0969			countDelete = 0970			textDelete = nil971			textInsert = nil972			break973		}974	}975	if len(diffs[len(diffs)-1].Text) == 0 {976		diffs = diffs[0 : len(diffs)-1] // Remove the dummy entry at the end.977	}978	// Second pass: look for single edits surrounded on both sides by equalities which can be shifted sideways to eliminate an equality. E.g: A<ins>BA</ins>C -> <ins>AB</ins>AC979	changes := false980	pointer = 1981	// Intentionally ignore the first and last element (don't need checking).982	for pointer < (len(diffs) - 1) {983		if diffs[pointer-1].Type == DiffEqual &&984			diffs[pointer+1].Type == DiffEqual {985			// This is a single edit surrounded by equalities.986			if strings.HasSuffix(diffs[pointer].Text, diffs[pointer-1].Text) {987				// Shift the edit over the previous equality.988				diffs[pointer].Text = diffs[pointer-1].Text +989					diffs[pointer].Text[:len(diffs[pointer].Text)-len(diffs[pointer-1].Text)]990				diffs[pointer+1].Text = diffs[pointer-1].Text + diffs[pointer+1].Text991				diffs = splice(diffs, pointer-1, 1)992				changes = true993			} else if strings.HasPrefix(diffs[pointer].Text, diffs[pointer+1].Text) {994				// Shift the edit over the next equality.995				diffs[pointer-1].Text += diffs[pointer+1].Text996				diffs[pointer].Text =997					diffs[pointer].Text[len(diffs[pointer+1].Text):] + diffs[pointer+1].Text998				diffs = splice(diffs, pointer+1, 1)999				changes = true1000			}1001		}1002		pointer++1003	}1004	// If shifts were made, the diff needs reordering and another shift sweep.1005	if changes {1006		diffs = dmp.DiffCleanupMerge(diffs)1007	}1008	return diffs1009}1010// DiffXIndex returns the equivalent location in s2.1011func (dmp *DiffMatchPatch) DiffXIndex(diffs []Diff, loc int) int {1012	chars1 := 01013	chars2 := 01014	lastChars1 := 01015	lastChars2 := 01016	lastDiff := Diff{}1017	for i := 0; i < len(diffs); i++ {1018		aDiff := diffs[i]1019		if aDiff.Type != DiffInsert {1020			// Equality or deletion.1021			chars1 += len(aDiff.Text)1022		}1023		if aDiff.Type != DiffDelete {1024			// Equality or insertion.1025			chars2 += len(aDiff.Text)1026		}1027		if chars1 > loc {1028			// Overshot the location.1029			lastDiff = aDiff1030			break1031		}1032		lastChars1 = chars11033		lastChars2 = chars21034	}1035	if lastDiff.Type == DiffDelete {1036		// The location was deleted.1037		return lastChars21038	}1039	// Add the remaining character length.1040	return lastChars2 + (loc - lastChars1)1041}1042// DiffPrettyHtml converts a []Diff into a pretty HTML report.1043// It is intended as an example from which to write one's own display functions.1044func (dmp *DiffMatchPatch) DiffPrettyHtml(diffs []Diff) string {1045	var buff bytes.Buffer1046	for _, diff := range diffs {1047		text := strings.Replace(html.EscapeString(diff.Text), "\n", "&para;<br>", -1)1048		switch diff.Type {1049		case DiffInsert:1050			_, _ = buff.WriteString("<ins style=\"background:#e6ffe6;\">")1051			_, _ = buff.WriteString(text)1052			_, _ = buff.WriteString("</ins>")1053		case DiffDelete:1054			_, _ = buff.WriteString("<del style=\"background:#ffe6e6;\">")1055			_, _ = buff.WriteString(text)1056			_, _ = buff.WriteString("</del>")1057		case DiffEqual:1058			_, _ = buff.WriteString("<span>")1059			_, _ = buff.WriteString(text)1060			_, _ = buff.WriteString("</span>")1061		}1062	}1063	return buff.String()1064}1065// DiffPrettyText converts a []Diff into a colored text report.1066func (dmp *DiffMatchPatch) DiffPrettyText(diffs []Diff) string {1067	var buff bytes.Buffer1068	for _, diff := range diffs {1069		text := diff.Text1070		switch diff.Type {1071		case DiffInsert:1072			_, _ = buff.WriteString("\x1b[32m")1073			_, _ = buff.WriteString(text)1074			_, _ = buff.WriteString("\x1b[0m")1075		case DiffDelete:1076			_, _ = buff.WriteString("\x1b[31m")1077			_, _ = buff.WriteString(text)1078			_, _ = buff.WriteString("\x1b[0m")1079		case DiffEqual:1080			_, _ = buff.WriteString(text)1081		}1082	}1083	return buff.String()1084}1085// DiffText1 computes and returns the source text (all equalities and deletions).1086func (dmp *DiffMatchPatch) DiffText1(diffs []Diff) string {1087	//StringBuilder text = new StringBuilder()1088	var text bytes.Buffer1089	for _, aDiff := range diffs {1090		if aDiff.Type != DiffInsert {1091			_, _ = text.WriteString(aDiff.Text)1092		}1093	}1094	return text.String()1095}1096// DiffText2 computes and returns the destination text (all equalities and insertions).1097func (dmp *DiffMatchPatch) DiffText2(diffs []Diff) string {1098	var text bytes.Buffer1099	for _, aDiff := range diffs {1100		if aDiff.Type != DiffDelete {1101			_, _ = text.WriteString(aDiff.Text)1102		}1103	}1104	return text.String()1105}1106// DiffLevenshtein computes the Levenshtein distance that is the number of inserted, deleted or substituted characters.1107func (dmp *DiffMatchPatch) DiffLevenshtein(diffs []Diff) int {1108	levenshtein := 01109	insertions := 01110	deletions := 01111	for _, aDiff := range diffs {1112		switch aDiff.Type {1113		case DiffInsert:1114			insertions += utf8.RuneCountInString(aDiff.Text)1115		case DiffDelete:1116			deletions += utf8.RuneCountInString(aDiff.Text)1117		case DiffEqual:1118			// A deletion and an insertion is one substitution.1119			levenshtein += max(insertions, deletions)1120			insertions = 01121			deletions = 01122		}1123	}1124	levenshtein += max(insertions, deletions)1125	return levenshtein1126}1127// DiffToDelta crushes the diff into an encoded string which describes the operations required to transform text1 into text2.1128// E.g. =3\t-2\t+ing  -> Keep 3 chars, delete 2 chars, insert 'ing'. Operations are tab-separated.  Inserted text is escaped using %xx notation.1129func (dmp *DiffMatchPatch) DiffToDelta(diffs []Diff) string {1130	var text bytes.Buffer1131	for _, aDiff := range diffs {1132		switch aDiff.Type {1133		case DiffInsert:1134			_, _ = text.WriteString("+")1135			_, _ = text.WriteString(strings.Replace(url.QueryEscape(aDiff.Text), "+", " ", -1))1136			_, _ = text.WriteString("\t")1137			break1138		case DiffDelete:1139			_, _ = text.WriteString("-")1140			_, _ = text.WriteString(strconv.Itoa(utf8.RuneCountInString(aDiff.Text)))1141			_, _ = text.WriteString("\t")1142			break1143		case DiffEqual:1144			_, _ = text.WriteString("=")1145			_, _ = text.WriteString(strconv.Itoa(utf8.RuneCountInString(aDiff.Text)))1146			_, _ = text.WriteString("\t")1147			break1148		}1149	}1150	delta := text.String()1151	if len(delta) != 0 {1152		// Strip off trailing tab character.1153		delta = delta[0 : utf8.RuneCountInString(delta)-1]1154		delta = unescaper.Replace(delta)1155	}1156	return delta1157}1158// DiffFromDelta given the original text1, and an encoded string which describes the operations required to transform text1 into text2, comAdde the full diff.1159func (dmp *DiffMatchPatch) DiffFromDelta(text1 string, delta string) (diffs []Diff, err error) {1160	i := 01161	runes := []rune(text1)1162	for _, token := range strings.Split(delta, "\t") {1163		if len(token) == 0 {1164			// Blank tokens are ok (from a trailing \t).1165			continue1166		}1167		// Each token begins with a one character parameter which specifies the operation of this token (delete, insert, equality).1168		param := token[1:]1169		switch op := token[0]; op {1170		case '+':1171			// Decode would Diff all "+" to " "1172			param = strings.Replace(param, "+", "%2b", -1)1173			param, err = url.QueryUnescape(param)1174			if err != nil {1175				return nil, err1176			}1177			if !utf8.ValidString(param) {1178				return nil, fmt.Errorf("invalid UTF-8 token: %q", param)1179			}1180			diffs = append(diffs, Diff{DiffInsert, param})1181		case '=', '-':1182			n, err := strconv.ParseInt(param, 10, 0)1183			if err != nil {1184				return nil, err1185			} else if n < 0 {1186				return nil, errors.New("Negative number in DiffFromDelta: " + param)1187			}1188			i += int(n)1189			// Break out if we are out of bounds, go1.6 can't handle this very well1190			if i > len(runes) {1191				break...

Full Screen

Full Screen

diff_test.go

Source:diff_test.go Github

copy

Full Screen

...18)19func pretty(diffs []Diff) string {20	var w bytes.Buffer21	for i, diff := range diffs {22		_, _ = w.WriteString(fmt.Sprintf("%v. ", i))23		switch diff.Type {24		case DiffInsert:25			_, _ = w.WriteString("DiffIns")26		case DiffDelete:27			_, _ = w.WriteString("DiffDel")28		case DiffEqual:29			_, _ = w.WriteString("DiffEql")30		default:31			_, _ = w.WriteString("Unknown")32		}33		_, _ = w.WriteString(fmt.Sprintf(": %v\n", diff.Text))34	}35	return w.String()36}37func diffRebuildTexts(diffs []Diff) []string {38	texts := []string{"", ""}39	for _, d := range diffs {40		if d.Type != DiffInsert {41			texts[0] += d.Text42		}43		if d.Type != DiffDelete {44			texts[1] += d.Text45		}46	}47	return texts48}49func TestDiffCommonPrefix(t *testing.T) {50	type TestCase struct {51		Name string52		Text1 string53		Text2 string54		Expected int55	}56	dmp := New()57	for i, tc := range []TestCase{58		{"Null", "abc", "xyz", 0},59		{"Non-null", "1234abcdef", "1234xyz", 4},60		{"Whole", "1234", "1234xyz", 4},61	} {62		actual := dmp.DiffCommonPrefix(tc.Text1, tc.Text2)63		assert.Equal(t, tc.Expected, actual, fmt.Sprintf("Test case #%d, %s", i, tc.Name))64	}65}66func BenchmarkDiffCommonPrefix(b *testing.B) {67	s := "ABCDEFGHIJKLMNOPQRSTUVWXYZÅÄÖ"68	dmp := New()69	for i := 0; i < b.N; i++ {70		dmp.DiffCommonPrefix(s, s)71	}72}73func TestCommonPrefixLength(t *testing.T) {74	type TestCase struct {75		Text1 string76		Text2 string77		Expected int78	}79	for i, tc := range []TestCase{80		{"abc", "xyz", 0},81		{"1234abcdef", "1234xyz", 4},82		{"1234", "1234xyz", 4},83	} {84		actual := commonPrefixLength([]rune(tc.Text1), []rune(tc.Text2))85		assert.Equal(t, tc.Expected, actual, fmt.Sprintf("Test case #%d, %#v", i, tc))86	}87}88func TestDiffCommonSuffix(t *testing.T) {89	type TestCase struct {90		Name string91		Text1 string92		Text2 string93		Expected int94	}95	dmp := New()96	for i, tc := range []TestCase{97		{"Null", "abc", "xyz", 0},98		{"Non-null", "abcdef1234", "xyz1234", 4},99		{"Whole", "1234", "xyz1234", 4},100	} {101		actual := dmp.DiffCommonSuffix(tc.Text1, tc.Text2)102		assert.Equal(t, tc.Expected, actual, fmt.Sprintf("Test case #%d, %s", i, tc.Name))103	}104}105var SinkInt int // exported sink var to avoid compiler optimizations in benchmarks106func BenchmarkDiffCommonSuffix(b *testing.B) {107	s := "ABCDEFGHIJKLMNOPQRSTUVWXYZÅÄÖ"108	dmp := New()109	b.ResetTimer()110	for i := 0; i < b.N; i++ {111		SinkInt = dmp.DiffCommonSuffix(s, s)112	}113}114func BenchmarkCommonLength(b *testing.B) {115	data := []struct {116		name string117		x, y []rune118	}{119		{name: "empty", x: nil, y: []rune{}},120		{name: "short", x: []rune("AABCC"), y: []rune("AA-CC")},121		{name: "long",122			x: []rune(strings.Repeat("A", 1000) + "B" + strings.Repeat("C", 1000)),123			y: []rune(strings.Repeat("A", 1000) + "-" + strings.Repeat("C", 1000)),124		},125	}126	b.Run("prefix", func(b *testing.B) {127		for _, d := range data {128			b.Run(d.name, func(b *testing.B) {129				for i := 0; i < b.N; i++ {130					SinkInt = commonPrefixLength(d.x, d.y)131				}132			})133		}134	})135	b.Run("suffix", func(b *testing.B) {136		for _, d := range data {137			b.Run(d.name, func(b *testing.B) {138				for i := 0; i < b.N; i++ {139					SinkInt = commonSuffixLength(d.x, d.y)140				}141			})142		}143	})144}145func TestCommonSuffixLength(t *testing.T) {146	type TestCase struct {147		Text1 string148		Text2 string149		Expected int150	}151	for i, tc := range []TestCase{152		{"abc", "xyz", 0},153		{"abcdef1234", "xyz1234", 4},154		{"1234", "xyz1234", 4},155		{"123", "a3", 1},156	} {157		actual := commonSuffixLength([]rune(tc.Text1), []rune(tc.Text2))158		assert.Equal(t, tc.Expected, actual, fmt.Sprintf("Test case #%d, %#v", i, tc))159	}160}161func TestDiffCommonOverlap(t *testing.T) {162	type TestCase struct {163		Name string164		Text1 string165		Text2 string166		Expected int167	}168	dmp := New()169	for i, tc := range []TestCase{170		{"Null", "", "abcd", 0},171		{"Whole", "abc", "abcd", 3},172		{"Null", "123456", "abcd", 0},173		{"Null", "123456xxx", "xxxabcd", 3},174		// Some overly clever languages (C#) may treat ligatures as equal to their component letters, e.g. U+FB01 == 'fi'175		{"Unicode", "fi", "\ufb01i", 0},176	} {177		actual := dmp.DiffCommonOverlap(tc.Text1, tc.Text2)178		assert.Equal(t, tc.Expected, actual, fmt.Sprintf("Test case #%d, %s", i, tc.Name))179	}180}181func TestDiffHalfMatch(t *testing.T) {182	type TestCase struct {183		Text1 string184		Text2 string185		Expected []string186	}187	dmp := New()188	dmp.DiffTimeout = 1189	for i, tc := range []TestCase{190		// No match191		{"1234567890", "abcdef", nil},192		{"12345", "23", nil},193		// Single Match194		{"1234567890", "a345678z", []string{"12", "90", "a", "z", "345678"}},195		{"a345678z", "1234567890", []string{"a", "z", "12", "90", "345678"}},196		{"abc56789z", "1234567890", []string{"abc", "z", "1234", "0", "56789"}},197		{"a23456xyz", "1234567890", []string{"a", "xyz", "1", "7890", "23456"}},198		// Multiple Matches199		{"121231234123451234123121", "a1234123451234z", []string{"12123", "123121", "a", "z", "1234123451234"}},200		{"x-=-=-=-=-=-=-=-=-=-=-=-=", "xx-=-=-=-=-=-=-=", []string{"", "-=-=-=-=-=", "x", "", "x-=-=-=-=-=-=-="}},201		{"-=-=-=-=-=-=-=-=-=-=-=-=y", "-=-=-=-=-=-=-=yy", []string{"-=-=-=-=-=", "", "", "y", "-=-=-=-=-=-=-=y"}},202		// Non-optimal halfmatch, ptimal diff would be -q+x=H-i+e=lloHe+Hu=llo-Hew+y not -qHillo+x=HelloHe-w+Hulloy203		{"qHilloHelloHew", "xHelloHeHulloy", []string{"qHillo", "w", "x", "Hulloy", "HelloHe"}},204	} {205		actual := dmp.DiffHalfMatch(tc.Text1, tc.Text2)206		assert.Equal(t, tc.Expected, actual, fmt.Sprintf("Test case #%d, %#v", i, tc))207	}208	dmp.DiffTimeout = 0209	for i, tc := range []TestCase{210		// Optimal no halfmatch211		{"qHilloHelloHew", "xHelloHeHulloy", nil},212	} {213		actual := dmp.DiffHalfMatch(tc.Text1, tc.Text2)214		assert.Equal(t, tc.Expected, actual, fmt.Sprintf("Test case #%d, %#v", i, tc))215	}216}217func BenchmarkDiffHalfMatch(b *testing.B) {218	s1, s2 := speedtestTexts()219	dmp := New()220	b.ResetTimer()221	for i := 0; i < b.N; i++ {222		dmp.DiffHalfMatch(s1, s2)223	}224}225func TestDiffBisectSplit(t *testing.T) {226	type TestCase struct {227		Text1 string228		Text2 string229	}230	dmp := New()231	for _, tc := range []TestCase{232		{"STUV\x05WX\x05YZ\x05[", "WĺĻļ\x05YZ\x05ĽľĿŀZ"},233	} {234		diffs := dmp.diffBisectSplit([]rune(tc.Text1),235			[]rune(tc.Text2), 7, 6, time.Now().Add(time.Hour))236		for _, d := range diffs {237			assert.True(t, utf8.ValidString(d.Text))238		}239		// TODO define the expected outcome240	}241}242func TestDiffLinesToChars(t *testing.T) {243	type TestCase struct {244		Text1 string245		Text2 string246		ExpectedChars1 string247		ExpectedChars2 string248		ExpectedLines  []string249	}250	dmp := New()251	for i, tc := range []TestCase{252		{"", "alpha\r\nbeta\r\n\r\n\r\n", "", "\u0001\u0002\u0003\u0003", []string{"", "alpha\r\n", "beta\r\n", "\r\n"}},253		{"a", "b", "\u0001", "\u0002", []string{"", "a", "b"}},254		// Omit final newline.255		{"alpha\nbeta\nalpha", "", "\u0001\u0002\u0003", "", []string{"", "alpha\n", "beta\n", "alpha"}},256	} {257		actualChars1, actualChars2, actualLines := dmp.DiffLinesToChars(tc.Text1, tc.Text2)258		assert.Equal(t, tc.ExpectedChars1, actualChars1, fmt.Sprintf("Test case #%d, %#v", i, tc))259		assert.Equal(t, tc.ExpectedChars2, actualChars2, fmt.Sprintf("Test case #%d, %#v", i, tc))260		assert.Equal(t, tc.ExpectedLines, actualLines, fmt.Sprintf("Test case #%d, %#v", i, tc))261	}262	// More than 256 to reveal any 8-bit limitations.263	n := 300264	lineList := []string{265		"", // Account for the initial empty element of the lines array.266	}267	var charList []rune268	for x := 1; x < n+1; x++ {269		lineList = append(lineList, strconv.Itoa(x)+"\n")270		charList = append(charList, rune(x))271	}272	lines := strings.Join(lineList, "")273	chars := string(charList)274	assert.Equal(t, n, utf8.RuneCountInString(chars))275	actualChars1, actualChars2, actualLines := dmp.DiffLinesToChars(lines, "")276	assert.Equal(t, chars, actualChars1)277	assert.Equal(t, "", actualChars2)278	assert.Equal(t, lineList, actualLines)279}280func TestDiffCharsToLines(t *testing.T) {281	type TestCase struct {282		Diffs []Diff283		Lines []string284		Expected []Diff285	}286	dmp := New()287	for i, tc := range []TestCase{288		{...

Full Screen

Full Screen

String

Using AI Code Generation

copy

Full Screen

1import (2func main() {3    dmp := diffmatchpatch.New()4    d := dmp.DiffMain("Hello World", "Hello Go", false)5    fmt.Println(dmp.DiffPrettyText(d))6}

Full Screen

Full Screen

String

Using AI Code Generation

copy

Full Screen

1import (2func main() {3	dmp := diffmatchpatch.New()4	diffs := dmp.DiffMain(a, b, false)5	fmt.Println(dmp.DiffPrettyText(diffs))6}

Full Screen

Full Screen

String

Using AI Code Generation

copy

Full Screen

1import (2func main() {3    dmp := diffmatchpatch.New()4    d := dmp.DiffMain(a, b, false)5    fmt.Println(dmp.DiffPrettyText(d))6}

Full Screen

Full Screen

String

Using AI Code Generation

copy

Full Screen

1import (2func main() {3    dmp := diffmatchpatch.New()4    d := dmp.DiffMain(a, b, false)5    fmt.Println(dmp.DiffPrettyText(d))6}7import (8func main() {9    dmp := diffmatchpatch.New()10    d := dmp.DiffMain(a, b, false)11    for _, diff := range d {12        fmt.Println(diff.Type, diff.Text)13    }14}

Full Screen

Full Screen

String

Using AI Code Generation

copy

Full Screen

1import (2func main() {3    dmp := diffmatchpatch.New()4    d := dmp.DiffMain(a, b, false)5    fmt.Println(dmp.DiffPrettyText(d))6}

Full Screen

Full Screen

String

Using AI Code Generation

copy

Full Screen

1import (2func main() {3	dmp := diffmatchpatch.New()4	diffs := dmp.DiffMain(a, b, false)5	fmt.Println(dmp.DiffPrettyText(diffs))6}

Full Screen

Full Screen

String

Using AI Code Generation

copy

Full Screen

1import (2func main() {3    differ := gojsondiff.New()4    a := []byte(`{"a": 1, "b": 2}`)5    b := []byte(`{"a": 1, "b": 3}`)6    aJson, err := gojsondiff.NewJson(a)7    if err != nil {8        panic(err)9    }10    bJson, err := gojsondiff.NewJson(b)11    if err != nil {12        panic(err)13    }14    diff := differ.Compare(aJson, bJson)15    if diff.Modified() {16        fmt.Println(diff)17    }18    formatter := formatter.NewAsciiFormatter(aJson, formatter.AsciiFormatterConfig{19    })20    s, err := formatter.Format(diff)21    if err != nil {22        panic(err)23    }24    fmt.Println(s)25}26{"b": [2, 3]}27    {28    }29Related posts: Go: How to format JSON using Go standard library How to format JSON using Go standard library? package main import ( "encoding/json" "fmt" ) func main() { var data = []byte(`{"key1":"value1", "key2":"value2"}`) var v map[string]interface{} err := json.Unmarshal(data, &v) if err != nil { panic(err) } output, err := json.MarshalIndent(v, "", " ") if err != nil { panic(err) } fmt.Println(string(output)) } Output: $ go run 1.go { "key1": "value1", "key2": "value2" } Related posts:

Full Screen

Full Screen

Automation Testing Tutorials

Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.

LambdaTest Learning Hubs:

YouTube

You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful