Skip to content

Commit a30f1e3

Browse files
authored
fix ContainsEmptyListOrNullTest sproadic failures (#14946)
* Update GraphNodeManagerViewExtensionTests.cs * Update GraphNodeManagerViewExtensionTests.cs * update * Update GraphNodeManagerViewExtensionTests.cs * update * Update GraphNodeManagerViewExtensionTests.cs * Update GraphNodeManagerViewExtensionTests.cs
1 parent e7a0f38 commit a30f1e3

File tree

4 files changed

+100
-58
lines changed

4 files changed

+100
-58
lines changed

src/GraphNodeManagerViewExtension/GraphNodeManagerView.xaml.cs

+56-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
1+
using System;
2+
using System.ComponentModel;
3+
using System.Linq;
14
using System.Windows;
25
using System.Windows.Controls;
6+
using System.Windows.Data;
37
using System.Windows.Input;
48
using Dynamo.GraphNodeManager.ViewModels;
59

@@ -8,7 +12,7 @@ namespace Dynamo.GraphNodeManager
812
/// <summary>
913
/// Interaction logic for GraphNodeManagerView.xaml
1014
/// </summary>
11-
public partial class GraphNodeManagerView : UserControl
15+
public partial class GraphNodeManagerView : UserControl, IDisposable
1216
{
1317
/// <summary>
1418
/// A persistent handle of the currently selected row
@@ -25,6 +29,9 @@ public partial class GraphNodeManagerView : UserControl
2529
/// </summary>
2630
private bool mouseHandled = false;
2731

32+
private GraphNodeManagerViewModel viewModel;
33+
private bool disposedValue;
34+
2835
/// <summary>
2936
/// Constructor
3037
/// </summary>
@@ -33,7 +40,38 @@ public GraphNodeManagerView(GraphNodeManagerViewModel viewModel)
3340
{
3441
InitializeComponent();
3542

43+
this.viewModel = viewModel;
3644
this.DataContext = viewModel;
45+
46+
viewModel.PropertyChanged += ViewModel_OnPropertyChanged;
47+
viewModel.RequestExportGraph += ViewModel_RequestExportGraph;
48+
}
49+
50+
private void ViewModel_RequestExportGraph(object parameter)
51+
{
52+
if (parameter == null) return;
53+
var type = parameter.ToString();
54+
var promptName = System.IO.Path.GetFileNameWithoutExtension(viewModel.CurrentWorkspace.FileName);
55+
56+
var filteredNodes = NodesInfoDataGrid.ItemsSource.Cast<GridNodeViewModel>().ToArray();
57+
58+
switch (type)
59+
{
60+
case "CSV":
61+
Utilities.Utilities.ExportToCSV(filteredNodes, promptName);
62+
break;
63+
case "JSON":
64+
Utilities.Utilities.ExportToJson(filteredNodes, promptName);
65+
break;
66+
}
67+
}
68+
69+
private void ViewModel_OnPropertyChanged(object? sender, PropertyChangedEventArgs e)
70+
{
71+
if (e.PropertyName == nameof(GraphNodeManagerViewModel.IsAnyFilterOn))
72+
{
73+
CollectionViewSource.GetDefaultView(NodesInfoDataGrid.ItemsSource).Refresh();
74+
}
3775
}
3876

3977
/// <summary>
@@ -118,5 +156,22 @@ private void ExportButton_OnClick(object sender, RoutedEventArgs e)
118156
e.Handled = true;
119157
}
120158

159+
protected virtual void Dispose(bool disposing)
160+
{
161+
if (!disposedValue)
162+
{
163+
viewModel.PropertyChanged -= ViewModel_OnPropertyChanged;
164+
viewModel.RequestExportGraph -= ViewModel_RequestExportGraph;
165+
166+
disposedValue = true;
167+
}
168+
}
169+
170+
public void Dispose()
171+
{
172+
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
173+
Dispose(disposing: true);
174+
GC.SuppressFinalize(this);
175+
}
121176
}
122177
}

src/GraphNodeManagerViewExtension/GraphNodeManagerViewExtension.cs

