\documentclass{article}

\usepackage[a4paper,margin=1in]{geometry}
\usepackage{jvlisting}
\usepackage{multicol}

\newcommand{\testbreak}{\vskip0pt plus 10cm\penalty-100\vskip0pt plus-10cm
  \bigskip}
\newenvironment{test}[1]{\testbreak\begingroup\textbf{Test~#1}}%
  {\par\endgroup}
\newenvironment{testpages}[1]{\parskip0pt
    \vskip2pt\hrule\begin{minipage}[c][#1\baselineskip]{1\linewidth}%
    \begin{multicols}{2}\parskip1ex}%
  {\end{multicols}\end{minipage}\vskip3pt\hrule}
\parindent0pt
\parskip1ex

\newwrite\outfile

\begin{document}

\begin{center}
  \bf Test Cases for the jvlisting Package
\end{center}


This document contains test cases to exercise different features of
the \verb|jvlisting| \LaTeX\ package.


\begin{test}{1.1} (printing of special characters).
  The following two lines should be the same
  \setlength{\listingindent}{0pt}
  \setlength{\listingskipamount}{0pt}
  \begin{listing}
    start  %\{}~``''$ end
  \end{listing}
  \verb|start  %\{}~``''$ end|
\end{test}


\begin{test}{1.2} (ligatures).
  The following two lines should be the same
  \setlength{\listingindent}{0pt}
  \setlength{\listingskipamount}{0pt}
  \begin{listing}
    start ?` !` end
  \end{listing}
  \verb|start ?` !` end|
\end{test}


\begin{test}{2.1} (indentation).
  The following five lines should align horizontally.
  \setlength{\listingskipamount}{0pt}
  \begin{listing}
    |line1|
  \end{listing}
  \begin{listing}
|line2|
  \end{listing}
  \begin{listing}    |line3|
    |line4|
    |line5|\end{listing}
\end{test}


\begin{test}{2.2} (decreasing indentation level).
  The left end of the following lines should align horizontally.
  \begin{listing}       |line0
      |line1
     |line2
    |line3
  \end{listing}
\end{test}


\begin{test}{2.3} (increasing indentation level).
  The right end of the following lines should align horizontally.
  \begin{listing}
    xxline1|
     xline2|
      line3|
  \end{listing}
\end{test}


\begin{test}{2.4} (\verb|\listingindent|).
  The following two lines should align horizontally.
  \setlength{\listingskipamount}{0pt}

\hskip3cm\texttt{|line1|}

\setlength{\listingindent}{3cm}
\begin{listing}
  |line2|
\end{listing}
\end{test}


\begin{test}{3.1} (\verb|\listingskipamount|, part~1).
The lines of the listing should vertically align with the lines to the
right.

\setlength{\listingskipamount}{0pt}
\begin{minipage}{.4\linewidth}
  line1 line1 line1 line1 line1
  \begin{listing}
    line2 line2 line2 line2 line2
    line3 line3 line3 line3 line3
  \end{listing}
  line4 line4 line4 line4 line4
\end{minipage}%
\begin{minipage}{.6\linewidth}
  line1 \\
  line2 \\
  line3 \\
  line4
\end{minipage}
\end{test}


\begin{test}{3.2} (\verb|\listingskipamount|, part~2).
The lines of the listing should vertically align with the lines to the
right.

\begin{minipage}{.4\linewidth}
  line1 line1 line1 line1 line1
  \setlength{\listingskipamount}{1\baselineskip}
  \begin{listing}
    line3 line3 line3 line3 line3
  \end{listing}
  line5 line5 line5 line5 line5
\end{minipage}%
\begin{minipage}{.6\linewidth}
  line1 \\
  line2 \\
  line3 \\
  line4 \\
  line5
\end{minipage}
\end{test}


\begin{test}{3.3} (no extra parskip before/after listings).
The lines of the listing should vertically align with the lines to the
right.

\begin{minipage}{.4\linewidth}\parskip12pt
\setlength{\listingskipamount}{0pt}
  line1 line1 line1 line1 line1
  \begin{listing}
    line2 line2 line2 line2 line2
    line3 line3 line3 line3 line3
    line4 line4 line4 line4 line4
  \end{listing}
  line5 line5 line5 line5 line5

  line7
\end{minipage}%
\begin{minipage}{.6\linewidth}\parskip1\baselineskip
  line1

  line3

  line5

  line7
\end{minipage}
\end{test}


\begin{test}{4.1} (page breaks).
The columns should be of equal height (four rows each).
\setlength{\listingskipamount}{0pt}%
\begin{testpages}{6}
  Some text \dots \\
  \dots\ before the listing.
  \begin{listing}
    line1
    line2
    line3
    line4
    line5
    line6
  \end{listing}
\end{testpages}
\end{test}


\begin{test}{4.2} (page breaks, \verb|\listingpenalty|).
The column break should be immediately before \verb|line1|.
\setlength{\listingskipamount}{0pt}%
\listingpenalty=10000
\begin{testpages}{6}
  Some text \dots \\
  \dots\ before the listing.
  \begin{listing}
    line1
    line2
    line3
    line4
    line5
    line6
  \end{listing}
\end{testpages}
\end{test}


\begin{test}{4.3} (page breaks, \verb|\prelistingpenalty|).
The column break should {\em not} be immediately before \verb|line1|.
\setlength{\listingskipamount}{0pt}%
\prelistingpenalty=10000
\begin{testpages}{3}
  Some text \dots \\
  \dots\ before \dots \\
  \dots the listing.
  \begin{listing}
    line1
    line2
  \end{listing}
\end{testpages}
\end{test}


\begin{test}{4.4} (page breaks, \verb|\postlistingpenalty|).
The column break should {\em not} be immediately after \verb|line3|.
\setlength{\listingskipamount}{0pt}%
\postlistingpenalty=10000
\begin{testpages}{3}
  \begin{listing}
    line1
    line2
    line3
  \end{listing}
  Some text \dots \\
  \dots\ after the listing.
\end{testpages}
\end{test}


\begin{test}{5} (\verb|\filelisting|)
The following two listings should look the same.
\immediate\openout\outfile=tmp.txt
\immediate\write\outfile{line1}
\immediate\write\outfile{line2}
\immediate\write\outfile{line3}
\immediate\closeout\outfile

\begin{minipage}{.5\linewidth}
\begin{listing}
line1
line2
line3
\end{listing}
\end{minipage}%
\begin{minipage}{.5\linewidth}
\filelisting{tmp.txt}
\end{minipage}
\end{test}


\begin{test}{6.1} (\verb|\listingstarthook|, prepending a character)
  The following two lines should be the same.
  \setlength{\listingskipamount}{0pt}%
  \begin{listing}
    xtest
  \end{listing}
  \def\listingstarthook#1{#1x\ignorespaces}%
  \begin{listing}
    test
  \end{listing}
\end{test}

\begin{test}{6.2} (\verb|\listingstarthook|, prepending a line)
  The following listing should have two lines.
  \setlength{\listingskipamount}{0pt}%
  {\obeylines
  \gdef\listingstarthook#1{#1{ }{ }{ }{ }line1
    }}%
  \begin{listing}
    line2
  \end{listing}
  \global\let\listingstarthook=\undefined
\end{test}

\begin{test}{6.3} (\verb|\listingstarthook|, removing the first line)
  The following listing should have two lines.
  \setlength{\listingskipamount}{0pt}%
  {\obeylines
  \gdef\listingstarthook#1#2
    {#1}}%
  \begin{listing}
    this should not be shown
    line1
    line2
  \end{listing}
  \global\let\listingstarthook=\undefined
\end{test}

\begin{test}{6.4} (\verb|\listingstarthook|, conditionally removing the first line)
  The following listing should have two lines.
  \setlength{\listingskipamount}{0pt}%
  {\catcode`\#=12\gdef\hash{#}}
  {\obeylines
  \gdef\skiptoeol#1#2
    {\noindent\hbox to0pt{\hss (a line was removed)\hskip-\textwidth}#1}}
  \def\x#1#2#3{\if#3 \def\next{\x{#1}{#2#3}}\else
    \expandafter\ifx\hash#3\def\next{\skiptoeol{#1}}\else
    \def\next{#1#2#3}\fi\fi\next}
  \def\listingstarthook#1{\x{#1}{}}
  \begin{listing}
    #line0
    line1
    line2
  \end{listing}
  The following listing should have three lines.
  \begin{listing}
    line0
    line1
    line2
  \end{listing}
\end{test}

\newcommand{\writetofile}[1]{\immediate\write\outfile{#1}}
\NewListingEnvironment{filetestlisting}{0}{}%
  {\immediate\openout\outfile=tmp.txt}{\writetofile}%
  {\immediate\closeout\outfile}

\begin{test}{7.1} (writing listings to file)
  The following two lines should be the same.
  \setlength{\listingskipamount}{0pt}%
  \begin{listing}
    a line with ``quotes'', \slashes and potential ligatures: `   ?` !`   '
  \end{listing}
  \begin{filetestlisting}
    a line with ``quotes'', \slashes and potential ligatures: `   ?` !`   '
  \end{filetestlisting}
  \filelisting{tmp.txt}
\end{test}

\newcommand{\copytypeset}[1]{\ListingTypesetLine{#1}%
  {\DisableLigatureFix\immediate\write\outfile{#1}}}
\NewListingEnvironment{copylisting}{0}{\prelistingskip}%
  {\immediate\openout\outfile=tmp.txt\listingfont}{\copytypeset}%
  {\immediate\closeout\outfile\postlistingskip}

\begin{test}{7.2} (simultaneously typesetting and writing to a file)
  The following four lines should be the same.
  \setlength{\listingskipamount}{0pt}%
  \begin{copylisting}
    a line with ``quotes'', \slashes and potential ligatures: `   ?` !`   '
    a line with ``quotes'', \slashes and potential ligatures: `   ?` !`   '
  \end{copylisting}
  \filelisting{tmp.txt}
\end{test}

\end{document}
