Skip to content

Commit

Permalink
feat(swift): generate tests for helpers (#3248)
Browse files Browse the repository at this point in the history
Co-authored-by: Thomas Raffray <[email protected]>
  • Loading branch information
millotp and Fluf22 authored Jun 27, 2024
1 parent 993f70e commit 197d198
Show file tree
Hide file tree
Showing 30 changed files with 71 additions and 182 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -525,18 +525,19 @@ public extension SearchClient {
///
/// See https://api-clients-automation.netlify.app/docs/contributing/add-new-api-client#5-helpers for implementation
/// details.
/// - parameter objects: The new objects
/// - parameter indexName: The name of the index where to replace the objects
/// - parameter objects: The new objects
/// - parameter batchSize: The maximum number of objects to include in a batch
/// - parameter requestOptions: The request options
/// - returns: ReplaceAllObjectsResponse
@discardableResult
func replaceAllObjects(
with objects: [some Encodable],
in indexName: String,
indexName: String,
objects: [some Encodable],
batchSize: Int = 1000,
requestOptions: RequestOptions? = nil
) async throws -> ReplaceAllObjectsResponse {
let tmpIndexName = try "\(indexName)_tmp_\(randomString())"
let tmpIndexName = try "\(indexName)_tmp_\(Int.random(in: 1_000_000 ..< 10_000_000))"

var copyOperationResponse = try await operationIndex(
indexName: indexName,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ public extension SecuredApiKeyRestrictions {
}

return (APIHelper.mapValuesToQueryItems(queryDictionary) ?? [])
.sorted { $0.name < $1.name }
.map { "\($0.name)=\($0.value ?? "null")" }
.joined(separator: "&")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,8 @@ public void processOpts() {
supportingFiles.add(new SupportingFile("netcore_project.mustache", "Algolia.Search.csproj"));
supportingFiles.add(new SupportingFile("Configuration.mustache", "Clients", packageName + "Configuration.cs"));
supportingFiles.add(new SupportingFile("LICENSE", "", "LICENSE"));

reservedWords.removeIf(word -> word.equals("Configuration"));
}

/** Escape <> in generic with {} */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ public void processOpts() {
additionalProperties.put("isSearchClient", client.equals("search"));
supportingFiles.add(new SupportingFile("LICENSE", "", "LICENSE"));

reservedWords.removeIf(word -> word.equals("configuration"));

try {
additionalProperties.put("packageVersion", Helpers.getClientConfigField("java", "packageVersion"));
} catch (GeneratorException e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ public class AlgoliaSwiftGenerator extends Swift5ClientCodegen {
"promote",
"promoteobjectid",
"promoteobjectids",
"querysuggestionsconfiguration",
"querytype",
"rankinginfo",
"redirect",
Expand Down Expand Up @@ -135,21 +136,6 @@ public static String prefixReservedModelName(String name, String client) {
return name;
}

public static String removeReservedModelNamePrefix(String name, String client) {
if (name == null || name.isEmpty()) {
return name;
}

var camelizedName = camelize(name, LOWERCASE_FIRST_LETTER);
var clientName = camelize(INSTANCE.getClientName(client), LOWERCASE_FIRST_LETTER);
var trimmedName = camelize(camelizedName.replaceFirst(clientName, ""), LOWERCASE_FIRST_LETTER);
if (isReservedModelName(trimmedName)) {
return trimmedName;
}

return name;
}

private String CLIENT;

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public static CTSManager getManager(String language, String client) {
case "java" -> new JavaCTSManager(client);
case "php" -> new PhpCTSManager();
case "kotlin" -> new KotlinCTSManager(client);
case "go" -> new GoCTSManager();
case "go" -> new GoCTSManager(client);
case "dart" -> new DartCTSManager(client);
case "ruby" -> new RubyCTSManager(client);
case "scala" -> new ScalaCTSManager(client);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,21 @@
package com.algolia.codegen.cts.manager;

import com.algolia.codegen.exceptions.GeneratorException;
import com.algolia.codegen.utils.*;
import java.util.*;

public class GoCTSManager implements CTSManager {

private final String client;

public GoCTSManager(String client) {
this.client = client;
}

@Override
public void addDataToBundle(Map<String, Object> bundle) throws GeneratorException {
Object clientPrefix = bundle.get("clientPrefix");
bundle.put("clientName", Helpers.toPascalCase(this.client));

if (clientPrefix.equals("query-suggestions")) {
bundle.put("clientPrefix", "suggestions");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -195,8 +195,6 @@ private String getFinalParamName(String paramName) {
return paramName.startsWith("_") ? paramName.substring(1) : paramName;
case "go":
return paramName.equals("type") ? "type_" : paramName;
case "swift":
return AlgoliaSwiftGenerator.removeReservedModelNamePrefix(paramName, client);
}

return paramName;
Expand Down Expand Up @@ -296,8 +294,6 @@ private void handleModel(
CodegenModel model = (CodegenModel) spec;
IJsonSchemaValidationProperties match = findMatchingOneOf(param, model);

paramName = getTransformedParamName(paramName);

testOutput.putAll(traverseParams(paramName, param, match, parent, suffix, isParentFreeFormObject));

Map<String, Object> oneOfModel = new HashMap<>();
Expand Down
2 changes: 1 addition & 1 deletion scripts/cts/runCts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ async function runCtsOne(language: string): Promise<void> {
await run('sbt test', { cwd, language });
break;
case 'swift':
await run('rm -rf .build && swift test -Xswiftc -suppress-warnings -q --parallel', {
await run('swift test -Xswiftc -suppress-warnings -q --parallel', {
cwd,
language,
});
Expand Down
2 changes: 1 addition & 1 deletion specs/query-suggestions/common/parameters.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ IndexName:
required: true
description: Query Suggestions index name.
schema:
$ref: './schemas/QuerySuggestionsIndexName.yml'
$ref: './schemas/IndexName.yml'
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
QuerySuggestionsConfigurationResponse:
ConfigurationResponse:
type: object
description: API response for retrieving Query Suggestions configurations.
allOf:
- $ref: '#/AppID'
- $ref: '../schemas/QuerySuggestionsConfiguration.yml#/QuerySuggestionsConfigurationWithIndex'
- $ref: '../schemas/Configuration.yml#/ConfigurationWithIndex'
required:
- appID
- allowSpecialCharacters
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
QuerySuggestionsConfigurationWithIndex:
ConfigurationWithIndex:
type: object
description: Query Suggestions configuration.
required:
Expand All @@ -8,10 +8,10 @@ QuerySuggestionsConfigurationWithIndex:
- type: object
properties:
indexName:
$ref: './QuerySuggestionsIndexName.yml'
- $ref: '#/QuerySuggestionsConfiguration'
$ref: './IndexName.yml'
- $ref: '#/Configuration'

QuerySuggestionsConfiguration:
Configuration:
type: object
description: Query Suggestions configuration.
required:
Expand Down
2 changes: 1 addition & 1 deletion specs/query-suggestions/paths/getConfigurationStatus.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ get:
additionalProperties: false
properties:
indexName:
$ref: '../common/schemas/QuerySuggestionsIndexName.yml'
$ref: '../common/schemas/IndexName.yml'
isRunning:
type: boolean
description: Whether the creation or update of the Query Suggestions index is in progress.
Expand Down
4 changes: 2 additions & 2 deletions specs/query-suggestions/paths/qsConfig.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ get:
content:
application/json:
schema:
$ref: '../common/responses/QuerySuggestionsConfigurationResponse.yml#/QuerySuggestionsConfigurationResponse'
$ref: '../common/responses/ConfigurationResponse.yml#/ConfigurationResponse'
'400':
$ref: '../common/responses/BadRequest.yml'
'401':
Expand All @@ -37,7 +37,7 @@ put:
content:
application/json:
schema:
$ref: '../common/schemas/QuerySuggestionsConfiguration.yml#/QuerySuggestionsConfiguration'
$ref: '../common/schemas/Configuration.yml#/Configuration'
responses:
'200':
description: OK
Expand Down
4 changes: 2 additions & 2 deletions specs/query-suggestions/paths/qsConfigs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ get:
schema:
type: array
items:
$ref: '../common/responses/QuerySuggestionsConfigurationResponse.yml#/QuerySuggestionsConfigurationResponse'
$ref: '../common/responses/ConfigurationResponse.yml#/ConfigurationResponse'
'401':
$ref: '../common/responses/Unauthorized.yml'

Expand All @@ -34,7 +34,7 @@ post:
content:
application/json:
schema:
$ref: '../common/schemas/QuerySuggestionsConfiguration.yml#/QuerySuggestionsConfigurationWithIndex'
$ref: '../common/schemas/Configuration.yml#/ConfigurationWithIndex'
responses:
'200':
description: OK
Expand Down
8 changes: 4 additions & 4 deletions templates/go/client.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,13 @@ import (
// In most cases there should be only one, shared, APIClient.
type APIClient struct {
appID string
cfg *Configuration
cfg *{{#lambda.titlecase}}{{#lambda.camelcase}}{{client}}{{/lambda.camelcase}}{{/lambda.titlecase}}Configuration
transport *transport.Transport
}

// NewClient creates a new API client with {{#hasRegionalHost}}appID, apiKey and region.{{/hasRegionalHost}}{{^hasRegionalHost}}appID and apiKey.{{/hasRegionalHost}}
func NewClient(appID, apiKey string{{#hasRegionalHost}}, region Region{{/hasRegionalHost}}) (*APIClient, error) {
return NewClientWithConfig(Configuration{
return NewClientWithConfig({{#lambda.titlecase}}{{#lambda.camelcase}}{{client}}{{/lambda.camelcase}}{{/lambda.titlecase}}Configuration{
Configuration: transport.Configuration{
AppID: appID,
ApiKey: apiKey,
Expand All @@ -48,7 +48,7 @@ return NewClientWithConfig(Configuration{
}

// NewClientWithConfig creates a new API client with the given configuration to fully customize the client behaviour.
func NewClientWithConfig(cfg Configuration) (*APIClient, error) {
func NewClientWithConfig(cfg {{#lambda.titlecase}}{{#lambda.camelcase}}{{client}}{{/lambda.camelcase}}{{/lambda.titlecase}}Configuration) (*APIClient, error) {
var hosts []transport.StatefulHost
if cfg.AppID == "" {
Expand Down Expand Up @@ -175,7 +175,7 @@ func (c *APIClient) callAPI(request *http.Request, useReadTransporter bool) (*ht

// Allow modification of underlying config for alternate implementations and testing
// Caution: modifying the configuration while live can cause data races and potentially unwanted behavior
func (c *APIClient) GetConfiguration() *Configuration {
func (c *APIClient) GetConfiguration() *{{#lambda.titlecase}}{{#lambda.camelcase}}{{client}}{{/lambda.camelcase}}{{/lambda.titlecase}}Configuration {
return c.cfg
}

Expand Down
4 changes: 2 additions & 2 deletions templates/go/configuration.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ const (
)
{{/hasRegionalHost}}

// Configuration stores the configuration of the API client
type Configuration struct {
// {{#lambda.titlecase}}{{#lambda.camelcase}}{{client}}{{/lambda.camelcase}}{{/lambda.titlecase}}Configuration stores the configuration of the API client
type {{#lambda.titlecase}}{{#lambda.camelcase}}{{client}}{{/lambda.camelcase}}{{/lambda.titlecase}}Configuration struct {
transport.Configuration
{{#hasRegionalHost}}Region Region{{/hasRegionalHost}}
Expand Down
2 changes: 1 addition & 1 deletion templates/go/tests/client/createClient.mustache
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
cfg = {{clientPrefix}}.Configuration{
cfg = {{clientPrefix}}.{{clientName}}Configuration{
Configuration: transport.Configuration{
AppID: "{{parametersWithDataTypeMap.appId.value}}",
ApiKey: "{{parametersWithDataTypeMap.apiKey.value}}",
Expand Down
4 changes: 2 additions & 2 deletions templates/go/tests/client/suite.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import (

func create{{#lambda.titlecase}}{{clientPrefix}}{{/lambda.titlecase}}Client(t *testing.T) (*{{clientPrefix}}.APIClient, *tests.EchoRequester) {
echo := &tests.EchoRequester{}
cfg := {{clientPrefix}}.Configuration{
cfg := {{clientPrefix}}.{{clientName}}Configuration{
Configuration: transport.Configuration{
AppID: "appID",
ApiKey: "apiKey",
Expand All @@ -45,7 +45,7 @@ func Test{{#lambda.titlecase}}{{clientPrefix}}{{testType}}{{/lambda.titlecase}}{
{{^autoCreateClient}}
echo := &tests.EchoRequester{}
var client *{{clientPrefix}}.APIClient
var cfg {{clientPrefix}}.Configuration
var cfg {{clientPrefix}}.{{clientName}}Configuration
_ = client
{{/autoCreateClient}}
_ = echo
Expand Down
2 changes: 1 addition & 1 deletion templates/go/tests/requests/requests.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ func create{{#lambda.titlecase}}{{clientPrefix}}{{/lambda.titlecase}}Client(t *t
t.Helper()
echo := &tests.EchoRequester{}
cfg := {{clientPrefix}}.Configuration{
cfg := {{clientPrefix}}.{{clientName}}Configuration{
Configuration: transport.Configuration{
AppID: "appID",
ApiKey: "apiKey",
Expand Down
6 changes: 3 additions & 3 deletions templates/swift/api.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ import Foundation

/**
{{#allParams}}
- parameter {{paramName}}: ({{#isFormParam}}form{{/isFormParam}}{{#isQueryParam}}query{{/isQueryParam}}{{#isPathParam}}path{{/isPathParam}}{{#isHeaderParam}}header{{/isHeaderParam}}{{#isBodyParam}}body{{/isBodyParam}}) {{description}} {{^required}}(optional{{#defaultValue}}, default to {{{.}}}{{/defaultValue}}){{/required}}
- parameter {{paramName}}: ({{#isFormParam}}form{{/isFormParam}}{{#isQueryParam}}query{{/isQueryParam}}{{#isPathParam}}path{{/isPathParam}}{{#isHeaderParam}}header{{/isHeaderParam}}{{#isBodyParam}}body{{/isBodyParam}}) {{{description}}} {{^required}}(optional{{#defaultValue}}, default to {{{.}}}{{/defaultValue}}){{/required}}
{{/allParams}}
- returns: {{{returnType}}}{{#returnType}}{{#isResponseOptional}}?{{/isResponseOptional}}{{/returnType}}{{^returnType}}Void{{/returnType}}
*/
Expand Down Expand Up @@ -89,9 +89,9 @@ import Foundation
- {{.}}
{{/x-acl}}
{{/vendorExtensions}}{{#allParams}}
- parameter {{paramName}}: ({{#isFormParam}}form{{/isFormParam}}{{#isQueryParam}}query{{/isQueryParam}}{{#isPathParam}}path{{/isPathParam}}{{#isHeaderParam}}header{{/isHeaderParam}}{{#isBodyParam}}body{{/isBodyParam}}) {{description}} {{^required}}(optional{{#defaultValue}}, default to {{{.}}}{{/defaultValue}}){{/required}}
- parameter {{paramName}}: ({{#isFormParam}}form{{/isFormParam}}{{#isQueryParam}}query{{/isQueryParam}}{{#isPathParam}}path{{/isPathParam}}{{#isHeaderParam}}header{{/isHeaderParam}}{{#isBodyParam}}body{{/isBodyParam}}) {{{description}}} {{^required}}(optional{{#defaultValue}}, default to {{{.}}}{{/defaultValue}}){{/required}}
{{/allParams}}
- returns: RequestBuilder<{{{returnType}}}{{#returnType}}{{#isResponseOptional}}?{{/isResponseOptional}}{{/returnType}}{{^returnType}}Void{{/returnType}}> {{description}}
- returns: RequestBuilder<{{{returnType}}}{{#returnType}}{{#isResponseOptional}}?{{/isResponseOptional}}{{/returnType}}{{^returnType}}Void{{/returnType}}> {{{description}}}
*/
{{#isDeprecated}}
@available(*, deprecated, message: "This operation is deprecated.")
Expand Down
5 changes: 1 addition & 4 deletions templates/swift/tests/client/method.mustache
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
let response = try {{#isAsync}}await {{/isAsync}}client{{#path}}.{{.}}{{#isAsync}}WithHTTPInfo{{/isAsync}}{{/path}}(
let response = try {{#isAsync}}await {{/isAsync}}client{{#path}}.{{.}}{{^isHelper}}WithHTTPInfo{{/isHelper}}{{/path}}(
{{#parametersWithDataType}}{{> tests/generateParams }}{{^-last}},{{/-last}}
{{/parametersWithDataType}}{{#requestOptions.parametersWithDataType}}{{#-first}}, requestOptions: RequestOptions({{/-first}}
{{> tests/generateParams }}{{^-last}},{{/-last}}
Expand All @@ -11,7 +11,4 @@ let echoResponse = try CodableHelper.jsonDecoder.decode(EchoResponse.self, from:
{{^useEchoRequester}}
let responseBodyJSON = try XCTUnwrap(responseBodyData.jsonString)
{{/useEchoRequester}}
{{/isHelper}}
{{#isHelper}}
let responseBodyJSON = response
{{/isHelper}}
26 changes: 15 additions & 11 deletions templates/swift/tests/client/suite.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,9 @@ final class {{client}}ClientTests: XCTestCase {
let API_KEY = "my_api_key"
{{#blocksClient}}
{{#tests}}
{{^isHelper}} {{! Helper tests are not supported yet}}

/**
{{testName}}
{{{testName}}}
*/
func test{{#lambda.titlecase}}{{testType}}{{/lambda.titlecase}}Test{{testIndex}}() async throws {
{{#autoCreateClient}}
Expand Down Expand Up @@ -58,20 +57,25 @@ final class {{client}}ClientTests: XCTestCase {
XCTAssertEqual("{{{match}}}", echoResponse.host);
{{/testHost}}
{{#testResponse}}
{{#matchIsObject}}
let comparableData = "{{#lambda.escapeQuotes}}{{{match.parameters}}}{{/lambda.escapeQuotes}}".data(using: .utf8)
{{/matchIsObject}}
{{^matchIsObject}}
let comparableData = "{{#lambda.escapeQuotes}}{{{match}}}{{/lambda.escapeQuotes}}".data(using: .utf8)
{{/matchIsObject}}
let comparableJSON = try XCTUnwrap(comparableData?.jsonString)
XCTAssertEqual(comparableJSON, responseBodyJSON);
{{#isHelper}}
{{#matchIsObject}}
let comparableData = try XCTUnwrap("{{#lambda.escapeQuotes}}{{{match.parameters}}}{{/lambda.escapeQuotes}}".data(using: .utf8))
try XCTLenientAssertEqual(received: CodableHelper.jsonEncoder.encode(response), expected: comparableData)
{{/matchIsObject}}
{{^matchIsObject}}
XCTAssertEqual("{{#lambda.escapeQuotes}}{{{match}}}{{/lambda.escapeQuotes}}", response)
{{/matchIsObject}}
{{/isHelper}}
{{^isHelper}}
let comparableData = "{{#lambda.escapeQuotes}}{{#matchIsObject}}{{{match.parameters}}}{{/matchIsObject}}{{^matchIsObject}}{{{match}}}{{/matchIsObject}}{{/lambda.escapeQuotes}}".data(using: .utf8)
let comparableJSON = try XCTUnwrap(comparableData?.jsonString)
XCTAssertEqual(comparableJSON, responseBodyJSON);
{{/isHelper}}
{{/testResponse}}
{{/match}}
{{/isError}}
{{/steps}}
}
{{/isHelper}}
{{/tests}}
{{/blocksClient}}
}
2 changes: 1 addition & 1 deletion templates/swift/tests/requests/requests.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ final class {{client}}RequestsTests: XCTestCase {
{{#blocksRequests}}
{{#tests}}
/**
{{testName}}
{{{testName}}}
*/
func test{{#lambda.titlecase}}{{method}}{{/lambda.titlecase}}Test{{testIndex}}() async throws {
let configuration = try {{client}}Configuration(appID: {{client}}RequestsTests.APPLICATION_ID, apiKey: {{client}}RequestsTests.API_KEY{{#hasRegionalHost}}, region: Region.{{defaultRegion}}{{/hasRegionalHost}})
Expand Down
Loading

1 comment on commit 197d198

@github-actions
Copy link

Choose a reason for hiding this comment

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

Please sign in to comment.