001    package com.mockrunner.base;
002    
003    import java.io.BufferedReader;
004    import java.io.StringReader;
005    
006    import com.mockrunner.mock.web.WebMockObjectFactory;
007    import com.mockrunner.util.common.StringUtil;
008    import com.mockrunner.util.web.XmlUtil;
009    
010    /**
011     * Base class for modules which produce HTML
012     * code as output. These modules have to implement
013     * {@link #getOutput}. The HTML code is provided
014     * in different formats, e.g. as parsed XML
015     * documents.
016     */
017    public abstract class HTMLOutputModule extends WebTestModule
018    {
019        private boolean caseSensitive;
020        
021        public HTMLOutputModule(WebMockObjectFactory mockFactory)
022        {
023            super(mockFactory);
024            caseSensitive = true;
025        }
026        
027        /**
028         * Returns the output as a string. Concrete modules implement
029         * this method.
030         * @return the output
031         */
032        public abstract String getOutput();
033        
034        /**
035         * Returns the output as a <code>BufferedReader</code>. 
036         * @return the output
037         */
038        public BufferedReader getOutputAsBufferedReader()
039        {
040            return new BufferedReader(new StringReader(getOutput()));   
041        }
042        
043        /**
044         * Parses the output with the NekoHTML parser and returns it
045         * as a W3C XML document. Throws a {@link NestedApplicationException} 
046         * if the output is not parsable. NekoHTML is quite good in fixing sloppy
047         * HTML code. If you want to use a different parser configuration,
048         * you can use the method {@link com.mockrunner.util.web.XmlUtil#parse} 
049         * to parse the string output yourself. Please note that
050         * HTML parsing is not very fast and may slow down
051         * your test suite.
052         * @return the output as <code>org.w3c.dom.Document</code>
053         * @throws RuntimeException if a parsing error occurs
054         */
055        public org.w3c.dom.Document getOutputAsW3CDocument()
056        {
057            return XmlUtil.parseHTML(getOutput());
058        }
059        
060        /**
061         * Parses the output with the NekoHTML parser and returns it
062         * as a JDOM XML document. Throws a {@link NestedApplicationException} 
063         * if the output is not parsable. NekoHTML is quite good in fixing sloppy
064         * HTML code. If you want to use a different parser configuration,
065         * you can use the method {@link com.mockrunner.util.web.XmlUtil#parse} 
066         * to parse the string output yourself. Please note that
067         * HTML parsing is not very fast and may slow down
068         * your test suite.
069         * @return the output as <code>org.jdom.Document</code>
070         * @throws RuntimeException if a parsing error occurs
071         */
072        public org.jdom.Document getOutputAsJDOMDocument()
073        {
074            return XmlUtil.createJDOMDocument(getOutputAsW3CDocument());
075        }
076        
077        /**
078         * Parses the output with the NekoHTML parser and returns it
079         * as fixed, wellformed XML. Throws a {@link NestedApplicationException} 
080         * if the output is not parsable. NekoHTML is quite good in fixing sloppy
081         * HTML code. If you want to use a different parser configuration,
082         * you can use the method {@link com.mockrunner.util.web.XmlUtil#parse} 
083         * to parse the string output yourself. Please note that
084         * HTML parsing is not very fast and may slow down
085         * your test suite.
086         * @return the output as wellformed XML
087         * @throws RuntimeException if a parsing error occurs
088         */
089        public String getOutputAsWellformedXML()
090        {
091            return XmlUtil.createStringFromJDOMDocument(getOutputAsJDOMDocument());
092        }
093        
094        /**
095         * Set if {@link #verifyOutput}, {@link #verifyOutputContains}
096         * and {@link #verifyOutputRegularExpression}.
097         * should compare case sensitive. Default is <code>true</code>.
098         * @param caseSensitive enable or disable case sensitivity
099         */
100        public void setCaseSensitive(boolean caseSensitive)
101        {
102            this.caseSensitive = caseSensitive;
103        }
104        
105        /**
106         * Verifies the tag output.
107         * @param expectedOutput the expected output.
108         * @throws VerifyFailedException if verification fails
109         */
110        public void verifyOutput(String expectedOutput)
111        {
112            String actualOutput = getOutput();
113            if(!StringUtil.matchesExact(actualOutput, expectedOutput, caseSensitive))
114            {
115                throw new VerifyFailedException("actual output: " + actualOutput + " does not match expected output");
116            }
117        }
118        
119        /**
120         * Verifies if the output contains the specified data.
121         * @param expectedOutput the data
122         * @throws VerifyFailedException if verification fails
123         */
124        public void verifyOutputContains(String expectedOutput)
125        {
126            String actualOutput = getOutput();
127            if(!StringUtil.matchesContains(actualOutput, expectedOutput, caseSensitive))
128            {
129                throw new VerifyFailedException("actual output: " + actualOutput + " does not match expected output");
130            }
131        }
132        
133        /**
134         * Verifies if the output matches the specified regular expression.
135         * @param expression the data
136         * @throws VerifyFailedException if verification fails
137         */
138        public void verifyOutputRegularExpression(String expression)
139        {
140            String actualOutput = getOutput();
141            if(!StringUtil.matchesPerl5(actualOutput, expression, caseSensitive))
142            {
143                throw new VerifyFailedException("actual output: " + actualOutput + " does not match expected output");
144            }
145        }
146    }