langtools/test/jdk/jshell/HistoryTest.java
changeset 33362 65ec6de1d6b4
child 35359 f04501964016
equal deleted inserted replaced
33361:1c96344ecd49 33362:65ec6de1d6b4
       
     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 
       
    31 import java.io.ByteArrayInputStream;
       
    32 import java.io.ByteArrayOutputStream;
       
    33 import java.io.PrintStream;
       
    34 import java.util.Arrays;
       
    35 import java.util.HashMap;
       
    36 import java.util.Map;
       
    37 import java.util.prefs.AbstractPreferences;
       
    38 import java.util.prefs.BackingStoreException;
       
    39 import jdk.internal.jline.console.history.MemoryHistory;
       
    40 
       
    41 import jdk.jshell.JShell;
       
    42 import jdk.jshell.SourceCodeAnalysis;
       
    43 import jdk.jshell.SourceCodeAnalysis.CompletionInfo;
       
    44 import org.testng.annotations.Test;
       
    45 import jdk.internal.jshell.tool.EditingHistory;
       
    46 
       
    47 import static org.testng.Assert.*;
       
    48 
       
    49 @Test
       
    50 public 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 }