| /* | |
| * | |
| * Copyright 2026 gRPC authors. | |
| * | |
| * Licensed under the Apache License, Version 2.0 (the "License"); | |
| * you may not use this file except in compliance with the License. | |
| * You may obtain a copy of the License at | |
| * | |
| * http://www.apache.org/licenses/LICENSE-2.0 | |
| * | |
| * Unless required by applicable law or agreed to in writing, software | |
| * distributed under the License is distributed on an "AS IS" BASIS, | |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| * See the License for the specific language governing permissions and | |
| * limitations under the License. | |
| * | |
| */ | |
| package optional_test | |
| import ( | |
| "slices" | |
| "testing" | |
| "google.golang.org/grpc/internal/grpctest" | |
| "google.golang.org/grpc/internal/optional" | |
| ) | |
| type s struct { | |
| grpctest.Tester | |
| } | |
| func Test(t *testing.T) { | |
| grpctest.RunSubTests(t, s{}) | |
| } | |
| // TestOptionalInt tests the scenario of using integer optional values and | |
| // verifies that zero value, constructors, and mutation methods return correct | |
| // outputs. | |
| func (s) TestOptionalInt(t *testing.T) { | |
| var opt optional.Optional[int] | |
| // Test unset value. | |
| if v, set := opt.Value(); set || v != 0 { | |
| t.Fatalf("Zero-value Option[int] = (%v, %v); want (0, false)", v, set) | |
| } | |
| opt = optional.New(42) | |
| if v, set := opt.Value(); !set || v != 42 { | |
| t.Fatalf("NewValue(42) = (%v, %v); want (42, true)", v, set) | |
| } | |
| opt.SetValue(100) | |
| if v, set := opt.Value(); !set || v != 100 { | |
| t.Fatalf("Set(100) = (%v, %v); want (100, true)", v, set) | |
| } | |
| } | |
| // TestOptionalString tests the scenario of using string optional values and | |
| // verifies that zero value, constructors, and mutation methods return correct | |
| // outputs. | |
| func (s) TestOptionalString(t *testing.T) { | |
| var opt optional.Optional[string] | |
| // Test unset value. | |
| if v, set := opt.Value(); set || v != "" { | |
| t.Fatalf("Zero-value Option[string] = (%q, %v); want (%q, false)", v, set, "") | |
| } | |
| wantString := "test-string" | |
| opt = optional.New(wantString) | |
| if v, set := opt.Value(); !set || v != wantString { | |
| t.Fatalf("NewValue(%q) = (%q, %v); want (%q, true)", wantString, v, set, wantString) | |
| } | |
| wantStringNew := "world" | |
| opt.SetValue(wantStringNew) | |
| if v, set := opt.Value(); !set || v != wantStringNew { | |
| t.Fatalf("Set(%q) = (%q, %v); want (%q, true)", wantStringNew, v, set, wantStringNew) | |
| } | |
| } | |
| // TestOptionalStruct tests the scenario of using a custom struct optional value | |
| // and verifies that custom struct field values are preserved, modified, and | |
| // cleared correctly. | |
| func (s) TestOptionalStruct(t *testing.T) { | |
| type testStruct struct { | |
| name string | |
| age int | |
| } | |
| var opt optional.Optional[testStruct] | |
| if v, set := opt.Value(); set || v != (testStruct{}) { | |
| t.Fatalf("Zero-value Option[struct] = (%v, %v); want (empty, false)", v, set) | |
| } | |
| want := testStruct{name: "Alice", age: 30} | |
| opt = optional.New(want) | |
| if v, set := opt.Value(); !set || v != want { | |
| t.Fatalf("NewValue(%v) = (%v, %v); want (%v, true)", want, v, set, want) | |
| } | |
| want2 := testStruct{name: "Bob", age: 40} | |
| opt.SetValue(want2) | |
| if v, set := opt.Value(); !set || v != want2 { | |
| t.Fatalf("Set(%v) = (%v, %v); want (%v, true)", want2, v, set, want2) | |
| } | |
| } | |
| // TestOptionalSlice tests the scenario of using a slice optional value and | |
| // verifies that zero value, constructors, and mutation methods return correct | |
| // outputs. | |
| func (s) TestOptionalSlice(t *testing.T) { | |
| var opt optional.Optional[[]int] | |
| if v, set := opt.Value(); set || v != nil { | |
| t.Fatalf("Zero-value Option[[]int] = (%v, %v); want (nil, false)", v, set) | |
| } | |
| want := []int{1, 2, 3} | |
| opt = optional.New(want) | |
| if v, set := opt.Value(); !set || !slices.Equal(v, want) { | |
| t.Fatalf("NewValue(%v) = (%v, %v); want (%v, true)", want, v, set, want) | |
| } | |
| want2 := []int{4, 5, 6} | |
| opt.SetValue(want2) | |
| if v, set := opt.Value(); !set || !slices.Equal(v, want2) { | |
| t.Fatalf("Set(%v) = (%v, %v); want (%v, true)", &want2, v, set, &want2) | |
| } | |
| } |