refactor: Improve textual's API (#14595)

This commit is contained in:
Amaury 2023-01-12 17:00:55 +01:00 committed by GitHub
parent 5e7b744592
commit 305053136a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
35 changed files with 258 additions and 115 deletions

View File

@ -0,0 +1,117 @@
// Code generated by protoc-gen-go-pulsar. DO NOT EDIT.
package textualv1
import (
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
descriptorpb "google.golang.org/protobuf/types/descriptorpb"
reflect "reflect"
)
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.27.0
// protoc (unknown)
// source: cosmos/msg/textual/v1/textual.proto
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
var file_cosmos_msg_textual_v1_textual_proto_extTypes = []protoimpl.ExtensionInfo{
{
ExtendedType: (*descriptorpb.MessageOptions)(nil),
ExtensionType: (*string)(nil),
Field: 11110009,
Name: "cosmos.msg.textual.v1.expert_custom_renderer",
Tag: "bytes,11110009,opt,name=expert_custom_renderer",
Filename: "cosmos/msg/textual/v1/textual.proto",
},
}
// Extension fields to descriptorpb.MessageOptions.
var (
// expert_custom_renderer is an informative identifier to reference the
// algorithm used to generate the custom textual representation of the
// protobuf message where this annotation is applied. We recommend to use a
// short, versioned name as this identifier, e.g. "replace_with_username_v1".
// We also recommand providing a human-readable description as protobuf
// comments on this annotation, for example a short specification or a link
// to the relevant documentation.
//
// Also see the section on Custom Message Renderers in ADR-050.
//
// optional string expert_custom_renderer = 11110009;
E_ExpertCustomRenderer = &file_cosmos_msg_textual_v1_textual_proto_extTypes[0]
)
var File_cosmos_msg_textual_v1_textual_proto protoreflect.FileDescriptor
var file_cosmos_msg_textual_v1_textual_proto_rawDesc = []byte{
0x0a, 0x23, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x6d, 0x73, 0x67, 0x2f, 0x74, 0x65, 0x78,
0x74, 0x75, 0x61, 0x6c, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x65, 0x78, 0x74, 0x75, 0x61, 0x6c, 0x2e,
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x15, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x6d, 0x73,
0x67, 0x2e, 0x74, 0x65, 0x78, 0x74, 0x75, 0x61, 0x6c, 0x2e, 0x76, 0x31, 0x1a, 0x20, 0x67, 0x6f,
0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x64, 0x65,
0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x3a, 0x58,
0x0a, 0x16, 0x65, 0x78, 0x70, 0x65, 0x72, 0x74, 0x5f, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x5f,
0x72, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x65, 0x72, 0x12, 0x1f, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c,
0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61,
0x67, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xf9, 0x8c, 0xa6, 0x05, 0x20, 0x01,
0x28, 0x09, 0x52, 0x14, 0x65, 0x78, 0x70, 0x65, 0x72, 0x74, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d,
0x52, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x65, 0x72, 0x42, 0xd2, 0x01, 0x0a, 0x19, 0x63, 0x6f, 0x6d,
0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x6d, 0x73, 0x67, 0x2e, 0x74, 0x65, 0x78, 0x74,
0x75, 0x61, 0x6c, 0x2e, 0x76, 0x31, 0x42, 0x0c, 0x54, 0x65, 0x78, 0x74, 0x75, 0x61, 0x6c, 0x50,
0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x30, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64,
0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f,
0x6d, 0x73, 0x67, 0x2f, 0x74, 0x65, 0x78, 0x74, 0x75, 0x61, 0x6c, 0x2f, 0x76, 0x31, 0x3b, 0x74,
0x65, 0x78, 0x74, 0x75, 0x61, 0x6c, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x43, 0x4d, 0x54, 0xaa, 0x02,
0x15, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x4d, 0x73, 0x67, 0x2e, 0x54, 0x65, 0x78, 0x74,
0x75, 0x61, 0x6c, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x15, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x5c,
0x4d, 0x73, 0x67, 0x5c, 0x54, 0x65, 0x78, 0x74, 0x75, 0x61, 0x6c, 0x5c, 0x56, 0x31, 0xe2, 0x02,
0x21, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x5c, 0x4d, 0x73, 0x67, 0x5c, 0x54, 0x65, 0x78, 0x74,
0x75, 0x61, 0x6c, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61,
0x74, 0x61, 0xea, 0x02, 0x18, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x3a, 0x3a, 0x4d, 0x73, 0x67,
0x3a, 0x3a, 0x54, 0x65, 0x78, 0x74, 0x75, 0x61, 0x6c, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70,
0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var file_cosmos_msg_textual_v1_textual_proto_goTypes = []interface{}{
(*descriptorpb.MessageOptions)(nil), // 0: google.protobuf.MessageOptions
}
var file_cosmos_msg_textual_v1_textual_proto_depIdxs = []int32{
0, // 0: cosmos.msg.textual.v1.expert_custom_renderer:extendee -> google.protobuf.MessageOptions
1, // [1:1] is the sub-list for method output_type
1, // [1:1] is the sub-list for method input_type
1, // [1:1] is the sub-list for extension type_name
0, // [0:1] is the sub-list for extension extendee
0, // [0:0] is the sub-list for field type_name
}
func init() { file_cosmos_msg_textual_v1_textual_proto_init() }
func file_cosmos_msg_textual_v1_textual_proto_init() {
if File_cosmos_msg_textual_v1_textual_proto != nil {
return
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_cosmos_msg_textual_v1_textual_proto_rawDesc,
NumEnums: 0,
NumMessages: 0,
NumExtensions: 1,
NumServices: 0,
},
GoTypes: file_cosmos_msg_textual_v1_textual_proto_goTypes,
DependencyIndexes: file_cosmos_msg_textual_v1_textual_proto_depIdxs,
ExtensionInfos: file_cosmos_msg_textual_v1_textual_proto_extTypes,
}.Build()
File_cosmos_msg_textual_v1_textual_proto = out.File
file_cosmos_msg_textual_v1_textual_proto_rawDesc = nil
file_cosmos_msg_textual_v1_textual_proto_goTypes = nil
file_cosmos_msg_textual_v1_textual_proto_depIdxs = nil
}

