StyleContextTest.java :  » Apache-Harmony-Java-SE » javax-package » javax » swing » text » Java Open Source

Java Open Source » Apache Harmony Java SE » javax package 
javax package » javax » swing » text » StyleContextTest.java
/*
 *  Licensed to the Apache Software Foundation (ASF) under one or more
 *  contributor license agreements.  See the NOTICE file distributed with
 *  this work for additional information regarding copyright ownership.
 *  The ASF licenses this file to You 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.
 */
/**
 * @author Alexey A. Ivanov
 */
package javax.swing.text;

import java.awt.Color;
import java.awt.Font;
import java.lang.reflect.Field;
import java.util.Enumeration;
import java.util.Map;
import javax.swing.BasicSwingTestCase;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.text.StyleContext.SmallAttributeSet;
import junit.framework.TestCase;

public class StyleContextTest extends TestCase implements ChangeListener {
    /**
     * Shared style context object
     */
    protected static StyleContext sc;

    /**
     * The array of attribute key-value pair that is shared in the tests.
     */
    protected static final Object[] attr = { StyleConstants.Bold, Boolean.TRUE,
            StyleConstants.Italic, Boolean.TRUE, StyleConstants.Underline, Boolean.TRUE,
            StyleConstants.StrikeThrough, Boolean.TRUE, StyleConstants.Alignment,
            new Integer(1), StyleConstants.Background, Color.WHITE,
            StyleConstants.FirstLineIndent, new Float(0.75), StyleConstants.FontFamily,
            new String("monospaced"), StyleConstants.FontSize, new Integer(10),
            StyleConstants.Foreground, Color.BLACK };

    /**
     * Tracks that a change listener was been called.
     */
    private boolean bStateChanged;

    /**
     * Adds some attributes from <code>attr</code> array.
     *
     * @param as old attribute set to add to, may be null
     * @param start index of the first attribute in the array
     * @param count the number of attributes to add
     * @return new attribute set with attributes added
     */
    protected static AttributeSet addAttribute(AttributeSet as, int start, int count) {
        if (as == null) {
            as = sc.getEmptySet();
        }
        start <<= 1;
        count <<= 1;
        count += start;
        for (int i = start; i < count; i += 2) {
            as = sc.addAttribute(as, attr[i], attr[i + 1]);
        }
        return as;
    }

    /**
     * Adds some attributes from <code>attr</code> array, starting at index 0.
     *
     * @param as old attribute set to add to, may be null
     * @param count the number of attributes to add
     * @return new attribute set with attributes added
     * @see StyleContextTest#addAttribute(AttributeSet, int, int)
     */
    protected static AttributeSet addAttribute(final AttributeSet as, final int count) {
        return addAttribute(as, 0, count);
    }

    /**
     * Adds <code>count</code> attributes to a newly created attribute set
     * from <code>attr</code> array, starting at index 0.
     *
     * @param count the number of attributes to add
     * @return new attribute set with attributes added
     * @see StyleContextTest#addAttribute(AttributeSet, int, int)
     */
    protected static AttributeSet addAttribute(final int count) {
        return addAttribute(null, 0, count);
    }

    /**
     * Wrapper to access StyleContext.cache field.
     * @return style context's cache
     */
    protected static Map<?, ?> getSCCache() {
        try {
            Field f = sc.getClass().getDeclaredField("cache");
            f.setAccessible(true);
            return (Map<?, ?>) (f.get(sc));
        } catch (IllegalAccessException e) {
            fail(e.getMessage());
        } catch (NoSuchFieldException e) {
            fail(e.getMessage());
        }
        return null;
    }

    /**
     * Wrapper to access StyleContext.fontCache field.
     * @return style context's cache
     */
    protected static Map<?, ?> getSCFontCache() {
        try {
            Field f = sc.getClass().getDeclaredField("fontCache");
            f.setAccessible(true);
            return (Map<?, ?>) (f.get(sc));
        } catch (IllegalAccessException e) {
            fail(e.getMessage());
        } catch (NoSuchFieldException e) {
            fail(e.getMessage());
        }
        return null;
    }

    /*
     * @see TestCase#setUp()
     */
    @Override
    protected void setUp() throws Exception {
        sc = new StyleContext();
    }

