mirror of
https://github.com/protocolbuffers/protobuf-go.git
synced 2025-01-01 03:14:16 +00:00
e62d8edb75
protoreflect (as pref) and protoiface (as piface) are imported duplicates in some files. Respect package name, remove unnecessary aliased import statements. Change-Id: Ie9897f17a50d19a462035964e366af72afed0e4d Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/405694 Reviewed-by: Kirill Kolyshkin <kolyshkin@gmail.com> Reviewed-by: Lasse Folger <lassefolger@google.com> Reviewed-by: Damien Neil <dneil@google.com>
175 lines
5.0 KiB
Go
175 lines
5.0 KiB
Go
// 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 order
|
|
|
|
import (
|
|
"math/rand"
|
|
"sort"
|
|
"testing"
|
|
|
|
"github.com/google/go-cmp/cmp"
|
|
"google.golang.org/protobuf/reflect/protoreflect"
|
|
)
|
|
|
|
type fieldDesc struct {
|
|
index int
|
|
name protoreflect.FullName
|
|
number protoreflect.FieldNumber
|
|
extension bool
|
|
oneofIndex int // non-zero means within oneof; negative means synthetic
|
|
protoreflect.FieldDescriptor
|
|
}
|
|
|
|
func (d fieldDesc) Index() int { return d.index }
|
|
func (d fieldDesc) Name() protoreflect.Name { return d.name.Name() }
|
|
func (d fieldDesc) FullName() protoreflect.FullName { return d.name }
|
|
func (d fieldDesc) Number() protoreflect.FieldNumber { return d.number }
|
|
func (d fieldDesc) IsExtension() bool { return d.extension }
|
|
func (d fieldDesc) ContainingOneof() protoreflect.OneofDescriptor {
|
|
switch {
|
|
case d.oneofIndex < 0:
|
|
return oneofDesc{index: -d.oneofIndex, synthetic: true}
|
|
case d.oneofIndex > 0:
|
|
return oneofDesc{index: +d.oneofIndex, synthetic: false}
|
|
default:
|
|
return nil
|
|
}
|
|
}
|
|
|
|
type oneofDesc struct {
|
|
index int
|
|
synthetic bool
|
|
protoreflect.OneofDescriptor
|
|
}
|
|
|
|
func (d oneofDesc) Index() int { return d.index }
|
|
func (d oneofDesc) IsSynthetic() bool { return d.synthetic }
|
|
|
|
func TestFieldOrder(t *testing.T) {
|
|
tests := []struct {
|
|
label string
|
|
order FieldOrder
|
|
fields []fieldDesc
|
|
}{{
|
|
label: "LegacyFieldOrder",
|
|
order: LegacyFieldOrder,
|
|
fields: []fieldDesc{
|
|
// Extension fields sorted first by field number.
|
|
{number: 2, extension: true},
|
|
{number: 4, extension: true},
|
|
{number: 100, extension: true},
|
|
{number: 120, extension: true},
|
|
|
|
// Non-extension fields that are not within a oneof
|
|
// sorted next by field number.
|
|
{number: 1},
|
|
{number: 5, oneofIndex: -9}, // synthetic oneof
|
|
{number: 10},
|
|
{number: 11, oneofIndex: -10}, // synthetic oneof
|
|
{number: 12},
|
|
|
|
// Non-synthetic oneofs sorted last by index.
|
|
{number: 13, oneofIndex: 4},
|
|
{number: 3, oneofIndex: 5},
|
|
{number: 9, oneofIndex: 5},
|
|
{number: 7, oneofIndex: 8},
|
|
},
|
|
}, {
|
|
label: "NumberFieldOrder",
|
|
order: NumberFieldOrder,
|
|
fields: []fieldDesc{
|
|
{number: 1, index: 5, name: "c"},
|
|
{number: 2, index: 2, name: "b"},
|
|
{number: 3, index: 3, name: "d"},
|
|
{number: 5, index: 1, name: "a"},
|
|
{number: 7, index: 7, name: "e"},
|
|
},
|
|
}, {
|
|
label: "IndexNameFieldOrder",
|
|
order: IndexNameFieldOrder,
|
|
fields: []fieldDesc{
|
|
// Non-extension fields sorted first by index.
|
|
{index: 0, number: 5, name: "c"},
|
|
{index: 2, number: 2, name: "a"},
|
|
{index: 4, number: 4, name: "b"},
|
|
{index: 7, number: 6, name: "d"},
|
|
|
|
// Extension fields sorted last by full name.
|
|
{index: 3, number: 1, name: "d.a", extension: true},
|
|
{index: 5, number: 3, name: "e", extension: true},
|
|
{index: 1, number: 7, name: "g", extension: true},
|
|
},
|
|
}}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.label, func(t *testing.T) {
|
|
want := tt.fields
|
|
got := append([]fieldDesc(nil), want...)
|
|
for i, j := range rand.Perm(len(got)) {
|
|
got[i], got[j] = got[j], got[i]
|
|
}
|
|
sort.Slice(got, func(i, j int) bool {
|
|
return tt.order(got[i], got[j])
|
|
})
|
|
if diff := cmp.Diff(want, got,
|
|
cmp.Comparer(func(x, y fieldDesc) bool { return x == y }),
|
|
); diff != "" {
|
|
t.Errorf("order mismatch (-want +got):\n%s", diff)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestKeyOrder(t *testing.T) {
|
|
tests := []struct {
|
|
label string
|
|
order KeyOrder
|
|
keys []interface{}
|
|
}{{
|
|
label: "GenericKeyOrder",
|
|
order: GenericKeyOrder,
|
|
keys: []interface{}{false, true},
|
|
}, {
|
|
label: "GenericKeyOrder",
|
|
order: GenericKeyOrder,
|
|
keys: []interface{}{int32(-100), int32(-99), int32(-10), int32(-9), int32(-1), int32(0), int32(+1), int32(+9), int32(+10), int32(+99), int32(+100)},
|
|
}, {
|
|
label: "GenericKeyOrder",
|
|
order: GenericKeyOrder,
|
|
keys: []interface{}{int64(-100), int64(-99), int64(-10), int64(-9), int64(-1), int64(0), int64(+1), int64(+9), int64(+10), int64(+99), int64(+100)},
|
|
}, {
|
|
label: "GenericKeyOrder",
|
|
order: GenericKeyOrder,
|
|
keys: []interface{}{uint32(0), uint32(1), uint32(9), uint32(10), uint32(99), uint32(100)},
|
|
}, {
|
|
label: "GenericKeyOrder",
|
|
order: GenericKeyOrder,
|
|
keys: []interface{}{uint64(0), uint64(1), uint64(9), uint64(10), uint64(99), uint64(100)},
|
|
}, {
|
|
label: "GenericKeyOrder",
|
|
order: GenericKeyOrder,
|
|
keys: []interface{}{"", "a", "aa", "ab", "ba", "bb", "\u0080", "\u0080\u0081", "\u0082\u0080"},
|
|
}}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.label, func(t *testing.T) {
|
|
var got, want []protoreflect.MapKey
|
|
for _, v := range tt.keys {
|
|
want = append(want, protoreflect.ValueOf(v).MapKey())
|
|
}
|
|
got = append(got, want...)
|
|
for i, j := range rand.Perm(len(got)) {
|
|
got[i], got[j] = got[j], got[i]
|
|
}
|
|
sort.Slice(got, func(i, j int) bool {
|
|
return tt.order(got[i], got[j])
|
|
})
|
|
if diff := cmp.Diff(want, got, cmp.Transformer("", protoreflect.MapKey.Interface)); diff != "" {
|
|
t.Errorf("order mismatch (-want +got):\n%s", diff)
|
|
}
|
|
})
|
|
}
|
|
}
|