github.com/thetreep/go-swagger@v0.0.0-20240223100711-35af64f14f01/cmd/swagger/commands/diff/spec_analyser_test.go (about) 1 package diff 2 3 import ( 4 "io" 5 "os" 6 "path/filepath" 7 "strings" 8 "testing" 9 10 "github.com/go-openapi/loads" 11 "github.com/stretchr/testify/require" 12 "github.com/thetreep/go-swagger/cmd/swagger/commands/internal/cmdtest" 13 ) 14 15 func fixturePath(file string, parts ...string) string { 16 return filepath.Join("..", "..", "..", "..", "fixtures", "diff", strings.Join(append([]string{file}, parts...), "")) 17 } 18 19 type testCaseData struct { 20 name string 21 oldSpec string 22 newSpec string 23 expectedLines io.Reader 24 expectedFile string 25 } 26 27 func fixturePart(file string) string { 28 base := filepath.Base(file) 29 parts := strings.Split(base, ".diff.txt") 30 return parts[0] 31 } 32 33 // TestDiffForVariousCombinations - computes the diffs for a number 34 // of scenarios and compares the computed diff with expected diffs 35 func TestDiffForVariousCombinations(t *testing.T) { 36 pattern := fixturePath("*.diff.txt") 37 allTests, err := filepath.Glob(pattern) 38 require.NoError(t, err) 39 require.True(t, len(allTests) > 0) 40 41 // To filter cases for debugging poke an individual case here eg "path", "enum" etc 42 // see the test cases in fixtures/diff 43 // Don't forget to remove it once you're done. 44 // (There's a test at the end to check all cases were run) 45 matches := allTests 46 // matches := []string{"enum"} 47 48 testCases := makeTestCases(t, matches) 49 50 for i, tc := range testCases { 51 tc := tc 52 t.Run( 53 tc.name, func(t *testing.T) { 54 diffs, err := getDiffs(tc.oldSpec, tc.newSpec) 55 require.NoError(t, err) 56 57 out, err, warn := diffs.ReportAllDiffs(false) 58 require.NoError(t, err) 59 60 if !cmdtest.AssertReadersContent(t, true, tc.expectedLines, out) { 61 t.Logf("unexpected content for fixture %q[%d] (file: %s)", tc.name, i, tc.expectedFile) 62 } 63 64 if diffs.BreakingChangeCount() > 0 { 65 require.Error(t, warn) 66 } 67 }, 68 ) 69 } 70 71 require.Equalf(t, len(allTests), len(matches), "All test cases were not run. Remove filter") 72 } 73 74 func getDiffs(oldSpecPath, newSpecPath string) (SpecDifferences, error) { 75 swaggerDoc1 := oldSpecPath 76 specDoc1, err := loads.Spec(swaggerDoc1) 77 78 if err != nil { 79 return nil, err 80 } 81 82 swaggerDoc2 := newSpecPath 83 specDoc2, err := loads.Spec(swaggerDoc2) 84 if err != nil { 85 return nil, err 86 } 87 88 return Compare(specDoc1.Spec(), specDoc2.Spec()) 89 } 90 91 func makeTestCases(t testing.TB, matches []string) []testCaseData { 92 testCases := make([]testCaseData, 0, len(matches)) 93 for _, eachFile := range matches { 94 namePart := fixturePart(eachFile) 95 if _, err := os.Stat(fixturePath(namePart, ".v1.json")); err == nil { 96 testCases = append( 97 testCases, testCaseData{ 98 name: namePart, 99 oldSpec: fixturePath(namePart, ".v1.json"), 100 newSpec: fixturePath(namePart, ".v2.json"), 101 expectedLines: linesInFile(t, fixturePath(namePart, ".diff.txt")), 102 }, 103 ) 104 } 105 if _, err := os.Stat(fixturePath(namePart, ".v1.yml")); err == nil { 106 testCases = append( 107 testCases, testCaseData{ 108 name: namePart, 109 oldSpec: fixturePath(namePart, ".v1.yml"), 110 newSpec: fixturePath(namePart, ".v2.yml"), 111 expectedLines: linesInFile(t, fixturePath(namePart, ".diff.txt")), 112 }, 113 ) 114 } 115 } 116 return testCases 117 } 118 119 func linesInFile(t testing.TB, fileName string) io.ReadCloser { 120 file, err := os.Open(fileName) 121 require.NoError(t, err) 122 return file 123 } 124 125 func TestIssue2962(t *testing.T) { 126 oldSpec := filepath.Join("..", "..", "..", "..", "fixtures", "bugs", "2962", "old.json") 127 newSpec := filepath.Join("..", "..", "..", "..", "fixtures", "bugs", "2962", "new.json") 128 diffs, err := getDiffs(oldSpec, newSpec) 129 require.NoError(t, err) 130 131 require.Len(t, diffs, 3) 132 require.Equal(t, 1, diffs.BreakingChangeCount()) 133 }