Skip to content

Commit 3ef75b2

Browse files
committed
Improve code coverage by skipping unreachable code
1 parent fb78af3 commit 3ef75b2

14 files changed

+43
-90
lines changed

Diff for: src/JsonApiDotNetCore.Annotations/ArgumentGuard.cs

+18
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
using System.Diagnostics;
2+
using System.Diagnostics.CodeAnalysis;
13
using System.Runtime.CompilerServices;
24
using JetBrains.Annotations;
35
using SysNotNull = System.Diagnostics.CodeAnalysis.NotNullAttribute;
@@ -19,4 +21,20 @@ public static void NotNullNorEmpty<T>([SysNotNull] IEnumerable<T>? value, [Calle
1921
throw new ArgumentException("Collection cannot be null or empty.", parameterName);
2022
}
2123
}
24+
25+
[ExcludeFromCodeCoverage]
26+
public static void ThrowUnreachableExceptionIf([DoesNotReturnIf(true)] bool condition)
27+
{
28+
if (condition)
29+
{
30+
throw new UnreachableException();
31+
}
32+
}
33+
34+
[ExcludeFromCodeCoverage]
35+
[DoesNotReturn]
36+
public static T ThrowUnreachableException<T>()
37+
{
38+
throw new UnreachableException();
39+
}
2240
}

Diff for: src/JsonApiDotNetCore.OpenApi.Swashbuckle/JsonApiActionDescriptorCollectionProvider.cs

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
using System.Diagnostics;
21
using System.Reflection;
32
using JsonApiDotNetCore.Errors;
43
using JsonApiDotNetCore.Middleware;
@@ -126,7 +125,7 @@ private static void UpdateProducesResponseTypeAttribute(ActionDescriptor endpoin
126125
}
127126
}
128127

129-
throw new UnreachableException();
128+
ArgumentGuard.ThrowUnreachableExceptionIf(true);
130129
}
131130

132131
private static bool ProducesJsonApiResponseDocument(ActionDescriptor endpoint)

Diff for: src/JsonApiDotNetCore.OpenApi.Swashbuckle/JsonApiMetadata/JsonApiEndpointMetadataProvider.cs

+1-6
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
using System.Diagnostics;
21
using System.Reflection;
32
using JsonApiDotNetCore.Configuration;
43
using JsonApiDotNetCore.Controllers;
@@ -43,11 +42,7 @@ public JsonApiEndpointMetadataContainer Get(MethodInfo controllerAction)
4342
}
4443

4544
ResourceType? primaryResourceType = _controllerResourceMapping.GetResourceTypeForController(controllerAction.ReflectedType);
46-
47-
if (primaryResourceType == null)
48-
{
49-
throw new UnreachableException();
50-
}
45+
ArgumentGuard.ThrowUnreachableExceptionIf(primaryResourceType == null);
5146

5247
IJsonApiRequestMetadata? requestMetadata = GetRequestMetadata(endpoint, primaryResourceType);
5348
IJsonApiResponseMetadata? responseMetadata = GetResponseMetadata(endpoint, primaryResourceType);

Diff for: src/JsonApiDotNetCore.OpenApi.Swashbuckle/OpenApiEndpointConvention.cs

+3-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
using System.Diagnostics;
21
using System.Net;
32
using System.Reflection;
43
using JsonApiDotNetCore.Configuration;
@@ -109,7 +108,7 @@ private static bool IsEndpointAvailable(JsonApiEndpoints endpoint, ResourceType
109108
JsonApiEndpoints.PatchRelationship => availableEndpoints.HasFlag(JsonApiEndpoints.PatchRelationship),
110109
JsonApiEndpoints.Delete => availableEndpoints.HasFlag(JsonApiEndpoints.Delete),
111110
JsonApiEndpoints.DeleteRelationship => availableEndpoints.HasFlag(JsonApiEndpoints.DeleteRelationship),
112-
_ => throw new UnreachableException()
111+
_ => ArgumentGuard.ThrowUnreachableException<bool>()
113112
};
114113
}
115114

@@ -179,7 +178,7 @@ private static HttpStatusCode[] GetSuccessStatusCodesForEndpoint(JsonApiEndpoint
179178
[
180179
HttpStatusCode.NoContent
181180
],
182-
_ => throw new UnreachableException()
181+
_ => ArgumentGuard.ThrowUnreachableException<HttpStatusCode[]>()
183182
};
184183
}
185184

@@ -238,7 +237,7 @@ private HttpStatusCode[] GetErrorStatusCodesForEndpoint(JsonApiEndpointWrapper e
238237
HttpStatusCode.Conflict,
239238
HttpStatusCode.UnprocessableEntity
240239
],
241-
_ => throw new UnreachableException()
240+
_ => ArgumentGuard.ThrowUnreachableException<HttpStatusCode[]>()
242241
};
243242
}
244243

Diff for: src/JsonApiDotNetCore.OpenApi.Swashbuckle/OpenApiOperationIdSelector.cs

+3-16
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
using System.Diagnostics;
21
using System.Reflection;
32
using System.Text.Json;
43
using Humanizer;
@@ -64,23 +63,14 @@ public string GetOpenApiOperationId(ApiDescription endpoint)
6463
private static string GetTemplate(ApiDescription endpoint)
6564
{
6665
Type bodyType = GetBodyType(endpoint);
67-
68-
if (!SchemaOpenTypeToOpenApiOperationIdTemplateMap.TryGetValue(bodyType, out string? template))
69-
{
70-
throw new UnreachableException();
71-
}
72-
66+
ArgumentGuard.ThrowUnreachableExceptionIf(!SchemaOpenTypeToOpenApiOperationIdTemplateMap.TryGetValue(bodyType, out string? template));
7367
return template;
7468
}
7569

7670
private static Type GetBodyType(ApiDescription endpoint)
7771
{
7872
var producesResponseTypeAttribute = endpoint.ActionDescriptor.GetFilterMetadata<ProducesResponseTypeAttribute>();
79-
80-
if (producesResponseTypeAttribute == null)
81-
{
82-
throw new UnreachableException();
83-
}
73+
ArgumentGuard.ThrowUnreachableExceptionIf(producesResponseTypeAttribute == null);
8474

8575
ControllerParameterDescriptor? requestBodyDescriptor = endpoint.ActionDescriptor.GetBodyParameterDescriptor();
8676
Type bodyType = (requestBodyDescriptor?.ParameterType ?? producesResponseTypeAttribute.Type).ConstructedToOpenType();
@@ -95,10 +85,7 @@ private static Type GetBodyType(ApiDescription endpoint)
9585

9686
private string ApplyTemplate(string openApiOperationIdTemplate, ResourceType? resourceType, ApiDescription endpoint)
9787
{
98-
if (endpoint.RelativePath == null || endpoint.HttpMethod == null)
99-
{
100-
throw new UnreachableException();
101-
}
88+
ArgumentGuard.ThrowUnreachableExceptionIf(endpoint.RelativePath == null || endpoint.HttpMethod == null);
10289

10390
string method = endpoint.HttpMethod.ToLowerInvariant();
10491
string relationshipName = openApiOperationIdTemplate.Contains("[RelationshipName]") ? endpoint.RelativePath.Split('/').Last() : string.Empty;

Diff for: src/JsonApiDotNetCore.OpenApi.Swashbuckle/OpenApiSchemaExtensions.cs

+1-5
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
using System.Diagnostics;
21
using Microsoft.OpenApi.Models;
32

43
namespace JsonApiDotNetCore.OpenApi.Swashbuckle;
@@ -20,10 +19,7 @@ public static void ReorderProperties(this OpenApiSchema fullSchema, IEnumerable<
2019
}
2120
}
2221

23-
if (fullSchema.Properties.Count != propertiesInOrder.Count)
24-
{
25-
throw new UnreachableException();
26-
}
22+
ArgumentGuard.ThrowUnreachableExceptionIf(fullSchema.Properties.Count != propertiesInOrder.Count);
2723

2824
fullSchema.Properties = propertiesInOrder;
2925
}

Diff for: src/JsonApiDotNetCore.OpenApi.Swashbuckle/SchemaGenerators/Components/DataContainerSchemaGenerator.cs

