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
@@ -0,0 +1,7 @@
---
changeKind: fix
packages:
- "@azure-tools/typespec-java"
---

Avoid duplicate inherited discriminator fields in generated Java models.
2 changes: 1 addition & 1 deletion packages/typespec-java/core-commit.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{ "sha": "890cad64c70072aacf01c8e540a26fb676fa6abe" }
{ "sha": "a61e90890abb32806dba1efa87f6d4f0aae8bf29" }
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

package tsptest.discriminatoredgecases;

import com.azure.core.util.BinaryData;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import tsptest.discriminatoredgecases.models.RegressionAncestorOrdinaryPropertyMaskingAssistant;
import tsptest.discriminatoredgecases.models.RegressionAncestorOrdinaryPropertyMaskingBase;
import tsptest.discriminatoredgecases.models.RegressionDuplicateRepeatedInheritedDiscriminatorAssistant;
import tsptest.discriminatoredgecases.models.RegressionDuplicateRepeatedInheritedDiscriminatorBase;
import tsptest.discriminatoredgecases.models.RegressionSuperclassConstructorPropagationAssistant;
import tsptest.discriminatoredgecases.models.RegressionSuperclassConstructorPropagationBase;

public class DiscriminatorRegressionTests {

@Test
public void duplicateRepeatedInheritedDiscriminatorHasOneCanonicalRepresentation() {
String json = "{\"type\":\"message\",\"role\":\"assistant\"}";

RegressionDuplicateRepeatedInheritedDiscriminatorBase model
= BinaryData.fromString(json).toObject(RegressionDuplicateRepeatedInheritedDiscriminatorBase.class);

Assertions.assertInstanceOf(RegressionDuplicateRepeatedInheritedDiscriminatorAssistant.class, model);
Assertions.assertEquals(json, BinaryData.fromObject(model).toString());
}

@Test
public void canonicalDiscriminatorMasksAncestorOrdinaryProperty() {
String json = "{\"type\":\"message\",\"role\":\"assistant\"}";

RegressionAncestorOrdinaryPropertyMaskingBase model
= BinaryData.fromString(json).toObject(RegressionAncestorOrdinaryPropertyMaskingBase.class);

Assertions.assertInstanceOf(RegressionAncestorOrdinaryPropertyMaskingAssistant.class, model);
Assertions.assertEquals(json, BinaryData.fromObject(model).toString());
}

@Test
public void canonicalDiscriminatorSuppliesSuperclassConstructor() {
String json = "{\"type\":\"message\",\"role\":\"assistant\"}";

RegressionSuperclassConstructorPropagationBase model
= BinaryData.fromString(json).toObject(RegressionSuperclassConstructorPropagationBase.class);

Assertions.assertInstanceOf(RegressionSuperclassConstructorPropagationAssistant.class, model);
Assertions.assertEquals("message", model.getType());
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import com.azure.core.test.http.MockHttpResponse;
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import java.util.Map;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import reactor.core.publisher.Mono;
Expand All @@ -25,7 +26,9 @@ private ResponseHeadersClient createClient(HttpHeaders responseHeaders) {
public void testResponseHeadersAsModel() {
HttpHeaders responseHeaders = new HttpHeaders().set(HttpHeaderName.ETAG, "\"0x8D9\"")
.set(HttpHeaderName.fromString("x-resource-count"), "42")
.set(HttpHeaderName.LAST_MODIFIED, "Mon, 26 Aug 2022 14:38:00 GMT");
.set(HttpHeaderName.LAST_MODIFIED, "Mon, 26 Aug 2022 14:38:00 GMT")
.set(HttpHeaderName.fromString("X-Ms-Meta-key1"), "value1")
.set(HttpHeaderName.fromString("x-ms-meta-key2"), "value2");

ResponseHeaderOpsGetResourceMetadataHeaders headers = createClient(responseHeaders).getResourceMetadata();

Expand All @@ -35,6 +38,7 @@ public void testResponseHeadersAsModel() {
Assertions.assertEquals(42, headers.getResourceCount());
Assertions.assertEquals(OffsetDateTime.of(2022, 8, 26, 14, 38, 0, 0, ZoneOffset.UTC),
headers.getLastModified());
Assertions.assertEquals(Map.of("key1", "value1", "key2", "value2"), headers.getMetadata());
}

@Test
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import "@typespec/rest";
import "@typespec/xml";
import "@azure-tools/typespec-azure-core";
import "@azure-tools/typespec-client-generator-core";

using TypeSpec.Http;
using TypeSpec.Xml;
using Azure.Core;
using Azure.ClientGenerator.Core;

Expand All @@ -28,6 +30,91 @@ model GrandChildWithRequiredProperty extends ChildWithRequiredPropertyAsDiscrimi
discriminator: "aValue";
}

@usage(Usage.output)
@access(Access.public)
@discriminator("type")
model RegressionDuplicateRepeatedInheritedDiscriminatorBase {
type: string;
}

@discriminator("role")
model RegressionDuplicateRepeatedInheritedDiscriminatorMessage
extends RegressionDuplicateRepeatedInheritedDiscriminatorBase {
type: "message";
role: string;
}

model RegressionDuplicateRepeatedInheritedDiscriminatorAssistant
extends RegressionDuplicateRepeatedInheritedDiscriminatorMessage {
type: "message";
role: "assistant";
}

model RegressionAncestorOrdinaryPropertyMaskingRoot {
type?: string;
}

@usage(Usage.output)
@access(Access.public)
@discriminator("type")
model RegressionAncestorOrdinaryPropertyMaskingBase
extends RegressionAncestorOrdinaryPropertyMaskingRoot {}

@discriminator("role")
model RegressionAncestorOrdinaryPropertyMaskingMessage
extends RegressionAncestorOrdinaryPropertyMaskingBase {
type: "message";
role: string;
}

model RegressionAncestorOrdinaryPropertyMaskingAssistant
extends RegressionAncestorOrdinaryPropertyMaskingMessage {
role: "assistant";
}

model RegressionSuperclassConstructorPropagationRoot {
type: string;
}

@usage(Usage.output)
@access(Access.public)
@discriminator("type")
model RegressionSuperclassConstructorPropagationBase
extends RegressionSuperclassConstructorPropagationRoot {}

@discriminator("role")
model RegressionSuperclassConstructorPropagationMessage
extends RegressionSuperclassConstructorPropagationBase {
type: "message";
role: string;
}

model RegressionSuperclassConstructorPropagationAssistant
extends RegressionSuperclassConstructorPropagationMessage {
role: "assistant";
}

@usage(Usage.output)
@access(Access.public)
@name("NestedDiscriminatorBase")
@discriminator("type")
model NestedDiscriminatorBase {
@attribute type: string;
}

@name("NestedDiscriminatorMessage")
@discriminator("role")
model NestedDiscriminatorMessage extends NestedDiscriminatorBase {
@attribute type: "message";
@attribute role: string;
}

@name("NestedDiscriminatorAssistant")
model NestedDiscriminatorAssistant extends NestedDiscriminatorMessage {
@attribute type: "message";
@attribute role: "assistant";
}

model GrandChildWithAnotherDiscriminator extends ChildWithAnotherDiscriminator {
differentDiscriminator: "anotherValue";
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ using Azure.ClientGenerator.Core;
@service(#{ title: "ResponseHeaders" })
namespace TspTest.ResponseHeaders;

model MetadataHeaders {
@header("x-ms-meta") metadata?: string;
}

@route("/response-headers")
interface ResponseHeaderOp {
// HEAD operation with significant response headers but no response body.
Expand All @@ -28,7 +32,11 @@ interface ResponseHeaderOp {

// optional header, with mixed-case header name
@header("Last-Modified") lastModified?: utcDateTime;

...MetadataHeaders;
};
}

@@clientOption(ResponseHeaderOp.getResourceMetadata, "responseHeadersAsModel", true, "java");
@@alternateType(MetadataHeaders.metadata, Record<string>, "java");
@@clientOption(MetadataHeaders.metadata, "collectionHeaderPrefix", "x-ms-meta-", "java");
Loading