1 /*
   2  * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package com.sun.javafx.event;
  27 
  28 import java.util.Arrays;
  29 import java.util.Collection;
  30 
  31 import javafx.event.EventDispatchChain;
  32 
  33 import org.junit.Test;
  34 import org.junit.Assert;
  35 import org.junit.runner.RunWith;
  36 import org.junit.runners.Parameterized;
  37 import org.junit.runners.Parameterized.Parameters;
  38 
  39 @RunWith(Parameterized.class)
  40 public final class EventDispatchChainTest {
  41     private static final Operation[] IDENTITY_FUNCTION_OPS = {
  42         Operation.mul(3), Operation.add(5), Operation.mul(4), Operation.sub(2),
  43         Operation.div(6), Operation.add(9), Operation.div(2), Operation.sub(6)
  44     };
  45 
  46     @Parameters
  47     public static Collection data() {
  48         return Arrays.asList(
  49                 new Object[][] {
  50                     { EventDispatchChainImpl.class },
  51                     { EventDispatchTreeImpl.class }
  52                 });
  53     }
  54 
  55     private EventDispatchChain eventDispatchChain;
  56 
  57     public EventDispatchChainTest(final Class<EventDispatchChain> chainClass) 
  58             throws InstantiationException, IllegalAccessException {
  59         eventDispatchChain = chainClass.newInstance();
  60     }
  61 
  62     @Test
  63     public void chainConstructionBeforeDispatchTest() {
  64         eventDispatchChain = initializeTestChain(eventDispatchChain);
  65         verifyChain(eventDispatchChain, 0, 702);
  66     }
  67 
  68     @Test
  69     public void chainModificationAfterDispatchTest() {
  70         eventDispatchChain = initializeTestChain(eventDispatchChain);
  71         eventDispatchChain.dispatchEvent(new ValueEvent());
  72 
  73         eventDispatchChain = eventDispatchChain.append(
  74                                      new EventChangingDispatcher(
  75                                          Operation.sub(6),
  76                                          Operation.div(3)));
  77         verifyChain(eventDispatchChain, 0, 270);
  78 
  79         eventDispatchChain = prependIdentityChain(eventDispatchChain);
  80         verifyChain(eventDispatchChain, 0, 270);
  81     }
  82 
  83     @Test
  84     public void chainModificationDuringDispatchTest() {
  85         // x + 55, y + 55
  86         eventDispatchChain = prependSeriesChain(eventDispatchChain, 10);
  87         eventDispatchChain = 
  88                 eventDispatchChain.prepend(
  89                         new PathChangingDispatcher(
  90                             new EventChangingDispatcher(Operation.mul(3),
  91                                                         Operation.div(5)),
  92                             new EventChangingDispatcher(Operation.div(7),
  93                                                         Operation.mul(9)),
  94                             1));
  95         // x + 15, y + 15
  96         eventDispatchChain = prependSeriesChain(eventDispatchChain, 5);
  97         
  98         eventDispatchChain =
  99                 eventDispatchChain.prepend(
 100                         new PathChangingDispatcher(null, null, 2));
 101         
 102         // x + 6, y + 6
 103         eventDispatchChain = prependSeriesChain(eventDispatchChain, 3);
 104 
 105         for (int x = 0; x < 5; ++x) {
 106             verifyChain(eventDispatchChain, 1225 * x - 86, 729 * x + 50);
 107         }
 108     }
 109 
 110     @Test
 111     public void buildLongChainTest() {
 112         eventDispatchChain = prependSeriesChain(eventDispatchChain, 100);
 113         verifyChain(eventDispatchChain, 0, 10100);
 114 
 115         eventDispatchChain = prependIdentityChain(eventDispatchChain);
 116         verifyChain(eventDispatchChain, 1, 10101);
 117 
 118         eventDispatchChain = prependSeriesChain(eventDispatchChain, 100);
 119         verifyChain(eventDispatchChain, 2, 20202);
 120     }
 121 
 122     private static EventDispatchChain prependIdentityChain(
 123             EventDispatchChain tailChain) {
 124         for (int i = 0; i < IDENTITY_FUNCTION_OPS.length; ++i) {
 125             tailChain = tailChain.prepend(
 126                     new EventChangingDispatcher(
 127                             IDENTITY_FUNCTION_OPS[
 128                                     IDENTITY_FUNCTION_OPS.length - i - 1],
 129                             IDENTITY_FUNCTION_OPS[i]));
 130         }
 131 
 132         return tailChain;
 133     }
 134 
 135     private static EventDispatchChain prependSeriesChain(
 136             EventDispatchChain tailChain, final int count) {
 137         for (int i = 1; i <= count; ++i) {
 138             tailChain = tailChain.prepend(
 139                     new EventChangingDispatcher(Operation.add(i),
 140                                                 Operation.add(i)));
 141         }
 142 
 143         return tailChain;
 144     }
 145 
 146     private static EventDispatchChain initializeTestChain(
 147             final EventDispatchChain emptyChain) {
 148         return emptyChain.append(new EventChangingDispatcher(
 149                                      Operation.add(3),
 150                                      Operation.div(2)))
 151                          .append(new EventChangingDispatcher(
 152                                      Operation.mul(7),
 153                                      Operation.sub(6)))
 154                          .prepend(new EventChangingDispatcher(
 155                                       Operation.sub(4),
 156                                       Operation.mul(6)))
 157                          .append(new EventChangingDispatcher(
 158                                      Operation.div(3),
 159                                      Operation.add(11)))
 160                          .prepend(new EventChangingDispatcher(
 161                                       Operation.add(10),
 162                                       Operation.mul(9)));
 163     }
 164 
 165     private static void verifyChain(final EventDispatchChain testChain,
 166                                     final int initialValue,
 167                                     final int resultValue) {
 168         final ValueEvent valueEvent =
 169                 (ValueEvent) testChain.dispatchEvent(
 170                                      new ValueEvent(initialValue));
 171 
 172         Assert.assertNotNull(valueEvent);
 173         Assert.assertEquals(resultValue, valueEvent.getValue());
 174     }
 175 }