+2-10
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
using System.Diagnostics;
21
using System.Reflection;
32
using JsonApiDotNetCore.Configuration;
43
using JsonApiDotNetCore.OpenApi.Swashbuckle.JsonApiObjects.ResourceObjects;
@@ -64,11 +63,7 @@ public OpenApiSchema GenerateSchema(Type dataContainerSchemaType, ResourceType r
6463
private static Type GetElementTypeOfDataProperty(Type dataContainerConstructedType, ResourceType resourceType)
6564
{
6665
PropertyInfo? dataProperty = dataContainerConstructedType.GetProperty("Data");
67-
68-
if (dataProperty == null)
69-
{
70-
throw new UnreachableException();
71-
}
66+
ArgumentGuard.ThrowUnreachableExceptionIf(dataProperty == null);
7267

7368
Type innerPropertyType = dataProperty.PropertyType.ConstructedToOpenType().IsAssignableTo(typeof(ICollection<>))
7469
? dataProperty.PropertyType.GenericTypeArguments[0]
@@ -79,10 +74,7 @@ private static Type GetElementTypeOfDataProperty(Type dataContainerConstructedTy
7974
return typeof(DataInResponse<>).MakeGenericType(resourceType.ClrType);
8075
}
8176

82-
if (!innerPropertyType.IsGenericType)
83-
{
84-
throw new UnreachableException();
85-
}
77+
ArgumentGuard.ThrowUnreachableExceptionIf(!innerPropertyType.IsGenericType);
8678

8779
return innerPropertyType;
8880
}

Diff for: src/JsonApiDotNetCore.OpenApi.Swashbuckle/SchemaGenerators/Components/DataSchemaGenerator.cs

+3-12
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
using System.Collections.Concurrent;
2-
using System.Diagnostics;
32
using System.Reflection;
43
using JsonApiDotNetCore.Configuration;
54
using JsonApiDotNetCore.OpenApi.Swashbuckle.JsonApiMetadata;
@@ -199,7 +198,7 @@ public OpenApiSchema GenerateSchema(Type dataSchemaType, bool forRequestSchema,
199198
return typeof(RelationshipsInResponse);
200199
}
201200

202-
throw new UnreachableException();
201+
return ArgumentGuard.ThrowUnreachableException<Type?>();
203202
}
204203

