Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 10 additions & 10 deletions Sharpie.Tests/BaseCursesBackendTests.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright (c) 2022-2023, Alexandru Ciobanu
Copyright (c) 2022-2025, Alexandru Ciobanu, Jordan Hemming
All rights reserved.

Redistribution and use in source and binary forms, with or without
Expand Down Expand Up @@ -89,7 +89,7 @@ public void TestInitialize()
public void DecodeRawMouseButtonState_ParsesUsingMouseParser()
{
_backendMock.Setup(s => s.CursesMouseEventParser)
.Returns(CursesMouseEventParser.Get(2));
.Returns(CursesMouseEventParser.Get(CursesAbiVersion.NCurses6));

_backendMock.Setup(s => s.DecodeRawMouseButtonState(It.IsAny<uint>()))
.CallBase();
Expand All @@ -104,7 +104,7 @@ public void DecodeRawMouseButtonState_ParsesUsingMouseParser()
public void DecodeRawMouseButtonState_ReturnsDefault_IfNotParsed()
{
_backendMock.Setup(s => s.CursesMouseEventParser)
.Returns(CursesMouseEventParser.Get(2));
.Returns(CursesMouseEventParser.Get(CursesAbiVersion.NCurses6));

_backendMock.Setup(s => s.DecodeRawMouseButtonState(It.IsAny<uint>()))
.CallBase();
Expand Down Expand Up @@ -1139,7 +1139,7 @@ public void color_content_IsRelayedToLibrary(int ret)
[TestMethod, DataRow(0), DataRow(-1)]
public void mousemask_IsRelayedToLibrary(int ret)
{
var p = CursesMouseEventParser.Get(2);
var p = CursesMouseEventParser.Get(CursesAbiVersion.NCurses6);
_backendMock.Setup(s => s.CursesMouseEventParser)
.Returns(p);

Expand All @@ -1165,7 +1165,7 @@ public void mousemask_IsRelayedToLibrary(int ret)
public void mousemask_WhenUnix_CallsCursesButNotConsole_IfCursesFails()
{
_backendMock.Setup(s => s.CursesMouseEventParser)
.Returns(CursesMouseEventParser.Get(1));
.Returns(CursesMouseEventParser.Get(CursesAbiVersion.NCurses5));

_nativeSymbolResolverMock.MockResolve<BaseCursesFunctionMap.mousemask>()
.Setup(s => s(It.IsAny<uint>(), out It.Ref<uint>.IsAny))
Expand All @@ -1183,8 +1183,8 @@ public void mousemask_WhenUnix_CallsCursesButNotConsole_IfCursesFails()
_dotNetSystemAdapterMock.Verify(v => v.OutAndFlush(It.IsAny<string>()), Times.Never);
}

[TestMethod, SuppressMessage("ReSharper", "IdentifierTypo"), DataRow(1), DataRow(2)]
public void mousemask_WhenUnix_OutsToConsole_WhenReportingPosition(int abi)
[TestMethod, SuppressMessage("ReSharper", "IdentifierTypo"), DataRow(CursesAbiVersion.NCurses5), DataRow(CursesAbiVersion.NCurses6)]
public void mousemask_WhenUnix_OutsToConsole_WhenReportingPosition(CursesAbiVersion abi)
{
_nativeSymbolResolverMock.MockResolve<BaseCursesFunctionMap.mousemask, int>(
s => s(It.IsAny<uint>(), out It.Ref<uint>.IsAny), 0);
Expand All @@ -1199,8 +1199,8 @@ public void mousemask_WhenUnix_OutsToConsole_WhenReportingPosition(int abi)
_dotNetSystemAdapterMock.Verify(v => v.OutAndFlush("\x1b[?1003h"), Times.Once);
}

[TestMethod, SuppressMessage("ReSharper", "IdentifierTypo"), DataRow(1), DataRow(2)]
public void mousemask_WhenUnix_OutsToConsole_WhenAll(int abi)
[TestMethod, SuppressMessage("ReSharper", "IdentifierTypo"), DataRow(CursesAbiVersion.NCurses5), DataRow(CursesAbiVersion.NCurses6)]
public void mousemask_WhenUnix_OutsToConsole_WhenAll(CursesAbiVersion abi)
{
_nativeSymbolResolverMock.MockResolve<BaseCursesFunctionMap.mousemask, int>(
s => s(It.IsAny<uint>(), out It.Ref<uint>.IsAny), 0);
Expand All @@ -1222,7 +1222,7 @@ public void mousemask_WhenUnix_OutsToConsole_WhenNothing()
s => s(It.IsAny<uint>(), out It.Ref<uint>.IsAny), 0);

_backendMock.Setup(s => s.CursesMouseEventParser)
.Returns(CursesMouseEventParser.Get(1));
.Returns(CursesMouseEventParser.Get(CursesAbiVersion.NCurses5));

_backend.mousemask(0, out var _)
.ShouldBe(0);
Expand Down
82 changes: 73 additions & 9 deletions Sharpie.Tests/CursesMouseEventParserTests.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright (c) 2022-2023, Alexandru Ciobanu
Copyright (c) 2022-2025, Alexandru Ciobanu, Jordan Hemming
All rights reserved.

Redistribution and use in source and binary forms, with or without
Expand Down Expand Up @@ -35,6 +35,16 @@ public class CursesMouseEventParserTests
{
[TestMethod]
public void Get_ReturnsObject_ForAbi1()
{
var r = CursesMouseEventParser.Get(CursesAbiVersion.NCurses5);
r.ShouldNotBeNull();

r.ReportPosition.ShouldBe(8u << 24);
r.All.ShouldBe((8u << 24) - 1);
}

[TestMethod]
public void Get_ReturnsObject_ForAbi1_OldApi()
{
var r = CursesMouseEventParser.Get(1);
r.ShouldNotBeNull();
Expand All @@ -45,6 +55,16 @@ public void Get_ReturnsObject_ForAbi1()

[TestMethod]
public void Get_ReturnsObject_ForAbi2()
{
var r = CursesMouseEventParser.Get(CursesAbiVersion.NCurses6);
r.ShouldNotBeNull();

r.ReportPosition.ShouldBe(8u << 25);
r.All.ShouldBe((8u << 25) - 1);
}

[TestMethod]
public void Get_ReturnsObject_ForAbi2_OldApi()
{
var r = CursesMouseEventParser.Get(2);
r.ShouldNotBeNull();
Expand All @@ -53,11 +73,31 @@ public void Get_ReturnsObject_ForAbi2()
r.All.ShouldBe((8u << 25) - 1);
}

[TestMethod]
public void Get_ReturnsObject_ForPdCursesAbi()
{
var r = CursesMouseEventParser.Get(CursesAbiVersion.PdCurses);
r.ShouldNotBeNull();

r.ReportPosition.ShouldBe(1u << 29);
r.All.ShouldBe((1u << 29) - 1);
}

[TestMethod]
public void Get_ReturnsObject_ForPdCursesAbi_OldApi()
{
var r = CursesMouseEventParser.Get(3);
r.ShouldNotBeNull();

r.ReportPosition.ShouldBe(1u << 29);
r.All.ShouldBe((1u << 29) - 1);
}

[TestMethod]
public void Get_ReturnsAbi1_ForUnknownAbi()
{
CursesMouseEventParser.Get(-1)
.ShouldBe(CursesMouseEventParser.Get(1));
CursesMouseEventParser.Get(CursesAbiVersion.Unknown)
.ShouldBe(CursesMouseEventParser.Get(CursesAbiVersion.Unknown));
}

[TestMethod, DataRow(1u << ((1 - 1) * 6), MouseButton.Button1, MouseButtonState.Released),
Expand All @@ -82,7 +122,7 @@ public void Get_ReturnsAbi1_ForUnknownAbi()
DataRow(16u << ((4 - 1) * 6), MouseButton.Button4, MouseButtonState.TripleClicked)]
public void Parse_ParsesTheButtonAndState_ForAbi1(uint raw, MouseButton expButton, MouseButtonState expState)
{
var parser = CursesMouseEventParser.Get(1);
var parser = CursesMouseEventParser.Get(CursesAbiVersion.NCurses5);
var p = parser.Parse(raw);

p.ShouldBe((expButton, expState, ModifierKey.None));
Expand Down Expand Up @@ -115,7 +155,7 @@ public void Parse_ParsesTheButtonAndState_ForAbi1(uint raw, MouseButton expButto
DataRow(16u << ((5 - 1) * 5), MouseButton.Button5, MouseButtonState.TripleClicked)]
public void Parse_ParsesTheButtonAndState_ForAbi2(uint raw, MouseButton expButton, MouseButtonState expState)
{
var parser = CursesMouseEventParser.Get(2);
var parser = CursesMouseEventParser.Get(CursesAbiVersion.NCurses6);
var p = parser.Parse(raw);

p.ShouldBe((expButton, expState, ModifierKey.None));
Expand All @@ -130,7 +170,7 @@ public void Parse_ParsesTheButtonAndState_ForAbi2(uint raw, MouseButton expButto
DataRow((4u << 24) | (1u << 24) | (2u << 24), ModifierKey.Alt | ModifierKey.Shift | ModifierKey.Ctrl)]
public void Parse_ParsesTheModifiers_ForAbi1(uint raw, ModifierKey expMod)
{
var parser = CursesMouseEventParser.Get(1);
var parser = CursesMouseEventParser.Get(CursesAbiVersion.NCurses5);
var p = parser.Parse(raw | 1u);

p.ShouldBe((MouseButton.Button1, MouseButtonState.Released, expMod));
Expand All @@ -145,7 +185,22 @@ public void Parse_ParsesTheModifiers_ForAbi1(uint raw, ModifierKey expMod)
DataRow((4u << 25) | (1u << 25) | (2u << 25), ModifierKey.Alt | ModifierKey.Shift | ModifierKey.Ctrl)]
public void Parse_ParsesTheModifiers_ForAbi2(uint raw, ModifierKey expMod)
{
var parser = CursesMouseEventParser.Get(2);
var parser = CursesMouseEventParser.Get(CursesAbiVersion.NCurses6);
var p = parser.Parse(raw | 1u);

p.ShouldBe((MouseButton.Button1, MouseButtonState.Released, expMod));
}

[TestMethod, DataRow(0u, ModifierKey.None), DataRow(2u << 26, ModifierKey.Ctrl),
DataRow(1u << 26, ModifierKey.Shift), DataRow(4u << 26, ModifierKey.Alt),
DataRow((4u << 26) | (2u << 26), ModifierKey.Alt | ModifierKey.Ctrl),
DataRow((1u << 26) | (2u << 26), ModifierKey.Shift | ModifierKey.Ctrl),
DataRow((4u << 26) | (1u << 26), ModifierKey.Alt | ModifierKey.Shift),
DataRow((2u << 26) | (1u << 26), ModifierKey.Ctrl | ModifierKey.Shift),
DataRow((4u << 26) | (1u << 26) | (2u << 26), ModifierKey.Alt | ModifierKey.Shift | ModifierKey.Ctrl)]
public void Parse_ParsesTheModifiers_ForPdCursesAbi(uint raw, ModifierKey expMod)
{
var parser = CursesMouseEventParser.Get(CursesAbiVersion.PdCurses);
var p = parser.Parse(raw | 1u);

p.ShouldBe((MouseButton.Button1, MouseButtonState.Released, expMod));
Expand All @@ -154,7 +209,7 @@ public void Parse_ParsesTheModifiers_ForAbi2(uint raw, ModifierKey expMod)
[TestMethod, DataRow(0u), DataRow(8u << 24), DataRow(1u << 24)]
public void Parse_ReturnsNullIfNoButtonPresent_ForAbi1(uint raw)
{
var parser = CursesMouseEventParser.Get(1);
var parser = CursesMouseEventParser.Get(CursesAbiVersion.NCurses5);
var p = parser.Parse(raw);

p.ShouldBeNull();
Expand All @@ -163,7 +218,16 @@ public void Parse_ReturnsNullIfNoButtonPresent_ForAbi1(uint raw)
[TestMethod, DataRow(0u), DataRow(8u << 25), DataRow(1u << 25)]
public void Parse_ReturnsNullIfNoButtonPresent_ForAbi2(uint raw)
{
var parser = CursesMouseEventParser.Get(2);
var parser = CursesMouseEventParser.Get(CursesAbiVersion.NCurses6);
var p = parser.Parse(raw);

p.ShouldBeNull();
}

[TestMethod, DataRow(0u), DataRow(8u << 26), DataRow(1u << 26)]
public void Parse_ReturnsNullIfNoButtonPresent_ForPdCursesAbi(uint raw)
{
var parser = CursesMouseEventParser.Get(CursesAbiVersion.NCurses6);
var p = parser.Parse(raw);

p.ShouldBeNull();
Expand Down
6 changes: 3 additions & 3 deletions Sharpie.Tests/NCursesBackendTests.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright (c) 2022-2023, Alexandru Ciobanu
Copyright (c) 2022-2025, Alexandru Ciobanu, Jordan Hemming
All rights reserved.

Redistribution and use in source and binary forms, with or without
Expand Down Expand Up @@ -394,8 +394,8 @@ public void CursesMouseEventParser_ReturnsMouseParserBasedOnAbi(string ver, int
.Returns(h);

_backend.CursesMouseEventParser.ShouldBe(m == 2
? CursesMouseEventParser.Get(2)
: CursesMouseEventParser.Get(1));
? CursesMouseEventParser.Get(CursesAbiVersion.NCurses6)
: CursesMouseEventParser.Get(CursesAbiVersion.NCurses5));
}

[TestMethod]
Expand Down
6 changes: 3 additions & 3 deletions Sharpie.Tests/PdCursesBackendTests.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright (c) 2022-2023, Alexandru Ciobanu
Copyright (c) 2022-2025, Alexandru Ciobanu, Jordan Hemming
All rights reserved.

Redistribution and use in source and binary forms, with or without
Expand Down Expand Up @@ -310,9 +310,9 @@ public void getcchar_IsRelayedToLibrary(int ret)
}

[TestMethod]
public void CursesMouseEventParser_ReturnsMouseParserAbi2()
public void CursesMouseEventParser_ReturnsMouseParserPdCursesAbi()
{
_backend.CursesMouseEventParser.ShouldBe(CursesMouseEventParser.Get(2));
_backend.CursesMouseEventParser.ShouldBe(CursesMouseEventParser.Get(CursesAbiVersion.PdCurses));
}

[TestMethod, DataRow(VideoAttribute.None, 0), DataRow(VideoAttribute.StandOut, 0x00A00000),
Expand Down
6 changes: 3 additions & 3 deletions Sharpie.Tests/PdCursesMod32BackendTests.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright (c) 2022-2023, Alexandru Ciobanu
Copyright (c) 2022-2025, Alexandru Ciobanu, Jordan Hemming
All rights reserved.

Redistribution and use in source and binary forms, with or without
Expand Down Expand Up @@ -373,9 +373,9 @@ public void getcchar_IsRelayedToLibrary(int ret)
}

[TestMethod]
public void CursesMouseEventParser_ReturnsMouseParserAbi2()
public void CursesMouseEventParser_ReturnsMouseParserPdCursesAbi()
{
_backend.CursesMouseEventParser.ShouldBe(CursesMouseEventParser.Get(2));
_backend.CursesMouseEventParser.ShouldBe(CursesMouseEventParser.Get(CursesAbiVersion.PdCurses));
}

[TestMethod, DataRow(VideoAttribute.None, 0), DataRow(VideoAttribute.StandOut, 0x00A00000),
Expand Down
55 changes: 55 additions & 0 deletions Sharpie/Backend/CursesAbiVersion.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
Copyright (c) 2022-2025, Alexandru Ciobanu, Jordan Hemming
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.

2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.

3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

namespace Sharpie.Backend;

/// <summary>
/// Specifies the supported ABI versions for the Curses library.
/// Used for mouse event parsing.
/// </summary>
public enum CursesAbiVersion
{
/// <summary>
/// Unknown ABI version. Defaults to NCurses5.
/// </summary>
Unknown,
/// <summary>
/// NCurses 5 ABI version.
/// </summary>
NCurses5,
/// <summary>
/// NCurses 6 ABI version.
/// </summary>
NCurses6,
/// <summary>
/// PDCurses (and PDCursesMod) ABI version.
/// </summary>
PdCurses
}
Loading
Loading