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  }