Skip to content
Open
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

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -1,4 +1,15 @@
class {{classname}}
{{#rbNamespaceOnly}}
class {{rbNamespaceClassName}}
def initialize(connection)
@connection = connection
end
{{#rbNamespaceResources}}

def {{accessor}}
@{{accessor}} ||= {{className}}.new(@connection)
end
{{/rbNamespaceResources}}
end{{/rbNamespaceOnly}}{{^rbNamespaceOnly}}class {{classname}}
def initialize(connection)
@connection = connection
end
Expand Down Expand Up @@ -34,4 +45,12 @@ class {{classname}}
)
end
{{/operation}}
end
{{#rbNamespaceHasDirectOperations}}
{{#rbNamespaceResources}}

def {{accessor}}
@{{accessor}} ||= {{className}}.new(@connection)
end
{{/rbNamespaceResources}}
{{/rbNamespaceHasDirectOperations}}
end{{/rbNamespaceOnly}}
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,11 @@ RSpec.describe {{moduleName}}::{{#apiNamespacePresent}}{{apiNamespace}}::{{/apiN
api = described_class.new(client.connection)
expect(api).to be_a(described_class)
end
{{#rbNamespaceResources}}

it 'exposes {{accessor}} through the namespace client' do
expect(client.{{rbNamespaceAccessor}}.{{accessor}}).to be_a({{moduleName}}::{{#apiNamespacePresent}}{{apiNamespace}}::{{/apiNamespacePresent}}{{className}})
end
{{/rbNamespaceResources}}
end
{{/operations}}
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,47 @@ public void testOperationGroupingBuildsNamespaces() {
assertEquals(co.operationId, "get");
}

@Test
public void testSupportingFilesRespectSelectiveApiGeneration() {
io.swagger.v3.oas.models.OpenAPI openAPI = org.openapitools.codegen.TestUtils
.parseSpec("src/test/resources/3_0/petstore.yaml");
RubyNextgenClientCodegen codegen = new RubyNextgenClientCodegen();
codegen.setOpenAPI(openAPI);
codegen.preprocessOpenAPI(openAPI);

java.util.Map<String, java.util.List<org.openapitools.codegen.CodegenOperation>> groups =
new java.util.TreeMap<>();
for (java.util.Map.Entry<String, io.swagger.v3.oas.models.PathItem> pathEntry
: openAPI.getPaths().entrySet()) {
for (java.util.Map.Entry<io.swagger.v3.oas.models.PathItem.HttpMethod,
io.swagger.v3.oas.models.Operation> operationEntry
: pathEntry.getValue().readOperationsMap().entrySet()) {
org.openapitools.codegen.CodegenOperation operation = codegen.fromOperation(
pathEntry.getKey(), operationEntry.getKey().name(), operationEntry.getValue(), null);
codegen.addOperationToGroup(null, pathEntry.getKey(), operationEntry.getValue(), operation, groups);
}
}

org.openapitools.codegen.model.OperationMap generatedOperations =
new org.openapitools.codegen.model.OperationMap();
generatedOperations.setClassname(codegen.toApiName("pet"));
org.openapitools.codegen.model.OperationsMap generatedApi =
new org.openapitools.codegen.model.OperationsMap();
generatedApi.setOperation(generatedOperations);
org.openapitools.codegen.model.ApiInfoMap apiInfo =
new org.openapitools.codegen.model.ApiInfoMap();
apiInfo.setApis(java.util.Collections.singletonList(generatedApi));

java.util.Map<String, Object> supportingData = new java.util.HashMap<>();
supportingData.put("apiInfo", apiInfo);
codegen.postProcessSupportingFileData(supportingData);

java.util.List<java.util.Map<String, Object>> namespaces =
(java.util.List<java.util.Map<String, Object>>) supportingData.get("rbNamespaces");
assertEquals(namespaces.size(), 1);
assertEquals(namespaces.get(0).get("routeName"), "pet");
}

@Test
public void testOperationIdCollisionIsDeduped() {
io.swagger.v3.oas.models.OpenAPI openAPI = org.openapitools.codegen.TestUtils
Expand Down Expand Up @@ -390,12 +431,98 @@ public void testAcronymModelsGetZeitwerkInflections() throws Exception {
// and the model file itself must define the acronym-cased constant
org.openapitools.codegen.TestUtils.assertFileContains(
target.resolve("lib/acme/models/http_config.rb"), "HTTPConfig");
// Acronyms in API resource classes must be registered too: the file
// api/dedicated_cloud/two_fa_whitelist.rb defines DedicatedCloud::TwoFAWhitelist,
// which the default inflector (expecting TwoFaWhitelist) would fail to autoload.
// Acronyms in API resource classes must be registered too. Namespace and resource
// classes use separate files so Zeitwerk sees one constant per path.
org.openapitools.codegen.TestUtils.assertFileContains(
target.resolve("lib/acme.rb"), "\"two_fa_whitelist\" => \"TwoFAWhitelist\"");
org.openapitools.codegen.TestUtils.assertFileContains(
target.resolve("lib/acme/api/dedicated_cloud/two_fa_whitelist.rb"), "TwoFAWhitelist");
target.resolve("lib/acme/api/dedicated_cloud/two_fa_whitelist.rb"), "class DedicatedCloud::TwoFAWhitelist");
org.openapitools.codegen.TestUtils.assertFileContains(
target.resolve("lib/acme/api/dedicated_cloud.rb"),
"class DedicatedCloud", "def two_fa_whitelist",
"@two_fa_whitelist ||= DedicatedCloud::TwoFAWhitelist.new(@connection)");
}
Comment thread
cubic-dev-ai[bot] marked this conversation as resolved.

@Test
public void testNestedResourcesAreReachableFromClient() throws Exception {
java.nio.file.Path target = java.nio.file.Files.createTempDirectory("test");
target.toFile().deleteOnExit();
org.openapitools.codegen.ClientOptInput input =
new org.openapitools.codegen.config.CodegenConfigurator()
.setGeneratorName("ruby-nextgen")
.setInputSpec("src/test/resources/3_0/ruby-nextgen/nested-resources.yaml")
.setOutputDir(target.toString())
.addAdditionalProperty("gemName", "petstore")
.addAdditionalProperty("moduleName", "Petstore")
.toClientOptInput();
new org.openapitools.codegen.DefaultGenerator(false).opts(input).generate();

org.openapitools.codegen.TestUtils.assertFileContains(
Comment thread
cubic-dev-ai[bot] marked this conversation as resolved.
target.resolve("lib/petstore/client.rb"), "def stables", "Petstore::Api::Stables.new",
"def only", "Petstore::Api::Only.new");
org.openapitools.codegen.TestUtils.assertFileContains(
target.resolve("lib/petstore/api/stables.rb"),
"def ponies", "@ponies ||= Stables::Ponies.new(@connection)");
org.openapitools.codegen.TestUtils.assertFileExists(
target.resolve("lib/petstore/api/stables/ponies.rb"));

java.nio.file.Path namespaceOnly = target.resolve("lib/petstore/api/only.rb");
org.openapitools.codegen.TestUtils.assertFileContains(
namespaceOnly, "class Only", "def children", "@children ||= Only::Children.new(@connection)",
"def siblings", "@siblings ||= Only::Siblings.new(@connection)");
org.openapitools.codegen.TestUtils.assertFileNotContains(
namespaceOnly, "class Only::Children", "class Only::Siblings");
assertEquals(java.nio.file.Files.readString(namespaceOnly),
"# frozen_string_literal: true\n"
+ "\n"
+ "module Petstore\n"
+ " module Api\n"
+ " class Only\n"
+ " def initialize(connection)\n"
+ " @connection = connection\n"
+ " end\n"
+ "\n"
+ " def children\n"
+ " @children ||= Only::Children.new(@connection)\n"
+ " end\n"
+ "\n"
+ " def siblings\n"
+ " @siblings ||= Only::Siblings.new(@connection)\n"
+ " end\n"
+ " end\n"
+ " end\n"
+ "end\n");
org.openapitools.codegen.TestUtils.assertFileContains(
target.resolve("spec/api/only_spec.rb"),
"exposes children through the namespace client",
"exposes siblings through the namespace client");
org.openapitools.codegen.TestUtils.assertFileContains(
target.resolve("lib/petstore/api/only/children.rb"), "class Only::Children");
org.openapitools.codegen.TestUtils.assertFileExists(
target.resolve("lib/petstore/api/only/siblings.rb"));
}

@Test
public void testResourceAccessorsUseFinalOperationIdsAndAvoidObjectMethods() throws Exception {
java.nio.file.Path target = java.nio.file.Files.createTempDirectory("test");
target.toFile().deleteOnExit();
java.util.Map<String, String> mappings = new java.util.HashMap<>();
mappings.put("stablesStats", "stables_ponies");
org.openapitools.codegen.ClientOptInput input =
new org.openapitools.codegen.config.CodegenConfigurator()
.setGeneratorName("ruby-nextgen")
.setInputSpec("src/test/resources/3_0/ruby-nextgen/resource-accessor-collisions.yaml")
.setOutputDir(target.toString())
.setOperationIdNameMappings(mappings)
.addAdditionalProperty("gemName", "petstore")
.addAdditionalProperty("moduleName", "Petstore")
.toClientOptInput();
new org.openapitools.codegen.DefaultGenerator(false).opts(input).generate();

java.nio.file.Path stables = target.resolve("lib/petstore/api/stables.rb");
org.openapitools.codegen.TestUtils.assertFileContains(
stables, "def ponies(stable:", "def ponies_api", "def class_api", "def hash_api");
org.openapitools.codegen.TestUtils.assertFileContains(
target.resolve("lib/petstore/api/stables/ponies.rb"), "class Stables::Ponies");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
openapi: 3.0.3
info:
title: Nested resources
version: 1.0.0
paths:
/stables:
get:
operationId: listStables
responses:
'200':
description: OK
/stables/{stable}:
get:
operationId: getStable
parameters:
- name: stable
in: path
required: true
schema:
type: string
responses:
'200':
description: OK
/stables/{stable}/ponies/{pony}:
get:
operationId: getPony
parameters:
- name: stable
in: path
required: true
schema:
type: string
- name: pony
in: path
required: true
schema:
type: string
responses:
'200':
description: OK
/only/{only}/children/{child}:
get:
operationId: getChild
parameters:
- name: only
in: path
required: true
schema:
type: string
- name: child
in: path
required: true
schema:
type: string
responses:
'200':
description: OK
/only/{only}/siblings/{sibling}:
get:
operationId: getSibling
parameters:
- name: only
in: path
required: true
schema:
type: string
- name: sibling
in: path
required: true
schema:
type: string
responses:
'200':
description: OK
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
openapi: 3.0.3
info:
title: Resource accessor collisions
version: 1.0.0
paths:
/stables:
get:
operationId: listStables
responses:
'200':
description: OK
/stables/{stable}/stats:
get:
operationId: stablesStats
parameters:
- name: stable
in: path
required: true
schema:
type: string
responses:
'200':
description: OK
/stables/{stable}/ponies/{pony}:
get:
operationId: getPony
parameters:
- name: stable
in: path
required: true
schema:
type: string
- name: pony
in: path
required: true
schema:
type: string
responses:
'200':
description: OK
/stables/{stable}/class/{class}:
get:
operationId: getClassResource
parameters:
- name: stable
in: path
required: true
schema:
type: string
- name: class
in: path
required: true
schema:
type: string
responses:
'200':
description: OK
/stables/{stable}/hash/{hash}:
get:
operationId: getHashResource
parameters:
- name: stable
in: path
required: true
schema:
type: string
- name: hash
in: path
required: true
schema:
type: string
responses:
'200':
description: OK
12 changes: 11 additions & 1 deletion samples/client/others/go/oneof-not-enum/docs/EnumNullUnion.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**Kind** | Pointer to **string** | | [optional]
**Kind** | Pointer to **NullableString** | | [optional]

## Methods

Expand Down Expand Up @@ -50,6 +50,16 @@ SetKind sets Kind field to given value.

HasKind returns a boolean if a field has been set.

### SetKindNil

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2: These new entries advertise SetKindNil and UnsetKind methods on EnumNullUnion, but neither method exists on this oneOf wrapper. Remove them or document the generated union API so callers are not led to use nonexistent methods.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At samples/client/others/go/oneof-not-enum/docs/EnumNullUnion.md, line 53:

<comment>These new entries advertise `SetKindNil` and `UnsetKind` methods on `EnumNullUnion`, but neither method exists on this oneOf wrapper. Remove them or document the generated union API so callers are not led to use nonexistent methods.</comment>

<file context>
@@ -50,6 +50,16 @@ SetKind sets Kind field to given value.
 
 HasKind returns a boolean if a field has been set.
 
+### SetKindNil
+
+`func (o *EnumNullUnion) SetKindNil(b bool)`
</file context>


`func (o *EnumNullUnion) SetKindNil(b bool)`

SetKindNil sets the value for Kind to be an explicit nil

### UnsetKind
`func (o *EnumNullUnion) UnsetKind()`

UnsetKind ensures that no value is present for Kind, not even an explicit nil

[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ def status
auth: ['api-key', 'bearerAuth']
)
end

def peer
@peer ||= Cluster::Peer.new(@connection)
end
end
end
end
Loading
Loading