    /**
     * Makes sure that after initialization, any style context will
     * contain exactly one style (default).
     */
    public void testStyleContext() {
        int count = 0;
        Enumeration<?> names = sc.getStyleNames();
        Object name = null;
        while (names.hasMoreElements()) {
            name = names.nextElement();
            count++;
        }
        assertEquals(1, count);
        assertEquals("default", (String) name);
    }

    public void testCollectGarbageInCache() {
        if (!BasicSwingTestCase.isHarmony()) {
            // This is internal test only
            return;
        }
        Map<?, ?> cache = getSCCache();
        assertEquals(2, cache.size());
        // Create an attribute set containing 10 items. This will
        // create sets with items from 1 to 10
        addAttribute(10);
        // The sets with number of items from 1 up to 9 will be cached
        // (Plus attribute set to support styles: the named style itself
        //  with "name" attribute and the reference to this style from
        //  the internal list of styles)
        assertEquals(9 + 2, cache.size());
        // Run the garbage collector several times
        for (int i = 0; i < 20; i++) {
            System.gc();
        }
        // Create an attribute set cotaining one and only item. This will
        // lead to a call to collectGarbageInCache method
        addAttribute(1);
        // The cache has been cleared but the newly created set is cached
        assertEquals(1 + 2, cache.size());
    }

    public void testCollectGarbageInCacheFont() {
        if (!BasicSwingTestCase.isHarmony()) {
            // This is internal test only
            return;
        }
        Map<?, ?> fontCache = getSCFontCache();
        assertEquals(0, fontCache.size());
        sc.getFont("Arial", Font.BOLD, 14);
        sc.getFont("Tahoma", Font.PLAIN, 8);
        assertEquals(2, fontCache.size());
        // Run the garbage collector several times
        for (int i = 0; i < 5; i++) {
            System.gc();
        }
        // Create an attribute set cotaining one and only item. This will
        // lead to a call to collectGarbageInCache method
        addAttribute(1);
        // The cache has been cleared but the newly created set is cached
        assertEquals(0, fontCache.size());
    }

    public void testAddStyle() {
        Style aStyle = sc.addStyle("aStyle", null);
        Style anotherStyle = sc.addStyle("anotherStyle", aStyle);
        int count = 0;
        boolean[] was = { false, false, false };
        String styleNames = new String();
        Enumeration<?> names = sc.getStyleNames();
        while (names.hasMoreElements()) {
            String name = (String) names.nextElement();
            styleNames += name + " ";
            if (name == "aStyle") {
                assertSame(aStyle, sc.getStyle(name));
                // Should contain only "name" attribute
                assertEquals(1, aStyle.getAttributeCount());
                assertNull(aStyle.getResolveParent());
                was[0] = true;
            } else if (name == "anotherStyle") {
                assertSame(anotherStyle, sc.getStyle(name));
                // Should contain "name" and "parent" attributes
                assertEquals(2, anotherStyle.getAttributeCount());
                assertNotNull(anotherStyle.getResolveParent());
                assertSame(aStyle, anotherStyle.getResolveParent());
                was[1] = true;
            } else if (name == "default") {
                sc.getStyle(name);
                assertEquals(1, aStyle.getAttributeCount());
                assertNull(aStyle.getResolveParent());
                was[2] = true;
            }
            count++;
        }
        assertEquals(3, count);
        for (int i = 0; i < was.length; i++) {
            assertTrue("The style named '"
                    + (i == 0 ? "aStyle" : (i == 1 ? "anotherStyle" : "default"))
                    + "' was not in the list.", was[i]);
        }
    }

    public void testAddStyleMisc() {
        // Add styles with diff parameters
        Object[] styles = { null, null, "one", null, null, sc.new NamedStyle(), "two",
                sc.new NamedStyle() };
        for (int i = 0; i < styles.length; i += 2) {
            Style style = sc.addStyle((String) styles[i], (Style) styles[i + 1]);
            assertEquals("Iteration: " + i, (String) styles[i], style.getName());
            assertSame("Iteration: " + i, styles[i + 1], style.getResolveParent());
        }
    }

    public void testAddStyleTwice() {
        final String styleName = "styleName";
        final Style style = sc.addStyle(styleName, null);
        final Style another = sc.addStyle(styleName, null);
        assertNotSame(style, another);
        assertSame(another, sc.getStyle(styleName));
    }

    public void testCreateSmallAttributeSet() {
        AttributeSet as = sc.createSmallAttributeSet(sc.getEmptySet());
        assertTrue(as instanceof SmallAttributeSet);
        assertEquals(0, as.getAttributeCount());
        assertEquals(sc.getEmptySet(), as);
    }

