- Description
- LPRun .NET Versions
- Website
- Download
- Usage
- Known Issues
- Troubleshooting
- Authors
- Credits
- Licenses
The LPRun is the LINQPad driver's unit/integration tests runner. Can be used for testing LINQPad 8/LINQPad 7/LINQPad 6 drivers or for running LINQPad scripts.
.NET versions supported by LPRun are listed below. In case of unsupported version LPRun fallbacks to the latest production .NET installed.
LPRun | .NET 8.0 | .NET 7.0 | .NET 6.0 | .NET 5.0 | .NET 3.1 |
---|---|---|---|---|---|
8 | ✔️ | ✔️ | ✔️ | ||
7 | ✔️ | ✔️ | ✔️ | ✔️ |
Use the following script to check the .NET version used by LPRun:
<Query Kind="Expression"/>
System.Environment.Version
The LPRun is used for testing of the CsvLINQPadDriver for LINQPad 8/7/6/5.
Tested driver MUST NOT be installed via NuGet into LINQPad. In this case LPRun will use it instead of local one.
LPRun # Created by LPRun NuGet.
Templates # LINQPad script templates.
Data # Optional: Driver data files.
LPRun executes LINQPad test script. Test script uses Fluent Assertions for assertion checks.
StringComparison.linq LINQPad test script example:
var original = Books.First();
var copy = original with { Title = original.Title.ToUpper() };
var expectedEquality = original.Title.Equals(copy.Title, context.StringComparison);
original.Equals(copy).Should().Be(expectedEquality, Reason());
original.GetHashCode()
.Equals(copy.GetHashCode())
.Should()
.Be(expectedEquality, Reason());
Reason()
method (prints exact line number if assertion fails) and context
variable are injected by test below.
Full NUnit test code can be found here.
[TestFixture]
public class LPRunTests
{
[OneTimeSetUp]
public void Init()
{
// Check that driver is not installed via NuGet.
Driver.EnsureNotInstalledViaNuGet("CsvLINQPadDriver");
// Install driver.
Driver.InstallWithDepsJson(
// The directory to copy driver files to.
"CsvLINQPadDriver",
// The LINQPad driver files.
"CsvLINQPadDriver.dll",
// The test folder path.
"Tests");
}
[Test]
[TestCaseSource(nameof(TestsData))]
public async Task Execute_ScriptWithDriverProperties_Success(
(string linqScriptName,
string? context,
ICsvDataContextDriverProperties driverProperties) testData)
{
var (linqScriptName, context, driverProperties) = testData;
// Arrange: Create query connection header. Custom code can be added here.
var queryConfig = GetQueryHeaders().Aggregate(
new StringBuilder(),
(stringBuilder, h) =>
{
stringBuilder.AppendLine(h);
stringBuilder.AppendLine();
return stringBuilder;
}).ToString();
// Arrange: Create test LNQPad script.
// You can also use LinqScript.FromScript method.
var linqScript = LinqScript.FromFile(
$"{linqScriptName}.linq",
queryConfig);
// Act: Execute test LNQPad script.
var (output, error, exitCode) =
await Runner.ExecuteAsync(linqScript);
// Assert.
error.Should().BeNullOrWhiteSpace();
exitCode.Should().Be(0);
// Helpers.
IEnumerable<string> GetQueryHeaders()
{
// Connection header.
yield return ConnectionHeader.Get(
"CsvLINQPadDriver",
"CsvLINQPadDriver.CsvDataContextDriver",
driverProperties,
"System.Runtime.CompilerServices");
// FluentAssertions helper.
yield return
"string Reason([CallerLineNumber] int sourceLineNumber = 0) =>" +
@" $""something went wrong at line #{sourceLineNumber}"";";
// Test context.
if (!string.IsNullOrWhiteSpace(context))
{
yield return $"var context = {context};";
}
}
}
private static IEnumerable<
(string linqScriptName,
string? context,
ICsvDataContextDriverProperties driverProperties)> TestsData()
{
// Omitted for brevity.
}
}
Tests can also be run in parallel:
[TestFixture]
public class LPRunTests
{
[Test]
[Parallelizable(ParallelScope.Children)]
[TestCaseSource(nameof(ParallelizableTestsData))]
public void Execute_ScriptWithDriverProperties_Success(
(string linqScriptName,
string? context,
ICsvDataContextDriverProperties driverProperties,
int index) testData)
{
// ...
// Arrange: Create test LNQPad script.
// You can also use LinqScript.FromScript method.
var linqScript = LinqScript.FromFile(
$"{linqScriptName}.linq",
queryConfig,
$"{linqScriptName}_{testData.index}");
// ...
}
private static IEnumerable<
(string linqScriptName,
string? context,
ICsvDataContextDriverProperties driverProperties,
int index)> TestsData()
{
// Omitted for brevity.
}
// Parallelized tests data.
private static IEnumerable<
(string linqScriptName,
string? context,
ICsvDataContextDriverProperties driverProperties,
int index)> ParallelizableTestsData() =>
TestsData().AugmentWithFileIndex(
static testData => testData.linqScriptName,
static (testData, index) => { testData.index = index; return testData; });
}
Tested with NUnit. Other test frameworks should work as well.
Avoid referencing LINQPad.Runtime.dll
in your tests, e.g. for Moq:
// LINQPad.Runtime.dll IConnectionInfo reference:
var connectionInfoMock = new Mock<LINQPad.Extensibility.DataContext.IConnectionInfo>();
var driverProperties = new DriverProperties(connectionInfoMock.Object);
This code compiles but fails in runtime with Could not load file or assembly LINQPad.Runtime
error. If you still need to reference it, add the following target which copies assembly to output folder of the test project:
<Target Name="CopyLINQPadRuntimeToOutput" AfterTargets="Build">
<Copy SourceFiles="$(OutputPath)\LPRun\Bin\LINQPad.Runtime.dll" DestinationFolder="$(OutputPath)" UseHardlinksIfPossible="true" />
</Target>
Your can avoid referencing LINQPad.Runtime.dll
assembly by using mock framework facilities, e.g. for Moq you can extract IDriverProperties
interface and setup driver properties as follows:
var driverProperties = Mock.Of<IDriverProperties>(props =>
props.BoolProp == true &&
props.IntProp == 42 &&
props.StringProp == "string"
);
- Ivan Ivon
- LINQPad.Runtime/LPRun binaries (license) by Joseph Albahari