3 using System
.Collections
.Generic
;
4 using System
.Reflection
;
8 using Xunit
.Abstractions
;
10 using Xunit
.ConsoleClient
;
12 class MsgBus
: IMessageBus
14 public MsgBus(IMessageSink messageSink
, bool stopOnFail
= false) {
18 IMessageSink Sink { get; set; }
20 public bool QueueMessage(IMessageSinkMessage message
) {
21 return Sink
.OnMessage (message
);
24 public void Dispose() {
29 class Discoverer
: XunitTestFrameworkDiscoverer
31 List
<ITestClass
> TestClasses
;
32 IEnumerator
<ITestClass
> TestClassesEnumerator
;
34 ITestFrameworkDiscoveryOptions DiscoveryOptions
;
35 IXunitTestCollectionFactory TestCollectionFactory
;
37 public Discoverer(IAssemblyInfo assemblyInfo
,
38 ISourceInformationProvider sourceProvider
,
39 IMessageSink diagnosticMessageSink
,
40 ITestFrameworkDiscoveryOptions discoveryOptions
,
41 IXunitTestCollectionFactory collectionFactory
= null)
42 : base (assemblyInfo
, sourceProvider
, diagnosticMessageSink
, collectionFactory
) {
43 TestCollectionFactory
= collectionFactory
;
44 Sink
= diagnosticMessageSink
;
45 DiscoveryOptions
= discoveryOptions
;
47 TestClasses
= new List
<ITestClass
> ();
48 foreach (var type
in AssemblyInfo
.GetTypes (false).Where (IsValidTestClass
))
49 TestClasses
.Add (CreateTestClass (type
));
50 TestClassesEnumerator
= TestClasses
.GetEnumerator ();
53 protected override ITestClass
CreateTestClass(ITypeInfo
@class) {
54 return new TestClass(TestCollectionFactory
.Get(@class), @class);
60 if (!TestClassesEnumerator
.MoveNext ())
63 using (var messageBus
= new MsgBus (Sink
)) {
64 var testClass
= TestClassesEnumerator
.Current
;
65 //Console.WriteLine (testClass.Class.Name);
66 if (testClass
.Class
.Name
== "System.Threading.ThreadPools.Tests.ThreadPoolTests")
67 // FIXME: This invokes the static ctor which creates threads
70 FindTestsForType (testClass
, false, messageBus
, DiscoveryOptions
);
71 } catch (Exception ex
) {
72 Console
.WriteLine ("EX: " + ex
);
77 if (nenumerated
% 10 == 0)
78 Console
.WriteLine ("" + (nenumerated
* 100) / TestClasses
.Count
+ "%");
84 class WasmRunner
: IMessageSink
86 ITestFrameworkDiscoveryOptions DiscoveryOptions
;
87 Discoverer discoverer
;
88 ITestFrameworkExecutor executor
;
89 ITestFrameworkExecutionOptions executionOptions
;
90 List
<ITestCase
> testCases
;
93 public WasmRunner (XunitProject project
) {
94 this.project
= project
;
96 var assemblyFileName
= "/" + project
.Assemblies
.First ().AssemblyFilename
;
97 testCases
= new List
<ITestCase
> ();
99 var assembly
= Assembly
.LoadFrom (assemblyFileName
);
100 var assemblyInfo
= new Xunit
.Sdk
.ReflectionAssemblyInfo (assembly
);
102 var collectionBehaviorAttribute
= assemblyInfo
.GetCustomAttributes(typeof(CollectionBehaviorAttribute
)).SingleOrDefault();
103 var testAssembly
= new TestAssembly(assemblyInfo
, null);
105 var collectionFactory
= ExtensibilityPointFactory
.GetXunitTestCollectionFactory(this, collectionBehaviorAttribute
, testAssembly
);
109 res = Activator.CreateInstance (typeof (Xunit.Sdk.MemberDataDiscoverer), true, true);
110 Console.WriteLine ("DISC2: " + res);
113 DiscoveryOptions
= TestFrameworkOptions
.ForDiscovery(null);
114 executionOptions
= TestFrameworkOptions
.ForExecution(null);
116 discoverer
= new Discoverer (assemblyInfo
, new NullSourceInformationProvider(), this, DiscoveryOptions
, collectionFactory
);
118 executor
= new XunitTestFrameworkExecutor (assembly
.GetName (), new NullSourceInformationProvider (), this);
121 static object ConvertArg (object arg
, Type argType
) {
122 //if (args [i] != null && pars [i].ParameterType != args [i].GetType () && (args [i] is IConvertible))
123 // args [i] = Convert.ChangeType (args [i], pars [i].ParameterType);
124 if (arg
== null || arg
.GetType () == argType
)
126 // Not clear what conversions should be done
127 // IEnumerable<T> -> T[]
128 if (argType
.IsArray
) {
129 Type t
= typeof (IEnumerable
<>).MakeGenericType (argType
.GetElementType ());
130 if (t
.IsAssignableFrom (arg
.GetType ())) {
131 var m
= typeof (Enumerable
).GetMethod ("ToArray").MakeGenericMethod (new Type
[] { argType.GetElementType () }
);
132 return m
.Invoke (null, new object [] { arg }
);
138 public virtual bool OnMessage (IMessageSinkMessage msg
) {
139 if (msg
is Xunit
.Sdk
.TestCaseDiscoveryMessage disc_msg
) {
140 testCases
.Add (disc_msg
.TestCase
);
143 //Console.WriteLine ("MSG:" + msg);
145 if (msg is Xunit.Sdk.DiagnosticMessage dmsg)
146 Console.WriteLine ("MSG:" + dmsg.Message);
147 else if (msg is Xunit.Sdk.TestCaseDiscoveryMessage disc_msg)
148 Console.WriteLine ("TEST:" + disc_msg.TestCase.DisplayName);
150 Console.WriteLine ("MSG:" + msg);
155 public int nrun
, nfail
, nskipped
, nfiltered
;
161 Console
.WriteLine ("Discovering tests...");
165 bool res
= discoverer
.Step ();
171 Console
.WriteLine ("Running " + testCases
.Count
+ " tests...");
175 Console
.WriteLine (".");
177 string last_name
= "";
179 if (tc_index
== testCases
.Count
)
181 var tc
= testCases
[tc_index
] as XunitTestCase
;
185 if (!project
.Filters
.Filter (tc
)) {
190 var itrait_attrs
= tc
.TestMethod
.Method
.GetCustomAttributes(typeof(ITraitAttribute
));
192 if (itrait_attrs
.Count () > 0) {
193 Console
.WriteLine ("SKIP (ITraitAttribute): " + tc
.DisplayName
);
198 foreach (var attr in itrait_attrs) {
199 Console.WriteLine (attr);
200 foreach (var disc_attr in attr.GetCustomAttributes (typeof (TraitDiscovererAttribute))) {
201 Console.WriteLine (disc_attr);
207 var method
= (tc
.Method
as ReflectionMethodInfo
).MethodInfo
;
209 if (method
.ReflectedType
.IsGenericTypeDefinition
) {
210 Console
.WriteLine ("FAIL (generic): " + tc
.DisplayName
);
215 if (tc
is Xunit
.Sdk
.XunitTheoryTestCase
) {
216 if (method
.IsGenericMethod
) {
217 Console
.WriteLine ("SKIP (generic): " + tc
.DisplayName
);
222 // From XunitTheoryTestCaseRunner
223 var attrs
= tc
.TestMethod
.Method
.GetCustomAttributes(typeof(DataAttribute
));
225 foreach (var dataAttribute
in attrs
) {
226 var discovererAttribute
= dataAttribute
.GetCustomAttributes(typeof(DataDiscovererAttribute
)).First();
227 var args
= discovererAttribute
.GetConstructorArguments().Cast
<string>().ToList();
229 Type discovererType
= null;
230 if (args
[1] == "xunit.core")
231 discovererType
= typeof (IXunitTestCollectionFactory
).Assembly
.GetType (args
[0]);
232 if (discovererType
== null) {
233 Console
.WriteLine ("FAIL (discoverer): " + args
[0] + " " + args
[1]);
237 IDataDiscoverer discoverer
;
238 discoverer
= ExtensibilityPointFactory
.GetDataDiscoverer (this, discovererType
);
240 var data
= discoverer
.GetData (dataAttribute
, tc
.TestMethod
.Method
);
241 Console
.WriteLine (tc
.DisplayName
+ " [" + data
.Count () + "]");
242 foreach (var dataRow
in data
) {
246 if (!method
.IsStatic
)
247 obj
= Activator
.CreateInstance (method
.ReflectedType
);
248 var pars
= method
.GetParameters ();
249 for (int i
= 0; i
< dataRow
.Length
; ++i
)
250 dataRow
[i
] = ConvertArg (dataRow
[i
], pars
[i
].ParameterType
);
251 method
.Invoke (obj
, BindingFlags
.Default
, null, dataRow
, null);
252 } catch (Exception ex
) {
253 Console
.WriteLine ("FAIL: " + ex
);
263 if (!String
.IsNullOrEmpty (tc
.SkipReason
)) {
268 var name
= tc
.DisplayName
;
269 if (name
.Contains ("("))
270 name
= name
.Substring (0, name
.IndexOf ("("));
271 if (name
!= last_name
)
272 Console
.WriteLine (name
);
274 //Console.WriteLine (tc.DisplayName);
277 if (!method
.IsStatic
)
278 obj
= Activator
.CreateInstance (method
.ReflectedType
);
280 var args
= tc
.TestMethodArguments
;
282 var pars
= method
.GetParameters ();
283 for (int i
= 0; i
< args
.Length
; ++i
) {
284 args
[i
] = ConvertArg (args
[i
], pars
[i
].ParameterType
);
287 method
.Invoke (obj
, args
);
288 } catch (Exception ex
) {
289 Console
.WriteLine ("FAIL: " + tc
.DisplayName
);
290 Console
.WriteLine (ex
);
296 //foreach (var tc in testCases)
297 // Console.WriteLine (tc.DisplayName);
298 //executor.RunTests (testCases, this, executionOptions);
299 Console
.WriteLine ("TESTS = " + testCases
.Count
+ ", RUN = " + nrun
+ ", SKIP = " + nfiltered
+ ", FAIL = " + nfail
);
300 return nfail
== 0 ? 0 : 1;
304 class CmdLineParser
: CommandLine
306 public CmdLineParser (String
[] args
) : base (args
, s
=> true) {
310 public class XunitDriver
312 static WasmRunner testRunner
;
314 static int Main (String
[] args
) {
316 // FIXME: This doesn't work with wasm
318 var new_args = new List<string> ();
319 foreach (var arg in args) {
320 if (arg [0] == '@') {
321 foreach (var line in File.ReadAllLines ("/" + arg.Substring (1)))
328 var cmdline
= new CmdLineParser (args
);
329 testRunner
= new WasmRunner (cmdline
.Project
);
330 return testRunner
.Run ();