    public void testGetStyle() {
        Style style = sc.getStyle("default");
        assertEquals("default", style.getName());
        sc.addStyle("aStyle", style);
        style = sc.getStyle("aStyle");
        assertEquals("aStyle", style.getName());
        assertEquals("default", ((Style) style.getResolveParent()).getName());
    }

    public void testCreateLargeAttributeSet() {
        AttributeSet as = sc.createLargeAttributeSet(new SimpleAttributeSet());
        assertTrue(as instanceof SimpleAttributeSet);
    }

    public void testGetEmptySet() {
        assertSame(sc.getEmptySet(), sc.getEmptySet());
        assertEquals(0, sc.getEmptySet().getAttributeCount());
    }

    // test {add,remove}ChangeListener while adding styles
    public void testChangeListenerAddStyle() {
        bStateChanged = false;
        sc.addStyle("one", null);
        assertFalse(bStateChanged);
        sc.addChangeListener(this);
        bStateChanged = false;
        sc.addStyle("two", null);
        assertTrue(bStateChanged);
        sc.removeChangeListener(this);
        bStateChanged = false;
        sc.addStyle("three", null);
        assertFalse(bStateChanged);
    }

    // test if a listener gets called when adding style with null name
    public void testChangeListenerAddStyleNull() {
        sc.addChangeListener(this);
        bStateChanged = false;
        sc.addStyle(null, StyleContext.getDefaultStyleContext().new NamedStyle());
        assertFalse(bStateChanged);
        int count = 0;
        boolean wasNull = false;
        Enumeration<?> names = sc.getStyleNames();
        while (names.hasMoreElements()) {
            Object name = names.nextElement();
            wasNull = wasNull || name == null;
            count++;
        }
        assertEquals(1, count);
        assertFalse(wasNull);
    }

    // test {add,remove}ChangeListener while removing styles
    public void testChangeListenerRemoveStyle() {
        sc.addStyle("one", null);
        sc.addStyle("two", null);
        sc.addStyle("three", null);
        bStateChanged = false;
        sc.removeStyle("one");
        assertFalse(bStateChanged);
        sc.addChangeListener(this);
        bStateChanged = false;
        sc.removeStyle("two");
        assertTrue(bStateChanged);
        sc.removeChangeListener(this);
        bStateChanged = false;
        sc.removeStyle("three");
        assertFalse(bStateChanged);
    }

    public void testGetChangeListeners() {
        ChangeListener[] listeners = sc.getChangeListeners();
        assertEquals(0, listeners.length);
        sc.addChangeListener(this);
        listeners = sc.getChangeListeners();
        assertEquals(1, listeners.length);
        sc.removeChangeListener(this);
        listeners = sc.getChangeListeners();
        assertEquals(0, listeners.length);
    }

    public void testGetStyleNamesDef() {
        boolean wasDefault = false;
        int count = 0;
        Enumeration<?> names = sc.getStyleNames();
        while (names.hasMoreElements()) {
            String name = (String) names.nextElement();
            wasDefault = name == "default";
            count++;
        }
        assertEquals(1, count);
        assertTrue(wasDefault);
    }

    public void testGetStyleNames() {
        sc.addStyle("style", null);
        boolean wasDefault = false;
        boolean wasStyle = false;
        int count = 0;
        Enumeration<?> names = sc.getStyleNames();
        while (names.hasMoreElements()) {
            String name = (String) names.nextElement();
            wasDefault = wasDefault || name == "default";
            wasStyle = wasStyle || name == "style";
            count++;
        }
        assertEquals(2, count);
        assertTrue(wasDefault);
        assertTrue(wasStyle);
    }

    public void testRemoveStyle() {
        sc.addStyle("style", null);
        sc.removeStyle("style");
        boolean wasDefault = false;
        boolean wasStyle = false;
        int count = 0;
        Enumeration<?> names = sc.getStyleNames();
        while (names.hasMoreElements()) {
            String name = (String) names.nextElement();
            wasDefault = wasDefault || "default".equals(name);
            wasStyle = wasStyle || "style".equals(name);
            count++;
        }
        assertEquals(1, count);
        assertTrue(wasDefault);
        assertFalse(wasStyle);
    }

