Implementing a navigation menu system for admin pages.

--HG--
extra : convert_revision : svn%3A5ff7c347-ad56-4c35-b696-ccb81de16e03/trunk%4039716
This commit is contained in:
loudej
2009-11-11 23:36:29 +00:00
parent 3a951297fa
commit d5a78a53ed
31 changed files with 754 additions and 41 deletions

View File

@@ -138,6 +138,9 @@
<Compile Include="Records\Foo.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Stubs\StubHttpContext.cs" />
<Compile Include="UI\Navigation\MenuItemComparerTests.cs" />
<Compile Include="UI\Navigation\NavigationManagerTests.cs" />
<Compile Include="UI\Navigation\PositionComparerTests.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Orchard\Orchard.csproj">

View File

@@ -0,0 +1,87 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Routing;
using NUnit.Framework;
using Orchard.UI.Navigation;
namespace Orchard.Tests.UI.Navigation {
[TestFixture]
public class MenuItemComparerTests {
[Test]
public void TextShouldCauseDifferenceAndNullRouteValuesAreEqual() {
var item1 = new MenuItem { Text = "hello" };
var item2 = new MenuItem { Text = "hello" };
var item3 = new MenuItem { Text = "hello3" };
AssertSameSameDifferent(item1, item2, item3);
}
[Test]
public void NullRouteValuesShouldNotEqualEmptyRouteValues() {
var item1 = new MenuItem { Text = "hello" };
var item2 = new MenuItem { Text = "hello" };
var item3 = new MenuItem { Text = "hello", RouteValues = new RouteValueDictionary() };
var item4 = new MenuItem { Text = "hello", RouteValues = new RouteValueDictionary() };
AssertSameSameDifferent(item1, item2, item3);
AssertSameSameDifferent(item3, item4, item1);
}
[Test]
public void AdditionalPropertiesShouldMismatch() {
var item1 = new MenuItem { Text = "hello", RouteValues = new RouteValueDictionary(new { one = 1 }) };
var item2 = new MenuItem { Text = "hello", RouteValues = new RouteValueDictionary(new { one = 1 }) };
var item3 = new MenuItem { Text = "hello", RouteValues = new RouteValueDictionary(new { one = 1, two = 2 }) };
AssertSameSameDifferent(item1, item2, item3);
}
[Test]
public void ValueTypeShouldMismatch() {
var item1 = new MenuItem { Text = "hello", RouteValues = new RouteValueDictionary(new { one = 1 }) };
var item2 = new MenuItem { Text = "hello", RouteValues = new RouteValueDictionary(new { one = 1 }) };
var item3 = new MenuItem { Text = "hello", RouteValues = new RouteValueDictionary(new { one = "1" }) };
AssertSameSameDifferent(item1, item2, item3);
}
[Test]
public void ValuesShouldMismatch() {
var item1 = new MenuItem { Text = "hello", RouteValues = new RouteValueDictionary(new { one = "1", two = "2" }) };
var item2 = new MenuItem { Text = "hello", RouteValues = new RouteValueDictionary(new { one = "1", two = "2" }) };
var item3 = new MenuItem { Text = "hello", RouteValues = new RouteValueDictionary(new { one = "1", two = "3" }) };
AssertSameSameDifferent(item1, item2, item3);
}
[Test]
public void PositionAndChildrenDontMatter() {
var item1 = new MenuItem { Text = "hello", RouteValues = new RouteValueDictionary(new { one = "1", two = "2" }) };
var item2 = new MenuItem { Text = "hello", RouteValues = new RouteValueDictionary(new { one = "1", two = "2" }), Position = "4.0" };
var item3 = new MenuItem { Text = "hello", RouteValues = new RouteValueDictionary(new { one = "1", two = "2" }), Contained = new[] { new MenuItem() } };
AssertSameSameSame(item1, item2, item3);
}
private static void AssertSameSameDifferent(MenuItem item1, MenuItem item2, MenuItem item3) {
var comparer = new MenuItemComparer();
Assert.That(comparer.Equals(item1, item2), Is.True);
Assert.That(comparer.Equals(item1, item3), Is.False);
Assert.That(comparer.Equals(item2, item3), Is.False);
Assert.That(comparer.GetHashCode(item1), Is.EqualTo(comparer.GetHashCode(item2)));
// - hash inequality isn't really guaranteed, now that you mention it
//Assert.That(comparer.GetHashCode(item1), Is.Not.EqualTo(comparer.GetHashCode(item3)));
//Assert.That(comparer.GetHashCode(item2), Is.Not.EqualTo(comparer.GetHashCode(item3)));
}
private static void AssertSameSameSame(MenuItem item1, MenuItem item2, MenuItem item3) {
var comparer = new MenuItemComparer();
Assert.That(comparer.Equals(item1, item2), Is.True);
Assert.That(comparer.Equals(item1, item3), Is.True);
Assert.That(comparer.Equals(item2, item3), Is.True);
Assert.That(comparer.GetHashCode(item1), Is.EqualTo(comparer.GetHashCode(item2)));
Assert.That(comparer.GetHashCode(item1), Is.EqualTo(comparer.GetHashCode(item3)));
Assert.That(comparer.GetHashCode(item2), Is.EqualTo(comparer.GetHashCode(item3)));
}
}
}

View File

@@ -0,0 +1,80 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NUnit.Framework;
using Orchard.UI.Navigation;
namespace Orchard.Tests.UI.Navigation {
[TestFixture]
public class NavigationManagerTests {
[Test]
public void EmptyMenuIfNameDoesntMatch() {
var manager = new NavigationManager(new[] { new StubProvider() });
var menuItems = manager.BuildMenu("primary");
Assert.That(menuItems.Count(), Is.EqualTo(0));
}
[Test]
public void NavigationManagerShouldUseProvidersToBuildNamedMenu() {
var manager = new NavigationManager(new[] { new StubProvider() });
var menuItems = manager.BuildMenu("admin");
Assert.That(menuItems.Count(), Is.EqualTo(2));
Assert.That(menuItems.First(), Has.Property("Text").EqualTo("Foo"));
Assert.That(menuItems.Last(), Has.Property("Text").EqualTo("Bar"));
Assert.That(menuItems.Last().Contained.Count(), Is.EqualTo(1));
Assert.That(menuItems.Last().Contained.Single().Text, Is.EqualTo("Frap"));
}
[Test]
public void NavigationManagerShouldMergeAndOrderNavigation() {
var manager = new NavigationManager(new INavigationProvider[] { new StubProvider(), new Stub2Provider() });
var menuItems = manager.BuildMenu("admin");
Assert.That(menuItems.Count(), Is.EqualTo(3));
var item1 = menuItems.First();
var item2 = menuItems.Skip(1).First();
var item3 = menuItems.Skip(2).First();
Assert.That(item1.Text, Is.EqualTo("Foo"));
Assert.That(item1.Position, Is.EqualTo("1.0"));
Assert.That(item2.Text, Is.EqualTo("Bar"));
Assert.That(item2.Position, Is.EqualTo("2.0"));
Assert.That(item3.Text, Is.EqualTo("Frap"));
Assert.That(item3.Position, Is.EqualTo("3.0"));
Assert.That(item2.Contained.Count(), Is.EqualTo(2));
var subitem1 = item2.Contained.First();
var subitem2 = item2.Contained.Last();
Assert.That(subitem1.Text, Is.EqualTo("Quad"));
Assert.That(subitem1.Position, Is.EqualTo("1.a"));
Assert.That(subitem2.Text, Is.EqualTo("Frap"));
Assert.That(subitem2.Position, Is.EqualTo("1.b"));
}
public class StubProvider : INavigationProvider {
public string MenuName { get { return "admin"; } }
public void GetNavigation(NavigationBuilder builder) {
builder
.Add("Foo", "1.0")
.Add("Bar", "2.0", x => x.Add("Frap", "1.b"));
}
}
public class Stub2Provider : INavigationProvider {
public string MenuName { get { return "admin"; } }
public void GetNavigation(NavigationBuilder builder) {
builder
.Add("Frap", "3.0")
.Add("Bar", "4.0", x => x.Add("Quad", "1.a"));
}
}
}
}

View File

