github.com/vpayno/adventofcode-2022-golang-workspace@v0.0.0-20230605190011-dbafed5593de/internal/day01/app_test.go (about) 1 package day01 2 3 import ( 4 "bufio" 5 "bytes" 6 "io" 7 "os" 8 "path/filepath" 9 "testing" 10 11 "github.com/stretchr/testify/assert" 12 "github.com/vpayno/adventofcode-2022-golang-workspace/internal/aocshared" 13 ) 14 15 /* 16 Stdout testing code borrowed from Jon Calhoun's FizzBuzz example. 17 https://courses.calhoun.io/lessons/les_algo_m01_08 18 https://github.com/joncalhoun/algorithmswithgo.com/blob/master/module01/fizz_buzz_test.go 19 */ 20 21 // This is the main test function. This is the gatekeeper of all the tests in the appwc package. 22 func TestMain(m *testing.M) { 23 exitCode := m.Run() 24 os.Exit(exitCode) 25 } 26 27 func TestRun(t *testing.T) { 28 conf := Setup("day01") 29 30 err := Run(conf) 31 var cause string 32 if err != nil { 33 cause = err.Error() 34 } 35 assert.Nil(t, err, cause) 36 } 37 38 func TestRun_fileError(t *testing.T) { 39 // this tests fails because it can't find the file 40 conf := Setup("day00") 41 42 err := Run(conf) 43 assert.NotNil(t, err, "Run() didn't fail with a can't find file error") 44 } 45 46 func TestRun_badData(t *testing.T) { 47 // this tests fails because it can't find the file 48 conf := Setup("day01") 49 50 // Give it bad data. 51 conf.inputFileName = "data/day01/day01-input-bad_data.txt" 52 53 err := Run(conf) 54 assert.NotNil(t, err, "Run() didn't fail with a bad data error") 55 } 56 57 func TestGetFile(t *testing.T) { 58 fileName := "data/day01/day01-input.txt" 59 60 fileRoot, err := os.Getwd() 61 assert.Nil(t, err, err) 62 63 fileRoot = filepath.Clean(fileRoot + "/../../") 64 testFile := fileRoot + "/" + fileName 65 66 wantFile, wantErr := os.Open(testFile) 67 68 gotFile, gotErr := aocshared.GetFile(fileName) 69 70 assert.Nil(t, wantErr, "failed to open wanted file") 71 assert.Nil(t, gotErr, "failed to open got file") 72 73 assert.Equal(t, wantFile.Name(), gotFile.Name(), "file names don't match") 74 } 75 76 func TestGetFile_NoCW(t *testing.T) { 77 wd, err := os.Getwd() 78 assert.Nil(t, err, err) 79 80 tmpDir, err := os.MkdirTemp("/tmp", "TestGetFile_NoCW") 81 assert.Nil(t, err, err) 82 83 err = os.Chdir(tmpDir) 84 assert.Nil(t, err, err) 85 86 err = os.Remove(tmpDir) 87 assert.Nil(t, err, err) 88 89 _, err = aocshared.GetFile("data/day01/day01-input.txt") 90 assert.NotNil(t, err, "aocshared.GetFile() should have failed here") 91 92 err = os.Chdir(wd) 93 var cause string 94 if err != nil { 95 cause = err.Error() 96 } 97 assert.Nil(t, err, "failed to return to the original working directory: "+cause) 98 } 99 100 func TestGetScanner(t *testing.T) { 101 fileName := "data/day01/day01-input.txt" 102 103 wantScanner, wantErr := aocshared.GetFile(fileName) 104 var cause string 105 if wantErr != nil { 106 cause = wantErr.Error() 107 } 108 assert.Nil(t, wantErr, "failed to get wantScanner: "+cause) 109 110 want := bufio.NewScanner(wantScanner) 111 112 gotScanner, gotErr := aocshared.GetFile(fileName) 113 if gotErr != nil { 114 cause = gotErr.Error() 115 } 116 assert.Nil(t, gotErr, "failed to get gotScanner: "+cause) 117 118 got := aocshared.GetScanner(gotScanner) 119 120 for { 121 if !want.Scan() { 122 break 123 } 124 lineWant := want.Text() 125 126 if !got.Scan() { 127 break 128 } 129 lineGot := got.Text() 130 131 assert.Equal(t, lineWant, lineGot, "lines in "+fileName+" not equal") 132 } 133 } 134 135 func TestLoadData(t *testing.T) { 136 want := map[string]int{ 137 "elf1": 51_844, 138 "elf2": 44_141, 139 "elf3": 28_132, 140 "elf4": 49_298, 141 "elf5": 26_247, 142 } 143 144 fileName := "data/day01/day01-input.txt" 145 146 file, err := aocshared.GetFile(fileName) 147 assert.Nil(t, err, err) 148 149 scanner := aocshared.GetScanner(file) 150 151 got, err := loadData(scanner) 152 assert.Nil(t, err, err) 153 154 for key, wantValue := range want { 155 gotValue, gotFound := got[key] 156 assert.True(t, gotFound, "wanted key, "+key+", not found in dictionary") 157 assert.Equal(t, wantValue, gotValue, "want/got values don't match for key ["+key+"]") 158 } 159 } 160 161 func TestLoadData_badFile(t *testing.T) { 162 fileName := "data/day01/day01-input-bad_data.txt" 163 164 file, err := aocshared.GetFile(fileName) 165 assert.Nil(t, err, err) 166 167 scanner := aocshared.GetScanner(file) 168 169 _, err = loadData(scanner) 170 assert.NotNil(t, err, err) 171 } 172 173 func TestGetMaxCalories(t *testing.T) { 174 input := map[string]int{ 175 "elf1": 2_000, 176 "elf2": 8_000, 177 "elf3": 5_000, 178 "elf4": 1_000, 179 "elf5": 3_000, 180 } 181 182 want := 8_000 183 184 got := getMaxCalories(input) 185 186 assert.Equal(t, want, got, "highest elf calories don't match") 187 } 188 189 func TestGetTopThreeSum(t *testing.T) { 190 input := []int{2_000, 7_000, 3_000, 5_000, 1_000} 191 192 want := 15_000 193 194 got := getTopThreeSum(input) 195 196 assert.Equal(t, want, got, "top three sums don't match") 197 } 198 199 func TestGetResultTopThreeCalories(t *testing.T) { 200 input := map[string]int{ 201 "elf1": 2_000, 202 "elf2": 8_000, 203 "elf3": 5_000, 204 "elf4": 1_000, 205 "elf5": 3_000, 206 } 207 208 want := 16_000 209 210 got := getResultTopThreeCalories(input) 211 212 assert.Equal(t, want, got, "top three sums don't match") 213 } 214 215 func TestShowResult(t *testing.T) { 216 testStdout, writer, err := os.Pipe() 217 if err != nil { 218 t.Errorf("os.Pipe() err %v; want %v", err, nil) 219 } 220 221 osStdout := os.Stdout // keep backup of the real stdout 222 os.Stdout = writer 223 224 defer func() { 225 // Undo what we changed when this test is done. 226 os.Stdout = osStdout 227 }() 228 229 want := "1234\n" 230 231 // Run the function who's output we want to capture. 232 aocshared.ShowResult(1234) 233 234 // Stop capturing stdout. 235 writer.Close() 236 237 var buf bytes.Buffer 238 _, err = io.Copy(&buf, testStdout) 239 if err != nil { 240 t.Error(err) 241 } 242 got := buf.String() 243 if got != want { 244 t.Errorf("main(); want %q, got %q", want, got) 245 } 246 }