Skip to content

Commit 6ff258b

Browse files
committed
Add unit tests for ApplicableTo serialization and ProductApplicability.ToString() implementation
1 parent 8cb26a1 commit 6ff258b

File tree

3 files changed

+627
-0
lines changed

3 files changed

+627
-0
lines changed

src/Elastic.Documentation/AppliesTo/ApplicableTo.cs

Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
// See the LICENSE file in the project root for more information
44

55
using System.Collections;
6+
using System.Text;
67
using System.Text.Json.Serialization;
78
using Elastic.Documentation.Diagnostics;
89
using YamlDotNet.Serialization;
@@ -62,6 +63,58 @@ public record ApplicableTo
6263
Deployment = DeploymentApplicability.All,
6364
Product = AppliesCollection.GenerallyAvailable
6465
};
66+
67+
public static ApplicableTo Default { get; } = new()
68+
{
69+
Stack = new AppliesCollection([new Applicability { Version = new SemVersion(9, 0, 0), Lifecycle = ProductLifecycle.GenerallyAvailable }]),
70+
Serverless = ServerlessProjectApplicability.All
71+
};
72+
73+
/// <inheritdoc />
74+
public override string ToString()
75+
{
76+
var sb = new StringBuilder();
77+
var hasContent = false;
78+
79+
if (Stack is not null)
80+
{
81+
_ = sb.Append("stack: ").Append(Stack);
82+
hasContent = true;
83+
}
84+
85+
if (Deployment is not null)
86+
{
87+
if (hasContent)
88+
_ = sb.Append(", ");
89+
_ = sb.Append("deployment: ").Append(Deployment);
90+
hasContent = true;
91+
}
92+
93+
if (Serverless is not null)
94+
{
95+
if (hasContent)
96+
_ = sb.Append(", ");
97+
_ = sb.Append("serverless: ").Append(Serverless);
98+
hasContent = true;
99+
}
100+
101+
if (Product is not null)
102+
{
103+
if (hasContent)
104+
_ = sb.Append(", ");
105+
_ = sb.Append("product: ").Append(Product);
106+
hasContent = true;
107+
}
108+
109+
if (ProductApplicability is not null)
110+
{
111+
if (hasContent)
112+
_ = sb.Append(", ");
113+
_ = sb.Append("products: ").Append(ProductApplicability);
114+
}
115+
116+
return sb.ToString();
117+
}
65118
}
66119

67120
[YamlSerializable]
@@ -86,6 +139,44 @@ public record DeploymentApplicability
86139
Ess = AppliesCollection.GenerallyAvailable,
87140
Self = AppliesCollection.GenerallyAvailable
88141
};
142+
143+
/// <inheritdoc />
144+
public override string ToString()
145+
{
146+
var sb = new StringBuilder();
147+
var hasContent = false;
148+
149+
if (Self is not null)
150+
{
151+
_ = sb.Append("self=").Append(Self);
152+
hasContent = true;
153+
}
154+
155+
if (Ece is not null)
156+
{
157+
if (hasContent)
158+
_ = sb.Append(", ");
159+
_ = sb.Append("ece=").Append(Ece);
160+
hasContent = true;
161+
}
162+
163+
if (Eck is not null)
164+
{
165+
if (hasContent)
166+
_ = sb.Append(", ");
167+
_ = sb.Append("eck=").Append(Eck);
168+
hasContent = true;
169+
}
170+
171+
if (Ess is not null)
172+
{
173+
if (hasContent)
174+
_ = sb.Append(", ");
175+
_ = sb.Append("ess=").Append(Ess);
176+
}
177+
178+
return sb.ToString();
179+
}
89180
}
90181

91182
[YamlSerializable]
@@ -114,6 +205,36 @@ public record ServerlessProjectApplicability
114205
Observability = AppliesCollection.GenerallyAvailable,
115206
Security = AppliesCollection.GenerallyAvailable
116207
};
208+
209+
/// <inheritdoc />
210+
public override string ToString()
211+
{
212+
var sb = new StringBuilder();
213+
var hasContent = false;
214+
215+
if (Elasticsearch is not null)
216+
{
217+
_ = sb.Append("elasticsearch=").Append(Elasticsearch);
218+
hasContent = true;
219+
}
220+
221+
if (Observability is not null)
222+
{
223+
if (hasContent)
224+
_ = sb.Append(", ");
225+
_ = sb.Append("observability=").Append(Observability);
226+
hasContent = true;
227+
}
228+
229+
if (Security is not null)
230+
{
231+
if (hasContent)
232+
_ = sb.Append(", ");
233+
_ = sb.Append("security=").Append(Security);
234+
}
235+
236+
return sb.ToString();
237+
}
117238
}
118239

119240
[YamlSerializable]
@@ -184,4 +305,46 @@ public record ProductApplicability
184305

