diff --git a/learn_go_with_tests/dependency_injection/greet_test.go b/learn_go_with_tests/dependency_injection/greet_test.go index 3da0b77..24e4b2c 100644 --- a/learn_go_with_tests/dependency_injection/greet_test.go +++ b/learn_go_with_tests/dependency_injection/greet_test.go @@ -11,7 +11,7 @@ func TestGreet(t *testing.T) { Greet(&buffer, "Chris") got := buffer.String() - want := "Hello, Chris" + want := "Hello, Chris\n" if got != want { t.Errorf("got %q want %q", got, want) diff --git a/learn_go_with_tests/mocking/go.mod b/learn_go_with_tests/mocking/go.mod new file mode 100644 index 0000000..a0fa02e --- /dev/null +++ b/learn_go_with_tests/mocking/go.mod @@ -0,0 +1,3 @@ +module mocking + +go 1.21.0 diff --git a/learn_go_with_tests/mocking/main b/learn_go_with_tests/mocking/main new file mode 100755 index 0000000..57fd4f8 Binary files /dev/null and b/learn_go_with_tests/mocking/main differ diff --git a/learn_go_with_tests/mocking/main.go b/learn_go_with_tests/mocking/main.go new file mode 100644 index 0000000..e9903e0 --- /dev/null +++ b/learn_go_with_tests/mocking/main.go @@ -0,0 +1,45 @@ +package main + +import ( + "fmt" + "io" + "os" + "time" +) + +const finalWord = "Go!" + +// const countDownStart = 3 + +type Sleeper interface { + Sleep() +} + +// type DefaultSleeper struct{} + +// func (d *DefaultSleeper) Sleep() { +// time.Sleep(1 * time.Second) +// } + +type ConfigurableSleeper struct { + duration time.Duration + sleep func(time.Duration) +} + +func (c *ConfigurableSleeper) Sleep() { + c.sleep(c.duration) +} + +func Countdown(out io.Writer, sleeper Sleeper, count int) { + for i := count; i > 0; i-- { + fmt.Fprint(out, i, "\n") + sleeper.Sleep() + } + + fmt.Fprint(out, finalWord, "\n") +} + +func main() { + sleeper := &ConfigurableSleeper{1 * time.Second, time.Sleep} + Countdown(os.Stdout, sleeper, 3) +} diff --git a/learn_go_with_tests/mocking/mocking_test.go b/learn_go_with_tests/mocking/mocking_test.go new file mode 100644 index 0000000..5e40cf2 --- /dev/null +++ b/learn_go_with_tests/mocking/mocking_test.go @@ -0,0 +1,118 @@ +package main + +import ( + "bytes" + "reflect" + "testing" + "time" +) + +const write = "write" +const sleep = "sleep" + +type SpyCountdownOperations struct { + Calls []string +} + +func (s *SpyCountdownOperations) Sleep() { + s.Calls = append(s.Calls, sleep) +} + +func (s *SpyCountdownOperations) Write(p []byte) (n int, err error) { + s.Calls = append(s.Calls, write) + return +} + +func TestCountdownRuns(t *testing.T) { + + t.Run("Prints 3 to Go!", func(t *testing.T) { + count := 3 + buffer := &bytes.Buffer{} + sleeper := &SpyCountdownOperations{} + Countdown(buffer, sleeper, count) + + got := buffer.String() + // ` backtick allows strings with preserved newlines. + want := `3 +2 +1 +Go! +` + + if got != want { + t.Errorf("got %q want %q", got, want) + } + + if len(sleeper.Calls) != 3 { + t.Errorf("Not enough calls to sleeper, want 3 got %q", sleeper.Calls) + } + + }) + + t.Run("Prints 4 to Go!", func(t *testing.T) { + count := 4 + buffer := &bytes.Buffer{} + sleeper := &SpyCountdownOperations{} + Countdown(buffer, sleeper, count) + + got := buffer.String() + // ` backtick allows strings with preserved newlines. + want := `4 +3 +2 +1 +Go! +` + + if got != want { + t.Errorf("got %q want %q", got, want) + } + + if len(sleeper.Calls) != 4 { + t.Errorf("Not enough calls to sleeper, want 3 got %q", sleeper.Calls) + } + + }) + + t.Run("sleep before every print", func(t *testing.T) { + count := 3 + sleeper := &SpyCountdownOperations{} + Countdown(sleeper, sleeper, count) + + want := []string{ + write, + sleep, + write, + sleep, + write, + sleep, + write, + } + + if !reflect.DeepEqual(want, sleeper.Calls) { + t.Errorf("wanted calls %v got %v", want, sleeper.Calls) + + } + + }) + +} + +type SpyTimeSleeper struct { + durationSlept time.Duration +} + +func (s *SpyTimeSleeper) Sleep(duration time.Duration) { + s.durationSlept = duration +} + +func TestConfigurableSleeper(t *testing.T) { + sleepTime := 5 * time.Second + spyTime := &SpyTimeSleeper{} + sleeper := ConfigurableSleeper{sleepTime, spyTime.Sleep} + sleeper.Sleep() + + if spyTime.durationSlept != sleepTime { + t.Errorf("should have slept for %v but slept for %v", spyTime.durationSlept, sleepTime) + } +} diff --git a/learn_go_with_tests/pointers_errors/wallet.go b/learn_go_with_tests/pointers_errors/wallet.go index 889ff51..3f05eff 100644 --- a/learn_go_with_tests/pointers_errors/wallet.go +++ b/learn_go_with_tests/pointers_errors/wallet.go @@ -5,7 +5,6 @@ import ( "fmt" ) - // The var keyword allows us to define values global to the package. var ErrInsufficientFunds = errors.New("cannot withdraw, insufficient funds") @@ -13,8 +12,6 @@ type Stringer interface { String() string } -errors.Wrap() - // creating a new type from an existing on // The idea being it could be more descriptive // but also you can declare methods on them diff --git a/learn_go_with_tests/pointers_errors/wallet_test.go b/learn_go_with_tests/pointers_errors/wallet_test.go index 5e59082..3aa704a 100644 --- a/learn_go_with_tests/pointers_errors/wallet_test.go +++ b/learn_go_with_tests/pointers_errors/wallet_test.go @@ -4,6 +4,8 @@ import ( "testing" ) +//https://dave.cheney.net/2016/04/27/dont-just-check-errors-handle-them-gracefully + func assertNoError(t testing.TB, got error) { t.Helper() if got != nil { diff --git a/tablewriter/go.mod b/tablewriter/go.mod new file mode 100644 index 0000000..32e41ee --- /dev/null +++ b/tablewriter/go.mod @@ -0,0 +1,8 @@ +module git.runcible.io/androiddrew/mytablewriter + +go 1.21.0 + +require ( + github.com/mattn/go-runewidth v0.0.9 // indirect + github.com/olekukonko/tablewriter v0.0.5 // indirect +) diff --git a/tablewriter/go.sum b/tablewriter/go.sum new file mode 100644 index 0000000..56c7ba4 --- /dev/null +++ b/tablewriter/go.sum @@ -0,0 +1,4 @@ +github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= +github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= +github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= +github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= diff --git a/tablewriter/main.go b/tablewriter/main.go new file mode 100644 index 0000000..47edc2f --- /dev/null +++ b/tablewriter/main.go @@ -0,0 +1,20 @@ +package main + +import ( + "os" + + "github.com/olekukonko/tablewriter" +) + +func main() { + data := [][]string{ + []string{"Alfred", "15", "10/20", "(10.32, 56.21, 30.25)"}, + []string{"Beelzebub", "30", "30/50", "(11.32, 57.21, 31.25)"}, + []string{"Pokey", "19", "20/20", "(12.32, 54.21, 33.25)"}, + } + + table := tablewriter.NewWriter(os.Stdout) + table.SetHeader([]string{"Name", "Speed", "Power", "Location"}) + table.AppendBulk(data) + table.Render() +} diff --git a/tablewriter/my-table-writer b/tablewriter/my-table-writer new file mode 100755 index 0000000..90ee22a Binary files /dev/null and b/tablewriter/my-table-writer differ