-
Notifications
You must be signed in to change notification settings - Fork 40
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Loading status checks…
Add test coverage (#78)
* add test cases * add test cases * remove fmt stmts * fix flaky tests and add more test cases
1 parent
789555f
commit 3483af4
Showing
15 changed files
with
904 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,3 +7,7 @@ tf-summarize | |
*.swp | ||
|
||
example/tfplan | ||
|
||
cover.out | ||
cover.html | ||
*.cov |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
package parser | ||
|
||
import ( | ||
"encoding/json" | ||
"testing" | ||
|
||
tfjson "github.com/hashicorp/terraform-json" | ||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
func TestJSONParser_Parse_Success(t *testing.T) { | ||
mockPlan := tfjson.Plan{ | ||
FormatVersion: "0.1", | ||
TerraformVersion: "1.0.0", | ||
Variables: map[string]*tfjson.PlanVariable{"example": {}}, | ||
} | ||
data, err := json.Marshal(mockPlan) | ||
assert.NoError(t, err) | ||
|
||
parser := NewJSONParser(data) | ||
parsedPlan, err := parser.Parse() | ||
|
||
assert.NoError(t, err) | ||
assert.Equal(t, mockPlan.FormatVersion, parsedPlan.FormatVersion) | ||
assert.Equal(t, mockPlan.TerraformVersion, parsedPlan.TerraformVersion) | ||
assert.Equal(t, mockPlan.Variables, parsedPlan.Variables) | ||
} | ||
|
||
func TestJSONParser_Parse_InvalidJSON(t *testing.T) { | ||
// invalid JSON data | ||
invalidData := []byte(`{"invalid-json"}`) | ||
|
||
parser := NewJSONParser(invalidData) | ||
_, err := parser.Parse() | ||
|
||
assert.Error(t, err) | ||
assert.Contains(t, err.Error(), "error when parsing input") | ||
} | ||
|
||
func TestNewJSONParser(t *testing.T) { | ||
data := []byte(`{"plan": "mock"}`) | ||
|
||
parser := NewJSONParser(data) | ||
jp, ok := parser.(JSONParser) | ||
assert.True(t, ok, "expected a JSONParser instance") | ||
assert.Equal(t, data, jp.data, "expected data to match the input") | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
package parser | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/dineshba/tf-summarize/reader" | ||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
// Test for JSON file input | ||
func TestCreateParser_JSONFile(t *testing.T) { | ||
data := []byte(`{"plan": "mock"}`) | ||
fileName := "example.json" | ||
|
||
p, err := CreateParser(data, fileName) | ||
|
||
assert.NoError(t, err) | ||
|
||
_, ok := p.(JSONParser) | ||
assert.True(t, ok, "expected a JSON parser to be returned") | ||
} | ||
|
||
// Test for stdin input | ||
func TestCreateParser_Stdin(t *testing.T) { | ||
data := []byte(`{"plan": "mock"}`) | ||
fileName := reader.StdinFileName | ||
|
||
p, err := CreateParser(data, fileName) | ||
|
||
assert.NoError(t, err) | ||
|
||
_, ok := p.(JSONParser) | ||
assert.True(t, ok, "expected a JSON parser for stdin input") | ||
} | ||
|
||
// Test for binary file input | ||
func TestCreateParser_BinaryFile(t *testing.T) { | ||
data := []byte{0x00, 0x01, 0x02} // Mock binary data | ||
fileName := "example.binary" | ||
|
||
p, err := CreateParser(data, fileName) | ||
|
||
assert.NoError(t, err) | ||
|
||
_, ok := p.(BinaryParser) | ||
assert.True(t, ok, "expected a Binary parser to be returned") | ||
} | ||
|
||
// Test for non-JSON file name (like .txt or other extensions) | ||
func TestCreateParser_InvalidFileName(t *testing.T) { | ||
data := []byte(`irrelevant data`) | ||
fileName := "example.txt" | ||
|
||
p, err := CreateParser(data, fileName) | ||
|
||
assert.NoError(t, err) | ||
|
||
_, ok := p.(BinaryParser) | ||
assert.True(t, ok, "expected a Binary parser for non-JSON file extension") | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
package writer | ||
|
||
import ( | ||
"bytes" | ||
"testing" | ||
"testing/fstest" | ||
|
||
"github.com/dineshba/tf-summarize/terraformstate" | ||
. "github.com/hashicorp/terraform-json" | ||
) | ||
|
||
func TestHTMLWriterWithMockFileSystem(t *testing.T) { | ||
origFS := cfs | ||
cfs = fstest.MapFS{ | ||
"templates/resourceChanges.html": &fstest.MapFile{ | ||
Data: []byte(`<table> | ||
<tr> | ||
<th>CHANGE</th> | ||
<th>RESOURCE</th> | ||
</tr>{{ range $change, $resources := .ResourceChanges }}{{ $length := len $resources }}{{ if gt $length 0 }} | ||
<tr> | ||
<td>{{ $change }}</td> | ||
<td> | ||
<ul>{{ range $i, $r := $resources }} | ||
<li><code>{{ $r.Address }}</code></li>{{ end }} | ||
</ul> | ||
</td> | ||
</tr>{{ end }}{{ end }} | ||
</table> | ||
`), | ||
}, | ||
"templates/outputChanges.html": &fstest.MapFile{ | ||
Data: []byte(`<table> | ||
<tr> | ||
<th>CHANGE</th> | ||
<th>OUTPUT</th> | ||
</tr>{{ range $change, $outputs := .OutputChanges }}{{ $length := len $outputs }}{{ if gt $length 0 }} | ||
<tr> | ||
<td>{{ $change }}</td> | ||
<td> | ||
<ul>{{ range $i, $o := $outputs }} | ||
<li><code>{{ $o }}</code></li>{{ end }} | ||
</ul> | ||
</td> | ||
</tr>{{ end }}{{ end }} | ||
</table> | ||
`), | ||
}, | ||
} | ||
t.Cleanup(func() { | ||
cfs = origFS | ||
}) | ||
|
||
resourceChanges := map[string]terraformstate.ResourceChanges{ | ||
"module.test": { | ||
{ | ||
Address: "aws_instance.example", | ||
Name: "example", | ||
Change: &Change{ | ||
Before: map[string]interface{}{"name": "old_instance"}, | ||
After: map[string]interface{}{"name": "new_instance"}, | ||
Actions: Actions{ActionCreate}, | ||
}, | ||
}, | ||
}, | ||
} | ||
outputChanges := map[string][]string{ | ||
"output_key": {"output_value"}, | ||
} | ||
|
||
htmlWriter := NewHTMLWriter(resourceChanges, outputChanges) | ||
var buf bytes.Buffer | ||
|
||
err := htmlWriter.Write(&buf) | ||
if err != nil { | ||
t.Fatalf("expected no error, got %v", err) | ||
} | ||
|
||
expectedOutput := `<table> | ||
<tr> | ||
<th>CHANGE</th> | ||
<th>RESOURCE</th> | ||
</tr> | ||
<tr> | ||
<td>module.test</td> | ||
<td> | ||
<ul> | ||
<li><code>aws_instance.example</code></li> | ||
</ul> | ||
</td> | ||
</tr> | ||
</table> | ||
<table> | ||
<tr> | ||
<th>CHANGE</th> | ||
<th>OUTPUT</th> | ||
</tr> | ||
<tr> | ||
<td>output_key</td> | ||
<td> | ||
<ul> | ||
<li><code>output_value</code></li> | ||
</ul> | ||
</td> | ||
</tr> | ||
</table> | ||
` | ||
if buf.String() != expectedOutput { | ||
t.Errorf("expected %q, got %q", expectedOutput, buf.String()) | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
package writer | ||
|
||
import ( | ||
"bytes" | ||
"encoding/json" | ||
"testing" | ||
|
||
"github.com/dineshba/tf-summarize/terraformstate" | ||
. "github.com/hashicorp/terraform-json" | ||
"github.com/nsf/jsondiff" | ||
) | ||
|
||
// Struct to hold arguments and expected output for each test case | ||
type testCase struct { | ||
args terraformstate.ResourceChanges | ||
expectedOutput map[string]interface{} | ||
} | ||
|
||
func TestJSONWriter(t *testing.T) { | ||
|
||
// Define test cases | ||
testCases := []testCase{ | ||
{ | ||
args: terraformstate.ResourceChanges{ | ||
{ | ||
Address: "module.test.azapi_resource.logical_network", | ||
Type: "aws_instance", | ||
Name: "example", | ||
Change: &Change{ | ||
Before: map[string]interface{}{"name": "old_instance"}, | ||
After: map[string]interface{}{"name": "new_instance"}, | ||
Actions: Actions{ActionCreate}, | ||
}, | ||
}, | ||
}, | ||
expectedOutput: map[string]interface{}{ | ||
"module": map[string]interface{}{ | ||
"test": map[string]interface{}{ | ||
"azapi_resource": map[string]interface{}{ | ||
"logical_network": map[string]interface{}{ | ||
"(+)": map[string]interface{}{ | ||
"name": "new_instance", | ||
}, | ||
}, | ||
}, | ||
}, | ||
}, | ||
}, | ||
}, | ||
{ | ||
args: terraformstate.ResourceChanges{ | ||
{ | ||
Address: "module.test.aws_s3_bucket.example", | ||
Type: "aws_s3_bucket", | ||
Name: "example", | ||
Change: &Change{ | ||
Before: map[string]interface{}{"name": "old_bucket"}, | ||
After: map[string]interface{}{"name": "new_bucket"}, | ||
Actions: Actions{ActionUpdate}, | ||
}, | ||
}, | ||
}, | ||
expectedOutput: map[string]interface{}{ | ||
"module": map[string]interface{}{ | ||
"test": map[string]interface{}{ | ||
"aws_s3_bucket": map[string]interface{}{ | ||
"example": map[string]interface{}{ | ||
"(~)": map[string]interface{}{ | ||
"name": map[string]interface{}{ | ||
"changed": []string{ | ||
"old_bucket", | ||
"new_bucket", | ||
}, | ||
}, | ||
}, | ||
}, | ||
}, | ||
}, | ||
}, | ||
}, | ||
}, | ||
{ | ||
args: terraformstate.ResourceChanges{ | ||
{ | ||
Address: "module.test.aws_security_group.example", | ||
Type: "aws_security_group", | ||
Name: "example", | ||
Change: &Change{ | ||
Before: map[string]interface{}{"name": "old_sg"}, | ||
After: map[string]interface{}{"name": "new_sg"}, | ||
Actions: Actions{ActionDelete}, | ||
}, | ||
}, | ||
}, | ||
expectedOutput: map[string]interface{}{ | ||
"module": map[string]interface{}{ | ||
"test": map[string]interface{}{ | ||
"aws_security_group": map[string]interface{}{ | ||
"example": map[string]interface{}{ | ||
"(-)": map[string]interface{}{ | ||
"name": "old_sg", | ||
}, | ||
}, | ||
}, | ||
}, | ||
}, | ||
}, | ||
}, | ||
} | ||
|
||
// Iterate through test cases | ||
for i, tc := range testCases { | ||
jsonWriter := NewJSONWriter(tc.args) | ||
var buf bytes.Buffer | ||
err := jsonWriter.Write(&buf) | ||
if err != nil { | ||
t.Fatalf("Unexpected error in test case %d: %v", i+1, err) | ||
} | ||
expectedJSON, err := json.Marshal(tc.expectedOutput) | ||
if err != nil { | ||
t.Fatalf("Error marshalling expected output in test case %d: %v", i+1, err) | ||
} | ||
opts := jsondiff.DefaultJSONOptions() | ||
diff, str := jsondiff.Compare(expectedJSON, buf.Bytes(), &opts) | ||
if diff != jsondiff.FullMatch { | ||
t.Errorf("Output mismatch in test case %d: %s", i+1, str) | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,168 @@ | ||
package writer | ||
|
||
import ( | ||
"bytes" | ||
"errors" | ||
"io" | ||
"testing" | ||
|
||
"github.com/dineshba/tf-summarize/terraformstate" | ||
"github.com/golang/mock/gomock" | ||
"github.com/stretchr/testify/assert" | ||
|
||
"github.com/dineshba/tf-summarize/testdata/mocks" | ||
|
||
. "github.com/hashicorp/terraform-json" | ||
tfjson "github.com/hashicorp/terraform-json" | ||
) | ||
|
||
// Mock tree writer | ||
type mockTreeWriter struct{} | ||
|
||
func (m *mockTreeWriter) Write(writer io.Writer) error { | ||
return nil | ||
} | ||
|
||
func NewMockTreeWriter(changes []*tfjson.ResourceChange, drawable bool) Writer { | ||
return &mockTreeWriter{} | ||
} | ||
|
||
// Mock tree writer to simulate an error during treeWriter.Write | ||
type mockTreeWriterWithError struct{} | ||
|
||
func (m *mockTreeWriterWithError) Write(writer io.Writer) error { | ||
return errors.New("tree writer error") | ||
} | ||
|
||
func NewMockTreeWriterWithError(changes []*tfjson.ResourceChange, drawable bool) Writer { | ||
return &mockTreeWriterWithError{} | ||
} | ||
|
||
// Helper function to create changes | ||
func createMockChanges() map[string]terraformstate.ResourceChanges { | ||
return map[string]terraformstate.ResourceChanges{ | ||
"add": { | ||
{ | ||
Address: "aws_instance.example1", | ||
Change: &Change{Actions: Actions{ActionCreate}}, | ||
}, | ||
}, | ||
"delete": { | ||
{ | ||
Address: "aws_instance.example2", | ||
Change: &Change{Actions: Actions{ActionDelete}}, | ||
}, | ||
}, | ||
} | ||
} | ||
|
||
func TestSeparateTree_Write(t *testing.T) { | ||
mockChanges := createMockChanges() | ||
|
||
t.Run("Drawable True", func(t *testing.T) { | ||
tw := NewSeparateTree(mockChanges, true) | ||
var buf bytes.Buffer | ||
err := tw.Write(&buf) | ||
|
||
assert.NoError(t, err) | ||
|
||
expectedAdd := `################### ADD ################### | ||
╭─╮ | ||
│.│ | ||
╰┬╯ | ||
│ | ||
╭──────┴─────╮ | ||
│aws_instance│ | ||
╰──────┬─────╯ | ||
│ | ||
╭─────┴─────╮ | ||
│example1(+)│ | ||
╰───────────╯ | ||
` | ||
expectedDelete := `################### DELETE ################### | ||
╭─╮ | ||
│.│ | ||
╰┬╯ | ||
│ | ||
╭──────┴─────╮ | ||
│aws_instance│ | ||
╰──────┬─────╯ | ||
│ | ||
╭─────┴─────╮ | ||
│example2(-)│ | ||
╰───────────╯ | ||
` | ||
|
||
actualOutput := removeANSI(buf.String()) | ||
assert.Contains(t, actualOutput, expectedAdd) | ||
assert.Contains(t, actualOutput, expectedDelete) | ||
|
||
}) | ||
|
||
t.Run("Drawable False", func(t *testing.T) { | ||
tw := NewSeparateTree(mockChanges, false) | ||
var buf bytes.Buffer | ||
err := tw.Write(&buf) | ||
|
||
assert.NoError(t, err) | ||
|
||
expectedAdd := `################### ADD ################### | ||
|---aws_instance | ||
| |---example1(+) | ||
` | ||
expectedDelete := `################### DELETE ################### | ||
|---aws_instance | ||
| |---example2(-) | ||
` | ||
|
||
actualOutput := removeANSI(buf.String()) | ||
assert.Contains(t, actualOutput, expectedAdd) | ||
assert.Contains(t, actualOutput, expectedDelete) | ||
}) | ||
|
||
t.Run("Error Handling", func(t *testing.T) { | ||
ctrl := gomock.NewController(t) | ||
defer ctrl.Finish() | ||
|
||
s := NewSeparateTree(mockChanges, false) | ||
|
||
t.Run("Write Error", func(t *testing.T) { | ||
mockWriter := mocks.NewMockWriter(ctrl) | ||
mockWriter.EXPECT().Write(gomock.Any()).Return(0, errors.New("write error")).Times(1) | ||
|
||
err := s.Write(mockWriter) | ||
assert.Error(t, err) | ||
assert.Contains(t, err.Error(), "write error") | ||
}) | ||
|
||
t.Run("Tree Writer Error", func(t *testing.T) { | ||
originalFunc := NewTreeWriterFunc | ||
defer func() { NewTreeWriterFunc = originalFunc }() | ||
|
||
// Replace NewTreeWriter with the mock that returns an error | ||
NewTreeWriterFunc = NewMockTreeWriterWithError | ||
|
||
mockWriter := mocks.NewMockWriter(ctrl) | ||
mockWriter.EXPECT().Write(gomock.Any()).Return(0, nil).AnyTimes() | ||
|
||
err := s.Write(mockWriter) | ||
assert.Error(t, err) | ||
assert.Contains(t, err.Error(), "tree writer error") | ||
}) | ||
|
||
t.Run("Final Newline Write Error", func(t *testing.T) { | ||
originalFunc := NewTreeWriterFunc | ||
defer func() { NewTreeWriterFunc = originalFunc }() | ||
|
||
NewTreeWriterFunc = NewMockTreeWriter | ||
|
||
mockWriter := mocks.NewMockWriter(ctrl) | ||
mockWriter.EXPECT().Write(gomock.Any()).Return(0, nil).Times(1) | ||
mockWriter.EXPECT().Write(gomock.Any()).Return(0, errors.New("write error")).Times(1) | ||
|
||
err := s.Write(mockWriter) | ||
assert.Error(t, err) | ||
assert.Contains(t, err.Error(), "write error") | ||
}) | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
package writer | ||
|
||
import ( | ||
"bytes" | ||
"testing" | ||
|
||
"github.com/dineshba/tf-summarize/terraformstate" | ||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
func TestTableWriter_Write_NoMarkdown(t *testing.T) { | ||
changes := createMockChanges() | ||
|
||
outputChanges := map[string][]string{ | ||
"update": { | ||
"output.example", | ||
}, | ||
} | ||
|
||
tw := NewTableWriter(changes, outputChanges, false) | ||
var output bytes.Buffer | ||
err := tw.Write(&output) | ||
assert.NoError(t, err) | ||
|
||
expectedOutput := `+--------+-----------------------+ | ||
| CHANGE | RESOURCE | | ||
+--------+-----------------------+ | ||
| add | aws_instance.example1 | | ||
+--------+-----------------------+ | ||
| delete | aws_instance.example2 | | ||
+--------+-----------------------+ | ||
+--------+----------------+ | ||
| CHANGE | OUTPUT | | ||
+--------+----------------+ | ||
| update | output.example | | ||
+--------+----------------+ | ||
` | ||
|
||
assert.Equal(t, expectedOutput, output.String()) | ||
} | ||
|
||
func TestTableWriter_Write_WithMarkdown(t *testing.T) { | ||
changes := createMockChanges() | ||
|
||
outputChanges := map[string][]string{ | ||
"update": { | ||
"output.example", | ||
}, | ||
} | ||
|
||
tw := NewTableWriter(changes, outputChanges, true) | ||
var output bytes.Buffer | ||
err := tw.Write(&output) | ||
assert.NoError(t, err) | ||
|
||
expectedOutput := `| CHANGE | RESOURCE | | ||
|--------|-------------------------| | ||
| add | ` + "`aws_instance.example1`" + ` | | ||
| delete | ` + "`aws_instance.example2`" + ` | | ||
| CHANGE | OUTPUT | | ||
|--------|------------------| | ||
| update | ` + "`output.example`" + ` | | ||
` | ||
|
||
assert.Equal(t, expectedOutput, output.String()) | ||
} | ||
|
||
func TestTableWriter_NoChanges(t *testing.T) { | ||
changes := map[string]terraformstate.ResourceChanges{} | ||
outputChanges := map[string][]string{} | ||
|
||
tw := NewTableWriter(changes, outputChanges, false) | ||
var output bytes.Buffer | ||
err := tw.Write(&output) | ||
assert.NoError(t, err) | ||
|
||
expectedOutput := `+--------+----------+ | ||
| CHANGE | RESOURCE | | ||
+--------+----------+ | ||
+--------+----------+ | ||
` | ||
assert.Equal(t, expectedOutput, output.String()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
package writer | ||
|
||
import ( | ||
"bytes" | ||
"errors" | ||
"testing" | ||
|
||
"github.com/dineshba/tf-summarize/terraformstate" | ||
. "github.com/hashicorp/terraform-json" | ||
tfjson "github.com/hashicorp/terraform-json" | ||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
func TestTreeWriter_Write_DrawableTrue(t *testing.T) { | ||
|
||
changes := terraformstate.ResourceChanges{ | ||
&tfjson.ResourceChange{Address: "module.test.azapi_resource.logical_network", Change: &Change{Actions: Actions{ActionNoop}}}, | ||
} | ||
|
||
tw := NewTreeWriter(changes, true) | ||
|
||
var buf bytes.Buffer | ||
err := tw.Write(&buf) | ||
|
||
assert.NoError(t, err) | ||
|
||
expectedOutput := ` ╭─╮ | ||
│.│ | ||
╰┬╯ | ||
│ | ||
╭───┴──╮ | ||
│module│ | ||
╰───┬──╯ | ||
│ | ||
╭──┴─╮ | ||
│test│ | ||
╰──┬─╯ | ||
│ | ||
╭───────┴──────╮ | ||
│azapi_resource│ | ||
╰───────┬──────╯ | ||
│ | ||
╭───────┴───────╮ | ||
│logical_network│ | ||
╰───────────────╯ | ||
` | ||
|
||
assert.Equal(t, expectedOutput, removeANSI(buf.String())) | ||
} | ||
|
||
func TestTreeWriter_Write_NonDrawable(t *testing.T) { | ||
|
||
changes := terraformstate.ResourceChanges{ | ||
&tfjson.ResourceChange{Address: "module.test.azapi_resource.logical_network", Change: &Change{Actions: Actions{ActionNoop}}}, | ||
} | ||
|
||
tw := NewTreeWriter(changes, false) | ||
|
||
var buf bytes.Buffer | ||
err := tw.Write(&buf) | ||
|
||
assert.NoError(t, err) | ||
assert.Contains(t, buf.String(), "|---module") | ||
assert.Contains(t, buf.String(), "|---test") | ||
assert.Contains(t, buf.String(), "|---azapi_resource") | ||
assert.Contains(t, buf.String(), "|---logical_network") | ||
|
||
expectedOutput := `|---module | ||
| |---test | ||
| | |---azapi_resource | ||
| | | |---logical_network | ||
` | ||
|
||
assert.Equal(t, expectedOutput, removeANSI(buf.String())) | ||
} | ||
|
||
func TestTreeWriter_Write_NonDrawable_PrintTreeError(t *testing.T) { | ||
|
||
changes := terraformstate.ResourceChanges{ | ||
&tfjson.ResourceChange{Address: "module.test.azapi_resource.logical_network", Change: &Change{Actions: Actions{ActionNoop}}}, | ||
} | ||
tw := NewTreeWriter(changes, false) | ||
faultyWriter := &errorWriter{} | ||
err := tw.Write(faultyWriter) | ||
assert.Error(t, err) | ||
} | ||
|
||
func TestTreeWriter_Write_PrintTreeError(t *testing.T) { | ||
changes := terraformstate.ResourceChanges{ | ||
&tfjson.ResourceChange{Address: "module.test.azapi_resource.logical_network", Change: &Change{Actions: Actions{ActionNoop}}}, | ||
} | ||
tw := NewTreeWriter(changes, true) | ||
faultyWriter := &errorWriter{} | ||
err := tw.Write(faultyWriter) | ||
assert.Error(t, err) | ||
assert.Contains(t, err.Error(), "simulated write error") | ||
} | ||
|
||
func TestTreeWriter_Write_EmptyChanges(t *testing.T) { | ||
changes := terraformstate.ResourceChanges{} // Empty changes | ||
tw := NewTreeWriter(changes, false) | ||
var buf bytes.Buffer | ||
err := tw.Write(&buf) | ||
|
||
// Verify output and no errors (it should handle empty cases gracefully) | ||
assert.NoError(t, err) | ||
assert.Equal(t, "", buf.String()) | ||
} | ||
|
||
// Custom faulty writer to simulate write errors | ||
type errorWriter struct{} | ||
|
||
func (ew *errorWriter) Write(p []byte) (n int, err error) { | ||
return 0, errors.New("simulated write error") | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
package writer | ||
|
||
import ( | ||
"testing" | ||
) | ||
|
||
// Test for hasOutputChanges function | ||
func TestHasOutputChanges(t *testing.T) { | ||
tests := []struct { | ||
name string | ||
input map[string][]string | ||
expected bool | ||
}{ | ||
{ | ||
name: "No changes", | ||
input: map[string][]string{ | ||
"change1": {}, | ||
"change2": {}, | ||
}, | ||
expected: false, | ||
}, | ||
{ | ||
name: "Has changes", | ||
input: map[string][]string{ | ||
"change1": {"added"}, | ||
"change2": {}, | ||
}, | ||
expected: true, | ||
}, | ||
{ | ||
name: "All empty", | ||
input: map[string][]string{ | ||
"change1": {}, | ||
"change2": {}, | ||
"change3": {}, | ||
}, | ||
expected: false, | ||
}, | ||
} | ||
|
||
for _, tt := range tests { | ||
t.Run(tt.name, func(t *testing.T) { | ||
result := hasOutputChanges(tt.input) | ||
if result != tt.expected { | ||
t.Errorf("expected %v, got %v", tt.expected, result) | ||
} | ||
}) | ||
} | ||
} | ||
|
||
// Test for removeANSI function | ||
func TestRemoveANSI(t *testing.T) { | ||
tests := []struct { | ||
name string | ||
input string | ||
expected string | ||
}{ | ||
{ | ||
name: "String without ANSI escape", | ||
input: "This is a normal string", | ||
expected: "This is a normal string", | ||
}, | ||
{ | ||
name: "String with ANSI escape", | ||
input: "\x1b[31mThis is red\x1b[0m", | ||
expected: "This is red", | ||
}, | ||
{ | ||
name: "String with multiple ANSI escapes", | ||
input: "\x1b[31mThis is red\x1b[0m and \x1b[32mthis is green\x1b[0m", | ||
expected: "This is red and this is green", | ||
}, | ||
{ | ||
name: "Empty string", | ||
input: "", | ||
expected: "", | ||
}, | ||
} | ||
|
||
for _, tt := range tests { | ||
t.Run(tt.name, func(t *testing.T) { | ||
result := removeANSI(tt.input) | ||
if result != tt.expected { | ||
t.Errorf("expected %v, got %v", tt.expected, result) | ||
} | ||
}) | ||
} | ||
} |