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  }