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 }