From 4c0edcd1a58a2c39e7043b1646cbe930aa52f9b4 Mon Sep 17 00:00:00 2001 From: Dan Jones Date: Sun, 10 Mar 2024 11:33:51 -0500 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20Add=20JSON=20formatter?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- formatters/json.go | 63 ++++++++++++++++++++++++++++++++++++++ formatters/json_test.go | 67 +++++++++++++++++++++++++++++++++++++++++ formatters/new.go | 1 + formatters/new_test.go | 2 +- 4 files changed, 132 insertions(+), 1 deletion(-) create mode 100644 formatters/json.go create mode 100644 formatters/json_test.go diff --git a/formatters/json.go b/formatters/json.go new file mode 100644 index 0000000..b3b2d97 --- /dev/null +++ b/formatters/json.go @@ -0,0 +1,63 @@ +package formatters + +import ( + "encoding/json" + "time" + + "codeberg.org/danjones000/my-log/config" + "codeberg.org/danjones000/my-log/models" + //"codeberg.org/danjones000/my-log/tools" +) + +func newJson(ff config.Formatters) (Formatter, error) { + // @todo pretty print + return &Json{ff.Json()}, nil +} + +type Json struct { + jf config.JsonFormat +} + +func (js *Json) Name() string { + return "json" +} + +func (js *Json) Meta(m models.Meta) ([]byte, error) { + o := map[string]any{m.Key: m.Value} + return json.Marshal(o) +} + +func (js *Json) entryMap(e models.Entry) map[string]any { + o := map[string]any{ + "title": e.Title, + "date": e.Date.Format(time.RFC3339), + } + for _, m := range e.Fields { + o[m.Key] = m.Value + } + return o +} + +func (js *Json) Entry(e models.Entry) ([]byte, error) { + return json.Marshal(js.entryMap(e)) +} + +func (js *Json) Log(l models.Log) ([]byte, error) { + return js.Logs([]models.Log{l}) +} + +func (js *Json) Logs(logs []models.Log) (out []byte, err error) { + if len(logs) == 0 { + return + } + + o := map[string][]map[string]any{} + for _, l := range logs { + es := []map[string]any{} + for _, e := range l.Entries { + es = append(es, js.entryMap(e)) + } + o[l.Name] = es + } + return json.Marshal(o) +} diff --git a/formatters/json_test.go b/formatters/json_test.go new file mode 100644 index 0000000..a81d4ed --- /dev/null +++ b/formatters/json_test.go @@ -0,0 +1,67 @@ +package formatters + +import ( + //"bufio" + //"bytes" + "fmt" + "testing" + "time" + + "codeberg.org/danjones000/my-log/models" + //"codeberg.org/danjones000/my-log/tools" + "github.com/stretchr/testify/assert" + //"github.com/stretchr/testify/require" +) + +func TestJsonName(t *testing.T) { + f, _ := New("json") + assert.Equal(t, "json", f.Name()) +} + +func TestJsonMeta(t *testing.T) { + f, _ := New("json") + m := models.Meta{"foo", 42} + exp := `{"foo":42}` + o, err := f.Meta(m) + assert.NoError(t, err) + assert.JSONEq(t, exp, string(o)) +} + +func TestJsonEntry(t *testing.T) { + when := time.Now() + f, _ := New("json") + m := models.Meta{"foo", 42} + e := models.Entry{ + Title: "Homer", + Date: when, + Fields: []models.Meta{m}, + } + exp := fmt.Sprintf(`{"title":"%s","date":"%s","foo":42}`, e.Title, when.Format(time.RFC3339)) + o, err := f.Entry(e) + assert.NoError(t, err) + assert.JSONEq(t, exp, string(o)) +} + +func TestJsonLog(t *testing.T) { + when := time.Now() + f, _ := New("json") + m := models.Meta{"foo", 42} + e := models.Entry{ + Title: "Homer", + Date: when, + Fields: []models.Meta{m}, + } + l := models.Log{"stuff", []models.Entry{e}} + exp := fmt.Sprintf(`{"%s":[{"title":"%s","date":"%s","foo":42}]}`, l.Name, e.Title, when.Format(time.RFC3339)) + o, err := f.Log(l) + assert.NoError(t, err) + assert.JSONEq(t, exp, string(o)) +} + +func TestJsonNoLogs(t *testing.T) { + f, _ := New("json") + o, err := f.Logs([]models.Log{}) + var exp []byte + assert.NoError(t, err) + assert.Equal(t, exp, o) +} diff --git a/formatters/new.go b/formatters/new.go index d88a9d0..37d8a96 100644 --- a/formatters/new.go +++ b/formatters/new.go @@ -10,6 +10,7 @@ type formatMaker func(config.Formatters) (Formatter, error) var formatterMap = map[string]formatMaker{ "plain": newPlain, + "json": newJson, } func Preferred() (f Formatter, err error) { diff --git a/formatters/new_test.go b/formatters/new_test.go index 04b40fb..c6d5e56 100644 --- a/formatters/new_test.go +++ b/formatters/new_test.go @@ -10,7 +10,7 @@ import ( ) func TestKinds(t *testing.T) { - assert.Equal(t, []string{"plain"}, Kinds()) + assert.ElementsMatch(t, []string{"plain", "json"}, Kinds()) } func TestNewUnsupported(t *testing.T) {