Skip to content

Commit

Permalink
Merge pull request nats-io#653 from wallyqs/conf-json-compat
Browse files Browse the repository at this point in the history
Proposal: Improve compatibility with JSON in configuration
  • Loading branch information
derekcollison authored Mar 21, 2018
2 parents b2a9ed9 + c45d2f5 commit 5573037
Show file tree
Hide file tree
Showing 2 changed files with 155 additions and 1 deletion.
7 changes: 6 additions & 1 deletion conf/lex.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,9 @@ const (
sqStringStart = '\''
sqStringEnd = '\''
optValTerm = ';'
topOptStart = '{'
topOptValTerm = ','
topOptTerm = '}'
blockStart = '('
blockEnd = ')'
)
Expand Down Expand Up @@ -234,6 +237,8 @@ func lexTop(lx *lexer) stateFn {
}

switch r {
case topOptStart:
return lexSkip(lx, lexTop)
case commentHashStart:
lx.push(lexTop)
return lexCommentStart
Expand Down Expand Up @@ -280,7 +285,7 @@ func lexTopValueEnd(lx *lexer) stateFn {
fallthrough
case isWhitespace(r):
return lexTopValueEnd
case isNL(r) || r == eof || r == optValTerm:
case isNL(r) || r == eof || r == optValTerm || r == topOptValTerm || r == topOptTerm:
lx.ignore()
return lexTop
}
Expand Down
149 changes: 149 additions & 0 deletions conf/lex_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1049,3 +1049,152 @@ func TestMapInclude(t *testing.T) {
lx = lex("foo { include \"users.conf\"}")
expect(t, lx, expectedItems)
}

func TestJSONCompat(t *testing.T) {
for _, test := range []struct {
name string
input string
expected []item
}{
{
name: "should omit initial and final brackets at top level with a single item",
input: `
{
"http_port": 8223
}
`,
expected: []item{
{itemKey, "http_port", 3},
{itemInteger, "8223", 3},
},
},
{
name: "should omit trailing commas at top level with two items",
input: `
{
"http_port": 8223,
"port": 4223
}
`,
expected: []item{
{itemKey, "http_port", 3},
{itemInteger, "8223", 3},
{itemKey, "port", 4},
{itemInteger, "4223", 4},
},
},
{
name: "should omit trailing commas at top level with multiple items",
input: `
{
"http_port": 8223,
"port": 4223,
"max_payload": "5MB",
"debug": true,
"max_control_line": 1024
}
`,
expected: []item{
{itemKey, "http_port", 3},
{itemInteger, "8223", 3},
{itemKey, "port", 4},
{itemInteger, "4223", 4},
{itemKey, "max_payload", 5},
{itemString, "5MB", 5},
{itemKey, "debug", 6},
{itemBool, "true", 6},
{itemKey, "max_control_line", 7},
{itemInteger, "1024", 7},
},
},
{
name: "should support JSON not prettified",
input: `{"http_port": 8224,"port": 4224}
`,
expected: []item{
{itemKey, "http_port", 1},
{itemInteger, "8224", 1},
{itemKey, "port", 1},
{itemInteger, "4224", 1},
},
},
{
name: "should support JSON not prettified with final bracket after newline",
input: `{"http_port": 8225,"port": 4225
}
`,
expected: []item{
{itemKey, "http_port", 1},
{itemInteger, "8225", 1},
{itemKey, "port", 1},
{itemInteger, "4225", 1},
},
},
{
name: "should support uglified JSON with inner blocks",
input: `{"http_port": 8227,"port": 4227,"write_deadline": "1h","cluster": {"port": 6222,"routes": ["nats://127.0.0.1:4222","nats://127.0.0.1:4223","nats://127.0.0.1:4224"]}}
`,
expected: []item{
{itemKey, "http_port", 1},
{itemInteger, "8227", 1},
{itemKey, "port", 1},
{itemInteger, "4227", 1},
{itemKey, "write_deadline", 1},
{itemString, "1h", 1},
{itemKey, "cluster", 1},
{itemMapStart, "", 1},
{itemKey, "port", 1},
{itemInteger, "6222", 1},
{itemKey, "routes", 1},
{itemArrayStart, "", 1},
{itemString, "nats://127.0.0.1:4222", 1},
{itemString, "nats://127.0.0.1:4223", 1},
{itemString, "nats://127.0.0.1:4224", 1},
{itemArrayEnd, "", 1},
{itemMapEnd, "", 1},
},
},
{
name: "should support prettified JSON with inner blocks",
input: `
{
"http_port": 8227,
"port": 4227,
"write_deadline": "1h",
"cluster": {
"port": 6222,
"routes": [
"nats://127.0.0.1:4222",
"nats://127.0.0.1:4223",
"nats://127.0.0.1:4224"
]
}
}
`,
expected: []item{
{itemKey, "http_port", 3},
{itemInteger, "8227", 3},
{itemKey, "port", 4},
{itemInteger, "4227", 4},
{itemKey, "write_deadline", 5},
{itemString, "1h", 5},
{itemKey, "cluster", 6},
{itemMapStart, "", 6},
{itemKey, "port", 7},
{itemInteger, "6222", 7},
{itemKey, "routes", 8},
{itemArrayStart, "", 8},
{itemString, "nats://127.0.0.1:4222", 9},
{itemString, "nats://127.0.0.1:4223", 10},
{itemString, "nats://127.0.0.1:4224", 11},
{itemArrayEnd, "", 12},
{itemMapEnd, "", 13},
},
},
} {
t.Run(test.name, func(t *testing.T) {
lx := lex(test.input)
expect(t, lx, test.expected)
})
}
}

0 comments on commit 5573037

Please sign in to comment.