Package org.apache.tapestry.internal.services

Source Code of org.apache.tapestry.internal.services.ComponentTemplateSourceImplTest

// Copyright 2006, 2007 The Apache Software Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package org.apache.tapestry.internal.services;

import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Locale;
import java.util.UUID;

import org.apache.tapestry.internal.InternalConstants;
import org.apache.tapestry.internal.events.InvalidationListener;
import org.apache.tapestry.internal.parser.ComponentTemplate;
import org.apache.tapestry.internal.test.InternalBaseTestCase;
import org.apache.tapestry.ioc.Resource;
import org.apache.tapestry.ioc.internal.util.ClasspathResource;
import org.apache.tapestry.model.ComponentModel;
import org.testng.annotations.Test;

public class ComponentTemplateSourceImplTest extends InternalBaseTestCase
{
    private static final String PACKAGE = "org.apache.tapestry.internal.pageload";

    static public final String PATH = "org/apache/tapestry/internal/pageload";

    private final ClassLoader _loader = Thread.currentThread().getContextClassLoader();

    /**
     * Creates a new class loader, whose parent is the thread's context class loader, but adds a
     * single classpath root from the filesystem.
     *
     * @see #createClasspathRoot()
     */
    protected final URLClassLoader newLoaderWithClasspathRoot(File rootDir)
            throws MalformedURLException
    {
        String urlPath = rootDir.toURL().toString();
        // URLs for folders must end with a slash to make URLClassLoader happy.
        URL url = new URL(urlPath + "/");

        return new URLClassLoader(new URL[]
        { url }, _loader);
    }

    /**
     * Creates a new temporary directory which can act as a classpath root.
     *
     * @see #newLoaderWithClasspathRoot(File)
     */
    protected final File createClasspathRoot()
    {
        String temp = System.getProperty("java.io.tmpdir");
        String rootDirPath = temp + "/" + UUID.randomUUID().toString();

        return new File(rootDirPath);
    }

    @Test
    public void caching()
    {
        Resource baseResource = newResource("Fred.class");

        TemplateParser parser = mockTemplateParser();
        ComponentTemplate template = mockComponentTemplate();
        ComponentModel model = mockComponentModel();

        train_getComponentClassName(model, PACKAGE + ".Fred");

        train_getBaseResource(model, baseResource);

        train_parseTemplate(parser, baseResource
                .withExtension(InternalConstants.TEMPLATE_EXTENSION), template);

        replay();

        ComponentTemplateSource source = new ComponentTemplateSourceImpl(parser, null);

        assertSame(source.getTemplate(model, Locale.ENGLISH), template);

        // A second pass will test the caching (the
        // parser is not invoked).

        assertSame(source.getTemplate(model, Locale.ENGLISH), template);

        verify();
    }

    /** Tests resource invalidation. */
    @Test
    public void invalidation() throws Exception
    {
        File rootDir = createClasspathRoot();
        URLClassLoader loader = newLoaderWithClasspathRoot(rootDir);
        ComponentModel model = mockComponentModel();

        File packageDir = new File(rootDir, "baz");
        packageDir.mkdirs();

        File f = new File(packageDir, "Biff.tml");

        f.createNewFile();

        Resource baseResource = new ClasspathResource(loader, "baz/Biff.class");
        Resource localized = baseResource.withExtension(InternalConstants.TEMPLATE_EXTENSION);

        TemplateParser parser = mockTemplateParser();
        ComponentTemplate template = mockComponentTemplate();
        InvalidationListener listener = mockInvalidationListener();

        train_getComponentClassName(model, "baz.Biff");

        train_getBaseResource(model, baseResource);

        train_parseTemplate(parser, localized, template);

        replay();

        ComponentTemplateSourceImpl source = new ComponentTemplateSourceImpl(parser, null);
        source.addInvalidationListener(listener);

        assertSame(source.getTemplate(model, Locale.ENGLISH), template);

        // Check for updates (which won't be found).
        source.checkForUpdates();

        // A second pass will test the caching (the
        // parser is not invoked).

        assertSame(source.getTemplate(model, Locale.ENGLISH), template);

        verify();

        // Now, change the file and process an UpdateEvent.

        touch(f);

        listener.objectWasInvalidated();

        replay();

        // Check for updates (which will be found).
        source.checkForUpdates();

        verify();

        // Check that the cache really is cleared.

        train_getComponentClassName(model, "baz.Biff");

        train_getBaseResource(model, baseResource);

        train_parseTemplate(parser, localized, template);

        replay();

        assertSame(source.getTemplate(model, Locale.ENGLISH), template);

        verify();
    }

