...

Source file src/go.mongodb.org/mongo-driver/internal/assert/difflib_test.go

Documentation: go.mongodb.org/mongo-driver/internal/assert

     1  // Copied from https://github.com/pmezard/go-difflib/blob/5d4384ee4fb2527b0a1256a821ebfc92f91efefc/difflib/difflib_test.go
     2  
     3  // Copyright 2013 Patrick Mezard. All rights reserved. Use of this source code is
     4  // governed by a license that can be found in the THIRD-PARTY-NOTICES file.
     5  
     6  package assert
     7  
     8  import (
     9  	"bytes"
    10  	"fmt"
    11  	"math"
    12  	"reflect"
    13  	"strings"
    14  	"testing"
    15  )
    16  
    17  func assertAlmostEqual(t *testing.T, a, b float64, places int) {
    18  	if math.Abs(a-b) > math.Pow10(-places) {
    19  		t.Errorf("%.7f != %.7f", a, b)
    20  	}
    21  }
    22  
    23  func assertEqual(t *testing.T, a, b interface{}) {
    24  	if !reflect.DeepEqual(a, b) {
    25  		t.Errorf("%v != %v", a, b)
    26  	}
    27  }
    28  
    29  func splitChars(s string) []string {
    30  	chars := make([]string, 0, len(s))
    31  	// Assume ASCII inputs
    32  	for i := 0; i != len(s); i++ {
    33  		chars = append(chars, string(s[i]))
    34  	}
    35  	return chars
    36  }
    37  
    38  func TestSequenceMatcherRatio(t *testing.T) {
    39  	s := NewMatcher(splitChars("abcd"), splitChars("bcde"))
    40  	assertEqual(t, s.Ratio(), 0.75)
    41  	assertEqual(t, s.QuickRatio(), 0.75)
    42  	assertEqual(t, s.RealQuickRatio(), 1.0)
    43  }
    44  
    45  func TestGetOptCodes(t *testing.T) {
    46  	a := "qabxcd"
    47  	b := "abycdf"
    48  	s := NewMatcher(splitChars(a), splitChars(b))
    49  	w := &bytes.Buffer{}
    50  	for _, op := range s.GetOpCodes() {
    51  		fmt.Fprintf(w, "%s a[%d:%d], (%s) b[%d:%d] (%s)\n", string(op.Tag),
    52  			op.I1, op.I2, a[op.I1:op.I2], op.J1, op.J2, b[op.J1:op.J2])
    53  	}
    54  	result := w.String()
    55  	expected := `d a[0:1], (q) b[0:0] ()
    56  e a[1:3], (ab) b[0:2] (ab)
    57  r a[3:4], (x) b[2:3] (y)
    58  e a[4:6], (cd) b[3:5] (cd)
    59  i a[6:6], () b[5:6] (f)
    60  `
    61  	if expected != result {
    62  		t.Errorf("unexpected op codes: \n%s", result)
    63  	}
    64  }
    65  
    66  func TestGroupedOpCodes(t *testing.T) {
    67  	a := []string{}
    68  	for i := 0; i != 39; i++ {
    69  		a = append(a, fmt.Sprintf("%02d", i))
    70  	}
    71  	b := []string{}
    72  	b = append(b, a[:8]...)
    73  	b = append(b, " i")
    74  	b = append(b, a[8:19]...)
    75  	b = append(b, " x")
    76  	b = append(b, a[20:22]...)
    77  	b = append(b, a[27:34]...)
    78  	b = append(b, " y")
    79  	b = append(b, a[35:]...)
    80  	s := NewMatcher(a, b)
    81  	w := &bytes.Buffer{}
    82  	for _, g := range s.GetGroupedOpCodes(-1) {
    83  		fmt.Fprintf(w, "group\n")
    84  		for _, op := range g {
    85  			fmt.Fprintf(w, "  %s, %d, %d, %d, %d\n", string(op.Tag),
    86  				op.I1, op.I2, op.J1, op.J2)
    87  		}
    88  	}
    89  	result := w.String()
    90  	expected := `group
    91    e, 5, 8, 5, 8
    92    i, 8, 8, 8, 9
    93    e, 8, 11, 9, 12
    94  group
    95    e, 16, 19, 17, 20
    96    r, 19, 20, 20, 21
    97    e, 20, 22, 21, 23
    98    d, 22, 27, 23, 23
    99    e, 27, 30, 23, 26
   100  group
   101    e, 31, 34, 27, 30
   102    r, 34, 35, 30, 31
   103    e, 35, 38, 31, 34
   104  `
   105  	if expected != result {
   106  		t.Errorf("unexpected op codes: \n%s", result)
   107  	}
   108  }
   109  
   110  func rep(s string, count int) string {
   111  	return strings.Repeat(s, count)
   112  }
   113  
   114  func TestWithAsciiOneInsert(t *testing.T) {
   115  	sm := NewMatcher(splitChars(rep("b", 100)),
   116  		splitChars("a"+rep("b", 100)))
   117  	assertAlmostEqual(t, sm.Ratio(), 0.995, 3)
   118  	assertEqual(t, sm.GetOpCodes(),
   119  		[]OpCode{{'i', 0, 0, 0, 1}, {'e', 0, 100, 1, 101}})
   120  	assertEqual(t, len(sm.bPopular), 0)
   121  
   122  	sm = NewMatcher(splitChars(rep("b", 100)),
   123  		splitChars(rep("b", 50)+"a"+rep("b", 50)))
   124  	assertAlmostEqual(t, sm.Ratio(), 0.995, 3)
   125  	assertEqual(t, sm.GetOpCodes(),
   126  		[]OpCode{{'e', 0, 50, 0, 50}, {'i', 50, 50, 50, 51}, {'e', 50, 100, 51, 101}})
   127  	assertEqual(t, len(sm.bPopular), 0)
   128  }
   129  
   130  func TestWithAsciiOnDelete(t *testing.T) {
   131  	sm := NewMatcher(splitChars(rep("a", 40)+"c"+rep("b", 40)),
   132  		splitChars(rep("a", 40)+rep("b", 40)))
   133  	assertAlmostEqual(t, sm.Ratio(), 0.994, 3)
   134  	assertEqual(t, sm.GetOpCodes(),
   135  		[]OpCode{{'e', 0, 40, 0, 40}, {'d', 40, 41, 40, 40}, {'e', 41, 81, 40, 80}})
   136  }
   137  
   138  func TestWithAsciiBJunk(t *testing.T) {
   139  	isJunk := func(s string) bool {
   140  		return s == " "
   141  	}
   142  	sm := NewMatcherWithJunk(splitChars(rep("a", 40)+rep("b", 40)),
   143  		splitChars(rep("a", 44)+rep("b", 40)), true, isJunk)
   144  	assertEqual(t, sm.bJunk, map[string]struct{}{})
   145  
   146  	sm = NewMatcherWithJunk(splitChars(rep("a", 40)+rep("b", 40)),
   147  		splitChars(rep("a", 44)+rep("b", 40)+rep(" ", 20)), false, isJunk)
   148  	assertEqual(t, sm.bJunk, map[string]struct{}{" ": struct{}{}})
   149  
   150  	isJunk = func(s string) bool {
   151  		return s == " " || s == "b"
   152  	}
   153  	sm = NewMatcherWithJunk(splitChars(rep("a", 40)+rep("b", 40)),
   154  		splitChars(rep("a", 44)+rep("b", 40)+rep(" ", 20)), false, isJunk)
   155  	assertEqual(t, sm.bJunk, map[string]struct{}{" ": struct{}{}, "b": struct{}{}})
   156  }
   157  
   158  func TestSFBugsRatioForNullSeqn(t *testing.T) {
   159  	sm := NewMatcher(nil, nil)
   160  	assertEqual(t, sm.Ratio(), 1.0)
   161  	assertEqual(t, sm.QuickRatio(), 1.0)
   162  	assertEqual(t, sm.RealQuickRatio(), 1.0)
   163  }
   164  
   165  func TestSFBugsComparingEmptyLists(t *testing.T) {
   166  	groups := NewMatcher(nil, nil).GetGroupedOpCodes(-1)
   167  	assertEqual(t, len(groups), 0)
   168  	diff := UnifiedDiff{
   169  		FromFile: "Original",
   170  		ToFile:   "Current",
   171  		Context:  3,
   172  	}
   173  	result, err := GetUnifiedDiffString(diff)
   174  	assertEqual(t, err, nil)
   175  	assertEqual(t, result, "")
   176  }
   177  
   178  func TestOutputFormatRangeFormatUnified(t *testing.T) {
   179  	// Per the diff spec at http://www.unix.org/single_unix_specification/
   180  	//
   181  	// Each <range> field shall be of the form:
   182  	//   %1d", <beginning line number>  if the range contains exactly one line,
   183  	// and:
   184  	//  "%1d,%1d", <beginning line number>, <number of lines> otherwise.
   185  	// If a range is empty, its beginning line number shall be the number of
   186  	// the line just before the range, or 0 if the empty range starts the file.
   187  	fm := formatRangeUnified
   188  	assertEqual(t, fm(3, 3), "3,0")
   189  	assertEqual(t, fm(3, 4), "4")
   190  	assertEqual(t, fm(3, 5), "4,2")
   191  	assertEqual(t, fm(3, 6), "4,3")
   192  	assertEqual(t, fm(0, 0), "0,0")
   193  }
   194  
   195  func TestOutputFormatRangeFormatContext(t *testing.T) {
   196  	// Per the diff spec at http://www.unix.org/single_unix_specification/
   197  	//
   198  	// The range of lines in file1 shall be written in the following format
   199  	// if the range contains two or more lines:
   200  	//     "*** %d,%d ****\n", <beginning line number>, <ending line number>
   201  	// and the following format otherwise:
   202  	//     "*** %d ****\n", <ending line number>
   203  	// The ending line number of an empty range shall be the number of the preceding line,
   204  	// or 0 if the range is at the start of the file.
   205  	//
   206  	// Next, the range of lines in file2 shall be written in the following format
   207  	// if the range contains two or more lines:
   208  	//     "--- %d,%d ----\n", <beginning line number>, <ending line number>
   209  	// and the following format otherwise:
   210  	//     "--- %d ----\n", <ending line number>
   211  	fm := formatRangeContext
   212  	assertEqual(t, fm(3, 3), "3")
   213  	assertEqual(t, fm(3, 4), "4")
   214  	assertEqual(t, fm(3, 5), "4,5")
   215  	assertEqual(t, fm(3, 6), "4,6")
   216  	assertEqual(t, fm(0, 0), "0")
   217  }
   218  
   219  func TestOutputFormatTabDelimiter(t *testing.T) {
   220  	diff := UnifiedDiff{
   221  		A:        splitChars("one"),
   222  		B:        splitChars("two"),
   223  		FromFile: "Original",
   224  		FromDate: "2005-01-26 23:30:50",
   225  		ToFile:   "Current",
   226  		ToDate:   "2010-04-12 10:20:52",
   227  		Eol:      "\n",
   228  	}
   229  	ud, err := GetUnifiedDiffString(diff)
   230  	assertEqual(t, err, nil)
   231  	assertEqual(t, SplitLines(ud)[:2], []string{
   232  		"--- Original\t2005-01-26 23:30:50\n",
   233  		"+++ Current\t2010-04-12 10:20:52\n",
   234  	})
   235  	cd, err := GetContextDiffString(ContextDiff(diff))
   236  	assertEqual(t, err, nil)
   237  	assertEqual(t, SplitLines(cd)[:2], []string{
   238  		"*** Original\t2005-01-26 23:30:50\n",
   239  		"--- Current\t2010-04-12 10:20:52\n",
   240  	})
   241  }
   242  
   243  func TestOutputFormatNoTrailingTabOnEmptyFiledate(t *testing.T) {
   244  	diff := UnifiedDiff{
   245  		A:        splitChars("one"),
   246  		B:        splitChars("two"),
   247  		FromFile: "Original",
   248  		ToFile:   "Current",
   249  		Eol:      "\n",
   250  	}
   251  	ud, err := GetUnifiedDiffString(diff)
   252  	assertEqual(t, err, nil)
   253  	assertEqual(t, SplitLines(ud)[:2], []string{"--- Original\n", "+++ Current\n"})
   254  
   255  	cd, err := GetContextDiffString(ContextDiff(diff))
   256  	assertEqual(t, err, nil)
   257  	assertEqual(t, SplitLines(cd)[:2], []string{"*** Original\n", "--- Current\n"})
   258  }
   259  
   260  func TestOmitFilenames(t *testing.T) {
   261  	diff := UnifiedDiff{
   262  		A:   SplitLines("o\nn\ne\n"),
   263  		B:   SplitLines("t\nw\no\n"),
   264  		Eol: "\n",
   265  	}
   266  	ud, err := GetUnifiedDiffString(diff)
   267  	assertEqual(t, err, nil)
   268  	assertEqual(t, SplitLines(ud), []string{
   269  		"@@ -0,0 +1,2 @@\n",
   270  		"+t\n",
   271  		"+w\n",
   272  		"@@ -2,2 +3,0 @@\n",
   273  		"-n\n",
   274  		"-e\n",
   275  		"\n",
   276  	})
   277  
   278  	cd, err := GetContextDiffString(ContextDiff(diff))
   279  	assertEqual(t, err, nil)
   280  	assertEqual(t, SplitLines(cd), []string{
   281  		"***************\n",
   282  		"*** 0 ****\n",
   283  		"--- 1,2 ----\n",
   284  		"+ t\n",
   285  		"+ w\n",
   286  		"***************\n",
   287  		"*** 2,3 ****\n",
   288  		"- n\n",
   289  		"- e\n",
   290  		"--- 3 ----\n",
   291  		"\n",
   292  	})
   293  }
   294  
   295  func TestSplitLines(t *testing.T) {
   296  	allTests := []struct {
   297  		input string
   298  		want  []string
   299  	}{
   300  		{"foo", []string{"foo\n"}},
   301  		{"foo\nbar", []string{"foo\n", "bar\n"}},
   302  		{"foo\nbar\n", []string{"foo\n", "bar\n", "\n"}},
   303  	}
   304  	for _, test := range allTests {
   305  		assertEqual(t, SplitLines(test.input), test.want)
   306  	}
   307  }
   308  
   309  func benchmarkSplitLines(b *testing.B, count int) {
   310  	str := strings.Repeat("foo\n", count)
   311  
   312  	b.ResetTimer()
   313  
   314  	n := 0
   315  	for i := 0; i < b.N; i++ {
   316  		n += len(SplitLines(str))
   317  	}
   318  }
   319  
   320  func BenchmarkSplitLines100(b *testing.B) {
   321  	benchmarkSplitLines(b, 100)
   322  }
   323  
   324  func BenchmarkSplitLines10000(b *testing.B) {
   325  	benchmarkSplitLines(b, 10000)
   326  }
   327  

View as plain text