2018-05-22 02:39:26 +02:00
package funcs
import (
"fmt"
2018-05-23 00:43:29 +02:00
"path/filepath"
2018-05-22 02:39:26 +02:00
"testing"
2018-05-23 00:43:29 +02:00
homedir "github.com/mitchellh/go-homedir"
2018-05-22 02:39:26 +02:00
"github.com/zclconf/go-cty/cty"
2018-12-21 02:42:42 +01:00
"github.com/zclconf/go-cty/cty/function"
2018-05-22 02:39:26 +02:00
)
func TestFile ( t * testing . T ) {
tests := [ ] struct {
Path cty . Value
Want cty . Value
Err bool
} {
{
cty . StringVal ( "testdata/hello.txt" ) ,
cty . StringVal ( "Hello World" ) ,
false ,
} ,
{
cty . StringVal ( "testdata/icon.png" ) ,
cty . NilVal ,
true , // Not valid UTF-8
} ,
{
cty . StringVal ( "testdata/missing" ) ,
cty . NilVal ,
true , // no file exists
} ,
}
for _ , test := range tests {
t . Run ( fmt . Sprintf ( "File(\".\", %#v)" , test . Path ) , func ( t * testing . T ) {
got , err := File ( "." , test . Path )
if test . Err {
if err == nil {
t . Fatal ( "succeeded; want error" )
}
return
2018-05-23 18:38:12 +02:00
} else if err != nil {
t . Fatalf ( "unexpected error: %s" , err )
2018-05-22 02:39:26 +02:00
}
if ! got . RawEquals ( test . Want ) {
t . Errorf ( "wrong result\ngot: %#v\nwant: %#v" , got , test . Want )
}
} )
}
}
2018-12-21 02:42:42 +01:00
func TestTemplateFile ( t * testing . T ) {
tests := [ ] struct {
Path cty . Value
Vars cty . Value
Want cty . Value
2020-02-22 01:26:32 +01:00
Err string
2018-12-21 02:42:42 +01:00
} {
{
cty . StringVal ( "testdata/hello.txt" ) ,
cty . EmptyObjectVal ,
cty . StringVal ( "Hello World" ) ,
2020-02-22 01:26:32 +01:00
` ` ,
2018-12-21 02:42:42 +01:00
} ,
{
cty . StringVal ( "testdata/icon.png" ) ,
cty . EmptyObjectVal ,
cty . NilVal ,
2020-02-22 01:26:32 +01:00
` contents of testdata/icon.png are not valid UTF-8; use the filebase64 function to obtain the Base64 encoded contents or the other file functions (e.g. filemd5, filesha256) to obtain file hashing results instead ` ,
2018-12-21 02:42:42 +01:00
} ,
{
cty . StringVal ( "testdata/missing" ) ,
cty . EmptyObjectVal ,
cty . NilVal ,
2020-02-22 01:26:32 +01:00
` no file exists at testdata/missing ` ,
2018-12-21 02:42:42 +01:00
} ,
{
cty . StringVal ( "testdata/hello.tmpl" ) ,
cty . MapVal ( map [ string ] cty . Value {
"name" : cty . StringVal ( "Jodie" ) ,
} ) ,
cty . StringVal ( "Hello, Jodie!" ) ,
2020-02-22 01:26:32 +01:00
` ` ,
2018-12-21 02:42:42 +01:00
} ,
{
cty . StringVal ( "testdata/hello.tmpl" ) ,
cty . ObjectVal ( map [ string ] cty . Value {
"name" : cty . StringVal ( "Jimbo" ) ,
} ) ,
cty . StringVal ( "Hello, Jimbo!" ) ,
2020-02-22 01:26:32 +01:00
` ` ,
2018-12-21 02:42:42 +01:00
} ,
{
cty . StringVal ( "testdata/hello.tmpl" ) ,
cty . EmptyObjectVal ,
cty . NilVal ,
2020-02-22 01:26:32 +01:00
` vars map does not contain key "name", referenced at testdata/hello.tmpl:1,10-14 ` ,
2018-12-21 02:42:42 +01:00
} ,
{
cty . StringVal ( "testdata/func.tmpl" ) ,
cty . ObjectVal ( map [ string ] cty . Value {
"list" : cty . ListVal ( [ ] cty . Value {
cty . StringVal ( "a" ) ,
cty . StringVal ( "b" ) ,
cty . StringVal ( "c" ) ,
} ) ,
} ) ,
cty . StringVal ( "The items are a, b, c" ) ,
2020-02-22 01:26:32 +01:00
` ` ,
2018-12-21 02:42:42 +01:00
} ,
{
cty . StringVal ( "testdata/recursive.tmpl" ) ,
cty . MapValEmpty ( cty . String ) ,
cty . NilVal ,
2020-02-22 01:26:32 +01:00
` testdata/recursive.tmpl:1,3-16: Error in function call; Call to function "templatefile" failed: cannot recursively call templatefile from inside templatefile call. ` ,
2018-12-21 02:42:42 +01:00
} ,
{
cty . StringVal ( "testdata/list.tmpl" ) ,
cty . ObjectVal ( map [ string ] cty . Value {
"list" : cty . ListVal ( [ ] cty . Value {
cty . StringVal ( "a" ) ,
cty . StringVal ( "b" ) ,
cty . StringVal ( "c" ) ,
} ) ,
} ) ,
cty . StringVal ( "- a\n- b\n- c\n" ) ,
2020-02-22 01:26:32 +01:00
` ` ,
2018-12-21 02:42:42 +01:00
} ,
{
cty . StringVal ( "testdata/list.tmpl" ) ,
cty . ObjectVal ( map [ string ] cty . Value {
"list" : cty . True ,
} ) ,
cty . NilVal ,
2020-02-22 01:26:32 +01:00
` testdata/list.tmpl:1,13-17: Iteration over non-iterable value; A value of type bool cannot be used as the collection in a 'for' expression. ` ,
2018-12-21 02:42:42 +01:00
} ,
{
cty . StringVal ( "testdata/bare.tmpl" ) ,
cty . ObjectVal ( map [ string ] cty . Value {
"val" : cty . True ,
} ) ,
cty . True , // since this template contains only an interpolation, its true value shines through
2020-02-22 01:26:32 +01:00
` ` ,
2018-12-21 02:42:42 +01:00
} ,
}
templateFileFn := MakeTemplateFileFunc ( "." , func ( ) map [ string ] function . Function {
return map [ string ] function . Function {
"join" : JoinFunc ,
"templatefile" : MakeFileFunc ( "." , false ) , // just a placeholder, since templatefile itself overrides this
}
} )
for _ , test := range tests {
t . Run ( fmt . Sprintf ( "TemplateFile(%#v, %#v)" , test . Path , test . Vars ) , func ( t * testing . T ) {
got , err := templateFileFn . Call ( [ ] cty . Value { test . Path , test . Vars } )
2019-03-20 00:07:04 +01:00
if argErr , ok := err . ( function . ArgError ) ; ok {
if argErr . Index < 0 || argErr . Index > 1 {
t . Errorf ( "ArgError index %d is out of range for templatefile (must be 0 or 1)" , argErr . Index )
}
}
2020-02-22 01:26:32 +01:00
if test . Err != "" {
2018-12-21 02:42:42 +01:00
if err == nil {
t . Fatal ( "succeeded; want error" )
}
2020-02-22 01:26:32 +01:00
if got , want := err . Error ( ) , test . Err ; got != want {
t . Errorf ( "wrong error\ngot: %s\nwant: %s" , got , want )
}
2018-12-21 02:42:42 +01:00
return
} else if err != nil {
t . Fatalf ( "unexpected error: %s" , err )
}
if ! got . RawEquals ( test . Want ) {
t . Errorf ( "wrong result\ngot: %#v\nwant: %#v" , got , test . Want )
}
} )
}
}
2018-10-11 12:40:09 +02:00
func TestFileExists ( t * testing . T ) {
tests := [ ] struct {
Path cty . Value
Want cty . Value
Err bool
} {
{
cty . StringVal ( "testdata/hello.txt" ) ,
cty . BoolVal ( true ) ,
false ,
} ,
{
cty . StringVal ( "" ) , // empty path
cty . BoolVal ( false ) ,
true ,
} ,
{
cty . StringVal ( "testdata/missing" ) ,
cty . BoolVal ( false ) ,
false , // no file exists
} ,
}
for _ , test := range tests {
t . Run ( fmt . Sprintf ( "FileExists(\".\", %#v)" , test . Path ) , func ( t * testing . T ) {
got , err := FileExists ( "." , test . Path )
if test . Err {
if err == nil {
t . Fatal ( "succeeded; want error" )
}
return
} else if err != nil {
t . Fatalf ( "unexpected error: %s" , err )
}
if ! got . RawEquals ( test . Want ) {
t . Errorf ( "wrong result\ngot: %#v\nwant: %#v" , got , test . Want )
}
} )
}
}
2019-08-20 10:50:01 +02:00
func TestFileSet ( t * testing . T ) {
tests := [ ] struct {
2019-08-28 17:54:04 +02:00
Path cty . Value
2019-08-20 10:50:01 +02:00
Pattern cty . Value
Want cty . Value
Err bool
} {
{
2019-08-28 17:54:04 +02:00
cty . StringVal ( "." ) ,
cty . StringVal ( "testdata*" ) ,
2019-08-20 10:50:01 +02:00
cty . SetValEmpty ( cty . String ) ,
false ,
} ,
{
2019-08-28 17:54:04 +02:00
cty . StringVal ( "." ) ,
cty . StringVal ( "testdata" ) ,
2019-08-20 10:50:01 +02:00
cty . SetValEmpty ( cty . String ) ,
false ,
} ,
2019-08-31 02:14:38 +02:00
{
cty . StringVal ( "." ) ,
cty . StringVal ( "{testdata,missing}" ) ,
cty . SetValEmpty ( cty . String ) ,
false ,
} ,
2019-08-20 10:50:01 +02:00
{
2019-08-28 17:54:04 +02:00
cty . StringVal ( "." ) ,
cty . StringVal ( "testdata/missing" ) ,
2019-08-20 10:50:01 +02:00
cty . SetValEmpty ( cty . String ) ,
false ,
} ,
{
2019-08-28 17:54:04 +02:00
cty . StringVal ( "." ) ,
cty . StringVal ( "testdata/missing*" ) ,
2019-08-20 10:50:01 +02:00
cty . SetValEmpty ( cty . String ) ,
false ,
} ,
{
2019-08-28 17:54:04 +02:00
cty . StringVal ( "." ) ,
cty . StringVal ( "*/missing" ) ,
2019-08-20 10:50:01 +02:00
cty . SetValEmpty ( cty . String ) ,
false ,
} ,
2019-08-31 02:14:38 +02:00
{
cty . StringVal ( "." ) ,
cty . StringVal ( "**/missing" ) ,
cty . SetValEmpty ( cty . String ) ,
false ,
} ,
2019-08-20 10:50:01 +02:00
{
2019-08-28 17:54:04 +02:00
cty . StringVal ( "." ) ,
2019-08-20 10:50:01 +02:00
cty . StringVal ( "testdata/*.txt" ) ,
cty . SetVal ( [ ] cty . Value {
cty . StringVal ( "testdata/hello.txt" ) ,
} ) ,
false ,
} ,
{
2019-08-28 17:54:04 +02:00
cty . StringVal ( "." ) ,
2019-08-20 10:50:01 +02:00
cty . StringVal ( "testdata/hello.txt" ) ,
cty . SetVal ( [ ] cty . Value {
cty . StringVal ( "testdata/hello.txt" ) ,
} ) ,
false ,
} ,
{
2019-08-28 17:54:04 +02:00
cty . StringVal ( "." ) ,
2019-08-20 10:50:01 +02:00
cty . StringVal ( "testdata/hello.???" ) ,
cty . SetVal ( [ ] cty . Value {
cty . StringVal ( "testdata/hello.txt" ) ,
} ) ,
false ,
} ,
{
2019-08-28 17:54:04 +02:00
cty . StringVal ( "." ) ,
2019-08-20 10:50:01 +02:00
cty . StringVal ( "testdata/hello*" ) ,
cty . SetVal ( [ ] cty . Value {
cty . StringVal ( "testdata/hello.tmpl" ) ,
cty . StringVal ( "testdata/hello.txt" ) ,
} ) ,
false ,
} ,
2019-08-31 02:14:38 +02:00
{
cty . StringVal ( "." ) ,
cty . StringVal ( "testdata/hello.{tmpl,txt}" ) ,
cty . SetVal ( [ ] cty . Value {
cty . StringVal ( "testdata/hello.tmpl" ) ,
cty . StringVal ( "testdata/hello.txt" ) ,
} ) ,
false ,
} ,
2019-08-20 10:50:01 +02:00
{
2019-08-28 17:54:04 +02:00
cty . StringVal ( "." ) ,
2019-08-20 10:50:01 +02:00
cty . StringVal ( "*/hello.txt" ) ,
cty . SetVal ( [ ] cty . Value {
cty . StringVal ( "testdata/hello.txt" ) ,
} ) ,
false ,
} ,
{
2019-08-28 17:54:04 +02:00
cty . StringVal ( "." ) ,
2019-08-20 10:50:01 +02:00
cty . StringVal ( "*/*.txt" ) ,
cty . SetVal ( [ ] cty . Value {
cty . StringVal ( "testdata/hello.txt" ) ,
} ) ,
false ,
} ,
{
2019-08-28 17:54:04 +02:00
cty . StringVal ( "." ) ,
2019-08-20 10:50:01 +02:00
cty . StringVal ( "*/hello*" ) ,
cty . SetVal ( [ ] cty . Value {
cty . StringVal ( "testdata/hello.tmpl" ) ,
cty . StringVal ( "testdata/hello.txt" ) ,
} ) ,
false ,
} ,
2019-08-31 02:14:38 +02:00
{
cty . StringVal ( "." ) ,
cty . StringVal ( "**/hello*" ) ,
cty . SetVal ( [ ] cty . Value {
cty . StringVal ( "testdata/hello.tmpl" ) ,
cty . StringVal ( "testdata/hello.txt" ) ,
} ) ,
false ,
} ,
{
cty . StringVal ( "." ) ,
cty . StringVal ( "**/hello.{tmpl,txt}" ) ,
cty . SetVal ( [ ] cty . Value {
cty . StringVal ( "testdata/hello.tmpl" ) ,
cty . StringVal ( "testdata/hello.txt" ) ,
} ) ,
false ,
} ,
2019-08-20 10:50:01 +02:00
{
2019-08-28 17:54:04 +02:00
cty . StringVal ( "." ) ,
2019-08-20 10:50:01 +02:00
cty . StringVal ( "[" ) ,
cty . SetValEmpty ( cty . String ) ,
true ,
} ,
{
2019-08-28 17:54:04 +02:00
cty . StringVal ( "." ) ,
2019-08-20 10:50:01 +02:00
cty . StringVal ( "\\" ) ,
cty . SetValEmpty ( cty . String ) ,
true ,
} ,
2019-08-28 17:54:04 +02:00
{
cty . StringVal ( "testdata" ) ,
cty . StringVal ( "missing" ) ,
cty . SetValEmpty ( cty . String ) ,
false ,
} ,
{
cty . StringVal ( "testdata" ) ,
cty . StringVal ( "missing*" ) ,
cty . SetValEmpty ( cty . String ) ,
false ,
} ,
{
cty . StringVal ( "testdata" ) ,
cty . StringVal ( "*.txt" ) ,
cty . SetVal ( [ ] cty . Value {
cty . StringVal ( "hello.txt" ) ,
} ) ,
false ,
} ,
{
cty . StringVal ( "testdata" ) ,
cty . StringVal ( "hello.txt" ) ,
cty . SetVal ( [ ] cty . Value {
cty . StringVal ( "hello.txt" ) ,
} ) ,
false ,
} ,
{
cty . StringVal ( "testdata" ) ,
cty . StringVal ( "hello.???" ) ,
cty . SetVal ( [ ] cty . Value {
cty . StringVal ( "hello.txt" ) ,
} ) ,
false ,
} ,
{
cty . StringVal ( "testdata" ) ,
cty . StringVal ( "hello*" ) ,
cty . SetVal ( [ ] cty . Value {
cty . StringVal ( "hello.tmpl" ) ,
cty . StringVal ( "hello.txt" ) ,
} ) ,
false ,
} ,
2019-08-20 10:50:01 +02:00
}
for _ , test := range tests {
2019-08-28 17:54:04 +02:00
t . Run ( fmt . Sprintf ( "FileSet(\".\", %#v, %#v)" , test . Path , test . Pattern ) , func ( t * testing . T ) {
got , err := FileSet ( "." , test . Path , test . Pattern )
2019-08-20 10:50:01 +02:00
if test . Err {
if err == nil {
t . Fatal ( "succeeded; want error" )
}
return
} else if err != nil {
t . Fatalf ( "unexpected error: %s" , err )
}
if ! got . RawEquals ( test . Want ) {
t . Errorf ( "wrong result\ngot: %#v\nwant: %#v" , got , test . Want )
}
} )
}
}
2018-05-22 02:39:26 +02:00
func TestFileBase64 ( t * testing . T ) {
tests := [ ] struct {
Path cty . Value
Want cty . Value
Err bool
} {
{
cty . StringVal ( "testdata/hello.txt" ) ,
cty . StringVal ( "SGVsbG8gV29ybGQ=" ) ,
false ,
} ,
{
cty . StringVal ( "testdata/icon.png" ) ,
cty . StringVal ( "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAq1BMVEX///9cTuVeUeRcTuZcTuZcT+VbSe1cTuVdT+MAAP9JSbZcT+VcTuZAQLFAQLJcTuVcTuZcUuBBQbA/P7JAQLJaTuRcT+RcTuVGQ7xAQLJVVf9cTuVcTuVGRMFeUeRbTeJcTuU/P7JeTeZbTOVcTeZAQLJBQbNAQLNaUORcTeZbT+VcTuRAQLNAQLRdTuRHR8xgUOdgUN9cTuVdTeRdT+VZTulcTuVAQLL///8+GmETAAAANnRSTlMApibw+osO6DcBB3fIX87+oRk3yehB0/Nj/gNs7nsTRv3dHmu//JYUMLVr3bssjxkgEK5CaxeK03nIAAAAAWJLR0QAiAUdSAAAAAlwSFlzAAADoQAAA6EBvJf9gwAAAAd0SU1FB+EEBRIQDxZNTKsAAACCSURBVBjTfc7JFsFQEATQQpCYxyBEzJ55rvf/f0ZHcyQLvelTd1GngEwWycs5+UISyKLraSi9geWKK9Gr1j7AeqOJVtt2XtD1Bchef2BjQDAcCTC0CsA4mihMtXw2XwgsV2sFw812F+4P3y2GdI6nn3FGSs//4HJNAXDzU4Dg/oj/E+bsEbhf5cMsAAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDE3LTA0LTA1VDE4OjE2OjE1KzAyOjAws5bLVQAAACV0RVh0ZGF0ZTptb2RpZnkAMjAxNy0wNC0wNVQxODoxNjoxNSswMjowMMLLc+kAAAAZdEVYdFNvZnR3YXJlAHd3dy5pbmtzY2FwZS5vcmeb7jwaAAAAC3RFWHRUaXRsZQBHcm91cJYfIowAAABXelRYdFJhdyBwcm9maWxlIHR5cGUgaXB0YwAAeJzj8gwIcVYoKMpPy8xJ5VIAAyMLLmMLEyMTS5MUAxMgRIA0w2QDI7NUIMvY1MjEzMQcxAfLgEigSi4A6hcRdPJCNZUAAAAASUVORK5CYII=" ) ,
false ,
} ,
{
cty . StringVal ( "testdata/missing" ) ,
cty . NilVal ,
true , // no file exists
} ,
}
for _ , test := range tests {
t . Run ( fmt . Sprintf ( "FileBase64(\".\", %#v)" , test . Path ) , func ( t * testing . T ) {
got , err := FileBase64 ( "." , test . Path )
if test . Err {
if err == nil {
t . Fatal ( "succeeded; want error" )
}
return
2018-05-23 18:38:12 +02:00
} else if err != nil {
t . Fatalf ( "unexpected error: %s" , err )
2018-05-22 02:39:26 +02:00
}
if ! got . RawEquals ( test . Want ) {
t . Errorf ( "wrong result\ngot: %#v\nwant: %#v" , got , test . Want )
}
} )
}
}
2018-05-23 00:04:49 +02:00
func TestBasename ( t * testing . T ) {
tests := [ ] struct {
Path cty . Value
Want cty . Value
Err bool
} {
{
cty . StringVal ( "testdata/hello.txt" ) ,
cty . StringVal ( "hello.txt" ) ,
false ,
} ,
{
cty . StringVal ( "hello.txt" ) ,
cty . StringVal ( "hello.txt" ) ,
false ,
} ,
{
cty . StringVal ( "" ) ,
cty . StringVal ( "." ) ,
false ,
} ,
}
for _ , test := range tests {
t . Run ( fmt . Sprintf ( "Basename(%#v)" , test . Path ) , func ( t * testing . T ) {
got , err := Basename ( test . Path )
if test . Err {
if err == nil {
t . Fatal ( "succeeded; want error" )
}
return
2018-05-23 18:38:12 +02:00
} else if err != nil {
t . Fatalf ( "unexpected error: %s" , err )
2018-05-23 00:04:49 +02:00
}
if ! got . RawEquals ( test . Want ) {
t . Errorf ( "wrong result\ngot: %#v\nwant: %#v" , got , test . Want )
}
} )
}
}
2018-05-23 00:24:50 +02:00
func TestDirname ( t * testing . T ) {
tests := [ ] struct {
Path cty . Value
Want cty . Value
Err bool
} {
{
cty . StringVal ( "testdata/hello.txt" ) ,
cty . StringVal ( "testdata" ) ,
false ,
} ,
{
cty . StringVal ( "testdata/foo/hello.txt" ) ,
cty . StringVal ( "testdata/foo" ) ,
false ,
} ,
{
cty . StringVal ( "hello.txt" ) ,
cty . StringVal ( "." ) ,
false ,
} ,
{
cty . StringVal ( "" ) ,
cty . StringVal ( "." ) ,
false ,
} ,
}
for _ , test := range tests {
t . Run ( fmt . Sprintf ( "Dirname(%#v)" , test . Path ) , func ( t * testing . T ) {
got , err := Dirname ( test . Path )
if test . Err {
if err == nil {
t . Fatal ( "succeeded; want error" )
}
return
2018-05-23 18:38:12 +02:00
} else if err != nil {
t . Fatalf ( "unexpected error: %s" , err )
2018-05-23 00:24:50 +02:00
}
if ! got . RawEquals ( test . Want ) {
t . Errorf ( "wrong result\ngot: %#v\nwant: %#v" , got , test . Want )
}
} )
}
}
2018-05-23 00:43:29 +02:00
func TestPathExpand ( t * testing . T ) {
homePath , err := homedir . Dir ( )
if err != nil {
t . Fatalf ( "Error getting home directory: %v" , err )
}
tests := [ ] struct {
Path cty . Value
Want cty . Value
Err bool
} {
{
cty . StringVal ( "~/test-file" ) ,
cty . StringVal ( filepath . Join ( homePath , "test-file" ) ) ,
false ,
} ,
{
cty . StringVal ( "~/another/test/file" ) ,
cty . StringVal ( filepath . Join ( homePath , "another/test/file" ) ) ,
false ,
} ,
{
cty . StringVal ( "/root/file" ) ,
cty . StringVal ( "/root/file" ) ,
false ,
} ,
{
cty . StringVal ( "/" ) ,
cty . StringVal ( "/" ) ,
false ,
} ,
}
for _ , test := range tests {
t . Run ( fmt . Sprintf ( "Dirname(%#v)" , test . Path ) , func ( t * testing . T ) {
got , err := Pathexpand ( test . Path )
if test . Err {
if err == nil {
t . Fatal ( "succeeded; want error" )
}
return
2018-05-23 18:38:12 +02:00
} else if err != nil {
t . Fatalf ( "unexpected error: %s" , err )
2018-05-23 00:43:29 +02:00
}
if ! got . RawEquals ( test . Want ) {
t . Errorf ( "wrong result\ngot: %#v\nwant: %#v" , got , test . Want )
}
} )
}
}