Skip to content

Commit

Permalink
Merge pull request #31 from LSViana/30-create-the-stickyindex-bindings
Browse files Browse the repository at this point in the history
Create the StickyIndex bindings
  • Loading branch information
LSViana authored Sep 13, 2023
2 parents 68f1b7a + 0378b11 commit 5c51f76
Show file tree
Hide file tree
Showing 14 changed files with 553 additions and 1 deletion.
1 change: 1 addition & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ dotnet_diagnostic.SA1101.severity = suggestion # Prefix local calls with this

# Ordering rules
dotnet_diagnostic.SA1200.severity = suggestion # Using directives should be placed correctly
dotnet_diagnostic.SA1204.severity = suggestion # Static elements should appear before instance elements

# Maintainability rules
dotnet_diagnostic.SA1407.severity = suggestion # Arithmetic expressions should declare precedence
Expand Down
46 changes: 46 additions & 0 deletions Tests/YDotNet.Tests.Unit/StickyIndexes/AssociationTypeTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
using NUnit.Framework;
using YDotNet.Document;
using YDotNet.Document.StickyIndexes;

namespace YDotNet.Tests.Unit.StickyIndexes;

public class AssociationTypeTests
{
[Test]
public void ReturnsCorrectlyWithBefore()
{
// Arrange
var doc = new Doc();
var text = doc.Text("text");

var transaction = doc.WriteTransaction();
text.Insert(transaction, 0, "Lucas");
var stickyIndex = text.StickyIndex(transaction, 3, StickyAssociationType.Before);
transaction.Commit();

// Act
var associationType = stickyIndex.AssociationType;

// Assert
Assert.That(associationType, Is.EqualTo(StickyAssociationType.Before));
}

[Test]
public void ReturnsCorrectlyWithAfter()
{
// Arrange
var doc = new Doc();
var text = doc.Text("text");

var transaction = doc.WriteTransaction();
text.Insert(transaction, 0, "Lucas");
var stickyIndex = text.StickyIndex(transaction, 3, StickyAssociationType.After);
transaction.Commit();

// Act
var associationType = stickyIndex.AssociationType;

// Assert
Assert.That(associationType, Is.EqualTo(StickyAssociationType.After));
}
}
62 changes: 62 additions & 0 deletions Tests/YDotNet.Tests.Unit/StickyIndexes/DecodeTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
using NUnit.Framework;
using YDotNet.Document;
using YDotNet.Document.Options;
using YDotNet.Document.StickyIndexes;

namespace YDotNet.Tests.Unit.StickyIndexes;

public class DecodeTests
{
[Test]
public void DecodesFromEmptyValue()
{
// Arrange
var doc = new Doc(
new DocOptions
{
Id = 91
});
var text = doc.Text("text");

var transaction = doc.WriteTransaction();
var stickyIndex = text.StickyIndex(transaction, index: 0, StickyAssociationType.Before);
transaction.Commit();

// Act
transaction = doc.WriteTransaction();
var decodedStickyIndex = StickyIndex.Decode(stickyIndex.Encode());
var index = decodedStickyIndex?.Read(transaction);
transaction.Commit();

// Assert
Assert.That(decodedStickyIndex, Is.Not.Null);
Assert.That(index, Is.EqualTo(expected: 0));
}

[Test]
public void DecodesOnFilledValue()
{
// Arrange
var doc = new Doc(
new DocOptions
{
Id = 73
});
var text = doc.Text("text");

var transaction = doc.WriteTransaction();
text.Insert(transaction, index: 0, "Lucas");
var stickyIndex = text.StickyIndex(transaction, index: 3, StickyAssociationType.Before);
transaction.Commit();

// Act
transaction = doc.WriteTransaction();
var decodedStickyIndex = StickyIndex.Decode(stickyIndex.Encode());
var index = decodedStickyIndex?.Read(transaction);
transaction.Commit();

// Assert
Assert.That(decodedStickyIndex, Is.Not.Null);
Assert.That(index, Is.EqualTo(expected: 3));
}
}
54 changes: 54 additions & 0 deletions Tests/YDotNet.Tests.Unit/StickyIndexes/EncodeTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
using NUnit.Framework;
using YDotNet.Document;
using YDotNet.Document.Options;
using YDotNet.Document.StickyIndexes;

namespace YDotNet.Tests.Unit.StickyIndexes;