+6-10
Original file line numberDiff line numberDiff line change
@@ -64,14 +64,14 @@ private void MenuItemCheckHandler(object sender, RoutedEventArgs e)
6464
{
6565
AddToSidebar();
6666
}
67+
6768
/// <summary>
6869
/// Close the Extension
6970
/// </summary>
7071
/// <param name="sender"></param>
7172
/// <param name="e"></param>
7273
private void MenuItemUnCheckedHandler(object sender, RoutedEventArgs e)
7374
{
74-
this.Dispose();
7575
viewLoadedParamsReference.CloseExtensioninInSideBar(this);
7676
}
7777

@@ -80,16 +80,11 @@ private void MenuItemUnCheckedHandler(object sender, RoutedEventArgs e)
8080
/// </summary>
8181
private void AddToSidebar()
8282
{
83+
// Use late initialization for the GraphNodeManagerViewModel
84+
this.ViewModel ??= new GraphNodeManagerViewModel(this.viewLoadedParamsReference, UniqueId, MessageLogged);
8385
// initialise the ViewModel and View for the window
84-
this.ViewModel = new GraphNodeManagerViewModel(this.viewLoadedParamsReference, UniqueId, MessageLogged);
85-
this.ManagerView = new GraphNodeManagerView(this.ViewModel);
86-
87-
if (this.ManagerView == null)
88-
{
89-
return;
90-
}
91-
92-
this.ViewModel.GraphNodeManagerView = this.ManagerView;
86+
// Use late initialization for the GraphNodeManagerView
87+
this.ManagerView ??= new GraphNodeManagerView(this.ViewModel);
9388

9489
this.viewLoadedParamsReference?.AddToExtensionsSideBar(this, this.ManagerView);
9590
}
@@ -114,6 +109,7 @@ public override void Shutdown()
114109
/// </summary>
115110
public override void Dispose()
116111
{
112+
this.ManagerView?.Dispose();
117113
this.ViewModel?.Dispose();
118114
this.ManagerView = null;
119115
this.ViewModel = null;

src/GraphNodeManagerViewExtension/GraphNodeManagerViewModel.cs

+5-27
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ public class GraphNodeManagerViewModel : NotificationObject, IDisposable
4444
private bool isAnyFilterOn = false;
4545
private Action<Logging.ILogMessage> logMessage;
4646

47-
private HomeWorkspaceModel CurrentWorkspace
47+
internal HomeWorkspaceModel CurrentWorkspace
4848
{
4949
get
5050
{
@@ -112,8 +112,6 @@ public string SearchText
112112
}
113113
}
114114

115-
public GraphNodeManagerView GraphNodeManagerView;
116-
117115
public string searchBoxPrompt = "Search..";
118116
/// <summary>
119117
/// Search Box Prompt binding
@@ -318,34 +316,16 @@ internal void ClearAllFilters(object obj)
318316
/// Export the current graph to CSV or JSON
319317
/// </summary>
320318
/// <param name="parameter"></param>
321-
/// <exception cref="NotImplementedException"></exception>
322319
internal void ExportGraph(object parameter)
323320
{
324-
if (parameter == null) return;
325-
var type = parameter.ToString();
326-
var promptName = System.IO.Path.GetFileNameWithoutExtension(currentWorkspace.FileName);
327-
328-
var filteredNodes = FilteredNodesArray();
329-
330-
switch (type)
331-
{
332-
case "CSV":
333-
Utilities.Utilities.ExportToCSV(filteredNodes, promptName);
334-
break;
335-
case "JSON":
336-
Utilities.Utilities.ExportToJson(filteredNodes, promptName);
337-
break;
338-
}
321+
RequestExportGraph?.Invoke(parameter);
339322
}
340323

341324
/// <summary>
342-
/// Helper method to return an Array of the currently active Nodes
325+
/// This action is called on the export graph command.
343326
/// </summary>
344-
/// <returns></returns>
345-
private GridNodeViewModel [] FilteredNodesArray()
346-
{
347-
return GraphNodeManagerView.NodesInfoDataGrid.ItemsSource.Cast<GridNodeViewModel>().ToArray();
348-
}
327+
/// <param name="parameter"></param>
328+
internal event Action<object> RequestExportGraph;
349329

350330
/// <summary>
351331
/// On changing a condition that affects the filter
@@ -354,7 +334,6 @@ internal void NodesCollectionFilter_Changed()
354334
{
355335
// Refresh the view to apply filters.
356336
RaisePropertyChanged(nameof(IsAnyFilterOn));
357-
CollectionViewSource.GetDefaultView(GraphNodeManagerView.NodesInfoDataGrid.ItemsSource).Refresh();
358337
}
359338

360339
/// <summary>
@@ -572,7 +551,6 @@ public void Dispose()
572551
viewLoadedParams.CurrentWorkspaceChanged -= OnCurrentWorkspaceChanged;
573552
viewLoadedParams.CurrentWorkspaceCleared -= OnCurrentWorkspaceCleared;
574553
NodesCollection.Filter -= NodesCollectionViewSource_Filter;
575-
GraphNodeManagerView = null;
576554
}
577555

