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.io.ByteArrayOutputStream; 25 import java.io.PrintStream; 26 import java.io.StringWriter; 27 import java.nio.file.Path; 28 import java.util.ArrayList; 29 import java.util.Arrays; 30 import java.util.Collection; 31 import java.util.Collections; 32 import java.util.HashMap; 33 import java.util.LinkedHashMap; 34 import java.util.LinkedHashSet; 35 import java.util.List; 36 import java.util.Map; 37 import java.util.Set; 38 import java.util.TreeMap; 39 import java.util.function.Predicate; 40 import java.util.function.Supplier; 41 import java.util.stream.Collectors; 42 import java.util.stream.Stream; 43 44 import javax.tools.Diagnostic; 45 46 import jdk.jshell.EvalException; 47 import jdk.jshell.JShell; 48 import jdk.jshell.JShell.Subscription; 49 import jdk.jshell.Snippet; 50 import jdk.jshell.DeclarationSnippet; 51 import jdk.jshell.ExpressionSnippet; 52 import jdk.jshell.ImportSnippet; 53 import jdk.jshell.Snippet.Kind; 54 import jdk.jshell.MethodSnippet; 55 import jdk.jshell.PersistentSnippet; 56 import jdk.jshell.Snippet.Status; 57 import jdk.jshell.Snippet.SubKind; 58 import jdk.jshell.TypeDeclSnippet; 59 import jdk.jshell.VarSnippet; 60 import jdk.jshell.SnippetEvent; 61 import jdk.jshell.SourceCodeAnalysis; 62 import jdk.jshell.SourceCodeAnalysis.CompletionInfo; 63 import jdk.jshell.SourceCodeAnalysis.Completeness; 64 import jdk.jshell.SourceCodeAnalysis.Suggestion; 65 import jdk.jshell.UnresolvedReferenceException; 66 import org.testng.annotations.AfterMethod; 67 import org.testng.annotations.BeforeMethod; 68 69 import jdk.jshell.Diag; 70 import static jdk.jshell.Snippet.Status.*; 71 import static org.testng.Assert.*; 72 import static jdk.jshell.Snippet.SubKind.METHOD_SUBKIND; 73 74 public class KullaTesting { 75 76 public static final String IGNORE_VALUE = "<ignore-value>"; 77 public static final Class<? extends Throwable> IGNORE_EXCEPTION = (new Throwable() {}).getClass(); 78 public static final Snippet MAIN_SNIPPET; 79 80 private SourceCodeAnalysis analysis = null; 81 private JShell state = null; 82 private TestingInputStream inStream = null; 83 private ByteArrayOutputStream outStream = null; 845 public void assertCompletion(String code, String... expected) { 846 assertCompletion(code, null, expected); 847 } 848 849 public void assertCompletion(String code, Boolean isSmart, String... expected) { 850 List<String> completions = computeCompletions(code, isSmart); 851 assertEquals(completions, Arrays.asList(expected), "Input: " + code + ", " + completions.toString()); 852 } 853 854 public void assertCompletionIncludesExcludes(String code, Set<String> expected, Set<String> notExpected) { 855 assertCompletionIncludesExcludes(code, null, expected, notExpected); 856 } 857 858 public void assertCompletionIncludesExcludes(String code, Boolean isSmart, Set<String> expected, Set<String> notExpected) { 859 List<String> completions = computeCompletions(code, isSmart); 860 assertTrue(completions.containsAll(expected), String.valueOf(completions)); 861 assertTrue(Collections.disjoint(completions, notExpected), String.valueOf(completions)); 862 } 863 864 private List<String> computeCompletions(String code, Boolean isSmart) { 865 int cursor = code.indexOf('|'); 866 code = code.replace("|", ""); 867 assertTrue(cursor > -1, "'|' expected, but not found in: " + code); 868 List<Suggestion> completions = 869 getAnalysis().completionSuggestions(code, cursor, new int[1]); //XXX: ignoring anchor for now 870 return completions.stream() 871 .filter(s -> isSmart == null || isSmart == s.isSmart) 872 .map(s -> s.continuation) 873 .distinct() 874 .collect(Collectors.toList()); 875 } 876 877 public void assertDocumentation(String code, String... expected) { 878 int cursor = code.indexOf('|'); 879 code = code.replace("|", ""); 880 assertTrue(cursor > -1, "'|' expected, but not found in: " + code); 881 String documentation = getAnalysis().documentation(code, cursor); 882 Set<String> docSet = Stream.of(documentation.split("\r?\n")).collect(Collectors.toSet()); 883 Set<String> expectedSet = Stream.of(expected).collect(Collectors.toSet()); 884 assertEquals(docSet, expectedSet, "Input: " + code); 885 } 886 887 public enum ClassType { 888 CLASS("CLASS_SUBKIND") { 889 @Override 890 public String toString() { 891 return "class"; 892 } 893 }, 894 ENUM("ENUM_SUBKIND") { 895 @Override 896 public String toString() { | 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.io.ByteArrayOutputStream; 25 import java.io.PrintStream; 26 import java.io.StringWriter; 27 import java.lang.reflect.Method; 28 import java.nio.file.Path; 29 import java.util.ArrayList; 30 import java.util.Arrays; 31 import java.util.Collection; 32 import java.util.Collections; 33 import java.util.HashMap; 34 import java.util.LinkedHashMap; 35 import java.util.LinkedHashSet; 36 import java.util.List; 37 import java.util.Map; 38 import java.util.Set; 39 import java.util.TreeMap; 40 import java.util.function.Predicate; 41 import java.util.function.Supplier; 42 import java.util.stream.Collectors; 43 import java.util.stream.Stream; 44 45 import javax.tools.Diagnostic; 46 47 import jdk.jshell.EvalException; 48 import jdk.jshell.JShell; 49 import jdk.jshell.JShell.Subscription; 50 import jdk.jshell.Snippet; 51 import jdk.jshell.DeclarationSnippet; 52 import jdk.jshell.ExpressionSnippet; 53 import jdk.jshell.ImportSnippet; 54 import jdk.jshell.Snippet.Kind; 55 import jdk.jshell.MethodSnippet; 56 import jdk.jshell.PersistentSnippet; 57 import jdk.jshell.Snippet.Status; 58 import jdk.jshell.Snippet.SubKind; 59 import jdk.jshell.TypeDeclSnippet; 60 import jdk.jshell.VarSnippet; 61 import jdk.jshell.SnippetEvent; 62 import jdk.jshell.SourceCodeAnalysis; 63 import jdk.jshell.SourceCodeAnalysis.CompletionInfo; 64 import jdk.jshell.SourceCodeAnalysis.Completeness; 65 import jdk.jshell.SourceCodeAnalysis.IndexResult; 66 import jdk.jshell.SourceCodeAnalysis.Suggestion; 67 import jdk.jshell.UnresolvedReferenceException; 68 import org.testng.annotations.AfterMethod; 69 import org.testng.annotations.BeforeMethod; 70 71 import jdk.jshell.Diag; 72 import static jdk.jshell.Snippet.Status.*; 73 import static org.testng.Assert.*; 74 import static jdk.jshell.Snippet.SubKind.METHOD_SUBKIND; 75 76 public class KullaTesting { 77 78 public static final String IGNORE_VALUE = "<ignore-value>"; 79 public static final Class<? extends Throwable> IGNORE_EXCEPTION = (new Throwable() {}).getClass(); 80 public static final Snippet MAIN_SNIPPET; 81 82 private SourceCodeAnalysis analysis = null; 83 private JShell state = null; 84 private TestingInputStream inStream = null; 85 private ByteArrayOutputStream outStream = null; 847 public void assertCompletion(String code, String... expected) { 848 assertCompletion(code, null, expected); 849 } 850 851 public void assertCompletion(String code, Boolean isSmart, String... expected) { 852 List<String> completions = computeCompletions(code, isSmart); 853 assertEquals(completions, Arrays.asList(expected), "Input: " + code + ", " + completions.toString()); 854 } 855 856 public void assertCompletionIncludesExcludes(String code, Set<String> expected, Set<String> notExpected) { 857 assertCompletionIncludesExcludes(code, null, expected, notExpected); 858 } 859 860 public void assertCompletionIncludesExcludes(String code, Boolean isSmart, Set<String> expected, Set<String> notExpected) { 861 List<String> completions = computeCompletions(code, isSmart); 862 assertTrue(completions.containsAll(expected), String.valueOf(completions)); 863 assertTrue(Collections.disjoint(completions, notExpected), String.valueOf(completions)); 864 } 865 866 private List<String> computeCompletions(String code, Boolean isSmart) { 867 waitIndexingFinished(); 868 869 int cursor = code.indexOf('|'); 870 code = code.replace("|", ""); 871 assertTrue(cursor > -1, "'|' expected, but not found in: " + code); 872 List<Suggestion> completions = 873 getAnalysis().completionSuggestions(code, cursor, new int[1]); //XXX: ignoring anchor for now 874 return completions.stream() 875 .filter(s -> isSmart == null || isSmart == s.isSmart) 876 .map(s -> s.continuation) 877 .distinct() 878 .collect(Collectors.toList()); 879 } 880 881 public void assertInferredType(String code, String expectedType) { 882 String inferredType = getAnalysis().analyzeType(code, code.length()); 883 884 assertEquals(inferredType, expectedType, "Input: " + code + ", " + inferredType); 885 } 886 887 public void assertInferredFQNs(String code, String... fqns) { 888 waitIndexingFinished(); 889 890 IndexResult candidates = getAnalysis().getDeclaredSymbols(code, code.length()); 891 892 assertEquals(candidates.getFqns(), Arrays.asList(fqns), "Input: " + code + ", " + candidates.getFqns()); 893 } 894 895 protected void waitIndexingFinished() { 896 try { 897 Method waitBackgroundTaskFinished = getAnalysis().getClass().getDeclaredMethod("waitBackgroundTaskFinished"); 898 899 waitBackgroundTaskFinished.setAccessible(true); 900 waitBackgroundTaskFinished.invoke(getAnalysis()); 901 } catch (Exception ex) { 902 throw new AssertionError("Cannot wait for indexing end.", ex); 903 } 904 } 905 906 public void assertDocumentation(String code, String... expected) { 907 int cursor = code.indexOf('|'); 908 code = code.replace("|", ""); 909 assertTrue(cursor > -1, "'|' expected, but not found in: " + code); 910 String documentation = getAnalysis().documentation(code, cursor); 911 Set<String> docSet = Stream.of(documentation.split("\r?\n")).collect(Collectors.toSet()); 912 Set<String> expectedSet = Stream.of(expected).collect(Collectors.toSet()); 913 assertEquals(docSet, expectedSet, "Input: " + code); 914 } 915 916 public enum ClassType { 917 CLASS("CLASS_SUBKIND") { 918 @Override 919 public String toString() { 920 return "class"; 921 } 922 }, 923 ENUM("ENUM_SUBKIND") { 924 @Override 925 public String toString() { |