github.com/shoshinnikita/budget-manager@v0.7.1-0.20220131195411-8c46ff1c6778/tests/tests.go (about)

     1  package tests
     2  
     3  import (
     4  	"fmt"
     5  	"testing"
     6  
     7  	"github.com/ShoshinNikita/budget-manager/internal/app"
     8  	"github.com/ShoshinNikita/budget-manager/internal/db"
     9  	"github.com/ShoshinNikita/budget-manager/internal/db/pg"
    10  	"github.com/ShoshinNikita/budget-manager/internal/db/sqlite"
    11  	"github.com/ShoshinNikita/budget-manager/internal/logger"
    12  	"github.com/ShoshinNikita/budget-manager/internal/web"
    13  )
    14  
    15  type Test interface {
    16  	Test(t *testing.T, host string)
    17  }
    18  
    19  // TestFn is a single test function that implements 'Test' interface
    20  type TestFn func(t *testing.T, host string)
    21  
    22  func (fn TestFn) Test(t *testing.T, host string) {
    23  	t.Helper()
    24  
    25  	fn(t, host)
    26  }
    27  
    28  // TestCases is a set of test cases that implements 'Test' interface.
    29  // All test cases are run consistently.
    30  type TestCases []struct {
    31  	Name string
    32  	Fn   TestFn
    33  }
    34  
    35  func (testCases TestCases) Test(t *testing.T, host string) {
    36  	t.Helper()
    37  
    38  	for _, tt := range testCases {
    39  		tt := tt
    40  		ok := t.Run(tt.Name, func(t *testing.T) {
    41  			tt.Fn(t, host)
    42  		})
    43  		if !ok {
    44  			t.FailNow()
    45  		}
    46  	}
    47  }
    48  
    49  type TestEnv struct {
    50  	Name       string
    51  	Cfg        app.Config
    52  	Components []StartComponentFn
    53  }
    54  
    55  type TestEnvOption func(env *TestEnv)
    56  
    57  // RunTest runs the passed test with all possible environments. Environment options are
    58  // applied to all environments
    59  func RunTest(t *testing.T, test Test, opts ...TestEnvOption) {
    60  	t.Helper()
    61  
    62  	for _, env := range []TestEnv{
    63  		{
    64  			Name:       "postgres",
    65  			Cfg:        getDefaultConfig(db.Postgres),
    66  			Components: []StartComponentFn{StartPostgreSQL},
    67  		},
    68  		{
    69  			Name:       "sqlite",
    70  			Cfg:        getDefaultConfig(db.Sqlite3),
    71  			Components: []StartComponentFn{StartSQLite},
    72  		},
    73  	} {
    74  		env := env
    75  		for _, opt := range opts {
    76  			opt(&env)
    77  		}
    78  		t.Run(env.Name, func(t *testing.T) {
    79  			t.Parallel()
    80  
    81  			prepareApp(t, &env.Cfg, env.Components...)
    82  
    83  			host := fmt.Sprintf("localhost:%d", env.Cfg.Server.Port)
    84  
    85  			test.Test(t, host)
    86  		})
    87  	}
    88  }
    89  
    90  func getDefaultConfig(dbType db.Type) app.Config {
    91  	return app.Config{
    92  		Logger: logger.Config{
    93  			Mode:  "dev",
    94  			Level: "error",
    95  		},
    96  		DB: app.DBConfig{
    97  			Type: dbType,
    98  			Postgres: pg.Config{
    99  				Host:     "localhost",
   100  				Port:     0,
   101  				User:     "postgres",
   102  				Database: "postgres",
   103  			},
   104  			SQLite: sqlite.Config{
   105  				Path: "",
   106  			},
   107  		},
   108  		Server: web.Config{
   109  			UseEmbed:        true,
   110  			EnableProfiling: false,
   111  			Auth: web.AuthConfig{
   112  				Disable: true,
   113  			},
   114  		},
   115  	}
   116  }