go-toml/ast_test.go

178 lines
6.5 KiB
Go

package toml
import (
"testing"
)
func TestAST_ConstructStructure(t *testing.T) {
testAST(t, func() (error, *parser) {
p := newParser()
p.setKeyValuePair(newKey("ding"), newItem(tInteger, 10))
p.setKeyValuePair(newKey("dong"), newItem(tString, "not a song"))
p.openTable(newKey("key1", "key2 a"))
p.setKeyValuePair(newKey("dooh"), newItem(tBoolean, true))
p.setKeyValuePair(newKey("dah"), newItem(tBoolean, false))
p.openTable(newKey("key1", "key2 b"))
p.setKeyValuePair(newKey("dieh"), newItem(tFloat, 1.111))
p.setKeyValuePair(newKey("duh"), newItem(tFloat, 1.18e-12))
p.setKeyValuePair(newKey("foo", "bar"), newItem(tArrayOfTables, newItem(tInteger, 1), newItem(tInteger, 2)))
p.openArrayOfTables(newKey("aaah", "table array"))
p.setKeyValuePair(newKey("a"), newItem(tFloat, 1.234))
p.openArrayOfTables(newKey("aaah", "table array"))
p.setKeyValuePair(newKey("b"), newItem(tFloat, 2.345))
p.setKeyValuePair(newKey("c"), newItem(tString, "bingo!"))
p.openArrayOfTables(newKey("aaah", "table array"))
return nil, p
},
"",
`{"aaah": {"table array": [{"a": 1.234}, {"b": 2.345, "c": "bingo!"}, {}]}, `+
`"ding": 10, "dong": "not a song", `+
`"key1": {"key2 a": {"dah": false, "dooh": true}, "key2 b": {"dieh": 1.111, "duh": 1.18e-12, "foo": {"bar": [1, 2]}}}}`)
}
func TestAST_EmptyKeyForCreatingTablePath_Panics(t *testing.T) {
defer func() {
r := recover()
if r.(string) != "makeTablePath(): empty key provided; a key must have at least one key part" {
t.Fatalf("Did not get the expected panic message")
}
}()
p := newParser()
p.openTable(newKey())
}
func TestAST_StoreValueInRootTable(t *testing.T) {
testAST(t, func() (error, *parser) {
p := newParser()
p.setKeyValuePair(newKey("key1"), newItem(tString, "value1"))
return p.setKeyValuePair(newKey("key2"), newItem(tString, "value2")), p
},
"",
`{"key1": "value1", "key2": "value2"}`)
}
func TestAST_StoreValueWithMultipartKey_CreatesTableHierarchy(t *testing.T) {
testAST(t, func() (error, *parser) {
p := newParser()
return p.setKeyValuePair(newKey("key1", "key2", "key3"), newItem(tString, "value")), p
},
"",
`{"key1": {"key2": {"key3": "value"}}}`)
}
func TestAST_StoreDuplicateKeyInRootTable_ReturnsError(t *testing.T) {
testAST(t, func() (error, *parser) {
p := newParser()
p.setKeyValuePair(newKey("key"), newItem(tString, "value"))
return p.setKeyValuePair(newKey("key"), newItem(tInteger, 321)), p
},
`invalid key/value pair: string item already exists at key [key]`,
`{"key": "value"}`)
}
func TestAST_StoreValueWithMultipartKey_UnderSubtable_CreatesTableHierarchy(t *testing.T) {
testAST(t, func() (error, *parser) {
p := newParser()
p.openTable(newKey("tablekey1", "tablekey2"))
return p.setKeyValuePair(newKey("valuekey1", "valuekey2", "valuekey3"), newItem(tString, "value")), p
},
"",
`{"tablekey1": {"tablekey2": {"valuekey1": {"valuekey2": {"valuekey3": "value"}}}}}`)
}
func TestAST_StoreKeyPathWherePathContainsNonTableAlready_ReturnsError(t *testing.T) {
testAST(t, func() (error, *parser) {
p := newParser()
p.openTable(newKey("key1"))
p.setKeyValuePair(newKey("key2"), newItem(tInteger, 0))
return p.setKeyValuePair(newKey("key2", "key3"), newItem(tString, "value")), p
},
`invalid key/value pair: integer item already exists at key [key1->key2]`,
`{"key1": {"key2": 0}}`)
}
func TestAST_GivenExistingTableAtKey_CreatingTableAtSameKey_ReturnsError(t *testing.T) {
testAST(t, func() (error, *parser) {
p := newParser()
p.openTable(newKey("key1", "key2"))
return p.openTable(newKey("key1", "key2")), p
},
`invalid table: table item already exists at key [key1->key2]`,
`{"key1": {"key2": {}}}`)
}
func TestAST_GivenExistingItemAtKey_CreatingTableAtSameKey_ReturnsError(t *testing.T) {
testAST(t, func() (error, *parser) {
p := newParser()
p.setKeyValuePair(newKey("key"), newItem(tString, "value"))
return p.openTable(newKey("key")), p
},
`invalid table: string item already exists at key [key]`,
`{"key": "value"}`)
}
func TestAST_GivenExistingItemInKeyPath_CreatingTable_ReturnsError(t *testing.T) {
testAST(t, func() (error, *parser) {
p := newParser()
p.setKeyValuePair(newKey("key"), newItem(tString, "value"))
return p.openTable(newKey("key", "subkey")), p
},
`invalid table: string item already exists at key [key]`,
`{"key": "value"}`)
}
func TestAST_GivenExistingItemAtDeepKey_CreatingTableAtSameKey_ReturnsError(t *testing.T) {
testAST(t, func() (error, *parser) {
p := newParser()
p.openTable(newKey("deep", "table"))
p.setKeyValuePair(newKey("key"), newItem(tInteger, 0))
return p.openTable(newKey("deep", "table", "key")), p
},
`invalid table: integer item already exists at key [deep->table->key]`,
`{"deep": {"table": {"key": 0}}}`)
}
func TestAST_GivenExistingItemAtDeepKeyFromSubTable_CreatingTableAtSameKey_ReturnsError(t *testing.T) {
testAST(t, func() (error, *parser) {
p := newParser()
p.openTable(newKey("deep", "table"))
p.setKeyValuePair(newKey("key1", "key2"), newItem(tInteger, 0))
return p.setKeyValuePair(newKey("key1", "key2"), newItem(tBoolean, true)), p
},
// This test mainly tests the formatting of [deep->table->key1->key2], being a concatenation
// of the currently active table plus the multipart key for setKeyValuePair().
`invalid key/value pair: integer item already exists at key [deep->table->key1->key2]`,
`{"deep": {"table": {"key1": {"key2": 0}}}}`)
}
func TestAST_FormattingOfQuotedPathPartInError(t *testing.T) {
testAST(t, func() (error, *parser) {
p := newParser()
p.openTable(newKey("must be quoted"))
p.setKeyValuePair(newKey("this one too"), newItem(tInteger, 0))
return p.setKeyValuePair(newKey("this one too"), newItem(tInteger, 0)), p
},
`invalid key/value pair: integer item already exists at key ["must be quoted"->"this one too"]`,
`{"must be quoted": {"this one too": 0}}`)
}
func TestAST_GivenExistingItemAtKey_CreatingArrayOfTablesAtSameKey_ReturnsError(t *testing.T) {
testAST(t, func() (error, *parser) {
p := newParser()
p.Root["key"] = newItem(tString, "value")
return p.openArrayOfTables(newKey("key")), p
},
`invalid table array: string item already exists at key [key]`,
`{"key": "value"}`)
}
func TestAST_GivenExistingItemInKeyPath_CreatingArrayOfTables_ReturnsError(t *testing.T) {
testAST(t, func() (error, *parser) {
p := newParser()
p.Root["key"] = newItem(tString, "value")
return p.openArrayOfTables(newKey("key", "subkey")), p
},
`invalid table array: string item already exists at key [key]`,
`{"key": "value"}`)
}