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
Original file line number Diff line number Diff line change
Expand Up @@ -54,20 +54,20 @@ exports[`Snippets > 'enum (optional)' 1`] = `
"package example

import (
acme "github.com/acme/acme-go"
acmego "github.com/acme/acme-go"
)

var value = acme.StatusDeactivated.Ptr()"
var value = acmego.StatusDeactivated.Ptr()"
`;

exports[`Snippets > 'enum (required)' 1`] = `
"package example

import (
acme "github.com/acme/acme-go"
acmego "github.com/acme/acme-go"
)

var value = acme.StatusActivated"
var value = acmego.StatusActivated"
`;

exports[`Snippets > 'map (empty)' 1`] = `
Expand All @@ -80,14 +80,14 @@ exports[`Snippets > 'map (nested)' 1`] = `
"package example

import (
acme "github.com/acme/acme-go"
acmego "github.com/acme/acme-go"
)

var value = map[string]acme.User{
"john": acme.User{
var value = map[string]acmego.User{
"john": acmego.User{
Name: "John Doe",
},
"jane": acme.User{
"jane": acmego.User{
Name: "Jane Doe",
},
}"
Expand Down Expand Up @@ -151,30 +151,30 @@ exports[`Snippets > 'struct (empty)' 1`] = `
"package example

import (
acme "github.com/acme/acme-go"
acmego "github.com/acme/acme-go"
)

var value = acme.User{}"
var value = acmego.User{}"
`;

exports[`Snippets > 'struct (nested)' 1`] = `
"package example

import (
acme "github.com/acme/acme-go"
acmego "github.com/acme/acme-go"
billing "github.com/acme/acme-go/billing"
uuid "github.com/google/uuid"
)

var value = acme.User{
var value = acmego.User{
Name: "John Doe",
Address: billing.Address{
ID: uuid.MustParse(
"123e4567-e89b-12d3-a456-426614174000",
),
Street: "123 Main St.",
CreatedAt: acme.Time(
acme.MustParseDateTime(
CreatedAt: acmego.Time(
acmego.MustParseDateTime(
"1994-01-01T00:00:00Z",
),
),
Expand All @@ -186,13 +186,13 @@ exports[`Snippets > 'struct (primitives)' 1`] = `
"package example

import (
acme "github.com/acme/acme-go"
acmego "github.com/acme/acme-go"
)

var value = acme.User{
var value = acmego.User{
Name: "John Doe",
Age: 42,
Active: acme.Bool(
Active: acmego.Bool(
true,
),
}"
Expand All @@ -202,10 +202,10 @@ exports[`Snippets > 'struct (w/ nop)' 1`] = `
"package example

import (
acme "github.com/acme/acme-go"
acmego "github.com/acme/acme-go"
)

var value = acme.User{
var value = acmego.User{
Name: "John Doe",
Age: 42,
}"
Expand Down
2 changes: 1 addition & 1 deletion generators/go-v2/ast/src/ast/core/Writer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,6 @@ export class Writer extends AbstractWriter {
if (split[0] == null) {
return s;
}
return split[0].replace(INVALID_GO_IDENTIFIER_TOKEN, "");
return split.map((part) => part.replace(INVALID_GO_IDENTIFIER_TOKEN, "")).join("");
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't have go-wiremock alias as go

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess we do need to be careful that this is not breaking behavior for package consumers.

But I don't think it is since it's just changing the alias we use in generated files, it isn't actual changing package names that the consumer might try to import and use without aliasing. But double check me on that!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yea as this is a writer change can this impact any other code generation parts?

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ export const baseGoCustomConfigSchema = z.object({
union: z.enum(["v0", "v1"]).optional(),
useReaderForBytesRequest: z.boolean().optional(),
useDefaultRequestParameterValues: z.boolean().optional(),
gettersPassByValue: z.boolean().optional()
gettersPassByValue: z.boolean().optional(),
enableWireTests: z.boolean().optional()
});

export type BaseGoCustomConfigSchema = z.infer<typeof baseGoCustomConfigSchema>;
3 changes: 2 additions & 1 deletion generators/go-v2/base/src/AsIs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@ export enum AsIsFiles {
ExtraProperties = "internal/extra_properties.go_",
ExtraPropertiesTest = "internal/extra_properties_test.go_",
Stringer = "internal/stringer.go_",
Time = "internal/time.go_"
Time = "internal/time.go_",
MainTest = "test/main_test.go_"
}
56 changes: 56 additions & 0 deletions generators/go-v2/base/src/asIs/test/main_test.go_
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package wiremock
Copy link
Collaborator Author

@musicpulpite musicpulpite Sep 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file is useful to run once for the entire test suite since initializing the wiremock test container does incur overhead. It can then be used in all individual test cases in the package


import (
"context"
"fmt"
"os"
"testing"

gowiremock "github.com/wiremock/go-wiremock"
wiremocktestcontainersgo "github.com/wiremock/wiremock-testcontainers-go"
)

// Global test fixtures
var (
WireMockContainer *wiremocktestcontainersgo.WireMockContainer
WireMockBaseURL string
WireMockClient *gowiremock.Client
)

// TestMain sets up shared test fixtures for all tests in this package
func TestMain(m *testing.M) {
// Setup shared WireMock container
ctx := context.Background()
container, err := wiremocktestcontainersgo.RunContainerAndStopOnCleanup(
ctx,
&testing.T{},
wiremocktestcontainersgo.WithImage("docker.io/wiremock/wiremock:3.9.1"),
)
if err != nil {
fmt.Printf("Failed to start WireMock container: %v\n", err)
os.Exit(1)
}

// Store global references
WireMockContainer = container
WireMockClient = container.Client

// Get the base URL
baseURL, err := container.Endpoint(ctx, "")
if err != nil {
fmt.Printf("Failed to get WireMock container endpoint: %v\n", err)
os.Exit(1)
}
WireMockBaseURL = "http://" + baseURL

// Run all tests
code := m.Run()

// Cleanup
if WireMockContainer != nil {
WireMockContainer.Terminate(ctx)
}

// Exit with the same code as the tests
os.Exit(code)
}
Original file line number Diff line number Diff line change
Expand Up @@ -667,4 +667,6 @@ export abstract class AbstractGoGeneratorContext<
}

public abstract getInternalAsIsFiles(): string[];

public abstract getTestAsIsFiles(): string[];
}
11 changes: 11 additions & 0 deletions generators/go-v2/base/src/project/GoProject.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,17 @@ export class GoProject extends AbstractProject<AbstractGoGeneratorContext<BaseGo
});
}

public async writeSharedTestFiles(): Promise<AbsoluteFilePath> {
const sharedTestFiles = await Promise.all(
this.context.getTestAsIsFiles().map(async (filename) => await this.createAsIsFile({ filename }))
);

return await this.createGoDirectory({
absolutePathToDirectory: join(this.absolutePathToOutputDirectory),
files: sharedTestFiles
});
}

private async createGoDirectory({
absolutePathToDirectory,
files
Expand Down
15 changes: 10 additions & 5 deletions generators/go-v2/dynamic-snippets/src/DynamicSnippetsGenerator.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import {
AbstractDynamicSnippetsGenerator,
AbstractFormatter,
FernGeneratorExec
FernGeneratorExec,
Options
} from "@fern-api/browser-compatible-base-generator";
import { FernIr } from "@fern-api/dynamic-ir-sdk";
import { DynamicSnippetsGeneratorContext } from "./context/DynamicSnippetsGeneratorContext";
Expand All @@ -27,13 +28,17 @@ export class DynamicSnippetsGenerator extends AbstractDynamicSnippetsGenerator<
}

public async generate(
request: FernIr.dynamic.EndpointSnippetRequest
request: FernIr.dynamic.EndpointSnippetRequest,
options?: Options
): Promise<FernIr.dynamic.EndpointSnippetResponse> {
return super.generate(request);
return super.generate(request, options);
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since options is untyped and optional its the best way for me to pass in new options to the dynamic snippets endpoint generator to create "unit test case" snippets without breaking the abstract interface for all other users of DynamicSnippetsGenerator

}

public generateSync(request: FernIr.dynamic.EndpointSnippetRequest): FernIr.dynamic.EndpointSnippetResponse {
return super.generateSync(request);
public generateSync(
request: FernIr.dynamic.EndpointSnippetRequest,
options?: Options
): FernIr.dynamic.EndpointSnippetResponse {
return super.generateSync(request, options);
}

protected createSnippetGenerator(context: DynamicSnippetsGeneratorContext): EndpointSnippetGenerator {
Expand Down
Loading
Loading