/******************************************************************************* * Copyright (c) Mar 12, 2016 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.jdt.debug.tests.variables; import org.eclipse.debug.core.model.IValue; import org.eclipse.debug.ui.IValueDetailListener; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.Signature; import org.eclipse.jdt.debug.core.IJavaThread; import org.eclipse.jdt.debug.core.IJavaValue; import org.eclipse.jdt.debug.core.IJavaVariable; import org.eclipse.jdt.debug.tests.AbstractDebugTest; import org.eclipse.jdt.internal.debug.ui.DetailFormatter; import org.eclipse.jdt.internal.debug.ui.JavaDetailFormattersManager; /** * Tests detail formatters * * @since 3.8.100 */ public class DetailFormatterTests extends AbstractDebugTest { class TestListener implements IValueDetailListener { IValue value; String result; @Override public void detailComputed(IValue value, String result) { this.value = value; this.result = result; } void reset() { value = null; result = null; } } TestListener fListener = new TestListener(); /** * @param name */ public DetailFormatterTests(String name) { super(name); } @Override protected IJavaProject getProjectContext() { return get15Project(); } @Override protected void tearDown() throws Exception { fListener.reset(); super.tearDown(); } /** * Tests a detail formatter made from a large compound expression * @see https://bugs.eclipse.org/bugs/show_bug.cgi?id=403028 * @throws Exception */ public void testCompoundDetails1() throws Exception { IJavaThread thread = null; DetailFormatter formatter = null; JavaDetailFormattersManager jdfm = JavaDetailFormattersManager.getDefault(); try { String typename = "a.b.c.bug403028"; createLineBreakpoint(10, typename); thread = launchToBreakpoint(typename); assertNotNull("The program did not suspend", thread); String snippet = "StringBuffer buf = new StringBuffer();\n" + "buf.append(\"{\");\n" + "Iterator i = this.entrySet().iterator();\n" + "boolean hasNext = i.hasNext();\n" + "while (hasNext) {\n" + " Entry e = (Entry) (i.next());\n" + " Object key = e.getKey();\n" + " Object value = e.getValue();\n" + " buf.append((key == this ? \"(this Map)\" : key) + \"=\" + \n" + " (value == this ? \"(this Map)\": value));\n" + " hasNext = i.hasNext();\n" + " if (hasNext)\n" + " buf.append(\"\n,\");\n" + "}\n" + "buf.append(\"}\");\n" + "return buf.toString();"; formatter = new DetailFormatter("java.util.HashMap", snippet, true); jdfm.setAssociatedDetailFormatter(formatter); IJavaVariable var = thread.findVariable("map"); assertNotNull("the variable 'map' must exist in the frame", var); jdfm.computeValueDetail((IJavaValue) var.getValue(), thread, fListener); long timeout = System.currentTimeMillis()+5000; while(fListener.value == null && System.currentTimeMillis() < timeout) { Thread.sleep(100); } assertNotNull("The IValue of the detailComputed callback cannot be null", fListener.value); assertTrue("The map should be an instance of java.util.LinkedHashMap", Signature.getTypeErasure(fListener.value.getReferenceTypeName()).equals("java.util.LinkedHashMap")); assertNotNull("The computed value of the detail should not be null", fListener.result); } finally { jdfm.removeAssociatedDetailFormatter(formatter); terminateAndRemove(thread); removeAllBreakpoints(); } } /** * Tests a detail formatter made from a small compound expression * @see https://bugs.eclipse.org/bugs/show_bug.cgi?id=403028 * @throws Exception */ public void testCompoundDetails2() throws Exception { IJavaThread thread = null; DetailFormatter formatter = null; JavaDetailFormattersManager jdfm = JavaDetailFormattersManager.getDefault(); try { String typename = "a.b.c.bug403028"; createLineBreakpoint(10, typename); thread = launchToBreakpoint(typename); assertNotNull("The program did not suspend", thread); String snippet = "StringBuffer buf = new StringBuffer();\n" + "buf.append(this);\n" + "return buf.toString();"; formatter = new DetailFormatter("java.util.HashMap", snippet, true); jdfm.setAssociatedDetailFormatter(formatter); IJavaVariable var = thread.findVariable("map"); assertNotNull("the variable 'map' must exist in the frame", var); jdfm.computeValueDetail((IJavaValue) var.getValue(), thread, fListener); long timeout = System.currentTimeMillis()+5000; while(fListener.value == null && System.currentTimeMillis() < timeout) { Thread.sleep(100); } assertNotNull("The IValue of the detailComputed callback cannot be null", fListener.value); assertTrue("The map should be an instance of java.util.LinkedHashMap", Signature.getTypeErasure(fListener.value.getReferenceTypeName()).equals("java.util.LinkedHashMap")); assertNotNull("The computed value of the detail should not be null", fListener.result); } finally { jdfm.removeAssociatedDetailFormatter(formatter); terminateAndRemove(thread); removeAllBreakpoints(); } } /** * Tests a detail formatter made from a small compound expression * @see https://bugs.eclipse.org/bugs/show_bug.cgi?id=403028 * @throws Exception */ public void testSimpleDetails1() throws Exception { IJavaThread thread = null; DetailFormatter formatter = null; JavaDetailFormattersManager jdfm = JavaDetailFormattersManager.getDefault(); try { String typename = "a.b.c.bug403028"; createLineBreakpoint(10, typename); thread = launchToBreakpoint(typename); assertNotNull("The program did not suspend", thread); String snippet = "return toString();"; formatter = new DetailFormatter("java.util.HashMap", snippet, true); jdfm.setAssociatedDetailFormatter(formatter); IJavaVariable var = thread.findVariable("map"); assertNotNull("the variable 'map' must exist in the frame", var); jdfm.computeValueDetail((IJavaValue) var.getValue(), thread, fListener); long timeout = System.currentTimeMillis()+5000; while(fListener.value == null && System.currentTimeMillis() < timeout) { Thread.sleep(100); } assertNotNull("The IValue of the detailComputed callback cannot be null", fListener.value); assertTrue("The map should be an instance of java.util.LinkedHashMap", Signature.getTypeErasure(fListener.value.getReferenceTypeName()).equals("java.util.LinkedHashMap")); assertNotNull("The computed value of the detail should not be null", fListener.result); } finally { jdfm.removeAssociatedDetailFormatter(formatter); terminateAndRemove(thread); removeAllBreakpoints(); } } /** * Tests a detail formatter made from a small compound expression * @see https://bugs.eclipse.org/bugs/show_bug.cgi?id=403028 * @throws Exception */ public void testSimpleDetails2() throws Exception { IJavaThread thread = null; DetailFormatter formatter = null; JavaDetailFormattersManager jdfm = JavaDetailFormattersManager.getDefault(); try { String typename = "a.b.c.bug403028"; createLineBreakpoint(10, typename); thread = launchToBreakpoint(typename); assertNotNull("The program did not suspend", thread); String snippet = "return \"map test detail formatter [\" + toString() + \"]\";"; formatter = new DetailFormatter("java.util.HashMap", snippet, true); jdfm.setAssociatedDetailFormatter(formatter); IJavaVariable var = thread.findVariable("map"); assertNotNull("the variable 'map' must exist in the frame", var); jdfm.computeValueDetail((IJavaValue) var.getValue(), thread, fListener); long timeout = System.currentTimeMillis()+5000; while(fListener.value == null && System.currentTimeMillis() < timeout) { Thread.sleep(100); } assertNotNull("The IValue of the detailComputed callback cannot be null", fListener.value); assertTrue("The map should be an instance of java.util.LinkedHashMap", Signature.getTypeErasure(fListener.value.getReferenceTypeName()).equals("java.util.LinkedHashMap")); assertNotNull("The computed value of the detail should not be null", fListener.result); } finally { jdfm.removeAssociatedDetailFormatter(formatter); terminateAndRemove(thread); removeAllBreakpoints(); } } /** * Tests a detail formatter made from an infix expression * @see https://bugs.eclipse.org/bugs/show_bug.cgi?id=403028 * @throws Exception */ public void testInfixDetails1() throws Exception { IJavaThread thread = null; DetailFormatter formatter = null; JavaDetailFormattersManager jdfm = JavaDetailFormattersManager.getDefault(); try { String typename = "a.b.c.bug403028"; createLineBreakpoint(10, typename); thread = launchToBreakpoint(typename); assertNotNull("The program did not suspend", thread); String snippet = "return (true && true || !(false&&true) || !(true==true||true!=true&&true));"; formatter = new DetailFormatter("java.util.HashMap", snippet, true); jdfm.setAssociatedDetailFormatter(formatter); IJavaVariable var = thread.findVariable("map"); assertNotNull("the variable 'map' must exist in the frame", var); jdfm.computeValueDetail((IJavaValue) var.getValue(), thread, fListener); long timeout = System.currentTimeMillis()+5000; while(fListener.value == null && System.currentTimeMillis() < timeout) { Thread.sleep(100); } assertNotNull("The IValue of the detailComputed callback cannot be null", fListener.value); assertTrue("The map should be an instance of java.util.LinkedHashMap", Signature.getTypeErasure(fListener.value.getReferenceTypeName()).equals("java.util.LinkedHashMap")); assertNotNull("The computed value of the detail should not be null", fListener.result); assertTrue("The returned value from (true && true || !(false&&true) || !(true==true||true!=true&&true)) should be true", Boolean.parseBoolean(fListener.result)); } finally { jdfm.removeAssociatedDetailFormatter(formatter); terminateAndRemove(thread); removeAllBreakpoints(); } } /** * Tests a detail formatter made from an infix expression * @see https://bugs.eclipse.org/bugs/show_bug.cgi?id=403028 * @throws Exception */ public void testInfixDetails2() throws Exception { IJavaThread thread = null; DetailFormatter formatter = null; JavaDetailFormattersManager jdfm = JavaDetailFormattersManager.getDefault(); try { String typename = "a.b.c.bug403028"; createLineBreakpoint(10, typename); thread = launchToBreakpoint(typename); assertNotNull("The program did not suspend", thread); String snippet = "return !true;"; formatter = new DetailFormatter("java.util.HashMap", snippet, true); jdfm.setAssociatedDetailFormatter(formatter); IJavaVariable var = thread.findVariable("map"); assertNotNull("the variable 'map' must exist in the frame", var); jdfm.computeValueDetail((IJavaValue) var.getValue(), thread, fListener); long timeout = System.currentTimeMillis()+5000; while(fListener.value == null && System.currentTimeMillis() < timeout) { Thread.sleep(100); } assertNotNull("The IValue of the detailComputed callback cannot be null", fListener.value); assertTrue("The map should be an instance of java.util.LinkedHashMap", Signature.getTypeErasure(fListener.value.getReferenceTypeName()).equals("java.util.LinkedHashMap")); assertNotNull("The computed value of the detail should not be null", fListener.result); assertFalse("The returned value from !true should be false", Boolean.parseBoolean(fListener.result)); } finally { jdfm.removeAssociatedDetailFormatter(formatter); terminateAndRemove(thread); removeAllBreakpoints(); } } /** * Tests a detail formatter made from an infix expression * @see https://bugs.eclipse.org/bugs/show_bug.cgi?id=403028 * @throws Exception */ public void testInfixDetails3() throws Exception { IJavaThread thread = null; DetailFormatter formatter = null; JavaDetailFormattersManager jdfm = JavaDetailFormattersManager.getDefault(); try { String typename = "a.b.c.bug403028"; createLineBreakpoint(10, typename); thread = launchToBreakpoint(typename); assertNotNull("The program did not suspend", thread); String snippet = "return !(true==true||true!=true&&true);"; formatter = new DetailFormatter("java.util.HashMap", snippet, true); jdfm.setAssociatedDetailFormatter(formatter); IJavaVariable var = thread.findVariable("map"); assertNotNull("the variable 'map' must exist in the frame", var); jdfm.computeValueDetail((IJavaValue) var.getValue(), thread, fListener); long timeout = System.currentTimeMillis()+5000; while(fListener.value == null && System.currentTimeMillis() < timeout) { Thread.sleep(100); } assertNotNull("The IValue of the detailComputed callback cannot be null", fListener.value); assertTrue("The map should be an instance of java.util.LinkedHashMap", Signature.getTypeErasure(fListener.value.getReferenceTypeName()).equals("java.util.LinkedHashMap")); assertNotNull("The computed value of the detail should not be null", fListener.result); assertFalse("The returned value from !(true==true||true!=true&&true) should be false", Boolean.parseBoolean(fListener.result)); } finally { jdfm.removeAssociatedDetailFormatter(formatter); terminateAndRemove(thread); removeAllBreakpoints(); } } /** * Tests a detail formatter made from an collection with no type arguments * * @see https://bugs.eclipse.org/bugs/show_bug.cgi?id=484686 * @throws Exception */ public void testHoverWithNoTypeArguments() throws Exception { IJavaThread thread = null; DetailFormatter formatter = null; JavaDetailFormattersManager jdfm = JavaDetailFormattersManager.getDefault(); try { String typename = "a.b.c.bug484686"; createLineBreakpoint(8, typename); thread = launchToBreakpoint(typename); assertNotNull("The program did not suspend", thread); String snippet = "StringBuilder sb = new StringBuilder();\n" + "for (Object obj : this) { \n" + "sb.append(obj).append(\"\\n\"); }\n" + "return sb.toString();"; formatter = new DetailFormatter("java.util.Collection", snippet, true); jdfm.setAssociatedDetailFormatter(formatter); IJavaVariable var = thread.findVariable("coll"); assertNotNull("the variable 'coll' must exist in the frame", var); jdfm.computeValueDetail((IJavaValue) var.getValue(), thread, fListener); long timeout = System.currentTimeMillis() + 5000; while (fListener.value == null && System.currentTimeMillis() < timeout) { Thread.sleep(100); } assertNotNull("The IValue of the detailComputed callback cannot be null", fListener.value); assertNotNull("The computed value of the detail should not be null", fListener.result); } finally { jdfm.removeAssociatedDetailFormatter(formatter); terminateAndRemove(thread); removeAllBreakpoints(); } } }