diff --git a/TUnit.TestProject.FSharp/AfterTestAttributeTests.fs b/TUnit.TestProject.FSharp/AfterTestAttributeTests.fs new file mode 100644 index 0000000000..d7deba498a --- /dev/null +++ b/TUnit.TestProject.FSharp/AfterTestAttributeTests.fs @@ -0,0 +1,31 @@ +namespace TUnit.TestProject.FSharp + +open System +open System.IO +open System.Threading.Tasks +open TUnit.Assertions +open TUnit.Assertions.Extensions +open TUnit.Core.Interfaces +open TUnit.Core +open TUnit.Assertions.FSharp.Operations + + +//type WriteFileAfterTestAttribute() = +// inherit System.Attribute() +// interface ITestEndEventReceiver with +// member _.OnTestEnd(testContext: AfterTestContext) = +// task { +// Console.WriteLine("Writing file inside WriteFileAfterTestAttribute!") +// do! FilePolyfill.WriteAllTextAsync(filename, "Foo!") +// } :> Task +// member _.Order = 0 + +//type AfterTestAttributeTests() = +// static let filename = sprintf "%s-AfterTestAttributeTests.txt" (Guid.NewGuid().ToString("N")) + +// [] +// [] +// member _.Test() = +// async{ +// do! check(Assert.That(File.Exists(filename)).IsFalse()) +// } diff --git a/TUnit.TestProject.FSharp/ArgumentWithImplicitConverterTests.fs b/TUnit.TestProject.FSharp/ArgumentWithImplicitConverterTests.fs new file mode 100644 index 0000000000..4cce221a0d --- /dev/null +++ b/TUnit.TestProject.FSharp/ArgumentWithImplicitConverterTests.fs @@ -0,0 +1,33 @@ +namespace TUnit.TestProject.FSharp + +open System +open TUnit.Core + +// F# equivalents for ArgumentWithImplicitConverterTests.cs + +type ExplicitInteger = + | ExplicitInteger of int + static member op_Explicit(i: int) = ExplicitInteger i + override this.ToString() = + let (ExplicitInteger i) = this in i.ToString() + +type ImplicitInteger = + | ImplicitInteger of int + static member op_Implicit(i: int) = ImplicitInteger i + override this.ToString() = + let (ImplicitInteger i) = this in i.ToString() + +type ArgumentWithImplicitConverterTests() = + [] + [] + [] + [] + member _.Explicit(integer: ExplicitInteger) = + Console.WriteLine(integer) + + [] + [] + [] + [] + member _.Implicit(integer: ImplicitInteger) = + Console.WriteLine(integer) diff --git a/TUnit.TestProject.FSharp/AssemblyHooks.fs b/TUnit.TestProject.FSharp/AssemblyHooks.fs new file mode 100644 index 0000000000..313cfad7a4 --- /dev/null +++ b/TUnit.TestProject.FSharp/AssemblyHooks.fs @@ -0,0 +1,62 @@ +namespace TUnit.TestProject.FSharp + +open System.Threading +open System.Threading.Tasks +open TUnit.Assertions +open TUnit.Assertions.Extensions +open TUnit.Core +open TUnit.Assertions.FSharp.Operations + +// F# equivalent of AssemblyHooks.cs + +type AssemblyHooks() = + static let mutable beforeHook1Calls = 0 + + [] + static member BeforeHook1() = + beforeHook1Calls <- beforeHook1Calls + 1 + +#if NET + [] + static member BeforeHook2(context: AssemblyHookContext) = async{ + do! check(Assert.That(context.TestCount).IsPositive()) + } +#endif + + [] + [] + static member BeforeHook3(cancellationToken: CancellationToken) = + () + +#if NET + [] + [] + static member BeforeHook4(context: AssemblyHookContext, cancellationToken: CancellationToken) = async { + do! check(Assert.That(context.TestCount).IsPositive()) + } +#endif + + [] + static member AfterHook1() = async { + do! check(Assert.That(beforeHook1Calls).IsEqualTo(1)) + } + +#if NET + [] + static member AfterHook2(context: AssemblyHookContext) = async { + do! check(Assert.That(context.TestCount).IsPositive()) + } +#endif + + [] + [] + static member AfterHook3(cancellationToken: CancellationToken) = + () + +#if NET + [] + [] + static member AfterHook4(context: AssemblyHookContext, cancellationToken: CancellationToken) = async { + do! check(Assert.That(context.TestCount).IsPositive()) + } +#endif diff --git a/TUnit.TestProject.FSharp/BasicTests.fs b/TUnit.TestProject.FSharp/BasicTests.fs new file mode 100644 index 0000000000..7cae266db5 --- /dev/null +++ b/TUnit.TestProject.FSharp/BasicTests.fs @@ -0,0 +1,19 @@ +namespace TUnit.TestProject.FSharp + +open System.Threading.Tasks +open TUnit.Core + +// Equivalent of BasicTests.cs + +type BasicTests() = + [] + member _.SynchronousTest() = + () // Dummy method + + [] + member _.AsynchronousTest() : Task = + Task.CompletedTask + + [] + member _.ValueTaskAsynchronousTest() : ValueTask = + ValueTask() diff --git a/TUnit.TestProject.FSharp/ByteArgumentTests.fs b/TUnit.TestProject.FSharp/ByteArgumentTests.fs new file mode 100644 index 0000000000..b7c7b8be76 --- /dev/null +++ b/TUnit.TestProject.FSharp/ByteArgumentTests.fs @@ -0,0 +1,17 @@ +namespace TUnit.TestProject.FSharp + +open TUnit.Core + +// F# equivalent of ByteArgumentTests.cs + +type ByteArgumentTests() = + [] + [] + member _.Normal(b: byte) = + () // Dummy method + + [] + [] + [] + member _.Nullable(b: byte option) = + () // Dummy method diff --git a/TUnit.TestProject.FSharp/ClassConstructorTest.fs b/TUnit.TestProject.FSharp/ClassConstructorTest.fs index 9c19922192..24f457e969 100644 --- a/TUnit.TestProject.FSharp/ClassConstructorTest.fs +++ b/TUnit.TestProject.FSharp/ClassConstructorTest.fs @@ -1,12 +1,10 @@ -namespace TUnit.TestProject +namespace TUnit.TestProject.FSharp open TUnit.Core [)>] type ClassConstructorTest(dummyReferenceTypeClass: DummyReferenceTypeClass) = - member _.DummyReferenceTypeClass = dummyReferenceTypeClass - [] member _.Test() = () diff --git a/TUnit.TestProject.FSharp/ClassDataSourceDrivenTests.fs b/TUnit.TestProject.FSharp/ClassDataSourceDrivenTests.fs index b7ccdcc81a..8d47eb17cc 100644 --- a/TUnit.TestProject.FSharp/ClassDataSourceDrivenTests.fs +++ b/TUnit.TestProject.FSharp/ClassDataSourceDrivenTests.fs @@ -1,4 +1,4 @@ -namespace TUnit.TestProject +namespace TUnit.TestProject.FSharp open System.Threading.Tasks open TUnit.Assertions diff --git a/TUnit.TestProject.FSharp/ConflictingDependsOnTests.fs b/TUnit.TestProject.FSharp/ConflictingDependsOnTests.fs new file mode 100644 index 0000000000..da08425b07 --- /dev/null +++ b/TUnit.TestProject.FSharp/ConflictingDependsOnTests.fs @@ -0,0 +1,16 @@ +namespace TUnit.TestProject.FSharp + +open System +open System.Threading.Tasks +open System.Diagnostics.CodeAnalysis +open TUnit.Core + +[] +type ConflictingDependsOnTests() = + [] + [] + member _.Test1() : Task = Task.Delay(TimeSpan.FromSeconds(5.0)) + + [] + [] + member _.Test2() : Task = Task.CompletedTask diff --git a/TUnit.TestProject.FSharp/ConflictingDependsOnTests3.fs b/TUnit.TestProject.FSharp/ConflictingDependsOnTests3.fs new file mode 100644 index 0000000000..97e433c468 --- /dev/null +++ b/TUnit.TestProject.FSharp/ConflictingDependsOnTests3.fs @@ -0,0 +1,28 @@ +namespace TUnit.TestProject.FSharp + +open System +open System.Threading.Tasks +open TUnit.Core +open System.Diagnostics.CodeAnalysis + +[] +type ConflictingDependsOnTests3() = + [] + [] + member _.Test1() : Task = Task.Delay(TimeSpan.FromSeconds(5.0)) + + [] + [] + member _.Test2() : Task = Task.CompletedTask + + [] + [] + member _.Test3() : Task = Task.CompletedTask + + [] + [] + member _.Test4() : Task = Task.CompletedTask + + [] + [] + member _.Test5() : Task = Task.CompletedTask diff --git a/TUnit.TestProject.FSharp/ConsoleConcurrentTests.fs b/TUnit.TestProject.FSharp/ConsoleConcurrentTests.fs new file mode 100644 index 0000000000..22b28f45b4 --- /dev/null +++ b/TUnit.TestProject.FSharp/ConsoleConcurrentTests.fs @@ -0,0 +1,43 @@ +namespace TUnit.TestProject.FSharp + +open System +open TUnit.Core + +// F# equivalent of ConsoleConcurrentTests.cs + +type ConsoleConcurrentTests() = + [] + [] + member _.Test1() = Console.WriteLine("Test1") + [] + [] + member _.Test2() = Console.WriteLine("Test2") + [] + [] + member _.Test3() = Console.WriteLine("Test3") + [] + [] + member _.Test4() = Console.WriteLine("Test4") + [] + [] + member _.Test5() = Console.WriteLine("Test5") + [] + [] + member _.Test6() = Console.WriteLine("Test6") + [] + [] + member _.Test7() = + Console.WriteLine("Test7") + Console.WriteLine("Test7") + Console.WriteLine("Test7") + Console.WriteLine("Test7") + Console.WriteLine("Test7") + [] + [] + member _.Test8() = Console.WriteLine("Test8") + [] + [] + member _.Test9() = Console.WriteLine("Test9") + [] + [] + member _.Test10() = Console.WriteLine("Test10") diff --git a/TUnit.TestProject.FSharp/CustomSkipAttribute.fs b/TUnit.TestProject.FSharp/CustomSkipAttribute.fs new file mode 100644 index 0000000000..959d2b53bd --- /dev/null +++ b/TUnit.TestProject.FSharp/CustomSkipAttribute.fs @@ -0,0 +1,6 @@ +namespace TUnit.TestProject.FSharp + +open TUnit.Core + +type CustomSkipAttribute() = + inherit SkipAttribute("Some Reason") diff --git a/TUnit.TestProject.FSharp/DataDrivenTests.fs b/TUnit.TestProject.FSharp/DataDrivenTests.fs new file mode 100644 index 0000000000..bf6cd25fdb --- /dev/null +++ b/TUnit.TestProject.FSharp/DataDrivenTests.fs @@ -0,0 +1,64 @@ +namespace TUnit.TestProject.FSharp + +open System +open TUnit.Core + +// F# equivalent of DataDrivenTests.cs + +type TestEnum = + | One = 0 + | Two = 1 + +type DataDrivenTests() = + [] + [] + [] + [] + member _.DataSource_Method(value: int) = + () + + [] + [] + [] + [] + member _.DataSource_Method2(value: int, value2: string) = + () + + [] + [] + [] + [] + member _.EnumValue(testEnum: TestEnum) = + () + + [] + [] + member _.NullValue(value: string option) = + () + + [] + [] + member _.EmptyString(value: string) = + () + + [] + [] + member _.NonEmptyString(value: string) = + () + + [] + [] + [] + [] + member _.BooleanString(value: bool option) = + () + + [] + [)>] + member _.Type(value: Type) = + () + + [] + [] + member _.IntMaxValue(value: int) = + () diff --git a/TUnit.TestProject.FSharp/DataSourceClassCombinedWithDataSourceMethod.fs b/TUnit.TestProject.FSharp/DataSourceClassCombinedWithDataSourceMethod.fs new file mode 100644 index 0000000000..4da2234681 --- /dev/null +++ b/TUnit.TestProject.FSharp/DataSourceClassCombinedWithDataSourceMethod.fs @@ -0,0 +1,10 @@ +namespace TUnit.TestProject.FSharp + +open System.Threading.Tasks +open TUnit.Core + +// Equivalent of DataSourceClassCombinedWithDataSourceMethod.cs + +type DataSourceClassCombinedWithDataSourceMethod() = + [] + member _.Test(x: int) = () diff --git a/TUnit.TestProject.FSharp/DataSourceGeneratorTests.fs b/TUnit.TestProject.FSharp/DataSourceGeneratorTests.fs new file mode 100644 index 0000000000..f93587ef0f --- /dev/null +++ b/TUnit.TestProject.FSharp/DataSourceGeneratorTests.fs @@ -0,0 +1,10 @@ +namespace TUnit.TestProject.FSharp + +open System.Threading.Tasks +open TUnit.Core + +// Equivalent of DataSourceGeneratorTests.cs + +type DataSourceGeneratorTests() = + [] + member _.Test(x: int) = () diff --git a/TUnit.TestProject.FSharp/DeepNestedDependencyConflict.fs b/TUnit.TestProject.FSharp/DeepNestedDependencyConflict.fs new file mode 100644 index 0000000000..b4e5b2e33e --- /dev/null +++ b/TUnit.TestProject.FSharp/DeepNestedDependencyConflict.fs @@ -0,0 +1,48 @@ +namespace TUnit.TestProject.FSharp + +open TUnit.Core +open System.Diagnostics.CodeAnalysis + +// Equivalent of DeepNestedDependencyConflict.cs + +[] +type DeepNestedDependencyConflict() = + [] + [] + member _.Test1() = () + + [] + [] + member _.Test2() = () + + [] + [] + member _.Test3() = () + + [] + [] + member _.Test4() = () + + [] + [] + member _.Test5() = () + + [] + [] + member _.Test6() = () + + [] + [] + member _.Test7() = () + + [] + [] + member _.Test8() = () + + [] + [] + member _.Test9() = () + + [] + [] + member _.Test10() = () diff --git a/TUnit.TestProject.FSharp/DependencyInjectionClassConstructor.fs b/TUnit.TestProject.FSharp/DependencyInjectionClassConstructor.fs index 68e86cd75a..cbece7aff9 100644 --- a/TUnit.TestProject.FSharp/DependencyInjectionClassConstructor.fs +++ b/TUnit.TestProject.FSharp/DependencyInjectionClassConstructor.fs @@ -1,25 +1,26 @@ -namespace TUnit.TestProject +namespace TUnit.TestProject.FSharp open System -open System.Threading.Tasks open Microsoft.Extensions.DependencyInjection open TUnit.Core.Interfaces +open TUnit.Core +open System.Threading.Tasks + +// F# equivalent of DependencyInjectionClassConstructor.cs type DependencyInjectionClassConstructor() = - let serviceProvider: IServiceProvider = + let mutable scope: AsyncServiceScope option = None + let serviceProvider = ServiceCollection() .AddTransient() .BuildServiceProvider() - let mutable scope : AsyncServiceScope option = None - interface IClassConstructor with - member _.Create(typ, _) = + member _.Create(t: Type, classConstructorMetadata: ClassConstructorMetadata) = if scope.IsNone then scope <- Some(serviceProvider.CreateAsyncScope()) - ActivatorUtilities.GetServiceOrCreateInstance(scope.Value.ServiceProvider, typ) - + ActivatorUtilities.GetServiceOrCreateInstance(scope.Value.ServiceProvider, t) interface ITestEndEventReceiver with - member _.OnTestEnd(_testContext) = + member _.OnTestEnd(testContext: AfterTestContext) = match scope with | Some s -> s.DisposeAsync() | None -> ValueTask() diff --git a/TUnit.TestProject.FSharp/DependsOnTests3.fs b/TUnit.TestProject.FSharp/DependsOnTests3.fs new file mode 100644 index 0000000000..4118091b2b --- /dev/null +++ b/TUnit.TestProject.FSharp/DependsOnTests3.fs @@ -0,0 +1,48 @@ +namespace TUnit.TestProject.FSharp + +open System +open System.Threading.Tasks +open TUnit.Assertions +open TUnit.Assertions.Extensions +open TUnit.Core + +// F# equivalent of DependsOnTests3.cs + +type DependsOnTests3() = + static let mutable test1Start = DateTime.MinValue + static let mutable test2Start = DateTime.MinValue + static let mutable test3Start = DateTime.MinValue + + [] + member _.Test1() : Task = task { + test1Start <- TestContext.Current.Value.TestStart.Value.DateTime + do! Task.Delay(TimeSpan.FromSeconds(1.0)) + TestContext.Current.Value.ObjectBag.Add("Test1", box "1") + } + + [] + member _.Test2() : Task = task { + test2Start <- TestContext.Current.Value.TestStart.Value.DateTime + do! Task.Delay(TimeSpan.FromSeconds(1.0)) + TestContext.Current.Value.ObjectBag.Add("Test2", box "2") + } + + [] + [] + [] + member _.Test3() : Task = task { + test3Start <- TestContext.Current.Value.TestStart.Value.DateTime + do! Task.Delay(TimeSpan.FromSeconds(1.0)) + let test1 = TestContext.Current.GetTests("Test1") + let test2 = TestContext.Current.GetTests("Test2") + do! Assert.That(test1).HasCount().EqualTo(1) + do! Assert.That(test2).HasCount().EqualTo(1) + do! Assert.That(test1.[0].ObjectBag).ContainsKey("Test1") + do! Assert.That(test2.[0].ObjectBag).ContainsKey("Test2") + } + + [] + static member AssertStartTimes() : Task = task { + do! Assert.That(test3Start).IsAfterOrEqualTo(test1Start.AddSeconds(0.9)) + do! Assert.That(test3Start).IsAfterOrEqualTo(test2Start.AddSeconds(0.9)) + } diff --git a/TUnit.TestProject.FSharp/DummyReferenceTypeClass.fs b/TUnit.TestProject.FSharp/DummyReferenceTypeClass.fs index ffe2569fd8..854d52cb52 100644 --- a/TUnit.TestProject.FSharp/DummyReferenceTypeClass.fs +++ b/TUnit.TestProject.FSharp/DummyReferenceTypeClass.fs @@ -1,4 +1,4 @@ -namespace TUnit.TestProject +namespace TUnit.TestProject.FSharp type DummyReferenceTypeClass() = class end diff --git a/TUnit.TestProject.FSharp/DynamicCodeOnlyAttribute.fs b/TUnit.TestProject.FSharp/DynamicCodeOnlyAttribute.fs new file mode 100644 index 0000000000..a145340983 --- /dev/null +++ b/TUnit.TestProject.FSharp/DynamicCodeOnlyAttribute.fs @@ -0,0 +1,16 @@ +namespace TUnit.TestProject.FSharp + +open System.Threading.Tasks +open System.Runtime.CompilerServices +open TUnit.Core + +// F# equivalent of DynamicCodeOnlyAttribute.cs + +type DynamicCodeOnlyAttribute() = + inherit SkipAttribute("This test is only supported when dynamic code is available") + override _.ShouldSkip(context: BeforeTestContext) = +#if NET + Task.FromResult(not RuntimeFeature.IsDynamicCodeSupported) +#else + Task.FromResult(false) +#endif diff --git a/TUnit.TestProject.FSharp/DynamicTests/Basic.fs b/TUnit.TestProject.FSharp/DynamicTests/Basic.fs new file mode 100644 index 0000000000..5c76164337 --- /dev/null +++ b/TUnit.TestProject.FSharp/DynamicTests/Basic.fs @@ -0,0 +1,10 @@ +namespace TUnit.TestProject.FSharp.DynamicTests + +open System.Threading.Tasks +open TUnit.Core + +// Equivalent of DynamicTests/Basic.cs + +type Basic() = + [] + member _.Test() = () diff --git a/TUnit.TestProject.FSharp/DynamicTests/Basic2.fs b/TUnit.TestProject.FSharp/DynamicTests/Basic2.fs new file mode 100644 index 0000000000..de54ffa062 --- /dev/null +++ b/TUnit.TestProject.FSharp/DynamicTests/Basic2.fs @@ -0,0 +1,10 @@ +namespace TUnit.TestProject.FSharp.DynamicTests + +open System.Threading.Tasks +open TUnit.Core + +// Equivalent of DynamicTests/Basic2.cs + +type Basic2() = + [] + member _.Test() = () diff --git a/TUnit.TestProject.FSharp/DynamicTests/Runtime.fs b/TUnit.TestProject.FSharp/DynamicTests/Runtime.fs new file mode 100644 index 0000000000..e2a0ee1375 --- /dev/null +++ b/TUnit.TestProject.FSharp/DynamicTests/Runtime.fs @@ -0,0 +1,10 @@ +namespace TUnit.TestProject.FSharp.DynamicTests + +open System.Threading.Tasks +open TUnit.Core + +// Equivalent of DynamicTests/Runtime.cs + +type Runtime() = + [] + member _.Test() = () diff --git a/TUnit.TestProject.FSharp/DynamicallyRegisteredTests.fs b/TUnit.TestProject.FSharp/DynamicallyRegisteredTests.fs new file mode 100644 index 0000000000..e444fea175 --- /dev/null +++ b/TUnit.TestProject.FSharp/DynamicallyRegisteredTests.fs @@ -0,0 +1,57 @@ +namespace TUnit.TestProject.FSharp + +#nowarn "57" +open System +open System.Collections.Generic +open System.Threading +open System.Threading.Tasks +open TUnit.Core +open TUnit.Core.Enums +open TUnit.Core.Interfaces +open TUnit.Engine.Extensions + +type DynamicDataGenerator() = + inherit DataSourceGeneratorAttribute() + let mutable count = 0 + let cts = new CancellationTokenSource() + + override _.GenerateDataSources(dataGeneratorMetadata) = + seq { yield Func(fun () -> (Random()).Next()) } + + interface ITestStartEventReceiver with + member _.OnTestStart(beforeTestContext: BeforeTestContext) = + if not (DynamicDataGenerator.IsReregisteredTest(beforeTestContext.TestContext)) then + beforeTestContext.AddLinkedCancellationToken(cts.Token) + ValueTask() + + interface ITestEndEventReceiver with + member _.OnTestEnd(afterTestContext: AfterTestContext) = + task { + let testContext: TestContext | null = afterTestContext.TestContext + match testContext with + | null -> () + | ctx -> + if ctx.Result <> null && ctx.Result.Status = Status.Failed then + cts.Cancel() + count <- count + 1 + if count > 5 then + raise (Exception()) + if DynamicDataGenerator.IsReregisteredTest(ctx) then + () // Optionally suppress reporting + let retryDict = Dictionary() + retryDict.Add("DynamicDataGeneratorRetry", box true) + do! ctx.ReregisterTestWithArguments([|(Random()).Next()|], retryDict) + } |> ValueTask + + interface IEventReceiver with + member _.Order = 0 + + static member private IsReregisteredTest(testContext: TestContext) = + testContext.ObjectBag.ContainsKey("DynamicDataGeneratorRetry") + +[] +type DynamicallyRegisteredTests() = + [] + [] + member _.MyTest(value: int) = + raise (Exception($"Value {value} !")) diff --git a/TUnit.TestProject.FSharp/EnumerableDataSourceDrivenTests.fs b/TUnit.TestProject.FSharp/EnumerableDataSourceDrivenTests.fs new file mode 100644 index 0000000000..4971c335aa --- /dev/null +++ b/TUnit.TestProject.FSharp/EnumerableDataSourceDrivenTests.fs @@ -0,0 +1,44 @@ +namespace TUnit.TestProject.FSharp + +open System.Collections.Generic +open System.Threading.Tasks +open TUnit.Assertions +open TUnit.Assertions.Extensions +open TUnit.Core +open TUnit.Assertions.FSharp.Operations + +// F# equivalent of EnumerableDataSourceDrivenTests.cs + +type BaseValue() = class end + +type ConcreteValue() = + inherit BaseValue() + +type ConcreteValue2() = + inherit BaseValue() + +type EnumerableDataSourceDrivenTests() = + [] + [] + member _.DataSource_Method(value: int) = + async{ + do! check(Assert.That(value).IsEqualTo(1)) + } + + [] + [] + member _.DataSource_Method2(value: int) = + async{ + do! check(Assert.That(value).IsEqualTo(1)) + } + + [] + [] + member _.DataSource_WithBaseReturn(value: BaseValue) = + () + + static member SomeMethod() = seq { 1; 2; 3; 4; 5 } + + static member MethodWithBaseReturn() = + [ fun () -> ConcreteValue() :> BaseValue + fun () -> ConcreteValue2() :> BaseValue ] diff --git a/TUnit.TestProject.FSharp/ExperimentalTests.fs b/TUnit.TestProject.FSharp/ExperimentalTests.fs new file mode 100644 index 0000000000..f6c1e145b1 --- /dev/null +++ b/TUnit.TestProject.FSharp/ExperimentalTests.fs @@ -0,0 +1,15 @@ +namespace TUnit.TestProject.FSharp + +open System.Threading.Tasks +open TUnit.Core + +// F# equivalent of ExperimentalTests.cs + +type ExperimentalTests() = + [] + [] + member _.SynchronousTest() = () + + [] + [] + member _.AsynchronousTest() : Task = Task.CompletedTask diff --git a/TUnit.TestProject.FSharp/GenericMethodTests.fs b/TUnit.TestProject.FSharp/GenericMethodTests.fs new file mode 100644 index 0000000000..afaca63e3c --- /dev/null +++ b/TUnit.TestProject.FSharp/GenericMethodTests.fs @@ -0,0 +1,49 @@ +namespace TUnit.TestProject.FSharp + +open System +open System.Collections.Generic +open TUnit.Core + +// F# equivalent of GenericMethodTests.cs + +type GenericMethodTests() = + [] + [] + [] + member _.AggregateBy_HasExpectedOutput + (source: seq<'TSource>, + keySelector: 'TSource -> 'TKey, + seedSelector: 'TKey -> 'TAccumulate, + func: 'TAccumulate -> 'TSource -> 'TAccumulate, + comparer: IEqualityComparer<'TKey>, + expected: seq>) = + let enumerable = source |> Seq.toArray + Console.WriteLine(String.Join(", ", enumerable)) + Console.WriteLine(String.Join(", ", enumerable |> Seq.map keySelector)) + Console.WriteLine(String.Join(", ", enumerable |> Seq.map (fun x -> seedSelector (keySelector x)))) + + static member AggregateBy_Numeric_TestData() = + seq { + fun () -> + let source = seq { 0 .. 9 } + let keySelector = id + let seedSelector = fun _ -> 0 + let func = fun x y -> x + y + let comparer = null + let expected = + seq { for x in 0 .. 9 -> KeyValuePair(x, x) } + (source, keySelector, seedSelector, func, comparer, expected) + } + + static member AggregateBy_String_TestData() = + seq { + fun () -> + let source = [ "Bob"; "bob"; "tim"; "Bob"; "Tim" ] + let keySelector = id + let seedSelector = fun _ -> "" + let func = fun x y -> x + y + let comparer = null + let expected = + [ KeyValuePair("Bob", "BobBob"); KeyValuePair("bob", "bob"); KeyValuePair("tim", "tim"); KeyValuePair("Tim", "Tim") ] + (source, keySelector, seedSelector, func, comparer, expected) + } diff --git a/TUnit.TestProject.FSharp/GlobalSetUpCleanUp.fs b/TUnit.TestProject.FSharp/GlobalSetUpCleanUp.fs new file mode 100644 index 0000000000..1b03c346d5 --- /dev/null +++ b/TUnit.TestProject.FSharp/GlobalSetUpCleanUp.fs @@ -0,0 +1,19 @@ +namespace TUnit.TestProject.FSharp + +open System.Threading.Tasks +open TUnit.Core + +// F# equivalent of GlobalSetUpCleanUp.cs + +module GlobalSetUpCleanUp = + [] + let BlahSetUp() = + () + + [] + let BlahSetUp2() = + () + + [] + let BlahCleanUp() : Task = + Task.CompletedTask diff --git a/TUnit.TestProject.FSharp/Inject_SharedInstancePerKey.fs b/TUnit.TestProject.FSharp/Inject_SharedInstancePerKey.fs new file mode 100644 index 0000000000..c273428fa4 --- /dev/null +++ b/TUnit.TestProject.FSharp/Inject_SharedInstancePerKey.fs @@ -0,0 +1,176 @@ +namespace TUnit.TestProject.FSharp + +open System.Collections.Concurrent +open System.Linq +open TUnit.Assertions +open TUnit.Assertions.Extensions +open TUnit.Core + +// F# equivalent of SharedInjectedKeyedContainer +module SharedInjectedKeyedContainer = + let instancesPerKey = ConcurrentDictionary>() + +[, Shared=SharedType.PerClass)>] +[] +type InjectSharedPerKey1(dummyReferenceTypeClass: DummyReferenceTypeClass) = + [] + [] + member _.Test1() = task { + match TestContext.Current with + | null -> failwith "TestContext.Current is null" + | ctx -> + let testName = ctx.TestDetails.TestName + let found, list = SharedInjectedKeyedContainer.instancesPerKey.TryGetValue(testName) + if found && list.Count > 0 then + do! Assert.That(list).Contains(dummyReferenceTypeClass) + for KeyValue(k, v) in SharedInjectedKeyedContainer.instancesPerKey do + if k <> testName then + do! Assert.That(list).DoesNotContain(dummyReferenceTypeClass) + let l = SharedInjectedKeyedContainer.instancesPerKey.GetOrAdd(testName, fun _ -> ResizeArray()) + l.Add(dummyReferenceTypeClass) + do! Assert.That(l.Distinct()).HasSingleItem() + } + [] + [] + member _.Test2() = task { + match TestContext.Current with + | null -> failwith "TestContext.Current is null" + | ctx -> + let testName = ctx.TestDetails.TestName + let found, list = SharedInjectedKeyedContainer.instancesPerKey.TryGetValue(testName) + if found && list.Count > 0 then + do! Assert.That(list).Contains(dummyReferenceTypeClass) + for KeyValue(k, v) in SharedInjectedKeyedContainer.instancesPerKey do + if k <> testName then + do! Assert.That(list).DoesNotContain(dummyReferenceTypeClass) + let l = SharedInjectedKeyedContainer.instancesPerKey.GetOrAdd(testName, fun _ -> ResizeArray()) + l.Add(dummyReferenceTypeClass) + do! Assert.That(l.Distinct()).HasSingleItem() + } + [] + [] + member _.Test3() = task { + match TestContext.Current with + | null -> failwith "TestContext.Current is null" + | ctx -> + let testName = ctx.TestDetails.TestName + let found, list = SharedInjectedKeyedContainer.instancesPerKey.TryGetValue(testName) + if found && list.Count > 0 then + do! Assert.That(list).Contains(dummyReferenceTypeClass) + for KeyValue(k, v) in SharedInjectedKeyedContainer.instancesPerKey do + if k <> testName then + do! Assert.That(list).DoesNotContain(dummyReferenceTypeClass) + let l = SharedInjectedKeyedContainer.instancesPerKey.GetOrAdd(testName, fun _ -> ResizeArray()) + l.Add(dummyReferenceTypeClass) + do! Assert.That(l.Distinct()).HasSingleItem() + } + +[, Shared=SharedType.PerClass)>] +[] +type InjectSharedPerKey2(dummyReferenceTypeClass: DummyReferenceTypeClass) = + [] + [] + member _.Test1() = task { + match TestContext.Current with + | null -> failwith "TestContext.Current is null" + | ctx -> + let testName = ctx.TestDetails.TestName + let found, list = SharedInjectedKeyedContainer.instancesPerKey.TryGetValue(testName) + if found && list.Count > 0 then + do! Assert.That(list).Contains(dummyReferenceTypeClass) + for KeyValue(k, v) in SharedInjectedKeyedContainer.instancesPerKey do + if k <> testName then + do! Assert.That(list).DoesNotContain(dummyReferenceTypeClass) + let l = SharedInjectedKeyedContainer.instancesPerKey.GetOrAdd(testName, fun _ -> ResizeArray()) + l.Add(dummyReferenceTypeClass) + do! Assert.That(l.Distinct()).HasSingleItem() + } + [] + [] + member _.Test2() = task { + match TestContext.Current with + | null -> failwith "TestContext.Current is null" + | ctx -> + let testName = ctx.TestDetails.TestName + let found, list = SharedInjectedKeyedContainer.instancesPerKey.TryGetValue(testName) + if found && list.Count > 0 then + do! Assert.That(list).Contains(dummyReferenceTypeClass) + for KeyValue(k, v) in SharedInjectedKeyedContainer.instancesPerKey do + if k <> testName then + do! Assert.That(list).DoesNotContain(dummyReferenceTypeClass) + let l = SharedInjectedKeyedContainer.instancesPerKey.GetOrAdd(testName, fun _ -> ResizeArray()) + l.Add(dummyReferenceTypeClass) + do! Assert.That(l.Distinct()).HasSingleItem() + } + [] + [] + member _.Test3() = task { + match TestContext.Current with + | null -> failwith "TestContext.Current is null" + | ctx -> + let testName = ctx.TestDetails.TestName + let found, list = SharedInjectedKeyedContainer.instancesPerKey.TryGetValue(testName) + if found && list.Count > 0 then + do! Assert.That(list).Contains(dummyReferenceTypeClass) + for KeyValue(k, v) in SharedInjectedKeyedContainer.instancesPerKey do + if k <> testName then + do! Assert.That(list).DoesNotContain(dummyReferenceTypeClass) + let l = SharedInjectedKeyedContainer.instancesPerKey.GetOrAdd(testName, fun _ -> ResizeArray()) + l.Add(dummyReferenceTypeClass) + do! Assert.That(l.Distinct()).HasSingleItem() + } + +[, Shared=SharedType.PerClass)>] +[] +type InjectSharedPerKey3(dummyReferenceTypeClass: DummyReferenceTypeClass) = + [] + [] + member _.Test1() = task { + match TestContext.Current with + | null -> failwith "TestContext.Current is null" + | ctx -> + let testName = ctx.TestDetails.TestName + let found, list = SharedInjectedKeyedContainer.instancesPerKey.TryGetValue(testName) + if found && list.Count > 0 then + do! Assert.That(list).Contains(dummyReferenceTypeClass) + for KeyValue(k, v) in SharedInjectedKeyedContainer.instancesPerKey do + if k <> testName then + do! Assert.That(list).DoesNotContain(dummyReferenceTypeClass) + let l = SharedInjectedKeyedContainer.instancesPerKey.GetOrAdd(testName, fun _ -> ResizeArray()) + l.Add(dummyReferenceTypeClass) + do! Assert.That(l.Distinct()).HasSingleItem() + } + [] + [] + member _.Test2() = task { + match TestContext.Current with + | null -> failwith "TestContext.Current is null" + | ctx -> + let testName = ctx.TestDetails.TestName + let found, list = SharedInjectedKeyedContainer.instancesPerKey.TryGetValue(testName) + if found && list.Count > 0 then + do! Assert.That(list).Contains(dummyReferenceTypeClass) + for KeyValue(k, v) in SharedInjectedKeyedContainer.instancesPerKey do + if k <> testName then + do! Assert.That(list).DoesNotContain(dummyReferenceTypeClass) + let l = SharedInjectedKeyedContainer.instancesPerKey.GetOrAdd(testName, fun _ -> ResizeArray()) + l.Add(dummyReferenceTypeClass) + do! Assert.That(l.Distinct()).HasSingleItem() + } + [] + [] + member _.Test3() = task { + match TestContext.Current with + | null -> failwith "TestContext.Current is null" + | ctx -> + let testName = ctx.TestDetails.TestName + let found, list = SharedInjectedKeyedContainer.instancesPerKey.TryGetValue(testName) + if found && list.Count > 0 then + do! Assert.That(list).Contains(dummyReferenceTypeClass) + for KeyValue(k, v) in SharedInjectedKeyedContainer.instancesPerKey do + if k <> testName then + do! Assert.That(list).DoesNotContain(dummyReferenceTypeClass) + let l = SharedInjectedKeyedContainer.instancesPerKey.GetOrAdd(testName, fun _ -> ResizeArray()) + l.Add(dummyReferenceTypeClass) + do! Assert.That(l.Distinct()).HasSingleItem() + } \ No newline at end of file diff --git a/TUnit.TestProject.FSharp/Inject_SharedInstancePerTestClass.fs b/TUnit.TestProject.FSharp/Inject_SharedInstancePerTestClass.fs new file mode 100644 index 0000000000..05c6cd9fe6 --- /dev/null +++ b/TUnit.TestProject.FSharp/Inject_SharedInstancePerTestClass.fs @@ -0,0 +1,10 @@ +namespace TUnit.TestProject.FSharp + +open System.Threading.Tasks +open TUnit.Core + +// Equivalent of Inject_SharedInstancePerTestClass.cs + +type Inject_SharedInstancePerTestClass() = + [] + member _.Test() = () diff --git a/TUnit.TestProject.FSharp/InjectedClassDataSourceWithAsyncInitializerTests.fs b/TUnit.TestProject.FSharp/InjectedClassDataSourceWithAsyncInitializerTests.fs new file mode 100644 index 0000000000..3147529826 --- /dev/null +++ b/TUnit.TestProject.FSharp/InjectedClassDataSourceWithAsyncInitializerTests.fs @@ -0,0 +1,35 @@ +namespace TUnit.TestProject.FSharp + +open System +open System.Threading.Tasks +open TUnit.Core +open TUnit.Core.Interfaces + + +type MyClass() = + interface IAsyncInitializer with + member _.InitializeAsync() = + Console.WriteLine("IAsyncInitializer.InitializeAsync") + Task.CompletedTask + +[, Shared=SharedType.Keyed, Key="MyKey")>] +type InjectedClassDataSourceWithAsyncInitializerTests(myClass: MyClass) = + [] + member _.BeforeTest() : Task = + Console.WriteLine("BeforeTest") + Task.CompletedTask + + [] + member _.Test1() : Task = + Console.WriteLine("Test") + Task.CompletedTask + + [] + member _.Test2() : Task = + Console.WriteLine("Test") + Task.CompletedTask + + [] + member _.Test3() : Task = + Console.WriteLine("Test") + Task.CompletedTask diff --git a/TUnit.TestProject.FSharp/LongFailures.fs b/TUnit.TestProject.FSharp/LongFailures.fs new file mode 100644 index 0000000000..5925df51a2 --- /dev/null +++ b/TUnit.TestProject.FSharp/LongFailures.fs @@ -0,0 +1,18 @@ +namespace TUnit.TestProject.FSharp + +open System +open System.Threading +open System.Threading.Tasks +open TUnit.Core + +[] +type LongFailures() = + static let mutable counter = 0 + + [] + [] + member _.LongFailure() : Task = task { + let delay = Interlocked.Increment(&counter) + do! Task.Delay(TimeSpan.FromSeconds(float delay)) + raise (Exception()) + } \ No newline at end of file diff --git a/TUnit.TestProject.FSharp/MyTests.fs b/TUnit.TestProject.FSharp/MyTests.fs new file mode 100644 index 0000000000..6e52863f39 --- /dev/null +++ b/TUnit.TestProject.FSharp/MyTests.fs @@ -0,0 +1,8 @@ +namespace TUnit.TestProject.FSharp + +open System.Threading.Tasks +open TUnit.Core + +// Equivalent of MyTests.cs + +type MyTests() = class end diff --git a/TUnit.TestProject.FSharp/NameOfArgumentTests.fs b/TUnit.TestProject.FSharp/NameOfArgumentTests.fs new file mode 100644 index 0000000000..6ecc446406 --- /dev/null +++ b/TUnit.TestProject.FSharp/NameOfArgumentTests.fs @@ -0,0 +1,10 @@ +namespace TUnit.TestProject.FSharp + +open System.Threading.Tasks +open TUnit.Core + +// Equivalent of NameOfArgumentTests.cs + +type NameOfArgumentTests() = + [] + member _.Test(x: int) = () diff --git a/TUnit.TestProject.FSharp/NestedBaseTests.fs b/TUnit.TestProject.FSharp/NestedBaseTests.fs new file mode 100644 index 0000000000..ec97266f53 --- /dev/null +++ b/TUnit.TestProject.FSharp/NestedBaseTests.fs @@ -0,0 +1,10 @@ +namespace TUnit.TestProject.FSharp + +open System.Threading.Tasks +open TUnit.Core + +// Equivalent of NestedBaseTests.cs + +type NestedBaseTests() = + [] + member _.Test() = () diff --git a/TUnit.TestProject.FSharp/NestedExceptionTests.fs b/TUnit.TestProject.FSharp/NestedExceptionTests.fs new file mode 100644 index 0000000000..53d8d01b45 --- /dev/null +++ b/TUnit.TestProject.FSharp/NestedExceptionTests.fs @@ -0,0 +1,8 @@ +namespace TUnit.TestProject.FSharp + +open System.Threading.Tasks +open TUnit.Core + +type NestedExceptionTests() = + [] + member _.Test() = () diff --git a/TUnit.TestProject.FSharp/NonBase.fs b/TUnit.TestProject.FSharp/NonBase.fs new file mode 100644 index 0000000000..524ece2ffa --- /dev/null +++ b/TUnit.TestProject.FSharp/NonBase.fs @@ -0,0 +1,20 @@ +namespace TUnit.TestProject.FSharp + +open System.Threading.Tasks +open TUnit.Core + +// Equivalent of OneTimeSetUpWithBaseTests.NonBase.cs + +type NonBase() = + inherit Base1() + + [] + static member NonBaseOneTimeSetup() : Task = + Task.CompletedTask + + [] + member _.NonBaseSetUp() : Task = + Task.CompletedTask + + [] + member _.Test() = () // Dummy method diff --git a/TUnit.TestProject.FSharp/NotInParallelTests.fs b/TUnit.TestProject.FSharp/NotInParallelTests.fs new file mode 100644 index 0000000000..10936ae771 --- /dev/null +++ b/TUnit.TestProject.FSharp/NotInParallelTests.fs @@ -0,0 +1,52 @@ +namespace TUnit.TestProject.FSharp + +open System +open System.Collections.Concurrent +open System.Linq +open System.Threading.Tasks +open TUnit.Assertions +open TUnit.Assertions.Extensions +open TUnit.Core + +// F# equivalent of NotInParallelTests.cs + +type DateTimeRange(start: DateTime, end_: DateTime) = + member _.Start = start + member _.End = end_ + member this.Overlap(other: DateTimeRange) = + this.Start <= other.End && other.Start <= this.End + +type NotInParallelTests() = + static let testDateTimeRanges = ConcurrentBag() + + [] + member _.TestOverlaps() : Task = task { + testDateTimeRanges.Add(DateTimeRange(TestContext.Current.TestStart.Value.DateTime, TestContext.Current.Result.End.Value.DateTime)) + do! NotInParallelTests.AssertNoOverlaps() + } + + [] + [] + [] + member _.NotInParallel_Test1() : Task = + Task.Delay(500) + + [] + [] + [] + member _.NotInParallel_Test2() : Task = + Task.Delay(500) + + [] + [] + [] + member _.NotInParallel_Test3() : Task = + Task.Delay(500) + + static member private AssertNoOverlaps() : Task = task { + for testDateTimeRange in testDateTimeRanges do + let overlaps = testDateTimeRanges + |> Seq.filter (fun x -> not (Object.ReferenceEquals(x, testDateTimeRange))) + |> Seq.exists (fun x -> x.Overlap(testDateTimeRange)) + do! Assert.That(overlaps).IsFalse() + } diff --git a/TUnit.TestProject.FSharp/NullableByteArgumentTests.fs b/TUnit.TestProject.FSharp/NullableByteArgumentTests.fs new file mode 100644 index 0000000000..6ed8d78ddc --- /dev/null +++ b/TUnit.TestProject.FSharp/NullableByteArgumentTests.fs @@ -0,0 +1,18 @@ +namespace TUnit.TestProject.FSharp + +open TUnit.Core + +// F# equivalent of NullableByteArgumentTests.cs + +type NullableByteArgumentTests() = + [] + [] + [] + member _.Test(someByte: byte option) = + () + + [] + [] + [] + member _.Test2(byte1: byte, byte2: byte option) = + () diff --git a/TUnit.TestProject.FSharp/NumberArgumentTests.fs b/TUnit.TestProject.FSharp/NumberArgumentTests.fs new file mode 100644 index 0000000000..ab470a6854 --- /dev/null +++ b/TUnit.TestProject.FSharp/NumberArgumentTests.fs @@ -0,0 +1,10 @@ +namespace TUnit.TestProject.FSharp + +open System.Threading.Tasks +open TUnit.Core + +// Equivalent of NumberArgumentTests.cs + +type NumberArgumentTests() = + [] + member _.Test(x: int) = () diff --git a/TUnit.TestProject.FSharp/OneTimeSetUpWithBaseTests.Base1.fs b/TUnit.TestProject.FSharp/OneTimeSetUpWithBaseTests.Base1.fs new file mode 100644 index 0000000000..06de7a07a1 --- /dev/null +++ b/TUnit.TestProject.FSharp/OneTimeSetUpWithBaseTests.Base1.fs @@ -0,0 +1,15 @@ +namespace TUnit.TestProject.FSharp.OneTimeSetUpWithBaseTests + +open System.Threading.Tasks +open TUnit.Core + +// Equivalent of OneTimeSetUpWithBaseTests.Base1.cs + +type Base1() = + [] + static member Base1OneTimeSetup() : Task = + Task.CompletedTask + + [] + member _.Base1SetUp() : Task = + Task.CompletedTask diff --git a/TUnit.TestProject.FSharp/OneTimeSetUpWithBaseTests.Base2.fs b/TUnit.TestProject.FSharp/OneTimeSetUpWithBaseTests.Base2.fs new file mode 100644 index 0000000000..d2ab809ce0 --- /dev/null +++ b/TUnit.TestProject.FSharp/OneTimeSetUpWithBaseTests.Base2.fs @@ -0,0 +1,15 @@ +namespace TUnit.TestProject.FSharp.OneTimeSetUpWithBaseTests + +open System.Threading.Tasks +open TUnit.Core + +// Equivalent of OneTimeSetUpWithBaseTests.Base2.cs + +type Base2() = + [] + static member Base2OneTimeSetup() : Task = + Task.CompletedTask + + [] + member _.Base2SetUp() : Task = + Task.CompletedTask diff --git a/TUnit.TestProject.FSharp/OneTimeSetUpWithBaseTests.NonBase.fs b/TUnit.TestProject.FSharp/OneTimeSetUpWithBaseTests.NonBase.fs new file mode 100644 index 0000000000..f0a3958ef6 --- /dev/null +++ b/TUnit.TestProject.FSharp/OneTimeSetUpWithBaseTests.NonBase.fs @@ -0,0 +1,20 @@ +namespace TUnit.TestProject.FSharp.OneTimeSetUpWithBaseTests + +open System.Threading.Tasks +open TUnit.Core + +// Equivalent of OneTimeSetUpWithBaseTests.NonBase.cs + +type NonBase() = + inherit Base1() + + [] + static member NonBaseOneTimeSetup() : Task = + Task.CompletedTask + + [] + member _.NonBaseSetUp() : Task = + Task.CompletedTask + + [] + member _.Test() = () diff --git a/TUnit.TestProject.FSharp/OptionalArgumentsTests.fs b/TUnit.TestProject.FSharp/OptionalArgumentsTests.fs new file mode 100644 index 0000000000..2e29720909 --- /dev/null +++ b/TUnit.TestProject.FSharp/OptionalArgumentsTests.fs @@ -0,0 +1,12 @@ +namespace TUnit.TestProject.FSharp + +open TUnit.Core + +// F# equivalent of OptionalArgumentsTests.cs + +type OptionalArgumentsTests() = + [] + [] + member _.Test(value: int, ?flag: bool) = + let flag = defaultArg flag true + () // Dummy Method diff --git a/TUnit.TestProject.FSharp/TUnit.TestProject.FSharp.fsproj b/TUnit.TestProject.FSharp/TUnit.TestProject.FSharp.fsproj index 5fce858d96..3b7084a157 100644 --- a/TUnit.TestProject.FSharp/TUnit.TestProject.FSharp.fsproj +++ b/TUnit.TestProject.FSharp/TUnit.TestProject.FSharp.fsproj @@ -2,6 +2,7 @@ 9.0 + enable @@ -13,12 +14,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -26,6 +65,8 @@ + + diff --git a/TUnit.TestProject.FSharp/TestDataSources.fs b/TUnit.TestProject.FSharp/TestDataSources.fs new file mode 100644 index 0000000000..035157866d --- /dev/null +++ b/TUnit.TestProject.FSharp/TestDataSources.fs @@ -0,0 +1,9 @@ +namespace TUnit.TestProject.FSharp + +type TestDataSources() = + static member One() = 1 + static member Two() = 2 + + static member OneEnumerable() = [| 1; 1; 1; 1; 1; 1; 1; 1; 1; 1 |] + static member OneFailingEnumerable() = [| 1; 2; 3; 4; 5; 6; 7; 8; 9 |] + diff --git a/TUnit.TestProject.FSharp/Tests.fs b/TUnit.TestProject.FSharp/Tests.fs index ee835b5b28..d488cbb114 100644 --- a/TUnit.TestProject.FSharp/Tests.fs +++ b/TUnit.TestProject.FSharp/Tests.fs @@ -1,19 +1,325 @@ namespace TUnit.TestProject.FSharp +open System +open System.Threading +open System.Threading.Tasks open TUnit.Assertions open TUnit.Assertions.Extensions open TUnit.Assertions.FSharp.Operations open TUnit.Core +open TUnit.TestProject +open TUnit.Assertions.AssertConditions.Throws type Tests() = + + let _retryCount = 0 + + [] + [] + member _.ConsoleOutput() = async { + Console.WriteLine("Blah!") + do! check ((Assert.That(TestContext.Current.GetStandardOutput(): string | null).IsEqualTo("Blah!", StringComparison.Ordinal))) + } + + [] + [] + member _.Test1() = async { + let value = "1" + do! check (Assert.That(value).IsEqualTo("1")) + } + + [] + [] + member _.LessThan() = async { + let value = 1 + do! check (Assert.That(value).IsLessThan(2)) + } + + [] + [] + member _.Test2() = async { + let value = "2" + do! check (Assert.That(value).IsEqualTo("1")) + } + + [] + [] + member _.Test3() = async { + let value = "1" + do! check (Assert.That(value).IsEqualTo("1")) + } + + [] + [] + member _.Test4() = async { + let value = "2" + do! check (Assert.That(value).IsEqualTo("1")) + } + + [] + [] + [] + [] + [] + [] + [] + member _.ParameterisedTests1(value: string) = async { + do! check (Assert.That(value).IsEqualTo("1").And.HasLength().EqualTo(1)) + } + + [] + [] + [] + [] + [] + [] + [] + member _.ParameterisedTests2(value: string) = async { + do! check (Assert.That(value).IsEqualTo("1")) + } + + [] + [] + [] + member _.Skip1() = async { + let value = "1" + do! check (Assert.That(value).IsEqualTo("1")) + } + + [] + [] + [] + member _.Skip2() = async { + let value = "1" + do! check (Assert.That(value).IsEqualTo("1")) + } + + [] + [] + [] + member _.CustomSkip1() = async { + let value = "1" + do! check (Assert.That(value).IsEqualTo("1")) + } + + [] + [] + [] + member _.TestDataSource1(value: int) = async { + do! check (Assert.That(value).IsEqualTo(1)) + } + + [] + [] + [] + member _.TestDataSource2(value: int) = async { + do! check (Assert.That(value).IsEqualTo(1)) + } + + [] + [] + [] + member _.TestDataSource3(value: int) = async { + do! check (Assert.That(value).IsEqualTo(1)) + } + + [] + [] + [] + member _.TestDataSource4(value: int) = async { + do! check (Assert.That(value).IsEqualTo(1)) + } + + [] + [, "One")>] + [] + member _.TestDataSource5(value: int) = async { + do! check (Assert.That(value).IsEqualTo(1)) + } + + [] + [, "One")>] + [] + member _.TestDataSource6(value: int) = async { + do! check (Assert.That(value).IsEqualTo(1)) + } + + [] + [, "Two")>] + [] + member _.TestDataSource_Wrong(value: int) = async { + do! check (Assert.That(value).IsNotEqualTo(1)) + } + + [] + [, "Two")>] + [] + member _.TestDataSource7(value: int) = async { + do! check (Assert.That(value).IsEqualTo(1)) + } + + [] + [, "Two")>] + [] + member _.TestDataSource8(value: int) = async { + do! check (Assert.That(value).IsEqualTo(1)) + } + + [] + [] + member _.TestContext1() = async { + do! check ((Assert.That(TestContext.Current.TestDetails.TestName: string | null).IsEqualTo("TestContext1"))) + } + [] - member this.Test() = - printfn "Test method executed" + [] + member _.TestContext2() = async { + do! check ((Assert.That(TestContext.Current.TestDetails.TestName: string | null).IsEqualTo("TestContext1"))) + } -#if NETCOREAPP [] - member this.TestAsync() = async { - let result = 1 + 1 - do! check (Assert.That(result).IsPositive()) - } -#endif \ No newline at end of file + [] + member _.Throws1() = async { + do! check (Assert.That(fun () -> task { return new string([||]) }).ThrowsException()) + } + + [] + [] + member _.Throws2() = async { + do! check (Assert.That(fun () -> task { do! Task.Yield() }).ThrowsException()) + } + + [] + [] + member _.Throws3() = async { + do! check (Assert.That(fun () -> raise (ApplicationException())).ThrowsException()) + } + + [] + [] + member _.Throws4() = async { + do! check (Assert.That(fun () -> Task.FromResult(true)).ThrowsNothing()) + } + + [] + [] + [] + member _.Timeout1(cancellationToken: CancellationToken) = async { + do! Task.Delay(TimeSpan.FromSeconds(5.0), cancellationToken) |> Async.AwaitTask + } + + [] + [] + member _.String_And_Condition() = async { + do! check (Assert.That("1").IsEqualTo("1").And.HasLength().EqualTo(1)) + } + + [] + [] + member _.String_And_Condition2() = async { + do! check (Assert.That("1").IsEqualTo("2").And.HasLength().EqualTo(2)) + } + + [] + [] + member _.Count1() = async { + let list = [1; 2; 3] + do! check (Assert.That(list).IsEquivalentTo([1; 2; 3]).And.HasCount().EqualTo(3)) + } + + [] + [] + member _.Single() = async { + let list = [1] + let item = list |> Seq.head + do! check(Assert.That(list).HasSingleItem()) + do! check (Assert.That(item).IsEqualTo(1)) + } + + [] + [] + member _.DistinctItems() = async { + let list = [1; 2; 3; 4; 5] + do! check (Assert.That(list).HasDistinctItems()) + } + + [] + [] + member _.Enumerable_NotEmpty() = async { + let list = [1; 2; 3] + do! check (Assert.That(list).IsNotEmpty()) + } + + [] + [] + member _.Count2() = async { + let list = [1; 2; 3] + do! check (Assert.That(list).IsEquivalentTo([1; 2; 3; 4; 5]).And.HasCount().EqualTo(5)) + } + + [] + member _.AssertMultiple() = async { + let list = [1; 2; 3] + use _ = Assert.Multiple() + do! check (Assert.That(list).IsEquivalentTo([1; 2; 3; 4; 5])) + do! check (Assert.That(list).HasCount().EqualTo(5)) + } + + [] + member _.NotNull() = async { + let item: string | null = null + do! check (Assert.That(item).IsNotNull().And.IsNotEmpty()) + } + + [] + member _.NotNull2() = async { + let item = "" + do! check (Assert.That(item).IsNotNull().And.IsNotEmpty()) + } + + [] + member _.Assert_Multiple_With_Or_Conditions() = async { + let one = "" + let two = "Foo bar!" + use _ = Assert.Multiple() + do! check (Assert.That(one).IsNull().Or.IsEmpty()) + do! check (Assert.That(two).IsEqualTo("2").Or.IsNull()) + } + + [] + member _.Throws5() = async { + do! Task.CompletedTask |> Async.AwaitTask + Console.WriteLine(_retryCount) + raise (Exception()) + } + + [] + member _.Throws6() = async { + do! Task.CompletedTask |> Async.AwaitTask + Console.WriteLine(_retryCount) + raise (Exception()) + } + + [] + member _.Throws7() = + Console.WriteLine(_retryCount) + raise (Exception()) + + [] + member _.OneSecond() = async { + do! Task.Delay(TimeSpan.FromSeconds(1.0)) |> Async.AwaitTask + } + + [] + member _.Long_String_Not_Equals() = async { + do! check (Assert.That("ABCDEFGHIJKLMNOOPQRSTUVWXYZ").IsEqualTo("ABCDEFGHIJKLMNOPQRSTUVWXYZ", StringComparison.Ordinal)) + } + + [] + member _.Short_String_Not_Equals() = async { + do! check (Assert.That("ABCCDE").IsEqualTo("ABCDE", StringComparison.Ordinal)) + } + + // Data source methods + static member One() = 1 + static member Two() = 2 \ No newline at end of file diff --git a/TUnit.TestProject.FSharp/UniqueBuilderContextsOnEnumerableDataGeneratorTests.fs b/TUnit.TestProject.FSharp/UniqueBuilderContextsOnEnumerableDataGeneratorTests.fs new file mode 100644 index 0000000000..52ce2a32e2 --- /dev/null +++ b/TUnit.TestProject.FSharp/UniqueBuilderContextsOnEnumerableDataGeneratorTests.fs @@ -0,0 +1,27 @@ +namespace TUnit.TestProject.FSharp + +open System +open System.Collections.Generic +open TUnit.Core +open Shouldly + +type UniqueBuilderContextsOnEnumerableDataGeneratorTestsGenerator() = + inherit DataSourceGeneratorAttribute() + override _.GenerateDataSources(dataGeneratorMetadata) = + let id1 = dataGeneratorMetadata.TestBuilderContext.Current.Id + let id2 = dataGeneratorMetadata.TestBuilderContext.Current.Id + seq { + yield Func(fun () -> 1) + let id3 = dataGeneratorMetadata.TestBuilderContext.Current.Id + yield Func(fun () -> 2) + let id4 = dataGeneratorMetadata.TestBuilderContext.Current.Id + id1.ShouldBe(id2) + id3.ShouldNotBe(id1) + id4.ShouldNotBe(id1) + id4.ShouldNotBe(id3) + } + +type UniqueBuilderContextsOnEnumerableDataGeneratorTests() = + [] + [] + member _.Test(value: int) = () diff --git a/TUnit.TestProject.FSharp/UniqueObjectsOnEnumerableDataGeneratorTests.fs b/TUnit.TestProject.FSharp/UniqueObjectsOnEnumerableDataGeneratorTests.fs new file mode 100644 index 0000000000..4262e494e6 --- /dev/null +++ b/TUnit.TestProject.FSharp/UniqueObjectsOnEnumerableDataGeneratorTests.fs @@ -0,0 +1,10 @@ +namespace TUnit.TestProject.FSharp + +open System.Threading.Tasks +open TUnit.Core + +// Equivalent of UniqueObjectsOnEnumerableDataGeneratorTests.cs + +type UniqueObjectsOnEnumerableDataGeneratorTests() = + [] + member _.Test(x: int) = ()