Initialize CBDD solution and add a .NET-focused gitignore for generated artifacts.
This commit is contained in:
107
tests/CBDD.Tests/CursorTests.cs
Executable file
107
tests/CBDD.Tests/CursorTests.cs
Executable file
@@ -0,0 +1,107 @@
|
||||
using ZB.MOM.WW.CBDD.Core.Storage;
|
||||
using ZB.MOM.WW.CBDD.Core.Indexing;
|
||||
using ZB.MOM.WW.CBDD.Bson;
|
||||
using Xunit;
|
||||
|
||||
namespace ZB.MOM.WW.CBDD.Tests;
|
||||
|
||||
public class CursorTests : IDisposable
|
||||
{
|
||||
private readonly string _testFile;
|
||||
private readonly StorageEngine _storage;
|
||||
private readonly BTreeIndex _index;
|
||||
|
||||
public CursorTests()
|
||||
{
|
||||
_testFile = Path.Combine(Path.GetTempPath(), $"docdb_cursor_test_{Guid.NewGuid()}.db");
|
||||
_storage = new StorageEngine(_testFile, PageFileConfig.Default);
|
||||
|
||||
var options = IndexOptions.CreateBTree("test");
|
||||
_index = new BTreeIndex(_storage, options);
|
||||
|
||||
SeedData();
|
||||
}
|
||||
|
||||
private void SeedData()
|
||||
{
|
||||
var txnId = _storage.BeginTransaction().TransactionId;
|
||||
|
||||
// Insert 10, 20, 30
|
||||
_index.Insert(IndexKey.Create(10), new DocumentLocation(1, 0), txnId);
|
||||
_index.Insert(IndexKey.Create(20), new DocumentLocation(2, 0), txnId);
|
||||
_index.Insert(IndexKey.Create(30), new DocumentLocation(3, 0), txnId);
|
||||
|
||||
_storage.CommitTransaction(txnId);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MoveToFirst_ShouldPositionAtFirst()
|
||||
{
|
||||
using var cursor = _index.CreateCursor(0);
|
||||
cursor.MoveToFirst().ShouldBeTrue();
|
||||
cursor.Current.Key.ShouldBe(IndexKey.Create(10));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MoveToLast_ShouldPositionAtLast()
|
||||
{
|
||||
using var cursor = _index.CreateCursor(0);
|
||||
cursor.MoveToLast().ShouldBeTrue();
|
||||
cursor.Current.Key.ShouldBe(IndexKey.Create(30));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MoveNext_ShouldTraverseForward()
|
||||
{
|
||||
using var cursor = _index.CreateCursor(0);
|
||||
cursor.MoveToFirst();
|
||||
|
||||
cursor.MoveNext().ShouldBeTrue();
|
||||
cursor.Current.Key.ShouldBe(IndexKey.Create(20));
|
||||
|
||||
cursor.MoveNext().ShouldBeTrue();
|
||||
cursor.Current.Key.ShouldBe(IndexKey.Create(30));
|
||||
|
||||
cursor.MoveNext().ShouldBeFalse(); // End
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MovePrev_ShouldTraverseBackward()
|
||||
{
|
||||
using var cursor = _index.CreateCursor(0);
|
||||
cursor.MoveToLast();
|
||||
|
||||
cursor.MovePrev().ShouldBeTrue();
|
||||
cursor.Current.Key.ShouldBe(IndexKey.Create(20));
|
||||
|
||||
cursor.MovePrev().ShouldBeTrue();
|
||||
cursor.Current.Key.ShouldBe(IndexKey.Create(10));
|
||||
|
||||
cursor.MovePrev().ShouldBeFalse(); // Start
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Seek_ShouldPositionExact_OrNext()
|
||||
{
|
||||
using var cursor = _index.CreateCursor(0);
|
||||
|
||||
// Exact
|
||||
cursor.Seek(IndexKey.Create(20)).ShouldBeTrue();
|
||||
cursor.Current.Key.ShouldBe(IndexKey.Create(20));
|
||||
|
||||
// Non-exact (15 -> should land on 20)
|
||||
cursor.Seek(IndexKey.Create(15)).ShouldBeFalse();
|
||||
cursor.Current.Key.ShouldBe(IndexKey.Create(20));
|
||||
|
||||
// Non-exact (35 -> should be invalid/end)
|
||||
cursor.Seek(IndexKey.Create(35)).ShouldBeFalse();
|
||||
// Current should throw invalid
|
||||
Should.Throw<InvalidOperationException>(() => cursor.Current);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_storage.Dispose();
|
||||
if (File.Exists(_testFile)) File.Delete(_testFile);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user