PageRenderTime 4627ms CodeModel.GetById 39ms RepoModel.GetById 4ms app.codeStats 2ms

/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.AutoTest/AppQueryRunner.cs

http://github.com/mono/monodevelop
C# | 143 lines | 92 code | 21 blank | 30 comment | 16 complexity | 4549336995c3b5b770965853204beeb6 MD5 | raw file
Possible License(s): LGPL-2.0, GPL-2.0, CC-BY-SA-3.0, MIT, LGPL-2.1, Apache-2.0, BSD-3-Clause
  1. //
  2. // AppQueryRunner.cs
  3. //
  4. // Author:
  5. // Marius Ungureanu <maungu@microsoft.com>
  6. //
  7. // Copyright (c) 2019 Microsoft Inc.
  8. //
  9. // Permission is hereby granted, free of charge, to any person obtaining a copy
  10. // of this software and associated documentation files (the "Software"), to deal
  11. // in the Software without restriction, including without limitation the rights
  12. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  13. // copies of the Software, and to permit persons to whom the Software is
  14. // furnished to do so, subject to the following conditions:
  15. //
  16. // The above copyright notice and this permission notice shall be included in
  17. // all copies or substantial portions of the Software.
  18. //
  19. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  20. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  21. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  22. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  23. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  24. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  25. // THE SOFTWARE.
  26. using System;
  27. using System.Collections.Generic;
  28. using System.Linq;
  29. using MonoDevelop.Components.AutoTest.Operations;
  30. using MonoDevelop.Components.AutoTest.Results;
  31. namespace MonoDevelop.Components.AutoTest
  32. {
  33. partial class AppQueryRunner
  34. {
  35. readonly string sourceQuery;
  36. readonly bool includeHidden;
  37. readonly CompositeFilter preFilter;
  38. readonly List<Operation> remainingOperations = new List<Operation> ();
  39. readonly List<AppResult> fullResultSet = new List<AppResult> ();
  40. public AppQueryRunner (List<Operation> operations)
  41. {
  42. includeHidden = operations.Any (x => {
  43. return x is IndexOperation || // this is to preserve backwards compat on Index operations
  44. x is PropertyOperation propertyOperation && propertyOperation.PropertyName == "Visible";
  45. });
  46. sourceQuery = GetQueryString (operations);
  47. var initialFilterOperations = operations.TakeWhile (x => x is IFilterOperation).Cast<IFilterOperation> ().ToArray ();
  48. preFilter = new CompositeFilter (initialFilterOperations);
  49. for (int i = initialFilterOperations.Length; i < operations.Count; ++i)
  50. remainingOperations.Add (operations [i]);
  51. }
  52. public (AppResult RootNode, AppResult[] AllResults) Execute ()
  53. {
  54. var rootNode = ResultSetFromWindows ();
  55. var resultSet = fullResultSet;
  56. for (int i = 0; i < remainingOperations.Count; ++i) {
  57. var subquery = remainingOperations [i];
  58. // Some subqueries can select different results
  59. resultSet = subquery.Execute (resultSet);
  60. if (resultSet == null || resultSet.Count == 0) {
  61. return (rootNode, Array.Empty<AppResult> ());
  62. }
  63. }
  64. return (rootNode, resultSet.ToArray ());
  65. }
  66. AppResult ResultSetFromWindows ()
  67. {
  68. // null for AppResult signifies root node
  69. var rootNode = new GtkWidgetResult (null) { SourceQuery = sourceQuery };
  70. // Build the tree and full result set recursively
  71. AppResult lastChild = null;
  72. ProcessGtkWindows (rootNode, ref lastChild);
  73. #if MAC
  74. ProcessNSWindows (rootNode, ref lastChild);
  75. #endif
  76. return rootNode;
  77. }
  78. void AddChild (AppResult parent, AppResult node, ref AppResult lastChild)
  79. {
  80. if (parent.FirstChild == null) {
  81. parent.FirstChild = node;
  82. } else {
  83. // Add the new node into the chain
  84. lastChild.NextSibling = node;
  85. node.PreviousSibling = lastChild;
  86. }
  87. lastChild = node;
  88. }
  89. AppResult AddToResultSet (AppResult result)
  90. {
  91. // filtered is the same as result.
  92. var filtered = preFilter.Filter (result);
  93. if (filtered != null)
  94. fullResultSet.Add (filtered);
  95. return result;
  96. }
  97. public static string GetQueryString (List<Operation> operations)
  98. {
  99. var strings = operations.Select (x => x.ToString ()).ToArray ();
  100. var operationChain = string.Join (".", strings);
  101. return string.Format ("c => c.{0};", operationChain);
  102. }
  103. class CompositeFilter : IFilterOperation
  104. {
  105. readonly IFilterOperation [] filters;
  106. public CompositeFilter (IFilterOperation[] filters)
  107. {
  108. this.filters = filters;
  109. }
  110. public AppResult Filter (AppResult result)
  111. {
  112. foreach (var subFilter in filters) {
  113. if (subFilter.Filter (result) == null) {
  114. result = null;
  115. break;
  116. }
  117. }
  118. return result;
  119. }
  120. }
  121. }
  122. }