1package stdlib
2
3import (
4	"fmt"
5	"testing"
6
7	"github.com/zclconf/go-cty/cty"
8)
9
10func TestRegex(t *testing.T) {
11	tests := []struct {
12		Pattern cty.Value
13		String  cty.Value
14		Want    cty.Value
15	}{
16		{
17			cty.StringVal("[a-z]+"),
18			cty.StringVal("135abc456def789"),
19			cty.StringVal("abc"),
20		},
21		{
22			cty.StringVal("([0-9]*)([a-z]*)"),
23			cty.StringVal("135abc456def"),
24			cty.TupleVal([]cty.Value{
25				cty.StringVal("135"),
26				cty.StringVal("abc"),
27			}),
28		},
29		{
30			cty.StringVal(`^(?:(?P<scheme>[^:/?#]+):)?(?://(?P<authority>[^/?#]*))?(?P<path>[^?#]*)(?:\?(?P<query>[^#]*))?(?:#(?P<fragment>.*))?`),
31			cty.StringVal("http://www.ics.uci.edu/pub/ietf/uri/#Related"),
32			cty.ObjectVal(map[string]cty.Value{
33				"scheme":    cty.StringVal("http"),
34				"authority": cty.StringVal("www.ics.uci.edu"),
35				"path":      cty.StringVal("/pub/ietf/uri/"),
36				"query":     cty.NullVal(cty.String), // query portion isn't present at all, because there's no ?
37				"fragment":  cty.StringVal("Related"),
38			}),
39		},
40		{
41			cty.StringVal("([0-9]*)([a-z]*)"),
42			cty.UnknownVal(cty.String),
43			cty.UnknownVal(cty.Tuple([]cty.Type{
44				cty.String,
45				cty.String,
46			})),
47		},
48		{
49			cty.StringVal("(?P<num>[0-9]*)"),
50			cty.UnknownVal(cty.String),
51			cty.UnknownVal(cty.Object(map[string]cty.Type{
52				"num": cty.String,
53			})),
54		},
55		{
56			cty.UnknownVal(cty.String),
57			cty.StringVal("135abc456def"),
58			cty.DynamicVal,
59		},
60		{
61			cty.StringVal("[a-z]+").Mark(1),
62			cty.StringVal("135abc456def789"),
63			cty.StringVal("abc").Mark(1),
64		},
65		{
66			cty.StringVal("[a-z]+"),
67			cty.StringVal("135abc456def789").Mark(2),
68			cty.StringVal("abc").Mark(2),
69		},
70	}
71
72	for _, test := range tests {
73		t.Run(fmt.Sprintf("Regex(%#v, %#v)", test.Pattern, test.String), func(t *testing.T) {
74			got, err := Regex(test.Pattern, test.String)
75
76			if err != nil {
77				t.Fatalf("unexpected error: %s", err)
78			}
79
80			if !got.RawEquals(test.Want) {
81				t.Errorf(
82					"wrong result\npattern: %#v\nstring:  %#v\ngot:     %#v\nwant:    %#v",
83					test.Pattern, test.String, got, test.Want,
84				)
85			}
86		})
87	}
88}
89
90func TestRegexAll(t *testing.T) {
91	tests := []struct {
92		Pattern cty.Value
93		String  cty.Value
94		Want    cty.Value
95	}{
96		{
97			cty.StringVal("[a-z]+"),
98			cty.StringVal("135abc456def789"),
99			cty.ListVal([]cty.Value{
100				cty.StringVal("abc"),
101				cty.StringVal("def"),
102			}),
103		},
104		{
105			cty.StringVal("([0-9]*)([a-z]*)"),
106			cty.StringVal("135abc456def"),
107			cty.ListVal([]cty.Value{
108				cty.TupleVal([]cty.Value{
109					cty.StringVal("135"),
110					cty.StringVal("abc"),
111				}),
112				cty.TupleVal([]cty.Value{
113					cty.StringVal("456"),
114					cty.StringVal("def"),
115				}),
116			}),
117		},
118		{
119			cty.StringVal(`^(?:(?P<scheme>[^:/?#]+):)?(?://(?P<authority>[^/?#]*))?(?P<path>[^?#]*)(?:\?(?P<query>[^#]*))?(?:#(?P<fragment>.*))?`),
120			cty.StringVal("http://www.ics.uci.edu/pub/ietf/uri/#Related"),
121			cty.ListVal([]cty.Value{
122				cty.ObjectVal(map[string]cty.Value{
123					"scheme":    cty.StringVal("http"),
124					"authority": cty.StringVal("www.ics.uci.edu"),
125					"path":      cty.StringVal("/pub/ietf/uri/"),
126					"query":     cty.NullVal(cty.String), // query portion isn't present at all, because there's no ?
127					"fragment":  cty.StringVal("Related"),
128				}),
129			}),
130		},
131		{
132			cty.StringVal("([0-9]*)([a-z]*)"),
133			cty.UnknownVal(cty.String),
134			cty.UnknownVal(cty.List(cty.Tuple([]cty.Type{
135				cty.String,
136				cty.String,
137			}))),
138		},
139		{
140			cty.StringVal("(?P<num>[0-9]*)"),
141			cty.UnknownVal(cty.String),
142			cty.UnknownVal(cty.List(cty.Object(map[string]cty.Type{
143				"num": cty.String,
144			}))),
145		},
146		{
147			cty.UnknownVal(cty.String),
148			cty.StringVal("135abc456def"),
149			cty.UnknownVal(cty.List(cty.DynamicPseudoType)),
150		},
151	}
152
153	for _, test := range tests {
154		t.Run(fmt.Sprintf("RegexAll(%#v, %#v)", test.Pattern, test.String), func(t *testing.T) {
155			got, err := RegexAll(test.Pattern, test.String)
156
157			if err != nil {
158				t.Fatalf("unexpected error: %s", err)
159			}
160
161			if !got.RawEquals(test.Want) {
162				t.Errorf(
163					"wrong result\npattern: %#v\nstring:  %#v\ngot:     %#v\nwant:    %#v",
164					test.Pattern, test.String, got, test.Want,
165				)
166			}
167		})
168	}
169}
170