more testing

master
Jordan Orelli 5 years ago
parent 7910f65eb8
commit 31ed54c71e

@ -45,19 +45,24 @@ func (l *LineWriter) WriteEvent(e *Event) {
}
buf.WriteRune('[')
buf.WriteString(e.Path.String())
if e.Path != nil {
buf.WriteString(e.Path.String())
}
buf.WriteRune(']')
buf.WriteRune(' ')
if e.Tags == nil {
buf.WriteString("[] ")
buf.WriteString("[]")
} else {
buf.WriteRune('[')
writeTags(buf, e.Tags)
buf.WriteString("] ")
buf.WriteRune(']')
}
buf.WriteString(strings.ReplaceAll(e.Text, string('\n'), "\n"))
if e.Text != "" {
buf.WriteRune(' ')
buf.WriteString(strings.ReplaceAll(e.Text, string('\n'), "\n"))
}
l.out.Lock()
l.out.Write(buf.Bytes())

@ -7,20 +7,129 @@ import (
)
func TestLineWriter(t *testing.T) {
var buf bytes.Buffer
w := NewLineWriter(&buf)
w.WriteEvent(&Event{
Level: Debug,
Time: time.Now(),
Path: NewPath("alice").Child("bob").Child("carol"),
Text: "hey you farthead",
Tags: &Tags{
key: "poop",
parent: &Tags{
key: "num_poops",
value: 27,
},
},
})
t.Error(buf.String())
refTime := time.Date(2020, time.January, 13, 12, 26, 47, 999999, time.UTC)
tests := []struct {
name string
event Event
line string
}{
{
name: "empty event",
event: Event{},
line: `0001-01-01T00:00:00Z d [] []`,
},
{
name: "just a time",
event: Event{
Time: refTime,
},
line: `2020-01-13T12:26:47Z d [] []`,
},
{
name: "root path only",
event: Event{
Time: refTime,
Path: NewPath("root"),
},
line: `2020-01-13T12:26:47Z d [root] []`,
},
{
name: "child path",
event: Event{
Time: refTime,
Path: NewPath("root").Child("kid"),
},
line: `2020-01-13T12:26:47Z d [root/kid] []`,
},
{
name: "another child path",
event: Event{
Time: refTime,
Path: NewPath("root").Child("kid").Child("fart"),
},
line: `2020-01-13T12:26:47Z d [root/kid/fart] []`,
},
{
name: "a message",
event: Event{
Time: refTime,
Path: NewPath("root").Child("kid").Child("fart"),
Text: "this is a message",
},
line: `2020-01-13T12:26:47Z d [root/kid/fart] [] this is a message`,
},
{
name: "a message with an empty tag",
event: Event{
Time: refTime,
Path: NewPath("root").Child("kid").Child("fart"),
Text: "this is a message",
Tags: &Tags{key: "alert"},
},
line: `2020-01-13T12:26:47Z d [root/kid/fart] [alert] this is a message`,
},
{
name: "a message with two empty tags",
event: Event{
Time: refTime,
Path: NewPath("root").Child("kid").Child("fart"),
Text: "this is a message",
Tags: &Tags{
key: "zombo-dot-com",
parent: &Tags{key: "alert"},
},
},
line: `2020-01-13T12:26:47Z d [root/kid/fart] [alert+zombo-dot-com] this is a message`,
},
{
name: "a message with an int tag",
event: Event{
Time: refTime,
Path: NewPath("root").Child("kid").Child("fart"),
Text: "this is a message",
Tags: &Tags{
key: "num-users",
value: 15,
},
},
line: `2020-01-13T12:26:47Z d [root/kid/fart] [num-users=15] this is a message`,
},
{
name: "a message with a variety of tags",
event: Event{
Time: refTime,
Path: NewPath("root").Child("kid").Child("fart"),
Text: "this is a message",
Tags: &Tags{
key: "num-users",
value: 15,
parent: &Tags{
key: "pi",
value: 3.14,
parent: &Tags{
key: "request-id",
value: "b49d31c7-d3bb-4bd3-96fe-34e7c7d2b0a4",
},
},
},
},
line: `2020-01-13T12:26:47Z d [root/kid/fart] [request-id=b49d31c7-d3bb-4bd3-96fe-34e7c7d2b0a4+pi=3.14+num-users=15] this is a message`,
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
var buf bytes.Buffer
w := NewLineWriter(&buf)
w.WriteEvent(&test.event)
line := buf.String()
if line != test.line {
t.Log("expected line does not match observed line")
t.Logf("expected line: '%s'", test.line)
t.Logf("observed line: '%s'", line)
t.Fail()
}
})
}
}

@ -1,23 +1,39 @@
package blammo
// Tags represent event metadata. Tags is an ordered collection of key-value
// pairs where every key is a string. Values are optional, and may be one of
// int, float64, and string. The same key may appear multiple times.
//
// Tags is internally represented by a singly linked list of key-value pairs. A
// Tags struct is immutable once created. The only thing that can be done is to
// create new nodes that point to old nodes. This allows us to continually
// recycle tag nodes that are widely used across an application.
type Tags struct {
key string
value interface{}
parent *Tags
}
// Tag creates a new Tags struct having the given key as its final key, with no
// associated value. All existing keys continue to exist.
func (t *Tags) Tag(key string) *Tags {
return &Tags{key: key, parent: t}
}
// TagInt creates a new Tags struct having the given key-value pair as the
// final key-value pair. All existing key-value pairs continue to exist.
func (t *Tags) TagInt(key string, v int) *Tags {
return &Tags{key: key, value: v, parent: t}
}
// TagString creates a new Tags struct having the given key-value pair as the
// final key-value pair. All existing key-value pairs continue to exist.
func (t *Tags) TagString(key, v string) *Tags {
return &Tags{key: key, value: v, parent: t}
}
// TagFloat creates a new Tags struct having the given key-value pair as the
// final key-value pair. All existing key-value pairs continue to exist.
func (t *Tags) TagFloat(key string, v float64) *Tags {
return &Tags{key: key, value: v, parent: t}
}

Loading…
Cancel
Save