Package com.salas.bb.views.mainframe

Source Code of com.salas.bb.views.mainframe.TestFeedSelectionListener$CustomCSL

// BlogBridge -- RSS feed reader, manager, and web based service
// Copyright (C) 2002-2006 by R. Pito Salas
//
// This program 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.
//
// This program 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 this program;
// if not, write to the Free Software Foundation, Inc., 59 Temple Place,
// Suite 330, Boston, MA 02111-1307 USA
//
// Contact: R. Pito Salas
// mailto:pitosalas@users.sourceforge.net
// More information: about BlogBridge
// http://www.blogbridge.com
// http://sourceforge.net/projects/blogbridge
//
// $Id: TestFeedSelectionListener.java,v 1.5 2008/02/28 15:59:52 spyromus Exp $
//

package com.salas.bb.views.mainframe;

import com.salas.bb.core.GlobalModel;
import com.salas.bb.domain.DirectFeed;
import com.salas.bb.domain.IFeed;
import com.salas.bb.domain.prefs.UserPreferences;
import junit.framework.TestCase;

import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
import java.beans.PropertyChangeEvent;

/**
* This suite contains tests for <code>FeedSelectionListener</code>.
* It covers:
* <ul>
<li>Zero-delay selection of feeds.</li>
<li>Delayed selection of feeds with various permitted delays.</li>
<li>Quick selection of several feeds with triggering of the last selection only.</li>
* </ul>
*/
public class TestFeedSelectionListener extends TestCase
{
    private static final long MAX_ZERO_DELAY_TIME = 30;
    private static final double DELAY_PRECISION = 0.4;

    private JList       list;
    private CustomCSL   listener;
    private IFeed       feed0;
    private IFeed       feed1;

    /**
     * Initialization before the tests.
     */
    protected void setUp()
    {
        listener = new CustomCSL(0);

        feed0 = new DirectFeed();
        feed1 = new DirectFeed();
        list = new JList(new IFeed[] { feed0, feed1 });
        list.addListSelectionListener(listener);
    }

    /**
     * Tests that the feed is selected immediately, withing the same thread and
     * it takes limited time (controlled by <code>MAX_ZERO_DELAY_TIME</code>
     * constant).
     */
    public void testFeedSelectionDelayZero()
    {
        // Select the first feed and get the delay without wating while holding the lock
        // to disallow the other threads to access listener. It will guaranty that the
        // threads aren't forked for zero-delays.
        long actualDelay;
        synchronized (listener)
        {
            list.setSelectedIndex(0);
            actualDelay = listener.waitForEvent(0);
        }

        assertFalse("Initial event (valueChanged()) didn't come.", actualDelay == -1);
        assertFalse("The feed wasn't selected in time.", actualDelay == -2);
        assertTrue("Too long selection: allowed=" + MAX_ZERO_DELAY_TIME + " actual=" + actualDelay,
            actualDelay < MAX_ZERO_DELAY_TIME);
    }

    /**
     * Tests that feeds are selected with proper delays (the error stays in defined bounds).
     */
    public void testFeedSelectionDelay()
    {
        for (int i = 0; i < 5; i++)
        {
            // Compute delay [100;500] and corresponding allowed error 33%
            long delay = (i * 100) + 100;
            long error = (long)(delay * DELAY_PRECISION);
            listener.setFeedSelectionDelay(delay);

            // Select feed and wait for selection event
            list.setSelectedIndex(i % 2);
            long actualDelay = listener.waitForEvent(delay + error);

            assertFalse("valueChanged() didn't come: delay=" + delay, actualDelay == -1);
            assertFalse("The feed wasn't selected in time: delay=" + delay, actualDelay == -2);
            assertTrue("Too fast selection: delay=" + delay + ", actual=" + actualDelay,
                actualDelay > (delay - error));

            // Reset the times for the next loop
            listener.reset();
        }
    }

