protobuf-go/proto/oneof_get_test.go
Michael Stapelberg eb7b468655 all: Release the Opaque API
For golang/protobuf#1657

Change-Id: I7b2b0c30506706015ce278e6054439c9ad9ef727
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/634815
TryBot-Bypass: Michael Stapelberg <stapelberg@google.com>
Reviewed-by: Joseph Tsai <joetsai@digital-static.net>
Reviewed-by: Damien Neil <dneil@google.com>
2024-12-11 03:16:51 -08:00

274 lines
9.2 KiB
Go

// Copyright 2024 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 proto_test
import (
"testing"
testhybridpb "google.golang.org/protobuf/internal/testprotos/testeditions/testeditions_hybrid"
testopaquepb "google.golang.org/protobuf/internal/testprotos/testeditions/testeditions_opaque"
)
func expectPanic(t *testing.T, f func(), fmt string, a ...any) {
t.Helper()
defer func() {
t.Helper()
if r := recover(); r == nil {
t.Errorf(fmt, a...)
}
}()
f()
}
func TestOpenGet(t *testing.T) {
x := &testhybridpb.TestAllTypes{}
tab := []struct {
fName string // Field name (in proto)
set func() // Set the field
clear func() // Clear the field
has func() bool // Has for the field
isZero func() bool // Get and return true if zero value
}{
{
fName: "oneof_uint32",
set: func() { x.SetOneofUint32(47) },
clear: func() { x.ClearOneofUint32() },
has: func() bool { return x.HasOneofUint32() },
isZero: func() bool { return x.GetOneofUint32() == 0 },
},
{
fName: "oneof_nested_message",
set: func() { x.SetOneofNestedMessage(&testhybridpb.TestAllTypes_NestedMessage{}) },
clear: func() { x.ClearOneofNestedMessage() },
has: func() bool { return x.HasOneofNestedMessage() },
isZero: func() bool { return x.GetOneofNestedMessage() == nil },
},
{
fName: "oneof_string",
set: func() { x.SetOneofString("test") },
clear: func() { x.ClearOneofString() },
has: func() bool { return x.HasOneofString() },
isZero: func() bool { return x.GetOneofString() == "" },
},
{
fName: "oneof_bytes",
set: func() { x.SetOneofBytes([]byte("test")) },
clear: func() { x.ClearOneofBytes() },
has: func() bool { return x.HasOneofBytes() },
isZero: func() bool { return len(x.GetOneofBytes()) == 0 },
},
{
fName: "oneof_bool",
set: func() { x.SetOneofBool(true) },
clear: func() { x.ClearOneofBool() },
has: func() bool { return x.HasOneofBool() },
isZero: func() bool { return x.GetOneofBool() == false },
},
{
fName: "oneof_uint64",
set: func() { x.SetOneofUint64(7438109473104) },
clear: func() { x.ClearOneofUint64() },
has: func() bool { return x.HasOneofUint64() },
isZero: func() bool { return x.GetOneofUint64() == 0 },
},
{
fName: "oneof_float",
set: func() { x.SetOneofFloat(3.1415) },
clear: func() { x.ClearOneofFloat() },
has: func() bool { return x.HasOneofFloat() },
isZero: func() bool { return x.GetOneofFloat() == 0.0 },
},
{
fName: "oneof_double",
set: func() { x.SetOneofDouble(3e+8) },
clear: func() { x.ClearOneofDouble() },
has: func() bool { return x.HasOneofDouble() },
isZero: func() bool { return x.GetOneofDouble() == 0.0 },
},
{
fName: "oneof_enum",
set: func() { x.SetOneofEnum(testhybridpb.TestAllTypes_BAZ) },
clear: func() { x.ClearOneofEnum() },
has: func() bool { return x.HasOneofEnum() },
isZero: func() bool { return x.GetOneofEnum() == 0 },
},
}
for i, mv := range tab {
x.ClearOneofField()
if got, want := x.HasOneofField(), false; got != want {
t.Errorf("HasOneofField returned %v, expected %v", got, want)
}
if got, want := mv.isZero(), true; got != want {
t.Errorf("Get on empty oneof member did not return zero value, got %v, expected %v (%s)", got, want, mv.fName)
}
mv.set()
if got, want := x.HasOneofField(), true; got != want {
t.Errorf("HasOneofField returned %v, expected %v (%s)", got, want, mv.fName)
}
if got, want := mv.isZero(), false; got != want {
t.Errorf("Get on non-empty oneof member did return zero value, got %v, expected %v (%s)", got, want, mv.fName)
}
mv.clear()
if got, want := x.HasOneofField(), false; got != want {
t.Errorf("HasOneofField returned %v, expected %v (%s)", got, want, mv.fName)
}
if got, want := mv.isZero(), true; got != want {
t.Errorf("Get on empty oneof member did not return zero value, got %v, expected %v (%s)", got, want, mv.fName)
}
other := tab[(i+1)%len(tab)]
mv.set()
other.set()
if got, want := x.HasOneofField(), true; got != want {
t.Errorf("HasOneofField returned %v, expected %v (%s)", got, want, mv.fName)
}
if got, want := mv.isZero(), true; got != want {
t.Errorf("Get on wrong oneof member did not return zero value, got %v, expected %v (%s)", got, want, mv.fName)
}
other.clear()
if got, want := x.HasOneofField(), false; got != want {
t.Errorf("HasOneofField returned %v, expected %v (%s)", got, want, mv.fName)
}
}
x = nil
for _, mv := range tab {
if got, want := mv.isZero(), true; got != want {
t.Errorf("Get on nil receiver did not return zero value, got %v, expected %v (%s)", got, want, mv.fName)
}
if got, want := mv.has(), false; got != want {
t.Errorf("Has on nil receiver failed, got %v, expected %v (%s)", got, want, mv.fName)
}
}
}
func TestOpaqueGet(t *testing.T) {
x := &testopaquepb.TestAllTypes{}
tab := []struct {
fName string // Field name (in proto)
set func() // Set the field
clear func() // Clear the field
has func() bool // Has for the field
isZero func() bool // Get and return true if zero value
}{
{
fName: "oneof_uint32",
set: func() { x.SetOneofUint32(47) },
clear: func() { x.ClearOneofUint32() },
has: func() bool { return x.HasOneofUint32() },
isZero: func() bool { return x.GetOneofUint32() == 0 },
},
{
fName: "oneof_nested_message",
set: func() { x.SetOneofNestedMessage(&testopaquepb.TestAllTypes_NestedMessage{}) },
clear: func() { x.ClearOneofNestedMessage() },
has: func() bool { return x.HasOneofNestedMessage() },
isZero: func() bool { return x.GetOneofNestedMessage() == nil },
},
{
fName: "oneof_string",
set: func() { x.SetOneofString("test") },
clear: func() { x.ClearOneofString() },
has: func() bool { return x.HasOneofString() },
isZero: func() bool { return x.GetOneofString() == "" },
},
{
fName: "oneof_bytes",
set: func() { x.SetOneofBytes([]byte("test")) },
clear: func() { x.ClearOneofBytes() },
has: func() bool { return x.HasOneofBytes() },
isZero: func() bool { return len(x.GetOneofBytes()) == 0 },
},
{
fName: "oneof_bool",
set: func() { x.SetOneofBool(true) },
clear: func() { x.ClearOneofBool() },
has: func() bool { return x.HasOneofBool() },
isZero: func() bool { return x.GetOneofBool() == false },
},
{
fName: "oneof_uint64",
set: func() { x.SetOneofUint64(7438109473104) },
clear: func() { x.ClearOneofUint64() },
has: func() bool { return x.HasOneofUint64() },
isZero: func() bool { return x.GetOneofUint64() == 0 },
},
{
fName: "oneof_float",
set: func() { x.SetOneofFloat(3.1415) },
clear: func() { x.ClearOneofFloat() },
has: func() bool { return x.HasOneofFloat() },
isZero: func() bool { return x.GetOneofFloat() == 0.0 },
},
{
fName: "oneof_double",
set: func() { x.SetOneofDouble(3e+8) },
clear: func() { x.ClearOneofDouble() },
has: func() bool { return x.HasOneofDouble() },
isZero: func() bool { return x.GetOneofDouble() == 0.0 },
},
{
fName: "oneof_enum",
set: func() { x.SetOneofEnum(testopaquepb.TestAllTypes_BAZ) },
clear: func() { x.ClearOneofEnum() },
has: func() bool { return x.HasOneofEnum() },
isZero: func() bool { return x.GetOneofEnum() == 0 },
},
}
for i, mv := range tab {
x.ClearOneofField()
if got, want := x.HasOneofField(), false; got != want {
t.Errorf("HasOneofField returned %v, expected %v", got, want)
}
if got, want := mv.isZero(), true; got != want {
t.Errorf("Get on empty oneof member did not return zero value, got %v, expected %v (%s)", got, want, mv.fName)
}
mv.set()
if got, want := x.HasOneofField(), true; got != want {
t.Errorf("HasOneofField returned %v, expected %v (%s)", got, want, mv.fName)
}
if got, want := mv.isZero(), false; got != want {
t.Errorf("Get on non-empty oneof member did return zero value, got %v, expected %v (%s)", got, want, mv.fName)
}
mv.clear()
if got, want := x.HasOneofField(), false; got != want {
t.Errorf("HasOneofField returned %v, expected %v (%s)", got, want, mv.fName)
}
if got, want := mv.isZero(), true; got != want {
t.Errorf("Get on empty oneof member did not return zero value, got %v, expected %v (%s)", got, want, mv.fName)
}
other := tab[(i+1)%len(tab)]
mv.set()
other.set()
if got, want := x.HasOneofField(), true; got != want {
t.Errorf("HasOneofField returned %v, expected %v (%s)", got, want, mv.fName)
}
if got, want := mv.isZero(), true; got != want {
t.Errorf("Get on wrong oneof member did not return zero value, got %v, expected %v (%s)", got, want, mv.fName)
}
other.clear()
if got, want := x.HasOneofField(), false; got != want {
t.Errorf("HasOneofField returned %v, expected %v (%s)", got, want, mv.fName)
}
}
x = nil
for _, mv := range tab {
if got, want := mv.isZero(), true; got != want {
t.Errorf("Get on nil receiver did not return zero value, got %v, expected %v (%s)", got, want, mv.fName)
}
if got, want := mv.has(), false; got != want {
t.Errorf("Has on nil receiver failed, got %v, expected %v (%s)", got, want, mv.fName)
}
}
}