185306
[YamlMember(Alias = "edot-collector")]
186307
public AppliesCollection? EdotCollector { get; set; }
308+
309+
/// <inheritdoc />
310+
public override string ToString()
311+
{
312+
var sb = new StringBuilder();
313+
var hasContent = false;
314+
315+
void AppendProduct(string name, AppliesCollection? value)
316+
{
317+
if (value is null)
318+
return;
319+
if (hasContent)
320+
_ = sb.Append(", ");
321+
_ = sb.Append(name).Append('=').Append(value);
322+
hasContent = true;
323+
}
324+
325+
AppendProduct("ecctl", Ecctl);
326+
AppendProduct("curator", Curator);
327+
AppendProduct("apm-agent-android", ApmAgentAndroid);
328+
AppendProduct("apm-agent-dotnet", ApmAgentDotnet);
329+
AppendProduct("apm-agent-go", ApmAgentGo);
330+
AppendProduct("apm-agent-ios", ApmAgentIos);
331+
AppendProduct("apm-agent-java", ApmAgentJava);
332+
AppendProduct("apm-agent-node", ApmAgentNode);
333+
AppendProduct("apm-agent-php", ApmAgentPhp);
334+
AppendProduct("apm-agent-python", ApmAgentPython);
335+
AppendProduct("apm-agent-ruby", ApmAgentRuby);
336+
AppendProduct("apm-agent-rum-js", ApmAgentRumJs);
337+
AppendProduct("edot-ios", EdotIos);
338+
AppendProduct("edot-android", EdotAndroid);
339+
AppendProduct("edot-dotnet", EdotDotnet);
340+
AppendProduct("edot-java", EdotJava);
341+
AppendProduct("edot-node", EdotNode);
342+
AppendProduct("edot-php", EdotPhp);
343+
AppendProduct("edot-python", EdotPython);
344+
AppendProduct("edot-cf-aws", EdotCfAws);
345+
AppendProduct("edot-cf-azure", EdotCfAzure);
346+
AppendProduct("edot-collector", EdotCollector);
347+
348+
return sb.ToString();
349+
}
187350
}
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
// Licensed to Elasticsearch B.V under one or more agreements.
2+
// Elasticsearch B.V licenses this file to you under the Apache 2.0 License.
3+
// See the LICENSE file in the project root for more information
4+
5+
using System.Reflection;
6+
using Elastic.Documentation;
7+
using Elastic.Documentation.AppliesTo;
8+
using FluentAssertions;
9+
using YamlDotNet.Serialization;
10+
11+
namespace Elastic.Markdown.Tests.AppliesTo;
12+
13+
public class ProductApplicabilityToStringTests
14+
{
15+
[Fact]
16+
public void ProductApplicability_ToString_IncludesAllProperties()
17+
{
18+
// Create a ProductApplicability with all properties set
19+
var productApplicability = new ProductApplicability();
20+
var productType = typeof(ProductApplicability);
21+
var properties = productType.GetProperties()
22+
.Where(p => p.GetCustomAttribute<YamlMemberAttribute>() != null)
23+
.ToList();
24+
25+
// Set all properties to a test value
26+
var testValue = AppliesCollection.GenerallyAvailable;
27+
foreach (var property in properties)
28+
{
29+
property.SetValue(productApplicability, testValue);
30+
}
31+
32+
// Get the ToString output
33+
var result = productApplicability.ToString();
34+
35+
// Verify that each property's YAML alias appears in the output
36+
foreach (var property in properties)
37+
{
38+
var yamlAlias = property.GetCustomAttribute<YamlMemberAttribute>()!.Alias;
39+
result.Should().Contain($"{yamlAlias}=",
40+
$"ToString should include the property {property.Name} with alias '{yamlAlias}'");
41+
}
42+
43+
// Verify we have the expected number of properties
44+
properties.Should().HaveCount(22, "ProductApplicability should have exactly 22 product properties");
45+
}
46+
47+
[Fact]
48+
public void ProductApplicability_ToString_WithSomeProperties_OnlyIncludesSetProperties()
49+
{
50+
var productApplicability = new ProductApplicability
51+
{
52+
ApmAgentDotnet = AppliesCollection.GenerallyAvailable,
53+
Ecctl = new AppliesCollection([new Applicability { Lifecycle = ProductLifecycle.Beta, Version = new SemVersion(1, 0, 0) }])
54+
};
55+
56+
var result = productApplicability.ToString();
57+
58+
// Should include set properties
59+
result.Should().Contain("apm-agent-dotnet=");
60+
result.Should().Contain("ecctl=");
61+
62+
// Should not include unset properties
63+
result.Should().NotContain("apm-agent-node=");
64+
result.Should().NotContain("curator=");
65+
}
66+
67+
[Fact]
68+
public void ProductApplicability_ToString_Empty_ReturnsEmptyString()
69+
{
70+
var productApplicability = new ProductApplicability();
71+
72+
var result = productApplicability.ToString();
73+
74+
result.Should().Be("");
75+
}
76+
77+
[Fact]
78+
public void ProductApplicability_ToString_PropertyOrder_MatchesReflectionOrder()
79+
{
80+
// This test ensures that properties appear in the order they are defined
81+
var productApplicability = new ProductApplicability
82+
{
83+
Ecctl = AppliesCollection.GenerallyAvailable,
84+
Curator = AppliesCollection.GenerallyAvailable,
85+
ApmAgentAndroid = AppliesCollection.GenerallyAvailable
86+
};
87+
88+
var result = productApplicability.ToString();
89+
90+
// Get the properties in reflection order
91+
var productType = typeof(ProductApplicability);
92+
var properties = productType.GetProperties()
93+
.Where(p => p.GetCustomAttribute<YamlMemberAttribute>() != null)
94+
.Select(p => p.GetCustomAttribute<YamlMemberAttribute>()!.Alias)
95+
.ToList();
96+
97+
// Find positions in the string
98+
var positions = new Dictionary<string, int>();
99+
foreach (var alias in new[] { "ecctl", "curator", "apm-agent-android" })
100+
{
101+
var index = result.IndexOf($"{alias}=", StringComparison.Ordinal);
102+
if (index >= 0)
103+
positions[alias] = index;
104+
}
105+
106+
// Verify that the properties appear in the correct order
107+
positions["ecctl"].Should().BeLessThan(positions["curator"],
108+
"ecctl should appear before curator");
109+
positions["curator"].Should().BeLessThan(positions["apm-agent-android"],
110+
"curator should appear before apm-agent-android");
111+
}
112+
}

0 commit comments

Comments
 (0)