...

Source file src/github.com/rogpeppe/go-internal/internal/misspell/misspell_test.go

Documentation: github.com/rogpeppe/go-internal/internal/misspell

     1  package misspell
     2  
     3  import (
     4  	"math"
     5  	"testing"
     6  )
     7  
     8  func TestAlmostEqual(t *testing.T) {
     9  	t.Parallel()
    10  
    11  	tcs := []struct {
    12  		inA  string
    13  		inB  string
    14  		want bool
    15  	}{
    16  		{"", "", true},
    17  		{"", "a", true},
    18  		{"a", "a", true},
    19  		{"a", "b", true},
    20  		{"hello", "hell", true},
    21  		{"hello", "jello", true},
    22  		{"hello", "helol", true},
    23  		{"hello", "jelol", false},
    24  	}
    25  	for _, tc := range tcs {
    26  		got := AlmostEqual(tc.inA, tc.inB)
    27  		if got != tc.want {
    28  			t.Errorf("AlmostEqual(%q, %q) = %v, want %v", tc.inA, tc.inB, got, tc.want)
    29  		}
    30  		// two tests for the price of one \o/
    31  		if got != AlmostEqual(tc.inB, tc.inA) {
    32  			t.Errorf("AlmostEqual(%q, %q) == %v != AlmostEqual(%q, %q)", tc.inA, tc.inB, got, tc.inB, tc.inA)
    33  		}
    34  	}
    35  }
    36  
    37  func FuzzAlmostEqual(f *testing.F) {
    38  	f.Add("", "")
    39  	f.Add("", "a")
    40  	f.Add("a", "a")
    41  	f.Add("a", "b")
    42  	f.Add("hello", "hell")
    43  	f.Add("hello", "jello")
    44  	f.Add("hello", "helol")
    45  	f.Add("hello", "jelol")
    46  	f.Fuzz(func(t *testing.T, a, b string) {
    47  		if len(a) > 10 || len(b) > 10 {
    48  			// longer strings won't add coverage, but take longer to check
    49  			return
    50  		}
    51  		d := editDistance([]rune(a), []rune(b))
    52  		got := AlmostEqual(a, b)
    53  		if want := d <= 1; got != want {
    54  			t.Errorf("AlmostEqual(%q, %q) = %v, editDistance(%q, %q) = %d", a, b, got, a, b, d)
    55  		}
    56  		if got != AlmostEqual(b, a) {
    57  			t.Errorf("AlmostEqual(%q, %q) == %v != AlmostEqual(%q, %q)", a, b, got, b, a)
    58  		}
    59  	})
    60  }
    61  
    62  // editDistance returns the Damerau-Levenshtein distance between a and b. It is
    63  // inefficient, but by keeping almost verbatim to the recursive definition from
    64  // Wikipedia, hopefully "obviously correct" and thus suitable for the fuzzing
    65  // test of AlmostEqual.
    66  func editDistance(a, b []rune) int {
    67  	i, j := len(a), len(b)
    68  	m := math.MaxInt
    69  	if i == 0 && j == 0 {
    70  		return 0
    71  	}
    72  	if i > 0 {
    73  		m = min(m, editDistance(a[1:], b)+1)
    74  	}
    75  	if j > 0 {
    76  		m = min(m, editDistance(a, b[1:])+1)
    77  	}
    78  	if i > 0 && j > 0 {
    79  		d := editDistance(a[1:], b[1:])
    80  		if a[0] != b[0] {
    81  			d += 1
    82  		}
    83  		m = min(m, d)
    84  	}
    85  	if i > 1 && j > 1 && a[0] == b[1] && a[1] == b[0] {
    86  		d := editDistance(a[2:], b[2:])
    87  		if a[0] != b[0] {
    88  			d += 1
    89  		}
    90  		m = min(m, d)
    91  	}
    92  	return m
    93  }
    94  
    95  func min(a, b int) int {
    96  	if a < b {
    97  		return a
    98  	}
    99  	return b
   100  }
   101  

View as plain text