✨ Entry with TextMarshaler
This commit is contained in:
parent
875ca7e33d
commit
e8fb298ea5
2 changed files with 160 additions and 0 deletions
|
|
@ -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
89
models/entry_test.go
Normal 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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue