Skip to content

Commit dcfbb6e

Browse files
committed
[Tests] Add tests for ui components
1 parent 9c6c141 commit dcfbb6e

16 files changed

Lines changed: 731 additions & 0 deletions

Directory.Packages.props

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
<PackageVersion Include="Nice3point.Revit.Api.RevitAPIUI" Version="$(RevitVersion).*-*" Condition="$(RevitVersion) != ''"/>
1515
<PackageVersion Include="Nice3point.Revit.Api.UIFramework" Version="$(RevitVersion).*-*" Condition="$(RevitVersion) != ''"/>
1616
<PackageVersion Include="Nice3point.Revit.Api.UIFrameworkServices" Version="$(RevitVersion).*-*" Condition="$(RevitVersion) != ''"/>
17+
<PackageVersion Include="Nice3point.Revit.Extensions" Version="$(RevitVersion).*-*" Condition="$(RevitVersion) != ''"/>
1718
<PackageVersion Include="Nice3point.TUnit.Revit" Version="$(RevitVersion).*-*" Condition="$(RevitVersion) != ''"/>
1819

1920
<!-- Build Automation -->

Nice3point.Revit.Toolkit.slnx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,10 @@
5151
<Build Solution="Debug.R20|*" Project="false" />
5252
<Build Solution="Release.R20|*" Project="false" />
5353
</Project>
54+
<Project Path="tests/Nice3point.Revit.Toolkit.Ui.Tests/Nice3point.Revit.Toolkit.Ui.Tests.csproj">
55+
<BuildType Solution="Debug.R20|*" Project="Debug.R21" />
56+
<BuildType Solution="Release.R20|*" Project="Debug.R21" />
57+
</Project>
5458
</Folder>
5559
<Project Path="source/Nice3point.Revit.Toolkit/Nice3point.Revit.Toolkit.csproj" />
5660
</Solution>
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
using System.ComponentModel;
2+
using System.Reflection;
3+
using Autodesk.Revit.UI;
4+
using Nice3point.Revit.Toolkit.External;
5+
6+
namespace Nice3point.Revit.Toolkit.Ui.Tests;
7+
8+
[UsedImplicitly]
9+
public class Application : ExternalApplication
10+
{
11+
private const string DefaultTestGroup = "General";
12+
13+
public override void OnStartup()
14+
{
15+
var panel = Application.CreatePanel("Toolkit Tests", "Nice3point.Revit.Toolkit");
16+
RegisterTestCommands(panel);
17+
}
18+
19+
private static void RegisterTestCommands(RibbonPanel panel)
20+
{
21+
var commandTypes = Assembly.GetExecutingAssembly()
22+
.GetTypes()
23+
.Where(type => type is { IsClass: true, IsAbstract: false })
24+
.Where(type => type.IsAssignableTo<IExternalCommand>())
25+
.ToList();
26+
27+
var groupedCommands = commandTypes
28+
.GroupBy(GetGroupName)
29+
.OrderBy(group => group.Key == DefaultTestGroup ? 1 : 0)
30+
.ThenBy(group => group.Key);
31+
32+
foreach (var group in groupedCommands)
33+
{
34+
var pullButton = panel.AddPullDownButton(group.Key, group.Key);
35+
pullButton.SetImage("/Nice3point.Revit.Toolkit.Ui.Tests;component/Resources/Icons/RibbonIcon16.png");
36+
pullButton.SetLargeImage("/Nice3point.Revit.Toolkit.Ui.Tests;component/Resources/Icons/RibbonIcon32.png");
37+
38+
foreach (var commandType in group.OrderBy(type => type.Name))
39+
{
40+
pullButton.AddPushButton(commandType, commandType.Name);
41+
}
42+
}
43+
}
44+
45+
private static string GetGroupName(Type type)
46+
{
47+
var displayNameAttribute = type.GetCustomAttribute<DisplayNameAttribute>();
48+
return displayNameAttribute?.DisplayName ?? DefaultTestGroup;
49+
}
50+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
using Nice3point.Revit.Toolkit.External;
2+
3+
namespace Nice3point.Revit.Toolkit.Ui.Tests.Engine.Commands;
4+
5+
/// <summary>
6+
/// Base class for asynchronous test commands.
7+
/// </summary>
8+
[PublicAPI]
9+
public abstract class AsyncTestExternalCommand : AsyncExternalCommand
10+
{
11+
protected TestRunner Runner { get; private set; } = null!;
12+
13+
public sealed override async Task ExecuteAsync()
14+
{
15+
Runner = new TestRunner(GetType().Name);
16+
17+
try
18+
{
19+
await TestAsync();
20+
}
21+
catch (Exception exception)
22+
{
23+
Runner.Exception = exception;
24+
}
25+
26+
Runner.ShowResult();
27+
}
28+
29+
/// <summary>
30+
/// Override this method to implement async test logic.
31+
/// </summary>
32+
public abstract Task TestAsync();
33+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
using Nice3point.Revit.Toolkit.External;
2+
3+
namespace Nice3point.Revit.Toolkit.Ui.Tests.Engine.Commands;
4+
5+
/// <summary>
6+
/// Base class for synchronous test commands.
7+
/// </summary>
8+
[PublicAPI]
9+
public abstract class TestExternalCommand : ExternalCommand
10+
{
11+
protected TestRunner Runner { get; private set; } = null!;
12+
13+
public sealed override void Execute()
14+
{
15+
Runner = new TestRunner(GetType().Name);
16+
17+
try
18+
{
19+
Test();
20+
}
21+
catch (Exception exception)
22+
{
23+
Runner.Exception = exception;
24+
}
25+
26+
Runner.ShowResult();
27+
}
28+
29+
/// <summary>
30+
/// Override this method to implement test logic.
31+
/// </summary>
32+
public abstract void Test();
33+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
using Autodesk.Revit.UI;
2+
3+
namespace Nice3point.Revit.Toolkit.Ui.Tests.Engine;
4+
5+
/// <summary>
6+
/// Provides helper methods for family document operations in tests.
7+
/// </summary>
8+
internal static class FamilyDocumentHelper
9+
{
10+
/// <summary>
11+
/// Creates a model line in a family document.
12+
/// </summary>
13+
public static ModelCurve CreateModelLine(Document document, double length)
14+
{
15+
var start = new XYZ(-length / 2, 0, 0);
16+
var end = new XYZ(length / 2, 0, 0);
17+
var line = Line.CreateBound(start, end);
18+
19+
var plane = Plane.CreateByNormalAndOrigin(XYZ.BasisZ, XYZ.Zero);
20+
var sketchPlane = SketchPlane.Create(document, plane);
21+
22+
return document.FamilyCreate.NewModelCurve(line, sketchPlane);
23+
}
24+
25+
/// <summary>
26+
/// Validates that the document is a family document and shows error if not.
27+
/// </summary>
28+
public static bool RequireFamilyDocument(Document? document)
29+
{
30+
if (document is null)
31+
{
32+
ShowValidationError("No active document. Please open a document.");
33+
return false;
34+
}
35+
36+
if (!document.IsFamilyDocument)
37+
{
38+
ShowValidationError("This test requires a family document. Please open a .rfa file.");
39+
return false;
40+
}
41+
42+
return true;
43+
}
44+
45+
private static void ShowValidationError(string message)
46+
{
47+
var dialog = new TaskDialog("Test Precondition Failed")
48+
{
49+
MainContent = message,
50+
MainIcon = TaskDialogIcon.TaskDialogIconWarning
51+
};
52+
53+
dialog.Show();
54+
}
55+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
using Autodesk.Revit.UI;
2+
3+
namespace Nice3point.Revit.Toolkit.Ui.Tests.Engine;
4+
5+
/// <summary>
6+
/// Provides test execution scope with automatic result reporting via TaskDialog.
7+
/// </summary>
8+
public sealed class TestRunner
9+
{
10+
private readonly string _testName;
11+
private readonly List<string> _summaryMessages = [];
12+
13+
internal TestRunner(string testName)
14+
{
15+
_testName = testName;
16+
}
17+
18+
internal Exception? Exception { get; set; }
19+
20+
/// <summary>
21+
/// Adds a summary message to the test report.
22+
/// </summary>
23+
public void Summary(string message)
24+
{
25+
_summaryMessages.Add(message);
26+
}
27+
28+
internal void ShowResult()
29+
{
30+
var passed = Exception is null;
31+
var status = passed ? "PASSED ✓" : "FAILED ✗";
32+
33+
var content = string.Empty;
34+
35+
if (_summaryMessages.Count > 0)
36+
{
37+
content = string.Join("\n", _summaryMessages);
38+
}
39+
40+
if (Exception is not null)
41+
{
42+
if (content.Length > 0) content += "\n\n";
43+
content += $"Exception:\n{Exception.Message}";
44+
}
45+
46+
if (string.IsNullOrEmpty(content))
47+
{
48+
content = passed ? "All assertions passed." : "Test failed.";
49+
}
50+
51+
var dialog = new TaskDialog($"{_testName} - {status}")
52+
{
53+
MainContent = content,
54+
MainIcon = passed ? TaskDialogIcon.TaskDialogIconShield : TaskDialogIcon.TaskDialogIconWarning
55+
};
56+
57+
dialog.Show();
58+
}
59+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<RevitAddIns>
2+
<AddIn Type="Application">
3+
<Name>Nice3point.Revit.Toolkit.Ui.Tests</Name>
4+
<Assembly>Nice3point.Revit.Toolkit.Ui.Tests\Nice3point.Revit.Toolkit.Ui.Tests.dll</Assembly>
5+
<AddInId>4B6CAFB7-C76D-416E-BB9B-B8A815D9F9C0</AddInId>
6+
<FullClassName>Nice3point.Revit.Toolkit.Ui.Tests.Application</FullClassName>
7+
<VendorId>Development</VendorId>
8+
<VendorDescription></VendorDescription>
9+
</AddIn>
10+
<ManifestSettings>
11+
<UseRevitContext>False</UseRevitContext>
12+
<ContextName>Nice3point.Revit.Toolkit.Ui.Tests</ContextName>
13+
</ManifestSettings>
14+
</RevitAddIns>
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<Project Sdk="Nice3point.Revit.Sdk/6.0.2">
2+
3+
<PropertyGroup>
4+
<UseWPF>true</UseWPF>
5+
<DeployAddin>true</DeployAddin>
6+
<LaunchRevit>true</LaunchRevit>
7+
<IsRepackable>false</IsRepackable>
8+
<EnableDynamicLoading>true</EnableDynamicLoading>
9+
<Configurations>Debug.R20;Debug.R21;Debug.R22;Debug.R23;Debug.R24;Debug.R25;Debug.R26;Debug.R27</Configurations>
10+
<Configurations>$(Configurations);Release.R20;Release.R21;Release.R22;Release.R23;Release.R24;Release.R25;Release.R26;Release.R27</Configurations>
11+
</PropertyGroup>
12+
13+
<ItemGroup>
14+
<PackageReference Include="Nice3point.Revit.Api.RevitAPI"/>
15+
<PackageReference Include="Nice3point.Revit.Api.RevitAPIUI"/>
16+
<PackageReference Include="Nice3point.Revit.Extensions"/>
17+
<PackageReference Include="JetBrains.Annotations"/>
18+
<PackageReference Include="Shouldly"/>
19+
</ItemGroup>
20+
21+
<ItemGroup>
22+
<ProjectReference Include="..\..\source\Nice3point.Revit.Toolkit\Nice3point.Revit.Toolkit.csproj"/>
23+
</ItemGroup>
24+
25+
<ItemGroup>
26+
<Resource Include="Resources\Icons\**\*.png"/>
27+
</ItemGroup>
28+
29+
</Project>
1.33 KB
Loading

0 commit comments

Comments
 (0)