    public void testToString() {
        Style style = sc.getStyle(StyleContext.DEFAULT_STYLE);
        style.addAttribute(StyleConstants.Bold, Boolean.TRUE);
        style.addAttribute(StyleConstants.Italic, Boolean.FALSE);
        style = sc.addStyle("aStyle", null);
        style.addAttribute(StyleConstants.FontFamily, "Arial");
        style.addAttribute(StyleConstants.FontSize, new Integer(14));
        sc.getFont(style);
        String[] asStr = new String[] { "{family=Arial,name=aStyle,size=14,}",
                "{default=AttributeSet,}", "{family=Arial,name=aStyle,}",
                "{aStyle=AttributeSet,default=AttributeSet,}",
                "{italic=false,bold=true,name=default,}", "{name=default,}", "{name=aStyle,}",
                "{name=default,bold=true,}", };
        String scStr = sc.toString();
        assertNotNull(scStr);
        String[] splitStrs = scStr.replaceAll("\r", "").split("\n");
        assertEquals(asStr.length, splitStrs.length);
        boolean[] met = new boolean[splitStrs.length];
        for (int i = 0; i < splitStrs.length; i++) {
            for (int j = 0; j < asStr.length; j++) {
                if (asStr[j].length() == splitStrs[i].length()
                        && assertAttributes(trimEnds(asStr[j]).split(","), trimEnds(
                                splitStrs[i]).split(","))) {
                    met[j] = true;
                }
            }
        }
        for (int i = 0; i < met.length; i++) {
            assertTrue("asStr[" + i + "] is missing", met[i]);
        }
    }

    public static boolean assertAttributes(final String[] expAttrs, final String[] realAttrs) {
        if (expAttrs.length != realAttrs.length) {
            return false;
        }
        boolean[] met = new boolean[expAttrs.length];
        for (int i = 0; i < realAttrs.length; i++) {
            for (int j = 0; j < expAttrs.length; j++) {
                if (expAttrs[j].equals(realAttrs[i])) {
                    met[j] = true;
                }
            }
        }
        boolean result = true;
        for (int i = 0; i < met.length && result; i++) {
            result = met[i];
        }
        return result;
    }

    public static String trimEnds(final String str) {
        assertEquals('{', str.charAt(0));
        final int len = str.length();
        assertEquals('}', str.charAt(len - 1));
        assertEquals(',', str.charAt(len - 2));
        return str.substring(1, len - 2);
    }

    public void testGetCompressionThreshold() {
        assertEquals(9, sc.getCompressionThreshold());
    }

    public void testGetDefaultStyleContext() {
        StyleContext def;
        assertSame(def = StyleContext.getDefaultStyleContext(), StyleContext
                .getDefaultStyleContext());
        int count = 0;
        Enumeration<?> names = def.getStyleNames();
        Object name = null;
        while (names.hasMoreElements()) {
            count++;
            name = names.nextElement();
        }
        assertEquals(1, count);
        assertEquals(StyleContext.DEFAULT_STYLE, (String) name);
    }

    /**
     * A class to test caching technique.
     * Stores values returned by createSmallAttributeSet in array.
     */
    private static class StyleContextX extends StyleContext {
        private static final long serialVersionUID = 1L;

        public int count;

        public AttributeSet[] attrSet;

        public StyleContextX() {
            count = 0;
            attrSet = new AttributeSet[20];
        }

        @Override
        public SmallAttributeSet createSmallAttributeSet(final AttributeSet a) {
            if (attrSet == null) {
                // This condition is true in StyleContext's constructor
                return super.createSmallAttributeSet(a);
            }
            attrSet[count] = super.createSmallAttributeSet(a);
            return (SmallAttributeSet) attrSet[count++];
        }

        @Override
        public MutableAttributeSet createLargeAttributeSet(final AttributeSet a) {
            attrSet[count] = super.createLargeAttributeSet(a);
            return (MutableAttributeSet) attrSet[count++];
        }
    }

    public void testCaching() {
        StyleContextX sc = new StyleContextX();
        int addStyle = sc.count;
        sc.addStyle("aStyle", null);
        int addAttr = sc.count;
        AttributeSet as = sc.addAttribute(sc.getEmptySet(), AttributeSet.NameAttribute,
                "aStyle");
        assertFalse(addStyle == addAttr);
        assertSame(sc.attrSet[addStyle], as);
    }

    /*
     public void testReclaim() {
     }
     */
    public void stateChanged(final ChangeEvent event) {
        bStateChanged = true;
    }
}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.