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

commit c95e5b6c7580432b54a4aa9d9a660d0355271dda
parent 620197169d12eec978671854d2b3eff0714c8aa3
Author: gearsix <gearsix@tuta.io>
Date:   Fri, 10 Feb 2023 12:22:53 +0000

added DataWrite(+test) and DataWriteFile(+tests)

Diffstat:
Mdata.go | 51++++++++++++++++++++++++++++++++++++++++++++-------
Mdata_test.go | 108+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------
2 files changed, 142 insertions(+), 17 deletions(-)

diff --git a/data.go b/data.go @@ -20,13 +20,14 @@ along with this program. If not, see <https://www.gnu.org/licenses/>. import ( "encoding/json" "fmt" - "github.com/pelletier/go-toml" - "gopkg.in/yaml.v3" "io" "io/ioutil" "os" "path/filepath" "strings" + + "github.com/pelletier/go-toml" + "gopkg.in/yaml.v3" ) // DataFormat provides a list of supported languages for @@ -70,8 +71,8 @@ func ReadDataFormat(path string) DataFormat { return "" } -// LoadData attempts to load all data from `in` as the data language `lang` -// and writes the result in the pointer `outp`. +// LoadData attempts to load all data from `in` as `format` and writes +// the result in the pointer `outp`. func LoadData(format DataFormat, in io.Reader, outp interface{}) error { inbuf, e := ioutil.ReadAll(in) if e != nil { @@ -94,9 +95,9 @@ func LoadData(format DataFormat, in io.Reader, outp interface{}) error { return e } -// LoadDataFile loads all the data from the file found at `path` into the the -// format of that files extension (e.g. "x.json" will be loaded as a json). -// The result is written to the value pointed at by `outp`. +// LoadDataFile loads all the data from the file found at `path` into +// the the format of that files extension (e.g. "x.json" will be loaded +// as a json). The result is written to the value pointed at by `outp`. func LoadDataFile(path string, outp interface{}) error { f, e := os.Open(path) defer f.Close() @@ -109,3 +110,39 @@ func LoadDataFile(path string, outp interface{}) error { return e } + +// WriteData attempts to write `data` as `format` to `outp`. +func WriteData(format DataFormat, data interface{}, w io.Writer) error { + var err error + + switch format { + case JSON: + err = json.NewEncoder(w).Encode(data) + case YAML: + err = yaml.NewEncoder(w).Encode(data) + case TOML: + err = toml.NewEncoder(w).Encode(data) + default: + err = fmt.Errorf("'%s' is not a supported data language", format) + } + + return err +} + +// WriteDataFile attempts to write `data` as `format` to the file at `path`. +// If `force` is *true*, then any existing files will be overwritten. +func WriteDataFile(format DataFormat, data interface{}, path string) (f *os.File, err error) { + f, err = os.Open(path) + defer f.Close() + + if err == nil { + if err = WriteData(format, data, f); err != nil { + err = fmt.Errorf("faild to write data '%s': %s", path, err.Error()) + } + } + if err != nil { + f = nil + } + + return +} diff --git a/data_test.go b/data_test.go @@ -18,12 +18,17 @@ along with this program. If not, see <https://www.gnu.org/licenses/>. */ import ( + "bytes" "encoding/json" - "github.com/pelletier/go-toml" - "gopkg.in/yaml.v3" + "fmt" + "io" "os" + "path/filepath" "strings" "testing" + + "github.com/pelletier/go-toml" + "gopkg.in/yaml.v3" ) var dataExts = []string{ @@ -36,7 +41,7 @@ var dataExts = []string{ func TestIsDataFormat(t *testing.T) { for i, ext := range dataExts { var target bool - + if i < 12 { target = true } @@ -79,7 +84,7 @@ var good = map[DataFormat]string{ `, } -const badData = `{"json"!:2:]}}` +const badData = `{"json!:2:]}}` func writeTestFile(t *testing.T, path string, Data string) { f, e := os.Create(path) @@ -91,11 +96,9 @@ func writeTestFile(t *testing.T, path string, Data string) { if e != nil { t.Skipf("setup failure: %s", e) } - - return } -func validateData(t *testing.T, d interface{}, e error, lang DataFormat) { +func validateLoadData(t *testing.T, d interface{}, e error, lang DataFormat) { var b []byte if e != nil { @@ -125,7 +128,7 @@ func TestLoadData(t *testing.T) { for lang, data := range good { e = LoadData(lang, strings.NewReader(data), &d) - validateData(t, d, e, lang) + validateLoadData(t, d, e, lang) } if e = LoadData(JSON, strings.NewReader(badData), &d); e == nil { @@ -151,7 +154,7 @@ func TestLoadDataFile(t *testing.T) { p = tdir + "/good." + string(lang) writeTestFile(t, p, data) e = LoadDataFile(p, &d) - validateData(t, d, e, lang) + validateLoadData(t, d, e, lang) } p = tdir + "/bad.json" @@ -171,6 +174,91 @@ func TestLoadDataFile(t *testing.T) { if e = LoadDataFile("non-existing-file.toml", &d); e == nil { t.Fatalf("non-existing file passed: %s, %s", d, e) } +} - return +func validateWriteData(t *testing.T, err error, data string, writer io.Reader) error { + if err != nil { + return err + } + + var buf []byte + if _, err = writer.Read(buf); string(buf) != data { + err = fmt.Errorf("%s does not match %s", string(buf), data) + } + return err +} + +func TestWriteData(t *testing.T) { + var err error + var buf []byte + writer := bytes.NewBuffer(buf) + + testGoodData := func(format DataFormat) { + writer.Reset() + err = WriteData(format, good[format], writer) + validateWriteData(t, err, good[format], writer) + } + + testEmptyData := func(format DataFormat) { + writer.Reset() + err = WriteData(format, "", writer) + validateWriteData(t, err, "", writer) + } + + testBadFormat := func() { + writer.Reset() + if err = WriteData("", good[JSON], writer); err == nil { + t.Errorf("invalid data format passed") + } + } + + for _, format := range []DataFormat{JSON, TOML, YAML} { + testGoodData(format) + testEmptyData(format) + } + testBadFormat() +} + +func TestWriteDataFile(t *testing.T) { + var err error + var path string + var file *os.File + dir := os.TempDir() + + testGoodData := func(format DataFormat) { + path = filepath.Join(dir, "good."+string(format)) + file, err = WriteDataFile(format, good[format], path) + validateWriteData(t, err, good[format], file) + } + + testEmptyData := func(format DataFormat) { + path = filepath.Join(dir, "empty."+string(format)) + file, err = WriteDataFile(format, nil, path) + validateWriteData(t, err, good[format], file) + } + + testBadData := func(format DataFormat) { + path = filepath.Join(dir, "bad."+string(format)) + if file, err = WriteDataFile(format, badData, path); err == nil { + t.Errorf("'%s': bad data passed\n", string(format)) + } else if file != nil { + t.Errorf("'%s': file is not nil\n", string(format)) + } + } + + testBadFormat := func() { + path = filepath.Join(dir, "bad") + if file, err = WriteDataFile("", nil, path); err == nil { + t.Errorf("bad format passed") + } else if file != nil { + t.Error("file is not nil") + } + } + + for _, format := range []DataFormat{JSON, YAML, TOML} { + testGoodData(format) + testEmptyData(format) + testBadData(format) + } + testBadFormat() }