github.com/adharshmk96/stk@v1.2.3/pkg/project/boilerplate_test.go (about)

     1  package project_test
     2  
     3  import (
     4  	"errors"
     5  	"path/filepath"
     6  	"testing"
     7  
     8  	"github.com/adharshmk96/stk/mocks"
     9  	"github.com/adharshmk96/stk/pkg/commands"
    10  	"github.com/adharshmk96/stk/pkg/project"
    11  	"github.com/adharshmk96/stk/testutils"
    12  	"github.com/stretchr/testify/assert"
    13  )
    14  
    15  func getMockCommands(t *testing.T) (*mocks.GoCmd, *mocks.GitCmd) {
    16  	goCmd := mocks.NewGoCmd(t)
    17  	gitCmd := mocks.NewGitCmd(t)
    18  
    19  	return goCmd, gitCmd
    20  }
    21  
    22  func TestGenerateBoilerplate(t *testing.T) {
    23  
    24  	goCmd := commands.NewGoCmd()
    25  	gitCmd := commands.NewGitCmd()
    26  
    27  	t.Run("generates boilerplate", func(t *testing.T) {
    28  
    29  		tc := []struct {
    30  			name       string
    31  			isGitRepo  bool
    32  			isGoModule bool
    33  		}{
    34  			{
    35  				name:       "empty project",
    36  				isGitRepo:  false,
    37  				isGoModule: false,
    38  			},
    39  			{
    40  				name:       "git repo",
    41  				isGitRepo:  true,
    42  				isGoModule: false,
    43  			},
    44  			{
    45  				name:       "go module",
    46  				isGitRepo:  false,
    47  				isGoModule: true,
    48  			},
    49  			{
    50  				name:       "git repo and go module",
    51  				isGitRepo:  true,
    52  				isGoModule: true,
    53  			},
    54  		}
    55  
    56  		for _, tt := range tc {
    57  			t.Run(tt.name, func(t *testing.T) {
    58  				tempDir, removeDir := testutils.SetupTempDirectory(t)
    59  				defer removeDir()
    60  
    61  				goCmd, gitCmd := getMockCommands(t)
    62  
    63  				if !tt.isGoModule {
    64  					goCmd.On("ModInit", "github.com/sample/sapp").Return(nil)
    65  				}
    66  				if !tt.isGitRepo {
    67  					gitCmd.On("Init").Return(nil)
    68  				}
    69  				goCmd.On("ModTidy").Return(nil)
    70  
    71  				ctx := &project.Context{
    72  					PackageName: "github.com/sample/sapp",
    73  					AppName:     "sapp",
    74  					IsGitRepo:   tt.isGitRepo,
    75  					IsGoModule:  tt.isGoModule,
    76  					WorkDir:     tempDir,
    77  
    78  					GoCmd:  goCmd,
    79  					GitCmd: gitCmd,
    80  				}
    81  
    82  				err := project.GenerateProjectBoilerplate(ctx)
    83  				assert.NoError(t, err)
    84  
    85  				assert.FileExists(t, filepath.Join(tempDir, "main.go"))
    86  			})
    87  		}
    88  
    89  	})
    90  
    91  	t.Run("generates project boilerplate non-mock", func(t *testing.T) {
    92  		tempDir, removeDir := testutils.SetupTempDirectory(t)
    93  		defer removeDir()
    94  
    95  		ctx := &project.Context{
    96  			PackageName: "github.com/sample/sapp",
    97  			AppName:     "sapp",
    98  			IsGitRepo:   false,
    99  			IsGoModule:  false,
   100  			WorkDir:     tempDir,
   101  
   102  			GoCmd:  goCmd,
   103  			GitCmd: gitCmd,
   104  		}
   105  
   106  		err := project.GenerateProjectBoilerplate(ctx)
   107  		assert.NoError(t, err)
   108  
   109  		assert.FileExists(t, filepath.Join(tempDir, "main.go"))
   110  		assert.FileExists(t, filepath.Join(tempDir, "go.mod"))
   111  		assert.FileExists(t, filepath.Join(tempDir, "go.sum"))
   112  
   113  		assert.True(t, goCmd.IsMod())
   114  		assert.True(t, gitCmd.IsRepo())
   115  
   116  	})
   117  
   118  }
   119  
   120  func TestGenerateModuleBoilerplate(t *testing.T) {
   121  	goCmd := commands.NewGoCmd()
   122  	gitCmd := commands.NewGitCmd()
   123  	t.Run("generates module boilerplate", func(t *testing.T) {
   124  		tempDir, removeDir := testutils.SetupTempDirectory(t)
   125  		defer removeDir()
   126  
   127  		goCmd.ModInit("github.com/sample/sapp")
   128  		gitCmd.Init()
   129  
   130  		ctx := &project.Context{
   131  			PackageName: "github.com/sample/sapp",
   132  			AppName:     "sapp",
   133  			IsGitRepo:   true,
   134  			IsGoModule:  true,
   135  			WorkDir:     tempDir,
   136  
   137  			GoCmd:  goCmd,
   138  			GitCmd: gitCmd,
   139  		}
   140  
   141  		err := project.GenerateModuleBoilerplate(ctx, "admin")
   142  		assert.NoError(t, err)
   143  
   144  		assert.DirExists(t, filepath.Join(tempDir, "internals/admin"))
   145  
   146  		assert.FileExists(t, filepath.Join(tempDir, "internals/admin/domain", "admin.go"))
   147  		assert.FileExists(t, filepath.Join(tempDir, "internals/admin/serr", "admin.go"))
   148  		assert.FileExists(t, filepath.Join(tempDir, "internals/admin/service", "admin.go"))
   149  		assert.FileExists(t, filepath.Join(tempDir, "internals/admin/service", "admin_test.go"))
   150  		assert.FileExists(t, filepath.Join(tempDir, "internals/admin/api/handler", "admin.go"))
   151  		assert.FileExists(t, filepath.Join(tempDir, "internals/admin/api/transport", "admin.go"))
   152  
   153  		assert.True(t, goCmd.IsMod())
   154  		assert.True(t, gitCmd.IsRepo())
   155  	})
   156  
   157  	t.Run("errors when go mod init fails", func(t *testing.T) {
   158  		tempDir, removeDir := testutils.SetupTempDirectory(t)
   159  		defer removeDir()
   160  
   161  		goCmd, gitCmd := getMockCommands(t)
   162  
   163  		gitCmd.On("Init").Return(errors.New(("init failed")))
   164  
   165  		ctx := &project.Context{
   166  			PackageName: "github.com/sample/sapp",
   167  			AppName:     "sapp",
   168  			IsGitRepo:   false,
   169  			IsGoModule:  false,
   170  			WorkDir:     tempDir,
   171  
   172  			GoCmd:  goCmd,
   173  			GitCmd: gitCmd,
   174  		}
   175  
   176  		err := project.GenerateProjectBoilerplate(ctx)
   177  		assert.Error(t, err)
   178  	})
   179  
   180  	t.Run("errors when git init fails", func(t *testing.T) {
   181  		tempDir, removeDir := testutils.SetupTempDirectory(t)
   182  		defer removeDir()
   183  
   184  		goCmd, gitCmd := getMockCommands(t)
   185  
   186  		gitCmd.On("Init").Return(errors.New("init failed"))
   187  
   188  		ctx := &project.Context{
   189  			PackageName: "github.com/sample/sapp",
   190  			AppName:     "sapp",
   191  			IsGitRepo:   false,
   192  			IsGoModule:  false,
   193  			WorkDir:     tempDir,
   194  
   195  			GoCmd:  goCmd,
   196  			GitCmd: gitCmd,
   197  		}
   198  
   199  		err := project.GenerateProjectBoilerplate(ctx)
   200  		assert.Error(t, err)
   201  	})
   202  
   203  	t.Run("errors when go mod tidy fails", func(t *testing.T) {
   204  		tempDir, removeDir := testutils.SetupTempDirectory(t)
   205  		defer removeDir()
   206  
   207  		goCmd, gitCmd := getMockCommands(t)
   208  
   209  		goCmd.On("ModInit", "github.com/sample/sapp").Return(nil)
   210  		gitCmd.On("Init").Return(nil)
   211  		goCmd.On("ModTidy").Return(errors.New("some error"))
   212  
   213  		ctx := &project.Context{
   214  			PackageName: "github.com/sample/sapp",
   215  			AppName:     "sapp",
   216  			IsGitRepo:   false,
   217  			IsGoModule:  false,
   218  			WorkDir:     tempDir,
   219  
   220  			GoCmd:  goCmd,
   221  			GitCmd: gitCmd,
   222  		}
   223  
   224  		err := project.GenerateProjectBoilerplate(ctx)
   225  		assert.Error(t, err)
   226  	})
   227  }
   228  
   229  func assertBoilerplateExists(t *testing.T, tempDir, moduleName string) {
   230  	dirs := []string{
   231  		filepath.Join("internals", moduleName),
   232  		filepath.Join("internals", moduleName, "domain"),
   233  		filepath.Join("internals", moduleName, "serr"),
   234  		filepath.Join("internals", moduleName, "service"),
   235  		filepath.Join("internals", moduleName, "web"),
   236  		filepath.Join("internals", moduleName, "storage"),
   237  		filepath.Join("internals", moduleName, "storage"),
   238  		filepath.Join("internals", moduleName, "api/handler"),
   239  		filepath.Join("internals", moduleName, "api/transport"),
   240  	}
   241  	files := []string{
   242  		filepath.Join("internals", moduleName, "routes.go"),
   243  		filepath.Join("internals", moduleName, "service", moduleName+".go"),
   244  		filepath.Join("internals", moduleName, "service", moduleName+"_test.go"),
   245  		filepath.Join("internals", moduleName, "storage", moduleName+".go"),
   246  		filepath.Join("internals", moduleName, "storage", moduleName+"Queries.go"),
   247  		filepath.Join("internals", moduleName, "domain", moduleName+".go"),
   248  		filepath.Join("internals", moduleName, "serr", moduleName+".go"),
   249  		filepath.Join("internals", moduleName, "api/handler", moduleName+".go"),
   250  		filepath.Join("internals", moduleName, "api/handler", moduleName+"_test.go"),
   251  		filepath.Join("internals", moduleName, "api/transport", moduleName+".go"),
   252  		filepath.Join("internals", moduleName, "web", moduleName+".go"),
   253  		filepath.Join("server/routing", moduleName+".go"),
   254  	}
   255  
   256  	for _, dir := range dirs {
   257  		assert.DirExists(t, filepath.Join(tempDir, dir))
   258  	}
   259  
   260  	for _, file := range files {
   261  		assert.FileExists(t, filepath.Join(tempDir, file))
   262  	}
   263  
   264  }
   265  
   266  func TestDeleteModuleBoilerplate(t *testing.T) {
   267  
   268  	t.Run("deletes module boilerplate", func(t *testing.T) {
   269  		tempDir, removeDir := testutils.SetupTempDirectory(t)
   270  		defer removeDir()
   271  
   272  		goCmd := commands.NewGoCmd()
   273  		gitCmd := commands.NewGitCmd()
   274  
   275  		goCmd.ModInit("github.com/sample/sapp")
   276  		gitCmd.Init()
   277  
   278  		ctx := &project.Context{
   279  			PackageName: "github.com/sample/sapp",
   280  			AppName:     "sapp",
   281  			IsGitRepo:   true,
   282  			IsGoModule:  true,
   283  			WorkDir:     tempDir,
   284  
   285  			GoCmd:  goCmd,
   286  			GitCmd: gitCmd,
   287  		}
   288  
   289  		err := project.GenerateProjectBoilerplate(ctx)
   290  		assert.NoError(t, err)
   291  
   292  		err = project.GenerateModuleBoilerplate(ctx, "admin")
   293  		assert.NoError(t, err)
   294  
   295  		assertBoilerplateExists(t, tempDir, "admin")
   296  
   297  		err = project.DeleteModuleBoilerplate(ctx, "admin")
   298  		assert.NoError(t, err)
   299  
   300  		assert.NoDirExists(t, filepath.Join(tempDir, "internals/admin"))
   301  		assert.NoFileExists(t, filepath.Join(tempDir, "server/routing", "admin.go"))
   302  
   303  		assert.True(t, goCmd.IsMod())
   304  		assert.True(t, gitCmd.IsRepo())
   305  	})
   306  
   307  	t.Run("remove default module", func(t *testing.T) {
   308  		tempDir, removeDir := testutils.SetupTempDirectory(t)
   309  		defer removeDir()
   310  
   311  		goCmd := commands.NewGoCmd()
   312  		gitCmd := commands.NewGitCmd()
   313  
   314  		goCmd.ModInit("github.com/sample/sapp")
   315  		gitCmd.Init()
   316  
   317  		ctx := &project.Context{
   318  			PackageName: "github.com/sample/sapp",
   319  			AppName:     "sapp",
   320  			IsGitRepo:   true,
   321  			IsGoModule:  true,
   322  			WorkDir:     tempDir,
   323  
   324  			GoCmd:  goCmd,
   325  			GitCmd: gitCmd,
   326  		}
   327  
   328  		err := project.GenerateProjectBoilerplate(ctx)
   329  		assert.NoError(t, err)
   330  		assertBoilerplateExists(t, tempDir, "ping")
   331  
   332  		err = project.GenerateModuleBoilerplate(ctx, "admin")
   333  		assert.NoError(t, err)
   334  		assertBoilerplateExists(t, tempDir, "admin")
   335  
   336  		err = project.DeleteModuleBoilerplate(ctx, "ping")
   337  		assert.NoError(t, err)
   338  
   339  		assert.NoDirExists(t, filepath.Join(tempDir, "internals/ping"))
   340  		assert.NoFileExists(t, filepath.Join(tempDir, "server/routing", "ping.go"))
   341  
   342  		assert.True(t, goCmd.IsMod())
   343  		assert.True(t, gitCmd.IsRepo())
   344  
   345  	})
   346  }