5

I am trying to use the Mojarra JSF 2 compiler programatically with a view to checking the correctness of the xhtml of any pages.

I have got so far but the compiler is not erroring for tags that don't exist in a particular tag library. It does the standard XML namespace checks but if say rich:spacer is present it should error (it got removed in Richfaces 4.x). At runtime this check takes does take place.

Any thoughts? Here is my code:

@RunWith( PowerMockRunner.class )
@PrepareForTest( { WebConfiguration.class, FacesContext.class } )
public class XhtmlValidatorTest
{

    @Test
    public void test() throws IOException
    {
        WebConfiguration webConfiguration = PowerMock.createMock( WebConfiguration.class );
        PowerMock.mockStatic( WebConfiguration.class );
        WebConfiguration.getInstance();
        PowerMock.expectLastCall().andReturn( webConfiguration ).anyTimes();

        FaceletsConfiguration faceletsConfiguration = PowerMock.createMock( FaceletsConfiguration.class );
        webConfiguration.getFaceletsConfiguration();

        PowerMock.expectLastCall().andReturn( faceletsConfiguration ).anyTimes();
        faceletsConfiguration.isProcessCurrentDocumentAsFaceletsXhtml(EasyMock.isA( String.class ) );
        PowerMock.expectLastCall().andReturn(true).anyTimes();
        faceletsConfiguration.isConsumeComments( EasyMock.isA( String.class) );
        PowerMock.expectLastCall().andReturn(false).anyTimes();
        faceletsConfiguration.isConsumeCDATA( EasyMock.isA( String.class ) );
        PowerMock.expectLastCall().andReturn(false).anyTimes();

        webConfiguration.isOptionEnabled(BooleanWebContextInitParameter.EnableMissingResourceLibraryDetection);
        PowerMock.expectLastCall().andReturn( false ).anyTimes();
        webConfiguration.isOptionEnabled(BooleanWebContextInitParameter.EnableCoreTagLibraryValidator );
        PowerMock.expectLastCall().andReturn( true ).anyTimes();

        FacesContext facesContext = PowerMock.createMock( FacesContext.class );
        PowerMock.mockStatic( FacesContext.class );
        FacesContext.getCurrentInstance();
        PowerMock.expectLastCall().andReturn( facesContext ).anyTimes();

        facesContext.isProjectStage( ProjectStage.Development );
        PowerMock.expectLastCall().andReturn( false ).anyTimes();

        Application application = PowerMock.createMock( Application.class );
        facesContext.getApplication();
        PowerMock.expectLastCall().andReturn( application ).anyTimes();

        application.getExpressionFactory();
        PowerMock.expectLastCall().andReturn( new org.jboss.el.ExpressionFactoryImpl() ).anyTimes();

        PowerMock.replayAll();

        long refreshPeriod = -1;
        com.sun.faces.facelets.compiler.Compiler compiler = new SAXCompiler();
        compiler.setValidating( true );
        System.out.println( "Compiler.isValidating() " + compiler.isValidating() );

        FaceletCache cache = new UnittestFaceletCacheFactory().getCache( refreshPeriod );
        ResourceResolver resolver = new ResourceResolver()
                {
                    @Override
                    public URL resolveUrl(String path)
                    {   
                        URL url = null;
                        try
                        {
                            url = new URL( BASE_PATH + path );
                        }
                        catch (MalformedURLException e)
                        {
                            throw new RuntimeException( e );
                        }
                        return url;
                    }
                }; 

        DefaultFaceletFactory defaultFaceletFactory = new DefaultFaceletFactory( compiler, resolver, refreshPeriod, cache );
        File file = new File( "WebContent" );
        File[] files = file.listFiles();
        for( File xhtmlFile : files )
        {
            if( xhtmlFile.isFile() )
            {
                String name = xhtmlFile.getName();
                if( name.endsWith(".xhtml" ) )
                {
                   System.out.println( "compiling: " + name );
                   defaultFaceletFactory.getFacelet( name );
                }
            }
        }
    }

The facelet cache factory used in the code is a hack:

package com.sun.faces.facelets.impl;

import javax.faces.view.facelets.FaceletCache;

public class UnittestFaceletCacheFactory
{
    public FaceletCache getCache( long refreshPeriod )
    {
        return new DefaultFaceletCache( refreshPeriod );
    }
}
Jens Piegsa
  • 7,399
  • 5
  • 58
  • 106
  • When testing what `JSF` user interfaces *look like* (as opposed to what they *do*) , the inherent need for a parser to convert `facelets` into `HTML`, and the requirement for a runner to make the converted view available, is what makes in-container testing popular for this technology. The most popular technology would appear to be `Selenium`. When testing what user interfaces *do*, traditional `jUnit` testing, make use of test doubles and targeting both backing beans and controller classes will usually suffice. Libraries such as `JSFUnit` may speed up your mocking of the `JSF` API. – 8bitjunkie Mar 10 '14 at 23:04
  • I think the point of the OP is to validate syntax and consistency of all facelet pages, at build time. He doesn't seem to talk about functional testing. This looks like an interesting idea. – ymajoros Jun 06 '14 at 10:22

0 Answers0