printer: implement file tests
This commit is contained in:
parent
2ea5683566
commit
0fc42b65df
@ -111,18 +111,14 @@ func writeBlank(buf io.ByteWriter, indent int) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func indent(buf []byte) []byte {
|
func indent(buf []byte) []byte {
|
||||||
splitted := bytes.Split(buf, []byte{newline})
|
var res []byte
|
||||||
newBuf := make([]byte, len(splitted))
|
bol := true
|
||||||
for i, s := range splitted {
|
for _, c := range buf {
|
||||||
s = append(s, 0)
|
if bol && c != '\n' {
|
||||||
copy(s[1:], s[0:])
|
res = append(res, []byte{tab}...)
|
||||||
s[0] = tab
|
|
||||||
newBuf = append(newBuf, s...)
|
|
||||||
|
|
||||||
if i != len(splitted)-1 {
|
|
||||||
newBuf = append(newBuf, newline)
|
|
||||||
}
|
}
|
||||||
|
res = append(res, c)
|
||||||
|
bol = c == '\n'
|
||||||
}
|
}
|
||||||
|
return res
|
||||||
return newBuf
|
|
||||||
}
|
}
|
||||||
|
@ -1,73 +1,137 @@
|
|||||||
package printer
|
package printer
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
|
"errors"
|
||||||
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"io/ioutil"
|
||||||
|
"path/filepath"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/fatih/hcl/parser"
|
"github.com/fatih/hcl/parser"
|
||||||
)
|
)
|
||||||
|
|
||||||
var listHCL = `foo = ["fatih", "arslan"]`
|
var update = flag.Bool("update", false, "update golden files")
|
||||||
var listHCL2 = `foo = [
|
|
||||||
"fatih",
|
|
||||||
"arslan",
|
|
||||||
]`
|
|
||||||
|
|
||||||
var complexHcl = `// This comes from Terraform, as a test
|
const (
|
||||||
variable "foo" {
|
dataDir = "testdata"
|
||||||
default = "bar"
|
)
|
||||||
description = "bar"
|
|
||||||
|
type entry struct {
|
||||||
|
source, golden string
|
||||||
}
|
}
|
||||||
|
|
||||||
provider "aws" {
|
// Use go test -update to create/update the respective golden files.
|
||||||
access_key = "foo"
|
var data = []entry{
|
||||||
secret_key = "bar"
|
{"complexhcl.input", "complexhcl.golden"},
|
||||||
}
|
}
|
||||||
|
|
||||||
provider "do" {
|
func TestFiles(t *testing.T) {
|
||||||
api_key = "${var.foo}"
|
for _, e := range data {
|
||||||
|
source := filepath.Join(dataDir, e.source)
|
||||||
|
golden := filepath.Join(dataDir, e.golden)
|
||||||
|
check(t, source, golden)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
resource "aws_security_group" "firewall" {
|
func check(t *testing.T, source, golden string) {
|
||||||
count = 5
|
src, err := ioutil.ReadFile(source)
|
||||||
}
|
|
||||||
|
|
||||||
resource aws_instance "web" {
|
|
||||||
ami = "${var.foo}"
|
|
||||||
security_groups = [
|
|
||||||
"foo",
|
|
||||||
"${aws_security_group.firewall.foo}"
|
|
||||||
]
|
|
||||||
|
|
||||||
network_interface {
|
|
||||||
device_index = 0
|
|
||||||
description = "Main network interface"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "aws_instance" "db" {
|
|
||||||
security_groups = "${aws_security_group.firewall.*.id}"
|
|
||||||
VPC = "foo"
|
|
||||||
|
|
||||||
depends_on = ["aws_instance.web"]
|
|
||||||
}
|
|
||||||
|
|
||||||
output "web_ip" {
|
|
||||||
value = "${aws_instance.web.private_ip}"
|
|
||||||
}
|
|
||||||
`
|
|
||||||
|
|
||||||
func TestPrint(t *testing.T) {
|
|
||||||
node, err := parser.Parse([]byte(complexHcl))
|
|
||||||
// node, err := parser.Parse([]byte(listHCL2))
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := Fprint(os.Stdout, node); err != nil {
|
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println("")
|
res, err := format(src)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// update golden files if necessary
|
||||||
|
if *update {
|
||||||
|
if err := ioutil.WriteFile(golden, res, 0644); err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// get golden
|
||||||
|
gld, err := ioutil.ReadFile(golden)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// formatted source and golden must be the same
|
||||||
|
if err := diff(source, golden, res, gld); err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// diff compares a and b.
|
||||||
|
func diff(aname, bname string, a, b []byte) error {
|
||||||
|
var buf bytes.Buffer // holding long error message
|
||||||
|
|
||||||
|
// compare lengths
|
||||||
|
if len(a) != len(b) {
|
||||||
|
fmt.Fprintf(&buf, "\nlength changed: len(%s) = %d, len(%s) = %d", aname, len(a), bname, len(b))
|
||||||
|
}
|
||||||
|
|
||||||
|
// compare contents
|
||||||
|
line := 1
|
||||||
|
offs := 1
|
||||||
|
for i := 0; i < len(a) && i < len(b); i++ {
|
||||||
|
ch := a[i]
|
||||||
|
if ch != b[i] {
|
||||||
|
fmt.Fprintf(&buf, "\n%s:%d:%d: %s", aname, line, i-offs+1, lineAt(a, offs))
|
||||||
|
fmt.Fprintf(&buf, "\n%s:%d:%d: %s", bname, line, i-offs+1, lineAt(b, offs))
|
||||||
|
fmt.Fprintf(&buf, "\n\n")
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if ch == '\n' {
|
||||||
|
line++
|
||||||
|
offs = i + 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if buf.Len() > 0 {
|
||||||
|
return errors.New(buf.String())
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// format parses src, prints the corresponding AST, verifies the resulting
|
||||||
|
// src is syntactically correct, and returns the resulting src or an error
|
||||||
|
// if any.
|
||||||
|
func format(src []byte) ([]byte, error) {
|
||||||
|
// parse src
|
||||||
|
node, err := parser.Parse(src)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("parse: %s\n%s", err, src)
|
||||||
|
}
|
||||||
|
|
||||||
|
var buf bytes.Buffer
|
||||||
|
if err := Fprint(&buf, node); err != nil {
|
||||||
|
return nil, fmt.Errorf("print: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// make sure formatted output is syntactically correct
|
||||||
|
res := buf.Bytes()
|
||||||
|
|
||||||
|
if _, err := parser.Parse(src); err != nil {
|
||||||
|
return nil, fmt.Errorf("parse: %s\n%s", err, src)
|
||||||
|
}
|
||||||
|
|
||||||
|
return res, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// lineAt returns the line in text starting at offset offs.
|
||||||
|
func lineAt(text []byte, offs int) []byte {
|
||||||
|
i := offs
|
||||||
|
for i < len(text) && text[i] != '\n' {
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
return text[offs:i]
|
||||||
}
|
}
|
||||||
|
39
printer/testdata/complexhcl.golden
vendored
Normal file
39
printer/testdata/complexhcl.golden
vendored
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
variable "foo" = {
|
||||||
|
default = "bar"
|
||||||
|
description = "bar"
|
||||||
|
}
|
||||||
|
|
||||||
|
provider "aws" = {
|
||||||
|
access_key = "foo"
|
||||||
|
secret_key = "bar"
|
||||||
|
}
|
||||||
|
|
||||||
|
provider "do" = {
|
||||||
|
api_key = "${var.foo}"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_security_group" "firewall" = {
|
||||||
|
count = 5
|
||||||
|
}
|
||||||
|
|
||||||
|
resource aws_instance "web" = {
|
||||||
|
ami = "${var.foo}"
|
||||||
|
security_groups = [
|
||||||
|
"foo",
|
||||||
|
"${aws_security_group.firewall.foo}",
|
||||||
|
]
|
||||||
|
network_interface = {
|
||||||
|
device_index = 0
|
||||||
|
description = "Main network interface"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_instance" "db" = {
|
||||||
|
security_groups = "${aws_security_group.firewall.*.id}"
|
||||||
|
VPC = "foo"
|
||||||
|
depends_on = [ "aws_instance.web"]
|
||||||
|
}
|
||||||
|
|
||||||
|
output "web_ip" = {
|
||||||
|
value = "${aws_instance.web.private_ip}"
|
||||||
|
}
|
42
printer/testdata/complexhcl.input
vendored
Normal file
42
printer/testdata/complexhcl.input
vendored
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
// This comes from Terraform, as a test
|
||||||
|
variable "foo" {
|
||||||
|
default = "bar"
|
||||||
|
description = "bar"
|
||||||
|
}
|
||||||
|
|
||||||
|
provider "aws" {
|
||||||
|
access_key = "foo"
|
||||||
|
secret_key = "bar"
|
||||||
|
}
|
||||||
|
|
||||||
|
provider "do" {
|
||||||
|
api_key = "${var.foo}"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_security_group" "firewall" {
|
||||||
|
count = 5
|
||||||
|
}
|
||||||
|
|
||||||
|
resource aws_instance "web" {
|
||||||
|
ami = "${var.foo}"
|
||||||
|
security_groups = [
|
||||||
|
"foo",
|
||||||
|
"${aws_security_group.firewall.foo}"
|
||||||
|
]
|
||||||
|
|
||||||
|
network_interface {
|
||||||
|
device_index = 0
|
||||||
|
description = "Main network interface"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_instance" "db" {
|
||||||
|
security_groups = "${aws_security_group.firewall.*.id}"
|
||||||
|
VPC = "foo"
|
||||||
|
|
||||||
|
depends_on = ["aws_instance.web"]
|
||||||
|
}
|
||||||
|
|
||||||
|
output "web_ip" {
|
||||||
|
value = "${aws_instance.web.private_ip}"
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user