undo change in mini.c
[mono-project.git] / sdks / wasm / xunit-runner.cs
blob8cddb14dca0d28254989924a67d53d08abe35339
1 using System;
2 using System.IO;
3 using System.Collections.Generic;
4 using System.Reflection;
5 using System.Linq;
7 using Xunit;
8 using Xunit.Abstractions;
9 using Xunit.Sdk;
10 using Xunit.ConsoleClient;
12 class MsgBus : IMessageBus
14 public MsgBus(IMessageSink messageSink, bool stopOnFail = false) {
15 Sink = messageSink;
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;
33 IMessageSink Sink;
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);
57 int nenumerated;
59 public bool Step () {
60 if (!TestClassesEnumerator.MoveNext ())
61 return false;
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
68 return true;
69 try {
70 FindTestsForType (testClass, false, messageBus, DiscoveryOptions);
71 } catch (Exception ex) {
72 Console.WriteLine ("EX: " + ex);
76 nenumerated ++;
77 if (nenumerated % 10 == 0)
78 Console.WriteLine ("" + (nenumerated * 100) / TestClasses.Count + "%");
80 return true;
84 class WasmRunner : IMessageSink
86 ITestFrameworkDiscoveryOptions DiscoveryOptions;
87 Discoverer discoverer;
88 ITestFrameworkExecutor executor;
89 ITestFrameworkExecutionOptions executionOptions;
90 List<ITestCase> testCases;
91 XunitProject project;
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);
108 object res = null;
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)
125 return arg;
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 });
135 return arg;
138 public virtual bool OnMessage (IMessageSinkMessage msg) {
139 if (msg is Xunit.Sdk.TestCaseDiscoveryMessage disc_msg) {
140 testCases.Add (disc_msg.TestCase);
141 return true;
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);
149 else
150 Console.WriteLine ("MSG:" + msg);
152 return true;
155 public int nrun, nfail, nskipped, nfiltered;
157 public int Run () {
158 int state;
159 int tc_index;
161 Console.WriteLine ("Discovering tests...");
163 int n = 0;
164 while (n < 20) {
165 bool res = discoverer.Step ();
166 if (!res) {
167 break;
171 Console.WriteLine ("Running " + testCases.Count + " tests...");
172 state = 3;
173 tc_index = 0;
175 Console.WriteLine (".");
176 int ncases = 0;
177 string last_name = "";
178 while (true) {
179 if (tc_index == testCases.Count)
180 break;
181 var tc = testCases [tc_index] as XunitTestCase;
183 tc_index ++;
185 if (!project.Filters.Filter (tc)) {
186 nfiltered ++;
187 continue;
190 var itrait_attrs = tc.TestMethod.Method.GetCustomAttributes(typeof(ITraitAttribute));
191 // FIXME:
192 if (itrait_attrs.Count () > 0) {
193 Console.WriteLine ("SKIP (ITraitAttribute): " + tc.DisplayName);
194 nfiltered ++;
195 continue;
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);
211 nfail ++;
212 continue;
215 if (tc is Xunit.Sdk.XunitTheoryTestCase) {
216 if (method.IsGenericMethod) {
217 Console.WriteLine ("SKIP (generic): " + tc.DisplayName);
218 nfiltered ++;
219 continue;
222 // From XunitTheoryTestCaseRunner
223 var attrs = tc.TestMethod.Method.GetCustomAttributes(typeof(DataAttribute));
224 bool failed = false;
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]);
234 failed = true;
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) {
243 nrun ++;
244 try {
245 object obj = null;
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);
254 nfail ++;
258 if (failed) {
259 nfail ++;
260 continue;
262 } else {
263 if (!String.IsNullOrEmpty (tc.SkipReason)) {
264 nskipped ++;
265 continue;
267 nrun ++;
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);
273 last_name = name;
274 //Console.WriteLine (tc.DisplayName);
275 try {
276 object obj = null;
277 if (!method.IsStatic)
278 obj = Activator.CreateInstance (method.ReflectedType);
280 var args = tc.TestMethodArguments;
281 if (args != null) {
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);
291 nfail ++;
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) {
315 // Process rsp files
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)))
322 new_args.Add (line);
323 } else {
324 new_args.Add (arg);
328 var cmdline = new CmdLineParser (args);
329 testRunner = new WasmRunner (cmdline.Project);
330 return testRunner.Run ();