Intellenum Help

FAQ

What tests are there

There are unit tests for Intellenum itself, and snapshot tests to test that the source code that is generated matches what is expected.

To run the unit tests for Intellenum itself, you can either run them in your IDE, or via Build.ps1. To run the snapshot tests, run RunSnapshots.ps1

I want to add a test, where is the best place for it?

Most tests involve checking two, maybe three, things:

  • checking that source generated is as expected (so the snapshot tests in the main solution)

  • checking that behavior of the change works as expected (so a test in the consumers solution (tests/consumers.sln))

  • (maybe) - if you added/changed behavior of the code that generates the source code (rather than just changing a template), then a unit test in the main solution

I've changed the source that is generated, and I now have snapshot failures, what should I do?

There are a lot of snapshot tests. A lot of permutations of the following are run:

  • framework

  • internal/public/sealed/readonly

  • locales

  • conversions, such as EF Core, JSON, etc.

When the tests are run, it uses snapshot tests to compare the current output to the expected output. If your feature/fix changes the output, the snapshot tests will bring up your configured code diff tool, for instance, Beyond Compare, and show you the differences. If your change modifies what is generated, then it is likely a lot of verified files will need update to match the new source code that is generated.

To do this, run RunSnapshots.ps1 -reset. This will delete all the snapshots and treat what is generated as the correct version. You should only do this if you're sure the newly generated code is correct.

How do I identify types that are generated by Vogen?

I'd like to be able to identify types that are generated by Intellenum so that I can integrate them in things like EFCore.

This is described in this how-to page

What versions of .NET are supported?

The source generator is .NET Standard 2.0. The code it generates supports all C# language versions from 6.0 and onwards

If you're using the generator in a .NET Framework project and using the old style projects (the one before the 'SDK style' projects), then you'll need to do a few things differently:

  • add the reference using PackageReference in the .csproj file:

<ItemGroup> <PackageReference Include="Intellenum" Version="[LATEST_VERSION_HERE - E.G. 1.0.0]" PrivateAssets="all" /> </ItemGroup>
  • set the language version to latest (or anything 8 or more):

<PropertyGroup> + <LangVersion>latest</LangVersion> <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>

How can I view the code that is generated?

Add this to your .csproj file:

<PropertyGroup> <EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles> <CompilerGeneratedFilesOutputPath> Generated </CompilerGeneratedFilesOutputPath> </PropertyGroup> <ItemGroup> <Compile Remove="Generated/*/**/*.cs" /> </ItemGroup>

Then, you can view the generated files in the Generated folder. In Visual Studio, you need to select 'Show all files' in the Solution Explorer window:

the solution explorer window shows the 'show all files' option

Here's an example from the included Samples project:

the solution explorer window showing generated files

Can I serialize and deserialize them?

Yes. By default, each Intellenum enum is decorated with a TypeConverter and System.Text.Json (STJ) serializer. There are other converters/serializers for:

  • Newtonsoft.Json (NSJ)

  • Dapper

  • EFCore

  • LINQ to DB

Can I use them in EFCore?

Yes, but there are certain considerations that you should be aware of. Please see the EFCore page on the Wiki, but the TL;DR is:

  • you need a conversion to be generated, e.g. [Intellenum<string>(conversions: Conversions.EfCoreValueConverter)] and you need to tell EFCore to use that converter in the OnModelCreating method, e.g.:

builder.Entity<SomeEntity>(b => { b.Property(e => e.CustomerType).HasConversion( new Name.EfCoreValueConverter()); });

How do I run the benchmarks?

dotnet run -c Release -- --job short --framework net8.0 --filter *

Why do I get a build error when running .\Build.ps1?

You might see this:

.\Build.ps1 : File C:\Build.ps1 cannot be loaded. The file C:\Build.ps1 is not digitally signed. You cannot run this script on the current system.

To get around this, run:

Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass

I've made a change that means the 'Snapshot' tests are expectedly failing in the build—what do I do?

Intellenum uses a combination of unit tests, in-memory compilation tests, and snapshot tests. The snapshot tests are used to compare the output of the source generators to the expected output stored on disk.

If your feature/fix changes the output of the source generators, then running the snapshot tests will bring up your configured code diff tool (for example, Beyond Compare), to show the differences. You can accept the differences in that tool, or, if there are a lot of differences (and they're all expected!), you have various options depending on your platform and tooling. Those are described here.

NOTE: If the change to the source generators expectedly changes a lot of the snapshot tests, then you can tell the snapshot runner to overwrite the expected files with the actual files that are generated.

To do this, run .\Build.ps1 -v "Minimal" -resetSnapshots $true. This deletes all snaphsot folders under the tests folder and treats everything generated as the new baseline for future comparisons.

This will result in potentially thousands of changed files that will end up in the commit, but it's expected and unavoidable.

How do I debug the source generator?

The easiest way is to debug the SnapshotTests. Put a breakpoint in the code, and then debug a test somewhere.

To debug an analyzer, select or write a test in the AnalyzerTests. There are tests that exercise the various analyzers and code-fixers.

How do I run the tests that actually use the source generator?

It is challenging to run tests that use the source generator in the same project as the source generator, so there is a separate solution for this. It's called Consumers.sln. What happens is that build.ps1 builds the generator, runs the tests, and creates the NuGet package in a private local folder. The package is version 999.9.xxx and the consumer references the latest version. The consumer can then really use the source generator, just like anything else.

I get an error from Linq2DB when I use a ValueObject that wraps a TimeOnly saying that DateTime cannot be converted to TimeOnly—what should I do?

Linq2DB 4.0 or greater supports DateOnly and TimeOnly. Vogen generates value converters for Linq2DB; for DateOnly, it just works, but for `TimeOnly, you need to add this to your application:

MappingSchema.Default.SetConverter<DateTime, TimeOnly>(dt => TimeOnly.FromDateTime(dt));

Can I use protobuf-net?

Yes. Add a dependency to protobuf-net and set a surrogate attribute:

[Intellenum<string>] [ProtoContract(Surrogate = typeof(string))] public partial class CustomerType;

The BoxId type will now be serialized as a string in all messages and grpc calls. If one is generating .proto files for other applications from C#, proto files will include the Surrogate type as the type.

thank you to @DomasM for this information.

Last modified: 12 September 2024