Skip to content

Commit 745d2fb

Browse files
author
Bart Koelman
authored
Various code cleanups in preparation of auto-formatting the codebase (#960)
* Replaced null checks with argument guard * Added curlies on single-statement branches and loops * Normalize blank lines around SaveChangesAsync in tests * use const * Move types into matching files * Adapt namespaces to match with directory structure * Fixed inconsistencies in naming conventions * Remove redundant parenthesis * Fixed culture-specific string comparisons * Use newer syntax for dictionary initializers * Various additional cleanups * Manual code cleanups in preparation for reformat * Extract variable on errors in tests to reduce assertion line length * Hide decimal precision from tests * Rewrite ResponseStatusCode tests using Theory * Fixed naming inconsistencies in tests * Replace FindAsync usage for consistency with other tests * Added formatter directives on fakers * Added formatter directives on DbContext types * Added FirstWithIdAsync / FirstWithIdOrDefaultAsync to reduce line length on database queries in tests * Added formatting directives on long database queries in tests * Reduced line length for links assertions * Variable naming consistency * Break up long strings to steer formatter * Extract constant * cleanup method * Fixed naming conventions Resharper was set to auto-detect, making it ignore configured rules * Additional cleanup based on suggestions from https://docs.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/ * Use helpers to prevent multiple line breaks in array and list initializers * Corrected link rendering for hosting inside an IIS application vdir (#955) Corrected link rendering for hosting inside an IIS application virtual directory * Update version from 4.0.3 to 4.0.4 * Marked types/members sealed/internal where non-breaking * Removed redundancies in code * remove unused tuple elements * Fixed spelling in comments * Added formatter directive to ErrorDocumentTests to prevent array chop * Added [UsedImplicitly] on DbContext classes to suppress suggestions like 'member can be private, set accessor is never used'etc. * Added [UsedImplicitly] on resource services, repositories, definitions and startups * Added [UsedImplicitly] on models * Use discard in empty property setters * Added missing setter * Addressed possible NullReferenceException warnings * Marked assertion methods as such, to suppress warning 'parameter is only used for precondition checks' Note that one suppression is needed, due to a bug in Resharper * Addressed possible multiple enumeration warnings * Suppressed warnings on non-readonly member access in GetHashCode, because these are assigned once at application startup by the resource graph builder and then are considered immutable. * extra: UsedImplicitly on models * Added [PublicAPI] on exposed types to suppress warnings like 'type/member can be made internal', 'type has no inheritors and can be marked sealed', 'member is never written to' etc. * Cleanup Startups * BenchmarkDotNet runners cannot be sealed * Suppress cases of unused TResource type parameter, because we register an open generic for them to enable different implementations per resource type. * Additional cleanup and annotations based on warnings and suggestions * AV1755: Async method name should end with [Task]Async * AV1739: Use underscores for unused lambda parameters * AV1568: Parameter value is overwritten in method body * AV1535: Block scope in case clauses * AV1522: Multiple assignments in single statement * AV1532: Avoid nested loops * AV1010: Member hides inherited member * AV1130: Use collection interface as return type * Fixed: Without the [CustomAssertion] attribute, Fluent Assertions would find the line that calls Subject.StatusCode.Should().Be() and treat the Subject variable as the subject-under-test (SUT). But by applying this attribute, it will ignore this invocation and instead find the SUT by looking for a call to Should().HaveStatusCode() and use the response variable instead.
1 parent b47f705 commit 745d2fb

File tree

646 files changed

+8292
-5482
lines changed

Some content is hidden

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

646 files changed

+8292
-5482
lines changed

benchmarks/BenchmarkResource.cs

+2-12
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1+
using JetBrains.Annotations;
12
using JsonApiDotNetCore.Resources;
23
using JsonApiDotNetCore.Resources.Annotations;
34

45
namespace Benchmarks
56
{
7+
[UsedImplicitly(ImplicitUseTargetFlags.Members)]
68
public sealed class BenchmarkResource : Identifiable
79
{
810
[Attr(PublicName = BenchmarkResourcePublicNames.NameAttr)]
@@ -11,16 +13,4 @@ public sealed class BenchmarkResource : Identifiable
1113
[HasOne]
1214
public SubResource Child { get; set; }
1315
}
14-
15-
public class SubResource : Identifiable
16-
{
17-
[Attr]
18-
public string Value { get; set; }
19-
}
20-
21-
internal static class BenchmarkResourcePublicNames
22-
{
23-
public const string NameAttr = "full-name";
24-
public const string Type = "simple-types";
25-
}
2616
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
namespace Benchmarks
2+
{
3+
internal static class BenchmarkResourcePublicNames
4+
{
5+
public const string NameAttr = "full-name";
6+
public const string Type = "simple-types";
7+
}
8+
}

benchmarks/LinkBuilder/LinkBuilderGetNamespaceFromPathBenchmarks.cs

+5-6
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
namespace Benchmarks.LinkBuilder
66
{
7+
// ReSharper disable once ClassCanBeSealed.Global
78
[MarkdownExporter, SimpleJob(launchCount: 3, warmupCount: 10, targetCount: 20), MemoryDiagnoser]
89
public class LinkBuilderGetNamespaceFromPathBenchmarks
910
{
@@ -17,7 +18,7 @@ public class LinkBuilderGetNamespaceFromPathBenchmarks
1718
[Benchmark]
1819
public void UsingReadOnlySpan() => GetNamespaceFromPathUsingReadOnlySpan(RequestPath, ResourceName);
1920

20-
public static string GetNamespaceFromPathUsingStringSplit(string path, string resourceName)
21+
private static void GetNamespaceFromPathUsingStringSplit(string path, string resourceName)
2122
{
2223
StringBuilder namespaceBuilder = new StringBuilder(path.Length);
2324
string[] segments = path.Split('/');
@@ -33,10 +34,10 @@ public static string GetNamespaceFromPathUsingStringSplit(string path, string re
3334
namespaceBuilder.Append(segments[index]);
3435
}
3536

36-
return namespaceBuilder.ToString();
37+
_ = namespaceBuilder.ToString();
3738
}
3839

39-
public static string GetNamespaceFromPathUsingReadOnlySpan(string path, string resourceName)
40+
private static void GetNamespaceFromPathUsingReadOnlySpan(string path, string resourceName)
4041
{
4142
ReadOnlySpan<char> resourceNameSpan = resourceName.AsSpan();
4243
ReadOnlySpan<char> pathSpan = path.AsSpan();
@@ -57,14 +58,12 @@ public static string GetNamespaceFromPathUsingReadOnlySpan(string path, string r
5758
bool hasDelimiterAfterSegment = pathSpan.Length >= lastCharacterIndex + 1 && pathSpan[lastCharacterIndex].Equals(PathDelimiter);
5859
if (isAtEnd || hasDelimiterAfterSegment)
5960
{
60-
return pathSpan.Slice(0, index).ToString();
61+
_ = pathSpan.Slice(0, index).ToString();
6162
}
6263
}
6364
}
6465
}
6566
}
66-
67-
return string.Empty;
6867
}
6968
}
7069
}

