13 type failingWriter struct {
19 func (f *failingWriter) Write(p []byte) (n int, err error) {
21 toWrite := f.failAt - (count + f.written)
31 f.buffer.Write(p[:toWrite])
33 return toWrite, fmt.Errorf("failingWriter failed after writing %d bytes", f.written)
36 func assertErrorString(t *testing.T, expected string, err error) {
37 expectedErr := errors.New(expected)
38 if err == nil || err.Error() != expectedErr.Error() {
39 t.Errorf("expecting error %s, but got %s instead", expected, err)
43 func TestTreeWriteToEmptyTable(t *testing.T) {
44 doc := `[[empty-tables]]
47 toml, err := Load(doc)
49 t.Fatal("Unexpected Load error:", err)
51 tomlString, err := toml.ToTomlString()
53 t.Fatal("Unexpected ToTomlString error:", err)
62 if tomlString != expected {
63 t.Fatalf("Expected:\n%s\nGot:\n%s", expected, tomlString)
67 func TestTreeWriteToTomlString(t *testing.T) {
68 toml, err := Load(`name = { first = "Tom", last = "Preston-Werner" }
69 points = { x = 1, y = 2 }`)
72 t.Fatal("Unexpected error:", err)
75 tomlString, _ := toml.ToTomlString()
76 reparsedTree, err := Load(tomlString)
78 assertTree(t, reparsedTree, err, map[string]interface{}{
79 "name": map[string]interface{}{
81 "last": "Preston-Werner",
83 "points": map[string]interface{}{
90 func TestTreeWriteToTomlStringSimple(t *testing.T) {
91 tree, err := Load("[foo]\n\n[[foo.bar]]\na = 42\n\n[[foo.bar]]\na = 69\n")
93 t.Errorf("Test failed to parse: %v", err)
96 result, err := tree.ToTomlString()
98 t.Errorf("Unexpected error: %s", err)
100 expected := "\n[foo]\n\n [[foo.bar]]\n a = 42\n\n [[foo.bar]]\n a = 69\n"
101 if result != expected {
102 t.Errorf("Expected got '%s', expected '%s'", result, expected)
106 func TestTreeWriteToTomlStringKeysOrders(t *testing.T) {
107 for i := 0; i < 100; i++ {
116 stringRepr, _ := tree.ToTomlString()
118 t.Log("Intermediate string representation:")
121 r := strings.NewReader(stringRepr)
122 toml, err := LoadReader(r)
125 t.Fatal("Unexpected error:", err)
128 assertTree(t, toml, err, map[string]interface{}{
132 "qux": map[string]interface{}{
140 func testMaps(t *testing.T, actual, expected map[string]interface{}) {
141 if !reflect.DeepEqual(actual, expected) {
142 t.Fatal("trees aren't equal.\n", "Expected:\n", expected, "\nActual:\n", actual)
146 func TestTreeWriteToMapSimple(t *testing.T) {
147 tree, _ := Load("a = 42\nb = 17")
149 expected := map[string]interface{}{
154 testMaps(t, tree.ToMap(), expected)
157 func TestTreeWriteToInvalidTreeSimpleValue(t *testing.T) {
158 tree := Tree{values: map[string]interface{}{"foo": int8(1)}}
159 _, err := tree.ToTomlString()
160 assertErrorString(t, "invalid value type at foo: int8", err)
163 func TestTreeWriteToInvalidTreeTomlValue(t *testing.T) {
164 tree := Tree{values: map[string]interface{}{"foo": &tomlValue{value: int8(1), comment: "", position: Position{}}}}
165 _, err := tree.ToTomlString()
166 assertErrorString(t, "unsupported value type int8: 1", err)
169 func TestTreeWriteToInvalidTreeTomlValueArray(t *testing.T) {
170 tree := Tree{values: map[string]interface{}{"foo": &tomlValue{value: int8(1), comment: "", position: Position{}}}}
171 _, err := tree.ToTomlString()
172 assertErrorString(t, "unsupported value type int8: 1", err)
175 func TestTreeWriteToFailingWriterInSimpleValue(t *testing.T) {
176 toml, _ := Load(`a = 2`)
177 writer := failingWriter{failAt: 0, written: 0}
178 _, err := toml.WriteTo(&writer)
179 assertErrorString(t, "failingWriter failed after writing 0 bytes", err)
182 func TestTreeWriteToFailingWriterInTable(t *testing.T) {
186 writer := failingWriter{failAt: 2, written: 0}
187 _, err := toml.WriteTo(&writer)
188 assertErrorString(t, "failingWriter failed after writing 2 bytes", err)
190 writer = failingWriter{failAt: 13, written: 0}
191 _, err = toml.WriteTo(&writer)
192 assertErrorString(t, "failingWriter failed after writing 13 bytes", err)
195 func TestTreeWriteToFailingWriterInArray(t *testing.T) {
199 writer := failingWriter{failAt: 2, written: 0}
200 _, err := toml.WriteTo(&writer)
201 assertErrorString(t, "failingWriter failed after writing 2 bytes", err)
203 writer = failingWriter{failAt: 15, written: 0}
204 _, err = toml.WriteTo(&writer)
205 assertErrorString(t, "failingWriter failed after writing 15 bytes", err)
208 func TestTreeWriteToMapExampleFile(t *testing.T) {
209 tree, _ := LoadFile("example.toml")
210 expected := map[string]interface{}{
211 "title": "TOML Example",
212 "owner": map[string]interface{}{
213 "name": "Tom Preston-Werner",
214 "organization": "GitHub",
215 "bio": "GitHub Cofounder & CEO\nLikes tater tots and beer.",
216 "dob": time.Date(1979, time.May, 27, 7, 32, 0, 0, time.UTC),
218 "database": map[string]interface{}{
219 "server": "192.168.1.1",
220 "ports": []interface{}{int64(8001), int64(8001), int64(8002)},
221 "connection_max": int64(5000),
224 "servers": map[string]interface{}{
225 "alpha": map[string]interface{}{
229 "beta": map[string]interface{}{
234 "clients": map[string]interface{}{
235 "data": []interface{}{
236 []interface{}{"gamma", "delta"},
237 []interface{}{int64(1), int64(2)},
241 testMaps(t, tree.ToMap(), expected)
244 func TestTreeWriteToMapWithTablesInMultipleChunks(t *testing.T) {
252 expected := map[string]interface{}{
253 "menu": map[string]interface{}{
254 "main": []interface{}{
255 map[string]interface{}{"a": "menu 1", "b": "menu 2"},
256 map[string]interface{}{"c": "menu 3", "d": "menu 4"},
260 treeMap := tree.ToMap()
262 testMaps(t, treeMap, expected)
265 func TestTreeWriteToMapWithArrayOfInlineTables(t *testing.T) {
269 { key = "shell", name = "Shell" },
270 { key = "ruby", name = "Ruby" },
271 { key = "python", name = "Python" }
274 expected := map[string]interface{}{
275 "params": map[string]interface{}{
276 "language_tabs": []interface{}{
277 map[string]interface{}{
281 map[string]interface{}{
285 map[string]interface{}{
293 treeMap := tree.ToMap()
294 testMaps(t, treeMap, expected)
297 func TestTreeWriteToFloat(t *testing.T) {
298 tree, err := Load(`a = 3.0`)
302 str, err := tree.ToTomlString()
306 expected := `a = 3.0`
307 if strings.TrimSpace(str) != strings.TrimSpace(expected) {
308 t.Fatalf("Expected:\n%s\nGot:\n%s", expected, str)
312 func BenchmarkTreeToTomlString(b *testing.B) {
313 toml, err := Load(sampleHard)
315 b.Fatal("Unexpected error:", err)
318 for i := 0; i < b.N; i++ {
319 _, err := toml.ToTomlString()
326 var sampleHard = `# Test file for TOML
327 # Only this one tries to emulate a TOML file written by a user of the kind of parser writers probably hate
328 # This part you'll really hate
331 test_string = "You'll hate me after this - #" # " Annoying, isn't it?
334 test_array = [ "] ", " # "] # ] There you go, parse this!
335 test_array2 = [ "Test #11 ]proved that", "Experiment #9 was a success" ]
336 # You didn't think it'd as easy as chucking out the last #, did you?
337 another_test_string = " Same thing, but with a string #"
338 harder_test_string = " And when \"'s are in the string, along with # \"" # "and comments are there too"
339 # Things will get harder
342 "what?" = "You don't think some user won't do that?"
348 # Each of the following keygroups/key value pairs should produce an error. Uncomment to them to test
350 #[error] if you didn't catch this, your parser is broken
351 #string = "Anything other than tabs, spaces and newline after a keygroup or key value pair has ended should produce an error unless it is a comment" like this
353 # "This might most likely happen in multiline arrays",
357 # ] End of array comment, forgot the #
358 #number = 3.14 pi <--again forgot the # `