diff --git a/.editorconfig b/.editorconfig index 048ee54..219bb1f 100644 --- a/.editorconfig +++ b/.editorconfig @@ -3,28 +3,26 @@ root = true [*] +charset = utf-8 indent_style = tab insert_final_newline = true # Build scripts [*.{yml,yaml}] -indent_style = spaces indent_size = 2 -# Code files -[*.{cs,csx,vb,vbx}] -indent_size = 4 -charset = utf-8-bom - # XML project files [*.{csproj,vbproj,vcxproj,vcxproj.filters,proj,projitems,shproj,props,targets,ruleset,config,nuspec,resx,vsixmanifest,vsct}] +indent_style = tab indent_size = 2 -# Dotnet code style settings: +# Code files [*.cs] +indent_size = 4 +tab_width = 4 +max_line_length = 150 -# IDE0055: Fix formatting -dotnet_diagnostic.IDE0055.severity = warning +## Dotnet code style settings: # Sort using and Import directives with System.* appearing first dotnet_sort_system_directives_first = true @@ -34,10 +32,10 @@ dotnet_separate_import_directive_groups = false dotnet_style_require_accessibility_modifiers = for_non_interface_members:error # Avoid "this." and "Me." if not necessary -dotnet_style_qualification_for_field = false:refactoring -dotnet_style_qualification_for_property = false:refactoring -dotnet_style_qualification_for_method = false:refactoring -dotnet_style_qualification_for_event = false:refactoring +dotnet_style_qualification_for_field = false +dotnet_style_qualification_for_property = false +dotnet_style_qualification_for_method = false +dotnet_style_qualification_for_event = false # Use language keywords instead of framework type names for type references dotnet_style_predefined_type_for_locals_parameters_members = true:error @@ -49,11 +47,7 @@ dotnet_style_collection_initializer = true:suggestion dotnet_style_coalesce_expression = true:suggestion dotnet_style_null_propagation = true:suggestion dotnet_style_explicit_tuple_names = true:suggestion -dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion dotnet_style_prefer_compound_assignment = true:warning -dotnet_style_prefer_auto_properties = true:silent -dotnet_style_prefer_simplified_boolean_expressions = true:suggestion -dotnet_style_operator_placement_when_wrapping = beginning_of_line # Constants are PascalCase dotnet_naming_rule.constants_should_be_pascal_case.severity = suggestion @@ -87,16 +81,15 @@ dotnet_naming_symbols.non_private_static_fields.required_modifiers = static dotnet_naming_style.non_private_static_field_style.capitalization = pascal_case -# Static fields are camelCase and start with s_ -dotnet_naming_rule.static_fields_should_be_camel_case.severity = suggestion -dotnet_naming_rule.static_fields_should_be_camel_case.symbols = static_fields -dotnet_naming_rule.static_fields_should_be_camel_case.style = static_field_style +# Static fields are PascalCase +dotnet_naming_rule.static_fields_should_be_pascal_case.severity = suggestion +dotnet_naming_rule.static_fields_should_be_pascal_case.symbols = static_fields +dotnet_naming_rule.static_fields_should_be_pascal_case.style = static_field_style dotnet_naming_symbols.static_fields.applicable_kinds = field dotnet_naming_symbols.static_fields.required_modifiers = static -dotnet_naming_style.static_field_style.capitalization = camel_case -dotnet_naming_style.static_field_style.required_prefix = s_ +dotnet_naming_style.static_field_style.capitalization = pascal_case # Instance fields are camelCase and start with _ dotnet_naming_rule.instance_fields_should_be_camel_case.severity = suggestion @@ -135,8 +128,8 @@ dotnet_naming_symbols.all_members.applicable_kinds = * dotnet_naming_style.pascal_case_style.capitalization = pascal_case -# CSharp code style settings: -[*.cs] +## C# style settings: + # Newline settings csharp_new_line_before_open_brace = all csharp_new_line_before_else = true @@ -166,6 +159,9 @@ csharp_style_expression_bodied_operators = false:none csharp_style_expression_bodied_lambdas = true:silent csharp_style_expression_bodied_local_functions = true:silent +# Prefer local method constructs to have a block body +csharp_style_expression_bodied_local_functions = true:suggestion + # Prefer property-like constructs to have an expression-body csharp_style_expression_bodied_properties = true:suggestion csharp_style_expression_bodied_indexers = true:suggestion @@ -212,18 +208,25 @@ csharp_space_between_parentheses = false csharp_space_between_square_brackets = false # Blocks are allowed -csharp_prefer_braces = true:silent -csharp_preserve_single_line_blocks = true:silent -csharp_preserve_single_line_statements = true:silent +csharp_prefer_braces = when_multiline:silent +csharp_preserve_single_line_blocks = true +csharp_preserve_single_line_statements = true -# Specific diagnostics +# Style Analytics +dotnet_analyzer_diagnostic.category-Style.severity = warning +dotnet_diagnostic.IDE0046.severity = none # IDE0046: Convert to conditional expression +dotnet_diagnostic.IDE0130.severity = none # IDE0130: Namespace does not match folder structure + +# XML Documentation dotnet_diagnostic.CS0105.severity = error # CS0105: Using directive is unnecessary. +dotnet_diagnostic.CS1573.severity = error # CS1573: Missing XML comment for parameter +dotnet_diagnostic.CS1591.severity = error # CS1591: Missing XML comment for publicly visible type or member +dotnet_diagnostic.CS1712.severity = error # CS1712: Type parameter has no matching typeparam tag in the XML comment (but other type parameters do) # Async dotnet_diagnostic.CS1998.severity = error # CS1998: Async method lacks 'await' operators and will run synchronously dotnet_diagnostic.CS4014.severity = error # CS4014: Because this call is not awaited, execution of the current method continues before the call is completed -dotnet_diagnostic.CA2007.severity = none # CA2007: Consider calling ConfigureAwait on the awaited task +dotnet_diagnostic.CA2007.severity = error # CA2007: Consider calling ConfigureAwait on the awaited task -# Documentation -dotnet_diagnostic.CS1573.severity = error # CS1573: Missing XML comment for parameter -dotnet_diagnostic.CS1591.severity = error # CS1591: Missing XML comment for publicly visible type or member +# Dispose things need disposing +dotnet_diagnostic.CA2000.severity = error # CA2000: Dispose objects before losing scope diff --git a/AlphaVantage.Net.sln b/AlphaVantage.Net.sln index c81a47c..d38b68a 100644 --- a/AlphaVantage.Net.sln +++ b/AlphaVantage.Net.sln @@ -11,6 +11,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".root", ".root", "{D5051E17 .github\workflows\build.yml = .github\workflows\build.yml .github\dependabot.yml = .github\dependabot.yml Directory.Build.props = Directory.Build.props + Directory.Packages.props = Directory.Packages.props LICENSE.txt = LICENSE.txt readme.md = readme.md EndProjectSection diff --git a/Directory.Build.props b/Directory.Build.props index 8dfa88a..5c374c4 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -9,6 +9,8 @@ latest-all true + + true diff --git a/Directory.Packages.props b/Directory.Packages.props new file mode 100644 index 0000000..9064055 --- /dev/null +++ b/Directory.Packages.props @@ -0,0 +1,55 @@ + + + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Source/AlphaVantage.Net/AlphaVantage.Net.csproj b/Source/AlphaVantage.Net/AlphaVantage.Net.csproj index 51d473a..4f458c5 100644 --- a/Source/AlphaVantage.Net/AlphaVantage.Net.csproj +++ b/Source/AlphaVantage.Net/AlphaVantage.Net.csproj @@ -23,8 +23,6 @@ true snupkg - - true @@ -46,46 +44,21 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + diff --git a/Source/AlphaVantage.Net/AlphaVantageClient.cs b/Source/AlphaVantage.Net/AlphaVantageClient.cs index d520c02..3917e38 100644 --- a/Source/AlphaVantage.Net/AlphaVantageClient.cs +++ b/Source/AlphaVantage.Net/AlphaVantageClient.cs @@ -91,7 +91,7 @@ public AlphaVantageClient( private async Task WrapJsonCall(Func> apiCall, CancellationToken cancellationToken) { - using var lease = await _rateLimiter.AcquireAsync(cancellationToken); + using var lease = await _rateLimiter.AcquireAsync(cancellationToken).ConfigureAwait(false); if (!lease.IsAcquired) ThrowHelper.ThrowTimeoutException(); @@ -100,7 +100,7 @@ private async Task WrapJsonCall(Func> apiC private async Task> WrapCsvCall(Func> apiCall, CancellationToken cancellationToken) { - using var lease = await _rateLimiter.AcquireAsync(cancellationToken); + using var lease = await _rateLimiter.AcquireAsync(cancellationToken).ConfigureAwait(false); if (!lease.IsAcquired) ThrowHelper.ThrowTimeoutException(); @@ -113,7 +113,8 @@ private async Task> WrapCsvCall(Func(str); var error = json.GetProperty("Error Message").GetString()!; throw new AlphaVantageException(error, str); diff --git a/Source/AlphaVantage.Net/AlphaVantageServiceCollectionExtensions.cs b/Source/AlphaVantage.Net/AlphaVantageServiceCollectionExtensions.cs index d8e5fdc..6b0537a 100644 --- a/Source/AlphaVantage.Net/AlphaVantageServiceCollectionExtensions.cs +++ b/Source/AlphaVantage.Net/AlphaVantageServiceCollectionExtensions.cs @@ -34,7 +34,7 @@ public static IServiceCollection AddAlphaVantageClient( Guard.IsNotNull(services); Guard.IsNotNull(sectionPath); - services + _ = services .AddOptions() .BindConfiguration(sectionPath); services.DoAddAlphaVantageClient(); @@ -56,7 +56,7 @@ public static IServiceCollection AddAlphaVantageClient( Guard.IsNotNull(services); Guard.IsNotNull(configureOptions); - services.Configure(configureOptions); + _ = services.Configure(configureOptions); services.DoAddAlphaVantageClient(); return services; @@ -64,16 +64,16 @@ public static IServiceCollection AddAlphaVantageClient( private static void DoAddAlphaVantageClient(this IServiceCollection services) { - services.PostConfigure(o => + _ = services.PostConfigure(o => { Guard.IsNotNull(o.ApiKey, "AlphaVantage ApiKey"); Guard.IsGreaterThan(o.MaxApiCallsPerMinute, 0, "AlphaVantage MaxApiCallsPerMinute"); }); - services.AddSingleton(sp => + _ = services.AddSingleton(sp => new AlphaVantageClient.RateLimiter( sp.GetRequiredService>().Value.MaxApiCallsPerMinute)); - services + _ = services .AddRefitClient(settings: new() { ContentSerializer = new SystemTextJsonContentSerializer(AlphaVantageClient.JsonSerializerOptions), @@ -81,7 +81,7 @@ private static void DoAddAlphaVantageClient(this IServiceCollection services) .ConfigureHttpClient(c => c.BaseAddress = new Uri("https://www.alphavantage.co/")) .ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler { AutomaticDecompression = System.Net.DecompressionMethods.All, }); - services.AddTransient(sp => + _ = services.AddTransient(sp => new AlphaVantageClient( sp.GetRequiredService(), sp.GetRequiredService(), diff --git a/Source/AlphaVantage.Net/EnumConverterFactory.cs b/Source/AlphaVantage.Net/EnumConverterFactory.cs index bccedd3..d6b46ee 100644 --- a/Source/AlphaVantage.Net/EnumConverterFactory.cs +++ b/Source/AlphaVantage.Net/EnumConverterFactory.cs @@ -47,7 +47,9 @@ internal static T ParseEnumValue(string? text) where T : struct, Enum { if (Enum.TryParse(text, out var e) || Enum.TryParse(text, ignoreCase: true, out e)) + { return e; + } foreach (var value in typeof(T).GetFields(BindingFlags.Public | BindingFlags.Static)) { @@ -59,7 +61,7 @@ internal static T ParseEnumValue(string? text) where T : struct, Enum return ThrowHelper.ThrowInvalidOperationException("Unknown enum value."); } - private Dictionary _converters = new(); + private Dictionary _converters = []; [System.Diagnostics.CodeAnalysis.SuppressMessage("Performance", "CA1812:Avoid uninstantiated internal classes", Justification = "Activated on L28")] internal sealed class EnumMemberEnumConverterNotNull : JsonConverter diff --git a/Source/AlphaVantage.Net/Fundamentals/EarningsResponse.cs b/Source/AlphaVantage.Net/Fundamentals/EarningsResponse.cs index e278994..94baa98 100644 --- a/Source/AlphaVantage.Net/Fundamentals/EarningsResponse.cs +++ b/Source/AlphaVantage.Net/Fundamentals/EarningsResponse.cs @@ -1,6 +1,4 @@ -using System.Text.Json.Serialization; - -namespace AlphaVantage.Fundamentals; +namespace AlphaVantage.Fundamentals; /// /// Annual and quarterly earnings information for an equity. @@ -8,7 +6,7 @@ namespace AlphaVantage.Fundamentals; public sealed class EarningsResponse { #pragma warning disable CS1591 - public required string symbol { get; set; } + public required string Symbol { get; set; } public required IReadOnlyList AnnualEarnings { get; set; } public required IReadOnlyList QuarterlyEarnings { get; set; } #pragma warning restore CS1591 diff --git a/Tests/AlphaVantage.Net.Tests/.editorconfig b/Tests/AlphaVantage.Net.Tests/.editorconfig new file mode 100644 index 0000000..ad551aa --- /dev/null +++ b/Tests/AlphaVantage.Net.Tests/.editorconfig @@ -0,0 +1,10 @@ +[*.cs] + +# XML Documentation +dotnet_diagnostic.CS0105.severity = none # CS0105: Using directive is unnecessary. +dotnet_diagnostic.CS1573.severity = none # CS1573: Missing XML comment for parameter +dotnet_diagnostic.CS1591.severity = none # CS1591: Missing XML comment for publicly visible type or member +dotnet_diagnostic.CS1712.severity = none # CS1712: Type parameter has no matching typeparam tag in the XML comment (but other type parameters do) + +# Async +dotnet_diagnostic.CA2007.severity = none # CA2007: Consider calling ConfigureAwait on the awaited task diff --git a/Tests/AlphaVantage.Net.Tests/AlphaVantage.Net.Tests.csproj b/Tests/AlphaVantage.Net.Tests/AlphaVantage.Net.Tests.csproj index 8e6d077..6b46a8c 100644 --- a/Tests/AlphaVantage.Net.Tests/AlphaVantage.Net.Tests.csproj +++ b/Tests/AlphaVantage.Net.Tests/AlphaVantage.Net.Tests.csproj @@ -8,14 +8,14 @@ - - - - - - - - + + + + + + + + diff --git a/Tests/AlphaVantage.Net.Tests/AlphaVantageFixture.cs b/Tests/AlphaVantage.Net.Tests/AlphaVantageFixture.cs index 452e98a..4e43b31 100644 --- a/Tests/AlphaVantage.Net.Tests/AlphaVantageFixture.cs +++ b/Tests/AlphaVantage.Net.Tests/AlphaVantageFixture.cs @@ -1,4 +1,4 @@ -using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; namespace AlphaVantage.Tests; @@ -17,8 +17,8 @@ public AlphaVantageFixture() .Build(); var services = new ServiceCollection(); - services.AddSingleton(_ => configuration); - services.AddAlphaVantageClient(); + _ = services.AddSingleton(_ => configuration); + _ = services.AddAlphaVantageClient(); _serviceProvider = services.BuildServiceProvider(); Client = _serviceProvider.GetRequiredService(); diff --git a/Tests/AlphaVantage.Net.Tests/FundmentalsTests.cs b/Tests/AlphaVantage.Net.Tests/FundmentalsTests.cs index 8e84b47..f9eb4aa 100644 --- a/Tests/AlphaVantage.Net.Tests/FundmentalsTests.cs +++ b/Tests/AlphaVantage.Net.Tests/FundmentalsTests.cs @@ -1,15 +1,10 @@ -using Xunit; +using Xunit; namespace AlphaVantage.Tests; -public sealed class FundmentalsTests : IClassFixture +public sealed class FundmentalsTests(AlphaVantageFixture fixture) : IClassFixture { - private readonly AlphaVantageFixture _fixture; - - public FundmentalsTests(AlphaVantageFixture fixture) - { - _fixture = fixture; - } + private readonly AlphaVantageFixture _fixture = fixture; [Fact] public async Task VerifyCompanySummary() => diff --git a/Tests/AlphaVantage.Net.Tests/IndicatorsTests.cs b/Tests/AlphaVantage.Net.Tests/IndicatorsTests.cs index 9038a5f..7a27c01 100644 --- a/Tests/AlphaVantage.Net.Tests/IndicatorsTests.cs +++ b/Tests/AlphaVantage.Net.Tests/IndicatorsTests.cs @@ -1,15 +1,10 @@ -using Xunit; +using Xunit; namespace AlphaVantage.Tests; -public sealed class IndicatorsTests : IClassFixture +public sealed class IndicatorsTests(AlphaVantageFixture fixture) : IClassFixture { - private readonly AlphaVantageFixture _fixture; - - public IndicatorsTests(AlphaVantageFixture fixture) - { - _fixture = fixture; - } + private readonly AlphaVantageFixture _fixture = fixture; [Fact] public async Task VerifyRealGdp() => diff --git a/Tests/AlphaVantage.Net.Tests/StocksTests.cs b/Tests/AlphaVantage.Net.Tests/StocksTests.cs index 0b738bf..9aedcc9 100644 --- a/Tests/AlphaVantage.Net.Tests/StocksTests.cs +++ b/Tests/AlphaVantage.Net.Tests/StocksTests.cs @@ -1,15 +1,10 @@ -using Xunit; +using Xunit; namespace AlphaVantage.Tests; -public sealed class StocksTests : IClassFixture +public sealed class StocksTests(AlphaVantageFixture fixture) : IClassFixture { - private readonly AlphaVantageFixture _fixture; - - public StocksTests(AlphaVantageFixture fixture) - { - _fixture = fixture; - } + private readonly AlphaVantageFixture _fixture = fixture; [Fact] public async Task VerifyIntradayTimeSeries() =>