| // Copyright 2019 The Go Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style |
| // license that can be found in the LICENSE file. |
| |
| package logfmt_test |
| |
| import ( |
| "strings" |
| "testing" |
| "time" |
| |
| "golang.org/x/exp/event" |
| "golang.org/x/exp/event/adapter/logfmt" |
| ) |
| |
| func TestPrint(t *testing.T) { |
| var p logfmt.Printer |
| buf := &strings.Builder{} |
| // the exporter is not used, but we need it to build the events |
| at, _ := time.Parse(logfmt.TimeFormat, "2020/03/05 14:27:48") |
| for _, test := range []struct { |
| name string |
| event event.Event |
| expect string |
| }{{ |
| name: "empty", |
| event: event.Event{}, |
| expect: ``, |
| }, { |
| name: "span", |
| event: event.Event{ID: 34}, |
| expect: `trace=34`, |
| }, { |
| name: "parent", |
| event: event.Event{Parent: 14}, |
| expect: `parent=14`, |
| }, { |
| name: "namespace", |
| event: event.Event{Source: event.Source{Space: "golang.org/x/exp/event"}}, |
| expect: `in=golang.org/x/exp/event`, |
| }, { |
| name: "at", |
| event: event.Event{At: at}, |
| expect: `time="2020/03/05 14:27:48"`, |
| }, { |
| name: "message", |
| event: event.Event{Labels: []event.Label{event.String("msg", "a message")}}, |
| expect: `msg="a message"`, |
| }, { |
| name: "end", |
| event: event.Event{Kind: event.EndKind}, |
| expect: `end`, |
| }, { |
| name: "string", |
| event: event.Event{ |
| Labels: []event.Label{ |
| event.String("v1", "text"), |
| event.String("v2", "text with quotes"), |
| event.String("empty", ""), |
| }, |
| }, |
| expect: `v1=text v2="text with quotes" empty=""`, |
| }, { |
| name: "int", |
| event: event.Event{ |
| Labels: []event.Label{ |
| event.Int64("value", 67), |
| }, |
| }, |
| expect: `value=67`, |
| }, { |
| name: "float", |
| event: event.Event{ |
| Labels: []event.Label{ |
| event.Float64("value", 263.2), |
| }, |
| }, |
| expect: `value=263.2`, |
| }, { |
| name: "bool", |
| event: event.Event{ |
| Labels: []event.Label{ |
| event.Bool("v1", true), |
| event.Bool("v2", false), |
| }, |
| }, |
| expect: `v1=true v2=false`, |
| }, { |
| name: "value", |
| event: event.Event{ |
| Labels: []event.Label{ |
| event.Value("v1", notString{"simple"}), |
| event.Value("v2", notString{"needs quoting"}), |
| }, |
| }, |
| expect: `v1=simple v2="needs quoting"`, |
| }, { |
| name: "empty label", |
| event: event.Event{ |
| Labels: []event.Label{ |
| event.Value("before", nil), |
| event.String("", "text"), |
| event.Value("after", nil), |
| }, |
| }, |
| expect: `before after`, |
| }, { |
| name: "quoted ident", |
| event: event.Event{ |
| Labels: []event.Label{ |
| event.String("name with space", "text"), |
| }, |
| }, |
| expect: `"name with space"=text`, |
| }, { |
| name: "quoting quote", |
| event: event.Event{Labels: []event.Label{event.String("msg", `with"middle`)}}, |
| expect: `msg="with\"middle"`, |
| }, { |
| name: "quoting newline", |
| event: event.Event{Labels: []event.Label{event.String("msg", "with\nmiddle")}}, |
| expect: `msg="with\nmiddle"`, |
| }, { |
| name: "quoting slash", |
| event: event.Event{Labels: []event.Label{event.String("msg", `with\middle`)}}, |
| expect: `msg="with\\middle"`, |
| }, { |
| name: "quoting bytes", |
| event: event.Event{ |
| Labels: []event.Label{ |
| event.Bytes("value", ([]byte)(`bytes "need" quote`)), |
| }, |
| }, |
| expect: `value="bytes \"need\" quote"`, |
| }} { |
| t.Run(test.name, func(t *testing.T) { |
| buf.Reset() |
| p.Event(buf, &test.event) |
| got := strings.TrimSpace(buf.String()) |
| if got != test.expect { |
| t.Errorf("got: \n%q\nexpect:\n%q\n", got, test.expect) |
| } |
| }) |
| } |
| } |
| |
| type notString struct { |
| value string |
| } |
| |
| func (v notString) String() string { return v.value } |
| |
| func TestPrinterFlags(t *testing.T) { |
| var reference logfmt.Printer |
| buf := &strings.Builder{} |
| // the exporter is not used, but we need it to build the events |
| for _, test := range []struct { |
| name string |
| printer logfmt.Printer |
| event event.Event |
| before string |
| after string |
| }{{ |
| name: "quote values", |
| printer: logfmt.Printer{QuoteValues: true}, |
| event: event.Event{ |
| Labels: []event.Label{ |
| event.String("value", "text"), |
| }, |
| }, |
| before: `value=text`, |
| after: `value="text"`, |
| }, { |
| name: "suppress namespace", |
| printer: logfmt.Printer{SuppressNamespace: true}, |
| event: event.Event{ |
| Source: event.Source{Space: "golang.org/x/exp/event"}, |
| Labels: []event.Label{event.String("msg", "some text")}, |
| }, |
| before: `in=golang.org/x/exp/event msg="some text"`, |
| after: `msg="some text"`, |
| }} { |
| t.Run(test.name, func(t *testing.T) { |
| buf.Reset() |
| reference.Event(buf, &test.event) |
| gotBefore := strings.TrimSpace(buf.String()) |
| buf.Reset() |
| test.printer.Event(buf, &test.event) |
| gotAfter := strings.TrimSpace(buf.String()) |
| if gotBefore != test.before { |
| t.Errorf("got: \n%q\nexpect:\n%q\n", gotBefore, test.before) |
| } |
| if gotAfter != test.after { |
| t.Errorf("got: \n%q\nexpect:\n%q\n", gotAfter, test.after) |
| } |
| }) |
| } |
| } |