Browse Source

Merge pull request #653 from tig/fix_568_topologicalsorterror

Fix 568 topologicalsorterror
Charlie Kindel 5 years ago
parent
commit
f85405d528
3 changed files with 50 additions and 6 deletions
  1. 6 6
      Terminal.Gui/Core/View.cs
  2. 16 0
      UICatalog/Scenarios/Generic.cs
  3. 28 0
      UnitTests/ViewTests.cs

+ 6 - 6
Terminal.Gui/Core/View.cs

@@ -1385,10 +1385,12 @@ namespace Terminal.Gui {
 				}
 			}
 
-			// if graph has edges then
 			if (edges.Any ()) {
-				// return error (graph has at least one cycle)
-				return null;
+				if (!object.ReferenceEquals(edges.First ().From, edges.First ().To)) {
+					throw new InvalidOperationException ($"TopologicalSort (for Pos/Dim) cannot find {edges.First ().From}. Did you forget to add it to {this}?");
+				} else {
+					throw new InvalidOperationException ("TopologicalSort encountered a recursive cycle in the relative Pos/Dim in the views of " + this);
+				}
 			} else {
 				// return L (a topologically sorted order)
 				return result;
@@ -1454,8 +1456,6 @@ namespace Terminal.Gui {
 			}
 
 			var ordered = TopologicalSort (nodes, edges);
-			if (ordered == null)
-				throw new Exception ("There is a recursive cycle in the relative Pos/Dim in the views of " + this);
 
 			foreach (var v in ordered) {
 				if (v.LayoutStyle == LayoutStyle.Computed)
@@ -1483,7 +1483,7 @@ namespace Terminal.Gui {
 		/// <param name="hotPos">The returning hot-key position.</param>
 		/// <param name="showHotKey">The character immediately to the right relative to the hot-key position</param>
 		/// <returns>It aims to facilitate the preparation for <see cref="TextAlignment"/> procedures.</returns>
-		public virtual ustring GetTextFromHotKey(ustring text, Rune hotKey, out int hotPos, out Rune showHotKey)
+		public virtual ustring GetTextFromHotKey (ustring text, Rune hotKey, out int hotPos, out Rune showHotKey)
 		{
 			Rune hot_key = (Rune)0;
 			int hot_pos = -1;

+ 16 - 0
UICatalog/Scenarios/Generic.cs

@@ -12,6 +12,22 @@ namespace UICatalog {
 				Y = Pos.Center (),
 				Clicked = () => MessageBox.Query (20, 7, "Hi", "Neat?", "Yes", "No")
 			});
+
+			var label = new Label ("Label: ") { 
+				X = 0,
+				Y = 0
+			};
+			Win.Add (label);
+
+			var button = new Button ("test") {
+				X = Pos.Y (label),
+				Y = Pos.Bottom (label),
+			};
+			button.Width = Dim.Width (label);
+			label.X = button.X;
+
+
+			Win.Add (button);
 		}
 	}
 }

+ 28 - 0
UnitTests/ViewTests.cs

@@ -107,5 +107,33 @@ namespace Terminal.Gui {
 
 			// TODO: Add more
 		}
+
+		[Fact]
+		public void TopologicalSort_Missing_Add ()
+		{
+			var root = new View ();
+			var sub1 = new View ();
+			root.Add (sub1);
+			var sub2 = new View ();
+			sub1.Width = Dim.Width(sub2);
+
+			Assert.Throws<InvalidOperationException> (() => root.LayoutSubviews ());
+
+			sub2.Width = Dim.Width (sub1);
+
+			Assert.Throws<InvalidOperationException> (() => root.LayoutSubviews ());
+		}
+
+		[Fact]
+		public void TopologicalSort_Recursive_Ref ()
+		{
+			var root = new View ();
+			var sub1 = new View ();
+			root.Add (sub1);
+			var sub2 = new View ();
+			root.Add (sub2);
+			sub2.Width = Dim.Width (sub2);
+			Assert.Throws<InvalidOperationException> (() => root.LayoutSubviews ());
+		}
 	}
 }