// Copyright 2020 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. package jsonrpc2_test import ( "bytes" "encoding/json" "fmt" "testing" "golang.org/x/tools/internal/jsonrpc2" ) var wireIDTestData = []struct { name string id jsonrpc2.ID encoded []byte plain string quoted string }{ { name: `empty`, encoded: []byte(`0`), plain: `0`, quoted: `#0`, }, { name: `number`, id: jsonrpc2.NewIntID(43), encoded: []byte(`43`), plain: `43`, quoted: `#43`, }, { name: `string`, id: jsonrpc2.NewStringID("life"), encoded: []byte(`"life"`), plain: `life`, quoted: `"life"`, }, } func TestIDFormat(t *testing.T) { for _, test := range wireIDTestData { t.Run(test.name, func(t *testing.T) { if got := fmt.Sprint(test.id); got != test.plain { t.Errorf("got %s expected %s", got, test.plain) } if got := fmt.Sprintf("%q", test.id); got != test.quoted { t.Errorf("got %s want %s", got, test.quoted) } }) } } func TestIDEncode(t *testing.T) { for _, test := range wireIDTestData { t.Run(test.name, func(t *testing.T) { data, err := json.Marshal(&test.id) if err != nil { t.Fatal(err) } checkJSON(t, data, test.encoded) }) } } func TestIDDecode(t *testing.T) { for _, test := range wireIDTestData { t.Run(test.name, func(t *testing.T) { var got *jsonrpc2.ID if err := json.Unmarshal(test.encoded, &got); err != nil { t.Fatal(err) } if got == nil { t.Errorf("got nil want %s", test.id) } else if *got != test.id { t.Errorf("got %s want %s", got, test.id) } }) } } func TestErrorEncode(t *testing.T) { b, err := json.Marshal(jsonrpc2.NewError(0, "")) if err != nil { t.Fatal(err) } checkJSON(t, b, []byte(`{ "code": 0, "message": "" }`)) } func TestErrorResponse(t *testing.T) { // originally reported in #39719, this checks that result is not present if // it is an error response r, _ := jsonrpc2.NewResponse(jsonrpc2.NewIntID(3), nil, fmt.Errorf("computing fix edits")) data, err := json.Marshal(r) if err != nil { t.Fatal(err) } checkJSON(t, data, []byte(`{ "jsonrpc":"2.0", "error":{ "code":0, "message":"computing fix edits" }, "id":3 }`)) } func checkJSON(t *testing.T, got, want []byte) { // compare the compact form, to allow for formatting differences g := &bytes.Buffer{} if err := json.Compact(g, []byte(got)); err != nil { t.Fatal(err) } w := &bytes.Buffer{} if err := json.Compact(w, []byte(want)); err != nil { t.Fatal(err) } if g.String() != w.String() { t.Fatalf("Got:\n%s\nWant:\n%s", g, w) } }