Adding structs and interfaces

drew/sql-it
Drew Bednar 10 months ago
parent eeef9622df
commit 3686956a02

@ -0,0 +1,7 @@
# Testing Structs
You can run individual tests like:
```
go test -run TestArea/Rectangle
```

@ -0,0 +1,3 @@
module structs
go 1.21.0

@ -0,0 +1,49 @@
package structs
import "math"
// In Go interface resolution is implicit. So Rectangle and Cirle have
// receiver functions that satisfy the Shape interface.
type Shape interface {
Area() float64
}
type Rectangle struct {
Width float64
Height float64
}
type Circle struct {
Radius float64
}
type Triangle struct {
Base float64
Height float64
}
// There are examples of functions (not methods)
// Perimeter calculates the perimeter of a rectangle
func Perimeter(rectangle Rectangle) float64 {
return 2 * (rectangle.Width + rectangle.Height)
}
// Area calculates the area of a rectangle
func Area(rectangle Rectangle) float64 {
return rectangle.Width * rectangle.Height
}
// A method is a function with a receiver. A method declaration binds an identifier,
// the method name, to a method, and associates the method with the receiver's base type.
func (r Rectangle) Area() float64 {
return r.Height * r.Width
}
func (c Circle) Area() float64 {
return math.Pow(c.Radius, 2) * math.Pi
}
func (t Triangle) Area() float64 {
// return (t.Base * t.Height) / 2
return (t.Base * t.Height) * 0.5
}

@ -0,0 +1,74 @@
package structs
import "testing"
func TestPerimeter(t *testing.T) {
rectangle := Rectangle{10.0, 10.0}
got := Perimeter(rectangle)
want := 40.0
if got != want {
t.Errorf("got %.2f want %.2f", got, want)
}
}
// %.2f is replaced with %g which will print a more precise decimal number in an error message.
func TestArea(t *testing.T) {
// Helper function
checkArea := func(t testing.TB, shape Shape, want float64) {
t.Helper()
got := shape.Area()
if got != want {
t.Errorf("got %g want %g", got, want)
}
}
t.Run("area rectangle", func(t *testing.T) {
rectangle := Rectangle{12.0, 6.0}
checkArea(t, rectangle, 72.0)
})
t.Run("area circle", func(t *testing.T) {
circle := Circle{10}
checkArea(t, circle, 314.1592653589793)
})
}
// https://go.dev/wiki/TableDrivenTests are useful when you want to build a list of test cases that can be tested in the same manner.
// They are a great fit when you wish to test various implementations of an interface, or if the data being passed in to a function has lots of different requirements that need testing.
func TestAreaTable(t *testing.T) {
// "anonymous struct"
areaTests := []struct {
name string
shape Shape
want float64
}{
// example showing named arguments. Arguably it is more readable.
{name: "Rectangle", shape: Rectangle{Width: 12, Height: 6}, want: 72.0},
{"Circle", Circle{10}, 314.1592653589793},
{"Triangle", Triangle{12, 6}, 36.0},
}
// for _, tt := range areaTests {
// got := tt.shape.Area()
// if got != tt.want {
// // %#v format string will print out our struct with the values in its field
// t.Errorf("%#v got %g want %g", tt, got, tt.want)
// }
//}
// Wrap in t.Run for better debug output and test failure identification
for _, tt := range areaTests {
t.Run(tt.name, func(t *testing.T) {
got := tt.shape.Area()
if got != tt.want {
t.Errorf("%#v got %g want %g", tt, got, tt.want)
}
})
}
}
Loading…
Cancel
Save