PageRenderTime 2592ms CodeModel.GetById 7ms RepoModel.GetById 0ms app.codeStats 0ms

/src/Atha.Clients.Wpf/ViewModels/MainViewModel.cs

#
C# | 398 lines | 249 code | 66 blank | 83 comment | 22 complexity | 223e15e5270b1d7515374470aced20d2 MD5 | raw file
Possible License(s): BSD-3-Clause, GPL-2.0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Collections.ObjectModel;
  4. using System.Linq;
  5. using System.Reactive.Linq;
  6. namespace Atha.Clients.ViewModels
  7. {
  8. public class MainViewModel : NotificationViewModelBase, IDisposable
  9. {
  10. private const string razor = "Razor";
  11. private const string ironPython = "IronPython";
  12. private const string ironRuby = "IronRuby";
  13. private const string powerShell = "PowerShell";
  14. private readonly Func<ITestScriptsReader> _testScriptsReaderFactory;
  15. private readonly Func<string, ITestScriptReader> _testScriptReaderFactory;
  16. private readonly Func<ITestScriptWriter> _testScriptWriterFactory;
  17. private readonly IClientTestRunner _clientTestRunner;
  18. private readonly Func<string> _getExistingTestPath;
  19. private readonly Func<string> _getNewTestSaveAsPath;
  20. private readonly IEnumerable<IDisposable> _observables;
  21. private ITestScript _selectedTestScript;
  22. private string _savedFilePath;
  23. private bool _isTutorialVisible;
  24. private string _testScript;
  25. private CommandViewModel _selectedLanguage;
  26. /// <summary>
  27. /// Initializes a new instance of the <see cref="MainViewModel"/> class.
  28. /// </summary>
  29. /// <param name="testScriptsReaderFactory">The test scripts reader factory.</param>
  30. /// <param name="testScriptReaderFactory">The test script reader factory.</param>
  31. /// <param name="testScriptWriterFactory">The test script writer factory.</param>
  32. /// <param name="clientTestRunner">The client test runner.</param>
  33. /// <param name="onNotify">The on notify.</param>
  34. /// <param name="getExistingTestPath">The get existing test path.</param>
  35. /// <param name="getNewTestSaveAsPath">The get new test save as path.</param>
  36. public MainViewModel(
  37. Func<ITestScriptsReader> testScriptsReaderFactory,
  38. Func<string, ITestScriptReader> testScriptReaderFactory,
  39. Func<ITestScriptWriter> testScriptWriterFactory,
  40. IClientTestRunner clientTestRunner,
  41. Action<NotifyViewModel> onNotify,
  42. Func<string> getExistingTestPath,
  43. Func<string> getNewTestSaveAsPath)
  44. : base(onNotify)
  45. {
  46. // TODO: Arg validations
  47. this._testScriptsReaderFactory = testScriptsReaderFactory;
  48. this._testScriptReaderFactory = testScriptReaderFactory;
  49. this._testScriptWriterFactory = testScriptWriterFactory;
  50. this._clientTestRunner = clientTestRunner;
  51. this._getExistingTestPath = getExistingTestPath;
  52. this._getNewTestSaveAsPath = getNewTestSaveAsPath;
  53. this.TestScripts = new ObservableCollection<ITestScript>();
  54. this.TestResults = new ObservableCollection<TestResultViewModel>();
  55. this.LearnAtha = new CommandViewModel("Learn Atha", @"Images\1322868576_school.png", true, this.OnLearnAtha);
  56. this.OpenTests = new CommandViewModel("Open Tests", @"Images\fileopen.png", true, this.OnOpenTests);
  57. this.OpenTest = new CommandViewModel("Open Script", @"Images\fileopen.png", true, this.OnOpenTest);
  58. this.SaveTest = new CommandViewModel("Save Script", @"Images\1321920923_3floppy_unmount.png", false, this.OnSaveTest);
  59. this.ExecuteTest = new CommandViewModel("Execute Script", @"Images\1321920940_application-x-executable-script.png", false, this.OnExecuteTest);
  60. var languages = new[]
  61. {
  62. new CommandViewModel(ironPython, @"Images\1319526175_application-x-python.png"),
  63. new CommandViewModel(ironRuby, @"Images\1319526162_application-x-ruby.png"),
  64. new CommandViewModel(powerShell, @"Images\Windows_PowerShell_icon.png"),
  65. new CommandViewModel(razor, @"Images\razor-icon.png")
  66. };
  67. this.Languages = languages;
  68. this.SelectedLanguage = languages[0];
  69. var observables = new List<IDisposable>();
  70. foreach (var lang in languages)
  71. {
  72. observables.Add(Observable
  73. .FromEventPattern<ViewModelEventArgs<CommandViewModel>>(lang, "Clicked")
  74. .Subscribe(e => this.SelectedLanguage = e.EventArgs.ViewModel));
  75. }
  76. this._observables = observables;
  77. }
  78. /// <summary>
  79. /// Gets the test scripts.
  80. /// </summary>
  81. public ObservableCollection<ITestScript> TestScripts { get; private set; }
  82. /// <summary>
  83. /// Gets the test results.
  84. /// </summary>
  85. public ObservableCollection<TestResultViewModel> TestResults { get; private set; }
  86. /// <summary>
  87. /// Gets the learn atha.
  88. /// </summary>
  89. public CommandViewModel LearnAtha { get; private set; }
  90. /// <summary>
  91. /// Gets the open tests.
  92. /// </summary>
  93. public CommandViewModel OpenTests { get; private set; }
  94. /// <summary>
  95. /// Gets the open test.
  96. /// </summary>
  97. public CommandViewModel OpenTest { get; private set; }
  98. /// <summary>
  99. /// Gets the save test.
  100. /// </summary>
  101. public CommandViewModel SaveTest { get; private set; }
  102. /// <summary>
  103. /// Gets the execute test.
  104. /// </summary>
  105. public CommandViewModel ExecuteTest { get; private set; }
  106. /// <summary>
  107. /// Gets the languages.
  108. /// </summary>
  109. public CommandViewModel[] Languages { get; private set; }
  110. /// <summary>
  111. /// Gets or sets the selected test script.
  112. /// </summary>
  113. public ITestScript SelectedTestScript
  114. {
  115. get
  116. {
  117. return this._selectedTestScript;
  118. }
  119. set
  120. {
  121. if (value != this._selectedTestScript)
  122. {
  123. this.OnPropertyChanging(() => this.SelectedTestScript);
  124. this._selectedTestScript = value;
  125. this.OnPropertyChanged(() => this.SelectedTestScript);
  126. if (this.SelectedTestScript != null)
  127. {
  128. this.SavedFilePath = this.SelectedTestScript.Title;
  129. this.SelectedLanguage = this.Languages.First(lang => lang.Text == this.SelectedTestScript.Language);
  130. this.TestScript = this.SelectedTestScript.Content;
  131. }
  132. }
  133. }
  134. }
  135. /// <summary>
  136. /// Gets or sets the selected language.
  137. /// </summary>
  138. /// <value>
  139. /// The selected language.
  140. /// </value>
  141. public CommandViewModel SelectedLanguage
  142. {
  143. get
  144. {
  145. return this._selectedLanguage;
  146. }
  147. set
  148. {
  149. if (value != this._selectedLanguage)
  150. {
  151. this.OnPropertyChanging(() => this.SelectedLanguage);
  152. this._selectedLanguage = value;
  153. this.OnPropertyChanged(() => this.SelectedLanguage);
  154. }
  155. }
  156. }
  157. /// <summary>
  158. /// Gets or sets a value indicating whether this instance is tutorial visible.
  159. /// </summary>
  160. /// <value>
  161. /// <c>true</c> if this instance is tutorial visible; otherwise, <c>false</c>.
  162. /// </value>
  163. public bool IsTutorialVisible
  164. {
  165. get
  166. {
  167. return this._isTutorialVisible;
  168. }
  169. set
  170. {
  171. if (value != this._isTutorialVisible)
  172. {
  173. this.OnPropertyChanging(() => this.IsTutorialVisible);
  174. this.OnPropertyChanging(() => this.IsTestScriptVisible);
  175. this._isTutorialVisible = value;
  176. this.OnPropertyChanged(() => this.IsTutorialVisible);
  177. this.OnPropertyChanged(() => this.IsTestScriptVisible);
  178. }
  179. if (value)
  180. {
  181. this.ExecuteTest.ClickCommand.IsExecutable = false;
  182. this.SaveTest.ClickCommand.IsExecutable = false;
  183. }
  184. else
  185. {
  186. this.SaveTest.ClickCommand.IsExecutable = !string.IsNullOrWhiteSpace(this.TestScript);
  187. this.ExecuteTest.ClickCommand.IsExecutable = !string.IsNullOrWhiteSpace(this.TestScript);
  188. }
  189. }
  190. }
  191. /// <summary>
  192. /// Gets a value indicating whether this instance is test script visible.
  193. /// </summary>
  194. /// <value>
  195. /// <c>true</c> if this instance is test script visible; otherwise, <c>false</c>.
  196. /// </value>
  197. public bool IsTestScriptVisible
  198. {
  199. get
  200. {
  201. return !this.IsTutorialVisible;
  202. }
  203. }
  204. /// <summary>
  205. /// Gets or sets the saved file path.
  206. /// </summary>
  207. /// <value>
  208. /// The saved file path.
  209. /// </value>
  210. public string SavedFilePath
  211. {
  212. get
  213. {
  214. return this._savedFilePath;
  215. }
  216. set
  217. {
  218. if (value != this._savedFilePath)
  219. {
  220. this.OnPropertyChanging(() => this.SavedFilePath);
  221. this._savedFilePath = value;
  222. this.OnPropertyChanged(() => this.SavedFilePath);
  223. }
  224. }
  225. }
  226. /// <summary>
  227. /// Gets or sets the test script.
  228. /// </summary>
  229. /// <value>
  230. /// The test script.
  231. /// </value>
  232. public string TestScript
  233. {
  234. get
  235. {
  236. return this._testScript;
  237. }
  238. set
  239. {
  240. if (value != this._testScript)
  241. {
  242. this.OnPropertyChanging(() => this.TestScript);
  243. this._testScript = value;
  244. this.OnPropertyChanged(() => this.TestScript);
  245. this.SaveTest.ClickCommand.IsExecutable = !string.IsNullOrWhiteSpace(this.TestScript);
  246. this.ExecuteTest.ClickCommand.IsExecutable = !string.IsNullOrWhiteSpace(this.TestScript);
  247. }
  248. }
  249. }
  250. /// <summary>
  251. /// Called when [learn atha].
  252. /// </summary>
  253. private void OnLearnAtha()
  254. {
  255. this.IsTutorialVisible = !this.IsTutorialVisible;
  256. }
  257. /// <summary>
  258. /// Called when [execute test].
  259. /// </summary>
  260. private void OnExecuteTest()
  261. {
  262. if (!string.IsNullOrWhiteSpace(this.TestScript))
  263. {
  264. this.TestResults.Clear();
  265. this._clientTestRunner.ExecuteTest(this.SelectedLanguage.Text, this.TestScript, this.TestResults);
  266. }
  267. }
  268. /// <summary>
  269. /// Called when [save test].
  270. /// </summary>
  271. private void OnSaveTest()
  272. {
  273. if (string.IsNullOrWhiteSpace(this.SavedFilePath))
  274. {
  275. this.SavedFilePath = this._getNewTestSaveAsPath();
  276. }
  277. if (string.IsNullOrWhiteSpace(this.SavedFilePath)) return;
  278. var scriptWriter = this._testScriptWriterFactory();
  279. var testScript = new BasicTestScript(this.SelectedLanguage.Text, this.SavedFilePath, this.TestScript);
  280. scriptWriter.SaveScript(testScript);
  281. }
  282. /// <summary>
  283. /// Called when [open tests].
  284. /// </summary>
  285. private void OnOpenTests()
  286. {
  287. this.IsTutorialVisible = false;
  288. this.TestScripts.Clear();
  289. var repository = this._testScriptsReaderFactory();
  290. repository.GetScripts(
  291. testScripts =>
  292. {
  293. foreach (var testScript in testScripts)
  294. this.TestScripts.Add(testScript);
  295. });
  296. }
  297. /// <summary>
  298. /// Called when [open test].
  299. /// </summary>
  300. private void OnOpenTest()
  301. {
  302. this.IsTutorialVisible = false;
  303. this.SavedFilePath = this._getExistingTestPath();
  304. if (string.IsNullOrWhiteSpace(this.SavedFilePath)) return;
  305. var repository = this._testScriptReaderFactory(this.SavedFilePath);
  306. repository.GetScript(
  307. testScript =>
  308. {
  309. this.SelectedLanguage = this.Languages.First(lang => lang.Text == testScript.Language);
  310. this.TestScript = testScript.Content;
  311. });
  312. }
  313. public void Dispose()
  314. {
  315. this.Dispose(true);
  316. GC.SuppressFinalize(this);
  317. }
  318. private void Dispose(bool disposing)
  319. {
  320. if (disposing)
  321. {
  322. if (this._observables != null)
  323. foreach (var observable in this._observables)
  324. observable.Dispose();
  325. }
  326. }
  327. ~MainViewModel()
  328. {
  329. this.Dispose(false);
  330. }
  331. }
  332. }