[LON-CAPA-cvs] cvs: modules /jerf/tests lonhelpTest.pm

bowersj2 lon-capa-cvs@mail.lon-capa.org
Fri, 23 May 2003 20:31:13 -0000


bowersj2		Fri May 23 16:31:13 2003 EDT

  Added files:                 
    /modules/jerf/tests	lonhelpTest.pm 
  Log:
  Beginnings of testing for the lonhelp.pm module; still need to implement
  a better %ENV so it's not running perfectly.
  
  Also wrapping validation of the help system itself (not just the code
  in lonhelp.pm) into the code, and lo and behold, it has found two 
  serious bugs (links to non-existant files) and five style violations. I 
  didn't actually expect to find bugs *quite* yet...
  
  
  

Index: modules/jerf/tests/lonhelpTest.pm
+++ modules/jerf/tests/lonhelpTest.pm
# The LearningOnline Network with CAPA
# lonhelp Handler Tester
#
# $Id: lonhelpTest.pm,v 1.1 2003/05/23 20:31:13 bowersj2 Exp $
#
# Copyright Michigan State University Board of Trustees
#
# This file is part of the LearningOnline Network with CAPA (LON-CAPA).
#
# LON-CAPA is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# LON-CAPA is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with LON-CAPA; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#
# /home/httpd/html/adm/gpl.txt
#
# http://www.lon-capa.org/
#
# (Testing: lonhelp Handler Tester

# This package, in addition to doing some sanity testing to lonhelper, tests
# the output of the helper for all of the .tex files it might use for sanity,
# allowing for this to also serve as a bit of a sanity check against those
# as well

package lonhelpTest;

use lib '.';
use lib '/home/httpd/lib/perl/';
use ApacheRequest;

use base qw(Test::Unit::TestCase);
use strict;
use Apache::Constants qw(:common);
use Apache::lonhelp;

sub new {
    my $self = shift()->SUPER::new(@_);
    return $self;
}

sub set_up {
    my $self = shift;
}

sub tear_down {
    my $self = shift;
}

# This makes sure we can call the help handler at *all*, without
# testing anything else.
sub test_help_handler_works_syntactically {
    my $self = shift;
    my $r = ApacheRequest->new();

    $r->doHandler("Apache::lonhelper");
}

# This tests the label converter; I use this paradigm a lot for string
# processing functions: "For each of these things, make sure the output
# meets some criterion."
sub test_processLabelName_makes_valid_anchors {
    # We're actually extra conservative, allowing only numbers, underscores, and
    # letters; HTML is significantly more flexible, but this is safe
    my $self = shift;

    for my $name ('safelabel', 'has_underscore', '(%#@^', '}|}}10~') {
        my $anchor = Apache::lonhelp::processLabelName($name);
        $self->assert($anchor =~ /^[a-zA-Z0-9_]+$/);
    }
}

# Since we can't well define the output from tex input, we regrettably
# can't directly test the rendering code, only pieces of it.
sub test_render_code {
    my $self = shift;
    
    my $tex = 'fe';
    my $html = Apache::lonhelp::render($tex);

    $self->assert(valid_html_code($html));

    $tex = '\emph{there}';
    $self->assert(valid_html_code(Apache::lonhelp::render($tex)));
}

# We can't test directly for whether or not a given HTML result from
# TTH is correct. But there *are* some things we can ensure are true...
sub valid_html_code {
    my $code = shift;

    # get this when tth doesn't like the command
    if ($code =~ /Unknown command/) {
        return 0;
    }

    return 1;
}

# Test all of the .tex files for various truths
sub test_help_files_all_valid {
    my $self = shift;
    
    my $docRoot = $Apache::lonnet::perlvar{'lonDocRoot'};
    my %fragmentLabels;
    tie (%fragmentLabels, 'GDBM_File', $docRoot . '/adm/help/fragmentLabels.gdbm', 0, 0);
    $self->assert(tied(%fragmentLabels), 'fragmentLabels.gdbm doesn\'t exist or is inaccessible');
    my $helpRoot = $docRoot . '/adm/help/tex/';

    my $errors = []; # Gather all the error messages so we can display them all
                     # at once

    for my $file (glob($helpRoot . "*.tex")) {
        my $openresult = open(TEX, "<", $file);
        my $humanFileName = substr $file, rindex($file, '/') + 1;
        if ($openresult) {
            my $tex = join('', <TEX>);
            
            # Now validate the tex
            
            # Assertion: All labels are defined by fragmentLabels
            for my $ref ($tex =~ /\\ref\{([^\}]+)\}/gm) {
                if (!defined($fragmentLabels{$ref})) {
                    push @$errors, "Reference '$ref' to undefined label in " .
                        "file $humanFileName";
                }
            }

            # Assertion: The phrase '.tex' never appears (almost certainly
            # an error
            # there is a Authoring_HTML_vs_Tex.tex that should have it
            if ($tex =~ /\.tex/m && $file !~ /Tex/) {
                push @$errors, "File $humanFileName has a '.tex' in it.";
            }

            # Assertion: There is a label for the name of the file, if it's
            # a help file. There are some files like "course.manual.access.tex"
            # that don't need that.
            if (index($humanFileName, '.') == rindex($humanFileName, '.')) {
                my $fileStem = substr $humanFileName, 0, rindex($humanFileName, '.');
                if ($tex !~ /\\label\{$fileStem\}/ ) {
                    push @$errors, "File $humanFileName does not have " .
                        "\\label{$fileStem} in it.";
                }
            }

        } else {
            push @$errors, "Couldn't open $humanFileName";
        }
    }

    untie %fragmentLabels;

    my $errorMessage = join("\n", @$errors);
    $self->assert($errorMessage eq '', $errorMessage);
}
1;