public class EncodeTests
{
[Test]
public void EncodesOnEmptyValue()
{
// Arrange
var doc = new Doc(
new DocOptions
{
Id = 91
});
var text = doc.Text("text");

var transaction = doc.WriteTransaction();
var stickyIndex = text.StickyIndex(transaction, index: 0, StickyAssociationType.Before);
transaction.Commit();

// Act
var result = stickyIndex.Encode();

// Assert
Assert.That(result, Is.EqualTo(new byte[] { 1, 4, 116, 101, 120, 116, 65 }));
}

[Test]
public void EncodesOnFilledValue()
{
// Arrange
var doc = new Doc(
new DocOptions
{
Id = 73
});
var text = doc.Text("text");

var transaction = doc.WriteTransaction();
text.Insert(transaction, index: 0, "Lucas");
var stickyIndex = text.StickyIndex(transaction, index: 3, StickyAssociationType.Before);
transaction.Commit();

// Act
var result = stickyIndex.Encode();

// Assert
Assert.That(result, Is.EqualTo(new byte[] { 0, 73, 2, 65 }));
}
}
126 changes: 126 additions & 0 deletions Tests/YDotNet.Tests.Unit/StickyIndexes/ReadTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
using NUnit.Framework;
using YDotNet.Document;
using YDotNet.Document.Cells;
using YDotNet.Document.StickyIndexes;

namespace YDotNet.Tests.Unit.StickyIndexes;

public class ReadTests
{
[Test]
public void ReadIndexFromText()
{
// Arrange
var doc = new Doc();
var text = doc.Text("text");

var transaction = doc.WriteTransaction();
text.Insert(transaction, index: 0, "Lucas");
var stickyIndexBefore = text.StickyIndex(transaction, index: 3, StickyAssociationType.Before);
var stickyIndexAfter = text.StickyIndex(transaction, index: 3, StickyAssociationType.After);
transaction.Commit();

// Act
transaction = doc.ReadTransaction();
var beforeIndex = stickyIndexBefore.Read(transaction);
var afterIndex = stickyIndexAfter.Read(transaction);
transaction.Commit();

// Assert
Assert.That(beforeIndex, Is.EqualTo(expected: 3));
Assert.That(afterIndex, Is.EqualTo(expected: 3));

// Act
transaction = doc.WriteTransaction();
text.Insert(transaction, index: 3, "(");
text.Insert(transaction, index: 5, ")");
text.Insert(transaction, index: 7, " Viana");
text.Insert(transaction, index: 0, "Hello, ");
beforeIndex = stickyIndexBefore.Read(transaction);
afterIndex = stickyIndexAfter.Read(transaction);
transaction.Commit();

// Assert
Assert.That(beforeIndex, Is.EqualTo(expected: 10));
Assert.That(afterIndex, Is.EqualTo(expected: 11));
}

[Test]
public void ReadIndexFromArray()
{
// Arrange
var doc = new Doc();
var array = doc.Array("array");

var transaction = doc.WriteTransaction();
array.InsertRange(
transaction, index: 0, new[] { Input.Long(value: 2469L), Input.Null(), Input.Boolean(value: false) });
var stickyIndexBefore = array.StickyIndex(transaction, index: 1, StickyAssociationType.Before);
var stickyIndexAfter = array.StickyIndex(transaction, index: 1, StickyAssociationType.After);
transaction.Commit();

// Act
transaction = doc.ReadTransaction();
var beforeIndex = stickyIndexBefore.Read(transaction);
var afterIndex = stickyIndexAfter.Read(transaction);
transaction.Commit();

// Assert
Assert.That(beforeIndex, Is.EqualTo(expected: 1));
Assert.That(afterIndex, Is.EqualTo(expected: 1));

// Act
transaction = doc.WriteTransaction();
array.InsertRange(transaction, index: 1, new[] { Input.String("(") });
array.InsertRange(transaction, index: 3, new[] { Input.String(")") });
array.InsertRange(transaction, index: 4, new[] { Input.String(" Viana") });
array.InsertRange(transaction, index: 0, new[] { Input.String("Hello, ") });
beforeIndex = stickyIndexBefore.Read(transaction);
afterIndex = stickyIndexAfter.Read(transaction);
transaction.Commit();

// Assert
Assert.That(beforeIndex, Is.EqualTo(expected: 2));
Assert.That(afterIndex, Is.EqualTo(expected: 3));
}

[Test]
public void ReadIndexFromXmlText()
{
// Arrange
var doc = new Doc();
var xmlText = doc.XmlText("xml-text");

var transaction = doc.WriteTransaction();
xmlText.Insert(transaction, index: 0, "Lucas");
var stickyIndexBefore = xmlText.StickyIndex(transaction, index: 3, StickyAssociationType.Before);
var stickyIndexAfter = xmlText.StickyIndex(transaction, index: 3, StickyAssociationType.After);
transaction.Commit();

// Act
transaction = doc.ReadTransaction();
var beforeIndex = stickyIndexBefore.Read(transaction);
var afterIndex = stickyIndexAfter.Read(transaction);
transaction.Commit();

// Assert
Assert.That(beforeIndex, Is.EqualTo(expected: 3));
Assert.That(afterIndex, Is.EqualTo(expected: 3));

// Act
transaction = doc.WriteTransaction();
xmlText.InsertAttribute(transaction, "bold", "true");
xmlText.Insert(transaction, index: 3, "(");
xmlText.Insert(transaction, index: 5, ")");
xmlText.Insert(transaction, index: 7, " Viana");
xmlText.Insert(transaction, index: 0, "Hello, ");
xmlText.InsertAttribute(transaction, "italics", "false");
beforeIndex = stickyIndexBefore.Read(transaction);
afterIndex = stickyIndexAfter.Read(transaction);
transaction.Commit();

// Assert
Assert.That(beforeIndex, Is.EqualTo(expected: 10));
Assert.That(afterIndex, Is.EqualTo(expected: 11));
}
}
65 changes: 65 additions & 0 deletions Tests/YDotNet.Tests.Unit/StickyIndexes/StickyIndexTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
using NUnit.Framework;
using YDotNet.Document;
using YDotNet.Document.StickyIndexes;

