test "10.0foo" path expression, and correct the spec

The spec described parsing this as a 1-element path but
the implementation parsed it as 2 elements which is probably
a better behavior because it's less surprising. The simple
rule is now "only quoted periods are special".
This commit is contained in:
Havoc Pennington 2011-11-16 23:23:46 -05:00
parent 9dc6f77078
commit 0bb9d19727
2 changed files with 18 additions and 4 deletions

View File

@ -290,13 +290,20 @@ substitutions. This means that you can't nest substitutions inside
other substitutions, and you can't have substitutions in keys.
When concatenating the path expression, any `.` characters outside
quoted strings or numbers are understood as path separators, while
inside quoted strings and numbers `.` has no special meaning. So
quoted strings are understood as path separators, while inside
quoted strings `.` has no special meaning. So
`foo.bar."hello.world"` would be a path with three elements,
looking up key `foo`, key `bar`, then key `hello.world`.
- `10.0foo` is a number then unquoted string `foo` so this would
be a single-element path.
The main tricky point is that `.` characters in numbers do count
as a path separator. When dealing with a number as part of a path
expression, it's essential to retain the _original_ string
representation of the number as it appeared in the file (rather
than converting it back to a string with a generic
number-to-string library function).
- `10.0foo` is a number then unquoted string `foo` and should
be the two-element path with `10` and `0foo` as the elements.
- `foo10.0` is an unquoted string with a `.` in it, so this would
be a two-element path with `foo10` and `0` as the elements.
- `foo"10.0"` is an unquoted then a quoted string which are

View File

@ -126,6 +126,13 @@ class ConfParserTest extends TestUtils {
assertEquals(path("a_c"), parsePath("a_c"))
assertEquals(path("-"), parsePath("\"-\""))
// here 10.0 is part of an unquoted string
assertEquals(path("foo10", "0"), parsePath("foo10.0"))
// here 10.0 is a number that gets value-concatenated
assertEquals(path("10", "0foo"), parsePath("10.0foo"))
// just a number
assertEquals(path("10", "0"), parsePath("10.0"))
for (invalid <- Seq("", " ", " \n \n ", "a.", ".b", "a..b", "a${b}c", "\"\".", ".\"\"")) {
try {
intercept[ConfigException.BadPath] {