1// Copyright 2014 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 parser
16
17import (
18	"bytes"
19	"testing"
20)
21
22var validPrinterTestCases = []struct {
23	input  string
24	output string
25}{
26	{
27		input: `
28foo {}
29`,
30		output: `
31foo {}
32`,
33	},
34	{
35		input: `
36foo(name= "abc",num= 4,)
37`,
38		output: `
39foo {
40    name: "abc",
41    num: 4,
42}
43`,
44	},
45	{
46		input: `
47			foo {
48				stuff: ["asdf", "jkl;", "qwert",
49					"uiop", "bnm,"]
50			}
51			`,
52		output: `
53foo {
54    stuff: [
55        "asdf",
56        "bnm,",
57        "jkl;",
58        "qwert",
59        "uiop",
60    ],
61}
62`,
63	},
64	{
65		input: `
66		        var = "asdf"
67			foo {
68				stuff: ["asdf"] + var,
69			}`,
70		output: `
71var = "asdf"
72foo {
73    stuff: ["asdf"] + var,
74}
75`,
76	},
77	{
78		input: `
79		        var = "asdf"
80			foo {
81				stuff: [
82				    "asdf"
83				] + var,
84			}`,
85		output: `
86var = "asdf"
87foo {
88    stuff: [
89        "asdf",
90    ] + var,
91}
92`,
93	},
94	{
95		input: `
96		        var = "asdf"
97			foo {
98				stuff: ["asdf"] + var + ["qwert"],
99			}`,
100		output: `
101var = "asdf"
102foo {
103    stuff: ["asdf"] + var + ["qwert"],
104}
105`,
106	},
107	{
108		input: `
109		foo {
110			stuff: {
111				isGood: true,
112				name: "bar",
113				num: 4,
114			}
115		}
116		`,
117		output: `
118foo {
119    stuff: {
120        isGood: true,
121        name: "bar",
122        num: 4,
123    },
124}
125`,
126	},
127	{
128		input: `
129// comment1
130foo {
131	// comment2
132	isGood: true,  // comment3
133}
134`,
135		output: `
136// comment1
137foo {
138    // comment2
139    isGood: true, // comment3
140}
141`,
142	},
143	{
144		input: `
145foo {
146	name: "abc",
147	num: 4,
148}
149
150bar  {
151	name: "def",
152	num: 5,
153}
154		`,
155		output: `
156foo {
157    name: "abc",
158    num: 4,
159}
160
161bar {
162    name: "def",
163    num: 5,
164}
165`,
166	},
167	{
168		input: `
169foo {
170    bar: "b" +
171        "a" +
172	"z",
173}
174`,
175		output: `
176foo {
177    bar: "b" +
178        "a" +
179        "z",
180}
181`,
182	},
183	{
184		input: `
185foo = "stuff"
186bar = foo
187baz = foo + bar
188baz += foo
189`,
190		output: `
191foo = "stuff"
192bar = foo
193baz = foo + bar
194baz += foo
195`,
196	},
197	{
198		input: `
199foo = 100
200bar = foo
201baz = foo + bar
202baz += foo
203`,
204		output: `
205foo = 100
206bar = foo
207baz = foo + bar
208baz += foo
209`,
210	},
211	{
212		input: `
213foo = "bar " +
214    "" +
215    "baz"
216`,
217		output: `
218foo = "bar " +
219    "" +
220    "baz"
221`,
222	},
223	{
224		input: `
225//test
226test /* test */ {
227    srcs: [
228        /*"bootstrap/bootstrap.go",
229    "bootstrap/cleanup.go",*/
230        "bootstrap/command.go",
231        "bootstrap/doc.go", //doc.go
232        "bootstrap/config.go", //config.go
233    ],
234    deps: ["libabc"],
235    incs: []
236} //test
237//test
238test2 {
239}
240
241
242//test3
243`,
244		output: `
245//test
246test /* test */ {
247    srcs: [
248        /*"bootstrap/bootstrap.go",
249        "bootstrap/cleanup.go",*/
250        "bootstrap/command.go",
251        "bootstrap/config.go", //config.go
252        "bootstrap/doc.go", //doc.go
253    ],
254    deps: ["libabc"],
255    incs: [],
256} //test
257//test
258
259test2 {
260}
261
262//test3
263`,
264	},
265	{
266		input: `
267// test
268module // test
269
270 {
271    srcs
272   : [
273        "src1.c",
274        "src2.c",
275    ],
276//test
277}
278//test2
279`,
280		output: `
281// test
282module { // test
283
284    srcs: [
285        "src1.c",
286        "src2.c",
287    ],
288    //test
289}
290
291//test2
292`,
293	},
294	{
295		input: `
296/*test {
297    test: true,
298}*/
299
300test {
301/*test: true,*/
302}
303
304// This
305/* Is *//* A */ // A
306// A
307
308// Multiline
309// Comment
310
311test {}
312
313// This
314/* Is */
315// A
316// Trailing
317
318// Multiline
319// Comment
320`,
321		output: `
322/*test {
323    test: true,
324}*/
325
326test {
327    /*test: true,*/
328}
329
330// This
331/* Is */ /* A */ // A
332// A
333
334// Multiline
335// Comment
336
337test {}
338
339// This
340/* Is */
341// A
342// Trailing
343
344// Multiline
345// Comment
346`,
347	},
348	{
349		input: `
350test // test
351
352// test
353{
354}
355`,
356		output: `
357test { // test
358
359// test
360
361}
362`,
363	},
364	{
365		input: `
366// test
367stuff {
368    namespace: "google",
369    string_vars: [
370      {
371          var: "one",
372          values: [ "one_a", "one_b",],
373      },
374      {
375          var: "two",
376          values: [ "two_a", "two_b", ],
377      },
378    ],
379}`,
380		output: `
381// test
382stuff {
383    namespace: "google",
384    string_vars: [
385        {
386            var: "one",
387            values: [
388                "one_a",
389                "one_b",
390            ],
391        },
392        {
393            var: "two",
394            values: [
395                "two_a",
396                "two_b",
397            ],
398        },
399    ],
400}
401`,
402	},
403	{
404		input: `
405// test
406stuff {
407    namespace: "google",
408    list_of_lists: [
409        [ "a", "b" ],
410        [ "c", "d" ],
411    ],
412}
413`,
414		output: `
415// test
416stuff {
417    namespace: "google",
418    list_of_lists: [
419        [
420            "a",
421            "b",
422        ],
423        [
424            "c",
425            "d",
426        ],
427    ],
428}
429`,
430	},
431}
432
433func TestPrinter(t *testing.T) {
434	for _, testCase := range validPrinterTestCases {
435		in := testCase.input[1:]
436		expected := testCase.output[1:]
437
438		r := bytes.NewBufferString(in)
439		file, errs := Parse("", r, NewScope(nil))
440		if len(errs) != 0 {
441			t.Errorf("test case: %s", in)
442			t.Errorf("unexpected errors:")
443			for _, err := range errs {
444				t.Errorf("  %s", err)
445			}
446			t.FailNow()
447		}
448
449		SortLists(file)
450
451		got, err := Print(file)
452		if err != nil {
453			t.Errorf("test case: %s", in)
454			t.Errorf("unexpected error: %s", err)
455			t.FailNow()
456		}
457
458		if string(got) != expected {
459			t.Errorf("test case: %s", in)
460			t.Errorf("  expected: %s", expected)
461			t.Errorf("       got: %s", string(got))
462		}
463	}
464}
465