4cc78c4bc9
* Use a stack channel for deserialization * multi-threaded * add object dictionary pool * more pooling * adjust sqlite transport * format * Optimize IsPropNameValid * object loader first pass * save test * add cache pre check * save better deserialize * mostly works * uses tasks but slower at end * rework to make more sense * add check to avoid multi-deserialize * modify max parallelism * async enqueuing of tasks * switch to more asyncenumerable * fmt * fmt * cleanup sqlite * make ServerObjectManager * revert change * add ability to skip cache check * cache json to know what is loaded * testing * clean up usage * clean up and added new op * Fix exception handling * fixing progress * remove codejam * Hides ObjectPool dependency * fmt * Use the 1.0 BCL async to try to be more compatible * rename to dependencies * Move Polly to internal dependencies * format * remove more old references * remove stackchannel * fixes for registration * remove console writeline * add cache check shortcut for root object * start refactoring send * recevie2 benchmark * add test for deserialize new * use channels for sending * test and fixes * Use same asyncinterfaces as Dynamo. Merge fixes * clean up * fix download object progress * put back from bad merge * intermediate commit: separating get child function from serializer * send didn't error * add channels * Use net48, netstandard2.1 and net8 * remove collection special case * have to make a tree of tasks even though it may serialize things twice * pre-id changing during serialize * need AsyncInterfaces for net48 :( * options changes * revert to netstandard2.0 and net8.0 * fix totals * revert httpcontext changes * format * clean up * active tasks works when accounting for id not being stable * add id tests * more fixes * works * format * Convert to BaseItem and use single SQLite checks to avoid locks * use locks and batch sqlite operations * hook up and handle null ids * remove unused parameter * remove progress from serializer itself * invert has objects call * readd object references * format * fix tests * remove active tasks check * bug fix for json cache * remove locks from sqlite * General Send test * add childclosures * redo extract all to be enumerable * group tests in projects * caching json does matter * cache checking should be managed by channels * format * Merge pull request #152 from specklesystems/new-json-test Uses a new objects test in Revit for serialization tests * add skip * add new roundtrip test * fix finish * clean up tests * check happens in serialize...don't do it twice * better progress reporting * fix progress reporting * only use detached properties when children gathering * move detached tests * add detached tests * fix merge * Fix progress change * fix more tests --------- Co-authored-by: Jedd Morgan <45512892+JR-Morgan@users.noreply.github.com> Co-authored-by: Claire Kuang <kuang.claire@gmail.com>
258 lines
7.2 KiB
C#
258 lines
7.2 KiB
C#
using System.Collections.Concurrent;
|
|
using System.Text;
|
|
using NUnit.Framework;
|
|
using Shouldly;
|
|
using Speckle.Newtonsoft.Json.Linq;
|
|
using Speckle.Sdk.Common;
|
|
using Speckle.Sdk.Dependencies.Serialization;
|
|
using Speckle.Sdk.Host;
|
|
using Speckle.Sdk.Models;
|
|
using Speckle.Sdk.Serialisation;
|
|
using Speckle.Sdk.Serialisation.V2;
|
|
using Speckle.Sdk.Serialisation.V2.Send;
|
|
using Speckle.Sdk.Transports;
|
|
|
|
namespace Speckle.Sdk.Tests.Unit.Models;
|
|
|
|
[TestFixture]
|
|
[TestOf(typeof(Base))]
|
|
[TestOf(typeof(DynamicBase))]
|
|
public class BaseTests
|
|
{
|
|
[SetUp]
|
|
public void Setup()
|
|
{
|
|
TypeLoader.Reset();
|
|
TypeLoader.Initialize(typeof(Base).Assembly, typeof(BaseTests).Assembly);
|
|
}
|
|
|
|
[Test]
|
|
public void CanGetSetDynamicItemProp()
|
|
{
|
|
var @base = new Base();
|
|
@base["Item"] = "Item";
|
|
|
|
Assert.That(@base["Item"], Is.EqualTo("Item"));
|
|
}
|
|
|
|
[Test]
|
|
public void CanGetSetTypedItemProp()
|
|
{
|
|
var @base = new ObjectWithItemProp { Item = "baz" };
|
|
|
|
Assert.That(@base["Item"], Is.EqualTo("baz"));
|
|
Assert.That(@base.Item, Is.EqualTo("baz"));
|
|
}
|
|
|
|
[Test(Description = "Checks if validation is performed in property names")]
|
|
public void CanValidatePropNames()
|
|
{
|
|
dynamic @base = new Base();
|
|
|
|
// Word chars are OK
|
|
@base["something"] = "B";
|
|
|
|
// Only single leading @ allowed
|
|
@base["@something"] = "A";
|
|
Assert.Throws<InvalidPropNameException>(() =>
|
|
{
|
|
@base["@@@something"] = "Testing";
|
|
});
|
|
|
|
// Invalid chars: ./
|
|
Assert.Throws<InvalidPropNameException>(() =>
|
|
{
|
|
@base["some.thing"] = "Testing";
|
|
});
|
|
Assert.Throws<InvalidPropNameException>(() =>
|
|
{
|
|
@base["some/thing"] = "Testing";
|
|
});
|
|
|
|
// Trying to change a class member value will throw exceptions.
|
|
//Assert.Throws<Exception>(() => { @base["speckle_type"] = "Testing"; });
|
|
//Assert.Throws<Exception>(() => { @base["id"] = "Testing"; });
|
|
}
|
|
|
|
[Test]
|
|
public void CountDynamicChunkables()
|
|
{
|
|
const int MAX_NUM = 3000;
|
|
var @base = new Base();
|
|
var customChunk = new List<double>();
|
|
var customChunkArr = new double[MAX_NUM];
|
|
|
|
for (int i = 0; i < MAX_NUM; i++)
|
|
{
|
|
customChunk.Add(i / 2);
|
|
customChunkArr[i] = i;
|
|
}
|
|
|
|
@base["@(1000)cc1"] = customChunk;
|
|
@base["@(1000)cc2"] = customChunkArr;
|
|
|
|
var num = @base.GetTotalChildrenCount();
|
|
Assert.That(num, Is.EqualTo(MAX_NUM / 1000 * 2 + 1));
|
|
}
|
|
|
|
[Test]
|
|
public void CountTypedChunkables()
|
|
{
|
|
const int MAX_NUM = 3000;
|
|
var @base = new SampleObject();
|
|
var customChunk = new List<double>();
|
|
var customChunkArr = new double[MAX_NUM];
|
|
|
|
for (int i = 0; i < MAX_NUM; i++)
|
|
{
|
|
customChunk.Add(i / 2);
|
|
customChunkArr[i] = i;
|
|
}
|
|
|
|
@base.list = customChunk;
|
|
@base.arr = customChunkArr;
|
|
|
|
var num = @base.GetTotalChildrenCount();
|
|
var actualNum = 1 + MAX_NUM / 300 + MAX_NUM / 1000;
|
|
Assert.That(num, Is.EqualTo(actualNum));
|
|
}
|
|
|
|
[Test(Description = "Checks that no ignored or obsolete properties are returned")]
|
|
public void CanGetMemberNames()
|
|
{
|
|
var @base = new SampleObject();
|
|
var dynamicProp = "dynamicProp";
|
|
@base[dynamicProp] = 123;
|
|
var names = @base.GetMembers().Keys;
|
|
Assert.That(names, Has.No.Member(nameof(@base.IgnoredSchemaProp)));
|
|
Assert.That(names, Has.No.Member(nameof(@base.ObsoleteSchemaProp)));
|
|
Assert.That(names, Has.Member(dynamicProp));
|
|
Assert.That(names, Has.Member(nameof(@base.attachedProp)));
|
|
}
|
|
|
|
[Test(Description = "Checks that only instance properties are returned, excluding obsolete and ignored.")]
|
|
public void CanGetMembers_OnlyInstance()
|
|
{
|
|
var @base = new SampleObject();
|
|
@base["dynamicProp"] = 123;
|
|
|
|
var names = @base.GetMembers(DynamicBaseMemberType.Instance).Keys;
|
|
Assert.That(names, Has.Member(nameof(@base.attachedProp)));
|
|
}
|
|
|
|
[Test(Description = "Checks that only dynamic properties are returned")]
|
|
public void CanGetMembers_OnlyDynamic()
|
|
{
|
|
var @base = new SampleObject();
|
|
var dynamicProp = "dynamicProp";
|
|
@base[dynamicProp] = 123;
|
|
|
|
var names = @base.GetMembers(DynamicBaseMemberType.Dynamic).Keys;
|
|
Assert.That(names, Has.Member(dynamicProp));
|
|
Assert.That(names, Has.Count.EqualTo(1));
|
|
}
|
|
|
|
[Test(Description = "Checks that all typed properties (including ignored ones) are returned")]
|
|
public void CanGetMembers_OnlyInstance_IncludeIgnored()
|
|
{
|
|
var @base = new SampleObject();
|
|
@base["dynamicProp"] = 123;
|
|
|
|
var names = @base.GetMembers(DynamicBaseMemberType.Instance | DynamicBaseMemberType.SchemaIgnored).Keys;
|
|
Assert.That(names, Has.Member(nameof(@base.IgnoredSchemaProp)));
|
|
Assert.That(names, Has.Member(nameof(@base.attachedProp)));
|
|
}
|
|
|
|
[Test(Description = "Checks that all typed properties (including obsolete ones) are returned")]
|
|
public void CanGetMembers_OnlyInstance_IncludeObsolete()
|
|
{
|
|
var @base = new SampleObject();
|
|
@base["dynamicProp"] = 123;
|
|
|
|
var names = @base.GetMembers(DynamicBaseMemberType.Instance | DynamicBaseMemberType.Obsolete).Keys;
|
|
Assert.That(names, Has.Member(nameof(@base.ObsoleteSchemaProp)));
|
|
Assert.That(names, Has.Member(nameof(@base.attachedProp)));
|
|
}
|
|
|
|
[Test]
|
|
public void CanGetDynamicMembers()
|
|
{
|
|
var @base = new SampleObject();
|
|
var dynamicProp = "dynamicProp";
|
|
@base[dynamicProp] = null;
|
|
|
|
var names = @base.GetDynamicMemberNames();
|
|
Assert.That(names, Has.Member(dynamicProp));
|
|
Assert.That(@base[dynamicProp], Is.Null);
|
|
}
|
|
|
|
[Test]
|
|
public void CanSetDynamicMembers()
|
|
{
|
|
var @base = new SampleObject();
|
|
var key = "dynamicProp";
|
|
var value = "something";
|
|
// Can create a new dynamic member
|
|
@base[key] = value;
|
|
Assert.That(value, Is.EqualTo((string)@base[key].NotNull()));
|
|
|
|
// Can overwrite existing
|
|
value = "some other value";
|
|
@base[key] = value;
|
|
Assert.That(value, Is.EqualTo((string)@base[key].NotNull()));
|
|
|
|
// Accepts null values
|
|
@base[key] = null;
|
|
Assert.That(@base[key], Is.Null);
|
|
}
|
|
|
|
[Test]
|
|
public void CanShallowCopy()
|
|
{
|
|
var sample = new SampleObject();
|
|
var copy = sample.ShallowCopy();
|
|
|
|
var selectedMembers =
|
|
DynamicBaseMemberType.Dynamic | DynamicBaseMemberType.Instance | DynamicBaseMemberType.SchemaIgnored;
|
|
var sampleMembers = sample.GetMembers(selectedMembers);
|
|
var copyMembers = copy.GetMembers(selectedMembers);
|
|
|
|
Assert.That(copyMembers.Keys, Is.EquivalentTo(sampleMembers.Keys));
|
|
Assert.That(copyMembers.Values, Is.EquivalentTo(sampleMembers.Values));
|
|
}
|
|
|
|
[SpeckleType("Speckle.Core.Tests.Unit.Models.BaseTests+SampleObject")]
|
|
public class SampleObject : Base
|
|
{
|
|
[Chunkable, DetachProperty]
|
|
public List<double> list { get; set; } = new();
|
|
|
|
[Chunkable(300), DetachProperty]
|
|
public double[] arr { get; set; }
|
|
|
|
[DetachProperty]
|
|
public SampleProp detachedProp { get; set; }
|
|
|
|
public SampleProp attachedProp { get; set; }
|
|
|
|
public string crazyProp { get; set; }
|
|
|
|
[SchemaIgnore]
|
|
public string IgnoredSchemaProp { get; set; }
|
|
|
|
[Obsolete("Use attached prop")]
|
|
public string ObsoleteSchemaProp { get; set; }
|
|
}
|
|
|
|
public class SampleProp
|
|
{
|
|
public string name { get; set; }
|
|
}
|
|
|
|
[SpeckleType("Speckle.Core.Tests.Unit.Models.BaseTests+ObjectWithItemProp")]
|
|
public class ObjectWithItemProp : Base
|
|
{
|
|
public string Item { get; set; } = "Item";
|
|
}
|
|
}
|