namespace YDotNet.Tests.Unit.StickyIndexes;

public class StickyIndexTests
{
[Test]
public void CreateFromText()
{
// Arrange
var doc = new Doc();
var text = doc.Text("text");

// Act
var transaction = doc.WriteTransaction();
var stickyIndexAfter = text.StickyIndex(transaction, index: 0, StickyAssociationType.After);
var stickyIndexBefore = text.StickyIndex(transaction, index: 0, StickyAssociationType.Before);
transaction.Commit();

// Assert
Assert.That(stickyIndexAfter, Is.Null);
Assert.That(stickyIndexBefore, Is.Not.Null);
Assert.That(stickyIndexBefore.Handle, Is.GreaterThan(nint.Zero));
}

[Test]
public void CreateFromArray()
{
// Arrange
var doc = new Doc();
var array = doc.Array("array");

// Act
var transaction = doc.WriteTransaction();
var stickyIndexAfter = array.StickyIndex(transaction, index: 0, StickyAssociationType.After);
var stickyIndexBefore = array.StickyIndex(transaction, index: 0, StickyAssociationType.Before);
transaction.Commit();

// Assert
Assert.That(stickyIndexAfter, Is.Null);
Assert.That(stickyIndexBefore, Is.Not.Null);
Assert.That(stickyIndexBefore.Handle, Is.GreaterThan(nint.Zero));
}

[Test]
public void CreateFromXmlText()
{
// Arrange
var doc = new Doc();
var xmlText = doc.XmlText("xml-text");

// Act
var transaction = doc.WriteTransaction();
var stickyIndexAfter = xmlText.StickyIndex(transaction, index: 0, StickyAssociationType.After);
var stickyIndexBefore = xmlText.StickyIndex(transaction, index: 0, StickyAssociationType.Before);
transaction.Commit();

// Assert
Assert.That(stickyIndexAfter, Is.Null);
Assert.That(stickyIndexBefore, Is.Not.Null);
Assert.That(stickyIndexBefore.Handle, Is.GreaterThan(nint.Zero));
}
}
28 changes: 28 additions & 0 deletions YDotNet/Document/StickyIndexes/StickyAssociationType.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
namespace YDotNet.Document.StickyIndexes;

/// <summary>
/// Association type used by a <see cref="StickyIndex" />.
/// </summary>
/// <remarks>
/// <para>
/// In general, a <see cref="StickyIndex" /> refers to a cursor space between two elements (eg. "ab.c" where "abc"
/// is our string and `.` is the <see cref="StickyIndex" /> placement).
/// </para>
/// <para>
/// In a situation when another client is updating a collection concurrently, a new set of elements may be inserted
/// into that space, expanding it in the result. In such case, the <see cref="StickyAssociationType" /> tells us if
/// the <see cref="StickyIndex" /> should stick to location before or after referenced index.
/// </para>
/// </remarks>
public enum StickyAssociationType : sbyte
{
/// <summary>
/// The corresponding <see cref="StickyIndex" /> points to space after the referenced element.
/// </summary>
After = 0,

/// <summary>
/// The corresponding <see cref="StickyIndex" /> points to space before the referenced element.
/// </summary>
Before = -1
}
Loading

0 comments on commit 5c51f76

Please sign in to comment.