package models import ( "encoding" "encoding/json" "errors" "testing" "time" "github.com/stretchr/testify/assert" ) // Type assertions var _ encoding.TextMarshaler = Entry{} var _ encoding.TextUnmarshaler = new(Entry) func TestEntryMarshal(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, ErrorMissingTitle}, {"zero-date", "Empty title", time.Time{}, simple, "", nolines, ErrorMissingDate}, {"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, getEntryMarshalTestRunner(tt.title, tt.date, tt.fields, tt.first, tt.lines, tt.err)) } } func getEntryMarshalTestRunner(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) } } } func TestEntryUnmarshal(t *testing.T) { when := time.Now() whens := when.Format(DateFormat) simple := []Meta{} tests := []struct { name string in string title string date time.Time fields []Meta err error }{ {"one-line", "@begin " + whens + " - A Title @end", "A Title", when, simple, nil}, {"multi-title", "@begin " + whens + " - A Title\nwith break @end", "A Title\nwith break", when, simple, nil}, {"no-title", "@begin " + whens + " - @end", "", when, simple, errors.New("Missing title")}, {"no-date", "@begin - A Title @end", "A Title", when, simple, errors.New("Missing date")}, {"one-field", "@begin " + whens + " - A Title\n@age 41 @end", "A Title", when, []Meta{{"age", 41}}, nil}, { "two-fields", "@begin " + whens + " - A Title\n@age 41\n@cool true @end", "A Title", when, []Meta{{"age", 41}, {"cool", true}}, nil, }, { "obj-field", "@begin " + whens + " - A Title\n" + `@me {"name":"Dan","coder":true} @end`, "A Title", when, []Meta{{"me", json.RawMessage(`{"name":"Dan","coder":true}`)}}, nil, }, /* uncomment when implemented { "json-field", "@begin " + whens + " - Some Guy\n" + `@json {"name":"Dan","coder":true} @end`, "A Title", when, []Meta{{"name", "Dan"}, {"coder", true}}, nil, }, */ } for _, tt := range tests { t.Run(tt.name, getEntryUnmarshalTestRunner(tt.in, tt.title, tt.date, tt.fields, tt.err)) } } func getEntryUnmarshalTestRunner(in string, title string, date time.Time, fields []Meta, err error) func(*testing.T) { return func(t *testing.T) { e := &Entry{} er := e.UnmarshalText([]byte(in)) assert.Equal(t, err, er) if err != nil { return } assert.Equal(t, title, e.Title) assert.WithinRange(t, e.Date, date.Add(-time.Second), date.Add(time.Second)) for _, f := range fields { got := false for _, m := range e.Fields { if m == f { got = true break } } assert.Truef(t, got, "Couldn't find field %+v", f) } } }