dati

A Go library/binary to parse & execute data against template langauges.
git clone git://src.gearsix.net/dati
Log | Files | Refs | Atom | README | LICENSE

data_test.go (5152B)


      1 package dati
      2 
      3 /*
      4 Copyright (C) 2023 gearsix <gearsix@tuta.io>
      5 
      6 This program is free software: you can redistribute it and/or modify
      7 it under the terms of the GNU General Public License as published by
      8 the Free Software Foundation, either version 3 of the License, or
      9 at your option) any later version.
     10 
     11 This program is distributed in the hope that it will be useful,
     12 but WITHOUT ANY WARRANTY; without even the implied warranty of
     13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14 GNU General Public License for more details.
     15 
     16 You should have received a copy of the GNU General Public License
     17 along with this program.  If not, see <https://www.gnu.org/licenses/>.
     18 */
     19 
     20 import (
     21 	"bytes"
     22 	"encoding/json"
     23 	"fmt"
     24 	"io"
     25 	"os"
     26 	"path/filepath"
     27 	"strings"
     28 	"testing"
     29 
     30 	"github.com/pelletier/go-toml"
     31 	"gopkg.in/yaml.v3"
     32 )
     33 
     34 var dataExts = []string{
     35 	".json", "json", "JSON", ".JSON",
     36 	".yaml", "yaml", "YAML", ".YAML",
     37 	".toml", "toml", "TOML", ".TOML",
     38 	".misc", "-", ".", "",
     39 }
     40 
     41 func TestIsDataFormat(t *testing.T) {
     42 	for i, ext := range dataExts {
     43 		var target bool
     44 
     45 		if i < 12 {
     46 			target = true
     47 		}
     48 
     49 		is := IsDataFormat(ext)
     50 		if is != target {
     51 			t.Fatalf("%t did not return %t", is, target)
     52 		}
     53 	}
     54 }
     55 
     56 func TestReadDataFormat(t *testing.T) {
     57 	for i, ext := range dataExts {
     58 		var target DataFormat
     59 
     60 		if i < 4 {
     61 			target = JSON
     62 		} else if i < 8 {
     63 			target = YAML
     64 		} else if i < 12 {
     65 			target = TOML
     66 		}
     67 
     68 		fmt := ReadDataFormat(ext)
     69 		if fmt != target {
     70 			if target == "" {
     71 				t.Fatalf("%s is not a supported data language", fmt)
     72 			} else {
     73 				t.Fatalf("%s did not return %s", fmt, target)
     74 			}
     75 		}
     76 	}
     77 }
     78 
     79 var good = map[DataFormat]string{
     80 	JSON: `{"eg":0}`,
     81 	YAML: `eg: 0
     82 `,
     83 	TOML: `eg = 0
     84 `,
     85 }
     86 
     87 const badData = `{"json!:2:]}}`
     88 
     89 func writeTestFile(t *testing.T, path string, Data string) {
     90 	f, e := os.Create(path)
     91 	defer f.Close()
     92 	if e != nil {
     93 		t.Skipf("setup failure: %s", e)
     94 	}
     95 	_, e = f.WriteString(Data)
     96 	if e != nil {
     97 		t.Skipf("setup failure: %s", e)
     98 	}
     99 }
    100 
    101 func validateLoadData(t *testing.T, d interface{}, e error, lang DataFormat) {
    102 	var b []byte
    103 
    104 	if e != nil {
    105 		t.Fatal(e)
    106 	}
    107 
    108 	switch lang {
    109 	case JSON:
    110 		b, e = json.Marshal(d)
    111 	case YAML:
    112 		b, e = yaml.Marshal(d)
    113 	case TOML:
    114 		b, e = toml.Marshal(d)
    115 	}
    116 
    117 	if e != nil {
    118 		t.Error(e)
    119 	}
    120 	if string(b) != good[lang] {
    121 		t.Fatalf("incorrect %s: %s does not match %s", lang, b, good[lang])
    122 	}
    123 }
    124 
    125 func TestLoadData(t *testing.T) {
    126 	var d interface{}
    127 	var e error
    128 
    129 	for lang, data := range good {
    130 		e = LoadData(lang, strings.NewReader(data), &d)
    131 		validateLoadData(t, d, e, lang)
    132 	}
    133 
    134 	if e = LoadData(JSON, strings.NewReader(badData), &d); e == nil {
    135 		t.Fatalf("bad data passed")
    136 	}
    137 	if e = LoadData(TOML, strings.NewReader(""), &d); e != nil {
    138 		t.Fatalf("empty data failed %s, %s", d, e)
    139 	}
    140 	if e = LoadData("", strings.NewReader("shouldn't pass"), &d); e == nil {
    141 		t.Fatalf("invalid data language passed")
    142 	}
    143 
    144 	return
    145 }
    146 
    147 func TestLoadDataFile(t *testing.T) {
    148 	var d interface{}
    149 	var e error
    150 	var p string
    151 	tdir := os.TempDir()
    152 
    153 	for lang, data := range good {
    154 		p = tdir + "/good." + string(lang)
    155 		writeTestFile(t, p, data)
    156 		e = LoadDataFile(p, &d)
    157 		validateLoadData(t, d, e, lang)
    158 	}
    159 
    160 	p = tdir + "/bad.json"
    161 	writeTestFile(t, p, badData)
    162 	e = LoadDataFile(p, &d)
    163 	if e == nil {
    164 		t.Fatalf("bad data passed")
    165 	}
    166 
    167 	p = tdir + "/empty.json"
    168 	writeTestFile(t, p, "")
    169 	e = LoadDataFile(p, &d)
    170 	if e != nil {
    171 		t.Fatalf("empty file failed: %s", e)
    172 	}
    173 
    174 	if e = LoadDataFile("non-existing-file.toml", &d); e == nil {
    175 		t.Fatalf("non-existing file passed: %s, %s", d, e)
    176 	}
    177 }
    178 
    179 func validateWriteData(t *testing.T, err error, data string, writer io.Reader) error {
    180 	if err != nil {
    181 		return err
    182 	}
    183 
    184 	var buf []byte
    185 	if _, err = writer.Read(buf); string(buf) != data {
    186 		err = fmt.Errorf("%s does not match %s", string(buf), data)
    187 	}
    188 	return err
    189 }
    190 
    191 func TestWriteData(t *testing.T) {
    192 	var err error
    193 	var buf []byte
    194 	writer := bytes.NewBuffer(buf)
    195 
    196 	testGoodData := func(format DataFormat) {
    197 		writer.Reset()
    198 		err = WriteData(format, good[format], writer)
    199 		validateWriteData(t, err, good[format], writer)
    200 	}
    201 
    202 	testEmptyData := func(format DataFormat) {
    203 		writer.Reset()
    204 		err = WriteData(format, "", writer)
    205 		validateWriteData(t, err, "", writer)
    206 	}
    207 
    208 	testBadFormat := func() {
    209 		writer.Reset()
    210 		if err = WriteData("", good[JSON], writer); err == nil {
    211 			t.Errorf("invalid data format passed")
    212 		}
    213 	}
    214 
    215 	for _, format := range []DataFormat{JSON, TOML, YAML} {
    216 		testGoodData(format)
    217 		testEmptyData(format)
    218 	}
    219 	testBadFormat()
    220 }
    221 
    222 func TestWriteDataFile(t *testing.T) {
    223 	var err error
    224 	var path string
    225 	var file *os.File
    226 	dir := os.TempDir()
    227 
    228 	testGoodData := func(format DataFormat) {
    229 		path = filepath.Join(dir, "good."+string(format))
    230 		file, err = WriteDataFile(format, good[format], path)
    231 		validateWriteData(t, err, good[format], file)
    232 	}
    233 
    234 	testBadFormat := func() {
    235 		path = filepath.Join(dir, "bad")
    236 		if file, err = WriteDataFile("", nil, path); err == nil {
    237 			t.Errorf("bad format passed")
    238 		} else if file != nil {
    239 			t.Error("file is not nil")
    240 		}
    241 	}
    242 
    243 	for _, format := range []DataFormat{JSON, YAML, TOML} {
    244 		testGoodData(format)
    245 	}
    246 	testBadFormat()
    247 }