HistoryTest.java revision 3062:15bdc18525ff
1/* 2 * Copyright (c) 2015, 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/* 25 * @test 26 * @summary Test Completion 27 * @build HistoryTest 28 * @run testng HistoryTest 29 */ 30 31import java.io.ByteArrayInputStream; 32import java.io.ByteArrayOutputStream; 33import java.io.PrintStream; 34import java.util.Arrays; 35import java.util.HashMap; 36import java.util.Map; 37import java.util.prefs.AbstractPreferences; 38import java.util.prefs.BackingStoreException; 39import jdk.internal.jline.console.history.MemoryHistory; 40 41import jdk.jshell.JShell; 42import jdk.jshell.SourceCodeAnalysis; 43import jdk.jshell.SourceCodeAnalysis.CompletionInfo; 44import org.testng.annotations.Test; 45import jdk.internal.jshell.tool.EditingHistory; 46 47import static org.testng.Assert.*; 48 49@Test 50public class HistoryTest { 51 52 public void testHistory() { 53 JShell eval = JShell.builder() 54 .in(new ByteArrayInputStream(new byte[0])) 55 .out(new PrintStream(new ByteArrayOutputStream())) 56 .err(new PrintStream(new ByteArrayOutputStream())) 57 .build(); 58 SourceCodeAnalysis analysis = eval.sourceCodeAnalysis(); 59 MemoryPreferences prefs = new MemoryPreferences(null, ""); 60 EditingHistory history = new EditingHistory(prefs) { 61 @Override protected CompletionInfo analyzeCompletion(String input) { 62 return analysis.analyzeCompletion(input); 63 } 64 }; 65 history.add("void test() {"); 66 history.add(" System.err.println(1);"); 67 history.add("}"); 68 history.add("/exit"); 69 70 previousAndAssert(history, "/exit"); 71 72 history.previous(); history.previous(); history.previous(); 73 74 history.add("void test() { /*changed*/"); 75 76 previousAndAssert(history, "}"); 77 previousAndAssert(history, " System.err.println(1);"); 78 previousAndAssert(history, "void test() {"); 79 80 assertFalse(history.previous()); 81 82 nextAndAssert(history, " System.err.println(1);"); 83 nextAndAssert(history, "}"); 84 nextAndAssert(history, ""); 85 86 history.add(" System.err.println(2);"); 87 history.add("} /*changed*/"); 88 89 assertEquals(history.size(), 7); 90 91 history.save(); 92 93 history = new EditingHistory(prefs) { 94 @Override protected CompletionInfo analyzeCompletion(String input) { 95 return analysis.analyzeCompletion(input); 96 } 97 }; 98 99 previousSnippetAndAssert(history, "void test() { /*changed*/"); 100 previousSnippetAndAssert(history, "/exit"); 101 previousSnippetAndAssert(history, "void test() {"); 102 103 assertFalse(history.previousSnippet()); 104 105 nextSnippetAndAssert(history, "/exit"); 106 nextSnippetAndAssert(history, "void test() { /*changed*/"); 107 nextSnippetAndAssert(history, ""); 108 109 assertFalse(history.nextSnippet()); 110 111 history.add("{"); 112 history.add("}"); 113 114 history.save(); 115 116 history = new EditingHistory(prefs) { 117 @Override protected CompletionInfo analyzeCompletion(String input) { 118 return analysis.analyzeCompletion(input); 119 } 120 }; 121 122 previousSnippetAndAssert(history, "{"); 123 previousSnippetAndAssert(history, "void test() { /*changed*/"); 124 previousSnippetAndAssert(history, "/exit"); 125 previousSnippetAndAssert(history, "void test() {"); 126 127 while (history.next()); 128 129 history.add("/*current1*/"); 130 history.add("/*current2*/"); 131 history.add("/*current3*/"); 132 133 assertEquals(history.currentSessionEntries(), Arrays.asList("/*current1*/", "/*current2*/", "/*current3*/")); 134 135 history.remove(0); 136 137 assertEquals(history.currentSessionEntries(), Arrays.asList("/*current1*/", "/*current2*/", "/*current3*/")); 138 139 while (history.size() > 2) 140 history.remove(0); 141 142 assertEquals(history.currentSessionEntries(), Arrays.asList("/*current2*/", "/*current3*/")); 143 144 for (int i = 0; i < MemoryHistory.DEFAULT_MAX_SIZE * 2; i++) { 145 history.add("/exit"); 146 } 147 148 history.add("void test() { /*after full*/"); 149 history.add(" System.err.println(1);"); 150 history.add("}"); 151 152 previousSnippetAndAssert(history, "void test() { /*after full*/"); 153 } 154 155 public void testSaveOneHistory() { 156 JShell eval = JShell.builder() 157 .in(new ByteArrayInputStream(new byte[0])) 158 .out(new PrintStream(new ByteArrayOutputStream())) 159 .err(new PrintStream(new ByteArrayOutputStream())) 160 .build(); 161 SourceCodeAnalysis analysis = eval.sourceCodeAnalysis(); 162 MemoryPreferences prefs = new MemoryPreferences(null, ""); 163 EditingHistory history = new EditingHistory(prefs) { 164 @Override protected CompletionInfo analyzeCompletion(String input) { 165 return analysis.analyzeCompletion(input); 166 } 167 }; 168 169 history.add("first"); 170 history.save(); 171 } 172 173 private void previousAndAssert(EditingHistory history, String expected) { 174 assertTrue(history.previous()); 175 assertEquals(history.current().toString(), expected); 176 } 177 178 private void nextAndAssert(EditingHistory history, String expected) { 179 assertTrue(history.next()); 180 assertEquals(history.current().toString(), expected); 181 } 182 183 private void previousSnippetAndAssert(EditingHistory history, String expected) { 184 assertTrue(history.previousSnippet()); 185 assertEquals(history.current().toString(), expected); 186 } 187 188 private void nextSnippetAndAssert(EditingHistory history, String expected) { 189 assertTrue(history.nextSnippet()); 190 assertEquals(history.current().toString(), expected); 191 } 192 193 private static final class MemoryPreferences extends AbstractPreferences { 194 195 private final Map<String, String> key2Value = new HashMap<>(); 196 private final Map<String, MemoryPreferences> key2SubNode = new HashMap<>(); 197 198 public MemoryPreferences(AbstractPreferences parent, String name) { 199 super(parent, name); 200 } 201 202 @Override 203 protected void putSpi(String key, String value) { 204 key2Value.put(key, value); 205 } 206 207 @Override 208 protected String getSpi(String key) { 209 return key2Value.get(key); 210 } 211 212 @Override 213 protected void removeSpi(String key) { 214 key2Value.remove(key); 215 } 216 217 @Override 218 protected void removeNodeSpi() throws BackingStoreException { 219 ((MemoryPreferences) parent()).key2SubNode.remove(name()); 220 } 221 222 @Override 223 protected String[] keysSpi() throws BackingStoreException { 224 return key2Value.keySet().toArray(new String[key2Value.size()]); 225 } 226 227 @Override 228 protected String[] childrenNamesSpi() throws BackingStoreException { 229 return key2SubNode.keySet().toArray(new String[key2SubNode.size()]); 230 } 231 232 @Override 233 protected AbstractPreferences childSpi(String name) { 234 return key2SubNode.computeIfAbsent(name, n -> new MemoryPreferences(this, n)); 235 } 236 237 @Override 238 protected void syncSpi() throws BackingStoreException {} 239 240 @Override 241 protected void flushSpi() throws BackingStoreException {} 242 243 } 244 245} 246