Skip to content

Commit 85730e9

Browse files
Adopt versioning spector scenario (Azure#51911)
* Adopt versioning spector scenario * regen
1 parent 98c2e17 commit 85730e9

File tree

180 files changed

+13729
-10
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

180 files changed

+13729
-10
lines changed

eng/packages/http-client-csharp/eng/scripts/Generate.ps1

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -52,12 +52,6 @@ function IsSpecDir {
5252
$failingSpecs = @(
5353
Join-Path 'http' 'streaming' 'jsonl'
5454
Join-Path 'http' 'payload' 'xml'
55-
Join-Path 'http' 'versioning' 'added'
56-
Join-Path 'http' 'versioning' 'madeOptional'
57-
Join-Path 'http' 'versioning' 'removed'
58-
Join-Path 'http' 'versioning' 'renamedFrom'
59-
Join-Path 'http' 'versioning' 'returnTypeChangedFrom'
60-
Join-Path 'http' 'versioning' 'typeChangedFrom'
6155
Join-Path 'http' 'client' 'naming' # pending until https://github.com/microsoft/typespec/issues/5653 is resolved
6256
Join-Path 'http' 'response' 'status-code-range' # Response namespace conflicts with Azure.Response
6357
# Azure scenarios not yet buildable

eng/packages/http-client-csharp/eng/scripts/Generation.psm1

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ function Get-TspCommand {
2727
[string]$specFile,
2828
[string]$generationDir,
2929
[bool]$generateStub = $false,
30-
[string]$apiVersion = $null
30+
[string]$apiVersion = $null,
31+
[string]$libraryNameOverride = $null
3132
)
3233
$command = "npx tsp compile $specFile"
3334
$command += " --trace @azure-typespec/http-client-csharp"
@@ -46,6 +47,10 @@ function Get-TspCommand {
4647
$command += " --option @azure-typespec/http-client-csharp.api-version=$apiVersion"
4748
}
4849

50+
if ($libraryNameOverride) {
51+
$command += " --option @azure-typespec/http-client-csharp.package-name=$libraryNameOverride"
52+
}
53+
4954
$command += " --option @azure-typespec/http-client-csharp.new-project=true"
5055

5156
return $command
@@ -189,16 +194,19 @@ function Generate-Versioning {
189194
## get the last two directories of the output directory and add V1/V2 to disambiguate the namespaces
190195
$namespaceRoot = $(($outputFolders[-2..-1] | `
191196
ForEach-Object { $_.Substring(0,1).ToUpper() + $_.Substring(1) }) -join ".")
197+
$v1LibraryNameOverride = $namespaceRoot + ".V1"
198+
$v2LibraryNameOverride = $namespaceRoot + ".V2"
192199

193-
Invoke (Get-TspCommand $specFilePath $v1Dir -generateStub $generateStub -apiVersion "v1")
194-
Invoke (Get-TspCommand $specFilePath $v2Dir -generateStub $generateStub -apiVersion "v2")
200+
Invoke (Get-TspCommand $specFilePath $v1Dir -generateStub $generateStub -apiVersion "v1" -libraryNameOverride $v1LibraryNameOverride)
201+
Invoke (Get-TspCommand $specFilePath $v2Dir -generateStub $generateStub -apiVersion "v2" -libraryNameOverride $v2LibraryNameOverride)
195202

196203
if ($outputFolders.Contains("removed")) {
197204
$v2PreviewDir = $(Join-Path $outputDir "v2Preview")
198205
if ($createOutputDirIfNotExist -and -not (Test-Path $v2PreviewDir)) {
199206
New-Item -ItemType Directory -Path $v2PreviewDir | Out-Null
200207
}
201-
Invoke (Get-TspCommand $specFilePath $v2PreviewDir -generateStub $generateStub -apiVersion "v2preview")
208+
$v2PreviewLibraryNameOverride = $namespaceRoot + ".V2Preview"
209+
Invoke (Get-TspCommand $specFilePath $v2PreviewDir -generateStub $generateStub -apiVersion "v2preview" -libraryNameOverride $v2PreviewLibraryNameOverride)
202210
}
203211

204212
# exit if the generation failed

eng/packages/http-client-csharp/generator/Azure.Generator/src/Properties/launchSettings.json

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,66 @@
369369
"commandLineArgs": "$(SolutionDir)/../dist/generator/Microsoft.TypeSpec.Generator.dll $(SolutionDir)/TestProjects/Spector/http/type/union/discriminated -g AzureStubGenerator",
370370
"commandName": "Executable",
371371
"executablePath": "dotnet"
372+
},
373+
"http-versioning-added-v1": {
374+
"commandLineArgs": "$(SolutionDir)/../dist/generator/Microsoft.TypeSpec.Generator.dll $(SolutionDir)/TestProjects/Spector/http/versioning/added/v1 -g AzureStubGenerator",
375+
"commandName": "Executable",
376+
"executablePath": "dotnet"
377+
},
378+
"http-versioning-added-v2": {
379+
"commandLineArgs": "$(SolutionDir)/../dist/generator/Microsoft.TypeSpec.Generator.dll $(SolutionDir)/TestProjects/Spector/http/versioning/added/v2 -g AzureStubGenerator",
380+
"commandName": "Executable",
381+
"executablePath": "dotnet"
382+
},
383+
"http-versioning-madeOptional-v1": {
384+
"commandLineArgs": "$(SolutionDir)/../dist/generator/Microsoft.TypeSpec.Generator.dll $(SolutionDir)/TestProjects/Spector/http/versioning/madeOptional/v1 -g AzureStubGenerator",
385+
"commandName": "Executable",
386+
"executablePath": "dotnet"
387+
},
388+
"http-versioning-madeOptional-v2": {
389+
"commandLineArgs": "$(SolutionDir)/../dist/generator/Microsoft.TypeSpec.Generator.dll $(SolutionDir)/TestProjects/Spector/http/versioning/madeOptional/v2 -g AzureStubGenerator",
390+
"commandName": "Executable",
391+
"executablePath": "dotnet"
392+
},
393+
"http-versioning-removed-v1": {
394+
"commandLineArgs": "$(SolutionDir)/../dist/generator/Microsoft.TypeSpec.Generator.dll $(SolutionDir)/TestProjects/Spector/http/versioning/removed/v1 -g AzureStubGenerator",
395+
"commandName": "Executable",
396+
"executablePath": "dotnet"
397+
},
398+
"http-versioning-removed-v2": {
399+
"commandLineArgs": "$(SolutionDir)/../dist/generator/Microsoft.TypeSpec.Generator.dll $(SolutionDir)/TestProjects/Spector/http/versioning/removed/v2 -g AzureStubGenerator",
400+
"commandName": "Executable",
401+
"executablePath": "dotnet"
402+
},
403+
"http-versioning-renamedFrom-v1": {
404+
"commandLineArgs": "$(SolutionDir)/../dist/generator/Microsoft.TypeSpec.Generator.dll $(SolutionDir)/TestProjects/Spector/http/versioning/renamedFrom/v1 -g AzureStubGenerator",
405+
"commandName": "Executable",
406+
"executablePath": "dotnet"
407+
},
408+
"http-versioning-renamedFrom-v2": {
409+
"commandLineArgs": "$(SolutionDir)/../dist/generator/Microsoft.TypeSpec.Generator.dll $(SolutionDir)/TestProjects/Spector/http/versioning/renamedFrom/v2 -g AzureStubGenerator",
410+
"commandName": "Executable",
411+
"executablePath": "dotnet"
412+
},
413+
"http-versioning-returnTypeChangedFrom-v1": {
414+
"commandLineArgs": "$(SolutionDir)/../dist/generator/Microsoft.TypeSpec.Generator.dll $(SolutionDir)/TestProjects/Spector/http/versioning/returnTypeChangedFrom/v1 -g AzureStubGenerator",
415+
"commandName": "Executable",
416+
"executablePath": "dotnet"
417+
},
418+
"http-versioning-returnTypeChangedFrom-v2": {
419+
"commandLineArgs": "$(SolutionDir)/../dist/generator/Microsoft.TypeSpec.Generator.dll $(SolutionDir)/TestProjects/Spector/http/versioning/returnTypeChangedFrom/v2 -g AzureStubGenerator",
420+
"commandName": "Executable",
421+
"executablePath": "dotnet"
422+
},
423+
"http-versioning-typeChangedFrom-v1": {
424+
"commandLineArgs": "$(SolutionDir)/../dist/generator/Microsoft.TypeSpec.Generator.dll $(SolutionDir)/TestProjects/Spector/http/versioning/typeChangedFrom/v1 -g AzureStubGenerator",
425+
"commandName": "Executable",
426+
"executablePath": "dotnet"
427+
},
428+
"http-versioning-typeChangedFrom-v2": {
429+
"commandLineArgs": "$(SolutionDir)/../dist/generator/Microsoft.TypeSpec.Generator.dll $(SolutionDir)/TestProjects/Spector/http/versioning/typeChangedFrom/v2 -g AzureStubGenerator",
430+
"commandName": "Executable",
431+
"executablePath": "dotnet"
372432
}
373433
}
374434
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
extern alias VersioningAddedV1;
5+
6+
using System;
7+
using System.Linq;
8+
using NUnit.Framework;
9+
using VersioningAddedV1::Versioning.Added;
10+
11+
namespace TestProjects.Spector.Tests.Http.Versioning.Added.V1
12+
{
13+
public class VersioningAddedV1Tests : SpectorTestBase
14+
{
15+
[SpectorTest]
16+
public void TestAddedMembersV1Client()
17+
{
18+
/* verify ModelV1. */
19+
var properties = typeof(ModelV1).GetProperties();
20+
Assert.IsNotNull(properties);
21+
Assert.AreEqual(2, properties.Length);
22+
/* verify property UnionProp added in V2 is not present.*/
23+
Assert.IsNull(typeof(ModelV1).GetProperty("UnionProp"));
24+
25+
/* verify EnumV1. */
26+
Assert.True(typeof(EnumV1).IsEnum);
27+
var enumValues = typeof(EnumV1).GetEnumNames();
28+
Assert.IsNotNull(enumValues);
29+
Assert.AreEqual(1, enumValues.Length);
30+
/* verify added enum value EnumMemberV2. */
31+
Assert.IsFalse(enumValues.Contains("EnumMemberV2"));
32+
33+
/* check existence of the added model ModelV2. */
34+
Assert.IsNull(Type.GetType("Versioning.Added.V1.Models.ModelV2"));
35+
36+
/* check existence of the added enum EnumV2. */
37+
Assert.IsNull(Type.GetType("Versioning.Added.V1.Models.EnumV2"));
38+
39+
/* check the added parameter. */
40+
var methods = typeof(AddedClient).GetMethods().Where(m => m.Name == "V1" || m.Name == "V1Async");
41+
Assert.IsNotNull(methods);
42+
Assert.AreEqual(4, methods.Count());
43+
var methodsArray = methods.ToArray();
44+
foreach (var method in methodsArray)
45+
{
46+
Assert.IsFalse(method.GetParameters().Any(p => p.Name == "headerV2"));
47+
}
48+
49+
/* check the existence of added method in V2. */
50+
var addedMethods = typeof(AddedClient).GetMethods().Where(m => m.Name == "V2" || m.Name == "V2Async");
51+
Assert.IsEmpty(addedMethods);
52+
53+
/* check the existence of added interface in V2. */
54+
Assert.IsNull(Type.GetType("Versioning.Added.V1.InterfaceV2"));
55+
}
56+
}
57+
}
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
extern alias VersioningAddedV2;
5+
6+
using System;
7+
using System.Linq;
8+
using System.Threading.Tasks;
9+
using NUnit.Framework;
10+
using VersioningAddedV2::Versioning.Added;
11+
12+
namespace TestProjects.Spector.Tests.Http.Versioning.Added.V2
13+
{
14+
public class VersioningAddedV2Tests : SpectorTestBase
15+
{
16+
[SpectorTest]
17+
public void TestAddedMembersV2Client()
18+
{
19+
/* verify ModelV1. */
20+
var properties = typeof(ModelV1).GetProperties();
21+
Assert.IsNotNull(properties);
22+
Assert.AreEqual(3, properties.Length);
23+
/* verify added property UnionProp in V2.*/
24+
Assert.IsNotNull(typeof(ModelV1).GetProperty("UnionProp"));
25+
26+
/* verify EnumV1. */
27+
Assert.True(typeof(EnumV1).IsEnum);
28+
var enumValues = typeof(EnumV1).GetEnumNames();
29+
Assert.IsNotNull(enumValues);
30+
Assert.AreEqual(2, enumValues.Length);
31+
/* verify added enum value EnumMemberV2. */
32+
Assert.IsTrue(enumValues.Contains("EnumMemberV2"));
33+
34+
/* check existence of the added model ModelV2. */
35+
var modelV2Type = typeof(ModelV1).Assembly.GetType("Versioning.Added.ModelV2");
36+
Assert.IsNotNull(modelV2Type);
37+
38+
/* check existence of the added enum EnumV2. */
39+
var enumV2Type = typeof(ModelV1).Assembly.GetType("Versioning.Added.EnumV2");
40+
Assert.IsNotNull(enumV2Type);
41+
42+
/* check the added parameter. */
43+
var methods = typeof(AddedClient).GetMethods().Where(m => m.Name == "V1" || m.Name == "V1Async");
44+
Assert.IsNotNull(methods);
45+
Assert.AreEqual(4, methods.Count());
46+
var methodsArray = methods.ToArray();
47+
foreach (var method in methodsArray)
48+
{
49+
Assert.IsTrue(method.GetParameters().Any(p => p.Name == "headerV2"));
50+
}
51+
52+
/* check the existence of added method in V2. */
53+
var addedMethods = typeof(AddedClient).GetMethods().Where(m => m.Name == "V2" || m.Name == "V2Async");
54+
Assert.IsNotNull(addedMethods);
55+
Assert.AreEqual(4, addedMethods.Count());
56+
57+
/* check the existence of added interface in V2. */
58+
var interfaceV2Type = typeof(ModelV1).Assembly.GetType("Versioning.Added.InterfaceV2");
59+
Assert.IsNotNull(interfaceV2Type);
60+
}
61+
62+
[SpectorTest]
63+
public Task Versioning_Added_v1() => Test(async (host) =>
64+
{
65+
ModelV1 modelV1 = new ModelV1("foo", EnumV1.EnumMemberV2, BinaryData.FromObjectAsJson(10));
66+
var response = await new AddedClient(host).V1Async("bar", modelV1);
67+
Assert.AreEqual(200, response.GetRawResponse().Status);
68+
Assert.AreEqual("foo", response.Value.Prop);
69+
Assert.AreEqual(EnumV1.EnumMemberV2, response.Value.EnumProp);
70+
Assert.AreEqual(10, response.Value.UnionProp.ToObjectFromJson<int>());
71+
});
72+
73+
[SpectorTest]
74+
public Task Versioning_Added_v2() => Test(async (host) =>
75+
{
76+
ModelV2 modelV2 = new ModelV2("foo", EnumV2.EnumMember, BinaryData.FromObjectAsJson("bar"));
77+
var response = await new AddedClient(host).V2Async(modelV2);
78+
Assert.AreEqual(200, response.GetRawResponse().Status);
79+
Assert.AreEqual("foo", response.Value.Prop);
80+
Assert.AreEqual(EnumV2.EnumMember, response.Value.EnumProp);
81+
Assert.AreEqual("bar", response.Value.UnionProp.ToObjectFromJson<string>());
82+
});
83+
84+
[SpectorTest]
85+
public Task Versioning_Added_InterfaceV2() => Test(async (host) =>
86+
{
87+
ModelV2 modelV2 = new ModelV2("foo", EnumV2.EnumMember, BinaryData.FromObjectAsJson("bar"));
88+
var response = await new AddedClient(host).GetInterfaceV2Client().V2InInterfaceAsync(modelV2);
89+
Assert.AreEqual(200, response.GetRawResponse().Status);
90+
Assert.AreEqual("foo", response.Value.Prop);
91+
Assert.AreEqual(EnumV2.EnumMember, response.Value.EnumProp);
92+
Assert.AreEqual("bar", response.Value.UnionProp.ToObjectFromJson<string>());
93+
});
94+
}
95+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
extern alias MadeOptionalV1;
5+
6+
using System.Linq;
7+
using MadeOptionalV1::Versioning.MadeOptional;
8+
using NUnit.Framework;
9+
10+
namespace TestProjects.Spector.Tests.Http.Versioning.MadeOptional.V1
11+
{
12+
public class VersioningMadeOptionalV1Tests : SpectorTestBase
13+
{
14+
[SpectorTest]
15+
public void CheckMadeOptionalMembers()
16+
{
17+
var constructors = typeof(TestModel).GetConstructors();
18+
Assert.IsNotNull(constructors);
19+
Assert.AreEqual(1, constructors.Length);
20+
/* property will not in public constructor signature. */
21+
Assert.IsTrue(constructors[0].GetParameters().Any(p => p.Name == "changedProp"));
22+
}
23+
}
24+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
extern alias MadeOptionalV2;
5+
using System.Linq;
6+
using System.Threading.Tasks;
7+
using MadeOptionalV2::Versioning.MadeOptional;
8+
using NUnit.Framework;
9+
10+
namespace TestProjects.Spector.Tests.Http.Versioning.MadeOptional.V2
11+
{
12+
public class VersioningMadeOptionalV2Tests : SpectorTestBase
13+
{
14+
[SpectorTest]
15+
public void CheckMadeOptionalMembers()
16+
{
17+
var constructors = typeof(TestModel).GetConstructors();
18+
Assert.IsNotNull(constructors);
19+
Assert.AreEqual(1, constructors.Length);
20+
/* optional property will not show in public constructor signature. */
21+
Assert.False(constructors[0].GetParameters().Any(p => p.Name == "changedProp"));
22+
}
23+
24+
[SpectorTest]
25+
public Task Versioning_MadeOptional_Test() => Test(async (host) =>
26+
{
27+
TestModel body = new TestModel("foo");
28+
var response = await new MadeOptionalClient(host).TestAsync(body);
29+
Assert.AreEqual(200, response.GetRawResponse().Status);
30+
Assert.AreEqual("foo", response.Value.Prop);
31+
});
32+
}
33+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
extern alias RemovedV1;
5+
using System;
6+
using System.Linq;
7+
using System.Threading.Tasks;
8+
using NUnit.Framework;
9+
using RemovedV1::Versioning.Removed;
10+
using RemovedV1::Versioning.Removed.V1;
11+
12+
namespace TestProjects.Spector.Tests.Http.Versioning.Removed.V1
13+
{
14+
public class VersioningRemovedV1Tests : SpectorTestBase
15+
{
16+
[SpectorTest]
17+
public void TestRemovedMembers()
18+
{
19+
var assembly = typeof(RemovedClient).Assembly;
20+
/* check existence of the removed model ModelV1. */
21+
var modelV1Type = assembly.GetType("Versioning.Removed.ModelV1");
22+
Assert.IsNotNull(modelV1Type);
23+
24+
/* check existence of the removed enum EnumV1. */
25+
var enumV1Type = assembly.GetType("Versioning.Removed.EnumV1");
26+
Assert.IsNotNull(enumV1Type);
27+
28+
/* check existence of removed method V1 */
29+
var removedMethods = typeof(RemovedClient).GetMethods().Where(m => m.Name == "V1" || m.Name == "V1Async");
30+
Assert.AreEqual(4, removedMethods.Count());
31+
32+
/* check existence of removed parameter. */
33+
var v2Methods = typeof(RemovedClient).GetMethods().Where(m => m.Name == "V2" || m.Name == "V2Async");
34+
Assert.IsNotNull(v2Methods);
35+
Assert.AreEqual(4, v2Methods.Count());
36+
foreach (var method in v2Methods)
37+
{
38+
Assert.IsTrue(method.GetParameters().Any(p => p.Name == "param"));
39+
}
40+
41+
/* check existence of removed interface. */
42+
var interfaceV1Type = assembly.GetType("Versioning.Removed.InterfaceV1");
43+
Assert.IsNotNull(interfaceV1Type);
44+
45+
// Only initial versions is defined
46+
var enumType = typeof(RemovedClientOptions.ServiceVersion);
47+
Assert.AreEqual(new string[] { "V1" }, enumType.GetEnumNames());
48+
}
49+
50+
[SpectorTest]
51+
public Task Versioning_Removed_V3Model() => Test(async (host) =>
52+
{
53+
var model = new ModelV3("123", EnumV3.EnumMemberV1);
54+
var response = await new RemovedClient(host).ModelV3Async(model);
55+
Assert.AreEqual(200, response.GetRawResponse().Status);
56+
Assert.AreEqual("123", response.Value.Id);
57+
Assert.AreEqual(EnumV3.EnumMemberV1, response.Value.EnumProp);
58+
});
59+
}
60+
}

0 commit comments

Comments
 (0)