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 }