1 /* 2 * Copyright (c) 2015, 2016, 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. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 import java.util.concurrent.ExecutorService; 25 import java.util.concurrent.Executors; 26 import java.util.function.Consumer; 27 28 import org.testng.annotations.Test; 29 30 import static org.testng.Assert.assertEquals; 31 import static org.testng.Assert.assertTrue; 32 33 public abstract class EditorTestBase extends ReplToolTesting { 34 35 private static ExecutorService executor; 36 37 public abstract void writeSource(String s); 38 public abstract String getSource(); 39 public abstract void accept(); 40 public abstract void exit(); 41 public abstract void cancel(); 42 public abstract void shutdownEditor(); 43 44 public void testEditor(ReplTest... tests) { 45 testEditor(false, new String[]{"--no-startup"}, tests); 46 } 47 48 public void testEditor(boolean defaultStartup, String[] args, ReplTest... tests) { 49 test(defaultStartup, args, tests); 50 } 51 52 public abstract void assertEdit(boolean after, String cmd, 53 Consumer<String> checkInput, Consumer<String> checkOutput, Action action); 54 55 public void assertEditInput(boolean after, String cmd, Consumer<String> checkInput, Action action) { 56 assertEdit(after, cmd, checkInput, s -> {}, action); 57 } 58 59 public void assertEditOutput(boolean after, String cmd, Consumer<String> checkOutput, Action action) { 60 assertEdit(after, cmd, s -> {}, checkOutput, action); 61 } 62 63 public void assertEditInput(boolean after, String cmd, String input, Action action) { 64 assertEditInput(after, cmd, s -> assertEquals(s, input, "Input"), action); 65 } 66 67 public void assertEditOutput(boolean after, String cmd, String output, Action action) { 68 assertEditOutput(after, cmd, s -> assertEquals(s.trim(), output.trim(), "command"), action); 69 } 70 71 @Test 72 public void testEditNegative() { 73 for (String edit : new String[] {"/ed", "/edit"}) { 74 test(new String[]{"--no-startup"}, 75 a -> assertCommandOutputStartsWith(a, edit + " 1", 76 "| No such snippet: 1"), 77 a -> assertCommandOutputStartsWith(a, edit + " unknown", 78 "| No such snippet: unknown") 79 ); 80 } 81 } 82 83 @Test 84 public void testDoNothing() { 85 testEditor( 86 a -> assertVariable(a, "int", "a", "0", "0"), 87 a -> assertEditOutput(a, "/ed 1", "", this::exit), 88 a -> assertCommandCheckOutput(a, "/v", assertVariables()) 89 ); 90 } 91 92 @Test 93 public void testEditVariable1() { 94 testEditor( 95 a -> assertVariable(a, "int", "a", "0", "0"), 96 a -> assertEditOutput(a, "/ed 1", "a ==> 10", () -> { 97 writeSource("\n\n\nint a = 10;\n\n\n"); 98 exit(); 99 loadVariable(true, "int", "a", "10", "10"); 100 }), 101 a -> assertEditOutput(a, "/ed 1", "a ==> 15", () -> { 102 writeSource("int a = 15;"); 103 exit(); 104 loadVariable(true, "int", "a", "15", "15"); 105 }), 106 a -> assertCommandCheckOutput(a, "/v", assertVariables()) 107 ); 108 } 109 110 @Test 111 public void testEditVariable2() { 112 testEditor( 113 a -> assertVariable(a, "int", "a", "0", "0"), 114 a -> assertEditOutput(a, "/ed 1", "b ==> 10", () -> { 115 writeSource("int b = 10;"); 116 exit(); 117 loadVariable(true, "int", "b", "10", "10"); 118 }), 119 a -> assertEditOutput(a, "/ed 1", "a ==> 15", () -> { 120 writeSource("int a = 15;"); 121 exit(); 122 loadVariable(true, "int", "a", "15", "15"); 123 }), 124 a -> assertCommandCheckOutput(a, "/v", assertVariables()) 125 ); 126 } 127 128 @Test(enabled = false) // TODO 8163816 129 public void testEditClass1() { 130 testEditor( 131 a -> assertClass(a, "class A {}", "class", "A"), 132 a -> assertEditOutput(a, "/ed 1", "", () -> { 133 writeSource("\n\n\nclass A {}\n\n\n"); 134 exit(); 135 loadClass(true, "class A {}", "class", "A"); 136 }), 137 a -> assertEditOutput(a, "/ed 1", 138 "| replaced enum A", () -> { 139 writeSource("enum A {}"); 140 exit(); 141 loadClass(true, "enum A {}", "enum", "A"); 142 }), 143 a -> assertCommandCheckOutput(a, "/types", assertClasses()) 144 ); 145 } 146 147 @Test 148 public void testEditClass2() { 149 testEditor( 150 a -> assertClass(a, "class A {}", "class", "A"), 151 a -> assertEditOutput(a, "/ed 1", "| created class B", () -> { 152 writeSource("class B { }"); 153 exit(); 154 loadClass(true, "class B {}", "class", "B"); 155 }), 156 a -> assertEditOutput(a, "/ed 1", 157 "| replaced enum A", () -> { 158 writeSource("enum A {}"); 159 exit(); 160 loadClass(true, "enum A {}", "enum", "A"); 161 }), 162 a -> assertCommandCheckOutput(a, "/types", assertClasses()) 163 ); 164 } 165 166 @Test(enabled = false) // TODO 8163816 167 public void testEditMethod1() { 168 testEditor( 169 a -> assertMethod(a, "void f() {}", "()void", "f"), 170 a -> assertEditOutput(a, "/ed 1", "", () -> { 171 writeSource("\n\n\nvoid f() {}\n\n\n"); 172 exit(); 173 loadMethod(true, "void f() {}", "()void", "f"); 174 }), 175 a -> assertEditOutput(a, "/ed 1", 176 "| replaced method f()", () -> { 177 writeSource("double f() { return 0; }"); 178 exit(); 179 loadMethod(true, "double f() { return 0; }", "()double", "f"); 180 }), 181 a -> assertCommandCheckOutput(a, "/m", assertMethods()) 182 ); 183 } 184 185 @Test 186 public void testEditMethod2() { 187 testEditor( 188 a -> assertMethod(a, "void f() {}", "()void", "f"), 189 a -> assertEditOutput(a, "/ed 1", "| created method g()", () -> { 190 writeSource("void g() {}"); 191 exit(); 192 loadMethod(true, "void g() {}", "()void", "g"); 193 }), 194 a -> assertEditOutput(a, "/ed 1", 195 "| replaced method f()", () -> { 196 writeSource("double f() { return 0; }"); 197 exit(); 198 loadMethod(true, "double f() { return 0; }", "()double", "f"); 199 }), 200 a -> assertCommandCheckOutput(a, "/m", assertMethods()) 201 ); 202 } 203 204 @Test 205 public void testNoArguments() { 206 testEditor( 207 a -> assertVariable(a, "int", "a"), 208 a -> assertMethod(a, "void f() {}", "()void", "f"), 209 a -> assertClass(a, "class A {}", "class", "A"), 210 a -> assertEditInput(a, "/ed", s -> { 211 String[] ss = s.split("\n"); 212 assertEquals(ss.length, 3, "Expected 3 lines: " + s); 213 assertEquals(ss[0], "int a;"); 214 assertEquals(ss[1], "void f() {}"); 215 assertEquals(ss[2], "class A {}"); 216 }, this::exit) 217 ); 218 } 219 220 @Test 221 public void testStartup() { 222 testEditor(true, new String[0], 223 a -> assertEditInput(a, "/ed", s -> assertTrue(s.isEmpty(), "Checking of startup: " + s), this::cancel), 224 a -> assertEditInput(a, "/ed printf", assertStartsWith("void printf"), this::cancel)); 225 } 226 227 @Test 228 public void testCancel() { 229 testEditor( 230 a -> assertVariable(a, "int", "a"), 231 a -> assertEditOutput(a, "/ed a", "", () -> { 232 writeSource("int b = 10"); 233 cancel(); 234 }) 235 ); 236 } 237 238 @Test 239 public void testAccept() { 240 testEditor( 241 a -> assertVariable(a, "int", "a"), 242 a -> assertEditOutput(a, "/ed a", "b ==> 10", () -> { 243 writeSource("int b = 10"); 244 accept(); 245 exit(); 246 }) 247 ); 248 } 249 250 public static ExecutorService getExecutor() { 251 if (executor == null) { 252 executor = Executors.newSingleThreadExecutor(); 253 } 254 return executor; 255 } 256 257 public static void executorShutdown() { 258 if (executor != null) { 259 executor.shutdown(); 260 executor = null; 261 } 262 } 263 264 interface Action { 265 void accept(); 266 } 267 }