Compare commits

..

5 Commits

Author SHA1 Message Date
Jedd Morgan e9076b7dd3 pass envvars properly
.NET Build and Publish / build (push) Has been cancelled
2025-07-29 21:45:38 +01:00
Jedd Morgan 45d3a08407 fix x2 2025-07-29 21:41:39 +01:00
Jedd Morgan 399b76e449 fix? 2025-07-29 21:40:13 +01:00
Jedd Morgan f8aef65750 Pr workflow 2025-07-29 20:28:02 +01:00
Jedd Morgan a797184af8 Strip out gitversion 2025-07-29 20:22:03 +01:00
24 changed files with 131 additions and 104 deletions
+2 -2
View File
@@ -3,11 +3,11 @@
"isRoot": true,
"tools": {
"csharpier": {
"version": "1.1.2",
"version": "1.0.2",
"commands": [
"csharpier"
],
"rollForward": false
}
}
}
}
+2 -2
View File
@@ -8,10 +8,10 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v5
uses: actions/checkout@v4
- name: Setup .NET
uses: actions/setup-dotnet@v5
uses: actions/setup-dotnet@v4
with:
dotnet-version: 8.x.x
+2 -2
View File
@@ -9,10 +9,10 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v5
uses: actions/checkout@v4
- name: Setup .NET
uses: actions/setup-dotnet@v5
uses: actions/setup-dotnet@v4
with:
dotnet-version: 8.x.x
+10 -21
View File
@@ -9,12 +9,9 @@ Speckle | Sharp | SDK
### .NET SDK, Tests, and Objects
[![codecov](https://codecov.io/gh/specklesystems/speckle-sharp-sdk/branch/dev/graph/badge.svg?token=TTM5OGr38m)](https://codecov.io/gh/specklesystems/speckle-sharp-sdk)
<a href="https://www.nuget.org/packages/Speckle.Sdk/"><img alt="NuGet Version" src="https://img.shields.io/nuget/v/Speckle.Sdk?label=Speckle.Sdk"></a>
<a href="https://www.nuget.org/packages/Speckle.Objects/"><img alt="NuGet Version" src="https://img.shields.io/nuget/v/Speckle.Sdk?label=Speckle.Objects"></a>
<a href="https://www.nuget.org/packages/Speckle.Automate.Sdk/"><img alt="NuGet Version" src="https://img.shields.io/nuget/v/Speckle.Sdk?label=Speckle.Automate.Sdk"></a>
> [!WARNING]
> Releases Speckle.Sdk and Speckle.Objects are reliable for production use, but the APIs may not be wholly stable, and there may be breaking changes between releases, with little documentation.
> This is an early beta release, not meant for use in production! We're working to stabilise the 3.0 API, and until then there will be breaking changes. You have been warned!
# Repo structure
@@ -31,13 +28,11 @@ This repo is the home of our next-generation Speckle .NET SDK. It uses .NET Stan
### Other repos
Make sure to also check and ⭐️ these other repositories:
Make sure to also check and ⭐️ these other Speckle next generation repositories:
- [`speckle-sharp-connectors`](https://github.com/specklesystems/speckle-sharp-connectors): our csharp repo of next gen connectors.
- [`speckle-server`](https://github.com/specklesystems/speckle-server): the speckle server.
- [`speckle-sketchup`](https://github.com/specklesystems/speckle-blender): Blender connector.
- [`speckle-sketchup`](https://github.com/specklesystems/speckle-sketchup): Sketchup connector.
- [`speckle-powerbi`](https://github.com/specklesystems/speckle-powerbi): PowerBi connector.
- [`speckle-sharp-connectors`](https://github.com/specklesystems/speckle-sharp-connectors): our csharp repo of next gen connectors
- [`speckle-sketchup`](https://github.com/specklesystems/speckle-sketchup): Sketchup connector
- [`speckle-powerbi`](https://github.com/specklesystems/speckle-powerbi): PowerBi connector
- and more [connectors & tooling](https://github.com/specklesystems/)!
## Documentation
@@ -50,24 +45,18 @@ Comprehensive developer and user documentation can be found in our:
### Building
Ensure you're using a [8.0.4xx](https://dotnet.microsoft.com/en-us/download/dotnet/8.0) .NET SDK.
After cloning this repository, just restore all the NuGet packages and hit Build!
Make sure you clone this repository together with its submodules: `git clone https://github.com/specklesystems/speckle-sharp-sdk.git -recursive`.
Afterwards, just restore all the NuGet packages and hit Build!
### Developing
It is highly recommended you use
- Either Jetbrains Rider or Visual Studio 2022
- Ensure your IDE is set to use [the correct .NET SDK version](https://github.com/specklesystems/speckle-sharp-sdk/blob/main/global.json) (newer major versions may work, but may incorrectly run analysers we haven't configured)
- You should install the cshapier plugin ([Rider](https://plugins.jetbrains.com/plugin/18243-csharpier), [VS](https://marketplace.visualstudio.com/items?itemName=csharpier.CSharpier)) and configure it to run on save
This project is evolving fast, to better understand how to use Core we suggest checking out the Unit and Integration tests. Running the integration tests locally requires a local server running on your computer.
Docs are a bit patchy [https://docs.speckle.systems/developers/looking-for-developer-docs](https://docs.speckle.systems/developers/looking-for-developer-docs)
We'll be also adding [preliminary documentation on our forum](https://discourse.speckle.works/c/speckle-insider/10).
### Tests
There are several test projects. It is a requirement that all tests pass for PRs to be merged.
The Integration test projects require a local server to be running.
You must have docker installed. Then you can run `docker compose up --wait` from the root of the repo to start the required containers.
There are two test projects, one for unit tests and one for integration tests. The latter needs a server running locally in order to run.
## Contributing
+1
View File
@@ -265,6 +265,7 @@ public sealed class BlobApi : IBlobApi
[AutoInterfaceIgnore]
public void Dispose()
{
_activityFactory.Dispose();
_authedClient.Dispose();
_unauthedClient.Dispose();
}
@@ -19,9 +19,6 @@ public sealed class ServerInfo
[Obsolete("Don't use")]
public bool frontend2 { get; set; } = true;
/// <summary>
/// The URL that should be used to talk with the server
/// </summary>
/// <remarks>
/// This field is not returned from the GQL API,
/// it should be populated after construction.
+2 -10
View File
@@ -59,20 +59,15 @@ public class Account : IEquatable<Account>
#region public methods
/// <remarks>The logic is aligned with <c>distinct_id</c> mixpanel property</remarks>
/// <exception cref="ArgumentNullException">Thrown if <see name="userInfo.email"/> was <see langword="null"/></exception>
public string GetHashedEmail()
{
string email = userInfo.email.NotNull();
string email = userInfo?.email ?? "unknown";
return "@" + Md5.GetString(email).ToUpperInvariant();
}
/// <remarks>The logic is aligned with <c>server</c> mixpanel property</remarks>
/// <exception cref="ArgumentNullException">Thrown if <see name="serverInfo.url"/> was <see langword="null"/></exception>
public string GetHashedServer()
{
string url = serverInfo.url.NotNull();
string url = serverInfo?.url ?? AccountManager.DEFAULT_SERVER_URL;
return Md5.GetString(CleanURL(url)).ToUpperInvariant();
}
@@ -102,8 +97,6 @@ public class Account : IEquatable<Account>
#endregion
internal const string LOCAL_IDENTIFIER_DEPRECATION_MESSAGE = "Local identifiers no longer nesseary";
/// <summary>
/// Retrieves the local identifier for the current user.
/// </summary>
@@ -128,6 +121,5 @@ public class Account : IEquatable<Account>
/// https://speckle.xyz?id=123
/// </code>
/// </example>
[Obsolete(LOCAL_IDENTIFIER_DEPRECATION_MESSAGE)]
internal Uri GetLocalIdentifier() => new($"{serverInfo.url}?id={userInfo.id}");
}
@@ -419,7 +419,6 @@ public sealed class AccountManager(
/// <remarks>
/// <inheritdoc cref="Account.GetLocalIdentifier"/>
/// </remarks>
[Obsolete(Account.LOCAL_IDENTIFIER_DEPRECATION_MESSAGE)]
public Uri? GetLocalIdentifierForAccount(Account account)
{
var identifier = account.GetLocalIdentifier();
@@ -441,7 +440,6 @@ public sealed class AccountManager(
/// </summary>
/// <param name="localIdentifier">The local identifier of the account.</param>
/// <returns>The account that matches the local identifier, or null if no match is found.</returns>
[Obsolete(Account.LOCAL_IDENTIFIER_DEPRECATION_MESSAGE)]
public Account? GetAccountForLocalIdentifier(Uri localIdentifier)
{
var searchResult = GetAccounts()
+2 -1
View File
@@ -169,7 +169,8 @@ public class Base : DynamicBase, ISpeckleObject
return count;
}
case IEnumerable e and not string:
case IEnumerable e
and not string:
{
foreach (var arrValue in e)
{
@@ -109,9 +109,9 @@ public abstract class GraphTraversal<T>
break;
case IList list:
{
for (int i = list.Count - 1; i >= 0; i--)
foreach (object? obj in list)
{
TraverseMemberToStack(stack, list[i], memberName, parent);
TraverseMemberToStack(stack, obj, memberName, parent);
}
break;
@@ -21,7 +21,12 @@ public class BaseSerializer(
public IReadOnlyDictionary<Id, ObjectReference> ObjectReferences => _objectReferences;
//leave this sync
public IEnumerable<BaseItem> Serialise(Base obj, bool skipCacheRead, CancellationToken cancellationToken)
public IEnumerable<BaseItem> Serialise(
Base obj,
IReadOnlyDictionary<Id, NodeInfo> childInfo,
bool skipCacheRead,
CancellationToken cancellationToken
)
{
if (!skipCacheRead && obj.id != null)
{
@@ -33,7 +38,7 @@ public class BaseSerializer(
}
}
using var serializer2 = objectSerializerFactory.Create(cancellationToken);
using var serializer2 = objectSerializerFactory.Create(childInfo, cancellationToken);
var items = _pool.Get();
try
{
@@ -20,10 +20,10 @@ public sealed class ObjectSaver(
ISqLiteJsonCacheManager sqLiteJsonCacheManager,
IServerObjectManager serverObjectManager,
ILogger<ObjectSaver> logger,
SerializeProcessOptions options,
CancellationToken cancellationToken
CancellationToken cancellationToken,
#pragma warning disable CS9107
#pragma warning disable CA2254
SerializeProcessOptions? options = null
) : ChannelSaver<BaseItem>, IObjectSaver
#pragma warning restore CA2254
#pragma warning restore CS9107
@@ -100,9 +100,9 @@ public sealed class ObjectSaver(
{
if (!_options.SkipCacheWrite && batch.Count != 0)
{
sqLiteJsonCacheManager.SaveObjects(batch.Select(x => (x.Id.Value, x.Json.Value)));
Interlocked.Add(ref _cached, batch.Count);
progress?.Report(new(ProgressEvent.CachedToLocal, _cached, _objectsSerialized));
sqLiteJsonCacheManager.SaveObjects(batch.Select(x => (x.Id.Value, x.Json.Value)));
}
}
catch (OperationCanceledException)
@@ -26,6 +26,8 @@ public sealed class ObjectSerializer : IObjectSerializer
{
private HashSet<object> _parentObjects = new();
private readonly IReadOnlyDictionary<Id, NodeInfo> _childCache;
private readonly IBasePropertyGatherer _propertyGatherer;
private readonly CancellationToken _cancellationToken;
@@ -50,6 +52,7 @@ public sealed class ObjectSerializer : IObjectSerializer
/// <param name="cancellationToken"></param>
public ObjectSerializer(
IBasePropertyGatherer propertyGatherer,
IReadOnlyDictionary<Id, NodeInfo> childCache,
Pool<List<(Id, Json, Closures)>> chunksPool,
Pool<List<DataChunk>> chunks2Pool,
Pool<List<object?>> chunks3Pool,
@@ -57,6 +60,7 @@ public sealed class ObjectSerializer : IObjectSerializer
)
{
_propertyGatherer = propertyGatherer;
_childCache = childCache;
_chunksPool = chunksPool;
_chunks2Pool = chunks2Pool;
_chunks3Pool = chunks3Pool;
@@ -295,14 +299,28 @@ public sealed class ObjectSerializer : IObjectSerializer
private (Id, Json)? SerializeDetachedBase(Base baseObj, Closures closures)
{
Closures childClosures = [];
var sb = Pools.StringBuilders.Get();
using var writer = new StringWriter(sb);
using var jsonWriter = SpeckleObjectSerializerPool.Instance.GetJsonTextWriter(writer);
var id = SerializeBaseWithClosures(baseObj, jsonWriter, childClosures, true);
var json = new Json(writer.ToString());
Pools.StringBuilders.Return(sb);
closures.IncrementClosures(childClosures);
Closures childClosures;
Id id;
Json json;
//avoid multiple serialization to get closures
if (baseObj.id != null && _childCache.TryGetValue(new(baseObj.id), out var info))
{
id = new Id(baseObj.id);
childClosures = info.GetClosures(_cancellationToken);
json = info.Json;
closures.IncrementClosures(childClosures);
}
else
{
childClosures = [];
var sb = Pools.StringBuilders.Get();
using var writer = new StringWriter(sb);
using var jsonWriter = SpeckleObjectSerializerPool.Instance.GetJsonTextWriter(writer);
id = SerializeBaseWithClosures(baseObj, jsonWriter, childClosures, true);
closures.IncrementClosures(childClosures);
json = new Json(writer.ToString());
Pools.StringBuilders.Return(sb);
}
var json2 = ReferenceGenerator.CreateReference(id);
closures.MergeClosure(id);
// add to obj refs to return
@@ -12,6 +12,6 @@ public class ObjectSerializerFactory(IBasePropertyGatherer propertyGatherer) : I
private readonly Pool<List<DataChunk>> _chunk2Pool = Pools.CreateListPool<DataChunk>();
private readonly Pool<List<object?>> _chunk3Pool = Pools.CreateListPool<object?>();
public IObjectSerializer Create(CancellationToken cancellationToken) =>
new ObjectSerializer(propertyGatherer, _chunkPool, _chunk2Pool, _chunk3Pool, cancellationToken);
public IObjectSerializer Create(IReadOnlyDictionary<Id, NodeInfo> baseCache, CancellationToken cancellationToken) =>
new ObjectSerializer(propertyGatherer, baseCache, _chunkPool, _chunk2Pool, _chunk3Pool, cancellationToken);
}
@@ -1,3 +1,4 @@
using System.Collections.Concurrent;
using System.Diagnostics.CodeAnalysis;
using Microsoft.Extensions.Logging;
using Speckle.InterfaceGenerator;
@@ -36,8 +37,8 @@ public sealed class SerializeProcess(
IBaseChildFinder baseChildFinder,
IBaseSerializer baseSerializer,
ILoggerFactory loggerFactory,
SerializeProcessOptions options,
CancellationToken cancellationToken
CancellationToken cancellationToken,
SerializeProcessOptions? options = null
) : ISerializeProcess
{
private static readonly Dictionary<Id, NodeInfo> EMPTY_CLOSURES = new();
@@ -63,8 +64,13 @@ public sealed class SerializeProcess(
ThreadPriority.BelowNormal,
Environment.ProcessorCount * 2
);
private readonly SerializeProcessOptions _options = options ?? new();
private readonly Pool<Dictionary<Id, NodeInfo>> _currentClosurePool = Pools.CreateDictionaryPool<Id, NodeInfo>();
private readonly Pool<ConcurrentDictionary<Id, NodeInfo>> _childClosurePool = Pools.CreateConcurrentDictionaryPool<
Id,
NodeInfo
>();
private readonly Pool<List<Task<Dictionary<Id, NodeInfo>>>> _taskResultPool = Pools.CreateListPool<
Task<Dictionary<Id, NodeInfo>>
@@ -107,13 +113,13 @@ public sealed class SerializeProcess(
try
{
var channelTask = objectSaver.Start(
options.MaxParallelism,
options.MaxHttpSendBatchSize,
options.MaxCacheBatchSize,
options?.MaxParallelism,
options?.MaxHttpSendBatchSize,
options?.MaxCacheBatchSize,
_processSource.Token
);
var findTotalObjectsTask = Task.CompletedTask;
if (!options.SkipFindTotalObjects)
if (!_options.SkipFindTotalObjects)
{
ThrowIfFailed();
findTotalObjectsTask = Task.Factory.StartNew(
@@ -219,6 +225,7 @@ public sealed class SerializeProcess(
return EMPTY_CLOSURES;
}
var childClosures = _childClosurePool.Get();
foreach (var childClosure in taskClosures)
{
if (IsCancelled())
@@ -227,6 +234,7 @@ public sealed class SerializeProcess(
}
foreach (var kvp in childClosure)
{
childClosures[kvp.Key] = kvp.Value;
if (IsCancelled())
{
return EMPTY_CLOSURES;
@@ -241,7 +249,7 @@ public sealed class SerializeProcess(
return EMPTY_CLOSURES;
}
var items = baseSerializer.Serialise(obj, options.SkipCacheRead, _processSource.Token);
var items = baseSerializer.Serialise(obj, childClosures, _options.SkipCacheRead, _processSource.Token);
if (IsCancelled())
{
@@ -249,27 +257,33 @@ public sealed class SerializeProcess(
}
var currentClosures = _currentClosurePool.Get();
Interlocked.Increment(ref _objectCount);
progress?.Report(new(ProgressEvent.FromCacheOrSerialized, _objectCount, Math.Max(_objectCount, _objectsFound)));
foreach (var item in items)
try
{
if (IsCancelled())
Interlocked.Increment(ref _objectCount);
progress?.Report(new(ProgressEvent.FromCacheOrSerialized, _objectCount, Math.Max(_objectCount, _objectsFound)));
foreach (var item in items)
{
return EMPTY_CLOSURES;
}
if (IsCancelled())
{
return EMPTY_CLOSURES;
}
if (item.NeedsStorage)
{
Interlocked.Increment(ref _objectsSerialized);
await objectSaver.SaveAsync(item).ConfigureAwait(false);
}
if (item.NeedsStorage)
{
Interlocked.Increment(ref _objectsSerialized);
await objectSaver.SaveAsync(item).ConfigureAwait(false);
}
if (!currentClosures.ContainsKey(item.Id))
{
currentClosures.Add(item.Id, new NodeInfo(item.Json, item.Closures));
if (!currentClosures.ContainsKey(item.Id))
{
currentClosures.Add(item.Id, new NodeInfo(item.Json, item.Closures));
}
}
}
finally
{
_childClosurePool.Return(childClosures);
}
return currentClosures;
}
@@ -44,14 +44,13 @@ public class SerializeProcessFactory(
sqLiteJsonCacheManager,
serverObjectManager,
loggerFactory.CreateLogger<ObjectSaver>(),
options ?? new SerializeProcessOptions(),
cancellationToken
),
baseChildFinder,
new BaseSerializer(sqLiteJsonCacheManager, objectSerializerFactory),
loggerFactory,
options ?? new SerializeProcessOptions(),
cancellationToken
cancellationToken,
options
);
public ISerializeProcess CreateSerializeProcess(
@@ -20,7 +20,7 @@ internal sealed class ProgressStream(
{
int n = _stream.Read(buffer, offset, count);
_position += n;
progress?.Report(new(ProgressEvent.DownloadBytes, n, streamLength));
progress?.Report(new(ProgressEvent.DownloadBytes, _position, streamLength));
return n;
}
@@ -28,7 +28,7 @@ internal sealed class ProgressStream(
{
_stream.Write(buffer, offset, count);
_position += count;
progress?.Report(new(ProgressEvent.UploadBytes, count, streamLength));
progress?.Report(new(ProgressEvent.UploadBytes, _position, streamLength));
}
public override bool CanRead => true;
@@ -18,7 +18,10 @@ public sealed class ObjectsSerializationTest
private static IReadOnlyList<(Id, Json, Dictionary<Id, int>)> Serialize(Base data)
{
using var serializer = new ObjectSerializerFactory(new BasePropertyGatherer()).Create(default);
using var serializer = new ObjectSerializerFactory(new BasePropertyGatherer()).Create(
new Dictionary<Id, NodeInfo>(),
default
);
return serializer.Serialize(data).ToList();
}
@@ -41,7 +41,7 @@ public class DataObjectTests
new DummyServerObjectManager(),
null,
default,
new SerializeProcessOptions(false, false, true, true)
new SerializeProcessOptions(true, true, false, true)
);
await serializeProcess.Serialize(x);
await VerifyJson(json.Single().Value.Value).UseParameters(type);
@@ -41,7 +41,7 @@ public class DetachedTests
objects,
null,
default,
new SerializeProcessOptions(true, true, false, true)
new SerializeProcessOptions(false, false, true, true)
);
await serializeProcess.Serialize(@base);
@@ -123,7 +123,7 @@ public class DetachedTests
objects,
null,
default,
new SerializeProcessOptions(true, true, false, true) { MaxParallelism = 1, MaxHttpSendBatchSize = 1 }
new SerializeProcessOptions(false, false, true, true) { MaxParallelism = 1, MaxHttpSendBatchSize = 1 }
);
var results = await serializeProcess.Serialize(@base);
@@ -150,7 +150,7 @@ public class DetachedTests
objects,
null,
default,
new SerializeProcessOptions(true, true, false, true) { MaxParallelism = 1, MaxHttpSendBatchSize = 1 }
new SerializeProcessOptions(false, false, true, true) { MaxParallelism = 1, MaxHttpSendBatchSize = 1 }
);
var results = await serializeProcess.Serialize(@base);
@@ -172,7 +172,7 @@ public class DetachedTests
objects,
null,
default,
new SerializeProcessOptions(true, true, false, true) { MaxParallelism = 1, MaxHttpSendBatchSize = 1 }
new SerializeProcessOptions(false, false, true, true) { MaxParallelism = 1, MaxHttpSendBatchSize = 1 }
);
var results = await serializeProcess.Serialize(@base);
@@ -239,7 +239,7 @@ public class DetachedTests
objects,
null,
default,
new SerializeProcessOptions(true, true, false, true)
new SerializeProcessOptions(false, false, true, true)
);
var results = await serializeProcess.Serialize(@base);
@@ -272,7 +272,7 @@ public class DetachedTests
objects,
null,
default,
new SerializeProcessOptions(true, true, false, true)
new SerializeProcessOptions(false, false, true, true)
);
var results = await serializeProcess.Serialize(@base);
await VerifyJsonDictionary(objects);
@@ -203,7 +203,7 @@ public class ExceptionTests
public void Test_SpeckleSerializerException()
{
var factory = new ObjectSerializerFactory(new BasePropertyGatherer());
var serializer = factory.Create(default);
var serializer = factory.Create(new Dictionary<Id, NodeInfo>(), default);
Assert.Throws<SpeckleSerializeException>(() =>
{
var _ = serializer.Serialize(new BadBase()).ToList();
@@ -3,6 +3,7 @@ using Speckle.Objects.Primitive;
using Speckle.Sdk.Host;
using Speckle.Sdk.Models;
using Speckle.Sdk.Models.Extensions;
using Speckle.Sdk.Serialisation;
using Speckle.Sdk.Serialisation.V2.Send;
namespace Speckle.Sdk.Serialization.Tests;
@@ -19,7 +20,10 @@ public class ExternalIdTests
public async Task ExternalIdTest_Detached()
{
var p = new Polyline() { units = "cm", value = [1, 2] };
using var serializer = new ObjectSerializerFactory(new BasePropertyGatherer()).Create(default);
using var serializer = new ObjectSerializerFactory(new BasePropertyGatherer()).Create(
new Dictionary<Id, NodeInfo>(),
default
);
var objects = serializer.Serialize(p).ToDictionary(x => x.Item1, x => x.Item2);
await VerifyJsonDictionary(objects);
@@ -41,7 +45,10 @@ public class ExternalIdTests
knots = [],
weights = [],
};
using var serializer = new ObjectSerializerFactory(new BasePropertyGatherer()).Create(default);
using var serializer = new ObjectSerializerFactory(new BasePropertyGatherer()).Create(
new Dictionary<Id, NodeInfo>(),
default
);
var objects = serializer.Serialize(curve).ToDictionary(x => x.Item1, x => x.Item2);
await VerifyJsonDictionary(objects);
@@ -64,7 +71,10 @@ public class ExternalIdTests
weights = [],
};
var polycurve = new Polycurve() { segments = [curve], units = "cm" };
using var serializer = new ObjectSerializerFactory(new BasePropertyGatherer()).Create(default);
using var serializer = new ObjectSerializerFactory(new BasePropertyGatherer()).Create(
new Dictionary<Id, NodeInfo>(),
default
);
var objects = serializer.Serialize(polycurve).ToDictionary(x => x.Item1, x => x.Item2);
await VerifyJsonDictionary(objects);
@@ -89,7 +99,10 @@ public class ExternalIdTests
var polycurve = new Polycurve() { segments = [curve], units = "cm" };
var @base = new Base();
@base.SetDetachedProp("profile", polycurve);
using var serializer = new ObjectSerializerFactory(new BasePropertyGatherer()).Create(default);
using var serializer = new ObjectSerializerFactory(new BasePropertyGatherer()).Create(
new Dictionary<Id, NodeInfo>(),
default
);
var objects = serializer.Serialize(@base).ToDictionary(x => x.Item1, x => x.Item2);
await VerifyJsonDictionary(objects);
}
@@ -39,7 +39,7 @@ public abstract class PrimitiveTestFixture
}.Select(x => new object[] { x });
public static Half[] Float16TestCases { get; } =
[default, Half.Epsilon, Half.MaxValue, Half.MinValue, Half.PositiveInfinity, Half.NegativeInfinity, Half.NaN];
[default, Half.Epsilon, Half.MaxValue, Half.MinValue, Half.PositiveInfinity, Half.NegativeInfinity, Half.NaN];
public static float[] FloatIntegralTestCases { get; } = [0, 1, int.MaxValue, int.MinValue];
@@ -31,7 +31,6 @@ public class SerializeProcessRecordExceptionTests : MoqTest
baseChildFinderMock.Object,
baseSerializerMock.Object,
loggerFactoryMock.Object,
new(),
cts.Token
);
var ex = new Exception("Test error");
@@ -68,7 +67,6 @@ public class SerializeProcessRecordExceptionTests : MoqTest
baseChildFinderMock.Object,
baseSerializerMock.Object,
loggerFactoryMock.Object,
new(),
cts.Token
);
var ex = new OperationCanceledException();
@@ -100,7 +98,6 @@ public class SerializeProcessRecordExceptionTests : MoqTest
baseChildFinderMock.Object,
baseSerializerMock.Object,
loggerFactoryMock.Object,
new(),
cts.Token
);
var ex = new AggregateException(new OperationCanceledException());