Entry with TextMarshaler

This commit is contained in:
Dan Jones 2024-01-28 01:13:25 -06:00
commit e8fb298ea5
2 changed files with 160 additions and 0 deletions

View file

@ -1 +1,72 @@
package models package models
import (
"bytes"
"errors"
"strings"
"sync"
"time"
)
const DateFormat = "January 02, 2006 at 03:04:05PM -0700"
type Entry struct {
Title string
Date time.Time
Fields []Meta
}
type metaRes struct {
out []byte
err error
}
func (e Entry) getFieldMarshalChan() chan metaRes {
size := len(e.Fields)
ch := make(chan metaRes, size)
var wg sync.WaitGroup
// @todo figure out a way to handle json field
for i := 0; i < size; i++ {
wg.Add(1)
go func(i int) {
defer wg.Done()
o, er := e.Fields[i].MarshalText()
ch <- metaRes{o, er}
}(i)
}
go func() {
wg.Wait()
close(ch)
}()
return ch
}
func (e Entry) MarshalText() ([]byte, error) {
e.Title = strings.TrimSpace(e.Title)
if e.Title == "" {
return []byte{}, errors.New("Empty title")
}
if e.Date == (time.Time{}) {
return []byte{}, errors.New("Empty date")
}
ch := e.getFieldMarshalChan()
buff := &bytes.Buffer{}
buff.WriteString("@begin ")
buff.WriteString(e.Date.Format(DateFormat))
buff.WriteString(" - ")
buff.WriteString(e.Title)
for res := range ch {
if res.err == nil && len(res.out) > 0 {
buff.WriteString("\n")
buff.Write(res.out)
}
}
buff.WriteString(" @end")
return buff.Bytes(), nil
}

89
models/entry_test.go Normal file
View file

@ -0,0 +1,89 @@
package models
import (
"encoding"
//"encoding/json"
"errors"
"testing"
"time"
"github.com/stretchr/testify/assert"
)
// Type assertions
var _ encoding.TextMarshaler = Entry{}
func TestEntry(t *testing.T) {
when := time.Now()
whens := when.Format(DateFormat)
simple := []Meta{}
nolines := []string{}
tests := []struct {
name string
title string
date time.Time
fields []Meta
first string
lines []string
err error
}{
{"no-title", "", when, simple, "", nolines, errors.New("Empty title")},
{"zero-date", "Empty title", time.Time{}, simple, "", nolines, errors.New("Empty date")},
{"one-line", "A Title", when, simple, "@begin " + whens + " - A Title @end", nolines, nil},
{
"one-field",
"Title 2",
when,
[]Meta{{"age", 41}},
"@begin " + whens + " - Title 2",
[]string{"@age 41 @end"},
nil,
},
{
"three-fields",
"Title 3",
when,
[]Meta{{"age", 41}, {"cool", true}, {"name", "Jim"}},
"@begin " + whens + " - Title 3",
[]string{"@age 41", "@cool true", "@name Jim"},
nil,
},
/* uncomment when implemented
{
"json-field",
"Title J",
when,
[]Meta{{"json", json.RawMessage(`{"age": 41, "cool": true, "name": "Jim"}`)}},
"@begin " + whens + " - Title J",
[]string{"@age 41", "@cool true", "@name Jim"},
nil,
},
*/
}
for _, tt := range tests {
t.Run(tt.name, getEntryTestRunner(tt.title, tt.date, tt.fields, tt.first, tt.lines, tt.err))
}
}
func getEntryTestRunner(title string, date time.Time, fields []Meta, first string, lines []string, err error) func(*testing.T) {
return func(t *testing.T) {
en := Entry{title, date, fields}
o, er := en.MarshalText()
assert.Equal(t, err, er)
if first == "" {
return
}
if len(lines) == 0 {
assert.Equal(t, first, string(o))
return
}
os := string(o)
assert.Regexp(t, "^"+first, os)
for _, line := range lines {
assert.Regexp(t, "(?m)^"+line, os)
}
}
}