205204
public OpenApiSchema GenerateSchemaForCommonData(Type commonDataSchemaType, SchemaRepository schemaRepository)
@@ -390,11 +389,7 @@ private void SetFieldSchemaMembers(OpenApiSchema fullSchemaForData, ResourceSche
390389
GetResourceSchemaTypeForFieldsProperty(resourceSchemaTypeForData, forAttributes ? "Attributes" : "Relationships");
391390

392391
Type? commonFieldsSchemaType = GetCommonSchemaType(resourceSchemaTypeForFields.SchemaOpenType);
393-
394-
if (commonFieldsSchemaType == null)
395-
{
396-
throw new UnreachableException();
397-
}
392+
ArgumentGuard.ThrowUnreachableExceptionIf(commonFieldsSchemaType == null);
398393

399394
_ = GenerateSchemaForCommonFields(commonFieldsSchemaType, schemaRepository);
400395

@@ -432,11 +427,7 @@ private void SetFieldSchemaMembers(OpenApiSchema fullSchemaForData, ResourceSche
432427
private ResourceSchemaType GetResourceSchemaTypeForFieldsProperty(ResourceSchemaType resourceSchemaTypeForData, string propertyName)
433428
{
434429
PropertyInfo? fieldsProperty = resourceSchemaTypeForData.SchemaConstructedType.GetProperty(propertyName);
435-
436-
if (fieldsProperty == null)
437-
{
438-
throw new UnreachableException();
439-
}
430+
ArgumentGuard.ThrowUnreachableExceptionIf(fieldsProperty == null);
440431

441432
Type fieldsConstructedType = fieldsProperty.PropertyType;
442433
return ResourceSchemaType.Create(fieldsConstructedType, _resourceGraph);

Diff for: src/JsonApiDotNetCore.OpenApi.Swashbuckle/SchemaGenerators/Components/RelationshipIdentifierSchemaGenerator.cs

+1-6
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
using System.Diagnostics;
21
using JsonApiDotNetCore.Configuration;
32
using JsonApiDotNetCore.OpenApi.Swashbuckle.JsonApiObjects.ResourceObjects;
43
using JsonApiDotNetCore.Resources.Annotations;
@@ -52,11 +51,7 @@ public OpenApiSchema GenerateSchema(RelationshipAttribute relationship, SchemaRe
5251
}
5352

5453
Type relationshipIdentifierConstructedType = typeof(RelationshipIdentifier<>).MakeGenericType(relationship.LeftType.ClrType);
55-
56-
if (schemaRepository.TryLookupByType(relationshipIdentifierConstructedType, out _))
57-
{
58-
throw new UnreachableException();
59-
}
54+
ArgumentGuard.ThrowUnreachableExceptionIf(schemaRepository.TryLookupByType(relationshipIdentifierConstructedType, out _));
6055

6156
OpenApiSchema referenceSchemaForIdentifier = _defaultSchemaGenerator.GenerateSchema(relationshipIdentifierConstructedType, schemaRepository);
6257
OpenApiSchema fullSchemaForIdentifier = schemaRepository.Schemas[referenceSchemaForIdentifier.Reference.Id];

Diff for: src/JsonApiDotNetCore.OpenApi.Swashbuckle/SchemaGenerators/Documents/AtomicOperationsDocumentSchemaGenerator.cs

+5-10
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
using System.Diagnostics;
21
using JsonApiDotNetCore.AtomicOperations;
32
using JsonApiDotNetCore.Configuration;
43
using JsonApiDotNetCore.Middleware;
@@ -163,7 +162,7 @@ private void GenerateSchemaForResourceOperation(Type operationOpenType, Resource
163162
AtomicOperationCode.Add => WriteOperationKind.CreateResource,
164163
AtomicOperationCode.Update => WriteOperationKind.UpdateResource,
165164
AtomicOperationCode.Remove => WriteOperationKind.DeleteResource,
166-
_ => throw new UnreachableException()
165+
_ => ArgumentGuard.ThrowUnreachableException<WriteOperationKind>()
167166
};
168167

169168
if (IsResourceTypeEnabled(resourceType, writeOperation))
@@ -282,7 +281,7 @@ private void GenerateSchemaForRelationshipOperation(Type operationOpenType, Rela
282281
AtomicOperationCode.Add => WriteOperationKind.AddToRelationship,
283282
AtomicOperationCode.Update => WriteOperationKind.SetRelationship,
284283
AtomicOperationCode.Remove => WriteOperationKind.RemoveFromRelationship,
285-
_ => throw new UnreachableException()
284+
_ => ArgumentGuard.ThrowUnreachableException<WriteOperationKind>()
286285
};
287286

288287
if (!IsRelationshipEnabled(relationship, writeOperation))
@@ -336,11 +335,7 @@ private void GenerateSchemaForRelationshipOperation(Type operationOpenType, Rela
336335
RemoveProperties(inlineSchemaForOperation);
337336

338337
string baseRelationshipSchemaId = _schemaIdSelector.GetRelationshipAtomicOperationSchemaId(relationshipInAnyBaseResourceType, operationCode);
339-
340-
if (!schemaRepository.Schemas.ContainsKey(baseRelationshipSchemaId))
341-
{
342-
throw new UnreachableException();
343-
}
338+
ArgumentGuard.ThrowUnreachableExceptionIf(!schemaRepository.Schemas.ContainsKey(baseRelationshipSchemaId));
344339

345340
fullSchemaForOperation.AllOf[0] = new OpenApiSchema
346341
{
@@ -381,7 +376,7 @@ private static bool IsToOneRelationshipEnabled(HasOneAttribute relationship, Wri
381376
return writeOperation switch
382377
{
383378
WriteOperationKind.SetRelationship => relationship.Capabilities.HasFlag(HasOneCapabilities.AllowSet),
384-
_ => throw new UnreachableException()
379+
_ => ArgumentGuard.ThrowUnreachableException<bool>()
385380
};
386381
}
387382

@@ -392,7 +387,7 @@ private static bool IsToManyRelationshipEnabled(HasManyAttribute relationship, W
392387
WriteOperationKind.SetRelationship => relationship.Capabilities.HasFlag(HasManyCapabilities.AllowSet),
393388
WriteOperationKind.AddToRelationship => relationship.Capabilities.HasFlag(HasManyCapabilities.AllowAdd),
394389
WriteOperationKind.RemoveFromRelationship => relationship.Capabilities.HasFlag(HasManyCapabilities.AllowRemove),
395-
_ => throw new UnreachableException()
390+
_ => ArgumentGuard.ThrowUnreachableException<bool>()
396391
};
397392
}
398393

Diff for: src/JsonApiDotNetCore.OpenApi.Swashbuckle/SchemaGenerators/JsonApiSchemaGenerator.cs

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
using System.Diagnostics;
21
using System.Reflection;
32
using JsonApiDotNetCore.Controllers;
43
using JsonApiDotNetCore.OpenApi.Swashbuckle.SchemaGenerators.Components;
@@ -62,6 +61,6 @@ private DocumentSchemaGenerator GetDocumentSchemaGenerator(Type schemaType)
6261
}
6362
}
6463

65-
throw new UnreachableException();
64+
return ArgumentGuard.ThrowUnreachableException<DocumentSchemaGenerator>();
6665
}
6766
}

