Skip to content
This repository has been archived by the owner on Jan 10, 2023. It is now read-only.

Commit

Permalink
Installs static analysis tools and improves code as suggested
Browse files Browse the repository at this point in the history
Some warnings are hidden due to demo time constraints.
Removes synchronous implementation from prime generator.
Adds file headers with license and copyright.
Adds documentation comments for public members.
Improves some names and member ordering.
  • Loading branch information
langsamu committed Jun 14, 2020
1 parent 3bc7ede commit a644cba
Show file tree
Hide file tree
Showing 37 changed files with 379 additions and 182 deletions.
5 changes: 5 additions & 0 deletions PrimeMultiplication.Cli/GlobalSuppressions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// MIT License, Copyright 2020 Samu Lang

using System.Diagnostics.CodeAnalysis;

[assembly: SuppressMessage("Reliability", "CA2007:Consider calling ConfigureAwait on the awaited task", Justification = "Honestly I don't know which option I should choose")]
18 changes: 17 additions & 1 deletion PrimeMultiplication.Cli/PrimeMultiplication.Cli.csproj
Original file line number Diff line number Diff line change
@@ -1,16 +1,32 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>

<PropertyGroup>
<DocumentationFile>obj\PrimeMultiplication.Cli.xml</DocumentationFile>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="3.0.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="System.CommandLine" Version="2.0.0-beta1.20303.1" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\PrimeMultiplication\PrimeMultiplication.csproj" />
</ItemGroup>

<ItemGroup>
<AdditionalFiles Include="..\stylecop.json" Link="stylecop.json" />
</ItemGroup>

</Project>
10 changes: 7 additions & 3 deletions PrimeMultiplication.Cli/PrimeMultiplicationCommand.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
namespace PrimeMultiplication.Cli
// MIT License, Copyright 2020 Samu Lang

namespace PrimeMultiplication.Cli
{
using System.CommandLine;
using System.CommandLine.Invocation;
using System.CommandLine.IO;
using System.Diagnostics.CodeAnalysis;
using System.Threading;
using System.Threading.Tasks;
using PrimeMultiplication;
Expand All @@ -26,11 +29,12 @@ internal PrimeMultiplicationCommand()
this.AddOption(throwOption);
}

