Skip to content

Instantly share code, notes, and snippets.

@yukitos
Last active October 3, 2015 16:02
Show Gist options
  • Save yukitos/7fb635868ef3bbd86c42 to your computer and use it in GitHub Desktop.
Save yukitos/7fb635868ef3bbd86c42 to your computer and use it in GitHub Desktop.
WIP: Trying to fix MissingMethodException of Persimmon.VisualStudio.TestExplorer.
namespace Persimmon.Runner.Wrapper
open Microsoft.VisualStudio.TestPlatform.ObjectModel.Logging
open System
open System.Collections.Generic
open System.Reflection
module private TestCollectorImpl =
open Persimmon
open RuntimeUtil
let publicTypes (asm: Assembly) =
asm.GetTypes()
|> Seq.filter (fun typ -> typ.IsPublic)
let publicNestedTypes (typ: Type) =
typ.GetNestedTypes()
|> Seq.filter (fun typ -> typ.IsNestedPublic)
let typedefis<'T>(typ: Type) =
typ.IsGenericType && typ.GetGenericTypeDefinition() = typedefof<'T>
let (|SubTypeOf|_|) (matching: Type) (typ: Type) =
if matching.IsAssignableFrom(typ) then Some typ else None
let (|ArrayType|_|) (typ: Type) = if typ.IsArray then Some (typ.GetElementType()) else None
let (|GenericType|_|) (typ: Type) =
if typ.IsGenericType then
Some (typ.GetGenericTypeDefinition(), typ.GetGenericArguments())
else
None
let log (s) =
let msg = sprintf "%s: %s%s" (DateTime.Now.ToString()) s Environment.NewLine
System.IO.File.AppendAllText("C:\\gh\\log.txt", msg)
let persimmonTests (f: unit -> obj) (typ: Type) name =
log("Target name: " + name)
log("Target type: " + typ.FullName)
seq {
let testObjType = typeof<TestObject>
match typ with
| SubTypeOf testObjType _ ->
log(String.Format("SubTypeOf: {0}", testObjType.FullName))
yield (f () :?> TestObject).SetNameIfNeed(name)
| ArrayType elemType when typedefis<TestCase<_>>(elemType) || elemType = typeof<TestObject> ->
log(String.Format("ArrayType: {0}", elemType.FullName))
yield! (f (), elemType) |> RuntimeArray.map (fun x -> (x :?> TestObject).SetNameIfNeed(name) |> box)
| GenericType (genTypeDef, _) when genTypeDef = typedefof<TestCase<_>> ->
log(String.Format("GenericType: {0}", genTypeDef.FullName))
yield (f () :?> TestObject).SetNameIfNeed(name)
| GenericType (genTypeDef, [| elemType |]) when genTypeDef = typedefof<_ seq> && (typedefis<TestCase<_>>(elemType) || elemType = typeof<TestObject>) ->
log(String.Format("GenericType: {0}, {1}", genTypeDef.FullName, elemType.FullName))
yield! (f (), elemType) |> RuntimeSeq.map (fun x -> (x :?> TestObject).SetNameIfNeed(name) |> box)
| GenericType (genTypeDef, [| elemType |]) when genTypeDef = typedefof<_ list> && (typedefis<TestCase<_>>(elemType) || elemType = typeof<TestObject>) ->
log(String.Format("GenericType: {0}, {1}", genTypeDef.FullName, elemType.FullName))
yield! (f (), elemType) |> RuntimeList.map (fun x -> (x :?> TestObject).SetNameIfNeed(name) |> box)
| _ -> log("Other."); ()
}
let persimmonTestProps (p: PropertyInfo) =
persimmonTests (fun () -> p.GetValue(null, null)) p.PropertyType p.Name
let persimmonTestMethods (m: MethodInfo) =
persimmonTests (fun () -> m.Invoke(null, [||])) m.ReturnType m.Name
let rec testObjects (typ: Type) =
log("Current target type: " + typ.FullName)
seq {
log("Yielding 1st things")
yield!
typ.GetProperties(BindingFlags.Static ||| BindingFlags.Public)
|> Seq.collect persimmonTestProps
|> Seq.map (fun x -> (typ, x))
log("Yielding 2nd things")
yield!
typ.GetMethods(BindingFlags.Static ||| BindingFlags.Public)
|> Seq.filter (fun m -> not m.IsSpecialName) // ignore getter methods
|> Seq.filter (fun m -> m.GetParameters() |> Array.isEmpty)
|> Seq.collect persimmonTestMethods
|> Seq.map (fun x -> (typ, x))
log("Yielding the last things")
for nestedType in publicNestedTypes typ do
let objs = testObjects nestedType |> Seq.map snd
if Seq.isEmpty objs then ()
else
log(String.Format("testObjects: nestedType: {0}", nestedType.FullName))
let testObj = typeof<Context>.GetConstructor([| typeof<string>; typeof<list<TestObject>> |]).Invoke([| nestedType.Name, objs |> Seq.toList |]) :?> TestObject
yield (nestedType, testObj)
}
type TestCollector() =
inherit MarshalByRefObject()
member __.CollectRootTestObjects (asms: IEnumerable<Assembly>): IEnumerable<TestCase> =
asms
|> Seq.collect (fun s ->
s
|> TestCollectorImpl.publicTypes
|> Seq.collect TestCollectorImpl.testObjects
|> Seq.map (TestCase.ofTestObject s.FullName)
|> Seq.map (fun i -> TestCollectorImpl.log("Test: " + i.FullyQualifiedName); i)
)
interface IExecutor<TestCase> with
member this.Execute asms = this.CollectRootTestObjects(asms)
2015/10/03 22:28:28: Current target type: Persimmon.Runner.Wrapper.IExecutor`1
2015/10/03 22:28:28: Yielding 1st things
2015/10/03 22:28:28: Yielding 2nd things
2015/10/03 22:28:28: Yielding the last things
2015/10/03 22:28:28: Current target type: Persimmon.Runner.Wrapper.TestCase
2015/10/03 22:28:28: Yielding 1st things
2015/10/03 22:28:28: Yielding 2nd things
2015/10/03 22:28:28: Yielding the last things
2015/10/03 22:28:28: Current target type: Persimmon.Runner.Wrapper.TestCollector
2015/10/03 22:28:28: Yielding 1st things
2015/10/03 22:28:28: Yielding 2nd things
2015/10/03 22:28:28: Yielding the last things
2015/10/03 22:28:28: Current target type: Persimmon.Runner.Wrapper.TestOutcome
2015/10/03 22:28:28: Yielding 1st things
2015/10/03 22:28:28: Yielding 2nd things
2015/10/03 22:28:28: Yielding the last things
2015/10/03 22:28:28: Current target type: Persimmon.Runner.Wrapper.TestResult
2015/10/03 22:28:28: Yielding 1st things
2015/10/03 22:28:28: Yielding 2nd things
2015/10/03 22:28:28: Yielding the last things
2015/10/03 22:28:28: Current target type: Persimmon.Runner.Wrapper.TestRunner
2015/10/03 22:28:28: Yielding 1st things
2015/10/03 22:28:28: Yielding 2nd things
2015/10/03 22:28:28: Yielding the last things
2015/10/03 22:28:28: Current target type: Persimmon.Runner.Wrapper.RuntimeUtil
2015/10/03 22:28:28: Yielding 1st things
2015/10/03 22:28:28: Yielding 2nd things
2015/10/03 22:28:28: Yielding the last things
2015/10/03 22:28:28: Current target type: Persimmon.VisualStudio.TestExplorer.Tests.ReflectTest
2015/10/03 22:28:28: Yielding 1st things
2015/10/03 22:28:28: Yielding 2nd things
2015/10/03 22:28:28: Yielding the last things
2015/10/03 22:28:28: Current target type: Persimmon.VisualStudio.TestExplorer.OptionBuilder
2015/10/03 22:28:28: Yielding 1st things
2015/10/03 22:28:28: Yielding 2nd things
2015/10/03 22:28:28: Yielding the last things
2015/10/03 22:28:28: Current target type: Persimmon.VisualStudio.TestExplorer.VSTestRunner
2015/10/03 22:28:28: Yielding 1st things
2015/10/03 22:28:28: Yielding 2nd things
2015/10/03 22:28:28: Yielding the last things
2015/10/03 22:28:28: Current target type: Persimmon.VisualStudio.TestExplorer.VSTestAdapter
2015/10/03 22:28:28: Yielding 1st things
2015/10/03 22:28:28: Yielding 2nd things
2015/10/03 22:28:28: Yielding the last things
2015/10/03 22:28:28: Current target type: Persimmon.VisualStudio.TestExplorer.VSTestResult
2015/10/03 22:28:28: Yielding 1st things
2015/10/03 22:28:28: Yielding 2nd things
2015/10/03 22:28:28: Yielding the last things
2015/10/03 22:28:28: Current target type: Persimmon.VisualStudio.TestExplorer.VSTestCase
2015/10/03 22:28:28: Yielding 1st things
2015/10/03 22:28:28: Yielding 2nd things
2015/10/03 22:28:28: Yielding the last things
2015/10/03 22:28:28: Current target type: Persimmon.VisualStudio.TestExplorer.ComputationExpression
2015/10/03 22:28:28: Yielding 1st things
2015/10/03 22:28:28: Target name: option
2015/10/03 22:28:28: Target type: Persimmon.VisualStudio.TestExplorer.OptionBuilder
2015/10/03 22:28:28: Other.
2015/10/03 22:28:28: Yielding 2nd things
2015/10/03 22:28:28: Yielding the last things
2015/10/03 22:28:28: Current target type: Persimmon.VisualStudio.TestExplorer.Constant
2015/10/03 22:28:28: Yielding 1st things
2015/10/03 22:28:28: Yielding 2nd things
2015/10/03 22:28:28: Yielding the last things
2015/10/03 22:28:28: Current target type: Persimmon.Runner.Wrapper.IExecutor`1
2015/10/03 22:28:28: Yielding 1st things
2015/10/03 22:28:28: Yielding 2nd things
2015/10/03 22:28:28: Yielding the last things
2015/10/03 22:28:28: Current target type: Persimmon.Runner.Wrapper.TestCase
2015/10/03 22:28:28: Yielding 1st things
2015/10/03 22:28:28: Yielding 2nd things
2015/10/03 22:28:28: Yielding the last things
2015/10/03 22:28:28: Current target type: Persimmon.Runner.Wrapper.TestCollector
2015/10/03 22:28:28: Yielding 1st things
2015/10/03 22:28:28: Yielding 2nd things
2015/10/03 22:28:28: Yielding the last things
2015/10/03 22:28:28: Current target type: Persimmon.Runner.Wrapper.TestOutcome
2015/10/03 22:28:28: Yielding 1st things
2015/10/03 22:28:28: Yielding 2nd things
2015/10/03 22:28:28: Yielding the last things
2015/10/03 22:28:28: Current target type: Persimmon.Runner.Wrapper.TestResult
2015/10/03 22:28:28: Yielding 1st things
2015/10/03 22:28:28: Yielding 2nd things
2015/10/03 22:28:28: Yielding the last things
2015/10/03 22:28:28: Current target type: Persimmon.Runner.Wrapper.TestRunner
2015/10/03 22:28:28: Yielding 1st things
2015/10/03 22:28:28: Yielding 2nd things
2015/10/03 22:28:28: Yielding the last things
2015/10/03 22:28:28: Current target type: Persimmon.Runner.Wrapper.RuntimeUtil
2015/10/03 22:28:28: Yielding 1st things
2015/10/03 22:28:28: Yielding 2nd things
2015/10/03 22:28:28: Yielding the last things
2015/10/03 22:28:28: Current target type: Persimmon.VisualStudio.TestExplorer.Tests.ReflectTest
2015/10/03 22:28:28: Yielding 1st things
2015/10/03 22:28:28: Yielding 2nd things
2015/10/03 22:28:28: Yielding the last things
2015/10/03 22:28:28: Current target type: Persimmon.VisualStudio.TestExplorer.OptionBuilder
2015/10/03 22:28:28: Yielding 1st things
2015/10/03 22:28:28: Yielding 2nd things
2015/10/03 22:28:28: Yielding the last things
2015/10/03 22:28:28: Current target type: Persimmon.VisualStudio.TestExplorer.VSTestRunner
2015/10/03 22:28:28: Yielding 1st things
2015/10/03 22:28:28: Yielding 2nd things
2015/10/03 22:28:28: Yielding the last things
2015/10/03 22:28:28: Current target type: Persimmon.VisualStudio.TestExplorer.VSTestAdapter
2015/10/03 22:28:28: Yielding 1st things
2015/10/03 22:28:28: Yielding 2nd things
2015/10/03 22:28:28: Yielding the last things
2015/10/03 22:28:28: Current target type: Persimmon.VisualStudio.TestExplorer.VSTestResult
2015/10/03 22:28:28: Yielding 1st things
2015/10/03 22:28:28: Yielding 2nd things
2015/10/03 22:28:28: Yielding the last things
2015/10/03 22:28:28: Current target type: Persimmon.VisualStudio.TestExplorer.VSTestCase
2015/10/03 22:28:28: Yielding 1st things
2015/10/03 22:28:28: Yielding 2nd things
2015/10/03 22:28:28: Yielding the last things
2015/10/03 22:28:28: Current target type: Persimmon.VisualStudio.TestExplorer.ComputationExpression
2015/10/03 22:28:28: Yielding 1st things
2015/10/03 22:28:28: Target name: option
2015/10/03 22:28:28: Target type: Persimmon.VisualStudio.TestExplorer.OptionBuilder
2015/10/03 22:28:28: Other.
2015/10/03 22:28:28: Yielding 2nd things
2015/10/03 22:28:28: Yielding the last things
2015/10/03 22:28:28: Current target type: Persimmon.VisualStudio.TestExplorer.Constant
2015/10/03 22:28:28: Yielding 1st things
2015/10/03 22:28:28: Yielding 2nd things
2015/10/03 22:28:28: Yielding the last things
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment