github.com/robgonnella/ardi/v2@v2.4.5-0.20230102052001-11a49de978c3/testutil/testutil.go (about)

     1  package testutil
     2  
     3  import (
     4  	"bytes"
     5  	"context"
     6  	"testing"
     7  
     8  	"github.com/golang/mock/gomock"
     9  	log "github.com/sirupsen/logrus"
    10  
    11  	cli "github.com/robgonnella/ardi/v2/cli-wrapper"
    12  	"github.com/robgonnella/ardi/v2/commands"
    13  	"github.com/robgonnella/ardi/v2/core"
    14  	"github.com/robgonnella/ardi/v2/mocks"
    15  	"github.com/robgonnella/ardi/v2/util"
    16  )
    17  
    18  // UnitTestEnv represents our unit test environment
    19  type UnitTestEnv struct {
    20  	T            *testing.T
    21  	Ctx          context.Context
    22  	Logger       *log.Logger
    23  	ArduinoCli   *mocks.MockCli
    24  	SerialPort   *mocks.MockSerialPort
    25  	ArdiCore     *core.ArdiCore
    26  	Stdout       *bytes.Buffer
    27  	PixieProjDir string
    28  	EmptyProjDIr string
    29  }
    30  
    31  // ClearStdout clears stdout for unit test
    32  func (e *UnitTestEnv) ClearStdout() {
    33  	var b bytes.Buffer
    34  	e.Logger.SetOutput(&b)
    35  	e.Stdout = &b
    36  }
    37  
    38  // RunUnitTest runs an ardi unit test
    39  func RunUnitTest(name string, t *testing.T, f func(env *UnitTestEnv)) {
    40  	t.Run(name, func(st *testing.T) {
    41  		ctx, cancel := context.WithCancel(context.Background())
    42  		defer cancel()
    43  		defer CleanAll()
    44  
    45  		cliCtrl := gomock.NewController(st)
    46  		defer cliCtrl.Finish()
    47  		cliInstance := mocks.NewMockCli(cliCtrl)
    48  
    49  		portCtrl := gomock.NewController(st)
    50  		defer portCtrl.Finish()
    51  		portInatance := mocks.NewMockSerialPort(portCtrl)
    52  		logger := log.New()
    53  
    54  		CleanAll()
    55  
    56  		var b bytes.Buffer
    57  		logger.SetOutput(&b)
    58  		logger.SetLevel(log.DebugLevel)
    59  
    60  		ardiConfig, svrSettings := util.GetAllSettings()
    61  		settingsPath := util.GetCliSettingsPath()
    62  
    63  		cliInstance.EXPECT().InitSettings(settingsPath).AnyTimes()
    64  		withArduinoCli := core.WithArduinoCli(cliInstance)
    65  		withSerialPort := core.WithCoreSerialPortManager(portInatance)
    66  
    67  		coreOpts := core.NewArdiCoreOpts{
    68  			Ctx:                ctx,
    69  			Logger:             logger,
    70  			CliSettingsPath:    settingsPath,
    71  			ArdiConfig:         *ardiConfig,
    72  			ArduinoCliSettings: *svrSettings,
    73  		}
    74  		ardiCore := core.NewArdiCore(coreOpts, withArduinoCli, withSerialPort)
    75  
    76  		env := UnitTestEnv{
    77  			T:          st,
    78  			Ctx:        ctx,
    79  			Logger:     logger,
    80  			ArduinoCli: cliInstance,
    81  			SerialPort: portInatance,
    82  			ArdiCore:   ardiCore,
    83  			Stdout:     &b,
    84  		}
    85  
    86  		f(&env)
    87  	})
    88  }
    89  
    90  // IntegrationTestEnv represents our integration test environment
    91  type IntegrationTestEnv struct {
    92  	T      *testing.T
    93  	Stdout *bytes.Buffer
    94  	ctx    context.Context
    95  	logger *log.Logger
    96  }
    97  
    98  // RunIntegrationTest runs an ardi integration test
    99  func RunIntegrationTest(name string, t *testing.T, f func(env *IntegrationTestEnv)) {
   100  	t.Run(name, func(st *testing.T) {
   101  		ctx, cancel := context.WithCancel(context.Background())
   102  		defer cancel()
   103  		defer CleanAll()
   104  
   105  		CleanAll()
   106  
   107  		var b bytes.Buffer
   108  		logger := log.New()
   109  		logger.Out = &b
   110  		logger.SetLevel(log.InfoLevel)
   111  
   112  		env := IntegrationTestEnv{
   113  			T:      st,
   114  			Stdout: &b,
   115  			ctx:    ctx,
   116  			logger: logger,
   117  		}
   118  
   119  		f(&env)
   120  	})
   121  }
   122  
   123  // RunProjectInit initializes and ardi project directory
   124  func (e *IntegrationTestEnv) RunProjectInit() error {
   125  	projectInitArgs := []string{"project-init"}
   126  	return e.Execute(projectInitArgs)
   127  }
   128  
   129  // Execute executes the root command with given arguments
   130  func (e *IntegrationTestEnv) Execute(args []string) error {
   131  	ardiConfig, svrSettings := util.GetAllSettings()
   132  	cliSettingsPath := util.GetCliSettingsPath()
   133  
   134  	coreOpts := core.NewArdiCoreOpts{
   135  		Ctx:                e.ctx,
   136  		Logger:             e.logger,
   137  		CliSettingsPath:    cliSettingsPath,
   138  		ArdiConfig:         *ardiConfig,
   139  		ArduinoCliSettings: *svrSettings,
   140  	}
   141  
   142  	arduinoCli := cli.NewArduinoCli()
   143  	withArduinoCli := core.WithArduinoCli(arduinoCli)
   144  	ardiCore := core.NewArdiCore(coreOpts, withArduinoCli)
   145  
   146  	env := &commands.CommandEnv{
   147  		ArdiCore: ardiCore,
   148  		Logger:   e.logger,
   149  	}
   150  
   151  	rootCmd := commands.GetRootCmd(env)
   152  	rootCmd.SetOut(e.logger.Out)
   153  	rootCmd.SetArgs(args)
   154  
   155  	return rootCmd.ExecuteContext(e.ctx)
   156  }
   157  
   158  // ClearStdout clears integration test env stdout
   159  func (e *IntegrationTestEnv) ClearStdout() {
   160  	var b bytes.Buffer
   161  	e.logger.SetOutput(&b)
   162  	e.Stdout = &b
   163  }
   164  
   165  // MockIntegrationTestEnv represents our integration test environment with a mocked arduino cli
   166  type MockIntegrationTestEnv struct {
   167  	T          *testing.T
   168  	Stdout     *bytes.Buffer
   169  	ArdiCore   *core.ArdiCore
   170  	ArduinoCli *mocks.MockCli
   171  	SerialPort *mocks.MockSerialPort
   172  	ctx        context.Context
   173  	logger     *log.Logger
   174  }
   175  
   176  // RunMockIntegrationTest runs an ardi integration test with mock cli
   177  func RunMockIntegrationTest(name string, t *testing.T, f func(env *MockIntegrationTestEnv)) {
   178  	t.Run(name, func(st *testing.T) {
   179  		ctx, cancel := context.WithCancel(context.Background())
   180  		defer cancel()
   181  		defer CleanAll()
   182  
   183  		cliCtrl := gomock.NewController(st)
   184  		defer cliCtrl.Finish()
   185  		cliInstance := mocks.NewMockCli(cliCtrl)
   186  		cliInstance.EXPECT().InitSettings(gomock.Any()).AnyTimes()
   187  
   188  		portCtrl := gomock.NewController(st)
   189  		defer portCtrl.Finish()
   190  		portInstance := mocks.NewMockSerialPort(portCtrl)
   191  
   192  		CleanAll()
   193  
   194  		var b bytes.Buffer
   195  		logger := log.New()
   196  		logger.Out = &b
   197  		logger.SetLevel(log.InfoLevel)
   198  
   199  		env := MockIntegrationTestEnv{
   200  			T:          st,
   201  			Stdout:     &b,
   202  			ArduinoCli: cliInstance,
   203  			SerialPort: portInstance,
   204  			logger:     logger,
   205  			ctx:        ctx,
   206  		}
   207  
   208  		f(&env)
   209  	})
   210  }
   211  
   212  // RunProjectInit initializes and ardi project directory in mock cli test
   213  func (e *MockIntegrationTestEnv) RunProjectInit() error {
   214  	projectInitArgs := []string{"project-init"}
   215  	return e.Execute(projectInitArgs)
   216  }
   217  
   218  // ClearStdout clears integration test env stdout in mock cli test
   219  func (e *MockIntegrationTestEnv) ClearStdout() {
   220  	var b bytes.Buffer
   221  	e.logger.SetOutput(&b)
   222  	e.Stdout = &b
   223  }
   224  
   225  // Execute executes the root command with given arguments for mock cli test
   226  func (e *MockIntegrationTestEnv) Execute(args []string) error {
   227  	ardiConfig, svrSettings := util.GetAllSettings()
   228  	cliSettingsPath := util.GetCliSettingsPath()
   229  
   230  	coreOpts := core.NewArdiCoreOpts{
   231  		Ctx:                e.ctx,
   232  		Logger:             e.logger,
   233  		CliSettingsPath:    cliSettingsPath,
   234  		ArdiConfig:         *ardiConfig,
   235  		ArduinoCliSettings: *svrSettings,
   236  	}
   237  
   238  	withArduinoCli := core.WithArduinoCli(e.ArduinoCli)
   239  	withPortManager := core.WithCoreSerialPortManager(e.SerialPort)
   240  	ardiCore := core.NewArdiCore(coreOpts, withArduinoCli, withPortManager)
   241  
   242  	e.ArdiCore = ardiCore
   243  
   244  	env := &commands.CommandEnv{
   245  		ArdiCore: ardiCore,
   246  		Logger:   e.logger,
   247  	}
   248  
   249  	rootCmd := commands.GetRootCmd(env)
   250  	rootCmd.SetOut(e.logger.Out)
   251  	rootCmd.SetArgs(args)
   252  
   253  	return rootCmd.ExecuteContext(e.ctx)
   254  }