benchmarks/Program.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
namespace Benchmarks
77
{
8-
internal class Program
8+
internal static class Program
99
{
1010
private static void Main(string[] args)
1111
{

benchmarks/Query/QueryParserBenchmarks.cs

+13-12
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
using System;
2-
using System.Collections.Generic;
32
using System.ComponentModel.Design;
43
using BenchmarkDotNet.Attributes;
4+
using JsonApiDotNetCore;
55
using JsonApiDotNetCore.Configuration;
66
using JsonApiDotNetCore.Middleware;
77
using JsonApiDotNetCore.QueryStrings;
@@ -13,6 +13,7 @@
1313

1414
namespace Benchmarks.Query
1515
{
16+
// ReSharper disable once ClassCanBeSealed.Global
1617
[MarkdownExporter, SimpleJob(launchCount: 3, warmupCount: 10, targetCount: 20), MemoryDiagnoser]
1718
public class QueryParserBenchmarks
1819
{
@@ -43,11 +44,8 @@ private static QueryStringReader CreateQueryParameterDiscoveryForSort(IResourceG
4344
JsonApiRequest request, IJsonApiOptions options, FakeRequestQueryStringAccessor queryStringAccessor)
4445
{
4546
var sortReader = new SortQueryStringParameterReader(request, resourceGraph);
46-
47-
var readers = new List<IQueryStringParameterReader>
48-
{
49-
sortReader
50-
};
47+
48+
var readers = sortReader.AsEnumerable();
5149

5250
return new QueryStringReader(options, queryStringAccessor, readers, NullLoggerFactory.Instance);
5351
}
@@ -65,10 +63,7 @@ private static QueryStringReader CreateQueryParameterDiscoveryForAll(IResourceGr
6563
var defaultsReader = new DefaultsQueryStringParameterReader(options);
6664
var nullsReader = new NullsQueryStringParameterReader(options);
6765

68-
var readers = new List<IQueryStringParameterReader>
69-
{
70-
includeReader, filterReader, sortReader, sparseFieldSetReader, paginationReader, defaultsReader, nullsReader
71-
};
66+
var readers = ArrayFactory.Create<IQueryStringParameterReader>(includeReader, filterReader, sortReader, sparseFieldSetReader, paginationReader, defaultsReader, nullsReader);
7267

7368
return new QueryStringReader(options, queryStringAccessor, readers, NullLoggerFactory.Instance);
7469
}
@@ -94,15 +89,21 @@ public void DescendingSort()
9489
[Benchmark]
9590
public void ComplexQuery() => Run(100, () =>
9691
{
97-
var queryString = $"?filter[{BenchmarkResourcePublicNames.NameAttr}]=abc,eq:abc&sort=-{BenchmarkResourcePublicNames.NameAttr}&include=child&page[size]=1&fields[{BenchmarkResourcePublicNames.Type}]={BenchmarkResourcePublicNames.NameAttr}";
92+
const string resourceName = BenchmarkResourcePublicNames.Type;
93+
const string attrName = BenchmarkResourcePublicNames.NameAttr;
94+
95+
var queryString = $"?filter[{attrName}]=abc,eq:abc&sort=-{attrName}&include=child&page[size]=1&fields[{resourceName}]={attrName}";
9896

9997
_queryStringAccessor.SetQueryString(queryString);
10098
_queryStringReaderForAll.ReadAll(null);
10199
});
102100

103-
private void Run(int iterations, Action action) {
101+
private void Run(int iterations, Action action)
102+
{
104103
for (int i = 0; i < iterations; i++)
104+
{
105105
action();
106+
}
106107
}
107108

108109
private sealed class FakeRequestQueryStringAccessor : IRequestQueryStringAccessor

benchmarks/Serialization/JsonApiDeserializerBenchmarks.cs

+6-5
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
namespace Benchmarks.Serialization
1414
{
15+
// ReSharper disable once ClassCanBeSealed.Global
1516
[MarkdownExporter]
1617
public class JsonApiDeserializerBenchmarks
1718
{
@@ -23,10 +24,7 @@ public class JsonApiDeserializerBenchmarks
2324
Id = "1",
2425
Attributes = new Dictionary<string, object>
2526
{
26-
{
27-
"name",
28-
Guid.NewGuid().ToString()
29-
}
27+
["name"] = Guid.NewGuid().ToString()
3028
}
3129
}
3230
});
@@ -39,7 +37,10 @@ public JsonApiDeserializerBenchmarks()
3937
IResourceGraph resourceGraph = DependencyFactory.CreateResourceGraph(options);
4038
var targetedFields = new TargetedFields();
4139
var request = new JsonApiRequest();
42-
_jsonApiDeserializer = new RequestDeserializer(resourceGraph, new ResourceFactory(new ServiceContainer()), targetedFields, new HttpContextAccessor(), request, options);
40+
var resourceFactory = new ResourceFactory(new ServiceContainer());
41+
var httpContextAccessor = new HttpContextAccessor();
42+
43+
_jsonApiDeserializer = new RequestDeserializer(resourceGraph, resourceFactory, targetedFields, httpContextAccessor, request, options);
4344
}
4445

4546
[Benchmark]

benchmarks/Serialization/JsonApiSerializerBenchmarks.cs

+3-2
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,11 @@
1111

1212
namespace Benchmarks.Serialization
1313
{
14+
// ReSharper disable once ClassCanBeSealed.Global
1415
[MarkdownExporter]
1516
public class JsonApiSerializerBenchmarks
1617
{
17-
private static readonly BenchmarkResource _content = new BenchmarkResource
18+
private static readonly BenchmarkResource Content = new BenchmarkResource
1819
{
1920
Id = 123,
2021
Name = Guid.NewGuid().ToString()
@@ -53,6 +54,6 @@ private static FieldsToSerialize CreateFieldsToSerialize(IResourceGraph resource
5354
}
5455

5556
[Benchmark]
56-
public object SerializeSimpleObject() => _jsonApiSerializer.Serialize(_content);
57+
public object SerializeSimpleObject() => _jsonApiSerializer.Serialize(Content);
5758
}
5859
}

benchmarks/SubResource.cs

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
using JetBrains.Annotations;
2+
using JsonApiDotNetCore.Resources;
3+
using JsonApiDotNetCore.Resources.Annotations;
4+
5+
namespace Benchmarks
6+
{
7+
[UsedImplicitly(ImplicitUseTargetFlags.Members)]
8+
public sealed class SubResource : Identifiable
9+
{
10+
[Attr]
11+
public string Value { get; set; }
12+
}
13+
}

src/Examples/GettingStarted/Data/SampleDbContext.cs

+2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
using GettingStarted.Models;
2+
using JetBrains.Annotations;
23
using Microsoft.EntityFrameworkCore;
34

45
namespace GettingStarted.Data
56
{
7+
[UsedImplicitly(ImplicitUseTargetFlags.Members)]
68
public class SampleDbContext : DbContext
79
{
810
public DbSet<Book> Books { get; set; }

src/Examples/GettingStarted/Models/Book.cs

+2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1+
using JetBrains.Annotations;
12
using JsonApiDotNetCore.Resources;
23
using JsonApiDotNetCore.Resources.Annotations;
34

45
namespace GettingStarted.Models
56
{
7+
[UsedImplicitly(ImplicitUseTargetFlags.Members)]
68
public sealed class Book : Identifiable
79
{
810
[Attr]

src/Examples/GettingStarted/Models/Person.cs

+2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
using System.Collections.Generic;
2+
using JetBrains.Annotations;
23
using JsonApiDotNetCore.Resources;
34
using JsonApiDotNetCore.Resources.Annotations;
45

56
namespace GettingStarted.Models
67
{
8+
[UsedImplicitly(ImplicitUseTargetFlags.Members)]
79
public sealed class Person : Identifiable
810
{
911
[Attr]

src/Examples/GettingStarted/Program.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,14 @@
33

44
namespace GettingStarted
55
{
6-
public class Program
6+
internal static class Program
77
{
88
public static void Main(string[] args)
99
{
1010
CreateHostBuilder(args).Build().Run();
1111
}
1212

13-
public static IHostBuilder CreateHostBuilder(string[] args) =>
13+
private static IHostBuilder CreateHostBuilder(string[] args) =>
1414
Host.CreateDefaultBuilder(args)
1515
.ConfigureWebHostDefaults(webBuilder =>
1616
{

src/Examples/GettingStarted/Startup.cs

+2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using GettingStarted.Data;
22
using GettingStarted.Models;
3+
using JetBrains.Annotations;
34
using JsonApiDotNetCore.Configuration;
45
using Microsoft.AspNetCore.Builder;
56
using Microsoft.EntityFrameworkCore;
@@ -27,6 +28,7 @@ public void ConfigureServices(IServiceCollection services)
2728
}
2829

2930
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
31+
[UsedImplicitly]
3032
public void Configure(IApplicationBuilder app, SampleDbContext context)
3133
{
3234
context.Database.EnsureDeleted();

src/Examples/JsonApiDotNetCoreExample/Data/AppDbContext.cs

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
1+
using JetBrains.Annotations;
12
using JsonApiDotNetCoreExample.Models;
23
using Microsoft.EntityFrameworkCore;
34

5+
// @formatter:wrap_chained_method_calls chop_always
6+
47
namespace JsonApiDotNetCoreExample.Data
58
{
9+
[UsedImplicitly(ImplicitUseTargetFlags.Members)]
610
public sealed class AppDbContext : DbContext
711
{
812
public DbSet<TodoItem> TodoItems { get; set; }
@@ -37,7 +41,7 @@ protected override void OnModelCreating(ModelBuilder builder)
3741
.OnDelete(DeleteBehavior.Cascade);
3842

3943
builder.Entity<TodoItem>()
40-
.HasMany(t => t.ChildrenTodos)
44+
.HasMany(t => t.ChildTodoItems)
4145
.WithOne(t => t.ParentTodo);
4246

4347
builder.Entity<Passport>()

src/Examples/JsonApiDotNetCoreExample/Definitions/ArticleHooksDefinition.cs

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System.Collections.Generic;
22
using System.Linq;
33
using System.Net;
4+
using JetBrains.Annotations;
45
using JsonApiDotNetCore.Configuration;
56
using JsonApiDotNetCore.Errors;
67
using JsonApiDotNetCore.Hooks.Internal.Execution;
@@ -10,7 +11,8 @@
1011

1112
namespace JsonApiDotNetCoreExample.Definitions
1213
{
13-
public class ArticleHooksDefinition : ResourceHooksDefinition<Article>
14+
[UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)]
15+
public sealed class ArticleHooksDefinition : ResourceHooksDefinition<Article>
1416
{
1517
public ArticleHooksDefinition(IResourceGraph resourceGraph) : base(resourceGraph) { }
1618

src/Examples/JsonApiDotNetCoreExample/Definitions/LockableHooksDefinition.cs

+2-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@ protected void DisallowLocked(IEnumerable<T> resources)
2525
{
2626
throw new JsonApiException(new Error(HttpStatusCode.Forbidden)
2727
{
28-
Title = $"You are not allowed to update fields or relationships of locked resource of type '{_resourceGraph.GetResourceContext<T>().PublicName}'."
28+
Title = "You are not allowed to update fields or relationships of " +
29+
$"locked resource of type '{_resourceGraph.GetResourceContext<T>().PublicName}'."
2930
});
3031
}
3132
}

src/Examples/JsonApiDotNetCoreExample/Definitions/PassportHooksDefinition.cs

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System.Collections.Generic;
22
using System.Linq;
33
using System.Net;
4+
using JetBrains.Annotations;
45
using JsonApiDotNetCore.Configuration;
56
using JsonApiDotNetCore.Errors;
67
using JsonApiDotNetCore.Hooks.Internal.Execution;
@@ -9,7 +10,8 @@
910

1011
namespace JsonApiDotNetCoreExample.Definitions
1112
{
12-
public class PassportHooksDefinition : LockableHooksDefinition<Passport>
13+
[UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)]
14+
public sealed class PassportHooksDefinition : LockableHooksDefinition<Passport>
1315
{
1416
public PassportHooksDefinition(IResourceGraph resourceGraph) : base(resourceGraph)
1517
{

src/Examples/JsonApiDotNetCoreExample/Definitions/PersonHooksDefinition.cs

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
using System.Collections.Generic;
22
using System.Linq;
3+
using JetBrains.Annotations;
34
using JsonApiDotNetCore.Configuration;
45
using JsonApiDotNetCore.Hooks.Internal.Execution;
56
using JsonApiDotNetCoreExample.Models;
67

78
namespace JsonApiDotNetCoreExample.Definitions
89
{
9-
public class PersonHooksDefinition : LockableHooksDefinition<Person>
10+
[UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)]
11+
public sealed class PersonHooksDefinition : LockableHooksDefinition<Person>
1012
{
1113
public PersonHooksDefinition(IResourceGraph resourceGraph) : base(resourceGraph) { }
1214

0 commit comments

Comments
 (0)