    /**
     * Tests that if the selection events come faster than the delayed selection
     * triggers only one (the last) event will be triggered in the end after the delay.
     */
    public void testQuickFeedSelection()
    {
        GlobalModel.SINGLETON = new GlobalModel(null);
       
        // Compute delay [100;500] and corresponding allowed error 33%
        long delay = 500;
        long error = (long)(delay * DELAY_PRECISION);
        long waitTime = delay - error;
        listener.setFeedSelectionDelay(delay);

        // Select first item and wait for some time (less than delay including error)
        list.setSelectedIndex(0);
        long actualDelay = listener.waitForEvent(waitTime);

        // Fast check to save time
        if (actualDelay >= -1)
        {
            assertFalse("valueChanged() didn't come.", actualDelay == -1);
            assertTrue("The feed wasn't selected faster than required.", actualDelay == -2);
        }

        // Select the second feed before the delay expires to start new delay counting
        // and wait for the calculated time as if the feed was first.
        list.setSelectedIndex(1);
        actualDelay = listener.waitForEvent(delay + error);

        long minDelay = waitTime + (delay - error);
        assertTrue("Too fast selection: min=" + minDelay + ", actual=" + actualDelay, actualDelay > minDelay);
        assertTrue("Wrong feed selected.", feed1 == list.getSelectedValue());
    }

    // ---------------------------------------------------------------------------------------------
    // Helper classes and methods
    // ---------------------------------------------------------------------------------------------

    /**
     * Listener which is recording call times of <code>valueChanged()</code> and
     * <code>selectFeed</code> methods for further measurements. It also allows to wait
     * for a both methods called in a given period of time.
     */
    private static class CustomCSL extends FeedSelectionListener
    {
        private long selectFeedTime;
        private long valueChangedTime;

        /**
         * Creates the custom test listener.
         *
         * @param delay initial delay.
         */
        public CustomCSL(long delay)
        {
            super(delay);
            reset();
        }

        /**
         * Sets the delay. This method is named the same way as the underlying private
         * method intentionally. If at some moment will decide to expose that method
         * to outer world or subclasses we will need to remove this declaration and
         * every test will continue to work as is.
         *
         * @param delay delay.
         */
        public void setFeedSelectionDelay(long delay)
        {
            propertyChange(new PropertyChangeEvent(this,
                UserPreferences.PROP_FEED_SELECTION_DELAY,
                new Integer(-1), new Integer((int)delay)));
        }

        /**
         * Resets the times.
         */
        public synchronized void reset()
        {
            selectFeedTime = -1;
            valueChangedTime = -1;
        }

        /**
         * Select feed if it's not currently selected.
         *
         * @param feed feed to select.
         */
        protected void selectFeed(IFeed feed)
        {
            // Experimental delay to check that test catches the delays correctly
//            try
//            {
//                Thread.sleep(1000);
//            } catch (InterruptedException e)
//            {
//            }

            synchronized (this)
            {
                selectFeedTime = System.currentTimeMillis();
                notifyAll();
            }
        }

        /**
         * Call this whenever user clicks on one of the Channels in the ChannelList.
         *
         * @param e event object.
         */
        public synchronized void valueChanged(final ListSelectionEvent e)
        {
            valueChangedTime = System.currentTimeMillis();
            super.valueChanged(e);
        }

        /**
         * Waits for event if it didn't happen yet and returns the delay between calls
         * to <code>valueChanged()</code> and <code>selectFeed()</code> methods. If the
         * first wasn't called then (-1) will be returned, if the second wasn't called
         * (-2) will be returned.
         *
         * @param period maximum time to wait (in ms).
         *
         * @return delay in ms between calls or (-1) if <code>valueChanged()</code>
         *         wasn't called or (-2) if <code>selectFeed()</code> wasn't called.
         */
        public synchronized long waitForEvent(long period)
        {
            if (selectFeedTime == -1 && period > 0)
            {
                try
                {
                    wait(period);
                } catch (InterruptedException e)
                {
                }
            }

            return valueChangedTime == -1 ? -1
                   : selectFeedTime == -1 ? -2
                       : selectFeedTime - valueChangedTime;
        }
    }
}
TOP

Related Classes of com.salas.bb.views.mainframe.TestFeedSelectionListener$CustomCSL

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.