1// Copyright 2015 The Prometheus Authors
2// Licensed under the Apache License, Version 2.0 (the "License");
3// you may not use this file except in compliance with the License.
4// You may obtain a copy of the License at
5//
6// http://www.apache.org/licenses/LICENSE-2.0
7//
8// Unless required by applicable law or agreed to in writing, software
9// distributed under the License is distributed on an "AS IS" BASIS,
10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11// See the License for the specific language governing permissions and
12// limitations under the License.
13
14package parser
15
16import (
17	"testing"
18
19	"github.com/stretchr/testify/require"
20)
21
22func TestExprString(t *testing.T) {
23	// A list of valid expressions that are expected to be
24	// returned as out when calling String(). If out is empty the output
25	// is expected to equal the input.
26	inputs := []struct {
27		in, out string
28	}{
29		{
30			in:  `sum by() (task:errors:rate10s{job="s"})`,
31			out: `sum(task:errors:rate10s{job="s"})`,
32		},
33		{
34			in: `sum by(code) (task:errors:rate10s{job="s"})`,
35		},
36		{
37			in: `sum without() (task:errors:rate10s{job="s"})`,
38		},
39		{
40			in: `sum without(instance) (task:errors:rate10s{job="s"})`,
41		},
42		{
43			in: `topk(5, task:errors:rate10s{job="s"})`,
44		},
45		{
46			in: `count_values("value", task:errors:rate10s{job="s"})`,
47		},
48		{
49			in: `a - on() c`,
50		},
51		{
52			in: `a - on(b) c`,
53		},
54		{
55			in: `a - on(b) group_left(x) c`,
56		},
57		{
58			in: `a - on(b) group_left(x, y) c`,
59		},
60		{
61			in:  `a - on(b) group_left c`,
62			out: `a - on(b) group_left() c`,
63		},
64		{
65			in: `a - on(b) group_left() (c)`,
66		},
67		{
68			in: `a - ignoring(b) c`,
69		},
70		{
71			in:  `a - ignoring() c`,
72			out: `a - c`,
73		},
74		{
75			in: `up > bool 0`,
76		},
77		{
78			in: `a offset 1m`,
79		},
80		{
81			in: `a offset -7m`,
82		},
83		{
84			in: `a{c="d"}[5m] offset 1m`,
85		},
86		{
87			in: `a[5m] offset 1m`,
88		},
89		{
90			in: `a[12m] offset -3m`,
91		},
92		{
93			in: `a[1h:5m] offset 1m`,
94		},
95		{
96			in: `{__name__="a"}`,
97		},
98		{
99			in: `a{b!="c"}[1m]`,
100		},
101		{
102			in: `a{b=~"c"}[1m]`,
103		},
104		{
105			in: `a{b!~"c"}[1m]`,
106		},
107		{
108			in:  `a @ 10`,
109			out: `a @ 10.000`,
110		},
111		{
112			in:  `a[1m] @ 10`,
113			out: `a[1m] @ 10.000`,
114		},
115		{
116			in: `a @ start()`,
117		},
118		{
119			in: `a @ end()`,
120		},
121		{
122			in: `a[1m] @ start()`,
123		},
124		{
125			in: `a[1m] @ end()`,
126		},
127	}
128
129	for _, test := range inputs {
130		expr, err := ParseExpr(test.in)
131		require.NoError(t, err)
132
133		exp := test.in
134		if test.out != "" {
135			exp = test.out
136		}
137
138		require.Equal(t, exp, expr.String())
139	}
140}
141