Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 47 additions & 0 deletions internal/sidekick/swift/generate_enum_swift_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"path/filepath"
"testing"

"github.com/google/go-cmp/cmp"
"github.com/googleapis/librarian/internal/sidekick/api"
"github.com/googleapis/librarian/internal/sidekick/parser"
)
Expand Down Expand Up @@ -68,3 +69,49 @@ func TestGenerateEnum_Files(t *testing.T) {
}
}
}

func TestGenerateEnum_DocComments(t *testing.T) {
outDir := t.TempDir()

color := &api.Enum{
Name: "Color",
Package: "google.cloud.test.v1",
ID: ".google.cloud.test.v1.Color",
Documentation: "Documentation for the Color enum.",
}
color.Values = []*api.EnumValue{
{
Name: "COLOR_UNSPECIFIED",
Number: 0,
Parent: color,
Documentation: "Documentation for the COLOR_UNSPECIFIED value.",
},
}
color.UniqueNumberValues = color.Values

model := api.NewTestAPI([]*api.Message{}, []*api.Enum{color}, []*api.Service{})
model.PackageName = "google.cloud.test.v1"
cfg := &parser.ModelConfig{}
if err := Generate(t.Context(), model, outDir, cfg, nil); err != nil {
t.Fatal(err)
}

filename := filepath.Join(outDir, "Sources", "GoogleCloudTestV1", "Color.swift")
content, err := os.ReadFile(filename)
if err != nil {
t.Fatal(err)
}
contentStr := string(content)

want := "/// Documentation for the Color enum.\npublic enum Color"
got := extractBlock(t, contentStr, "/// Documentation for the Color enum.", "public enum Color")
if diff := cmp.Diff(want, got); diff != "" {
t.Errorf("mismatch (-want +got):\n%s", diff)
}

want = "/// Documentation for the COLOR_UNSPECIFIED value.\n case unspecified"
got = extractBlock(t, contentStr, "/// Documentation for the COLOR_UNSPECIFIED value.", "case unspecified")
if diff := cmp.Diff(want, got); diff != "" {
t.Errorf("mismatch (-want +got):\n%s", diff)
}
}
70 changes: 70 additions & 0 deletions internal/sidekick/swift/generate_field_swift_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,3 +87,73 @@ func TestGenerateField_InitFromDecoder(t *testing.T) {
t.Errorf("mismatch (-want +got):\n%s", diff)
}
}

func TestGenerateField_DocComments(t *testing.T) {
outDir := t.TempDir()

field1 := &api.Field{
Name: "normal_field",
Documentation: "Documentation for normal_field.",
ID: ".google.cloud.test.v1.TestMessage.normal_field",
Typez: api.TypezString,
}

field2 := &api.Field{
Name: "oneof_field",
Documentation: "Documentation for oneof_field.",
ID: ".google.cloud.test.v1.TestMessage.oneof_field",
Typez: api.TypezString,
IsOneOf: true,
}

oneof := &api.OneOf{
Name: "my_oneof",
Documentation: "Documentation for my_oneof.",
Fields: []*api.Field{field2},
}
field2.Group = oneof

msg := &api.Message{
Name: "TestMessage",
Package: "google.cloud.test.v1",
ID: ".google.cloud.test.v1.TestMessage",
Fields: []*api.Field{field1, field2},
OneOfs: []*api.OneOf{oneof},
}

model := api.NewTestAPI([]*api.Message{msg}, []*api.Enum{}, []*api.Service{})
model.PackageName = "google.cloud.test.v1"
cfg := &parser.ModelConfig{}

if err := Generate(t.Context(), model, outDir, cfg, nil); err != nil {
t.Fatal(err)
}

filename := filepath.Join(outDir, "Sources", "GoogleCloudTestV1", "TestMessage.swift")
content, err := os.ReadFile(filename)
if err != nil {
t.Fatal(err)
}
contentStr := string(content)

// Verify normal field documentation
want := " /// Documentation for normal_field.\n public var normalField: Swift.String"
got := extractBlock(t, contentStr, " /// Documentation for normal_field.", "public var normalField: Swift.String")
if diff := cmp.Diff(want, got); diff != "" {
t.Errorf("mismatch (-want +got):\n%s", diff)
}

// Verify oneof documentation in the message
want = " /// Documentation for my_oneof.\n public var myOneof: OneOf_MyOneof?"
got = extractBlock(t, contentStr, " /// Documentation for my_oneof.", "public var myOneof: OneOf_MyOneof?")
if diff := cmp.Diff(want, got); diff != "" {
t.Errorf("mismatch (-want +got):\n%s", diff)
}

// Verify field documentation in the oneof enum
want = " /// Documentation for oneof_field.\n case oneofField(Swift.String)"
got = extractBlock(t, contentStr, " /// Documentation for oneof_field.", "case oneofField(Swift.String)")
if diff := cmp.Diff(want, got); diff != "" {
t.Errorf("mismatch (-want +got):\n%s", diff)
}
}
47 changes: 47 additions & 0 deletions internal/sidekick/swift/generate_message_swift_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -504,3 +504,50 @@ func TestGenerateMessage_RecursiveChain(t *testing.T) {
t.Errorf("nodeA initializer mismatch: want %q; got:\n%s", wantInitC, contentStrC)
}
}