[SuppressMessage("Reliability", "CA2000:Dispose objects before losing scope", Justification = "Out of scope for this demo")]
private async Task ExecuteAsync(int count, int? timeout, bool throwOnCancel, IConsole console, CancellationToken cancellationToken)
{
if (timeout.HasValue)
{
cancellationToken =
cancellationToken =
CancellationTokenSource.CreateLinkedTokenSource(
cancellationToken,
new CancellationTokenSource(timeout.Value).Token).Token;
Expand All @@ -46,7 +50,7 @@ private async Task ExecuteAsync(int count, int? timeout, bool throwOnCancel, ICo
{
await foreach (var cell in row)
{
console.Out.Write(string.Format("{0, 10}", cell));
console.Out.Write($"{cell,10}");
}

console.Out.WriteLine(); // LF
Expand Down
12 changes: 11 additions & 1 deletion PrimeMultiplication.Cli/Program.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,20 @@
namespace PrimeMultiplication.Cli
// MIT License, Copyright 2020 Samu Lang

namespace PrimeMultiplication.Cli
{
using System.CommandLine;
using System.Threading.Tasks;

/// <summary>
/// Represents a command line interface for generating a multiplication table of primes.
/// </summary>
public static class Program
{
/// <summary>
/// The entry point of the command line interface.
/// </summary>
/// <param name="args">Command line arguments.</param>
/// <returns>A <see cref="Task"/> representing the result of the asynchronous operation.</returns>
public static async Task Main(string[] args) =>
await new PrimeMultiplicationCommand().InvokeAsync(args);
}
Expand Down
11 changes: 8 additions & 3 deletions PrimeMultiplication.Tests/Cli/ProgramTests.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
namespace PrimeMultiplication.Tests.Cli
// MIT License, Copyright 2020 Samu Lang

namespace PrimeMultiplication.Tests.Cli
{
using System;
using System.IO;
Expand All @@ -19,7 +21,8 @@ 2 3 5
2 4 6 10
3 6 9 15
5 10 15 25
"[2..].Replace("\r\n", Environment.NewLine);
";
expected = expected[2..].Replace("\r\n", Environment.NewLine, StringComparison.InvariantCulture);

using var writer = new StringWriter();

Expand Down Expand Up @@ -76,7 +79,9 @@ testhost [options] <count>
--version Show version information
-?, -h, --help Show help and usage information
"[2..].Replace("\r\n", Environment.NewLine);
";

expected = expected[2..].Replace("\r\n", Environment.NewLine, StringComparison.InvariantCulture);

using var writer = new StringWriter();

Expand Down
8 changes: 8 additions & 0 deletions PrimeMultiplication.Tests/GlobalSuppressions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// MIT License, Copyright 2020 Samu Lang

using System.Diagnostics.CodeAnalysis;

[assembly: SuppressMessage("Naming", "CA1707:Identifiers should not contain underscores", Justification = "This is test method naming convention")]
[assembly: SuppressMessage("Usage", "CA2234:Pass system uri objects instead of strings", Justification = "Would clutter tests")]
[assembly: SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1600:Elements should be documented", Justification = "Test methods document themselves with name and content")]
[assembly: SuppressMessage("Reliability", "CA2007:Consider calling ConfigureAwait on the awaited task", Justification = "Honestly I don't know which option I should choose")]
6 changes: 4 additions & 2 deletions PrimeMultiplication.Tests/Library/AsyncEnumeratorTests.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// MIT License, Copyright 2020 Samu Lang

namespace PrimeMultiplication.Tests.Library
{
using System;
Expand All @@ -24,8 +26,8 @@ public async Task Current_throws_before_first()
public async Task Current_throws_after_last()
{
var generator = new PrimeGenerator();
var timeout = new CancellationTokenSource(1).Token;
await using var enumerator = generator.WithCancellation(timeout).GetAsyncEnumerator();
using var timeout = new CancellationTokenSource(1);
await using var enumerator = generator.WithCancellation(timeout.Token).GetAsyncEnumerator();

// Exhaust it
while (await enumerator.MoveNextAsync())
Expand Down
22 changes: 0 additions & 22 deletions PrimeMultiplication.Tests/Library/EnumeratorTests.cs

This file was deleted.

16 changes: 11 additions & 5 deletions PrimeMultiplication.Tests/Library/MultiplicationTableTests.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
// MIT License, Copyright 2020 Samu Lang

namespace PrimeMultiplication.Tests.Library
{
using System.Diagnostics.CodeAnalysis;
using System.Threading.Tasks;
using FluentAssertions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
Expand All @@ -9,13 +12,16 @@ namespace PrimeMultiplication.Tests.Library
public class MultiplicationTableTests
{
[TestMethod]
[SuppressMessage("Performance", "CA1814:Prefer jagged arrays over multidimensional", Justification = "This is actually a multidimensional array")]
[SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1025:Code should not contain multiple whitespace in a row", Justification = "Abnormal whitespace here elucidates behaviour")]
public async Task Multiplies_primes()
{
var expected = new int?[,] {
{ null, 2, 3, 5 },
{ 2, 4, 6, 10 },
{ 3, 6, 9 , 15 },
{ 5, 10, 15 , 25 },
var expected = new int?[,]
{
{ null, 2, 3, 5 },
{ 2, 4, 6, 10 },
{ 3, 6, 9, 15 },
{ 5, 10, 15, 25 },
};

var count = 3;
Expand Down
50 changes: 14 additions & 36 deletions PrimeMultiplication.Tests/Library/PrimeGeneratorTests.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
// MIT License, Copyright 2020 Samu Lang

namespace PrimeMultiplication.Tests.Library
{
using System;
using System.Collections;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
Expand All @@ -14,43 +15,20 @@ namespace PrimeMultiplication.Tests.Library
public class PrimeGeneratorTests
{
[TestMethod]
public void Generates_primes()
public async Task Generates_primes()
{
var generator = new PrimeGenerator();
var first10Primes = generator.Take(10);

first10Primes.Should().Equal(new[] { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29 });
}
var count = 10;
var expected = new[] { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29 };
var actual = new int[count];

[TestMethod]
public void Can_be_enumerated()
{
var generator = new PrimeGenerator();
var enumerable = (IEnumerable)generator;
await using var primes = new PrimeGenerator().GetAsyncEnumerator();

var i = 0;
foreach (object prime in enumerable)
for (var i = 0; i < count && await primes.MoveNextAsync(); i++)
{
if (i++ == 10)
{
break;
}
actual[i] = primes.Current;
}
}

[TestMethod]
public void Can_be_enumerated_generically()
{
var generator = new PrimeGenerator();

var i = 0;
foreach (int prime in generator)
{
if (i++ == 10)
{
break;
}
}
actual.Should().Equal(expected);
}

[TestMethod]
Expand All @@ -72,11 +50,11 @@ public async Task Can_be_enumerated_asynchronously()
public void Can_be_cancelled()
{
var generator = new PrimeGenerator();
var timeout = new CancellationTokenSource(1000).Token;
using var timeout = new CancellationTokenSource(1000);

Func<Task> enumerateWithTimeout = async () =>
{
await foreach (var prime in generator.WithCancellation(timeout))
await foreach (var prime in generator.WithCancellation(timeout.Token))
{
}
};
Expand All @@ -88,11 +66,11 @@ public void Can_be_cancelled()
public async Task Can_throw_when_cancelled()
{
var generator = new PrimeGenerator(PrimeGeneratorOptions.ThrowOnCancel);
var timeout = new CancellationTokenSource(1).Token;
using var timeout = new CancellationTokenSource(1);

Func<Task> enumerateWithTimeout = async () =>
{
await foreach (var prime in generator.WithCancellation(timeout))
await foreach (var prime in generator.WithCancellation(timeout.Token))
{
}
};
Expand Down
17 changes: 17 additions & 0 deletions PrimeMultiplication.Tests/PrimeMultiplication.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,27 @@
<IsPackable>false</IsPackable>
</PropertyGroup>

<PropertyGroup>
<DocumentationFile>obj\PrimeMultiplication.Tests.xml</DocumentationFile>
<NoWarn>1701;1702;1591</NoWarn>
</PropertyGroup>

<ItemGroup>
<FrameworkReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="AngleSharp" Version="0.14.0" />
<PackageReference Include="FluentAssertions" Version="5.10.3" />
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="3.0.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.6.1" />
<PackageReference Include="MSTest.TestAdapter" Version="2.1.2" />
<PackageReference Include="MSTest.TestFramework" Version="2.1.2" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="3.1.5" />
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>

<ItemGroup>
Expand All @@ -22,4 +35,8 @@
<ProjectReference Include="..\PrimeMultiplication.Web\PrimeMultiplication.Web.csproj" />
</ItemGroup>

<ItemGroup>
<AdditionalFiles Include="..\stylecop.json" Link="stylecop.json" />
</ItemGroup>

</Project>
18 changes: 12 additions & 6 deletions PrimeMultiplication.Tests/Web/ApiTests.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
namespace PrimeMultiplication.Tests.Web
// MIT License, Copyright 2020 Samu Lang

namespace PrimeMultiplication.Tests.Web
{
using System;
using System.Diagnostics.CodeAnalysis;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
Expand All @@ -19,6 +22,7 @@ public class ApiTests
private static HttpClient client;

[ClassInitialize]
[SuppressMessage("Usage", "CA1801:Review unused parameters", Justification = "Required by test framework")]
public static void Initialize(TestContext context)
{
factory = new WebApplicationFactory<Startup>();
Expand All @@ -33,13 +37,15 @@ public static void Cleanup()
}

[TestMethod]
[SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1025:Code should not contain multiple whitespace in a row", Justification = "Abnormal whitespace here elucidates behaviour")]
public async Task Multiplies_primes()
{
var expected = new[] {
new int?[] { null, 2, 3, 5 },
new int?[] { 2, 4, 6, 10 },
new int?[] { 3, 6, 9 , 15 },
new int?[] { 5, 10, 15 , 25 },
var expected = new[]
{
new int?[] { null, 2, 3, 5 },
new int?[] { 2, 4, 6, 10 },
new int?[] { 3, 6, 9, 15 },
new int?[] { 5, 10, 15, 25 },
};

using var response = await client.GetStreamAsync("/api?count=3");
Expand Down
Loading

0 comments on commit a644cba

Please sign in to comment.