@@ -1,36 +1,65 @@
using System.Text ;
#nullable enable
using System.Text ;
using JetBrains.Annotations ;
namespace Terminal.Gui.ViewsTests ;
public class HexViewTests
{
[Theory]
[InlineData (0, 4)]
[InlineData (4, 4)]
[InlineData (8, 4)]
[InlineData (35, 4)]
[InlineData (36, 8)]
[InlineData (37, 8)]
[InlineData (41, 8)]
[InlineData (54, 12)]
[InlineData (55, 12)]
[InlineData (71, 12)]
[InlineData (72, 16)]
[InlineData (73, 16)]
public void BytesPerLine_Calculates_Correctly ( int width , int expectedBpl )
{
var hv = new HexView ( LoadStream ( null , out long _ ) ) { Width = width , Height = 10 , AddressWidth = 0 } ;
hv . LayoutSubviews ( ) ;
Assert . Equal ( expectedBpl , hv . BytesPerLine ) ;
}
[Fact]
public void AllowEdits_Edits_ApplyEdits ( )
{
var hv = new HexView ( LoadStream ( true ) ) { Width = 20 , Height = 20 } ;
var hv = new HexView ( LoadStream ( null , out _ , true) ) { Width = 20 , Height = 20 } ;
Application . Navigation = new ApplicationNavigation ( ) ;
Application . Top = new Toplevel ( ) ;
Application . Top . Add ( hv ) ;
Application . Top . SetFocus ( ) ;
// Needed because HexView relies on LayoutComplete to calc sizes
hv . LayoutSubviews ( ) ;
Assert . True ( Application . RaiseKeyDownEvent ( Key . Tab ) ) ; // Move to left side
Assert . Empty ( hv . Edits ) ;
hv . AllowEdits = false ;
Assert . True ( hv . New KeyDownEvent ( Key . Home ) ) ;
Assert . False ( hv . New KeyDownEvent ( Key . A ) ) ;
Assert . True ( Application . Raise KeyDownEvent ( Key . Home ) ) ;
Assert . False ( Application . Raise KeyDownEvent ( Key . A ) ) ;
Assert . Empty ( hv . Edits ) ;
Assert . Equal ( 126 , hv . Source . Length ) ;
Assert . Equal ( 126 , hv . Source ! .Length ) ;
hv . AllowEdits = true ;
Assert . True ( hv . New KeyDownEvent ( Key . D4 ) ) ;
Assert . True ( hv . New KeyDownEvent ( Key . D1 ) ) ;
Assert . True ( Application . Raise KeyDownEvent ( Key . D4 ) ) ;
Assert . True ( Application . Raise KeyDownEvent ( Key . D1 ) ) ;
Assert . Single ( hv . Edits ) ;
Assert . Equal ( 65 , hv . Edits . ToList ( ) [ 0 ] . Value ) ;
Assert . Equal ( 'A' , ( char ) hv . Edits . ToList ( ) [ 0 ] . Value ) ;
Assert . Equal ( 126 , hv . Source . Length ) ;
// Appends byte
Assert . True ( hv . New KeyDownEvent ( Key . End ) ) ;
Assert . True ( hv . New KeyDownEvent ( Key . D4 ) ) ;
Assert . True ( hv . New KeyDownEvent ( Key . D2 ) ) ;
Assert . True ( Application . Raise KeyDownEvent ( Key . End ) ) ;
Assert . True ( Application . Raise KeyDownEvent ( Key . D4 ) ) ;
Assert . True ( Application . Raise KeyDownEvent ( Key . D2 ) ) ;
Assert . Equal ( 2 , hv . Edits . Count ) ;
Assert . Equal ( 66 , hv . Edits . ToList ( ) [ 1 ] . Value ) ;
Assert . Equal ( 'B' , ( char ) hv . Edits . ToList ( ) [ 1 ] . Value ) ;
@@ -39,11 +68,18 @@ public class HexViewTests
hv . ApplyEdits ( ) ;
Assert . Empty ( hv . Edits ) ;
Assert . Equal ( 127 , hv . Source . Length ) ;
Application . Top . Dispose ( ) ;
Application . ResetState ( true ) ;
}
[Fact]
public void ApplyEdits_With_Argument ( )
{
Application . Navigation = new ApplicationNavigation ( ) ;
Application . Top = new Toplevel ( ) ;
byte [ ] buffer = Encoding . Default . GetBytes ( "Fest" ) ;
var original = new MemoryStream ( ) ;
original . Write ( buffer , 0 , buffer . Length ) ;
@@ -53,28 +89,40 @@ public class HexViewTests
original . CopyTo ( copy ) ;
copy . Flush ( ) ;
var hv = new HexView ( copy ) { Width = Dim . Fill ( ) , Height = Dim . Fill ( ) } ;
Application . Top . Add ( hv ) ;
Application . Top . SetFocus ( ) ;
// Needed because HexView relies on LayoutComplete to calc sizes
hv . LayoutSubviews ( ) ;
var readBuffer = new byte [ hv . Source . Length ] ;
var readBuffer = new byte [ hv . Source ! .Length ] ;
hv . Source . Position = 0 ;
hv . Source . Read ( readBuffer ) ;
Assert . Equal ( "Fest" , Encoding . Default . GetString ( readBuffer ) ) ;
Assert . True ( hv . New KeyDownEvent ( Key . D5 ) ) ;
Assert . True ( hv . New KeyDownEvent ( Key . D4 ) ) ;
Assert . True ( Application . Raise KeyDownEvent ( Key . Tab ) ) ; // Move to left side
Assert . True ( Application . Raise KeyDownEvent ( Key . D5 ) ) ;
Assert . True ( Application . RaiseKeyDownEvent ( Key . D4 ) ) ;
readBuffer [ hv . Edits . ToList ( ) [ 0 ] . Key ] = hv . Edits . ToList ( ) [ 0 ] . Value ;
Assert . Equal ( "Test" , Encoding . Default . GetString ( readBuffer ) ) ;
Assert . True ( Application . RaiseKeyDownEvent ( Key . Tab ) ) ; // Move to right side
Assert . True ( Application . RaiseKeyDownEvent ( Key . CursorLeft ) ) ;
Assert . True ( Application . RaiseKeyDownEvent ( Key . Z . WithShift ) ) ;
readBuffer [ hv . Edits . ToList ( ) [ 0 ] . Key ] = hv . Edits . ToList ( ) [ 0 ] . Value ;
Assert . Equal ( "Zest" , Encoding . Default . GetString ( readBuffer ) ) ;
hv . ApplyEdits ( original ) ;
original . Position = 0 ;
original . Read ( buffer ) ;
copy . Position = 0 ;
copy . Read ( readBuffer ) ;
Assert . Equal ( "T est" , Encoding . Default . GetString ( buffer ) ) ;
Assert . Equal ( "T est" , Encoding . Default . GetString ( readBuffer ) ) ;
Assert . Equal ( "Z est" , Encoding . Default . GetString ( buffer ) ) ;
Assert . Equal ( "Z est" , Encoding . Default . GetString ( readBuffer ) ) ;
Assert . Equal ( Encoding . Default . GetString ( buffer ) , Encoding . Default . GetString ( readBuffer ) ) ;
Application . Top . Dispose ( ) ;
Application . ResetState ( true ) ;
}
[Fact]
@@ -94,69 +142,84 @@ public class HexViewTests
}
[Fact]
[AutoInitShutdown]
public void CursorPosition_Encoding_Default ( )
public void Position_Encoding_Default ( )
{
var hv = new HexView ( LoadStream ( ) ) { Width = Dim . Fill ( ) , Height = Dim . Fill ( ) } ;
var top = new Toplevel ( ) ;
top . Add ( hv ) ;
Application . Begin ( top ) ;
Application . Navigation = new ApplicationNavigation ( ) ;
Assert . Equal ( new ( 1 , 1 ) , hv . CursorPosition ) ;
var hv = new HexView ( LoadStream ( null , out _ ) ) { Width = 100 , Height = 100 } ;
Application . Top = new Toplevel ( ) ;
Application . Top . Add ( hv ) ;
Assert . True ( hv . NewKeyDownEvent ( Key . Tab ) ) ;
Assert . True ( hv . NewKeyDownEvent ( Key . CursorRight . WithCtrl ) ) ;
Assert . Equal ( hv . CursorPosition . X , hv . BytesPerLine ) ;
Assert . True ( hv . NewKeyDownEvent ( Key . Home ) ) ;
Application . Top . LayoutSubviews ( ) ;
Assert . True ( hv . NewKeyDownEvent ( Key . CursorRight ) ) ;
Assert . Equal ( new ( 2 , 1 ) , hv . CursorPosition ) ;
Assert . Equal ( 63 , hv . Source ! . Length ) ;
Assert . Equal ( 20 , hv . BytesPerLine ) ;
Assert . True ( hv . NewKeyDownEvent ( Key . CursorDown ) ) ;
Assert . Equal ( new ( 2 , 2 ) , hv . CursorPosition ) ;
Assert . Equal ( new ( 0 , 0 ) , hv . Position ) ;
Assert . True ( hv . New KeyDownEvent ( Key . End ) ) ;
int col = hv . Cursor Position. X ;
int line = hv . CursorPosition . Y ;
int off set = ( line - 1 ) * ( hv . BytesPerLine - col ) ;
Assert . Equal ( hv . Position , col * line + offset ) ;
top . Dispose ( ) ;
Assert . True ( Application . Raise KeyDownEvent ( Key . Tab ) ) ;
Assert . Equal ( new ( 0 , 0 ) , hv . Position ) ;
As ser t. True ( Application . RaiseKeyDownEvent ( Key . CursorRight . WithCtrl ) ) ;
Assert . Equal ( hv . BytesPerLine - 1 , hv . Position . X ) ;
Assert . True ( Application . RaiseKeyDownEvent ( Key . Home ) ) ;
Assert . True ( Application . RaiseKeyDownEvent ( Key . CursorRight ) ) ;
Assert . Equal ( new ( 1 , 0 ) , hv . Position ) ;
Assert . True ( Application . RaiseKeyDownEvent ( Key . CursorDown ) ) ;
Assert . Equal ( new ( 1 , 1 ) , hv . Position ) ;
Assert . True ( Application . RaiseKeyDownEvent ( Key . End ) ) ;
Assert . Equal ( new ( 3 , 3 ) , hv . Position ) ;
Assert . Equal ( hv . Source ! . Length , hv . Address ) ;
Application . Top . Dispose ( ) ;
Application . ResetState ( true ) ;
}
[Fact]
[AutoInitShutdown]
public void CursorPosition_Encoding_Unicode ( )
public void Position_Encoding_Unicode ( )
{
var hv = new HexView ( LoadStream ( true ) ) { Width = Dim . Fill ( ) , Height = Dim . Fill ( ) } ;
var top = new Toplevel ( ) ;
top . Add ( hv ) ;
Application . Begin ( top ) ;
Application . Navigation = new ApplicationNavigation ( ) ;
Assert . Equal ( new ( 1 , 1 ) , hv . CursorPosition ) ;
var hv = new HexView ( LoadStream ( null , out _ , unicode : true ) ) { Width = 100 , Height = 100 } ;
Application . Top = new Toplevel ( ) ;
Application . Top . Add ( hv ) ;
Assert . True ( hv . NewKeyDownEvent ( Key . Tab ) ) ;
Assert . True ( hv . NewKeyDownEvent ( Key . CursorRight . WithCtrl ) ) ;
Assert . Equal ( hv . CursorPosition . X , hv . BytesPerLine ) ;
Assert . True ( hv . NewKeyDownEvent ( Key . Home ) ) ;
hv . LayoutSubviews ( ) ;
Assert . True ( hv . NewKeyDownEvent ( Key . CursorRight ) ) ;
Assert . Equal ( new ( 2 , 1 ) , hv . CursorPosition ) ;
Assert . Equal ( 126 , hv . Source ! . Length ) ;
Assert . Equal ( 20 , hv . BytesPerLine ) ;
Assert . True ( hv . NewKeyDownEvent ( Key . CursorDown ) ) ;
Assert . Equal ( new ( 2 , 2 ) , hv . CursorPosition ) ;
Assert . Equal ( new ( 0 , 0 ) , hv . Position ) ;
Assert . True ( hv . New KeyDownEvent ( Key . End ) ) ;
int col = hv . CursorPosition . X ;
int line = hv . CursorPosition . Y ;
int off set = ( line - 1 ) * ( hv . BytesPerLine - col ) ;
Assert . Equal ( hv . Position , col * line + offset ) ;
top . Dispose ( ) ;
Assert . True ( Application . Raise KeyDownEvent ( Key . Tab ) ) ;
Assert . True ( Application . RaiseKeyDownEvent ( Key . CursorRight . WithCtrl ) ) ;
As ser t. Equal ( hv . BytesPerLine - 1 , hv . Position . X ) ;
Assert . True ( Application . RaiseKeyDownEvent ( Key . Home ) ) ;
Assert . True ( Application . RaiseKeyDownEvent ( Key . CursorRight ) ) ;
Assert . Equal ( new ( 1 , 0 ) , hv . Position ) ;
Assert . True ( Application . RaiseKeyDownEvent ( Key . CursorDown ) ) ;
Assert . Equal ( new ( 1 , 1 ) , hv . Position ) ;
Assert . True ( Application . RaiseKeyDownEvent ( Key . End ) ) ;
Assert . Equal ( new ( 6 , 6 ) , hv . Position ) ;
Assert . Equal ( hv . Source ! . Length , hv . Address ) ;
Application . Top . Dispose ( ) ;
Application . ResetState ( true ) ;
}
[Fact]
public void DiscardEdits_Method ( )
{
var hv = new HexView ( LoadStream ( true ) ) { Width = 20 , Height = 20 } ;
var hv = new HexView ( LoadStream ( null , out _ , true) ) { Width = 20 , Height = 20 } ;
// Needed because HexView relies on LayoutComplete to calc sizes
hv . LayoutSubviews ( ) ;
@@ -166,7 +229,7 @@ public class HexViewTests
Assert . Single ( hv . Edits ) ;
Assert . Equal ( 65 , hv . Edits . ToList ( ) [ 0 ] . Value ) ;
Assert . Equal ( 'A' , ( char ) hv . Edits . ToList ( ) [ 0 ] . Value ) ;
Assert . Equal ( 126 , hv . Source . Length ) ;
Assert . Equal ( 126 , hv . Source ! .Length ) ;
hv . DiscardEdits ( ) ;
Assert . Empty ( hv . Edits ) ;
@@ -175,7 +238,7 @@ public class HexViewTests
[Fact]
public void DisplayStart_Source ( )
{
var hv = new HexView ( LoadStream ( true ) ) { Width = 20 , Height = 20 } ;
var hv = new HexView ( LoadStream ( null , out _ , true) ) { Width = 20 , Height = 20 } ;
// Needed because HexView relies on LayoutComplete to calc sizes
hv . LayoutSubviews ( ) ;
@@ -184,7 +247,7 @@ public class HexViewTests
Assert . True ( hv . NewKeyDownEvent ( Key . PageDown ) ) ;
Assert . Equal ( 4 * hv . Frame . Height , hv . DisplayStart ) ;
Assert . Equal ( hv . Source . Length , hv . Source . Position ) ;
Assert . Equal ( hv . Source ! .Length , hv . Source . Position ) ;
Assert . True ( hv . NewKeyDownEvent ( Key . End ) ) ;
@@ -196,13 +259,13 @@ public class HexViewTests
[Fact]
public void Edited_Event ( )
{
var hv = new HexView ( LoadStream ( true ) ) { Width = 20 , Height = 20 } ;
var hv = new HexView ( LoadStream ( null , out _ , true) ) { Width = 20 , Height = 20 } ;
// Needed because HexView relies on LayoutComplete to calc sizes
hv . LayoutSubviews ( ) ;
KeyValuePair < long , byte > keyValuePair = default ;
hv . Edited + = ( s , e ) = > keyValuePair = new ( e . Position , e . NewValue ) ;
hv . Edited + = ( s , e ) = > keyValuePair = new ( e . Address , e . NewValue ) ;
Assert . True ( hv . NewKeyDownEvent ( Key . D4 ) ) ;
Assert . True ( hv . NewKeyDownEvent ( Key . D6 ) ) ;
@@ -220,231 +283,168 @@ public class HexViewTests
}
[Fact]
[AutoInitShutdown]
public void KeyBindings_Command ( )
public void KeyBindings_Test_Movement_LeftSide ( )
{
var hv = new HexView ( LoadStream ( ) ) { Width = 20 , Height = 10 } ;
var t op = new Toplevel ( ) ;
top . Add ( hv ) ;
Application . Begin ( top ) ;
Application . Navigation = new ApplicationNavigation ( ) ;
Application . T op = new Toplevel ( ) ;
var hv = new HexView ( LoadStream ( null , out _ ) ) { Width = 20 , Height = 10 } ;
Application . Top . Add ( hv ) ;
Assert . Equal ( 63 , hv . Source . Length ) ;
Assert . Equal ( 1 , hv . Position ) ;
hv . LayoutSubviews ( ) ;
Assert . Equal ( MEM_STRING_LENGTH , hv . Source ! . Length ) ;
Assert . Equal ( 0 , hv . Address ) ;
Assert . Equal ( 4 , hv . BytesPerLine ) ;
// right side only needed to press one time
Assert . True ( hv . New KeyDownEvent ( Key . Tab ) ) ;
// Default internal focus is on right side. Move back to left.
Assert . True ( Application . Raise KeyDownEvent ( Key . Tab . WithShift )) ;
Assert . True ( hv . New KeyDownEvent ( Key . CursorRight ) ) ;
Assert . Equal ( 2 , hv . Position ) ;
Assert . True ( Application . Raise KeyDownEvent ( Key . CursorRight ) ) ;
Assert . Equal ( 1 , hv . Address ) ;
Assert . True ( hv . New KeyDownEvent ( Key . CursorLeft ) ) ;
Assert . Equal ( 1 , hv . Position ) ;
Assert . True ( Application . Raise KeyDownEvent ( Key . CursorLeft ) ) ;
Assert . Equal ( 0 , hv . Address ) ;
Assert . True ( hv . New KeyDownEvent ( Key . CursorDown ) ) ;
Assert . Equal ( 5 , hv . Position ) ;
Assert . True ( Application . Raise KeyDownEvent ( Key . CursorDown ) ) ;
Assert . Equal ( 4 , hv . Address ) ;
Assert . True ( hv . New KeyDownEvent ( Key . CursorUp ) ) ;
Assert . Equal ( 1 , hv . Position ) ;
Assert . True ( Application . Raise KeyDownEvent ( Key . CursorUp ) ) ;
Assert . Equal ( 0 , hv . Address ) ;
Assert . True ( hv . New KeyDownEvent ( Key . V . WithCtrl ) ) ;
Assert . Equal ( 41 , hv . Position ) ;
Assert . True ( Application . Raise KeyDownEvent ( Key . PageDown ) ) ;
Assert . Equal ( 40 , hv . Address ) ;
Assert . True ( hv . NewKeyDownEvent ( new ( Key . V . WithAlt ) ) ) ;
Assert . Equal ( 1 , hv . Position ) ;
Assert . True ( Application . RaiseKeyDownEvent ( Key . PageUp ) ) ;
Assert . Equal ( 0 , hv . Address ) ;
Assert . True ( hv . New KeyDownEvent ( Key . PageDown ) ) ;
Assert . Equal ( 41 , hv . Position ) ;
Assert . True ( Application . Raise KeyDownEvent ( Key . End ) ) ;
Assert . Equal ( MEM_STRING_LENGTH , hv . Address ) ;
Assert . True ( hv . New KeyDownEvent ( Key . PageUp ) ) ;
Assert . Equal ( 1 , hv . Position ) ;
Assert . True ( Application . Raise KeyDownEvent ( Key . Home ) ) ;
Assert . Equal ( 0 , hv . Address ) ;
Assert . True ( hv . New KeyDownEvent ( Key . End ) ) ;
Assert . Equal ( 64 , hv . Position ) ;
Assert . True ( Application . Raise KeyDownEvent ( Key . CursorRight . WithCtrl ) ) ;
Assert . Equal ( 3 , hv . Address ) ;
Assert . True ( hv . New KeyDownEvent ( Key . Home ) ) ;
Assert . Equal ( 1 , hv . Position ) ;
Assert . True ( Application . Raise KeyDownEvent ( Key . CursorLeft . WithCtrl ) ) ;
Assert . Equal ( 0 , hv . Address ) ;
Assert . True ( hv . New KeyDownEvent ( Key . CursorRight . WithCtrl ) ) ;
Assert . Equal ( 4 , hv . Position ) ;
Assert . True ( Application . Raise KeyDownEvent ( Key . CursorDown . WithCtrl ) ) ;
Assert . Equal ( 36 , hv . Address ) ;
Assert . True ( hv . New KeyDownEvent ( Key . CursorLeft . WithCtrl ) ) ;
Assert . Equal ( 1 , hv . Position ) ;
Assert . True ( hv . NewKeyDownEvent ( Key . CursorDown . WithCtrl ) ) ;
Assert . Equal ( 37 , hv . Position ) ;
Assert . True ( hv . NewKeyDownEvent ( Key . CursorUp . WithCtrl ) ) ;
Assert . Equal ( 1 , hv . Position ) ;
top . Dispose ( ) ;
Assert . True ( Application . Raise KeyDownEvent ( Key . CursorUp . WithCtrl ) ) ;
Assert . Equal ( 0 , hv . Address ) ;
Application . Top . Dispose ( ) ;
Application . ResetState ( true ) ;
}
[Fact]
public void Position_Using_Encoding_Default ( )
{
var hv = new HexView ( LoadStream ( ) ) { Width = 20 , Height = 20 } ;
// Needed because HexView relies on LayoutComplete to calc sizes
hv . LayoutSubviews ( ) ;
Assert . Equal ( 63 , hv . Source . Length ) ;
Assert . Equal ( 63 , hv . Source . Position ) ;
Assert . Equal ( 1 , hv . Position ) ;
// left side needed to press twice
Assert . True ( hv . NewKeyDownEvent ( Key . CursorRight ) ) ;
Assert . Equal ( 63 , hv . Source . Position ) ;
Assert . Equal ( 1 , hv . Position ) ;
Assert . True ( hv . NewKeyDownEvent ( Key . CursorRight ) ) ;
Assert . Equal ( 63 , hv . Source . Position ) ;
Assert . Equal ( 2 , hv . Position ) ;
// right side only needed to press one time
Assert . True ( hv . NewKeyDownEvent ( Key . Tab ) ) ;
Assert . Equal ( 63 , hv . Source . Position ) ;
Assert . Equal ( 2 , hv . Position ) ;
Assert . True ( hv . NewKeyDownEvent ( Key . CursorLeft ) ) ;
Assert . Equal ( 63 , hv . Source . Position ) ;
Assert . Equal ( 1 , hv . Position ) ;
// last position is equal to the source length
Assert . True ( hv . NewKeyDownEvent ( Key . End ) ) ;
Assert . Equal ( 63 , hv . Source . Position ) ;
Assert . Equal ( 64 , hv . Position ) ;
Assert . Equal ( hv . Position - 1 , hv . Source . Length ) ;
}
[Fact]
public void Position_Using_Encoding_Unicode ( )
{
var hv = new HexView ( LoadStream ( true ) ) { Width = 20 , Height = 20 } ;
// Needed because HexView relies on LayoutComplete to calc sizes
hv . LayoutSubviews ( ) ;
Assert . Equal ( 126 , hv . Source . Length ) ;
Assert . Equal ( 126 , hv . Source . Position ) ;
Assert . Equal ( 1 , hv . Position ) ;
// left side needed to press twice
Assert . True ( hv . NewKeyDownEvent ( Key . CursorRight ) ) ;
Assert . Equal ( 126 , hv . Source . Position ) ;
Assert . Equal ( 1 , hv . Position ) ;
Assert . True ( hv . NewKeyDownEvent ( Key . CursorRight ) ) ;
Assert . Equal ( 126 , hv . Source . Position ) ;
Assert . Equal ( 2 , hv . Position ) ;
// right side only needed to press one time
Assert . True ( hv . NewKeyDownEvent ( Key . Tab ) ) ;
Assert . Equal ( 126 , hv . Source . Position ) ;
Assert . Equal ( 2 , hv . Position ) ;
Assert . True ( hv . NewKeyDownEvent ( Key . CursorLeft ) ) ;
Assert . Equal ( 126 , hv . Source . Position ) ;
Assert . Equal ( 1 , hv . Position ) ;
// last position is equal to the source length
Assert . True ( hv . NewKeyDownEvent ( Key . End ) ) ;
Assert . Equal ( 126 , hv . Source . Position ) ;
Assert . Equal ( 127 , hv . Position ) ;
Assert . Equal ( hv . Position - 1 , hv . Source . Length ) ;
}
[Fact]
[AutoInitShutdown]
public void PositionChanged_Event ( )
{
var hv = new HexView ( LoadStream ( ) ) { Width = Dim . Fill ( ) , Height = Dim . Fill ( ) } ;
HexViewEventArgs hexViewEventArgs = null ;
var hv = new HexView ( LoadStream ( null , out _ ) ) { Width = 20 , Height = 10 } ;
Application . Top = new Toplevel ( ) ;
Application . Top . Add ( hv ) ;
Application . Top . LayoutSubviews ( ) ;
HexViewEventArgs hexViewEventArgs = null ! ;
hv . PositionChanged + = ( s , e ) = > hexViewEventArgs = e ;
var top = new Toplevel ( ) ;
top . Add ( hv ) ;
Application . Begin ( top ) ;
Assert . Equal ( 4 , hv . BytesPerLine ) ;
Assert . True ( hv . NewKeyDownEvent ( Key . CursorRight ) ) ; // left side must press twice
Assert . True ( hv . NewKeyDownEvent ( Key . CursorRight ) ) ;
Assert . True ( hv . NewKeyDownEvent ( Key . CursorDown ) ) ;
Assert . Equal ( 12 , hexViewEventArgs . BytesPerLine ) ;
Assert . Equal ( new ( 2 , 2 ) , hexViewEventArgs . Cursor Position) ;
Assert . Equal ( 14 , hexViewEventArgs . Position ) ;
t op. Dispose ( ) ;
Assert . Equal ( 4 , hexViewEventArgs . BytesPerLine ) ;
Assert . Equal ( new ( 1 , 1 ) , hexViewEventArgs . Position ) ;
Assert . Equal ( 5 , hexViewEventArgs . Address ) ;
Application . T op. Dispose ( ) ;
Application . ResetState ( true ) ;
}
[Fact]
[AutoInitShutdown]
public void Source_Sets_DisplayStart_And_Position_To_Zero_If_Greater_Than_Source_Length ( )
{
var hv = new HexView ( LoadStream ( ) ) { Width = 10 , Height = 5 } ;
var t op = new Toplevel ( ) ;
t op. Add ( hv ) ;
Application . Begin ( top ) ;
var hv = new HexView ( LoadStream ( null , out _ ) ) { Width = 10 , Height = 5 } ;
Application . T op = new Toplevel ( ) ;
Application . T op. Add ( hv ) ;
hv . LayoutSubviews ( ) ;
Assert . True ( hv . NewKeyDownEvent ( Key . End ) ) ;
Assert . Equal ( 62 , hv . DisplayStart ) ;
Assert . Equal ( 64 , hv . Position ) ;
Assert . Equal ( MEM_STRING_LENGTH - 1 , hv . DisplayStart ) ;
Assert . Equal ( MEM_STRING_LENGTH , hv . Address ) ;
hv . Source = new MemoryStream ( ) ;
Assert . Equal ( 0 , hv . DisplayStart ) ;
Assert . Equal ( 0 , hv . Position - 1 ) ;
Assert . Equal ( 0 , hv . Address ) ;
hv . Source = LoadStream ( ) ;
hv . Source = LoadStream ( null , out _ ) ;
hv . Width = Dim . Fill ( ) ;
hv . Height = Dim . Fill ( ) ;
t op. LayoutSubviews ( ) ;
Application . T op. LayoutSubviews ( ) ;
Assert . Equal ( 0 , hv . DisplayStart ) ;
Assert . Equal ( 0 , hv . Position - 1 ) ;
Assert . Equal ( 0 , hv . Address ) ;
Assert . True ( hv . NewKeyDownEvent ( Key . End ) ) ;
Assert . Equal ( 0 , hv . DisplayStart ) ;
Assert . Equal ( 64 , hv . Position ) ;
Assert . Equal ( MEM_STRING_LENGTH , hv . Address ) ;
hv . Source = new MemoryStream ( ) ;
Assert . Equal ( 0 , hv . DisplayStart ) ;
Assert . Equal ( 0 , hv . Position - 1 ) ;
t op. Dispose ( ) ;
Assert . Equal ( 0 , hv . Address ) ;
Application . T op. Dispose ( ) ;
Application . ResetState ( true ) ;
}
private Stream LoadStream ( bool unicode = false )
private const string MEM_STRING = "Hello world.\nThis is a test of the Emergency Broadcast System.\n" ;
private const int MEM_STRING_LENGTH = 63 ;
private Stream LoadStream ( string? memString , out long numBytesInMemString , bool unicode = false )
{
var stream = new MemoryStream ( ) ;
byte [ ] bArray ;
var memString = "Hello world.\nThis is a test of the Emergency Broadcast System.\n" ;
Assert . Equal ( 63 , memString . Length ) ;
Assert . Equal ( MEM_STRING_LENGTH , MEM_STRING . Length ) ;
if ( memString is null )
{
memString = MEM_STRING ;
}
if ( unicode )
{
bArray = Encoding . Unicode . GetBytes ( memString ) ;
Assert . Equal ( 126 , bArray . Length ) ;
}
else
{
bArray = Encoding . Default . GetBytes ( memString ) ;
Assert . Equal ( 63 , bArray . Length ) ;
}
numBytesInMemString = bArray . Length ;
stream . Write ( bArray ) ;
return stream ;
}
private class NonSeekableStream : Stream
private class NonSeekableStream ( Stream baseStream ) : Stream
{
private readonly Stream m_stream ;
public NonSeekableStream ( Stream baseStream ) { m_stream = baseStream ; }
public override bool CanRead = > m_stream . CanRead ;
public override bool CanRead = > baseStream . CanRead ;
public override bool CanSeek = > false ;
public override bool CanWrite = > m_s tream. CanWrite ;
public override bool CanWrite = > baseS tream. CanWrite ;
public override long Length = > throw new NotSupportedException ( ) ;
public override long Position
{
get = > m_s tream. Position ;
get = > baseS tream. Position ;
set = > throw new NotSupportedException ( ) ;
}
public override void Flush ( ) { m_s tream. Flush ( ) ; }
public override int Read ( byte [ ] buffer , int offset , int count ) { return m_s tream. Read ( buffer , offset , count ) ; }
public override void Flush ( ) { baseS tream. Flush ( ) ; }
public override int Read ( byte [ ] buffer , int offset , int count ) { return baseS tream. Read ( buffer , offset , count ) ; }
public override long Seek ( long offset , SeekOrigin origin ) { throw new NotImplementedException ( ) ; }
public override void SetLength ( long value ) { throw new NotSupportedException ( ) ; }
public override void Write ( byte [ ] buffer , int offset , int count ) { m_s tream. Write ( buffer , offset , count ) ; }
public override void Write ( byte [ ] buffer , int offset , int count ) { baseS tream. Write ( buffer , offset , count ) ; }
}
}