dati

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

data_test.go (raw) (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 }