github.com/thetreep/go-swagger@v0.0.0-20240223100711-35af64f14f01/cmd/swagger/commands/generate/cli_test.go (about)

     1  package generate_test
     2  
     3  import (
     4  	"io"
     5  	"log"
     6  	"os"
     7  	"os/exec"
     8  	"path/filepath"
     9  	"testing"
    10  
    11  	flags "github.com/jessevdk/go-flags"
    12  	"github.com/stretchr/testify/assert"
    13  	"github.com/stretchr/testify/require"
    14  	"github.com/thetreep/go-swagger/cmd/swagger/commands/generate"
    15  )
    16  
    17  // Make sure generated code compiles
    18  func TestGenerateCLI(t *testing.T) {
    19  	log.SetOutput(io.Discard)
    20  	defer log.SetOutput(os.Stdout)
    21  
    22  	base := filepath.FromSlash("../../../../")
    23  
    24  	testcases := []struct {
    25  		name      string
    26  		spec      string
    27  		wantError bool
    28  	}{
    29  		{
    30  			name:      "tasklist_basic",
    31  			spec:      "tasklist.basic.yml",
    32  			wantError: false,
    33  		},
    34  		{
    35  			name:      "tasklist_allparams",
    36  			spec:      "todolist.allparams.yml",
    37  			wantError: false,
    38  		},
    39  		{
    40  			name:      "tasklist_arrayform",
    41  			spec:      "todolist.arrayform.yml",
    42  			wantError: false,
    43  		},
    44  		{
    45  			name:      "tasklist_arrayquery",
    46  			spec:      "todolist.arrayquery.yml",
    47  			wantError: false,
    48  		},
    49  		{
    50  			name:      "todolist_bodyparams",
    51  			spec:      "todolist.bodyparams.yml",
    52  			wantError: false,
    53  		},
    54  		{
    55  			name:      "tasklist_simplequery",
    56  			spec:      "todolist.simplequery.yml",
    57  			wantError: false,
    58  		},
    59  		{
    60  			name:      "todolist_responses",
    61  			spec:      "todolist.responses.yml",
    62  			wantError: false,
    63  		},
    64  		{
    65  			name:      "todo_simple-fixed",
    66  			spec:      "todolist.simple-fixed.yml",
    67  			wantError: false,
    68  		},
    69  		{
    70  			name:      "todo_simpleform",
    71  			spec:      "todolist.simpleform.yml",
    72  			wantError: false,
    73  		},
    74  		{
    75  			name:      "todo_simpleheader",
    76  			spec:      "todolist.simpleheader.yml",
    77  			wantError: false,
    78  		},
    79  		{
    80  			name:      "todo_simplepath",
    81  			spec:      "todolist.simplepath.yml",
    82  			wantError: false,
    83  		},
    84  	}
    85  
    86  	for _, tc := range testcases {
    87  		t.Run(
    88  			tc.name, func(t *testing.T) {
    89  				path := filepath.Join(base, "fixtures/codegen", tc.spec)
    90  				generated, err := os.MkdirTemp(filepath.Dir(path), "generated")
    91  				if err != nil {
    92  					t.Fatalf("TempDir()=%s", generated)
    93  				}
    94  				defer func() {
    95  					_ = os.RemoveAll(generated)
    96  				}()
    97  				m := &generate.Cli{}
    98  				_, _ = flags.Parse(m)
    99  				m.Shared.Spec = flags.Filename(path)
   100  				m.Shared.Target = flags.Filename(generated)
   101  
   102  				err = m.Execute([]string{})
   103  				if tc.wantError {
   104  					assert.Error(t, err)
   105  				} else {
   106  					require.NoError(t, err)
   107  					// change to true to run go vet on generated files
   108  					runVet := false
   109  					if runVet {
   110  						vet := exec.Command("go", "vet", generated+"/...")
   111  						output, err := vet.CombinedOutput()
   112  						assert.NoError(t, err, string(output))
   113  					}
   114  				}
   115  			},
   116  		)
   117  	}
   118  }
   119  
   120  func TestGenerateCli_Check(t *testing.T) {
   121  	log.SetOutput(io.Discard)
   122  	defer log.SetOutput(os.Stdout)
   123  
   124  	m := &generate.Cli{}
   125  	_, _ = flags.Parse(m)
   126  	err := m.Execute([]string{})
   127  	assert.Error(t, err)
   128  }
   129  
   130  // This test runs cli generation on various swagger specs, for sanity check.
   131  // Skipped in by default. Only run by developer locally.
   132  func TestVariousCli(t *testing.T) {
   133  	// comment out this skip to run test
   134  	t.Skip()
   135  
   136  	log.SetOutput(io.Discard)
   137  	defer log.SetOutput(os.Stdout)
   138  
   139  	base := filepath.FromSlash("../../../../")
   140  
   141  	// change to true to run test case with runOnly set true
   142  	runOnlyTest := false
   143  
   144  	testcases := []struct {
   145  		skip          bool
   146  		name          string
   147  		spec          string
   148  		wantError     bool
   149  		wantVetError  bool
   150  		preserveFiles bool // force to preserve files
   151  		runOnly       bool // run only this test, and skip all others
   152  	}{
   153  		{
   154  			skip:         true, // do not run this since it is known to have bug
   155  			name:         "crazy-alias",
   156  			spec:         "fixtures/bugs/1260/fixture-realiased-types.yaml",
   157  			wantError:    false, // generate files should success
   158  			wantVetError: true,  // polymorphism is not supported. model import is not right. TODO: fix this.
   159  		},
   160  		{
   161  			name:          "multi-auth",
   162  			spec:          "examples/composed-auth/swagger.yml",
   163  			preserveFiles: true,
   164  		},
   165  		// not working because of model generation order.
   166  		// {
   167  		// 	name:          "enum",
   168  		// 	spec:          "fixtures/enhancements/1623/swagger.yml",
   169  		// 	preserveFiles: true,
   170  		// 	runOnly:       true,
   171  		// },
   172  	}
   173  
   174  	for _, tc := range testcases {
   175  		if runOnlyTest && !tc.runOnly {
   176  			continue
   177  		}
   178  		t.Run(
   179  			tc.name, func(tt *testing.T) {
   180  				if tc.skip {
   181  					tt.Skip()
   182  				}
   183  				path := filepath.Join(base, tc.spec)
   184  				generated, err := os.MkdirTemp(filepath.Dir(path), "generated")
   185  				if err != nil {
   186  					t.Fatalf("TempDir()=%s", generated)
   187  				}
   188  				defer func() {
   189  					// only clean up if success, and leave the files around for developer to inspect
   190  					if !tt.Failed() {
   191  						if !tc.preserveFiles {
   192  							_ = os.RemoveAll(generated)
   193  						}
   194  					} else {
   195  						// stop all tests, since it will generate too many files to inspect
   196  						t.FailNow()
   197  					}
   198  				}()
   199  				m := &generate.Cli{}
   200  				_, _ = flags.Parse(m)
   201  				m.Shared.Spec = flags.Filename(path)
   202  				m.Shared.Target = flags.Filename(generated)
   203  
   204  				err = m.Execute([]string{})
   205  				if tc.wantError {
   206  					assert.Error(tt, err)
   207  				} else {
   208  					require.NoError(tt, err)
   209  					// always run go vet on generated files
   210  					runVet := true
   211  					if runVet {
   212  						vet := exec.Command("go", "vet", generated+"/...")
   213  						output, err := vet.CombinedOutput()
   214  						if !tc.wantVetError {
   215  							assert.NoError(tt, err, string(output))
   216  						} else {
   217  							assert.Error(t, err)
   218  						}
   219  					}
   220  				}
   221  			},
   222  		)
   223  	}
   224  }