Ignore:
Timestamp:
09/15/09 05:41:18 (3 years ago)
Author:
MichaelTempest
Message:

Item1980: First, do no harm

  • Let notWyswiwygEditable() check for specific problematic content that is corrupted by a roundtrip tml => html => tml conversion
  • Add unit tests for (some of the) content that is corrupted
  • In unit tests, check that notWysiwygEditable()'s result is consistent with the success or failure of roundtrip conversions
  • Refactor the ExtendedTranslatorTests to reduce duplicated code.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/WysiwygPlugin/test/unit/WysiwygPlugin/ExtendedTranslatorTests.pm

    r4638 r4930  
    2626# 
    2727package ExtendedTranslatorTests; 
    28 use base qw(FoswikiTestCase); 
     28use base qw(TranslatorTests); 
    2929 
    3030use strict; 
     
    3636# Bits for test type 
    3737# Fields in test records: 
    38 my $TML2HTML  = 1 << 0;    # test tml => html 
    39 my $HTML2TML  = 1 << 1;    # test html => finaltml (default tml) 
    40 my $ROUNDTRIP = 1 << 2;    # test tml => => finaltml 
     38my $TML2HTML  = 1 << 0;        # test tml => html 
     39my $HTML2TML  = 1 << 1;        # test html => finaltml (default tml) 
     40my $ROUNDTRIP = 1 << 2;        # test tml => => finaltml 
     41my $CANNOTWYSIWYG = 1 << 3;    # test that notWysiwygEditable returns true 
     42                               #   and make the ROUNDTRIP test expect failure 
    4143 
    4244# Note: ROUNDTRIP is *not* the same as the combination of 
     
    4749# of the TML, where TML -> HTML -> not quite TML -> HTML 
    4850# -> even worse TML, ad nauseum 
     51# 
     52# CANNOTWYSIWYG should normally be used in conjunction with ROUNDTRIP 
     53# to ensure that notWysiwygEditable is consistent with this plugin's 
     54# ROUNDTRIP capabilities. 
     55# 
     56# CANNOTWYSIWYG and ROUNDTRIP used together document the failure cases, 
     57# i.e. they indicate TML that WysiwygPlugin cannot properly translate 
     58# to HTML and back. When WysiwygPlugin is modified to support these 
     59# cases, CANNOTWYSIWYG should be removed from each corresponding 
     60# test case and nonWysiwygEditable should be updated so that the TML 
     61# is "WysiwygEditable". 
     62# 
     63# Use CANNOTWYSIWYG without ROUNDTRIP *only* with an appropriate  
     64# explanation. For example:  
     65#   Can't ROUNDTRIP this TML because perl on the SMURF platform 
     66#   automagically replaces all instances of 'blue' with 'beautiful'. 
    4967 
    5068# Bit mask for selected test types 
    51 my $mask = $TML2HTML | $HTML2TML | $ROUNDTRIP; 
     69my $mask = $TML2HTML | $HTML2TML | $ROUNDTRIP | $CANNOTWYSIWYG; 
    5270 
    5371my $protecton  = '<span class="WYSIWYG_PROTECTED">'; 
     
    6482# Each testcase is a subhash with fields as follows: 
    6583# exec => $TML2HTML to test TML -> HTML, $HTML2TML to test HTML -> TML, 
    66 #   $ROUNDTRIP to test TML-> ->TML, all other bits are ignored. 
     84#   $ROUNDTRIP to test TML-> ->TML, $CANNOTWYSIWYG to test  
     85#   notWysiwygEditable, all other bits are ignored. 
    6786#   They may be OR'd togoether to perform multiple tests. 
    6887#   For example: $TML2HTML | $HTML2TML to test both 
     
    161180          . '&lt;customtag&nbsp;with="attributes"&gt;<br />&nbsp;&nbsp;formatting&nbsp;&gt;&nbsp;&nbsp;preserved<br />&lt;/customtag&gt;' 
    162181          . $protectoff . '</p>', 
    163         tml => <<BLAH, 
     182        tml => <<'BLAH', 
    164183<customtag with="attributes"> 
    165184  formatting >  preserved 
     
    183202          . '&lt;/customtag&gt;' 
    184203          . $protectoff . '</p>', 
    185         tml => <<BLAH, 
     204        tml => <<'BLAH', 
    186205<customtag> 
    187206  formatting >  preserved 
     
    193212BLAH 
    194213    }, 
     214    { 
     215        exec => $CANNOTWYSIWYG, 
     216        # Do not perform ROUNDTRIP on this TML, because ROUNDTRIP passes. 
     217        # The problem with this TML is that the special handling of  
     218        # <verbatim> in the conversion to HTML messes up the contents  
     219        # of this custom XML  tag, so that the HTML is not representative  
     220        # of the TML in terms of intellectual content. 
     221        name => 'VerbatimInsideDot', 
     222        setup => sub { 
     223            Foswiki::Plugins::WysiwygPlugin::addXMLTag( 'dot', 
     224                sub { 1 } ); 
     225        }, 
     226        tml => <<'DOT', 
     227<dot> 
     228digraph G { 
     229    open [label="<verbatim>"]; 
     230    content [label="Put arbitrary content here"]; 
     231    close [label="</verbatim>"]; 
     232    open -> content -> close; 
     233} 
     234</dot> 
     235DOT 
     236    }, 
     237        { 
     238                exec => $TML2HTML | $ROUNDTRIP, 
     239                name => 'CustomtagInsideSticky', 
     240        setup => sub { 
     241            Foswiki::Plugins::WysiwygPlugin::addXMLTag( 'customtag', 
     242                sub { 1 } ); 
     243        }, 
     244        tml => "<sticky><customtag>this & that\n >   the other </customtag></sticky>", 
     245                html => '<p>' 
     246                  . '<div class="WYSIWYG_STICKY">' 
     247                  . '&lt;customtag&gt;' 
     248                  . 'this&nbsp;&amp;&nbsp;that<br />&nbsp;&gt;&nbsp;&nbsp;&nbsp;the&nbsp;other&nbsp;' 
     249                  . '&lt;/customtag&gt;' 
     250                  . '</div>' 
     251                  . '</p>' 
     252        }, 
     253        { 
     254                exec => $ROUNDTRIP | $CANNOTWYSIWYG, #SMELL: fix this case 
     255                name => 'StickyInsideCustomtag', 
     256        setup => sub { 
     257            Foswiki::Plugins::WysiwygPlugin::addXMLTag( 'customtag', 
     258                sub { 1 } ); 
     259        }, 
     260        tml => "<customtag>this <sticky>& that\n >   the</sticky> other </customtag>", 
     261                html => '<p>' 
     262          . $protecton 
     263                  . '&lt;customtag&gt;' 
     264                  . 'this&nbsp;' 
     265                  . '<div class="WYSIWYG_STICKY">' 
     266                  . '&amp;&nbsp;that<br />&nbsp;&gt;&nbsp;&nbsp;&nbsp;the' 
     267                  . '</div>' 
     268                  . '&nbsp;other&nbsp;' 
     269                  . '&lt;/customtag&gt;' 
     270                  . $protectoff 
     271                  . '</p>' 
     272        }, 
     273        { 
     274                exec => $TML2HTML | $ROUNDTRIP, 
     275                name => 'StickyInsideUnspecifiedCustomtag', 
     276        setup => sub { 
     277        }, 
     278        tml => "<customtag>this <sticky>& that\n >   the</sticky> other </customtag>", 
     279                html => '<p>' 
     280          . $protecton 
     281                  . '&lt;customtag&gt;' 
     282                  . $protectoff 
     283                  . 'this' 
     284                  . '<div class="WYSIWYG_STICKY">' 
     285                  . '&amp;&nbsp;that<br />&nbsp;&gt;&nbsp;&nbsp;&nbsp;the' 
     286                  . '</div>' 
     287                  . 'other' 
     288          . $protecton 
     289                  . '&lt;/customtag&gt;' 
     290                  . $protectoff 
     291                  . '</p>' 
     292        }, 
     293        { 
     294                exec => $ROUNDTRIP, 
     295                name => 'UnspecifiedCustomtagInsideSticky', 
     296        setup => sub { 
     297        }, 
     298        tml => "<sticky><customtag>this & that\n >   the other </customtag></sticky>" 
     299        }, 
     300        { 
     301                exec => $TML2HTML | $ROUNDTRIP, 
     302                name => 'CustomtagInsideLiteral', 
     303        setup => sub { 
     304            Foswiki::Plugins::WysiwygPlugin::addXMLTag( 'customtag', 
     305                sub { 1 } ); 
     306        }, 
     307        tml => '<literal><customtag>this & that >   the other </customtag></literal>', 
     308                html => '<p>' 
     309                  . '<div class="WYSIWYG_LITERAL">' 
     310                  . '<customtag>this & that >   the other </customtag>' 
     311                  . '</div>' 
     312                  . '</p>' 
     313        }, 
     314        { 
     315                exec => $TML2HTML | $ROUNDTRIP, 
     316                name => 'UnspecifiedCustomtagInsideLiteral', 
     317        setup => sub { 
     318        }, 
     319        tml => '<literal><customtag>this & that >   the other </customtag></literal>', 
     320                html => '<p>' 
     321                  . '<div class="WYSIWYG_LITERAL">' 
     322                  . '<customtag>this & that >   the other </customtag>' 
     323                  . '</div>' 
     324                  . '</p>' 
     325        }, 
     326        { 
     327                exec => $ROUNDTRIP | $CANNOTWYSIWYG, #SMELL: Fix this case 
     328                name => 'LiteralInsideCustomtag', 
     329        setup => sub { 
     330            Foswiki::Plugins::WysiwygPlugin::addXMLTag( 'customtag', 
     331                sub { 1 } ); 
     332        }, 
     333        tml => '<customtag>this <literal>& that > the</literal> other </customtag>', 
     334                html => '<p>' 
     335                  . '<div class="WYSIWYG_LITERAL">' 
     336                  . '<customtag>this & that > the other </customtag>' 
     337                  . '</div>' 
     338                  . '</p>' 
     339        }, 
     340        { 
     341                exec => $TML2HTML | $ROUNDTRIP, 
     342                name => 'LiteralInsideUnspecifiedCustomtag', 
     343        setup => sub { 
     344        }, 
     345        tml => '<customtag>this <literal>& that > the</literal> other </customtag>', 
     346                html => '<p>' 
     347          . $protecton 
     348                  . '&lt;customtag&gt;' 
     349                  . $protectoff 
     350                  . 'this' 
     351                  . '<div class="WYSIWYG_LITERAL">' 
     352                  . '& that > the' 
     353                  . '</div>' 
     354                  .'other' 
     355          . $protecton 
     356                  . '&lt;/customtag&gt;' 
     357                  . $protectoff 
     358                  . '</p>' 
     359        }, 
    195360]; 
    196361 
     
    205370            my $fn = 'ExtendedTranslatorTests::testTML2HTML_' . $datum->{name}; 
    206371            no strict 'refs'; 
    207             *$fn = sub { my $this = shift; $this->compareTML_HTML($datum) }; 
     372            *$fn = sub {  
     373                my $this = shift;  
     374                $this->testSpecificSetup($datum);  
     375                $this->compareTML_HTML($datum);  
     376                $this->testSpecificCleanup($datum); 
     377            }; 
    208378            use strict 'refs'; 
    209379        } 
     
    211381            my $fn = 'ExtendedTranslatorTests::testHTML2TML_' . $datum->{name}; 
    212382            no strict 'refs'; 
    213             *$fn = sub { my $this = shift; $this->compareHTML_TML($datum) }; 
     383            *$fn = sub {  
     384                my $this = shift; 
     385                $this->testSpecificSetup($datum);  
     386                $this->compareHTML_TML($datum); 
     387                $this->testSpecificCleanup($datum); 
     388            }; 
    214389            use strict 'refs'; 
    215390        } 
     
    217392            my $fn = 'ExtendedTranslatorTests::testROUNDTRIP_' . $datum->{name}; 
    218393            no strict 'refs'; 
    219             *$fn = sub { my $this = shift; $this->compareRoundTrip($datum) }; 
     394            *$fn = sub { 
     395                my $this = shift; 
     396                $this->testSpecificSetup($datum);  
     397                $this->compareRoundTrip($datum); 
     398                $this->testSpecificCleanup($datum); 
     399            }; 
     400            use strict 'refs'; 
     401        } 
     402        if ( ( $mask & $datum->{exec} ) & $CANNOTWYSIWYG ) { 
     403            my $fn = 'TranslatorTests::testCANNOTWYSIWYG_' . $datum->{name}; 
     404            no strict 'refs'; 
     405            *$fn = sub {  
     406                my $this = shift; 
     407                $this->testSpecificSetup($datum);  
     408                $this->compareNotWysiwygEditable($datum); 
     409                $this->testSpecificCleanup($datum); 
     410            }; 
    220411            use strict 'refs'; 
    221412        } 
     
    223414} 
    224415 
    225 sub set_up { 
    226     my $this = shift; 
    227     $this->SUPER::set_up(@_); 
    228     $Foswiki::cfg{Plugins}{WysiwygPlugin}{Enabled} = 1; 
    229  
    230     my $query; 
    231     eval { 
    232         require Unit::Request; 
    233         require Unit::Response; 
    234         $query = new Unit::Request(""); 
    235     }; 
    236     if ($@) { 
    237         $query = new CGI(""); 
    238     } 
    239     $query->path_info("/Current/TestTopic"); 
    240     $this->{session} = new Foswiki( undef, $query ); 
    241     $Foswiki::Plugins::SESSION = $this->{session}; 
    242 } 
    243  
    244 sub normaliseEntities { 
    245     my $text = shift; 
    246  
    247     # Convert text entities to &# representation 
    248     $text =~ s/(&\w+;)/'&#'.ord(HTML::Entities::decode_entities($1)).';'/ge; 
    249     return $text; 
    250 } 
    251  
    252 sub compareTML_HTML { 
     416sub testSpecificSetup { 
    253417    my ( $this, $args ) = @_; 
    254  
    255     my $page = 
    256       $this->{session}->getScriptUrl( 1, 'view', 'Current', 'TestTopic' ); 
    257     $page =~ s/\/Current\/TestTopic.*$//; 
    258     my $html = $args->{html} || ''; 
    259     $html =~ s/%!page!%/$page/g; 
    260     my $finaltml = $args->{finaltml} || ''; 
    261     $finaltml =~ s/%!page!%/$page/g; 
    262     my $tml = $args->{tml} || ''; 
    263     $tml =~ s/%!page!%/$page/g; 
    264  
    265418    # Reset the extendable parts of WysiwygPlugin 
    266419    %Foswiki::Plugins::WysiwygPlugin::xmltag       = (); 
     
    269422    # Test-specific setup 
    270423    if ( exists $args->{setup} ) { 
    271         $args->{setup}->(); 
    272     } 
    273  
    274     # convert to HTML 
    275     my $txer = new Foswiki::Plugins::WysiwygPlugin::TML2HTML(); 
    276     my $tx   = $txer->convert( 
    277         $tml, 
    278         { 
    279             web        => 'Current', 
    280             topic      => 'TestTopic', 
    281             getViewUrl => \&Foswiki::Plugins::WysiwygPlugin::getViewUrl, 
    282             expandVarsInURL => 
    283               \&Foswiki::Plugins::WysiwygPlugin::expandVarsInURL, 
    284             xmltag => \%Foswiki::Plugins::WysiwygPlugin::xmltag, 
    285         } 
    286     ); 
    287  
    288     # Test-specific cleanup 
    289     if ( exists $args->{cleanup} ) { 
    290         $args->{cleanup}->(); 
    291     } 
    292  
    293     $this->assert_html_equals( $html, $tx ); 
    294 } 
    295  
    296 sub compareRoundTrip { 
    297     my ( $this, $args ) = @_; 
    298     my $page = 
    299       $this->{session}->getScriptUrl( 1, 'view', 'Current', 'TestTopic' ); 
    300     $page =~ s/\/Current\/TestTopic.*$//; 
    301  
    302     my $tml = $args->{tml} || ''; 
    303     $tml =~ s/%!page!%/$page/g; 
    304  
    305     # Reset the extendable parts of WysiwygPlugin 
    306     %Foswiki::Plugins::WysiwygPlugin::xmltag       = (); 
    307     %Foswiki::Plugins::WysiwygPlugin::xmltagPlugin = (); 
    308  
    309     # Test-specific setup 
    310     if ( exists $args->{setup} ) { 
    311         $args->{setup}->(); 
    312     } 
    313  
    314     # convert to HTML 
    315     my $txer = new Foswiki::Plugins::WysiwygPlugin::TML2HTML(); 
    316     my $html = $txer->convert( 
    317         $tml, 
    318         { 
    319             web        => 'Current', 
    320             topic      => 'TestTopic', 
    321             getViewUrl => \&Foswiki::Plugins::WysiwygPlugin::getViewUrl, 
    322             expandVarsInURL => 
    323               \&Foswiki::Plugins::WysiwygPlugin::expandVarsInURL, 
    324             xmltag => \%Foswiki::Plugins::WysiwygPlugin::xmltag, 
    325         } 
    326     ); 
    327  
    328     # convert back to TML 
    329     $txer = new Foswiki::Plugins::WysiwygPlugin::HTML2TML(); 
    330     my $tx = $txer->convert( 
    331         $html, 
    332         { 
    333             web          => 'Current', 
    334             topic        => 'TestTopic', 
    335             convertImage => \&convertImage, 
    336             rewriteURL   => \&Foswiki::Plugins::WysiwygPlugin::postConvertURL, 
    337         } 
    338     ); 
    339  
    340     # Test-specific cleanup 
    341     if ( exists $args->{cleanup} ) { 
    342         $args->{cleanup}->(); 
    343     } 
    344  
    345     my $finaltml = $args->{finaltml} || $tml; 
    346     $finaltml =~ s/%!page!%/$page/g; 
    347     $this->_assert_tml_equals( $finaltml, $tx, $args->{name} ); 
    348 } 
    349  
    350 sub compareHTML_TML { 
    351     my ( $this, $args ) = @_; 
    352  
    353     my $page = 
    354       $this->{session}->getScriptUrl( 1, 'view', 'Current', 'TestTopic' ); 
    355     $page =~ s/\/Current\/TestTopic.*$//; 
    356     my $html = $args->{html} || ''; 
    357     $html =~ s/%!page!%/$page/g; 
    358     my $tml = $args->{tml} || ''; 
    359     $tml =~ s/%!page!%/$page/g; 
    360     my $finaltml = $args->{finaltml} || $tml; 
    361     $finaltml =~ s/%!page!%/$page/g; 
    362  
    363     # Reset the extendable parts of WysiwygPlugin 
    364     %Foswiki::Plugins::WysiwygPlugin::xmltag       = (); 
    365     %Foswiki::Plugins::WysiwygPlugin::xmltagPlugin = (); 
    366  
    367     # Test-specific setup 
    368     if ( exists $args->{setup} ) { 
    369         $args->{setup}->(); 
    370     } 
    371  
    372     # convert to TML 
    373     my $txer = new Foswiki::Plugins::WysiwygPlugin::HTML2TML(); 
    374     my $tx   = $txer->convert( 
    375         $html, 
    376         { 
    377             web          => 'Current', 
    378             topic        => 'TestTopic', 
    379             convertImage => \&convertImage, 
    380             rewriteURL   => \&Foswiki::Plugins::WysiwygPlugin::postConvertURL, 
    381         } 
    382     ); 
    383  
    384     # Test-specific cleanup 
    385     if ( exists $args->{cleanup} ) { 
    386         $args->{cleanup}->(); 
    387     } 
    388  
    389     $this->_assert_tml_equals( $finaltml, $tx, $args->{name} ); 
    390 } 
    391  
    392 sub encode { 
    393     my $s = shift; 
    394  
    395     # used for debugging odd chars 
    396     #    $s =~ s/([\000-\037])/'#'.ord($1)/ge; 
    397     return $s; 
    398 } 
    399  
    400 sub _assert_tml_equals { 
    401     my ( $this, $expected, $actual, $name ) = @_; 
    402     $expected ||= ''; 
    403     $actual   ||= ''; 
    404     $actual   =~ s/\n$//s; 
    405     $expected =~ s/\n$//s; 
    406     unless ( $expected eq $actual ) { 
    407         my $expl = 
    408             "==$name== Expected TML:\n" 
    409           . encode($expected) 
    410           . "\n==$name== Actual TML:\n" 
    411           . encode($actual) 
    412           . "\n==$name==\n"; 
    413         my $i = 0; 
    414         while ( $i < length($expected) && $i < length($actual) ) { 
    415             my $e = substr( $expected, $i, 1 ); 
    416             my $a = substr( $actual,   $i, 1 ); 
    417             if ( $a ne $e ) { 
    418                 $expl .= "<<==== HERE actual "; 
    419                 $expl .= ord($a) . " != expected " . ord($e) . "\n"; 
    420                 last; 
    421             } 
    422             $expl .= $a; 
    423             $i++; 
    424         } 
    425         $this->assert( 0, $expl . "\n" ); 
     424        $args->{setup}->($this); 
    426425    } 
    427426} 
    428427 
    429 sub convertImage { 
    430     my $url = shift; 
    431  
    432     if ( $url eq "test_image" ) { 
    433         return '%TRANSLATEDIMAGE%'; 
     428sub testSpecificCleanup { 
     429    my ( $this, $args ) = @_; 
     430    if ( exists $args->{cleanup} ) { 
     431        $args->{cleanup}->($this); 
    434432    } 
    435433} 
    436434 
     435sub TML_HTMLconverterOptions 
     436{ 
     437    my $this = shift; 
     438    my $options = $this->SUPER::TML_HTMLconverterOptions(@_); 
     439    $options->{xmltag} = \%Foswiki::Plugins::WysiwygPlugin::xmltag; 
     440    return $options; 
     441} 
     442 
    437443gen_compare_tests(); 
    438444 
Note: See TracChangeset for help on using the changeset viewer.