A set of F# analyzers which warn against code issues previously encountered by Idura.
You should be able to build the project by simply running dotnet build.
You can test the analyzers by running dotnet test.
The test suite works by running each analyzer on a number of test programs. There are two kinds of tests for the analyzers: positive and negative.
Positive tests check that the analyzer reports issues correctly when presented with a faulty program.
Positive tests run the analyzer on each test program and record the messages generated by the analyzer.
They then check that there is at least one message, and compare the generated messages with a snapshot to check that the analyzer does not change its behavior unintentionally.
If the snapshot does not match, the test suite will fail and generate a __mismatch__ directory containing the new messages so you can compare them with the snapshots while debugging your code.
If you are intentionally changing the behaviour of an analyzer and want to update the snapshots to reflect this, overwrite the old snapshots with the new snapshots generated in the __mismatch__ directory after running the test suite.
Negative tests check that the analyzer does not report issues on correct programs. Negative tests run the analyzer on each test program and check that the analyzer does not produce any messages.
Run dotnet pack --configuration Release to generate a NuGet package (in the bin/Release directory).
You can then use the NuGet package like any other F# analyzer.
The FSharp.Tree.Viewer project contains a small command-line utility which allows you to view the syntax tree and typed declarations as parsed by the F# compiler.
This can be useful to figure out what to look for when traversing the abstract syntax tree to find a specific construct.
From the src/FSharp.Tree.Viewer directory, the tool can be run with e.g. dotnet run -- Program.fs.
Run dotnet run -- Program.fs -- --help to get an overview of the options.
Xunit only supports literals in InlineData.
If you provide a non-literal type as input to an InlineData test, the test will silently be skipped by Xunit.
This can cause surprising behavior when refactoring tests and accidentally changing test input to a non-literal.
This can be somewhat mitigated by annotating the types of all input parameters supplied via InlineData.
This analyzer detects missing type annotations in parameters supplied via InlineData.
| About this analyzer | |
|---|---|
| Code | IDURA-XUNIT-001 |
| Message | Arguments with data supplied via the InlineData annotation must have type annotations |
| Severity | Warning |
| Works in | CLI, Ionide |
XUnit will silently skip any tests tagged with the Fact attribute if they don't have a unit argument. This is an easy way to accidentally disable a test, and it is also easy to forget to add the unit argument.
This analyzer detects missing unit arguments in functions that have the Fact attribute.
| About this analyzer | |
|---|---|
| Code | IDURA-XUNIT-002 |
| Message | Test functions tagged with the XUnit [Fact] attribute must have a unit argument or the test runner will not execute them |
| Severity | Warning |
| Works in | CLI, Ionide |
The random number generator instances in .NET sometimes fail with cryptographic exceptions for no observable reason. We have observed that this can cause the entire generator instance to permanently fail. For this reason, you should never use your own instances of random number generators.
In non-legacy code, the solution is to use the static methods on the RandomNumberGenerator class, which are not bound to a specific instance.
In legacy code where these are not available, you should maintain a pool of random number generator instances which replaces failed generators automatically. At Idura, we have implemented this in our legacy products at Idura by injecting such a pool as a dependency for every module that needs a random number generator.
This analyzer detects use of the constructors and Create methods of the RandomNumberGenerator and RNGCryptoServiceProvider classes.
| About this analyzer | |
|---|---|
| Code | IDURA-CRYPTO-001 |
| Message | Do not use your own instance of RNGCryptoServiceProvider. Depend on a global RNG pool to ensure stability of the generator. |
| Severity | Warning |
| Works in | CLI, Ionide |
| About this analyzer | |
|---|---|
| Code | IDURA-CRYPTO-002 |
| Message | Do not use your own instance of RandomNumberGenerator. Depend on a global RNG pool to ensure stability of the generator. |
| Severity | Warning |
| Works in | CLI, Ionide |