1// Copyright 2016 Google Inc. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package android
16
17import (
18	"fmt"
19	"testing"
20)
21
22var vars = map[string]string{
23	"var1":   "abc",
24	"var2":   "",
25	"var3":   "def",
26	"��":      "��",
27	"escape": "${in}",
28}
29
30func expander(s string) (string, bool, error) {
31	if val, ok := vars[s]; ok {
32		return val, s == "escape", nil
33	} else {
34		return "", false, fmt.Errorf("unknown variable %q", s)
35	}
36}
37
38var expandTestCases = []struct {
39	in          string
40	out         string
41	out_escaped string
42	err         bool
43}{
44	{
45		in:          "$(var1)",
46		out:         "abc",
47		out_escaped: "abc",
48	},
49	{
50		in:          "$( var1 )",
51		out:         "abc",
52		out_escaped: "abc",
53	},
54	{
55		in:          "def$(var1)",
56		out:         "defabc",
57		out_escaped: "defabc",
58	},
59	{
60		in:          "$(var1)def",
61		out:         "abcdef",
62		out_escaped: "abcdef",
63	},
64	{
65		in:          "def$(var1)def",
66		out:         "defabcdef",
67		out_escaped: "defabcdef",
68	},
69	{
70		in:          "$(var2)",
71		out:         "",
72		out_escaped: "",
73	},
74	{
75		in:          "def$(var2)",
76		out:         "def",
77		out_escaped: "def",
78	},
79	{
80		in:          "$(var2)def",
81		out:         "def",
82		out_escaped: "def",
83	},
84	{
85		in:          "def$(var2)def",
86		out:         "defdef",
87		out_escaped: "defdef",
88	},
89	{
90		in:          "$(var1)$(var3)",
91		out:         "abcdef",
92		out_escaped: "abcdef",
93	},
94	{
95		in:          "$(var1)g$(var3)",
96		out:         "abcgdef",
97		out_escaped: "abcgdef",
98	},
99	{
100		in:          "$$",
101		out:         "$",
102		out_escaped: "$$",
103	},
104	{
105		in:          "$$(var1)",
106		out:         "$(var1)",
107		out_escaped: "$$(var1)",
108	},
109	{
110		in:          "$$$(var1)",
111		out:         "$abc",
112		out_escaped: "$$abc",
113	},
114	{
115		in:          "$(var1)$$",
116		out:         "abc$",
117		out_escaped: "abc$$",
118	},
119	{
120		in:          "$(��)",
121		out:         "��",
122		out_escaped: "��",
123	},
124	{
125		in:          "$$a$(escape)$$b",
126		out:         "$a${in}$b",
127		out_escaped: "$$a${in}$$b",
128	},
129
130	// Errors
131	{
132		in:  "$",
133		err: true,
134	},
135	{
136		in:  "$$$",
137		err: true,
138	},
139	{
140		in:  "$(var1)$",
141		err: true,
142	},
143	{
144		in:  "$(var1)$",
145		err: true,
146	},
147	{
148		in:  "$(var4)",
149		err: true,
150	},
151	{
152		in:  "$var1",
153		err: true,
154	},
155	{
156		in:  "$(var1",
157		err: true,
158	},
159	{
160		in:  "$a��c",
161		err: true,
162	},
163}
164
165func TestExpand(t *testing.T) {
166	for _, test := range expandTestCases {
167		got, err := Expand(test.in, func(s string) (string, error) {
168			s, _, err := expander(s)
169			return s, err
170		})
171		if err != nil && !test.err {
172			t.Errorf("%q: unexpected error %s", test.in, err.Error())
173		} else if err == nil && test.err {
174			t.Errorf("%q: expected error, got %q", test.in, got)
175		} else if !test.err && got != test.out {
176			t.Errorf("%q: expected %q, got %q", test.in, test.out, got)
177		}
178	}
179}
180
181func TestExpandNinjaEscaped(t *testing.T) {
182	for _, test := range expandTestCases {
183		got, err := ExpandNinjaEscaped(test.in, expander)
184		if err != nil && !test.err {
185			t.Errorf("%q: unexpected error %s", test.in, err.Error())
186		} else if err == nil && test.err {
187			t.Errorf("%q: expected error, got %q", test.in, got)
188		} else if !test.err && got != test.out_escaped {
189			t.Errorf("%q: expected %q, got %q", test.in, test.out, got)
190		}
191	}
192}
193