FileDocCategorySizeDatePackage
Test6254765.javaAPI DocphoneME MR2 API (J2ME)7651Wed May 02 18:00:18 BST 2007javax.microedition.lcdui

Test6254765

public class Test6254765 extends com.sun.midp.i3test.TestCase
Regression tests for CR 6254765. There are actually two bugs mentioned there. Details are provided for each test case.

Fields Summary
Display
dpy
Constructors Summary
Methods Summary
booleancheckValidLayout(Form form)
Checks all of the itemLFs of the given form to see if their layouts are valid. Returns true if all are valid, false if any one is invalid.

        FormLFImpl formLF = (FormLFImpl)form.formLF;
        ItemLFImpl itemLF;
        boolean anyInvalid = false;

        for (int ii = 0; ii < formLF.numOfLFs; ii++) {
            itemLF = formLF.itemLFs[ii];
            boolean thisInvalid = 
                itemLF.actualBoundsInvalid[0] ||
                itemLF.actualBoundsInvalid[1] ||
                itemLF.actualBoundsInvalid[2] ||
                itemLF.actualBoundsInvalid[3];
            anyInvalid = anyInvalid || thisInvalid;
            // System.out.println(
            //     "item[" + ii + "] bounds (" +
            //     itemLF.bounds[0] + ", " +
            //     itemLF.bounds[1] + ", " +
            //     itemLF.bounds[2] + ", " +
            //     itemLF.bounds[3] + ")" +
            //     (thisInvalid ? " INVALID" : ""));
        }

        return !anyInvalid;
    
public voidrunTests()


        if (!LcduiTestMIDlet.invoke()) {
            throw new RuntimeException("can't start LcduiTestMIDlet");
        }

        try {
            dpy = LcduiTestMIDlet.getDisplay();

            declare("testScreenChangeAppend");
            testScreenChangeAppend();

            declare("testTraversalInconsistency");
            testTraversalInconsistency();

        } finally {
            LcduiTestMIDlet.cleanup();
        }
    
voidtestScreenChangeAppend()
Regression test for the main CR described in CR 6254765. This is a race condition between modifying a Form's contents (for example, with append) while the Form is in the process of becoming current.

        StringItem items[] = new StringItem[10];
        final Baton baton = new Baton();

        for (int ii = 0; ii < items.length; ii++) {
            items[ii] = new StringItem(null, Integer.toString(ii % 10));
        }

        Form form = new Form("Test Form");

        // gets called from dpy.callScreenChange() after uCallShow()
        dpy.liveTracer.add(
            Display.LTR_SCREENCHANGE_AFTERSHOW,
            new LiveTraceListener() {
                public void call(String tag) {
                    baton.pass();
                }
            });

        dpy.setCurrent(form);

        for (int ii = 0; ii < items.length; ii++) {
            form.append(items[ii]);
            if (ii == 3) {
                baton.start();
            }
        }
        baton.finish();

        // wait for queued events to be processed
        new SerialCallback(dpy).invokeAndWait();

        assertTrue("layout must be valid", checkValidLayout(form));
        dpy.liveTracer.clear();
    
voidtestTraversalInconsistency()
This is a regression test for another CR that is also mentioned in 6254765, which occurs when the form is in an inconsistent state such as what arose from the initial CR, but which can also arise for other reasons. This case is as follows: traverseIndex == -1 and itemTraverse == false, indicating no initial focus; and getNextInteractiveItem returns a value >= 0 indicating that there is a focusable item on screen. The uTraverse() code assumes that if getNextInteractiveItem returns some nonnegative value, there must be a currently focused item (that is, traverseIndex is also nonnegative). However, this is not always the case. This can occur if the form initially has no visible focusable items, and the app adds a focusable item, which triggers an invalidate, and then the user traverses before the invalidate can be processed. This test simulates that case.

        Form form = new Form("Test Form 2");
        FormLFImpl formLF = (FormLFImpl)form.formLF;
        final Baton baton = new Baton();
        SerialCallback scb = new SerialCallback(dpy);

        // can be any interactive item
        Item item = new Gauge(null, true, 1, 0);

        // Set up a form with no focusable item.

        form.append("String 1");
        dpy.setCurrent(form);
        scb.invokeAndWait();

        // Block the event queue to prevent the invalidate from
        // being processed.

        dpy.callSerially(
            new Runnable() {
                public void run() {
                    baton.pass();
                }
            });
        baton.start();

        // Append a focusable item to the form, and then call
        // uTraverse() directly, as if a key had been pressed at
        // exactly the right moment.

        form.insert(0, item);
        formLF.uTraverse(Canvas.DOWN);
        baton.finish();

        // Wait for the invalidate to finish processing, then
        // check assertions.

        scb.invokeAndWait();
        assertEquals("item 0 should be focused", 0, formLF.traverseIndex);