@@ -0,0 +1,141 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NUnit.Framework;
using Orchard.UI.Navigation;
namespace Orchard.Tests.UI.Navigation {
[TestFixture]
public class PositionComparerTests {
private IComparer<string> _comparer;
[SetUp]
public void Init() {
_comparer = new PositionComparer();
}
[Test]
public void LessThanAndGreaterThanShouldBeBelowAndAboveZero() {
var lessThan = StringComparer.InvariantCultureIgnoreCase.Compare("alpha", "beta");
var greaterThan = StringComparer.InvariantCultureIgnoreCase.Compare("gamma", "delta");
Assert.That(lessThan, Is.LessThan(0));
Assert.That(greaterThan, Is.GreaterThan(0));
}
[Test]
public void NullIsLessThanEmptyAndEmptyIsLessThanNonEmpty() {
Assert.That(_comparer.Compare(null, ""), Is.LessThan(0));
Assert.That(_comparer.Compare("", "5"), Is.LessThan(0));
Assert.That(_comparer.Compare(null, "5"), Is.LessThan(0));
Assert.That(_comparer.Compare("", null), Is.GreaterThan(0));
Assert.That(_comparer.Compare("5", ""), Is.GreaterThan(0));
Assert.That(_comparer.Compare("5", null), Is.GreaterThan(0));
Assert.That(_comparer.Compare(null, null), Is.EqualTo(0));
Assert.That(_comparer.Compare("", ""), Is.EqualTo(0));
}
[Test]
public void NumericValuesShouldCompareNumerically() {
AssertLess("3", "5");
AssertMore("8", "5");
AssertSame("5", "5");
AssertMore("100", "5");
AssertSame("007", "7");
}
[Test]
public void DotsSplitParts() {
AssertLess("0500.3", "0500.5");
AssertMore("0500.8", "0500.5");
AssertSame("0500.5", "0500.5");
AssertMore("0500.100", "0500.5");
AssertSame("0500.007", "0500.7");
AssertLess("0500.3.0300", "0500.5.0300");
AssertMore("0500.8.0300", "0500.5.0300");
AssertSame("0500.5.0300", "0500.5.0300");
AssertMore("0500.100.0300", "0500.5.0300");
AssertSame("0500.007.0300", "0500.7.0300");
}
[Test]
public void NumericValuesShouldComeBeforeNonNumeric() {
AssertLess("5", "x");
AssertLess("50", "50a");
AssertLess("1.50", "1.50a");
}
[Test]
public void NonNumericValuesCompareOrdinallyAndIgnoreCase() {
AssertSame("x", "X");
AssertLess("rt675x", "rt685x");
AssertMore("ru675x", "rt675x");
AssertLess("rt675x", "rt675y");
AssertSame("1.x.5", "1.X.5");
AssertLess("1.rt675x.5", "1.rt685x.5");
AssertMore("1.ru675x.5", "1.rt675x.5");
AssertLess("1.rt675x.5", "1.rt675y.5");
AssertSame("x.5", "X.5");
AssertLess("rt675x.5", "rt685x.5");
AssertMore("ru675x.5", "rt675x.5");
AssertLess("rt675x.5", "rt675y.5");
AssertSame("1.x", "1.X");
AssertLess("1.rt675x", "1.rt685x");
AssertMore("1.ru675x", "1.rt675x");
AssertLess("1.rt675x", "1.rt675y");
}
[Test]
public void LongerNonNumericShouldComeLater() {
AssertLess("rt675x", "rt675xx");
}
[Test]
public void EmptyBitsAreSafeAndShouldComeFirst() {
AssertSame("1.2.3", "1.2.3");
AssertSame(".1.2.3.", ".1.2.3.");
AssertSame(".1..3.", ".1..3.");
AssertLess("1..3", "1.2.3");
AssertLess(".1..3.", ".1.2.3.");
AssertSame("a.b.c", "a.b.c");
AssertSame(".a.b.c.", ".a.b.c.");
AssertSame(".a..c.", ".a..c.");
AssertLess("a..c", "a.b.c");
AssertLess(".a..c.", ".a.b.c.");
}
[Test]
public void AdditionalNonEmptySegmentsShouldComeLater() {
AssertLess("1.2", "1.2.3");
AssertSame("1.2", "1.2.");
AssertLess("a.b", "a.b.c");
AssertSame("a.b", "a.b.");
}
void AssertLess(string x, string y) {
Assert.That(_comparer.Compare(x, y), Is.LessThan(0));
Assert.That(_comparer.Compare(y, x), Is.GreaterThan(0));
}
void AssertMore(string x, string y) {
Assert.That(_comparer.Compare(x, y), Is.GreaterThan(0));
Assert.That(_comparer.Compare(y, x), Is.LessThan(0));
}
void AssertSame(string x, string y) {
Assert.That(_comparer.Compare(x, y), Is.EqualTo(0));
Assert.That(_comparer.Compare(y, x), Is.EqualTo(0));
}
}
}