Skip to content

Commit

Permalink
test: perform asserts on uniquely named tests (#67)
Browse files Browse the repository at this point in the history
  • Loading branch information
zimeg authored Jan 14, 2024
1 parent 5f7f8bf commit a76dce7
Show file tree
Hide file tree
Showing 10 changed files with 99 additions and 170 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:
- name: Check formatting
run: test -z $(gofmt -l $(find . -name '*.go'))
- name: Run tests
run: go test ./...
run: go test -v ./...

measurement:
name: Monitor energy usage
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Maintenance

- Perform asserts on uniquely named tests across packages
- Refactor command usage templating into a templates package
- Separate concerns of a single internal package into many
- Increment the end license year to include this new year
Expand Down
5 changes: 2 additions & 3 deletions cmd/etime.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package etime

import (
"os"
"os/exec"

"github.com/zimeg/emporia-time/internal/program"
Expand All @@ -18,8 +17,8 @@ type CommandResult struct {
}

// Setup prepares the command and client with provided inputs
func Setup() (command program.Command, client emporia.Emporia, err error) {
command = program.ParseFlags(os.Args)
func Setup(arguments []string) (command program.Command, client emporia.Emporia, err error) {
command = program.ParseFlags(arguments)
if command.Flags.Help {
return command, client, err
}
Expand Down
50 changes: 18 additions & 32 deletions internal/display/format_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,74 +2,60 @@ package display

import (
"testing"

"github.com/stretchr/testify/assert"
)

func TestFormatSeconds(t *testing.T) {
tests := []struct {
Title string
tests := map[string]struct {
Seconds float64
Expected string
}{
{
Title: "the zero time is preserved",
"the zero time is preserved": {
Seconds: 0.0,
Expected: "0.00",
},
{
Title: "single digit seconds are matched",
"single digit seconds are matched": {
Seconds: 8.05,
Expected: "8.05",
},
{
Title: "many seconds passed without formatting",
"many seconds passed without formatting": {
Seconds: 12.8,
Expected: "12.80",
},
{
Title: "a minute and a few seconds passed",
"a minute and a few seconds passed": {
Seconds: 64.46,
Expected: "1:04.46",
},
{
Title: "an amount of time greater than a minute",
"an amount of time greater than a minute": {
Seconds: 222.22,
Expected: "3:42.22",
},
{
Title: "many minutes passed and are formatted",
"many minutes passed and are formatted": {
Seconds: 1342.22,
Expected: "22:22.22",
},
{
Title: "slightly past one whole hour",
"slightly past one whole hour": {
Seconds: 3663.36,
Expected: "1:01:03.36",
},
{
Title: "around a third of an hour from seconds",
"around a third of an hour from seconds": {
Seconds: 5025.67,
Expected: "1:23:45.67",
},
{
Title: "multiple hours were measured",
"multiple hours were measured": {
Seconds: 52331.98,
Expected: "14:32:11.98",
},
{
Title: "multiple days were counted and shown in hours",
"multiple days were counted and shown in hours": {
Seconds: 314159.27,
Expected: "87:15:59.27",
},
}
for _, tt := range tests {
actual := FormatSeconds(tt.Seconds)
if actual != tt.Expected {
t.Errorf("A time is not formatted correctly!\nTEST: '%s'\nINPUT: %.2f\nEXPECT: %+v\nACTUAL: %+v",
tt.Title,
tt.Seconds,
tt.Expected,
actual,
)
}
for name, tt := range tests {
t.Run(name, func(t *testing.T) {
actual := FormatSeconds(tt.Seconds)
assert.Equalf(t, tt.Expected, actual, "Failed to format %.2f seconds", tt.Seconds)
})
}
}
10 changes: 5 additions & 5 deletions internal/display/templates/usage_mock.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,17 @@ type mockUsageStatistics struct {
Sureness float64
}

// GetReal returns the joules in a mocked result
// GetReal returns the real time of a mocked command
func (results mockUsageStatistics) GetReal() float64 {
return results.Real
}

// GetUser returns the joules in a mocked result
// GetUser returns the user time of a mocked command
func (results mockUsageStatistics) GetUser() float64 {
return results.User
}

// GetSys returns the joules in a mocked result
// GetSys returns the sys time of a mocked command
func (results mockUsageStatistics) GetSys() float64 {
return results.Sys
}
Expand All @@ -29,12 +29,12 @@ func (results mockUsageStatistics) GetJoules() float64 {
return results.Joules
}

// GetWatts returns the joules in a mocked result
// GetWatts returns the watts in a mocked result
func (results mockUsageStatistics) GetWatts() float64 {
return results.Watts
}

// GetSureness returns the joules in a mocked result
// GetSureness returns the sureness of a mocked result
func (results mockUsageStatistics) GetSureness() float64 {
return results.Sureness
}
4 changes: 2 additions & 2 deletions internal/program/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ func ParseFlags(arguments []string) Command {

flagset.Usage = templates.PrintHelpMessage
flagset.Parse(arguments[1:])
if len(arguments) <= 1 || flags.Help {
templates.PrintHelpMessage()
if len(arguments) <= 1 {
flags.Help = true
}
return Command{Args: flagset.Args(), Flags: flags}
}
8 changes: 7 additions & 1 deletion internal/program/flags_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ func TestParseFlags(t *testing.T) {
tests := map[string]struct {
arguments []string
command Command
makesExit bool
}{
"plain arguments are treated as a command": {
arguments: []string{"etime", "sleep", "12"},
Expand Down Expand Up @@ -58,6 +57,13 @@ func TestParseFlags(t *testing.T) {
Flags: Flags{Help: true},
},
},
"help is noticed when no arguments are provided": {
arguments: []string{"etime"},
command: Command{
Args: []string{},
Flags: Flags{Help: true},
},
},
}
for name, tt := range tests {
t.Run(name, func(t *testing.T) {
Expand Down
3 changes: 2 additions & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,11 @@ import (

// main manages the lifecycle of this program
func main() {
command, client, err := etime.Setup()
command, client, err := etime.Setup(os.Args)
if err != nil {
log.Fatalf("Error: %s", err)
} else if command.Flags.Help {
templates.PrintHelpMessage()
os.Exit(0)
}
if available, err := emporia.EmporiaStatus(); err != nil {
Expand Down
86 changes: 26 additions & 60 deletions pkg/energy/energy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,119 +3,85 @@ package energy
import (
"testing"
"time"

"github.com/stretchr/testify/assert"
)

func TestScaleKWhToWs(t *testing.T) {
tests := []struct {
Title string
tests := map[string]struct {
KWh float64
ExpectedWs float64
}{
{
"ensure the zero value is zero",
"ensure the zero value is zero": {
0,
0,
},
{
"convert a single KWh to Ws",
"convert a single KWh to Ws": {
1,
1 * 1000 * 3600,
},
{
"convert 1000 KWh to Ws",
"convert 1000 KWh to Ws": {
1000,
1000 * 1000 * 3600,
},
}

for _, tt := range tests {
actual := ScaleKWhToWs(tt.KWh)
if tt.ExpectedWs != actual {
t.Fatalf("An unexpected energy conversion was found!\nTEST: '%s'\nEXPECT: %8f\nACTUAL: %8f",
tt.Title,
tt.ExpectedWs,
actual,
)
}
for name, tt := range tests {
t.Run(name, func(t *testing.T) {
actual := ScaleKWhToWs(tt.KWh)
assert.Equal(t, tt.ExpectedWs, actual)
})
}
}

func TestExtrapolateUsage(t *testing.T) {
tests := []struct {
Title string
tests := map[string]struct {
Measurements []float64
Duration time.Duration
ExpectedResult EnergyResult
}{
{
"handle the measurements of instant commands",
"handle the measurements of instant commands": {
[]float64{0},
time.Duration(0 * float64(time.Second)),
EnergyResult{Joules: 0, Watts: 0, Sureness: 1},
},
{
"return unsure results if no measurements are returned",
"return unsure results if no measurements are returned": {
[]float64{},
time.Duration(3 * float64(time.Second)),
EnergyResult{Joules: 0, Watts: 0, Sureness: 0},
},
{
"return unsure results if all measurements are zero",
"return unsure results if all measurements are zero": {
[]float64{0, 0, 0},
time.Duration(3 * float64(time.Second)),
EnergyResult{Joules: 0, Watts: 0, Sureness: 0},
},
{
"confidently compute results for complete measurements",
"confidently compute results for complete measurements": {
[]float64{3.64, 4.2, 2}, // sum=9.84, avg=3.28
time.Duration(3 * float64(time.Second)),
EnergyResult{Joules: 9.84, Watts: 3.28, Sureness: 1},
},
{
"extrapolate a missing second of measured results",
"extrapolate a missing second of measured results": {
[]float64{3, 4, 6, 3}, // sum=16, avg=4
time.Duration(5 * float64(time.Second)),
EnergyResult{Joules: 20, Watts: 4, Sureness: 0.8},
},
{
"extrapolate a half second of undermeasured results",
"extrapolate a half second of undermeasured results": {
[]float64{3, 4, 6, 3}, // sum=16, avg=4
time.Duration(4.5 * float64(time.Second)),
EnergyResult{Joules: 18, Watts: 4, Sureness: 4 / 4.5},
},
{
"extrapolate a half second of overmeasured results",
"extrapolate a half second of overmeasured results": {
[]float64{3, 4, 6, 3, 4}, // sum=20, avg=4
time.Duration(4.5 * float64(time.Second)),
EnergyResult{Joules: 18, Watts: 4, Sureness: 1},
},
}

for _, tt := range tests {
actual := ExtrapolateUsage(EnergyMeasurement{
Chart: tt.Measurements,
Duration: tt.Duration,
for name, tt := range tests {
t.Run(name, func(t *testing.T) {
measurement := EnergyMeasurement{Chart: tt.Measurements, Duration: tt.Duration}
actual := ExtrapolateUsage(measurement)
assert.Equal(t, tt.ExpectedResult.Joules, actual.Joules)
assert.Equal(t, tt.ExpectedResult.Watts, actual.Watts)
assert.Equal(t, tt.ExpectedResult.Sureness, actual.Sureness)
})
if tt.ExpectedResult.Joules != actual.Joules {
t.Fatalf("An unexpected joule estimation was found!\nFAILED: '%s'\nEXPECT: %8f\nACTUAL: %8f",
tt.Title,
tt.ExpectedResult.Joules,
actual.Joules,
)
}
if tt.ExpectedResult.Watts != actual.Watts {
t.Fatalf("An unexpected watt estimation was found!\nFAILED: '%s'\nEXPECT: %8f\nACTUAL: %8f",
tt.Title,
tt.ExpectedResult.Watts,
actual.Watts,
)
}
if tt.ExpectedResult.Sureness != actual.Sureness {
t.Fatalf("An unexpected sureness score was found!\nFAILED: '%s'\nEXPECT: %8f\nACTUAL: %8f",
tt.Title,
tt.ExpectedResult.Sureness,
actual.Sureness,
)
}
}
}
Loading

0 comments on commit a76dce7

Please sign in to comment.