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