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. other substitutions, and you can't have substitutions in keys.
When concatenating the path expression, any `.` characters outside When concatenating the path expression, any `.` characters outside
quoted strings or numbers are understood as path separators, while quoted strings are understood as path separators, while inside
inside quoted strings and numbers `.` has no special meaning. So quoted strings `.` has no special meaning. So
`foo.bar."hello.world"` would be a path with three elements, `foo.bar."hello.world"` would be a path with three elements,
looking up key `foo`, key `bar`, then key `hello.world`. looking up key `foo`, key `bar`, then key `hello.world`.
- `10.0foo` is a number then unquoted string `foo` so this would The main tricky point is that `.` characters in numbers do count
be a single-element path. 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 - `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. be a two-element path with `foo10` and `0` as the elements.
- `foo"10.0"` is an unquoted then a quoted string which are - `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("a_c"), parsePath("a_c"))
assertEquals(path("-"), parsePath("\"-\"")) 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", "\"\".", ".\"\"")) { for (invalid <- Seq("", " ", " \n \n ", "a.", ".b", "a..b", "a${b}c", "\"\".", ".\"\"")) {
try { try {
intercept[ConfigException.BadPath] { intercept[ConfigException.BadPath] {