Diff for: src/JsonApiDotNetCore.OpenApi.Swashbuckle/SwaggerComponents/DocumentationOpenApiOperationFilter.cs

+1-5
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
using System.Diagnostics;
21
using System.Net;
32
using System.Reflection;
43
using Humanizer;
@@ -439,10 +438,7 @@ private void ApplyDeleteRelationship(OpenApiOperation operation, RelationshipAtt
439438

440439
private static RelationshipAttribute GetRelationshipFromRoute(ApiDescription apiDescription, ResourceType resourceType)
441440
{
442-
if (apiDescription.RelativePath == null)
443-
{
444-
throw new UnreachableException();
445-
}
441+
ArgumentGuard.ThrowUnreachableExceptionIf(apiDescription.RelativePath == null);
446442

447443
string relationshipName = apiDescription.RelativePath.Split('/').Last();
448444
return resourceType.GetRelationshipByPublicName(relationshipName);

Diff for: src/JsonApiDotNetCore.OpenApi.Swashbuckle/SwaggerComponents/ResourceFieldSchemaBuilder.cs

+2-6
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
using System.Diagnostics;
21
using System.Reflection;
32
using JsonApiDotNetCore.OpenApi.Swashbuckle.JsonApiMetadata;
43
using JsonApiDotNetCore.OpenApi.Swashbuckle.JsonApiObjects.ResourceObjects;
@@ -110,7 +109,7 @@ private static AttrCapabilities GetRequiredCapabilityForAttributes(Type resource
110109
{
111110
return resourceDataOpenType == typeof(DataInResponse<>) ? AttrCapabilities.AllowView :
112111
resourceDataOpenType == typeof(DataInCreateRequest<>) ? AttrCapabilities.AllowCreate :
113-
resourceDataOpenType == typeof(DataInUpdateRequest<>) ? AttrCapabilities.AllowChange : throw new UnreachableException();
112+
resourceDataOpenType == typeof(DataInUpdateRequest<>) ? AttrCapabilities.AllowChange : ArgumentGuard.ThrowUnreachableException<AttrCapabilities>();
114113
}
115114

116115
private void EnsureAttributeSchemaIsExposed(OpenApiSchema referenceSchemaForAttribute, AttrAttribute attribute, SchemaRepository schemaRepository)
@@ -221,9 +220,6 @@ private OpenApiSchema CreateReferenceSchemaForRelationship(Type relationshipSche
221220

222221
private static void AssertHasNoProperties(OpenApiSchema fullSchema)
223222
{
224-
if (fullSchema.Properties.Count > 0)
225-
{
226-
throw new UnreachableException();
227-
}
223+
ArgumentGuard.ThrowUnreachableExceptionIf(fullSchema.Properties.Count > 0);
228224
}
229225
}

Diff for: src/JsonApiDotNetCore.OpenApi.Swashbuckle/SwaggerComponents/StringEnumOrderingFilter.cs

+1-6
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
using System.Diagnostics;
21
using JetBrains.Annotations;
32
using Microsoft.OpenApi.Any;
43
using Microsoft.OpenApi.Interfaces;
@@ -47,11 +46,7 @@ private static bool HasSortAnnotation(OpenApiSchema schema)
4746
private static void OrderEnumMembers(OpenApiSchema schema)
4847
{
4948
List<IOpenApiAny> ordered = schema.Enum.OfType<OpenApiString>().OrderBy(openApiString => openApiString.Value).Cast<IOpenApiAny>().ToList();
50-
51-
if (ordered.Count != schema.Enum.Count)
52-
{
53-
throw new UnreachableException();
54-
}
49+
ArgumentGuard.ThrowUnreachableExceptionIf(ordered.Count != schema.Enum.Count);
5550

5651
schema.Enum = ordered;
5752
}

0 commit comments

Comments
 (0)