View File

@ -228,7 +228,6 @@ message Grant {
message MsgGrant {
option (cosmos.msg.v1.signer) = "granter";
option (cosmos.msg.v1.textual.type_url) = "authz v1beta1 grant";
string granter = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"];
string grantee = 2 [(cosmos_proto.scalar) = "cosmos.AddressString"];
@ -249,13 +248,13 @@ End of transaction messages
Application developers may choose to not follow default renderer value output for their own `Msg`s. In this case, they can implement their own custom `Msg` renderer. This is similar to [EIP4430](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-4430.md), where the smart contract developer chooses the description string to be shown to the end user.
This is done by setting the `cosmos.msg.v1.textual.expert_custom_renderer` Protobuf option to a non-empty string. This option CAN ONLY be set on a Protobuf message representing transaction message object (implementing `sdk.Msg` interface).
This is done by setting the `cosmos.msg.textual.v1.expert_custom_renderer` Protobuf option to a non-empty string. This option CAN ONLY be set on a Protobuf message representing transaction message object (implementing `sdk.Msg` interface).
```protobuf
message MsgFooBar {
// Optional comments to describe in human-readable language the formatting
// rules of the custom renderer.
option (cosmos.msg.v1.textual.expert_custom_renderer) = "<unique algorithm identifier>";
option (cosmos.msg.textual.v1.expert_custom_renderer) = "<unique algorithm identifier>";
// proto fields
}

View File

@ -0,0 +1,18 @@
syntax = "proto3";
package cosmos.msg.textual.v1;
import "google/protobuf/descriptor.proto";
extend google.protobuf.MessageOptions {
// expert_custom_renderer is an informative identifier to reference the
// algorithm used to generate the custom textual representation of the
// protobuf message where this annotation is applied. We recommend to use a
// short, versioned name as this identifier, e.g. "replace_with_username_v1".
// We also recommand providing a human-readable description as protobuf
// comments on this annotation, for example a short specification or a link
// to the relevant documentation.
//
// Also see the section on Custom Message Renderers in ADR-050.
string expert_custom_renderer = 11110009;
}

View File

@ -1,4 +1,4 @@
package valuerenderer
package textual
import (
"context"

View File

@ -1,4 +1,4 @@
package valuerenderer_test
package textual_test
import (
"context"
@ -7,8 +7,7 @@ import (
"os"
"testing"
"cosmossdk.io/tx/textual/valuerenderer"
"cosmossdk.io/tx/textual"
"github.com/google/go-cmp/cmp"
"github.com/stretchr/testify/require"
@ -20,18 +19,18 @@ import (
type anyJsonTest struct {
Proto json.RawMessage
Screens []valuerenderer.Screen
Screens []textual.Screen
}
func TestAny(t *testing.T) {
raw, err := os.ReadFile("../internal/testdata/any.json")
raw, err := os.ReadFile("./internal/testdata/any.json")
require.NoError(t, err)
var testcases []anyJsonTest
err = json.Unmarshal(raw, &testcases)
require.NoError(t, err)
tr := valuerenderer.NewTextual(EmptyCoinMetadataQuerier)
tr := textual.NewTextual(EmptyCoinMetadataQuerier)
for i, tc := range testcases {
t.Run(fmt.Sprintf("%d", i), func(t *testing.T) {
anyMsg := anypb.Any{}
@ -39,7 +38,7 @@ func TestAny(t *testing.T) {
require.NoError(t, err)
// Format into screens and check vs expected
rend := valuerenderer.NewAnyValueRenderer((&tr))
rend := textual.NewAnyValueRenderer((&tr))
screens, err := rend.Format(context.Background(), protoreflect.ValueOfMessage(anyMsg.ProtoReflect()))
require.NoError(t, err)
require.Equal(t, tc.Screens, screens)

View File

@ -1,4 +1,4 @@
package valuerenderer
package textual
import (
"bytes"

View File

@ -1,4 +1,4 @@
package valuerenderer
package textual
import (
"bytes"

View File

@ -1,4 +1,4 @@
package valuerenderer_test
package textual_test
import (
"context"
@ -6,7 +6,7 @@ import (
"os"
"testing"
"cosmossdk.io/tx/textual/valuerenderer"
"cosmossdk.io/tx/textual"
"github.com/stretchr/testify/require"
"google.golang.org/protobuf/reflect/protoreflect"
)
@ -15,12 +15,12 @@ func TestBytesJsonTestCases(t *testing.T) {
var testcases []bytesTest
// Bytes.json contains bytes that are represented in base64 format, and
// their expected results in hex.
raw, err := os.ReadFile("../internal/testdata/bytes.json")
raw, err := os.ReadFile("./internal/testdata/bytes.json")
require.NoError(t, err)
err = json.Unmarshal(raw, &testcases)
require.NoError(t, err)
textual := valuerenderer.NewTextual(nil)
textual := textual.NewTextual(nil)
for _, tc := range testcases {
valrend, err := textual.GetFieldValueRenderer(fieldDescriptorFromName("BYTES"))

View File

@ -1,4 +1,4 @@
package valuerenderer_test
package textual_test
import (
"context"
@ -12,7 +12,7 @@ import (
bankv1beta1 "cosmossdk.io/api/cosmos/bank/v1beta1"
basev1beta1 "cosmossdk.io/api/cosmos/base/v1beta1"
"cosmossdk.io/tx/textual/valuerenderer"
"cosmossdk.io/tx/textual"
)
// mockCoinMetadataKey is used in the mock coin metadata querier.
@ -47,33 +47,33 @@ func addMetadataToContext(ctx context.Context, metadata *bankv1beta1.Metadata) c
func TestMetadataQuerier(t *testing.T) {
// Errors on nil metadata querier
textual := valuerenderer.NewTextual(nil)
vr, err := textual.GetFieldValueRenderer(fieldDescriptorFromName("COIN"))
txt := textual.NewTextual(nil)
vr, err := txt.GetFieldValueRenderer(fieldDescriptorFromName("COIN"))
require.NoError(t, err)
_, err = vr.Format(context.Background(), protoreflect.ValueOf((&basev1beta1.Coin{}).ProtoReflect()))
require.Error(t, err)
// Errors if metadata querier returns an error
expErr := fmt.Errorf("mock error")
textual = valuerenderer.NewTextual(func(_ context.Context, _ string) (*bankv1beta1.Metadata, error) {
txt = textual.NewTextual(func(_ context.Context, _ string) (*bankv1beta1.Metadata, error) {
return nil, expErr
})
vr, err = textual.GetFieldValueRenderer(fieldDescriptorFromName("COIN"))
vr, err = txt.GetFieldValueRenderer(fieldDescriptorFromName("COIN"))
require.NoError(t, err)
_, err = vr.Format(context.Background(), protoreflect.ValueOf((&basev1beta1.Coin{}).ProtoReflect()))
require.ErrorIs(t, err, expErr)
_, err = vr.(valuerenderer.RepeatedValueRenderer).FormatRepeated(context.Background(), protoreflect.ValueOf(NewGenericList([]*basev1beta1.Coin{{}})))
_, err = vr.(textual.RepeatedValueRenderer).FormatRepeated(context.Background(), protoreflect.ValueOf(NewGenericList([]*basev1beta1.Coin{{}})))
require.ErrorIs(t, err, expErr)
}
func TestCoinJsonTestcases(t *testing.T) {
var testcases []coinJsonTest
raw, err := os.ReadFile("../internal/testdata/coin.json")
raw, err := os.ReadFile("./internal/testdata/coin.json")
require.NoError(t, err)
err = json.Unmarshal(raw, &testcases)
require.NoError(t, err)
textual := valuerenderer.NewTextual(mockCoinMetadataQuerier)
textual := textual.NewTextual(mockCoinMetadataQuerier)
vr, err := textual.GetFieldValueRenderer(fieldDescriptorFromName("COIN"))
require.NoError(t, err)

View File

@ -1,4 +1,4 @@
package valuerenderer
package textual
import (
"context"

View File

@ -1,4 +1,4 @@
package valuerenderer_test
package textual_test
import (
"context"
@ -9,21 +9,21 @@ import (
bankv1beta1 "cosmossdk.io/api/cosmos/bank/v1beta1"
basev1beta1 "cosmossdk.io/api/cosmos/base/v1beta1"
"cosmossdk.io/math"
"cosmossdk.io/tx/textual/valuerenderer"
"cosmossdk.io/tx/textual"
"github.com/stretchr/testify/require"
"google.golang.org/protobuf/reflect/protoreflect"
)
func TestCoinsJsonTestcases(t *testing.T) {
var testcases []coinsJsonTest
raw, err := os.ReadFile("../internal/testdata/coins.json")
raw, err := os.ReadFile("./internal/testdata/coins.json")
require.NoError(t, err)
err = json.Unmarshal(raw, &testcases)
require.NoError(t, err)
textual := valuerenderer.NewTextual(mockCoinMetadataQuerier)
vr, err := textual.GetFieldValueRenderer(fieldDescriptorFromName("COINS"))
vrr := vr.(valuerenderer.RepeatedValueRenderer)
txt := textual.NewTextual(mockCoinMetadataQuerier)
vr, err := txt.GetFieldValueRenderer(fieldDescriptorFromName("COINS"))
vrr := vr.(textual.RepeatedValueRenderer)
require.NoError(t, err)
for _, tc := range testcases {

View File

@ -1,4 +1,4 @@
package valuerenderer
package textual
import (
"context"

View File

@ -1,11 +1,11 @@
package valuerenderer_test
package textual_test
import (
"encoding/json"
"os"
"testing"
"cosmossdk.io/tx/textual/valuerenderer"
"cosmossdk.io/tx/textual"
"github.com/stretchr/testify/require"
"google.golang.org/protobuf/reflect/protoreflect"
)
@ -13,12 +13,12 @@ import (
func TestDecJsonTestcases(t *testing.T) {
type decimalTest []string
var testcases []decimalTest
raw, err := os.ReadFile("../internal/testdata/decimals.json")
raw, err := os.ReadFile("./internal/testdata/decimals.json")
require.NoError(t, err)
err = json.Unmarshal(raw, &testcases)
require.NoError(t, err)
textual := valuerenderer.NewTextual(nil)
textual := textual.NewTextual(nil)
for _, tc := range testcases {
tc := tc

View File

@ -1,4 +1,4 @@
package valuerenderer
package textual
import (
"context"

View File

@ -1,4 +1,4 @@
package valuerenderer_test
package textual_test
import (
"context"
@ -7,7 +7,7 @@ import (
"os"
"testing"
"cosmossdk.io/tx/textual/valuerenderer"
"cosmossdk.io/tx/textual"
"github.com/stretchr/testify/require"
"google.golang.org/protobuf/proto"
@ -22,7 +22,7 @@ type durationTest struct {
}
func TestDurationJSON(t *testing.T) {
raw, err := os.ReadFile("../internal/testdata/duration.json")
raw, err := os.ReadFile("./internal/testdata/duration.json")
require.NoError(t, err)
var testcases []durationTest
@ -31,9 +31,9 @@ func TestDurationJSON(t *testing.T) {
for i, tc := range testcases {
t.Run(fmt.Sprintf("%d", i), func(t *testing.T) {
rend := valuerenderer.NewDurationValueRenderer()
rend := textual.NewDurationValueRenderer()
var screens []valuerenderer.Screen
var screens []textual.Screen
if tc.Proto != nil {
screens, err = rend.Format(context.Background(), protoreflect.ValueOf(tc.Proto.ProtoReflect()))
if tc.Error {

View File

@ -1,4 +1,4 @@
package valuerenderer_test
package textual_test
import (
"context"
@ -16,8 +16,8 @@ import (
_ "cosmossdk.io/api/cosmos/crypto/multisig"
_ "cosmossdk.io/api/cosmos/crypto/secp256k1"
_ "cosmossdk.io/api/cosmos/gov/v1"
"cosmossdk.io/tx/textual"
"cosmossdk.io/tx/textual/internal/textualpb"
"cosmossdk.io/tx/textual/valuerenderer"
)
type e2eJsonTest struct {
@ -26,7 +26,7 @@ type e2eJsonTest struct {
}
func TestE2EJsonTestcases(t *testing.T) {
raw, err := os.ReadFile("../internal/testdata/e2e.json")
raw, err := os.ReadFile("./internal/testdata/e2e.json")
require.NoError(t, err)
var testcases []e2eJsonTest
@ -37,8 +37,8 @@ func TestE2EJsonTestcases(t *testing.T) {
t.Run(tc.Name, func(t *testing.T) {
_, bodyBz, _, authInfoBz, signerData := createTextualData(t, tc.Proto, tc.SignerData)
tr := valuerenderer.NewTextual(mockCoinMetadataQuerier)
rend := valuerenderer.NewTxValueRenderer(&tr)
tr := textual.NewTextual(mockCoinMetadataQuerier)
rend := textual.NewTxValueRenderer(&tr)
ctx := addMetadataToContext(context.Background(), tc.Metadata)
data := &textualpb.TextualData{

View File

@ -1,4 +1,4 @@
package valuerenderer
package textual
import (
"io"

View File

@ -1,4 +1,4 @@
package valuerenderer
package textual
import (
"bytes"
@ -17,7 +17,7 @@ type encodingJsonTest struct {
}
func TestEncodingJson(t *testing.T) {
raw, err := os.ReadFile("../internal/testdata/encode.json")
raw, err := os.ReadFile("./internal/testdata/encode.json")
require.NoError(t, err)
var testcases []encodingJsonTest

View File

@ -1,4 +1,4 @@
package valuerenderer
package textual
import (
"context"

View File

@ -1,4 +1,4 @@
package valuerenderer_test
package textual_test
import (
"context"
@ -7,8 +7,8 @@ import (
"strings"
"testing"
"cosmossdk.io/tx/textual"
"cosmossdk.io/tx/textual/internal/testpb"
"cosmossdk.io/tx/textual/valuerenderer"
"github.com/google/go-cmp/cmp"
"github.com/stretchr/testify/require"
"google.golang.org/protobuf/encoding/protojson"
@ -23,12 +23,12 @@ type enumTest struct {
func TestEnumJsonTestcases(t *testing.T) {
var testcases []enumTest
raw, err := os.ReadFile("../internal/testdata/enum.json")
raw, err := os.ReadFile("./internal/testdata/enum.json")
require.NoError(t, err)
err = json.Unmarshal(raw, &testcases)
require.NoError(t, err)
textual := valuerenderer.NewTextual(nil)
textual := textual.NewTextual(nil)
for _, tc := range testcases {
t.Run(tc.Text, func(t *testing.T) {

View File

@ -1,4 +1,4 @@
package valuerenderer
package textual
import (
"context"

View File

@ -1,4 +1,4 @@
package valuerenderer_test
package textual_test
import (
"context"
@ -11,18 +11,18 @@ import (
"google.golang.org/protobuf/reflect/protoreflect"
"cosmossdk.io/math"
"cosmossdk.io/tx/textual/valuerenderer"
"cosmossdk.io/tx/textual"
)
func TestIntJsonTestcases(t *testing.T) {
type integerTest []string
var testcases []integerTest
raw, err := os.ReadFile("../internal/testdata/integers.json")
raw, err := os.ReadFile("./internal/testdata/integers.json")
require.NoError(t, err)
err = json.Unmarshal(raw, &testcases)
require.NoError(t, err)
textual := valuerenderer.NewTextual(nil)
textual := textual.NewTextual(nil)
for _, tc := range testcases {
t.Run(tc[0], func(t *testing.T) {
@ -58,7 +58,7 @@ func TestIntJsonTestcases(t *testing.T) {
// checkNumberTest checks that the output of a number value renderer
// matches the expected string. Only use it to test numbers.
func checkNumberTest(t *testing.T, r valuerenderer.ValueRenderer, pv protoreflect.Value, expected string) {
func checkNumberTest(t *testing.T, r textual.ValueRenderer, pv protoreflect.Value, expected string) {
screens, err := r.Format(context.Background(), pv)
require.NoError(t, err)
require.Len(t, screens, 1)

View File

@ -1,4 +1,4 @@
package valuerenderer
package textual
import (
"context"

View File

@ -1,4 +1,4 @@
package valuerenderer_test
package textual_test
import (
"context"
@ -7,10 +7,10 @@ import (
"os"
"testing"
"cosmossdk.io/tx/textual/valuerenderer"
"github.com/stretchr/testify/require"
bankv1beta1 "cosmossdk.io/api/cosmos/bank/v1beta1"
"cosmossdk.io/tx/textual"
"cosmossdk.io/tx/textual/internal/testpb"
"google.golang.org/protobuf/proto"
"google.golang.org/protobuf/reflect/protoreflect"
@ -22,21 +22,21 @@ func EmptyCoinMetadataQuerier(ctx context.Context, denom string) (*bankv1beta1.M
type messageJsonTest struct {
Proto *testpb.Foo
Screens []valuerenderer.Screen
Screens []textual.Screen
}
func TestMessageJsonTestcases(t *testing.T) {
raw, err := os.ReadFile("../internal/testdata/message.json")
raw, err := os.ReadFile("./internal/testdata/message.json")
require.NoError(t, err)
var testcases []messageJsonTest
err = json.Unmarshal(raw, &testcases)
require.NoError(t, err)
tr := valuerenderer.NewTextual(EmptyCoinMetadataQuerier)
tr := textual.NewTextual(EmptyCoinMetadataQuerier)
for i, tc := range testcases {
t.Run(fmt.Sprintf("%d", i), func(t *testing.T) {
rend := valuerenderer.NewMessageValueRenderer(&tr, (&testpb.Foo{}).ProtoReflect().Descriptor())
rend := textual.NewMessageValueRenderer(&tr, (&testpb.Foo{}).ProtoReflect().Descriptor())
screens, err := rend.Format(context.Background(), protoreflect.ValueOf(tc.Proto.ProtoReflect()))
require.NoError(t, err)

View File

@ -1,4 +1,4 @@
package valuerenderer_test
package textual_test
import (
"google.golang.org/protobuf/proto"

View File

@ -1,4 +1,4 @@
package valuerenderer_test
package textual_test
import (
"context"
@ -7,9 +7,9 @@ import (
"os"
"testing"
"cosmossdk.io/tx/textual/valuerenderer"
"github.com/stretchr/testify/require"
"cosmossdk.io/tx/textual"
"cosmossdk.io/tx/textual/internal/testpb"
"google.golang.org/protobuf/proto"
"google.golang.org/protobuf/reflect/protoreflect"
@ -17,7 +17,7 @@ import (
type repeatedJsonTest struct {
Proto *testpb.Qux
Screens []valuerenderer.Screen
Screens []textual.Screen
// TODO Remove once we finished all primitive value renderers parsing
// https://github.com/cosmos/cosmos-sdk/pull/13696
// https://github.com/cosmos/cosmos-sdk/pull/13853
@ -25,20 +25,20 @@ type repeatedJsonTest struct {
}
func TestRepeatedJsonTestcases(t *testing.T) {
raw, err := os.ReadFile("../internal/testdata/repeated.json")
raw, err := os.ReadFile("./internal/testdata/repeated.json")
require.NoError(t, err)
var testcases []repeatedJsonTest
err = json.Unmarshal(raw, &testcases)
require.NoError(t, err)
tr := valuerenderer.NewTextual(mockCoinMetadataQuerier)
tr := textual.NewTextual(mockCoinMetadataQuerier)
for i, tc := range testcases {
t.Run(fmt.Sprintf("%d", i), func(t *testing.T) {
// Create a context.Context containing all coins metadata, to simulate
// that they are in state.
ctx := context.Background()
rend := valuerenderer.NewMessageValueRenderer(&tr, (&testpb.Qux{}).ProtoReflect().Descriptor())
rend := textual.NewMessageValueRenderer(&tr, (&testpb.Qux{}).ProtoReflect().Descriptor())
require.NoError(t, err)
screens, err := rend.Format(ctx, protoreflect.ValueOf(tc.Proto.ProtoReflect()))

View File

@ -1,4 +1,4 @@
package valuerenderer
package textual
import (
"context"

View File

@ -1,4 +1,4 @@
package valuerenderer_test
package textual_test
import (
"context"
@ -7,7 +7,7 @@ import (
"os"
"testing"
"cosmossdk.io/tx/textual/valuerenderer"
"cosmossdk.io/tx/textual"
"github.com/stretchr/testify/require"
"google.golang.org/protobuf/reflect/protoreflect"
)
@ -17,7 +17,7 @@ type stringJsonTest struct {
}
func TestStringJsonTestcases(t *testing.T) {
raw, err := os.ReadFile("../internal/testdata/string.json")
raw, err := os.ReadFile("./internal/testdata/string.json")
require.NoError(t, err)
var testcases []stringJsonTest
@ -26,7 +26,7 @@ func TestStringJsonTestcases(t *testing.T) {
for i, tc := range testcases {
t.Run(fmt.Sprintf("%d", i), func(t *testing.T) {
rend := valuerenderer.NewStringValueRenderer()
rend := textual.NewStringValueRenderer()
screens, err := rend.Format(context.Background(), protoreflect.ValueOfString(tc.Text))
require.NoError(t, err)
@ -44,7 +44,7 @@ func TestStringHighUnicode(t *testing.T) {
// We cannot encode Unicode characters beyond the BMP directly in JSON,
// so this case must be a native Go test.
s := "\U00101234"
rend := valuerenderer.NewStringValueRenderer()
rend := textual.NewStringValueRenderer()
screens, err := rend.Format(context.Background(), protoreflect.ValueOfString(s))
require.NoError(t, err)
require.Equal(t, 1, len(screens))

View File

@ -1,4 +1,4 @@
package valuerenderer
package textual
import (
"context"

View File

@ -1,4 +1,4 @@
package valuerenderer_test
package textual_test
import (
"context"
@ -8,7 +8,7 @@ import (
"testing"
"time"
"cosmossdk.io/tx/textual/valuerenderer"
"cosmossdk.io/tx/textual"
"github.com/stretchr/testify/require"
"google.golang.org/protobuf/proto"
@ -32,7 +32,7 @@ type timestampJsonTest struct {
}
func TestTimestampJsonTestcases(t *testing.T) {
raw, err := os.ReadFile("../internal/testdata/timestamp.json")
raw, err := os.ReadFile("./internal/testdata/timestamp.json")
require.NoError(t, err)
var testcases []timestampJsonTest
@ -41,9 +41,9 @@ func TestTimestampJsonTestcases(t *testing.T) {
for i, tc := range testcases {
t.Run(fmt.Sprintf("%d", i), func(t *testing.T) {
rend := valuerenderer.NewTimestampValueRenderer()
rend := textual.NewTimestampValueRenderer()
var screens []valuerenderer.Screen
var screens []textual.Screen
if tc.Proto != nil {
screens, err = rend.Format(context.Background(), protoreflect.ValueOf(tc.Proto.ProtoReflect()))
if tc.Error {
@ -70,7 +70,7 @@ func TestTimestampJsonTestcases(t *testing.T) {
}
func TestTimestampBadFormat(t *testing.T) {
rend := valuerenderer.NewTimestampValueRenderer()
rend := textual.NewTimestampValueRenderer()
_, err := rend.Format(context.Background(), protoreflect.ValueOf(dur.New(time.Hour).ProtoReflect()))
require.Error(t, err)
}

View File

@ -1,4 +1,4 @@
package valuerenderer
package textual
import (
"bytes"

View File

@ -1,4 +1,4 @@
package valuerenderer_test
package textual_test
import (
"context"
@ -24,8 +24,8 @@ import (
_ "cosmossdk.io/api/cosmos/gov/v1"
txv1beta1 "cosmossdk.io/api/cosmos/tx/v1beta1"
"cosmossdk.io/tx/signing"
"cosmossdk.io/tx/textual"
"cosmossdk.io/tx/textual/internal/textualpb"
"cosmossdk.io/tx/textual/valuerenderer"
)
// txJsonTestTx represents the type that in the JSON test
@ -43,11 +43,11 @@ type txJsonTest struct {
SignerData json.RawMessage `json:"signer_data"`
Metadata *bankv1beta1.Metadata
Error bool
Screens []valuerenderer.Screen
Screens []textual.Screen
}
func TestTxJsonTestcases(t *testing.T) {
raw, err := os.ReadFile("../internal/testdata/tx.json")
raw, err := os.ReadFile("./internal/testdata/tx.json")
require.NoError(t, err)
var testcases []txJsonTest
@ -58,8 +58,8 @@ func TestTxJsonTestcases(t *testing.T) {
t.Run(tc.Name, func(t *testing.T) {
txBody, bodyBz, txAuthInfo, authInfoBz, signerData := createTextualData(t, tc.Proto, tc.SignerData)
tr := valuerenderer.NewTextual(mockCoinMetadataQuerier)
rend := valuerenderer.NewTxValueRenderer(&tr)
tr := textual.NewTextual(mockCoinMetadataQuerier)
rend := textual.NewTxValueRenderer(&tr)
ctx := addMetadataToContext(context.Background(), tc.Metadata)
data := &textualpb.TextualData{

View File

@ -1,4 +1,4 @@
package valuerenderer
package textual
import (
"context"

View File

@ -1,4 +1,4 @@
package valuerenderer
package textual
import (
"bytes"
@ -22,7 +22,7 @@ import (
// metadata. It is meant to be passed as an argument into `NewTextual`.
type CoinMetadataQueryFn func(ctx context.Context, denom string) (*bankv1beta1.Metadata, error)
// ValueRendererCreator is a function returning a ValueRenderer.
// ValueRendererCreator is a function returning a textual.
type ValueRendererCreator func(protoreflect.FieldDescriptor) ValueRenderer
// Textual holds the configuration for dispatching
@ -115,6 +115,10 @@ func (r *Textual) GetMessageValueRenderer(md protoreflect.MessageDescriptor) (Va
return NewMessageValueRenderer(r, md), nil
}
// init initializes Textual's internal `scalars` and `messages` registry for
// custom scalar and message renderers.
//
// It is an idempotent method.
func (r *Textual) init() {
if r.scalars == nil {
r.scalars = map[string]ValueRendererCreator{}
@ -137,6 +141,12 @@ func (r *Textual) DefineScalar(scalar string, vr ValueRendererCreator) {
r.scalars[scalar] = vr
}
// DefineMessageRenderer adds a new custom message renderer.
func (r *Textual) DefineMessageRenderer(name protoreflect.FullName, vr ValueRenderer) {
r.init()
r.messages[name] = vr
}
// GetSignBytes returns the transaction sign bytes.
func (r *Textual) GetSignBytes(ctx context.Context, bodyBz, authInfoBz []byte, signerData signing.SignerData) ([]byte, error) {
data := &textualpb.TextualData{

View File

@ -1,4 +1,4 @@
package valuerenderer_test
package textual_test
import (
"fmt"
@ -7,34 +7,34 @@ import (
"github.com/stretchr/testify/require"
"google.golang.org/protobuf/reflect/protoreflect"
"cosmossdk.io/tx/textual"
"cosmossdk.io/tx/textual/internal/testpb"
"cosmossdk.io/tx/textual/valuerenderer"
)
func TestDispatcher(t *testing.T) {
testcases := []struct {
name string
expErr bool
expValueRenderer valuerenderer.ValueRenderer
expValueRenderer textual.ValueRenderer
}{
{"UINT32", false, valuerenderer.NewIntValueRenderer(fieldDescriptorFromName("UINT32"))},
{"UINT64", false, valuerenderer.NewIntValueRenderer(fieldDescriptorFromName("UINT64"))},
{"SDKINT", false, valuerenderer.NewIntValueRenderer(fieldDescriptorFromName("SDKINT"))},
{"SDKDEC", false, valuerenderer.NewDecValueRenderer()},
{"BYTES", false, valuerenderer.NewBytesValueRenderer()},
{"TIMESTAMP", false, valuerenderer.NewTimestampValueRenderer()},
{"DURATION", false, valuerenderer.NewDurationValueRenderer()},
{"COIN", false, valuerenderer.NewCoinsValueRenderer(nil)},
{"COINS", false, valuerenderer.NewCoinsValueRenderer(nil)},
{"ENUM", false, valuerenderer.NewEnumValueRenderer(fieldDescriptorFromName("ENUM"))},
{"ANY", false, valuerenderer.NewAnyValueRenderer(nil)},
{"UINT32", false, textual.NewIntValueRenderer(fieldDescriptorFromName("UINT32"))},
{"UINT64", false, textual.NewIntValueRenderer(fieldDescriptorFromName("UINT64"))},
{"SDKINT", false, textual.NewIntValueRenderer(fieldDescriptorFromName("SDKINT"))},
{"SDKDEC", false, textual.NewDecValueRenderer()},
{"BYTES", false, textual.NewBytesValueRenderer()},
{"TIMESTAMP", false, textual.NewTimestampValueRenderer()},
{"DURATION", false, textual.NewDurationValueRenderer()},
{"COIN", false, textual.NewCoinsValueRenderer(nil)},
{"COINS", false, textual.NewCoinsValueRenderer(nil)},
{"ENUM", false, textual.NewEnumValueRenderer(fieldDescriptorFromName("ENUM"))},
{"ANY", false, textual.NewAnyValueRenderer(nil)},
{"FLOAT", true, nil},
}
for _, tc := range testcases {
tc := tc
t.Run(tc.name, func(t *testing.T) {
textual := valuerenderer.NewTextual(nil)
textual := textual.NewTextual(nil)
rend, err := textual.GetFieldValueRenderer(fieldDescriptorFromName(tc.name))
if tc.expErr {