Improve roundtrip verification tests and debug dump.
Add another round-trip verification. For both original and generated state, generate a diff from an initial, empty state. Verify that these two diffs are the same.
This commit is contained in:
@@ -176,6 +176,12 @@ void TransportSender<MyState>::tick( void )
|
|||||||
if ( current_state.compare( newstate ) ) {
|
if ( current_state.compare( newstate ) ) {
|
||||||
fprintf( stderr, "Warning, round-trip Instruction verification failed!\n" );
|
fprintf( stderr, "Warning, round-trip Instruction verification failed!\n" );
|
||||||
}
|
}
|
||||||
|
/* Also verify that both the original frame and generated frame have the same initial diff. */
|
||||||
|
std::string current_diff( current_state.init_diff() );
|
||||||
|
std::string new_diff( newstate.init_diff() );
|
||||||
|
if ( current_diff != new_diff ) {
|
||||||
|
fprintf( stderr, "Warning, target state Instruction verification failed!\n" );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( diff.empty() && (now >= next_ack_time) ) {
|
if ( diff.empty() && (now >= next_ack_time) ) {
|
||||||
|
|||||||
@@ -94,6 +94,11 @@ string Complete::diff_from( const Complete &existing ) const
|
|||||||
return output.SerializeAsString();
|
return output.SerializeAsString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
string Complete::init_diff( void ) const
|
||||||
|
{
|
||||||
|
return diff_from( Complete( get_fb().ds.get_width(), get_fb().ds.get_height() ));
|
||||||
|
}
|
||||||
|
|
||||||
void Complete::apply_string( string diff )
|
void Complete::apply_string( string diff )
|
||||||
{
|
{
|
||||||
HostBuffers::HostMessage input;
|
HostBuffers::HostMessage input;
|
||||||
@@ -174,22 +179,35 @@ int Complete::wait_time( uint64_t now ) const
|
|||||||
bool Complete::compare( const Complete &other ) const
|
bool Complete::compare( const Complete &other ) const
|
||||||
{
|
{
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
for ( int y = 0; y < terminal.get_fb().ds.get_height(); y++ ) {
|
const Framebuffer &fb = terminal.get_fb();
|
||||||
for ( int x = 0; x < terminal.get_fb().ds.get_width(); x++ ) {
|
const Framebuffer &other_fb = other.terminal.get_fb();
|
||||||
if ( terminal.get_fb().get_cell( y, x )->compare( *other.terminal.get_fb().get_cell( y, x ) ) ) {
|
const int height = fb.ds.get_height();
|
||||||
|
const int other_height = other_fb.ds.get_height();
|
||||||
|
const int width = fb.ds.get_width();
|
||||||
|
const int other_width = other_fb.ds.get_width();
|
||||||
|
|
||||||
|
if ( height != other_height || width != other_width ) {
|
||||||
|
fprintf( stderr, "Framebuffer size (%dx%d, %dx%d) differs.\n", width, height, other_width, other_height );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( int y = 0; y < height; y++ ) {
|
||||||
|
for ( int x = 0; x < width; x++ ) {
|
||||||
|
if ( fb.get_cell( y, x )->compare( *other_fb.get_cell( y, x ) ) ) {
|
||||||
fprintf( stderr, "Cell (%d, %d) differs.\n", y, x );
|
fprintf( stderr, "Cell (%d, %d) differs.\n", y, x );
|
||||||
ret = true;
|
ret = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( (terminal.get_fb().ds.get_cursor_row() != other.terminal.get_fb().ds.get_cursor_row())
|
if ( (fb.ds.get_cursor_row() != other_fb.ds.get_cursor_row())
|
||||||
|| (terminal.get_fb().ds.get_cursor_col() != other.terminal.get_fb().ds.get_cursor_col()) ) {
|
|| (fb.ds.get_cursor_col() != other_fb.ds.get_cursor_col()) ) {
|
||||||
fprintf( stderr, "Cursor mismatch: (%d, %d) vs. (%d, %d).\n",
|
fprintf( stderr, "Cursor mismatch: (%d, %d) vs. (%d, %d).\n",
|
||||||
terminal.get_fb().ds.get_cursor_row(), terminal.get_fb().ds.get_cursor_col(),
|
fb.ds.get_cursor_row(), fb.ds.get_cursor_col(),
|
||||||
other.terminal.get_fb().ds.get_cursor_row(), other.terminal.get_fb().ds.get_cursor_col() );
|
other_fb.ds.get_cursor_row(), other_fb.ds.get_cursor_col() );
|
||||||
ret = true;
|
ret = true;
|
||||||
}
|
}
|
||||||
|
/* XXX should compare other terminal state too (mouse mode, bell. etc.) */
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -76,6 +76,7 @@ namespace Terminal {
|
|||||||
/* interface for Network::Transport */
|
/* interface for Network::Transport */
|
||||||
void subtract( const Complete * ) const {}
|
void subtract( const Complete * ) const {}
|
||||||
std::string diff_from( const Complete &existing ) const;
|
std::string diff_from( const Complete &existing ) const;
|
||||||
|
std::string init_diff( void ) const;
|
||||||
void apply_string( std::string diff );
|
void apply_string( std::string diff );
|
||||||
bool operator==( const Complete &x ) const;
|
bool operator==( const Complete &x ) const;
|
||||||
|
|
||||||
|
|||||||
@@ -89,6 +89,7 @@ namespace Network {
|
|||||||
/* interface for Network::Transport */
|
/* interface for Network::Transport */
|
||||||
void subtract( const UserStream *prefix );
|
void subtract( const UserStream *prefix );
|
||||||
string diff_from( const UserStream &existing ) const;
|
string diff_from( const UserStream &existing ) const;
|
||||||
|
string init_diff( void ) const { assert( false ); return string(); };
|
||||||
void apply_string( string diff );
|
void apply_string( string diff );
|
||||||
bool operator==( const UserStream &x ) const { return actions == x.actions; }
|
bool operator==( const UserStream &x ) const { return actions == x.actions; }
|
||||||
|
|
||||||
|
|||||||
@@ -643,16 +643,26 @@ void Framebuffer::prefix_window_title( const title_type &s )
|
|||||||
window_title.insert(window_title.begin(), s.begin(), s.end() );
|
window_title.insert(window_title.begin(), s.begin(), s.end() );
|
||||||
}
|
}
|
||||||
|
|
||||||
wint_t Cell::debug_contents( void ) const
|
std::string Cell::debug_contents( void ) const
|
||||||
{
|
{
|
||||||
if ( contents.empty() ) {
|
if ( contents.empty() ) {
|
||||||
return '_';
|
return "'_' ()";
|
||||||
} else {
|
} else {
|
||||||
/* very, very cheesy */
|
std::string chars( 1, '\'' );
|
||||||
wchar_t ch[2];
|
print_grapheme( chars );
|
||||||
const std::string chars( contents.begin(), contents.end() );
|
chars.append( "' [" );
|
||||||
mbstowcs(ch, chars.c_str(), 1);
|
const char *lazycomma = "";
|
||||||
return ch[0];
|
char buf[64];
|
||||||
|
for ( content_type::const_iterator i = contents.begin();
|
||||||
|
i < contents.end();
|
||||||
|
i++ ) {
|
||||||
|
|
||||||
|
sprintf( buf, "%s0x%02x", lazycomma, static_cast<uint8_t>(*i) );
|
||||||
|
chars.append( buf );
|
||||||
|
lazycomma = ", ";
|
||||||
|
}
|
||||||
|
chars.append( "]" );
|
||||||
|
return chars;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -660,15 +670,28 @@ bool Cell::compare( const Cell &other ) const
|
|||||||
{
|
{
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
|
|
||||||
if ( !contents_match( other ) ) {
|
std::string grapheme, other_grapheme;
|
||||||
|
|
||||||
|
print_grapheme( grapheme );
|
||||||
|
other.print_grapheme( other_grapheme );
|
||||||
|
|
||||||
|
if ( grapheme != other_grapheme ) {
|
||||||
ret = true;
|
ret = true;
|
||||||
fprintf( stderr, "Contents: %lc (%ld) vs. %lc (%ld)\n",
|
fprintf( stderr, "Graphemes: '%s' vs. '%s'\n",
|
||||||
debug_contents(), contents.size(),
|
grapheme.c_str(), other_grapheme.c_str() );
|
||||||
other.debug_contents(), other.contents.size() );
|
}
|
||||||
|
|
||||||
|
if ( !contents_match( other ) ) {
|
||||||
|
// ret = true;
|
||||||
|
fprintf( stderr, "Contents: %s (%ld) vs. %s (%ld)\n",
|
||||||
|
debug_contents().c_str(),
|
||||||
|
static_cast<long int>( contents.size() ),
|
||||||
|
other.debug_contents().c_str(),
|
||||||
|
static_cast<long int>( other.contents.size() ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( fallback != other.fallback ) {
|
if ( fallback != other.fallback ) {
|
||||||
ret = true;
|
// ret = true;
|
||||||
fprintf( stderr, "fallback: %d vs. %d\n",
|
fprintf( stderr, "fallback: %d vs. %d\n",
|
||||||
fallback, other.fallback );
|
fallback, other.fallback );
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -109,7 +109,7 @@ namespace Terminal {
|
|||||||
|
|
||||||
bool operator!=( const Cell &x ) const { return !operator==( x ); }
|
bool operator!=( const Cell &x ) const { return !operator==( x ); }
|
||||||
|
|
||||||
wint_t debug_contents( void ) const;
|
std::string debug_contents( void ) const;
|
||||||
|
|
||||||
bool is_blank( void ) const
|
bool is_blank( void ) const
|
||||||
{
|
{
|
||||||
@@ -165,18 +165,18 @@ namespace Terminal {
|
|||||||
|
|
||||||
void print_grapheme( std::string &output ) const
|
void print_grapheme( std::string &output ) const
|
||||||
{
|
{
|
||||||
if ( cell.contents.empty() ) {
|
if ( contents.empty() ) {
|
||||||
output.append( ' ' );
|
output.append( 1, ' ' );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* cells that begin with combining character get combiner
|
* cells that begin with combining character get combiner
|
||||||
* attached to no-break space
|
* attached to no-break space
|
||||||
*/
|
*/
|
||||||
if ( cell.fallback ) {
|
if ( fallback ) {
|
||||||
output.append( "\xC2\xA0" );
|
output.append( "\xC2\xA0" );
|
||||||
}
|
}
|
||||||
output.append( cell.contents );
|
output.append( contents );
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user