TestsBase.cs 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. using System;
  2. using System.IO;
  3. using System.Diagnostics;
  4. using System.Reflection;
  5. using System.Collections;
  6. using System.Collections.Generic;
  7. using System.Xml.Linq;
  8. using System.Linq;
  9. using Microsoft.CSharp.RuntimeBinder;
  10. using NUnit.Framework;
  11. using sccdlib;
  12. namespace csharp_tests
  13. {
  14. public abstract class TestsBase
  15. {
  16. protected string path_generated_code;
  17. protected bool keep_after_test;
  18. protected abstract bool generate(string file_path, string expected_exception);
  19. [Test, TestCaseSource(typeof(TestsBase),"GetTestCases")]
  20. public void testXML(string file_path)
  21. {
  22. XElement test_xml = XDocument.Load(file_path).Root.Element("test");
  23. Assert.AreNotEqual(null, test_xml, "No test data found. (A test that should just compile correctly, still needs an empthy test tag.)");
  24. //Calculate path to output file
  25. this.path_generated_code = Path.ChangeExtension(Path.GetFileName(file_path), ".cs");
  26. this.keep_after_test = false;
  27. if (File.Exists(this.path_generated_code))
  28. {
  29. this.keep_after_test = true;
  30. File.Delete(this.path_generated_code);
  31. }
  32. string expected_exception = null;
  33. if (test_xml.Attribute("exception") != null && test_xml.Attribute("exception").Value.Trim() != "")
  34. {
  35. expected_exception = test_xml.Attribute("exception").Value.Trim();
  36. }
  37. //Call code generator
  38. if (!this.generate(file_path, expected_exception))
  39. return;
  40. //Compile generated code
  41. CodeCompiler code_compiler = new CodeCompiler();
  42. code_compiler.AddReferencedAssembly("System.dll");
  43. code_compiler.AddReferencedAssembly("sccdlib.dll");
  44. Assembly assembly = code_compiler.compileFile(this.path_generated_code);
  45. Type class_type = assembly.GetType("Controller");
  46. //Prepare expected output
  47. XElement expected_xml = test_xml.Element("expected");
  48. if (expected_xml == null)
  49. return;
  50. HashSet<string> output_ports = new HashSet<string>();
  51. List<List<TestEvent>> expected_result = new List<List<TestEvent>>();
  52. foreach (XElement slot_xml in expected_xml.Elements("slot"))
  53. {
  54. List<TestEvent> slot = new List<TestEvent>();
  55. foreach (XElement event_xml in slot_xml.Elements("event"))
  56. {
  57. string event_name = event_xml.Attribute("name").Value;
  58. string port = event_xml.Attribute("port").Value;
  59. List<string> parameters = new List<string>();
  60. foreach (XElement parameter_xml in event_xml.Elements("parameter"))
  61. {
  62. string parameter_value = parameter_xml.Attribute("value").Value;
  63. parameters.Add(parameter_value);
  64. }
  65. slot.Add(new TestEvent(event_name, port, parameters));
  66. output_ports.Add(port);
  67. }
  68. if (slot.Count > 0)
  69. expected_result.Add(slot);
  70. }
  71. //Prepare model
  72. ThreadsControllerBase controller = (ThreadsControllerBase) Activator.CreateInstance(class_type, new object [] {false});
  73. IOutputListener output_listener = controller.addOutputListener(output_ports.ToArray());
  74. //Input
  75. XElement input_xml = test_xml.Element("input");
  76. if (input_xml != null)
  77. {
  78. foreach (XElement event_xml in input_xml.Elements("event"))
  79. {
  80. controller.addInput(new Event(event_xml.Attribute("name").Value, event_xml.Attribute("port").Value), Convert.ToDouble(event_xml.Attribute("time").Value));
  81. }
  82. }
  83. //Execute model
  84. controller.start();
  85. controller.join();
  86. //Check output
  87. for (int slot_index = 0; slot_index < expected_result.Count; slot_index++)
  88. {
  89. List<TestEvent> slot = expected_result[slot_index];
  90. List<TestEvent> remaining_options = new List<TestEvent>(slot);
  91. List<Event> received_output = new List<Event>();
  92. while (remaining_options.Count > 0)
  93. {
  94. Event output_event = output_listener.fetch();
  95. Assert.AreNotEqual(null, output_event,
  96. string.Format("Expected results slot {0} mismatch. Expected [{1}], but got [{2}] followed by null instead.", slot_index, string.Join(", ", slot), string.Join(", ", received_output))
  97. );
  98. received_output.Add(output_event);
  99. int i = 0;
  100. foreach (TestEvent option in remaining_options)
  101. {
  102. if (option.matches(output_event))
  103. break;
  104. i++;
  105. }
  106. //Mismath?
  107. Assert.AreNotEqual(remaining_options.Count,i,
  108. string.Format("Expected results slot {0} mismatch. Expected [{1}], but got [{2}] instead.", slot_index, string.Join(", ", slot), string.Join(", ", received_output))
  109. );
  110. remaining_options.RemoveAt(i);
  111. }
  112. }
  113. //check if there are no extra events
  114. Assert.AreEqual(null, output_listener.fetch(), "More output events than expected on selected ports.");
  115. }
  116. [TearDown]
  117. public void cleanup()
  118. {
  119. if (!keep_after_test && File.Exists(this.path_generated_code))
  120. {
  121. File.Delete(this.path_generated_code);
  122. }
  123. }
  124. protected static IEnumerable GetTestCases()
  125. {
  126. foreach (string file_path in Directory.EnumerateFiles("../../../test_files"))
  127. {
  128. if (Path.GetExtension(file_path) == ".xml")
  129. yield return new TestCaseData(file_path).SetName(Path.GetFileNameWithoutExtension(file_path));
  130. }
  131. }
  132. }
  133. }