diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2e75067..98ac1e8 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,26 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
+## [1.7.1] / 2024-12-07 - 2024-12-10
+### Application
+- Update to use `AssemblyMetadata` to set configuration. (Fix: #64)
+- Update `TestExecuteUtils` to use `ConfigurationMetadata`.
+- Update `Log` file name.
+- Update `ricaun.NUnit` to `1.4.1`.
+- Add `MetadataMapper` to map `AssemblyMetadata` configuration.
+- Update to use `Task.Run` to force run outside the Revit context.
+- Update `Timeout` to time unit in minutes.
+### Command
+- Update `AssemblyName` to use `Version`.
+- Update `Timeout` to `double`.
+### TestAdapter
+- Update `MapperKey` to multiple converts.
+- Update `MetadataMapper` with `prefix`.
+- Fix `Mapper` convert integer to ignore dot.
+- Update `Timeout` to `double`.
+### Tests
+- Update `TestsRevitTask` with `AssemblyMetadata` configuration.
+
## [1.7.0] / 2024-11-02 - 2024-12-03
### Features
- Support `IRevitTask` functions as parameters.
@@ -526,6 +546,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
- [x] TestsFail
[vNext]: ../../compare/1.0.0...HEAD
+[1.7.1]: ../../compare/1.7.0...1.7.1
[1.7.0]: ../../compare/1.6.0...1.7.0
[1.6.0]: ../../compare/1.5.0...1.6.0
[1.5.0]: ../../compare/1.4.1...1.5.0
diff --git a/Directory.Build.props b/Directory.Build.props
index 1a04156..3677869 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -1,5 +1,5 @@
- 1.7.0
+ 1.7.1
\ No newline at end of file
diff --git a/ricaun.RevitTest.Application/Revit/App.cs b/ricaun.RevitTest.Application/Revit/App.cs
index 2ea4a90..66fc5bf 100644
--- a/ricaun.RevitTest.Application/Revit/App.cs
+++ b/ricaun.RevitTest.Application/Revit/App.cs
@@ -179,7 +179,8 @@ private static void PipeTestServer_Initialize()
try
{
- testAssemblyModel = await TestExecuteUtils.ExecuteAsync(RevitTask, message.TestPathFile, RevitParameters.Parameters);
+ testAssemblyModel = await Task.Run(() => TestExecuteUtils.ExecuteAsync(RevitTask, message.TestPathFile, RevitParameters.Parameters));
+ //testAssemblyModel = await TestExecuteUtils.ExecuteAsync(RevitTask, message.TestPathFile, RevitParameters.Parameters);
}
catch (Exception ex)
{
diff --git a/ricaun.RevitTest.Application/Revit/Log.cs b/ricaun.RevitTest.Application/Revit/Log.cs
index ccfa163..6d27bf2 100644
--- a/ricaun.RevitTest.Application/Revit/Log.cs
+++ b/ricaun.RevitTest.Application/Revit/Log.cs
@@ -46,7 +46,7 @@ public static void OpenJornal()
#endregion
#region File
- private static string FileName = "RevitTest_{0}.log";
+ private static string FileName = "RevitTest_{0:X}.log";
private static string FilePath = null;
private static void CreateFile()
diff --git a/ricaun.RevitTest.Application/Revit/Utils/MetadataMapper.cs b/ricaun.RevitTest.Application/Revit/Utils/MetadataMapper.cs
new file mode 100644
index 0000000..e857c15
--- /dev/null
+++ b/ricaun.RevitTest.Application/Revit/Utils/MetadataMapper.cs
@@ -0,0 +1,199 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Reflection;
+
+namespace ricaun.RevitTest.Application.Revit
+{
+ internal static class MetadataMapper
+ {
+ public static T Map(T destination, IEnumerable attributes, string prefix = null) where T : class
+ {
+ if (attributes is null)
+ return destination;
+
+ var metadataDictionary = attributes
+ .GroupBy(attr => attr.Key)
+ .ToDictionary(group => group.Key, group => group.Last().Value);
+
+ return MapperKey.Map(destination, metadataDictionary, prefix);
+ }
+ }
+ internal static class MapperKey
+ {
+ public static T Map(T destination, IDictionary dictionary, string prefix = null)
+ {
+ if (dictionary is null)
+ return destination;
+
+ foreach (var kvp in Mapper.ProcessProperties(destination, prefix))
+ {
+ var sourceKey = kvp.Key;
+ var sourcePropertyInfo = kvp.PropertyInfo;
+ var sourceValue = sourcePropertyInfo.GetValue(kvp.Object);
+
+ Debug.WriteLine($"{sourceKey} - {sourcePropertyInfo} - {sourceValue}");
+
+ if (dictionary.TryGetValue(sourceKey, out string valueToConvert))
+ {
+ var destinationValue = Mapper.ConvertValueToPropertyInfo(valueToConvert, sourcePropertyInfo);
+ if (!Mapper.IsValueEqual(sourceValue, destinationValue))
+ {
+ try
+ {
+ destinationValue = Convert.ChangeType(destinationValue, sourcePropertyInfo.PropertyType);
+ sourcePropertyInfo.SetValue(kvp.Object, destinationValue);
+ Debug.WriteLine($"\t{sourceKey}: {sourceValue} >> {sourcePropertyInfo.Name}: {destinationValue}");
+ }
+ catch (Exception ex){ Debug.WriteLine(ex); }
+ }
+ }
+ }
+
+ return destination;
+ }
+ public static IEnumerable GetNames(T destination)
+ {
+ return Mapper.ProcessProperties(destination).Select(e => e.Key).ToList();
+ }
+ public static class Mapper
+ {
+ public static string[] CustomAttributeNames = new[] { "ElementName", "DisplayName", "Name" };
+ public static Dictionary> MapperConvert;
+ public static object ConvertToLong(string valueToConvert)
+ {
+ if (long.TryParse(valueToConvert.Replace(',', '.').Split('.')[0], out var value))
+ return value;
+ return valueToConvert;
+ }
+ public static object ConvertToULong(string valueToConvert)
+ {
+ if (ulong.TryParse(valueToConvert.Replace(',', '.').Split('.')[0], out var value))
+ return value;
+ return valueToConvert;
+ }
+ public static object ConvertToDouble(string valueToConvert)
+ {
+ try
+ {
+ return double.Parse(valueToConvert.Replace(',', '.'), System.Globalization.CultureInfo.InvariantCulture);
+ }
+ catch { }
+ return valueToConvert;
+ }
+ public static object ConvertToBool(string valueToConvert)
+ {
+ var value = valueToConvert.ToLower();
+ return value.Equals("true") || value.Equals("1");
+ }
+ static Mapper()
+ {
+ MapperConvert = new Dictionary>();
+ MapperConvert.Add(typeof(ulong), ConvertToULong);
+ MapperConvert.Add(typeof(uint), ConvertToULong);
+ MapperConvert.Add(typeof(ushort), ConvertToULong);
+ MapperConvert.Add(typeof(long), ConvertToLong);
+ MapperConvert.Add(typeof(int), ConvertToLong);
+ MapperConvert.Add(typeof(short), ConvertToLong);
+ MapperConvert.Add(typeof(double), ConvertToDouble);
+ MapperConvert.Add(typeof(float), ConvertToDouble);
+ MapperConvert.Add(typeof(bool), ConvertToBool);
+ }
+
+ #region PropertyInformation
+ public class PropertyInformation
+ {
+ public string Key { get; }
+ public object Object { get; }
+ public PropertyInfo PropertyInfo { get; }
+
+ public PropertyInformation(string key, object obj, PropertyInfo propertyInfo)
+ {
+ Key = key;
+ Object = obj;
+ PropertyInfo = propertyInfo;
+ }
+ }
+ public static IEnumerable ProcessProperties(object obj, string prefix = null)
+ {
+ if (obj == null)
+ yield break;
+
+ if (string.IsNullOrEmpty(prefix))
+ prefix = string.Empty;
+
+ Type objectType = obj.GetType();
+ PropertyInfo[] properties = objectType.GetProperties(BindingFlags.Public | BindingFlags.Instance);
+
+ foreach (PropertyInfo property in properties)
+ {
+ var propertyName = GetCustomAttributeName(property);
+ string propertyKey = string.IsNullOrEmpty(prefix) ? propertyName : $"{prefix}.{propertyName}";
+
+ if (property.PropertyType.IsClass && property.PropertyType != typeof(string))
+ {
+ object nestedPropertyValue = property.GetValue(obj);
+ if (nestedPropertyValue is null)
+ {
+ try
+ {
+ nestedPropertyValue = Activator.CreateInstance(property.PropertyType);
+ property.SetValue(obj, nestedPropertyValue);
+ }
+ catch { }
+ }
+ foreach (var nestedProperty in ProcessProperties(nestedPropertyValue, propertyKey))
+ {
+ yield return nestedProperty;
+ }
+ }
+ else
+ {
+ yield return new PropertyInformation(propertyKey, obj, property);
+ }
+ }
+ }
+ #endregion
+ public static string GetCustomAttributeName(MemberInfo memberInfo)
+ {
+ try
+ {
+ var customPropertyNames = CustomAttributeNames;
+ foreach (var customAttribute in memberInfo.GetCustomAttributes())
+ {
+ var type = customAttribute.GetType();
+ foreach (var propertyName in customPropertyNames)
+ {
+ if (type?.GetProperty(propertyName) is PropertyInfo propertyInfo)
+ {
+ var value = propertyInfo.GetValue(customAttribute) as string;
+ if (!string.IsNullOrEmpty(value)) return value;
+ }
+ }
+ }
+ }
+ catch { }
+ return memberInfo.Name;
+ }
+ public static object ConvertValueToPropertyInfo(string valueToConvert, PropertyInfo propertyInfo)
+ {
+ var type = propertyInfo.PropertyType;
+ if (MapperConvert.TryGetValue(type, out var converter))
+ {
+ return converter.Invoke(valueToConvert);
+ }
+ return valueToConvert;
+ }
+ public static bool IsValueEqual(object sourceValue, object destinationValue)
+ {
+ if (sourceValue is null)
+ {
+ return destinationValue is null;
+ }
+
+ return sourceValue.Equals(destinationValue);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/ricaun.RevitTest.Application/Revit/Utils/TestExecuteUtils.cs b/ricaun.RevitTest.Application/Revit/Utils/TestExecuteUtils.cs
index 8ee768b..10e9a52 100644
--- a/ricaun.RevitTest.Application/Revit/Utils/TestExecuteUtils.cs
+++ b/ricaun.RevitTest.Application/Revit/Utils/TestExecuteUtils.cs
@@ -18,7 +18,7 @@ public static async Task ExecuteAsync(IRevitTask revitTask, s
{
Log.WriteLine($"TestExecuteUtils: {filePath}");
var zipFile = await revitTask.Run(() => CopyFilesUsingZipFolder(filePath));
-
+
if (zipFile is null)
{
Log.WriteLine($"TestExecuteUtils: Copy Zip Fail");
@@ -27,15 +27,14 @@ public static async Task ExecuteAsync(IRevitTask revitTask, s
string zipDestination = null;
var extractToTempSucess = await revitTask.Run(() => ZipExtension.ExtractToTempFolder(zipFile, out zipDestination));
-
+
if (extractToTempSucess == false)
{
Log.WriteLine($"TestExecuteUtils: Extract Zip Fail");
throw new Exception("Extract Zip Fail");
}
- //TestAssemblyModel tests = await revitTask.Run(() => TestDirectory(zipDestination, parameters));
- TestAssemblyModel tests = await TestDirectoryAsync(revitTask, zipDestination, Path.GetFileName(filePath), parameters);
+ TestAssemblyModel tests = await Task.Run(() => TestDirectoryAsync(revitTask, zipDestination, Path.GetFileName(filePath), parameters));
await revitTask.Run(() => CopyFilesBackUsingZip(filePath, zipDestination));
@@ -85,9 +84,9 @@ private static async Task TestDirectoryAsync(IRevitTask revit
{
TestAssemblyModel modelTest = null;
- Log.WriteLine("----------------------------------");
+ Log.WriteLine();
Log.WriteLine($"TestEngine: {ricaun.NUnit.TestEngine.Initialize(out string testInitialize)} {testInitialize}");
- Log.WriteLine("----------------------------------");
+ Log.WriteLine();
foreach (var filePath in Directory.GetFiles(directory, filePattern)) // "*.dll"
{
@@ -101,51 +100,52 @@ private static async Task TestDirectoryAsync(IRevitTask revit
TestEngineFilter.CancellationTokenTimeOut = TimeSpan.FromSeconds(3);
#endif
- if (FileVersionInfoUtils.TryGetComments(filePath, out ConfigurationComments comments))
+ var configurationMetadata = ConfigurationMetadata.GetConfigurationMetadata(filePath);
+
+ if (configurationMetadata.Timeout > 0)
{
- if (comments.TimeOut > 0)
- {
- TestEngineFilter.CancellationTokenTimeOut = TimeSpan.FromSeconds(comments.TimeOut);
- Log.WriteLine($"TimeOut: {comments.TimeOut}");
- }
+ TestEngineFilter.CancellationTokenTimeOut = TimeSpan.FromMinutes(configurationMetadata.Timeout);
+ Log.WriteLine($"Tasks.Timeout: {configurationMetadata.Timeout} minutes");
+ }
- string containTestNameForNoRevitContext = comments.TestAsync;
- if (string.IsNullOrEmpty(containTestNameForNoRevitContext) == false)
+ string containTestNameForNoRevitContext = configurationMetadata.Name;
+ if (string.IsNullOrEmpty(containTestNameForNoRevitContext) == false)
+ {
+ Log.WriteLine($"Tasks.Name: {containTestNameForNoRevitContext}");
+ if (TestEngineFilter.ExplicitEnabled == false)
{
- if (TestEngineFilter.ExplicitEnabled == false)
- {
- TestEngineFilter.ExplicitEnabled = false;
- TestEngineFilter.TestNames.AddRange(TestEngine.GetTestFullNames(filePath));
- }
+ TestEngineFilter.ExplicitEnabled = false;
+ TestEngineFilter.TestNames.AddRange(TestEngine.GetTestFullNames(filePath));
+ }
- var originalTestNames = TestEngineFilter.TestNames.ToArray();
- var testGroupNoContext = originalTestNames
- .GroupBy(str => str.Contains(containTestNameForNoRevitContext))
- .ToDictionary(group => group.Key, group => group.ToList());
+ var originalTestNames = TestEngineFilter.TestNames.ToArray();
+ var testGroupNoContext = originalTestNames
+ .GroupBy(str => str.Contains(containTestNameForNoRevitContext))
+ .ToDictionary(group => group.Key, group => group.ToList());
- if (testGroupNoContext.TryGetValue(false, out var inContextTestNames))
- {
- TestEngineFilter.TestNames.Clear();
- TestEngineFilter.TestNames.AddRange(inContextTestNames);
- modelTest = await revitTask.Run(() => TestEngine.TestAssembly(filePath, parameters));
- }
+ if (testGroupNoContext.TryGetValue(false, out var inContextTestNames))
+ {
+ Log.WriteLine($"InContext: [{string.Join(",", inContextTestNames)}]");
+ TestEngineFilter.TestNames.Clear();
+ TestEngineFilter.TestNames.AddRange(inContextTestNames);
+ modelTest = await revitTask.Run(() => TestEngine.TestAssembly(filePath, parameters));
+ }
- if (testGroupNoContext.TryGetValue(true, out var testAsyncNames))
+ if (testGroupNoContext.TryGetValue(true, out var testAsyncNames))
+ {
+ Log.WriteLine($"Tasks: [{string.Join(",", testAsyncNames)}]");
+ TestEngineFilter.TestNames.Clear();
+ TestEngineFilter.TestNames.AddRange(testAsyncNames);
+ var modelTestAsync = await Task.Run(() => TestEngine.TestAssembly(filePath, parameters));
+ if (modelTest is null) modelTest = modelTestAsync;
+ else
{
- Log.WriteLine($"TestAsync: [{string.Join(",", testAsyncNames)}]");
- TestEngineFilter.TestNames.Clear();
- TestEngineFilter.TestNames.AddRange(testAsyncNames);
- var modelTestAsync = TestEngine.TestAssembly(filePath, parameters);
- if (modelTest is null) modelTest = modelTestAsync;
- else
- {
- modelTest.Tests.AddRange(modelTestAsync.Tests);
- }
+ modelTest.Tests.AddRange(modelTestAsync.Tests);
}
-
- TestEngineFilter.TestNames.Clear();
- TestEngineFilter.TestNames.AddRange(originalTestNames);
}
+
+ TestEngineFilter.TestNames.Clear();
+ TestEngineFilter.TestNames.AddRange(originalTestNames);
}
if (modelTest is null)
@@ -156,6 +156,7 @@ private static async Task TestDirectoryAsync(IRevitTask revit
var passed = modelTest.Success ? "Passed" : "Failed";
if (modelTest.TestCount == 0) { passed = "No Tests"; }
+ Log.WriteLine();
Log.WriteLine($"{modelTest}\t {passed}");
var tests = modelTest.Tests.SelectMany(e => e.Tests);
@@ -188,95 +189,29 @@ private static async Task TestDirectoryAsync(IRevitTask revit
}
}
- Log.WriteLine("----------------------------------");
+ Log.WriteLine();
return modelTest;
}
- //public static TestAssemblyModel Execute(string filePath, params object[] parameters)
- //{
- // var zipFile = CopyFilesUsingZipFolder(filePath);
-
- // if (zipFile is null)
- // return null;
-
- // var extractToTempSucess = ZipExtension.ExtractToTempFolder(zipFile, out string zipDestination);
-
- // if (extractToTempSucess == false)
- // return null;
-
- // TestAssemblyModel tests = TestDirectory(zipDestination, parameters);
-
- // CopyFilesBackUsingZip(filePath, zipDestination);
-
- // return tests;
- //}
-
- //private static TestAssemblyModel TestDirectory(string directory, params object[] parameters)
- //{
- // TestAssemblyModel modelTest = null;
-
- // Log.WriteLine("----------------------------------");
- // Log.WriteLine($"TestEngine: {ricaun.NUnit.TestEngine.Initialize(out string testInitialize)} {testInitialize}");
- // Log.WriteLine("----------------------------------");
-
- // foreach (var filePath in Directory.GetFiles(directory, "*.dll"))
- // {
- // var fileName = Path.GetFileName(filePath);
- // try
- // {
- // if (TestEngine.ContainNUnit(filePath))
- // {
- // //Log.WriteLine($"Test File: {fileName}");
- // //foreach (var testName in TestEngine.GetTestFullNames(filePath))
- // //{
- // // Log.WriteLine($"\t{testName}");
- // //}
-
- // TestEngineFilter.CancellationTokenTimeOut = TimeSpan.FromMinutes(1);
-
- // modelTest = TestEngine.TestAssembly(filePath, parameters);
-
- // var passed = modelTest.Success ? "Passed" : "Failed";
- // if (modelTest.TestCount == 0) { passed = "No Tests"; }
-
- // Log.WriteLine($"{modelTest}\t {passed}");
-
- // var tests = modelTest.Tests.SelectMany(e => e.Tests);
-
- // foreach (var test in tests)
- // {
- // Log.WriteLine($"\t {test.Time}\t {test}");
- // //Debug.WriteLine($"Debug:\t {test}\t {test.Console.Trim()}");
- // }
-
- // if (tests.Any() == false)
- // {
- // Log.WriteLine($"Error: {modelTest.Message}");
- // try
- // {
- // var ex = new Exception(modelTest.Message.Split('\n').FirstOrDefault());
- // modelTest = TestEngine.Fail(filePath, ex);
- // }
- // catch { }
- // }
- // }
- // }
- // catch (Exception ex)
- // {
- // Log.WriteLine($"Error: {fileName} {ex}");
- // }
- // }
-
- // Log.WriteLine("----------------------------------");
-
- // return modelTest;
- //}
-
- private class ConfigurationComments
+ private class ConfigurationMetadata
{
- public string TestAsync { get; set; }
- public double TimeOut { get; set; }
+ public string Name { get; set; }
+ ///
+ /// Timeout in minutes
+ ///
+ public double Timeout { get; set; }
+
+ public static ConfigurationMetadata GetConfigurationMetadata(string filePath)
+ {
+ var configurationMetadata = new ConfigurationMetadata();
+ try
+ {
+ MetadataMapper.Map(configurationMetadata, TestEngine.GetAssemblyMetadataAttributes(filePath), "ricaun.RevitTest.Application.Tasks");
+ }
+ catch { }
+ return configurationMetadata;
+ }
}
}
}
diff --git a/ricaun.RevitTest.Command/Command/IRunTestService.cs b/ricaun.RevitTest.Command/Command/IRunTestService.cs
index 9d7068b..ed39239 100644
--- a/ricaun.RevitTest.Command/Command/IRunTestService.cs
+++ b/ricaun.RevitTest.Command/Command/IRunTestService.cs
@@ -12,7 +12,7 @@ public bool RunTests(
string forceLanguageToRevit = null,
bool forceToOpenNewRevit = false,
bool forceToCloseRevit = false,
- int timeoutMinutes = 0,
+ double timeoutMinutes = 0,
params string[] testFilters);
}
}
\ No newline at end of file
diff --git a/ricaun.RevitTest.Command/Command/Options.cs b/ricaun.RevitTest.Command/Command/Options.cs
index 0169dc5..9a0c8c6 100644
--- a/ricaun.RevitTest.Command/Command/Options.cs
+++ b/ricaun.RevitTest.Command/Command/Options.cs
@@ -62,7 +62,7 @@ private static Parser CreateParser()
[Option("timeout",
Default = 0,
HelpText = "Timeout in minutes to abort this application.")]
- public int Timeout { get; set; }
+ public double Timeout { get; set; }
[Option("debugger",
Default = false,
diff --git a/ricaun.RevitTest.Command/Process/RevitTestProcessStart.cs b/ricaun.RevitTest.Command/Process/RevitTestProcessStart.cs
index aa1f653..318027d 100644
--- a/ricaun.RevitTest.Command/Process/RevitTestProcessStart.cs
+++ b/ricaun.RevitTest.Command/Process/RevitTestProcessStart.cs
@@ -48,7 +48,7 @@ public RevitTestProcessStart SetClose(bool close = true)
if (!close) return this;
return SetRevitArgument("close");
}
- public RevitTestProcessStart SetTimeout(int timeoutMinutes) => SetRevitArgument("timeout", timeoutMinutes);
+ public RevitTestProcessStart SetTimeout(double timeoutMinutes) => SetRevitArgument("timeout", timeoutMinutes);
public RevitTestProcessStart SetTestFilter(string[] testFilters)
{
if (testFilters.Length == 0)
diff --git a/ricaun.RevitTest.Command/Process/RevitTestProcessStartUtils.cs b/ricaun.RevitTest.Command/Process/RevitTestProcessStartUtils.cs
index eb0c208..6819d49 100644
--- a/ricaun.RevitTest.Command/Process/RevitTestProcessStartUtils.cs
+++ b/ricaun.RevitTest.Command/Process/RevitTestProcessStartUtils.cs
@@ -56,7 +56,7 @@ public static async Task RunExecuteTests(
string language = null,
bool revitOpen = false,
bool revitClose = false,
- int timeoutMinutes = 0,
+ double timeoutMinutes = 0,
bool debugger = false,
Action consoleAction = null,
Action debugAction = null,
diff --git a/ricaun.RevitTest.Command/ricaun.RevitTest.Command.csproj b/ricaun.RevitTest.Command/ricaun.RevitTest.Command.csproj
index be4d7ad..b830334 100644
--- a/ricaun.RevitTest.Command/ricaun.RevitTest.Command.csproj
+++ b/ricaun.RevitTest.Command/ricaun.RevitTest.Command.csproj
@@ -40,7 +40,7 @@
- $(PackageId)
+ $(PackageId).$(Version)
$(PackageId)
Copyright (C) $(Company) $(CopyrightYears)
diff --git a/ricaun.RevitTest.Console/Resources/ricaun.RevitTest.Application.bundle.zip b/ricaun.RevitTest.Console/Resources/ricaun.RevitTest.Application.bundle.zip
index 9e85817..d6fe362 100644
Binary files a/ricaun.RevitTest.Console/Resources/ricaun.RevitTest.Application.bundle.zip and b/ricaun.RevitTest.Console/Resources/ricaun.RevitTest.Application.bundle.zip differ
diff --git a/ricaun.RevitTest.Console/Revit/RevitRunTestService.cs b/ricaun.RevitTest.Console/Revit/RevitRunTestService.cs
index 4e04cfd..dc6418e 100644
--- a/ricaun.RevitTest.Console/Revit/RevitRunTestService.cs
+++ b/ricaun.RevitTest.Console/Revit/RevitRunTestService.cs
@@ -17,7 +17,7 @@ public bool RunTests(string fileToTest,
string forceLanguageToRevit = null,
bool forceToOpenNewRevit = false,
bool forceToCloseRevit = false,
- int timeoutMinutes = 0,
+ double timeoutMinutes = 0,
params string[] testFilters)
{
RevitTestUtils.CreateRevitServer(
diff --git a/ricaun.RevitTest.Console/Revit/Utils/RevitTestUtils.cs b/ricaun.RevitTest.Console/Revit/Utils/RevitTestUtils.cs
index 940c663..d478074 100644
--- a/ricaun.RevitTest.Console/Revit/Utils/RevitTestUtils.cs
+++ b/ricaun.RevitTest.Console/Revit/Utils/RevitTestUtils.cs
@@ -98,7 +98,7 @@ public static void CreateRevitServer(
string forceLanguageToRevit = null,
bool forceToOpenNewRevit = false,
bool forceToCloseRevit = false,
- int timeoutMinutes = 0,
+ double timeoutMinutes = 0,
params string[] testFilters)
{
int timeoutNotBusyCountMax = 10;
@@ -198,7 +198,7 @@ public static void CreateRevitServer(
}
};
- var timeoutSeconds = timeoutMinutes * 60;
+ int timeoutSeconds = (int) timeoutMinutes * 60;
for (int i = 0; i <= timeoutSeconds; i++)
{
Thread.Sleep(1000);
diff --git a/ricaun.RevitTest.TestAdapter/Metadatas/MapperKey.cs b/ricaun.RevitTest.TestAdapter/Metadatas/MapperKey.cs
index a606f46..cd39560 100644
--- a/ricaun.RevitTest.TestAdapter/Metadatas/MapperKey.cs
+++ b/ricaun.RevitTest.TestAdapter/Metadatas/MapperKey.cs
@@ -8,12 +8,12 @@ namespace ricaun.RevitTest.TestAdapter.Metadatas
{
internal static class MapperKey
{
- public static T Map(T destination, IDictionary dictionary)
+ public static T Map(T destination, IDictionary dictionary, string prefix = null)
{
if (dictionary is null)
return destination;
- foreach (var kvp in Mapper.ProcessProperties(destination))
+ foreach (var kvp in Mapper.ProcessProperties(destination, prefix))
{
var sourceKey = kvp.Key;
var sourcePropertyInfo = kvp.PropertyInfo;
@@ -28,6 +28,7 @@ public static T Map(T destination, IDictionary dictionary)
{
try
{
+ destinationValue = Convert.ChangeType(destinationValue, sourcePropertyInfo.PropertyType);
sourcePropertyInfo.SetValue(kvp.Object, destinationValue);
Debug.WriteLine($"\t{sourceKey}: {sourceValue} >> {sourcePropertyInfo.Name}: {destinationValue}");
}
@@ -46,29 +47,44 @@ public static class Mapper
{
public static string[] CustomAttributeNames = new[] { "ElementName", "DisplayName", "Name" };
public static Dictionary> MapperConvert;
+ public static object ConvertToLong(string valueToConvert)
+ {
+ if (long.TryParse(valueToConvert.Replace(',', '.').Split('.')[0], out var value))
+ return value;
+ return valueToConvert;
+ }
+ public static object ConvertToULong(string valueToConvert)
+ {
+ if (ulong.TryParse(valueToConvert.Replace(',', '.').Split('.')[0], out var value))
+ return value;
+ return valueToConvert;
+ }
+ public static object ConvertToDouble(string valueToConvert)
+ {
+ try
+ {
+ return double.Parse(valueToConvert.Replace(',', '.'), System.Globalization.CultureInfo.InvariantCulture);
+ }
+ catch { }
+ return valueToConvert;
+ }
+ public static object ConvertToBool(string valueToConvert)
+ {
+ var value = valueToConvert.ToLower();
+ return value.Equals("true") || value.Equals("1");
+ }
static Mapper()
{
MapperConvert = new Dictionary>();
- MapperConvert.Add(typeof(int), (string valueToConvert) =>
- {
- if (int.TryParse(valueToConvert, out int value))
- return value;
- return valueToConvert;
- });
- MapperConvert.Add(typeof(double), (string valueToConvert) =>
- {
- try
- {
- return double.Parse(valueToConvert.Replace(',', '.'), System.Globalization.CultureInfo.InvariantCulture);
- }
- catch { }
- return valueToConvert;
- });
- MapperConvert.Add(typeof(bool), (string valueToConvert) =>
- {
- var value = valueToConvert.ToLower();
- return value.Equals("true") || value.Equals("1");
- });
+ MapperConvert.Add(typeof(ulong), ConvertToULong);
+ MapperConvert.Add(typeof(uint), ConvertToULong);
+ MapperConvert.Add(typeof(ushort), ConvertToULong);
+ MapperConvert.Add(typeof(long), ConvertToLong);
+ MapperConvert.Add(typeof(int), ConvertToLong);
+ MapperConvert.Add(typeof(short), ConvertToLong);
+ MapperConvert.Add(typeof(double), ConvertToDouble);
+ MapperConvert.Add(typeof(float), ConvertToDouble);
+ MapperConvert.Add(typeof(bool), ConvertToBool);
}
#region PropertyInformation
diff --git a/ricaun.RevitTest.TestAdapter/Metadatas/MetadataMapper.cs b/ricaun.RevitTest.TestAdapter/Metadatas/MetadataMapper.cs
index fa67fdc..bd87ee9 100644
--- a/ricaun.RevitTest.TestAdapter/Metadatas/MetadataMapper.cs
+++ b/ricaun.RevitTest.TestAdapter/Metadatas/MetadataMapper.cs
@@ -8,7 +8,7 @@ namespace ricaun.RevitTest.TestAdapter.Metadatas
{
internal static class MetadataMapper
{
- public static T Map(T destination, IEnumerable attributes) where T : class
+ public static T Map(T destination, IEnumerable attributes, string prefix = null) where T : class
{
if (attributes is null)
return destination;
@@ -17,7 +17,7 @@ public static T Map(T destination, IEnumerable att
.GroupBy(attr => attr.Key)
.ToDictionary(group => group.Key, group => group.Last().Value);
- return MapperKey.Map(destination, metadataDictionary);
+ return MapperKey.Map(destination, metadataDictionary, prefix);
}
}
}
diff --git a/ricaun.RevitTest.TestAdapter/Models/RunSettingsModel.cs b/ricaun.RevitTest.TestAdapter/Models/RunSettingsModel.cs
index 6f88fa7..5f8abf1 100644
--- a/ricaun.RevitTest.TestAdapter/Models/RunSettingsModel.cs
+++ b/ricaun.RevitTest.TestAdapter/Models/RunSettingsModel.cs
@@ -24,7 +24,7 @@ public class NUnitModel
public bool Close { get; set; }
[XmlElement("Timeout")]
- public int Timeout { get; set; }
+ public double Timeout { get; set; }
[XmlElement("Verbosity")]
public int Verbosity { get; set; }
diff --git a/ricaun.RevitTest.TestAdapter/Resources/net48/ricaun.RevitTest.Console.zip b/ricaun.RevitTest.TestAdapter/Resources/net48/ricaun.RevitTest.Console.zip
index 9d6bbad..20d9364 100644
Binary files a/ricaun.RevitTest.TestAdapter/Resources/net48/ricaun.RevitTest.Console.zip and b/ricaun.RevitTest.TestAdapter/Resources/net48/ricaun.RevitTest.Console.zip differ
diff --git a/ricaun.RevitTest.TestAdapter/Resources/net8.0-windows/ricaun.RevitTest.Console.zip b/ricaun.RevitTest.TestAdapter/Resources/net8.0-windows/ricaun.RevitTest.Console.zip
index 50c3e69..504f500 100644
Binary files a/ricaun.RevitTest.TestAdapter/Resources/net8.0-windows/ricaun.RevitTest.Console.zip and b/ricaun.RevitTest.TestAdapter/Resources/net8.0-windows/ricaun.RevitTest.Console.zip differ
diff --git a/ricaun.RevitTest.TestAdapter/Services/RevitTestConsole.cs b/ricaun.RevitTest.TestAdapter/Services/RevitTestConsole.cs
index b3adca4..9d33e34 100644
--- a/ricaun.RevitTest.TestAdapter/Services/RevitTestConsole.cs
+++ b/ricaun.RevitTest.TestAdapter/Services/RevitTestConsole.cs
@@ -109,7 +109,7 @@ public async Task RunExecuteTests(
string language = null,
bool revitOpen = false,
bool revitClose = false,
- int timeoutMinutes = 0,
+ double timeoutMinutes = 0,
Action consoleAction = null,
Action debugAction = null,
Action errorAction = null,
diff --git a/ricaun.RevitTest.Tests/TestsDebugger.cs b/ricaun.RevitTest.Tests/TestsDebugger.cs
index 93eaf85..e8706a1 100644
--- a/ricaun.RevitTest.Tests/TestsDebugger.cs
+++ b/ricaun.RevitTest.Tests/TestsDebugger.cs
@@ -22,11 +22,11 @@
//[assembly: AssemblyMetadata("NUnit.Application", "..\\..\\..\\..\\ricaun.RevitTest.Console\\bin\\Debug\\ricaun.DA4R.NUnit.Console.zip")]
-[assembly: AssemblyMetadata("NUnit.Timeout", "5")]
-
//[assembly: AssemblyMetadata("NUnit.Language", "ENU /hosted")]
#endif
+[assembly: AssemblyMetadata("NUnit.Timeout", "5.5")]
+
namespace ricaun.RevitTest.Tests
{
#if DEBUG
diff --git a/ricaun.RevitTest.Tests/TestsRevitTask.cs b/ricaun.RevitTest.Tests/TestsRevitTask.cs
index 69833a2..1ac5433 100644
--- a/ricaun.RevitTest.Tests/TestsRevitTask.cs
+++ b/ricaun.RevitTest.Tests/TestsRevitTask.cs
@@ -2,10 +2,12 @@
using NUnit.Framework;
using ricaun.Revit.UI.Tasks;
using System;
+using System.Linq;
using System.Threading;
using System.Threading.Tasks;
-[assembly: System.Reflection.AssemblyDescription("{\"TestAsync\":\"RevitTask\",\"TimeOut\":60.0}")]
+[assembly: System.Reflection.AssemblyMetadata("ricaun.RevitTest.Application.Tasks.Name", "RevitTask")]
+[assembly: System.Reflection.AssemblyMetadata("ricaun.RevitTest.Application.Tasks.Timeout", "0.05")]
namespace ricaun.RevitTest.Tests
{
@@ -51,6 +53,20 @@ private bool InContext(UIApplication uiapp)
return !(uiapp.ActiveAddInId is null);
}
+ [Test]
+ public void GetAssemblies()
+ {
+ var assemblies = AppDomain.CurrentDomain.GetAssemblies().Where(assembly => typeof(TestsRevitTask).Assembly.FullName == assembly.FullName);
+ foreach (var assembly in assemblies)
+ {
+ Console.WriteLine($"{assembly.GetName().Name} | {(!string.IsNullOrEmpty(assembly.Location) ? System.IO.Path.GetFileName(assembly.Location) : string.Empty)}");
+ }
+#if !DEBUG
+ // Check if the assembly is only loaded once
+ Assert.AreEqual(1, assemblies.Count());
+#endif
+ }
+
[Test]
public async Task RunContext()
{