package com.jetbrains.dart.analysisServer; import com.intellij.psi.PsiFile; import com.intellij.testFramework.fixtures.CodeInsightFixtureTestCase; import com.intellij.testFramework.fixtures.impl.CodeInsightTestFixtureImpl; import com.jetbrains.lang.dart.ide.documentation.DartDocumentationProvider; import com.jetbrains.lang.dart.util.DartTestUtils; import org.dartlang.analysis.server.protocol.HoverInformation; public class DartServerDocUtilTest extends CodeInsightFixtureTestCase { @Override public void setUp() throws Exception { super.setUp(); DartTestUtils.configureDartSdk(myModule, myFixture.getTestRootDisposable(), true); ((CodeInsightTestFixtureImpl)myFixture).canChangeDocumentDuringHighlighting(true); } public void testAbstractClassSig() throws Exception { doTest("<code>abstract class Foo extends Bar<br></code>", "abstract class <caret>Foo extends Bar { }\nclass Bar { }"); } public void testClassMultilineDoc1() throws Exception { doTest("<code>class A<br></code>\n" + "<p>doc1\n" + "doc2\n" + " doc3</p>\n" + "\n" + "<p> doc4</p>\n" + "\n" + "<pre><code> code\n" + "</code></pre>", "/** 1 */\n" + "/**\n" + " * doc1\n" + " * doc2\n" + " * doc3\n" + " *\n" + " * doc4\n" + " * \n" + " * code\n" + " */\n" + "// non-doc\n" + "class <caret>A{}"); } public void testClassMultilineDoc2() throws Exception { doTest("<code>abstract class A<br></code>\n<p>doc1\n" + "doc2\n" + " doc3\n" + "doc4\n" + "doc5\n" + " doc6</p>", "@deprecated\n" + "/**\n" + "*doc1\n" + "* doc2\n" + "* doc3\n" + " *doc4\n" + " * doc5\n" + " * doc6\n" + " */\n" + "abstract class <caret>A{}"); } public void testClassSingleLineDocs1() throws Exception { doTest("<code>class A<br></code>\n<p>doc1\n" + "doc2</p>", "// not doc \n" + "/// doc1 \n" + " /* not doc */\n" + " /// doc2 \n" + " // not doc \n" + "class <caret>A{}"); } public void testClassSingleLineDocs2() throws Exception { doTest("<code>class A<br></code>\n<p>doc1\n" + "doc2</p>", "@deprecated" + "// not doc \n" + "/// doc1 \n" + " /* not doc */\n" + " /// doc2 \n" + " // not doc \n" + "class <caret>A{}"); } public void testConstructorSig() throws Exception { doTest("<code>Z() → Z<br><br><b>Containing class:</b> Z<br></code>", "class Z { <caret>Z(); }"); } public void testEnumSig() throws Exception { doTest("<code>enum Foo<br></code>", "enum <caret>Foo { BAR }"); } public void testFieldSig1() throws Exception { doTest("<code>int y<br><br><b>Containing class:</b> Z<br><br><b>Static type:</b> int<br></code>", "class Z { int <caret>y = 42; }"); } public void testFieldSig2() throws Exception { doTest("<code>int y<br><br><b>Containing class:</b> Z<br><br><b>Static type:</b> int<br></code>", "class Z { int <caret>y; }"); } public void testFunctionDoc1() throws Exception { doTest("<code>foo(int x) → void<br></code>\n<p>A function on [x]s.</p>", "/// A function on [x]s.\nvoid <caret>foo(int x) { }"); } public void testFunctionDoc2() throws Exception { doTest("<code>foo(int x) → void<br></code>\n<p>Good for:</p>\n" + "\n" + "<ul>\n" + "<li>this</li>\n" + "<li>that</li>\n" + "</ul>", "/** Good for:\n\n" + " * * this\n" + " * * that\n" + "*/\n" + "\nvoid <caret>foo(int x) { }"); } //public void testMetaClassSig2() throws Exception { // doTest("<code>class <b>A</b><br><br><b>Containing library:</b> test.dart<br></code>", // "@Meta(\'foo\') class <caret>A {};\n" + // "class Meta {\n" + // " final String name;\n" + // " const Meta([this.name]);\n" + // "}"); //} public void testFunctionSig1() throws Exception { doTest("<code>calc(int x) → int<br></code>", "int <caret>calc(int x) => x + 42;"); } public void testFunctionSig10() throws Exception { doTest("<code>x({bool b}) → void<br></code>", "void <caret>x({bool b}){};"); } public void testFunctionSig2() throws Exception { doTest("<code>foo([int x = 3]) → dynamic<br></code>", "<caret>foo([int x = 3]) { print(x); }"); } public void testFunctionSig3() throws Exception { doTest("<code>foo([int x = 3]) → void<br></code>", "void <caret>foo([int x = 3]) { print(x); }"); } public void testFunctionSig4() throws Exception { doTest("<code>foo(int x, {int y, int z}) → void<br></code>", "void <caret>foo(int x, {int y, int z}) { }"); } public void testFunctionSig5() throws Exception { doTest("<code>x(List<dynamic> e) → dynamic<br></code>", "E <caret>x(List<E> e) { }"); } public void testFunctionSig6() throws Exception { doTest("<code>calc(() → int x) → int<br></code>", "int <caret>calc(int x()) => null;"); } public void testFunctionSig7() throws Exception { doTest("<code>foo(Map<int, String> p) → Map<String, int><br></code>", "Map<String, int> <caret>foo(Map<int, String> p) => null;"); } public void testFunctionSig8() throws Exception { doTest("<code>x() → dynamic<br></code>", "<caret>x() => null;"); } public void testFunctionSig9() throws Exception { doTest("<code>x({bool b: true}) → dynamic<br></code>", "<caret>x({bool b: true}){};"); } public void testGetterSig() throws Exception { doTest("<code>get x → int<br><br><b>Containing class:</b> Z<br></code>", "class Z { int get <caret>x => 0; }"); } public void testImplementsSig1() throws Exception { doTest("<code>abstract class Foo implements Bar<br></code>", "abstract class <caret>Foo implements Bar<T> { }\nclass Bar { }"); } public void testLibraryClassDoc() throws Exception { doTest("<code>class A<br><br><b>Containing library:</b> c.b.a<br></code>", "library c.b.a;\nclass <caret>A {}"); } public void testMetaClassSig1() throws Exception { doTest("<code>class A<br></code>", " @deprecated class <caret>A {}"); } public void testMethodMultilineDoc() throws Exception { doTest("<code>foo() → dynamic<br><br><b>Containing class:</b> A<br></code>\n" + "<p>doc1\n" + "doc2\n" + " doc3</p>\n" + "\n" + "<p> doc4</p>\n" + "\n" + "<pre><code> code\n" + "</code></pre>", "class A{\n" + "/** 1 */\n" + "/**\n" + " * doc1\n" + " * doc2\n" + " * doc3\n" + " *\n" + " * doc4\n" + " * \n" + " * code\n" + " */\n" + "// non-doc\n" + "<caret>foo(){}\n" + "}"); } public void testMethodSig1() throws Exception { doTest("<code>y() → int<br><br><b>Containing class:</b> Z<br></code>", "class Z { int <caret>y() => 42; }"); } public void testMethodSingleLineDocs() throws Exception { doTest("<code>foo() → dynamic<br><br><b>Containing class:</b> A<br></code>\n<p>doc1\n" + "doc2</p>", "class A{\n" + "// not doc \n" + "/// doc1 \n" + " /* not doc */\n" + " /// doc2 \n" + " // not doc \n" + "<caret>foo(){}\n" + "}"); } public void testMixinSig1() throws Exception { doTest("<code>class Foo2 extends Bar1 with Baz1, Baz2<br></code>", "class Bar1 {} class Baz1{} class Baz2 {} class <caret>Foo2 = Bar1<E> with Baz1<K>, Baz2"); } public void testMixinSig2() throws Exception { doTest("<code>class X extends Y with Z<br></code>", "class Y {} class Z {} class <caret>X extends Y with Z { }"); } public void testNamedConstructorSig() throws Exception { doTest("<code>Z.z() → Z<br><br><b>Containing class:</b> Z<br></code>", "class Z { <caret>Z.z(); }"); } public void testParamClassSig() throws Exception { doTest("<code>class Foo<T><br></code>", "class <caret>Foo<T>{ }"); } public void testParamClassSig2() throws Exception { doTest("<code>class Foo<T, Z><br></code>", "class <caret>Foo<T,Z>{ }"); } public void testParamClassSig3() throws Exception { doTest("<code>class Foo implements Bar<br></code>", "class <caret>Foo implements Bar { }<br/>class Bar { }"); } public void testParamClassSig4() throws Exception { doTest("<code>class Foo implements Bar, Baz<br></code>", "class <caret>Foo implements Bar, Baz { }<br/>class Bar { }<br/>class Baz { }"); } public void testParamClassSig5() throws Exception { doTest("<code>class Foo<A, B> extends Bar<A, B><br></code>", "class <caret>Foo<A,B> extends Bar<A,B> { }<br/>class Bar<A,B> { }"); } public void testParamClassSig6() throws Exception { doTest("<code>List<String> ids<br><br><b>Static type:</b> List<String><br></code>", "class A { foo() { List<String> <caret>ids; }}"); } public void testParamClassSig7() throws Exception { doTest( "<code>List<Map<String, int>> ids<br><br><b>Static type:</b> List<Map<String, int>><br></code>", "class A { foo() { List<Map<String, int>> <caret>ids; }}"); } public void testParamClassSig8() throws Exception { doTest("<code>List<List<Map<String, List<Object>>>> list<br><br>" + "<b>Static type:</b> List<List<Map<String, List<Object>>>><br></code>", "class A { foo() { List<List<Map<String, List<Object>>>> <caret>list; }}"); } public void testSetterSig() throws Exception { doTest("<code>set x(int x) → void<br><br><b>Containing class:</b> Z<br></code>", "class Z { void set <caret>x(int x) { } }"); } public void testTopLevelVarDoc1() throws Exception { doTest("<code>dynamic x<br><br><b>Containing library:</b> a.b.c<br><br>" + "<b>Static type:</b> dynamic<br><b>Propagated type:</b> String<br></code>\n<p>docs1\n" + "docs2</p>", "library a.b.c;\n" + "/// docs1\n" + "/// docs2\n" + "@deprecated var <caret>x = 'foo';"); } public void testTopLevelVarDoc2() throws Exception { doTest("<code>int x<br><br><b>Containing library:</b> a.b.c<br><br><b>Static type:</b> int<br></code>", "library a.b.c;\nint <caret>x = 3;\n"); } public void testTypedefSig() throws Exception { doTest("<code>typedef F(int x) → int<br></code>", "typedef int <caret>F(int x);"); } private void doTest(String expectedDoc, String fileContents) { final int caretOffset = fileContents.indexOf("<caret>"); assertTrue(caretOffset != -1); final String realContents = fileContents.substring(0, caretOffset) + fileContents.substring(caretOffset + "<caret>".length()); final PsiFile psiFile = myFixture.configureByText("test.dart", realContents); //System.out.println(psiFile.getText()); myFixture.doHighlighting(); // warm up //final DartComponent dartComponent = PsiTreeUtil.getParentOfType(psiFile.findElementAt(caretOffset), DartComponent.class); //assertNotNull("target element not found at offset " + caretOffset, dartComponent); final HoverInformation hover = DartDocumentationProvider.getSingleHover(psiFile, caretOffset); assertNotNull(hover); //System.out.println(hover); final String doc = DartDocumentationProvider.generateDocServer(hover); assertEquals(expectedDoc, doc); //for (int i = 0; i < 10; i++) { // final HoverInformation hover = DartDocumentationProvider.getSingleHover(psiFile, caretOffset); // System.out.println(hover); // if (hover != null) { // final String doc = DartDocumentationProvider.generateDocServer(hover); // assertEquals(expectedDoc, doc); // System.out.println("!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); // break; // } // Uninterruptibles.sleepUninterruptibly(100, TimeUnit.MILLISECONDS); //} } }