578556
/// <summary>

test/DynamoCoreWpfTests/ViewExtensions/GraphNodeManagerViewExtensionTests.cs

+33-20
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,19 @@ namespace DynamoCoreWpfTests
2222
{
2323
public class GraphNodeManagerViewExtensionTests : DynamoTestUIBase
2424
{
25+
private bool oldEnablePersistance = false;
26+
2527
private string PackagesDirectory { get { return Path.Combine(GetTestDirectory(this.ExecutingDirectory), "pkgs"); } }
2628

29+
protected override void GetLibrariesToPreload(List<string> libraries)
30+
{
31+
libraries.Add("VMDataBridge.dll");
32+
libraries.Add("DesignScriptBuiltin.dll");
33+
libraries.Add("DSCoreNodes.dll");
34+
base.GetLibrariesToPreload(libraries);
35+
}
36+
37+
2738
protected override DynamoModel.IStartConfiguration CreateStartConfiguration(IPathResolver pathResolver)
2839
{
2940
string settingDirectory = Path.Combine(GetTestDirectory(ExecutingDirectory), "settings");
@@ -53,13 +64,26 @@ private void LoadExtension(GraphNodeManagerViewExtension v)
5364
#endregion
5465

5566
#region Tests
67+
68+
[SetUp]
69+
public void Setup()
70+
{
71+
oldEnablePersistance = ViewModel.PreferenceSettings.EnablePersistExtensions;
72+
ViewModel.PreferenceSettings.EnablePersistExtensions = false;
73+
}
74+
75+
[TearDown]
76+
public void Teardown()
77+
{
78+
ViewModel.PreferenceSettings.EnablePersistExtensions = oldEnablePersistance;
79+
}
80+
5681
/// <summary>
5782
/// Test if the Extension loads correctly
5883
/// </summary>
5984
[Test]
6085
public void ViewExtensionOpenTest()
6186
{
62-
RaiseLoadedEvent(this.View);
6387
var extensionManager = View.viewExtensionManager;
6488
var viewExtension = extensionManager.ViewExtensions
6589
.FirstOrDefault(x => x as GraphNodeManagerViewExtension != null)
@@ -82,7 +106,6 @@ public void ViewExtensionOpenTest()
82106
[Test]
83107
public void CorrectNumberNodeItemsTest()
84108
{
85-
RaiseLoadedEvent(this.View);
86109
var extensionManager = View.viewExtensionManager;
87110
var viewExt = extensionManager.ViewExtensions
88111
.FirstOrDefault(x => x as GraphNodeManagerViewExtension != null)
@@ -102,7 +125,6 @@ public void CorrectNumberNodeItemsTest()
102125
Open(@"pkgs\Dynamo Samples\extra\ZoomNodeColorStates.dyn");
103126

104127
hwm = this.ViewModel.CurrentSpace as HomeWorkspaceModel;
105-
Utility.DispatcherUtil.DoEvents();
106128

107129
int loadedGraphNodes = hwm.Nodes.Count();
108130
int loadedExtensionNodes = dataGridItems.Count;
@@ -121,13 +143,13 @@ public void CorrectNumberNodeItemsTest()
121143
Assert.AreEqual(loadedGraphNodes, loadedExtensionNodes);
122144
Assert.AreEqual(deleteGraphNodes, deleteExtensionNodes);
123145
}
146+
124147
/// <summary>
125148
/// Test if using the IsFrozen filter yields correct results
126149
/// </summary>
127150
[Test]
128151
public void FilterFrozenItemsTest()
129152
{
130-
RaiseLoadedEvent(this.View);
131153
var extensionManager = View.viewExtensionManager;
132154
var viewExt = extensionManager.ViewExtensions
133155
.FirstOrDefault(x => x as GraphNodeManagerViewExtension != null)
@@ -137,7 +159,6 @@ public void FilterFrozenItemsTest()
137159
LoadExtension(viewExt);
138160

139161
Open(@"pkgs\Dynamo Samples\extra\ZoomNodeColorStates.dyn");
140-
Utility.DispatcherUtil.DoEvents();
141162

142163
// Get number of frozen Nodes in the graph
143164
var hwm = this.ViewModel.CurrentSpace as HomeWorkspaceModel;
@@ -174,30 +195,25 @@ public void FilterFrozenItemsTest()
174195
[Test]
175196
public void ContainsEmptyListOrNullTest()
176197
{
177-
RaiseLoadedEvent(this.View);
178198
var extensionManager = View.viewExtensionManager;
179199
var viewExt = extensionManager.ViewExtensions
180200
.FirstOrDefault(x => x as GraphNodeManagerViewExtension != null)
181201
as GraphNodeManagerViewExtension;
182202

183-
var hwm = this.ViewModel.CurrentSpace as HomeWorkspaceModel;
184-
185-
// Arrange
186203
LoadExtension(viewExt);
187204

188-
var view = viewExt.ManagerView;
189-
190-
Open(@"pkgs\Dynamo Samples\extra\GraphNodeManagerTestGraph_NullsEmptyLists.dyn");
191-
192-
hwm = this.ViewModel.CurrentSpace as HomeWorkspaceModel;
193-
hwm.Run();
205+
OpenAndRun(@"pkgs\Dynamo Samples\extra\GraphNodeManagerTestGraph_NullsEmptyLists.dyn");
194206

195207
Utility.DispatcherUtil.DoEvents();
196208

209+
var view = viewExt.ManagerView;
210+
197211
var images = WpfUtilities.ChildrenOfType<Image>(view.NodesInfoDataGrid);
198-
212+
199213
int nullNodesImageCount = GetImageCount(images, "Null");
200-
int emptyListNodesImageCount = GetImageCount(images, "EmptyList");
214+
int emptyListNodesImageCount = GetImageCount(images, "EmptyList");
215+
216+
var hwm = this.ViewModel.CurrentSpace;
201217

202218
int nullNodesCount = hwm.Nodes.Count(ContainsAnyNulls);
203219
int emptyListNodesCount = hwm.Nodes.Count(ContainsAnyEmptyLists);
@@ -214,7 +230,6 @@ public void ContainsEmptyListOrNullTest()
214230
[Test]
215231
public void ViewExtensionOpensWithDynamoWhenRememberedTest()
216232
{
217-
RaiseLoadedEvent(this.View);
218233
ViewModel.PreferenceSettings.EnablePersistExtensions = true;
219234

220235
//assert that option is enabled
@@ -247,7 +262,6 @@ public void ViewExtensionOpensWithDynamoWhenRememberedTest()
247262
[Test]
248263
public void ViewExtensionDoesNotOpensWithDynamoWhenClosedTest()
249264
{
250-
RaiseLoadedEvent(this.View);
251265
ViewModel.PreferenceSettings.EnablePersistExtensions = true;
252266

253267
//assert that option is enabled
@@ -284,7 +298,6 @@ public void ViewExtensionDoesNotOpensWithDynamoWhenClosedTest()
284298
[Test]
285299
public void ViewExtensionDoesNotOpenWhenNotRememberedTest()
286300
{
287-
RaiseLoadedEvent(this.View);
288301
ViewModel.PreferenceSettings.EnablePersistExtensions = false;
289302

290303
//assert that option is disabled

0 commit comments

Comments
 (0)