The LPRun is the LINQPad driver's unit/integration tests runner. Can be used for testing LINQPad drivers, e.g., CsvLINQPadDriver for LINQPad, or for running LINQPad scripts.
Scripts targeting .NET 8 up to .NET 11 are supported. Use the following LINQPad script to check which .NET is used by LPRun:
<QueryKind="Expression"/>System.Environment.VersionTested 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 AwesomeAssertions for assertion checks.
StringComparison.linq LINQPad test script example:
varoriginal=Books.First();varcopy=originalwith{Title=original.Title.ToUpper()};varexpectedEquality=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 testbelow.
Full NUnit test code can be found here.
[TestFixture]publicclassLPRunTests{[OneTimeSetUp]publicvoidInit(){// 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))]publicasyncTaskExecute_ScriptWithDriverProperties_Success((stringlinqScriptName,string?context,ICsvDataContextDriverPropertiesdriverProperties)testData){var(linqScriptName,context,driverProperties)=testData;// Arrange: Create query connection header. Custom code can be added here.varqueryConfig=GetQueryHeaders().Aggregate(newStringBuilder(),(stringBuilder,h)=>{stringBuilder.AppendLine(h);stringBuilder.AppendLine();returnstringBuilder;}).ToString();// Arrange: Create test LNQPad script.// You can also use LinqScript.FromScript method.varlinqScript=LinqScript.FromFile($"{linqScriptName}.linq",queryConfig);// Act: Execute test LNQPad script.var(output,error,exitCode)=awaitRunner.ExecuteAsync(linqScript);// Assert.error.Should().BeNullOrWhiteSpace();exitCode.Should().Be(0);// Helpers.IEnumerable<string>GetQueryHeaders(){// Connection header.yieldreturnConnectionHeader.Get("CsvLINQPadDriver","CsvLINQPadDriver.CsvDataContextDriver",driverProperties,"System.Runtime.CompilerServices");// AwesomeAssertions helper.yieldreturn"string Reason([CallerLineNumber] int sourceLineNumber = 0) =>"+@" $""something went wrong at line #{sourceLineNumber}"";";// Test context.if(!string.IsNullOrWhiteSpace(context)){yieldreturn$"var context = {context};";}}}privatestaticIEnumerable<(stringlinqScriptName,string?context,ICsvDataContextDriverPropertiesdriverProperties)>TestsData(){// Omitted for brevity.}}Tests can also be run in parallel:
[TestFixture]publicclassLPRunTests{[Test][Parallelizable(ParallelScope.Children)][TestCaseSource(nameof(ParallelizableTestsData))]publicvoidExecute_ScriptWithDriverProperties_Success((stringlinqScriptName,string?context,ICsvDataContextDriverPropertiesdriverProperties,intindex)testData){// ...// Arrange: Create test LNQPad script.// You can also use LinqScript.FromScript method.varlinqScript=LinqScript.FromFile($"{linqScriptName}.linq",queryConfig,$"{linqScriptName}_{testData.index}");// ...}privatestaticIEnumerable<(stringlinqScriptName,string?context,ICsvDataContextDriverPropertiesdriverProperties,intindex)>TestsData(){// Omitted for brevity.}// Parallelized tests data.privatestaticIEnumerable<(stringlinqScriptName,string?context,ICsvDataContextDriverPropertiesdriverProperties,intindex)>ParallelizableTestsData()=>TestsData().AugmentWithFileIndex(static testData =>testData.linqScriptName,static(testData,index)=>{testData.index=index;returntestData;});}Tested with NUnit. Other test frameworks should work as well.
Running LPRun on macOS is not supported yet.
Avoid referencing LINQPad.Runtime.dll in your tests, e.g. for Moq:
// LINQPad.Runtime.dll IConnectionInfo reference:varconnectionInfoMock=newMock<LINQPad.Extensibility.DataContext.IConnectionInfo>();vardriverProperties=newDriverProperties(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:
<TargetName="CopyLINQPadRuntimeToOutput"AfterTargets="Build">
<CopySourceFiles="$(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:
vardriverProperties=Mock.Of<IDriverProperties>(props =>props.BoolProp==true&&props.IntProp==42&&props.StringProp=="string");- Ivan Ivon
- LINQPad.Runtime/LPRun binaries (license) by Joseph Albahari