Skip to content

Commit

Permalink
Add test structure to views package for rendering test output
Browse files Browse the repository at this point in the history
  • Loading branch information
liamcervante committed Jun 7, 2023
1 parent 7a039ed commit 2dcb188
Show file tree
Hide file tree
Showing 7 changed files with 751 additions and 0 deletions.
99 changes: 99 additions & 0 deletions internal/command/views/test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
package views

import (
"fmt"

"github.com/hashicorp/terraform/internal/command/arguments"
"github.com/hashicorp/terraform/internal/moduletest"
)

// Test renders outputs for test executions.
type Test interface {
// Abstract should print an early summary of the tests that will be
// executed. This will be called before the tests have been executed so
// the status for everything within suite will be test.Pending.
//
// This should be used to state what is going to be tested.
Abstract(suite *moduletest.Suite)

// Conclusion should print out a summary of the tests including their
// completed status.
Conclusion(suite *moduletest.Suite)

// File prints out the summary for an entire test file.
File(file *moduletest.File)

// Run prints out the summary for a single test run block.
Run(run *moduletest.Run)
}

func NewTest(vt arguments.ViewType, view *View) Test {
switch vt {
case arguments.ViewJSON:
// TODO(liamcervante): Add support for JSON outputs.
panic("not supported yet")
case arguments.ViewHuman:
return &TestHuman{
view: view,
}
default:
panic(fmt.Sprintf("unknown view type %v", vt))
}
}

type TestHuman struct {
view *View
}

var _ Test = (*TestHuman)(nil)

func (t *TestHuman) Abstract(_ *moduletest.Suite) {
// Do nothing, we don't print an abstract for the human view.
}

func (t *TestHuman) Conclusion(suite *moduletest.Suite) {
t.view.streams.Println()

counts := make(map[moduletest.Status]int)
for _, file := range suite.Files {
for _, run := range file.Runs {
count := counts[run.Status]
counts[run.Status] = count + 1
}
}

if suite.Status <= moduletest.Skip {
// Then no tests.
t.view.streams.Printf("Executed 0 tests")
if counts[moduletest.Skip] > 0 {
t.view.streams.Printf(", %d skipped.\n", counts[moduletest.Skip])
} else {
t.view.streams.Println(".")
}
return
}

if suite.Status == moduletest.Pass {
t.view.streams.Print(t.view.colorize.Color("[green]Success![reset]"))
} else {
t.view.streams.Print(t.view.colorize.Color("[red]Failure![reset]"))
}

t.view.streams.Printf(" %d passed, %d failed", counts[moduletest.Pass], counts[moduletest.Fail]+counts[moduletest.Error])
if counts[moduletest.Skip] > 0 {
t.view.streams.Printf(", %d skipped.\n", counts[moduletest.Skip])
} else {
t.view.streams.Println(".")
}
}

func (t *TestHuman) File(file *moduletest.File) {
t.view.streams.Printf("%s... %s\n", file.Name, file.Status.ColorizedText(t.view.colorize))
}

func (t *TestHuman) Run(run *moduletest.Run) {
t.view.streams.Printf(" run %q... %s\n", run.Name, run.Status.ColorizedText(t.view.colorize))

// Finally we'll print out a summary of the diagnostics from the run.
t.view.Diagnostics(run.Diagnostics)
}
Loading

0 comments on commit 2dcb188

Please sign in to comment.