    /** Checks that localization to the same resource works (w/ caching). */
    @Test
    public void localization_to_same()
    {
        Resource baseResource = newResource("Fred.class");

        TemplateParser parser = mockTemplateParser();
        ComponentTemplate template = mockComponentTemplate();
        ComponentModel model = mockComponentModel();

        train_getComponentClassName(model, PACKAGE + ".Fred");

        train_getBaseResource(model, baseResource);

        train_parseTemplate(parser, baseResource
                .withExtension(InternalConstants.TEMPLATE_EXTENSION), template);

        replay();

        ComponentTemplateSourceImpl source = new ComponentTemplateSourceImpl(parser, null);

        assertSame(source.getTemplate(model, Locale.ENGLISH), template);

        // A second pass finds the same resource, but using a different
        // path/locale combination.

        assertSame(source.getTemplate(model, Locale.FRENCH), template);

        // A third pass should further demonstrate the caching.

        assertSame(source.getTemplate(model, Locale.FRENCH), template);

        verify();
    }

    @Test
    public void page_template_found_in_context()
    {
        Resource baseResource = newResource("NotInClasspath.class");

        // Simpler to do it this way ...

        Resource contextTemplateResource = newResource("Fred.tml");

        TemplateParser parser = mockTemplateParser();
        ComponentTemplate template = mockComponentTemplate();
        ComponentModel model = mockComponentModel();
        PageTemplateLocator locator = mockPageTemplateLocator();
        Locale locale = Locale.FRENCH;

        train_getComponentClassName(model, PACKAGE + ".NotInClasspath");

        train_getBaseResource(model, baseResource);

        train_findPageTemplateResource(locator, model, locale, contextTemplateResource);

        train_parseTemplate(parser, contextTemplateResource, template);

        replay();

        ComponentTemplateSourceImpl source = new ComponentTemplateSourceImpl(parser, locator);

        assertSame(source.getTemplate(model, locale), template);

        verify();
    }

    @Test
    public void no_template_found()
    {
        TemplateParser parser = mockTemplateParser();
        ComponentModel model = mockComponentModel();
        PageTemplateLocator locator = mockPageTemplateLocator();

        Resource baseResource = newResource("Barney.class");

        train_getComponentClassName(model, PACKAGE + ".Barney");

        train_getBaseResource(model, baseResource);

        train_findPageTemplateResource(locator, model, Locale.ENGLISH, null);

        train_getParentModel(model, null);

        replay();

        ComponentTemplateSourceImpl source = new ComponentTemplateSourceImpl(parser, locator);

        ComponentTemplate template = source.getTemplate(model, Locale.ENGLISH);

        assertTrue(template.isMissing());

        verify();
    }

    @Test
    public void child_component_inherits_parent_template()
    {
        Resource baseFred = newResource("Fred.class");
        Resource baseBarney = baseFred.forFile("Barney.class");
        PageTemplateLocator locator = mockPageTemplateLocator();

        TemplateParser parser = mockTemplateParser();
        ComponentTemplate template = mockComponentTemplate();
        ComponentModel model = mockComponentModel();
        ComponentModel parentModel = mockComponentModel();

        train_getComponentClassName(model, PACKAGE + ".Barney");

        train_getBaseResource(model, baseBarney);

        train_findPageTemplateResource(locator, model, Locale.ENGLISH, null);

        train_getParentModel(model, parentModel);

        train_getBaseResource(parentModel, baseFred);

        train_parseTemplate(
                parser,
                baseFred.withExtension(InternalConstants.TEMPLATE_EXTENSION),
                template);

        replay();

        ComponentTemplateSource source = new ComponentTemplateSourceImpl(parser, locator);

        assertSame(source.getTemplate(model, Locale.ENGLISH), template);

        verify();
    }

    private Resource newResource(String name)
    {
        return new ClasspathResource(_loader, PATH + "/" + name);
    }
}
TOP

Related Classes of org.apache.tapestry.internal.services.ComponentTemplateSourceImplTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.