1 /* 2 * Copyright (c) 2020, 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 myapp2; 27 28 import java.io.IOException; 29 import java.net.URL; 30 import java.util.ArrayList; 31 import java.util.Iterator; 32 import java.util.List; 33 import java.util.Set; 34 import java.util.TreeMap; 35 36 import javafx.application.Application; 37 import javafx.application.Platform; 38 import javafx.event.ActionEvent; 39 import javafx.fxml.FXMLLoader; 40 import javafx.scene.Node; 41 import javafx.scene.Parent; 42 import javafx.scene.Scene; 43 import javafx.scene.control.Button; 44 import javafx.scene.input.MouseButton; 45 import javafx.scene.input.MouseEvent; 46 import javafx.scene.layout.AnchorPane; 47 import javafx.stage.Stage; 48 49 import javax.script.Bindings; 50 import javax.script.ScriptContext; 51 52 import static myapp2.Constants.*; 53 import pseudoScriptEngineCompilable.InvocationInfos; 54 import pseudoScriptEngineCompilable.RgfPseudoScriptEngineCompilable; 55 56 /** 57 * Modular test application for testing FXML. 58 * This is launched by ModuleLauncherTest. 59 */ 60 public class FXMLScriptDeployment2Compile_On extends Application { 61 62 static boolean bDebug = false; // true; // display invocation list 63 64 /** Runs the application and invokes the tests. 65 * @param args the command line arguments, if any given the RgfPseudoScriptEngine invocation logs get displayed 66 * which are used in the asserCorrectInvocations() method 67 */ 68 public static void main(String[] args) { 69 try { 70 // any argument will cause the bDebug flag to be set to true 71 if (args.length > 0) { 72 bDebug = true; 73 } 74 new FXMLScriptDeployment2Compile_On().launch(); 75 // for debugging, allows to study invocation logs in detail 76 if (bDebug) { dumpEvalInformation(); } 77 assertCorrectInvocations(); 78 } catch (AssertionError ex) { 79 System.err.println("ASSERTION ERROR: caught unexpected exception: " + ex); 80 ex.printStackTrace(System.err); 81 System.exit(ERROR_ASSERTION_FAILURE); 82 } catch (Error | Exception ex) { 83 System.err.println("ERROR: caught unexpected exception: " + ex); 84 ex.printStackTrace(System.err); 85 System.exit(ERROR_UNEXPECTED_EXCEPTION); 86 } 87 System.exit(ERROR_NONE); // not in stop() method as we need to run the assertions first 88 } 89 90 @Override 91 public void start(Stage mainStage) { 92 URL fxmlUrl = null; 93 Parent rootNode = null; 94 Scene scene = null; 95 Button btn = null; 96 try { 97 fxmlUrl = Util.getURL(FXMLScriptDeployment2Compile_On.class, "demo_02_on"); 98 rootNode = FXMLLoader.load(fxmlUrl); 99 scene = new Scene(rootNode); 100 btn = (Button) scene.lookup("#idButton"); 101 } 102 catch (Exception ioe) { 103 ioe.printStackTrace(); 104 System.exit(ERROR_UNEXPECTED_EXCEPTION); 105 } 106 // fire three events on the button 107 btn.fire(); 108 btn.fireEvent(new ActionEvent()); 109 btn.fireEvent(new MouseEvent(MouseEvent.MOUSE_CLICKED, 110 0, // double x, 111 0, // double y, 112 0, // double screenX, 113 0, // double screenY, 114 MouseButton.PRIMARY, // MouseButton button, 115 0, // int clickCount, 116 false, // boolean shiftDown, 117 false, // boolean controlDown, 118 false, // boolean altDown, 119 false, // boolean metaDown, 120 true, // boolean primaryButtonDown, 121 false, // boolean middleButtonDown, 122 false, // boolean secondaryButtonDown, 123 false, // boolean synthesized, 124 false, // boolean popupTrigger, 125 false, // boolean stillSincePress, 126 null // PickResult pickResult 127 ) 128 ); 129 130 // mainStage.setScene(scene); 131 // mainStage.show(); 132 Platform.exit(); 133 } 134 135 // show engine invocations with script text and their Bindings 136 static void dumpEvalInformation() { 137 System.err.println("\nListing eval() invocation information (invocationList):"); 138 139 Iterator<RgfPseudoScriptEngineCompilable> it = RgfPseudoScriptEngineCompilable.getEnginesUsed().iterator(); 140 while (it.hasNext()) { 141 RgfPseudoScriptEngineCompilable rpse = it.next(); 142 ArrayList invocationList = rpse.getInvocationList(); 143 System.err.println("ScriptEngine: [" + rpse + "]"); 144 145 Iterator<InvocationInfos> itEval = invocationList.iterator(); 146 int count = 1; 147 while (itEval.hasNext()) { 148 System.err.println("\teval() invocation # " + count + ": "); 149 InvocationInfos entry = itEval.next(); 150 System.err.println(entry.toDebugFormat("\t\t")); // indentation 151 count++; 152 System.err.println(); 153 } 154 } 155 } 156 157 static void assertCorrectInvocations() { 158 // test only creates one engine for a script controller 159 Util.assertTrue("exactly one pseudo script engine instance", 160 RgfPseudoScriptEngineCompilable.getEnginesUsed().size() == 1); 161 RgfPseudoScriptEngineCompilable rpse = RgfPseudoScriptEngineCompilable.getEnginesUsed().get(0); 162 163 ArrayList invocationList = rpse.getInvocationList(); 164 Util.assertTrue("exactly nine script engine invocations", invocationList.size() == 9); 165 166 final String FILENAME = "javax.script.filename"; 167 final String ARGV = "javax.script.argv"; 168 final String EVENT = "event"; 169 final String IDBUTTON = "idButton"; 170 final String IDROOT = "idRoot"; 171 final String LOCATION = "location"; // always FXML File hosting script controller code 172 final String RESOURCES = "resources"; // always null in this test 173 174 for (Integer invocation = 1; invocation <= invocationList.size(); invocation++) { 175 InvocationInfos entry = (InvocationInfos) invocationList.get(invocation - 1); 176 String script = entry.script; 177 TreeMap<Integer,TreeMap> scopes = (TreeMap) entry.bindings; 178 179 TreeMap<String,Object> engineBindings = scopes.get(100); 180 TreeMap<String,Object> globalBindings = scopes.get(200); 181 182 Object obj = null; 183 Button btn = null; 184 185 // global Bindings 186 Util.assertExists(IDROOT + " in global scope Bindings", globalBindings.containsKey(IDROOT)); 187 obj = globalBindings.get(IDROOT); 188 Util.assertType(IDROOT, AnchorPane.class, obj); 189 190 Util.assertExists(LOCATION + " in global scope Bindings", globalBindings.containsKey(LOCATION)); 191 obj = globalBindings.get(LOCATION); 192 Util.assertType(LOCATION, URL.class, obj); 193 194 Util.assertExists(RESOURCES + " in global scope Bindings", globalBindings.containsKey(RESOURCES)); 195 obj = globalBindings.get(RESOURCES); 196 Util.assertNull(RESOURCES,obj); 197 198 if (invocation == 1) { 199 Util.assertNotExists(IDBUTTON + " in global scope Bindings", globalBindings.containsKey(IDBUTTON)); 200 } 201 else { 202 Util.assertExists(IDBUTTON + " in global scope Bindings", globalBindings.containsKey(IDBUTTON)); 203 obj = globalBindings.get(IDBUTTON); 204 Util.assertType(IDBUTTON, Button.class, obj); 205 btn = (Button) obj; 206 } 207 208 // engine Bindings 209 Util.assertExists(FILENAME + " in engine scope Bindings", engineBindings.containsKey(FILENAME)); 210 if (invocation < 7) { // no event objects, no arguments 211 Util.assertNotExists(ARGV + " in engine scope Bindings", engineBindings.containsKey(ARGV)); 212 Util.assertNotExists(EVENT + " in engine scope Bindings", engineBindings.containsKey(EVENT)); 213 } 214 else { // this has events on the Button 215 Util.assertExists(ARGV + " in engine scope Bindings", engineBindings.containsKey(ARGV)); 216 Object[] argv = (Object[]) engineBindings.get(ARGV); 217 218 Util.assertExists(EVENT + " in engine scope Bindings", engineBindings.containsKey(EVENT)); 219 obj = engineBindings.get(EVENT); 220 221 Util.assertSame("argv[0] == event", argv[0], obj); 222 223 if (invocation == 9) { 224 Util.assertType(EVENT, MouseEvent.class, obj); 225 MouseEvent ev = (MouseEvent) obj; 226 Util.assertSame("MouseEvent.getSource() == btn", ev.getSource(), btn); 227 Util.assertSame("MouseEvent.MOUSE_CLICKED", MouseEvent.MOUSE_CLICKED, ev.getEventType()); 228 } else { 229 Util.assertType(EVENT, ActionEvent.class, obj); 230 ActionEvent ev = (ActionEvent) obj; 231 Util.assertSame("ActionEvent.getSource() == btn", ev.getSource(), btn); 232 } 233 } 234 235 // check filename and script 236 String filename = (String) engineBindings.get(FILENAME); 237 boolean ok = false; 238 switch (invocation) { 239 case 1: 240 Util.assertEndsWith ("demo_02_topscript.sqtmc", filename); 241 Util.assertStartsWith("RgfPseudoCompiledScript.eval(): RgfPseudoCompiledScript=[demo_02_topscript.sqtmc file - pseudo script", script); 242 break; 243 244 case 2: 245 Util.assertEndsWith ("demo_02_middlescript.sqtmc", filename); 246 Util.assertStartsWith("RgfPseudoCompiledScript.eval(): RgfPseudoCompiledScript=[demo_02_middlescript.sqtmc file - pseudo script", script); 247 break; 248 249 case 3: 250 Util.assertEndsWith("demo_02_on.fxml-script_starting_at_line_52", filename); 251 Util.assertStartsWith("RgfPseudoCompiledScript.eval(): RgfPseudoCompiledScript=[demo_02_on.fxml embedded script sqtmc - line # 52", script); 252 break; 253 254 case 4: 255 Util.assertEndsWith ("demo_02_bottomscript.sqtmc", filename); 256 Util.assertStartsWith("RgfPseudoCompiledScript.eval(): RgfPseudoCompiledScript=[demo_02_bottomscript.sqtmc file - pseudo script", script); 257 break; 258 259 case 5: 260 Util.assertEndsWith("demo_02_on.fxml-script_starting_at_line_56", filename); 261 Util.assertStartsWith("RgfPseudoCompiledScript.eval(): RgfPseudoCompiledScript=[something (line # 56)", script); 262 break; 263 264 case 6: 265 Util.assertEndsWith("demo_02_on.fxml-script_starting_at_line_59", filename); 266 Util.assertStartsWith("RgfPseudoCompiledScript.eval(): RgfPseudoCompiledScript=[demo_02_on.fxml (line # 59):", script); 267 break; 268 269 case 7: // same as case 8 (same button clicked) 270 Util.assertEndsWith("demo_02_on.fxml-onAction_attribute_in_element_ending_at_line_46", filename); 271 Util.assertStartsWith("RgfPseudoCompiledScript.eval(Bindings bindings): RgfPseudoCompiledScript=[demo_02_on.fxml embedded event - ActionEvent - line # 45 -", script); 272 break; 273 274 case 8: // same as case 7 (same button clicked) 275 Util.assertEndsWith("demo_02_on.fxml-onAction_attribute_in_element_ending_at_line_46", filename); 276 Util.assertStartsWith("RgfPseudoCompiledScript.eval(Bindings bindings): RgfPseudoCompiledScript=[demo_02_on.fxml embedded event - ActionEvent - line # 45 -", script); 277 break; 278 279 case 9: 280 Util.assertEndsWith("demo_02_on.fxml-onMouseClicked_attribute_in_element_ending_at_line_46", filename); 281 Util.assertStartsWith("RgfPseudoCompiledScript.eval(Bindings bindings): RgfPseudoCompiledScript=[demo_02_on.fxml embedded event - MouseClicked - line # 44", script); 282 break; 283 } 284 } 285 } 286 }