func TestGenerateMessage_DocComments(t *testing.T) {
outDir := t.TempDir()

nested := &api.Message{
Name: "NestedMessage",
Package: "google.cloud.test.v1",
ID: ".google.cloud.test.v1.TestMessage.NestedMessage",
Documentation: "Documentation for NestedMessage.",
}
msg := &api.Message{
Name: "TestMessage",
Package: "google.cloud.test.v1",
ID: ".google.cloud.test.v1.TestMessage",
Documentation: "Documentation for TestMessage.",
Messages: []*api.Message{nested},
}

model := api.NewTestAPI([]*api.Message{msg}, []*api.Enum{}, []*api.Service{})
model.PackageName = "google.cloud.test.v1"
cfg := &parser.ModelConfig{}

if err := Generate(t.Context(), model, outDir, cfg, swiftConfig(t, nil)); err != nil {
t.Fatal(err)
}

filename := filepath.Join(outDir, "Sources", "GoogleCloudTestV1", "TestMessage.swift")
content, err := os.ReadFile(filename)
if err != nil {
t.Fatal(err)
}
contentStr := string(content)

// Verify top-level message documentation
want := "/// Documentation for TestMessage.\npublic struct TestMessage"
got := extractBlock(t, contentStr, "/// Documentation for TestMessage.", "public struct TestMessage")
if diff := cmp.Diff(want, got); diff != "" {
t.Errorf("mismatch (-want +got):\n%s", diff)
}

// Verify nested message documentation
want = " /// Documentation for NestedMessage.\n public struct NestedMessage"
got = extractBlock(t, contentStr, " /// Documentation for NestedMessage.", "public struct NestedMessage")
if diff := cmp.Diff(want, got); diff != "" {
t.Errorf("mismatch (-want +got):\n%s", diff)
}
}
108 changes: 108 additions & 0 deletions internal/sidekick/swift/generate_service_comments_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
// Copyright 2026 Google LLC
//
// 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
//
// https://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 swift
Comment thread
coryan marked this conversation as resolved.

import (
"os"
"path/filepath"
"testing"

"github.com/google/go-cmp/cmp"
"github.com/googleapis/librarian/internal/sidekick/api"
"github.com/googleapis/librarian/internal/sidekick/parser"
)

func TestGenerateService_DocComments(t *testing.T) {
outDir := t.TempDir()

req := &api.Message{
Name: "GetSecretRequest",
Package: "google.cloud.test.v1",
ID: ".google.cloud.test.v1.GetSecretRequest",
Fields: []*api.Field{
{
Name: "project",
ID: ".google.cloud.test.v1.GetSecretRequest.project",
Typez: api.TypezString,
},
{
Name: "secret",
ID: ".google.cloud.test.v1.GetSecretRequest.secret",
Typez: api.TypezString,
},
},
}
req.Fields[0].Parent = req
req.Fields[1].Parent = req
res := &api.Message{
Name: "Secret",
Package: "google.cloud.test.v1",
ID: ".google.cloud.test.v1.Secret",
}

method := &api.Method{
Name: "GetSecret",
Documentation: "Documentation for GetSecret method.",
InputTypeID: req.ID,
OutputTypeID: res.ID,
InputType: req,
OutputType: res,
PathInfo: &api.PathInfo{
Bindings: []*api.PathBinding{
{
Verb: "GET",
PathTemplate: (&api.PathTemplate{}).WithLiteral("v1").WithLiteral("projects").WithVariableNamed("project").WithLiteral("secrets").WithVariableNamed("secret"),
},
},
},
}

service := &api.Service{
Name: "SecretManager",
Package: "google.cloud.test.v1",
Documentation: "Documentation for SecretManager service.",
Methods: []*api.Method{method},
}
method.Service = service

model := api.NewTestAPI([]*api.Message{req, res}, []*api.Enum{}, []*api.Service{service})
model.PackageName = "google.cloud.test.v1"
cfg := &parser.ModelConfig{}

if err := Generate(t.Context(), model, outDir, cfg, swiftConfig(t, nil)); err != nil {
t.Fatal(err)
}

filename := filepath.Join(outDir, "Sources", "GoogleCloudTestV1", "SecretManager.swift")
content, err := os.ReadFile(filename)
if err != nil {
t.Fatal(err)
}
contentStr := string(content)

// Verify service documentation
want := "/// Documentation for SecretManager service.\n///\n/// @Snippet(path: \"SecretManagerQuickstart\")\npublic class SecretManagerClient"
got := extractBlock(t, contentStr, "/// Documentation for SecretManager service.", "public class SecretManagerClient")
if diff := cmp.Diff(want, got); diff != "" {
t.Errorf("mismatch (-want +got):\n%s", diff)
}

// Verify method documentation
want = " /// Documentation for GetSecret method.\n ///\n /// @Snippet(path: \"SecretManager_GetSecret\")\n public func getSecret"
got = extractBlock(t, contentStr, " /// Documentation for GetSecret method.", "public func getSecret")
if diff := cmp.Diff(want, got); diff != "" {
t.Errorf("mismatch (-want +got):\n%s", diff)
}
}
4 changes: 2 additions & 2 deletions internal/sidekick/swift/templates/common/enum.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ limitations under the License.
{{/Codec.DocLines}}
public enum {{Codec.Name}}: Codable, Equatable, Sendable {
{{#UniqueNumberValues}}
{{#DocLines}}
{{#Codec.DocLines}}
/// {{{.}}}
{{/DocLines}}
{{/Codec.DocLines}}
case {{Codec.CaseName}}
{{/UniqueNumberValues}}
/// Encodes an unknown integer value.
Expand Down
Loading