1// Copyright 2022 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package slog
6
7import (
8	"bytes"
9	"flag"
10	"strings"
11	"testing"
12)
13
14func TestLevelString(t *testing.T) {
15	for _, test := range []struct {
16		in   Level
17		want string
18	}{
19		{0, "INFO"},
20		{LevelError, "ERROR"},
21		{LevelError + 2, "ERROR+2"},
22		{LevelError - 2, "WARN+2"},
23		{LevelWarn, "WARN"},
24		{LevelWarn - 1, "INFO+3"},
25		{LevelInfo, "INFO"},
26		{LevelInfo + 1, "INFO+1"},
27		{LevelInfo - 3, "DEBUG+1"},
28		{LevelDebug, "DEBUG"},
29		{LevelDebug - 2, "DEBUG-2"},
30	} {
31		got := test.in.String()
32		if got != test.want {
33			t.Errorf("%d: got %s, want %s", test.in, got, test.want)
34		}
35	}
36}
37
38func TestLevelVar(t *testing.T) {
39	var al LevelVar
40	if got, want := al.Level(), LevelInfo; got != want {
41		t.Errorf("got %v, want %v", got, want)
42	}
43	al.Set(LevelWarn)
44	if got, want := al.Level(), LevelWarn; got != want {
45		t.Errorf("got %v, want %v", got, want)
46	}
47	al.Set(LevelInfo)
48	if got, want := al.Level(), LevelInfo; got != want {
49		t.Errorf("got %v, want %v", got, want)
50	}
51
52}
53
54func TestLevelMarshalJSON(t *testing.T) {
55	want := LevelWarn - 3
56	wantData := []byte(`"INFO+1"`)
57	data, err := want.MarshalJSON()
58	if err != nil {
59		t.Fatal(err)
60	}
61	if !bytes.Equal(data, wantData) {
62		t.Errorf("got %s, want %s", string(data), string(wantData))
63	}
64	var got Level
65	if err := got.UnmarshalJSON(data); err != nil {
66		t.Fatal(err)
67	}
68	if got != want {
69		t.Errorf("got %s, want %s", got, want)
70	}
71}
72
73func TestLevelMarshalText(t *testing.T) {
74	want := LevelWarn - 3
75	wantData := []byte("INFO+1")
76	data, err := want.MarshalText()
77	if err != nil {
78		t.Fatal(err)
79	}
80	if !bytes.Equal(data, wantData) {
81		t.Errorf("got %s, want %s", string(data), string(wantData))
82	}
83	var got Level
84	if err := got.UnmarshalText(data); err != nil {
85		t.Fatal(err)
86	}
87	if got != want {
88		t.Errorf("got %s, want %s", got, want)
89	}
90}
91
92func TestLevelParse(t *testing.T) {
93	for _, test := range []struct {
94		in   string
95		want Level
96	}{
97		{"DEBUG", LevelDebug},
98		{"INFO", LevelInfo},
99		{"WARN", LevelWarn},
100		{"ERROR", LevelError},
101		{"debug", LevelDebug},
102		{"iNfo", LevelInfo},
103		{"INFO+87", LevelInfo + 87},
104		{"Error-18", LevelError - 18},
105		{"Error-8", LevelInfo},
106	} {
107		var got Level
108		if err := got.parse(test.in); err != nil {
109			t.Fatalf("%q: %v", test.in, err)
110		}
111		if got != test.want {
112			t.Errorf("%q: got %s, want %s", test.in, got, test.want)
113		}
114	}
115}
116
117func TestLevelParseError(t *testing.T) {
118	for _, test := range []struct {
119		in   string
120		want string // error string should contain this
121	}{
122		{"", "unknown name"},
123		{"dbg", "unknown name"},
124		{"INFO+", "invalid syntax"},
125		{"INFO-", "invalid syntax"},
126		{"ERROR+23x", "invalid syntax"},
127	} {
128		var l Level
129		err := l.parse(test.in)
130		if err == nil || !strings.Contains(err.Error(), test.want) {
131			t.Errorf("%q: got %v, want string containing %q", test.in, err, test.want)
132		}
133	}
134}
135
136func TestLevelFlag(t *testing.T) {
137	fs := flag.NewFlagSet("test", flag.ContinueOnError)
138	lf := LevelInfo
139	fs.TextVar(&lf, "level", lf, "set level")
140	err := fs.Parse([]string{"-level", "WARN+3"})
141	if err != nil {
142		t.Fatal(err)
143	}
144	if g, w := lf, LevelWarn+3; g != w {
145		t.Errorf("got %v, want %v", g, w)
146	}
147}
148
149func TestLevelVarMarshalText(t *testing.T) {
150	var v LevelVar
151	v.Set(LevelWarn)
152	data, err := v.MarshalText()
153	if err != nil {
154		t.Fatal(err)
155	}
156	var v2 LevelVar
157	if err := v2.UnmarshalText(data); err != nil {
158		t.Fatal(err)
159	}
160	if g, w := v2.Level(), LevelWarn; g != w {
161		t.Errorf("got %s, want %s", g, w)
162	}
163}
164
165func TestLevelVarFlag(t *testing.T) {
166	fs := flag.NewFlagSet("test", flag.ContinueOnError)
167	v := &LevelVar{}
168	v.Set(LevelWarn + 3)
169	fs.TextVar(v, "level", v, "set level")
170	err := fs.Parse([]string{"-level", "WARN+3"})
171	if err != nil {
172		t.Fatal(err)
173	}
174	if g, w := v.Level(), LevelWarn+3; g != w {
175		t.Errorf("got %v, want %v", g, w)
176	}
177}
178
179func TestLevelVarString(t *testing.T) {
180	var v LevelVar
181	v.Set(LevelError)
182	got := v.String()
183	want := "LevelVar(ERROR)"
184	if got != want {
185		t.Errorf("got %q, want %q", got, want)
186	}
187}
188