2020-02-29 12:12:16 -05:00
|
|
|
// Copyright 2015 Matthew Holt and The Caddy Authors
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
// you may not use this file except in compliance with the License.
|
|
|
|
// You may obtain a copy of the License at
|
|
|
|
//
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
//
|
|
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
// See the License for the specific language governing permissions and
|
|
|
|
// limitations under the License.
|
|
|
|
|
|
|
|
package caddyfile
|
|
|
|
|
|
|
|
import (
|
2020-03-25 19:45:54 -05:00
|
|
|
"strings"
|
2020-02-29 12:12:16 -05:00
|
|
|
"testing"
|
|
|
|
)
|
|
|
|
|
2020-03-25 19:45:54 -05:00
|
|
|
func TestFormatter(t *testing.T) {
|
|
|
|
for i, tc := range []struct {
|
|
|
|
description string
|
|
|
|
input string
|
|
|
|
expect string
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
description: "very simple",
|
|
|
|
input: `abc def
|
|
|
|
g hi jkl
|
|
|
|
mn`,
|
|
|
|
expect: `abc def
|
|
|
|
g hi jkl
|
|
|
|
mn`,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
description: "basic indentation, line breaks, and nesting",
|
|
|
|
input: ` a
|
2020-02-29 12:12:16 -05:00
|
|
|
b
|
|
|
|
|
|
|
|
c {
|
|
|
|
d
|
|
|
|
}
|
|
|
|
|
|
|
|
e { f
|
|
|
|
}
|
2020-02-29 15:23:08 -05:00
|
|
|
|
2020-03-25 19:45:54 -05:00
|
|
|
|
|
|
|
|
2020-02-29 15:23:08 -05:00
|
|
|
g {
|
|
|
|
h {
|
|
|
|
i
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
j { k {
|
|
|
|
l
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
m {
|
|
|
|
n { o
|
|
|
|
}
|
2020-03-25 19:45:54 -05:00
|
|
|
p { q r
|
|
|
|
s }
|
2020-02-29 15:23:08 -05:00
|
|
|
}
|
2020-03-17 10:55:36 -05:00
|
|
|
|
2020-03-25 19:45:54 -05:00
|
|
|
{
|
|
|
|
{ t
|
|
|
|
u
|
2020-03-17 10:55:36 -05:00
|
|
|
|
2020-03-25 19:45:54 -05:00
|
|
|
v
|
2020-03-17 10:55:36 -05:00
|
|
|
|
2020-03-25 19:45:54 -05:00
|
|
|
w
|
2020-03-17 10:55:36 -05:00
|
|
|
}
|
2020-03-25 19:45:54 -05:00
|
|
|
}`,
|
|
|
|
expect: `a
|
2020-02-29 12:12:16 -05:00
|
|
|
b
|
|
|
|
|
|
|
|
c {
|
|
|
|
d
|
|
|
|
}
|
|
|
|
|
|
|
|
e {
|
|
|
|
f
|
|
|
|
}
|
2020-02-29 15:23:08 -05:00
|
|
|
|
|
|
|
g {
|
|
|
|
h {
|
|
|
|
i
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
j {
|
|
|
|
k {
|
|
|
|
l
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
m {
|
|
|
|
n {
|
|
|
|
o
|
|
|
|
}
|
2020-03-25 19:45:54 -05:00
|
|
|
p {
|
|
|
|
q r
|
|
|
|
s
|
|
|
|
}
|
2020-02-29 15:23:08 -05:00
|
|
|
}
|
2020-03-17 10:55:36 -05:00
|
|
|
|
|
|
|
{
|
2020-03-25 19:45:54 -05:00
|
|
|
{
|
|
|
|
t
|
|
|
|
u
|
2020-03-17 10:55:36 -05:00
|
|
|
|
2020-03-25 19:45:54 -05:00
|
|
|
v
|
2020-03-17 10:55:36 -05:00
|
|
|
|
2020-03-25 19:45:54 -05:00
|
|
|
w
|
2020-03-17 10:55:36 -05:00
|
|
|
}
|
2020-03-25 19:45:54 -05:00
|
|
|
}`,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
description: "block spacing",
|
|
|
|
input: `a{
|
2020-02-29 12:12:16 -05:00
|
|
|
b
|
|
|
|
}
|
|
|
|
|
|
|
|
c{ d
|
2020-03-25 19:45:54 -05:00
|
|
|
}`,
|
|
|
|
expect: `a {
|
2020-02-29 12:12:16 -05:00
|
|
|
b
|
|
|
|
}
|
|
|
|
|
|
|
|
c {
|
|
|
|
d
|
2020-03-25 19:45:54 -05:00
|
|
|
}`,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
description: "advanced spacing",
|
|
|
|
input: `abc {
|
|
|
|
def
|
|
|
|
}ghi{
|
|
|
|
jkl mno
|
|
|
|
pqr}`,
|
|
|
|
expect: `abc {
|
|
|
|
def
|
|
|
|
}
|
|
|
|
|
|
|
|
ghi {
|
|
|
|
jkl mno
|
|
|
|
pqr
|
|
|
|
}`,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
description: "env var placeholders",
|
|
|
|
input: `{$A}
|
2020-02-29 12:12:16 -05:00
|
|
|
|
|
|
|
b {
|
|
|
|
{$C}
|
|
|
|
}
|
|
|
|
|
|
|
|
d { {$E}
|
|
|
|
}
|
2020-03-17 10:55:36 -05:00
|
|
|
|
|
|
|
{ {$F}
|
|
|
|
}
|
2020-03-25 19:45:54 -05:00
|
|
|
`,
|
|
|
|
expect: `{$A}
|
2020-02-29 12:12:16 -05:00
|
|
|
|
|
|
|
b {
|
|
|
|
{$C}
|
|
|
|
}
|
|
|
|
|
|
|
|
d {
|
|
|
|
{$E}
|
|
|
|
}
|
2020-03-17 10:55:36 -05:00
|
|
|
|
|
|
|
{
|
|
|
|
{$F}
|
2020-03-25 19:45:54 -05:00
|
|
|
}`,
|
|
|
|
},
|
2021-11-15 16:41:19 -05:00
|
|
|
{
|
|
|
|
description: "env var placeholders with port",
|
|
|
|
input: `:{$PORT}`,
|
|
|
|
expect: `:{$PORT}`,
|
|
|
|
},
|
2020-03-25 19:45:54 -05:00
|
|
|
{
|
|
|
|
description: "comments",
|
|
|
|
input: `#a "\n"
|
2020-02-29 12:12:16 -05:00
|
|
|
|
2020-03-25 19:45:54 -05:00
|
|
|
#b {
|
2020-02-29 12:12:16 -05:00
|
|
|
c
|
|
|
|
}
|
|
|
|
|
|
|
|
d {
|
2020-03-25 19:45:54 -05:00
|
|
|
e#f
|
2020-02-29 12:12:16 -05:00
|
|
|
# g
|
|
|
|
}
|
|
|
|
|
|
|
|
h { # i
|
2020-03-25 19:45:54 -05:00
|
|
|
}`,
|
|
|
|
expect: `#a "\n"
|
2020-02-29 12:12:16 -05:00
|
|
|
|
2020-03-25 19:45:54 -05:00
|
|
|
#b {
|
2020-02-29 12:12:16 -05:00
|
|
|
c
|
|
|
|
}
|
|
|
|
|
|
|
|
d {
|
2020-05-05 13:32:12 -05:00
|
|
|
e#f
|
2020-02-29 12:12:16 -05:00
|
|
|
# g
|
|
|
|
}
|
|
|
|
|
|
|
|
h {
|
|
|
|
# i
|
2020-03-25 19:45:54 -05:00
|
|
|
}`,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
description: "quotes and escaping",
|
|
|
|
input: `"a \"b\" "#c
|
2020-02-29 12:12:16 -05:00
|
|
|
d
|
|
|
|
|
|
|
|
e {
|
|
|
|
"f"
|
|
|
|
}
|
|
|
|
|
|
|
|
g { "h"
|
|
|
|
}
|
2020-03-25 19:45:54 -05:00
|
|
|
|
|
|
|
i {
|
|
|
|
"foo
|
|
|
|
bar"
|
|
|
|
}
|
|
|
|
|
|
|
|
j {
|
|
|
|
"\"k\" l m"
|
|
|
|
}`,
|
2020-05-05 13:32:12 -05:00
|
|
|
expect: `"a \"b\" "#c
|
2020-02-29 12:12:16 -05:00
|
|
|
d
|
|
|
|
|
|
|
|
e {
|
|
|
|
"f"
|
|
|
|
}
|
|
|
|
|
|
|
|
g {
|
|
|
|
"h"
|
|
|
|
}
|
2020-03-25 19:45:54 -05:00
|
|
|
|
|
|
|
i {
|
|
|
|
"foo
|
|
|
|
bar"
|
2020-02-29 12:12:16 -05:00
|
|
|
}
|
|
|
|
|
2020-03-25 19:45:54 -05:00
|
|
|
j {
|
|
|
|
"\"k\" l m"
|
|
|
|
}`,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
description: "bad nesting (too many open)",
|
|
|
|
input: `a
|
|
|
|
{
|
|
|
|
{
|
|
|
|
}`,
|
|
|
|
expect: `a {
|
|
|
|
{
|
|
|
|
}
|
|
|
|
`,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
description: "bad nesting (too many close)",
|
|
|
|
input: `a
|
|
|
|
{
|
|
|
|
{
|
|
|
|
}}}`,
|
|
|
|
expect: `a {
|
|
|
|
{
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
`,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
description: "json",
|
|
|
|
input: `foo
|
|
|
|
bar "{\"key\":34}"
|
|
|
|
`,
|
|
|
|
expect: `foo
|
|
|
|
bar "{\"key\":34}"`,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
description: "escaping after spaces",
|
|
|
|
input: `foo \"literal\"`,
|
|
|
|
expect: `foo \"literal\"`,
|
|
|
|
},
|
|
|
|
{
|
2020-03-29 14:53:00 -05:00
|
|
|
description: "simple placeholders as standalone tokens",
|
2020-03-25 19:45:54 -05:00
|
|
|
input: `foo {bar}`,
|
|
|
|
expect: `foo {bar}`,
|
|
|
|
},
|
2020-03-29 14:53:00 -05:00
|
|
|
{
|
|
|
|
description: "simple placeholders within tokens",
|
|
|
|
input: `foo{bar} foo{bar}baz`,
|
|
|
|
expect: `foo{bar} foo{bar}baz`,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
description: "placeholders and malformed braces",
|
|
|
|
input: `foo{bar} foo{ bar}baz`,
|
|
|
|
expect: `foo{bar} foo {
|
|
|
|
bar
|
|
|
|
}
|
|
|
|
|
|
|
|
baz`,
|
|
|
|
},
|
2020-05-05 13:32:12 -05:00
|
|
|
{
|
|
|
|
description: "hash within string is not a comment",
|
|
|
|
input: `redir / /some/#/path`,
|
|
|
|
expect: `redir / /some/#/path`,
|
|
|
|
},
|
2020-12-16 17:22:16 -05:00
|
|
|
{
|
|
|
|
description: "brace does not fold into comment above",
|
|
|
|
input: `# comment
|
|
|
|
{
|
|
|
|
foo
|
|
|
|
}`,
|
|
|
|
expect: `# comment
|
|
|
|
{
|
|
|
|
foo
|
|
|
|
}`,
|
|
|
|
},
|
2021-05-10 13:01:27 -05:00
|
|
|
{
|
|
|
|
description: "matthewpi/vscode-caddyfile-support#13",
|
|
|
|
input: `{
|
|
|
|
email {$ACMEEMAIL}
|
|
|
|
#debug
|
|
|
|
}
|
|
|
|
|
|
|
|
block {
|
|
|
|
}
|
|
|
|
`,
|
|
|
|
expect: `{
|
|
|
|
email {$ACMEEMAIL}
|
|
|
|
#debug
|
|
|
|
}
|
|
|
|
|
|
|
|
block {
|
|
|
|
}
|
|
|
|
`,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
description: "matthewpi/vscode-caddyfile-support#13 - bad formatting",
|
|
|
|
input: `{
|
|
|
|
email {$ACMEEMAIL}
|
|
|
|
#debug
|
|
|
|
}
|
|
|
|
|
|
|
|
block {
|
|
|
|
}
|
|
|
|
`,
|
|
|
|
expect: `{
|
|
|
|
email {$ACMEEMAIL}
|
|
|
|
#debug
|
|
|
|
}
|
|
|
|
|
|
|
|
block {
|
|
|
|
}
|
2024-01-21 21:24:49 -05:00
|
|
|
`,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
description: "keep heredoc as-is",
|
|
|
|
input: `block {
|
|
|
|
heredoc <<HEREDOC
|
|
|
|
Here's more than one space Here's more than one space
|
|
|
|
HEREDOC
|
|
|
|
}
|
|
|
|
`,
|
|
|
|
expect: `block {
|
|
|
|
heredoc <<HEREDOC
|
|
|
|
Here's more than one space Here's more than one space
|
|
|
|
HEREDOC
|
|
|
|
}
|
|
|
|
`,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
description: "Mixing heredoc with regular part",
|
|
|
|
input: `block {
|
|
|
|
heredoc <<HEREDOC
|
|
|
|
Here's more than one space Here's more than one space
|
|
|
|
HEREDOC
|
|
|
|
respond "More than one space will be eaten" 200
|
|
|
|
}
|
|
|
|
|
|
|
|
block2 {
|
|
|
|
heredoc <<HEREDOC
|
|
|
|
Here's more than one space Here's more than one space
|
|
|
|
HEREDOC
|
|
|
|
respond "More than one space will be eaten" 200
|
|
|
|
}
|
|
|
|
`,
|
|
|
|
expect: `block {
|
|
|
|
heredoc <<HEREDOC
|
|
|
|
Here's more than one space Here's more than one space
|
|
|
|
HEREDOC
|
|
|
|
respond "More than one space will be eaten" 200
|
|
|
|
}
|
|
|
|
|
|
|
|
block2 {
|
|
|
|
heredoc <<HEREDOC
|
|
|
|
Here's more than one space Here's more than one space
|
|
|
|
HEREDOC
|
|
|
|
respond "More than one space will be eaten" 200
|
|
|
|
}
|
|
|
|
`,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
description: "Heredoc as regular token",
|
|
|
|
input: `block {
|
|
|
|
heredoc <<HEREDOC "More than one space will be eaten"
|
|
|
|
}
|
|
|
|
`,
|
|
|
|
expect: `block {
|
|
|
|
heredoc <<HEREDOC "More than one space will be eaten"
|
|
|
|
}
|
|
|
|
`,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
description: "Escape heredoc",
|
|
|
|
input: `block {
|
|
|
|
heredoc \<<HEREDOC
|
|
|
|
respond "More than one space will be eaten" 200
|
|
|
|
}
|
|
|
|
`,
|
|
|
|
expect: `block {
|
|
|
|
heredoc \<<HEREDOC
|
|
|
|
respond "More than one space will be eaten" 200
|
|
|
|
}
|
2021-05-10 13:01:27 -05:00
|
|
|
`,
|
|
|
|
},
|
2020-03-25 19:45:54 -05:00
|
|
|
} {
|
2024-02-12 13:06:22 -05:00
|
|
|
// the formatter should output a trailing newline,
|
|
|
|
// even if the tests aren't written to expect that
|
|
|
|
if !strings.HasSuffix(tc.expect, "\n") {
|
|
|
|
tc.expect += "\n"
|
|
|
|
}
|
|
|
|
|
|
|
|
actual := Format([]byte(tc.input))
|
|
|
|
|
|
|
|
if string(actual) != tc.expect {
|
|
|
|
t.Errorf("\n[TEST %d: %s]\n====== EXPECTED ======\n%s\n====== ACTUAL ======\n%s^^^^^^^^^^^^^^^^^^^^^",
|
|
|
|
i, tc.description, string(tc.expect), string(actual))
|
|
|
|
}
|
2020-02-29 12:12:16 -05:00
|
|
|
}
|
|
|
|
}
|