Skip to content

Commit b7658bd

Browse files
committed
Additional round of tests for completion in query and fragment contexts (#164)
1 parent 73733cf commit b7658bd

32 files changed

+409
-4
lines changed

src/main/com/intellij/lang/jsgraphql/ide/completion/GraphQLCompletionContributor.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -290,8 +290,9 @@ protected void addCompletions(@NotNull final CompletionParameters parameters, Pr
290290
typeScopeProvider = PsiTreeUtil.getParentOfType(typeScopeProvider, GraphQLTypeScopeProvider.class);
291291
}
292292

293-
final GraphQLType typeScope = typeScopeProvider != null ? typeScopeProvider.getTypeScope() : null;
293+
GraphQLType typeScope = typeScopeProvider != null ? typeScopeProvider.getTypeScope() : null;
294294
if (typeScope != null) {
295+
typeScope = new SchemaUtil().getUnmodifiedType(typeScope); // unwrap non-null and lists since fragments are about the raw type
295296
final TypeDefinition fragmentType = typeDefinitionRegistry.getType(typeScope.getName()).orElse(null);
296297
if (fragmentType != null) {
297298
final Ref<Consumer<TypeDefinition<?>>> addTypesRecursive = new Ref<>();
@@ -983,6 +984,9 @@ private boolean isValidDirectiveLocation(GraphQLDirectivesAware directivesAware,
983984
*/
984985
private boolean isFragmentApplicableInTypeScope(TypeDefinitionRegistry typeDefinitionRegistry, GraphQLFragmentDefinition fragmentCandidate, GraphQLType requiredTypeScope) {
985986

987+
// unwrap non-nullable and list types
988+
requiredTypeScope = new SchemaUtil().getUnmodifiedType(requiredTypeScope);
989+
986990
final GraphQLTypeCondition typeCondition = fragmentCandidate.getTypeCondition();
987991
if (typeCondition == null || typeCondition.getTypeName() == null) {
988992
return false;
@@ -1008,6 +1012,10 @@ private boolean isFragmentApplicableInTypeScope(TypeDefinitionRegistry typeDefin
10081012
* @return true if the candidate type condtion name is compatible inside the required type scope
10091013
*/
10101014
private boolean isCompatibleFragment(TypeDefinitionRegistry typeDefinitionRegistry, GraphQLType requiredTypeScope, String fragmentTypeName) {
1015+
1016+
// unwrap non-nullable and list types
1017+
requiredTypeScope = new SchemaUtil().getUnmodifiedType(requiredTypeScope);
1018+
10111019
if (requiredTypeScope instanceof GraphQLInterfaceType) {
10121020
// also include fragments on types implementing the interface scope
10131021
final TypeDefinition typeScopeDefinition = typeDefinitionRegistry.types().get(requiredTypeScope.getName());

src/main/com/intellij/lang/jsgraphql/ide/project/graphqlconfig/GraphQLConfigGlobMatcherImpl.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
import com.google.common.collect.Maps;
1111
import com.intellij.ide.plugins.PluginManager;
12+
import com.intellij.openapi.application.ApplicationManager;
1213
import com.intellij.openapi.extensions.PluginDescriptor;
1314
import com.intellij.openapi.extensions.PluginId;
1415
import com.intellij.openapi.util.Pair;
@@ -46,7 +47,13 @@ public boolean matches(String filePath, String glob) {
4647
final ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
4748
try {
4849
engine.put(NASHORN_SCRIPT_OBJECT, engine.eval("new Object()"));
49-
final String script = IOUtils.resourceToString("/META-INF/minimatch-nashorn.js", Charset.defaultCharset(), pluginDescriptor.getPluginClassLoader());
50+
final String script;
51+
if(ApplicationManager.getApplication().isUnitTestMode()) {
52+
// plugin class loader appears to be unable to locate certain resources during unit-test?!
53+
script = IOUtils.toString(getClass().getResource("/META-INF/minimatch-nashorn.js"), Charset.forName("UTF-8"));
54+
} else {
55+
script = IOUtils.resourceToString("/META-INF/minimatch-nashorn.js", Charset.forName("UTF-8"), pluginDescriptor.getPluginClassLoader());
56+
}
5057
engine.eval(script);
5158
} catch (IOException | ScriptException e) {
5259
throw new RuntimeException("Unable to load minimatch-nashorn.js", e);
Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
/**
2+
* Copyright (c) 2018-present, Jim Kynde Meyer
3+
* All rights reserved.
4+
* <p>
5+
* This source code is licensed under the MIT license found in the
6+
* LICENSE file in the root directory of this source tree.
7+
*/
8+
package com.intellij.lang.jsgraphql.operations;
9+
10+
import com.google.common.collect.Lists;
11+
import com.intellij.codeInsight.completion.CompletionType;
12+
import com.intellij.openapi.application.ApplicationManager;
13+
import com.intellij.psi.PsiDocumentManager;
14+
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase;
15+
import org.junit.Test;
16+
17+
import java.util.List;
18+
19+
20+
public class JSGraphQLOperationsCodeInsightTest extends LightCodeInsightFixtureTestCase {
21+
22+
@Override
23+
public void setUp() throws Exception {
24+
super.setUp();
25+
myFixture.configureByFiles("CompletionSchema.graphqls");
26+
}
27+
28+
@Override
29+
protected String getTestDataPath() {
30+
return "test-resources/testData/graphql/operations";
31+
}
32+
33+
// ---- completion ----
34+
35+
@Test
36+
public void testCompletionOperation() {
37+
doTestCompletion("CompletionOperation.graphql", Lists.newArrayList("directive", "enum", "extend", "fragment", "input", "interface", "mutation", "query", "scalar", "schema", "subscription", "type", "union", "{"));
38+
}
39+
40+
// -- root field names --
41+
42+
@Test
43+
public void testCompletionRootField1() {
44+
doTestCompletion("CompletionRootField1.graphql", Lists.newArrayList("human", "node", "nodes"));
45+
}
46+
47+
@Test
48+
public void testCompletionRootField2() {
49+
doTestCompletion("CompletionRootField1.graphql", Lists.newArrayList("human", "node", "nodes"));
50+
}
51+
52+
@Test
53+
public void testCompletionRootField3() {
54+
doTestCompletion("CompletionRootField1.graphql", Lists.newArrayList("human", "node", "nodes"));
55+
}
56+
57+
// -- field arguments --
58+
59+
@Test
60+
public void testCompletionRootFieldArg1() {
61+
doTestCompletion("CompletionRootFieldArg1.graphql", Lists.newArrayList("id"));
62+
}
63+
64+
@Test
65+
public void testCompletionNestedFieldArg1() {
66+
doTestCompletion("CompletionNestedFieldArg1.graphql", Lists.newArrayList("another", "height"));
67+
}
68+
69+
@Test
70+
public void testCompletionNestedFieldArg2() {
71+
doTestCompletion("CompletionNestedFieldArg2.graphql", Lists.newArrayList("Imperial", "Metric"));
72+
}
73+
74+
@Test
75+
public void testCompletionNestedFieldArg3() {
76+
doTestCompletion("CompletionNestedFieldArg3.graphql", Lists.newArrayList("another"));
77+
}
78+
79+
// --- extend types --
80+
81+
@Test
82+
public void testCompletionFieldExtension() {
83+
doTestCompletion("CompletionFieldExtension.graphql", Lists.newArrayList("...", "enumField", "extended", "fieldWithArg", "fieldWithInput", "id", "name", "search"));
84+
}
85+
86+
87+
// -- fragments --
88+
89+
@Test
90+
public void testCompletionFragmentDefinition() {
91+
doTestCompletion("CompletionFragmentDefinition.graphql", Lists.newArrayList("Human", "Mutation", "Node", "Query", "SearchResult", "Ship"));
92+
}
93+
94+
@Test
95+
public void testCompletionFragmentField() {
96+
doTestCompletion("CompletionFragmentField.graphql", Lists.newArrayList("...", "id"));
97+
}
98+
99+
@Test
100+
public void testCompletionFragmentInlineType() {
101+
doTestCompletion("CompletionFragmentInlineType.graphql", Lists.newArrayList("Human", "Node", "Ship"));
102+
}
103+
104+
@Test
105+
public void testCompletionFragmentInlineUnionType() {
106+
doTestCompletion("CompletionFragmentInlineUnionType.graphql", Lists.newArrayList("Human", "Node", "Ship"));
107+
}
108+
109+
@Test
110+
public void testCompletionFragmentInlineReference() {
111+
doTestCompletion("CompletionFragmentInlineReference.graphql", Lists.newArrayList("MyHumanFragment", " on"));
112+
}
113+
114+
115+
// -- input objects --
116+
117+
@Test
118+
public void testCompletionInputNestedField1() {
119+
doTestCompletion("CompletionInputNestedField1.graphql", Lists.newArrayList("inputField1", "nestedField"));
120+
}
121+
122+
@Test
123+
public void testCompletionInputNestedField2() {
124+
doTestCompletion("CompletionInputNestedField2.graphql", Lists.newArrayList("val"));
125+
}
126+
127+
128+
// -- directives --
129+
130+
@Test
131+
public void testCompletionDirectiveOnField() {
132+
doTestCompletion("CompletionDirectiveOnField.graphql", Lists.newArrayList("defer", "include", "onField", "skip"));
133+
}
134+
135+
@Test
136+
public void testCompletionDirectiveOnFieldArg() {
137+
doTestCompletion("CompletionDirectiveOnFieldArg.graphql", Lists.newArrayList("if"));
138+
}
139+
140+
141+
142+
// ---- util ----
143+
private void doTestCompletion(String sourceFile, List<String> expectedCompletions) {
144+
myFixture.configureByFiles(sourceFile);
145+
myFixture.complete(CompletionType.BASIC, 1);
146+
final List<String> completions = myFixture.getLookupElementStrings();
147+
assertEquals("Wrong completions", expectedCompletions, completions);
148+
ApplicationManager.getApplication().runWriteAction(() -> {
149+
myFixture.getEditor().getDocument().setText(""); // blank out the file so it doesn't affect other tests
150+
PsiDocumentManager.getInstance(myFixture.getProject()).commitAllDocuments();
151+
});
152+
}
153+
154+
// ---- highlighting -----
155+
156+
// TODO
157+
// @Test
158+
// public void testErrorAnnotator() {
159+
// myFixture.configureByFiles("ErrorAnnotator.graphqls");
160+
// myFixture.checkHighlighting(false, false, false);
161+
// }
162+
163+
}

src/test/com/intellij/lang/jsgraphql/schema/JSGraphQLSchemaCodeInsightTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,8 @@ public void testCompletionImplementsSecondInterface() {
4242
}
4343

4444
@Test
45-
public void testCompletionOperation() {
46-
doTestCompletion("CompletionOperation.graphqls", Lists.newArrayList("directive", "enum", "extend", "fragment", "input", "interface", "mutation", "query", "scalar", "schema", "subscription", "type", "union", "{"));
45+
public void testCompletionTopLevelKeywords() {
46+
doTestCompletion("CompletionTopLevelKeywords.graphqls", Lists.newArrayList("directive", "enum", "extend", "fragment", "input", "interface", "mutation", "query", "scalar", "schema", "subscription", "type", "union", "{"));
4747
}
4848

4949
@Test
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/**
2+
* Copyright (c) 2018-present, Jim Kynde Meyer
3+
* All rights reserved.
4+
* <p>
5+
* This source code is licensed under the MIT license found in the
6+
* LICENSE file in the root directory of this source tree.
7+
*/
8+
package com.intellij.lang.jsgraphql.schema;
9+
10+
import com.google.common.collect.Lists;
11+
import com.intellij.codeInsight.completion.CompletionType;
12+
import com.intellij.lang.jsgraphql.GraphQLScopeResolution;
13+
import com.intellij.lang.jsgraphql.GraphQLSettings;
14+
import com.intellij.openapi.application.ApplicationManager;
15+
import com.intellij.psi.PsiDocumentManager;
16+
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase;
17+
import org.junit.Test;
18+
19+
import java.util.List;
20+
21+
22+
/**
23+
* Verifies that two schemas can be separated using graphql-config
24+
*/
25+
public class JSGraphQLSchemaGraphQLConfigCodeInsightTest extends LightCodeInsightFixtureTestCase {
26+
27+
@Override
28+
public void setUp() throws Exception {
29+
super.setUp();
30+
final GraphQLSettings settings = GraphQLSettings.getSettings(myFixture.getProject());
31+
settings.setScopeResolution(GraphQLScopeResolution.GRAPHQL_CONFIG_GLOBS);
32+
ApplicationManager.getApplication().saveSettings();
33+
myFixture.configureByFiles("schema-one/.graphqlconfig");
34+
myFixture.configureByFiles("schema-one/schema-one.graphql");
35+
myFixture.configureByFiles("schema-two/.graphqlconfig");
36+
myFixture.configureByFiles("schema-two/schema-two.graphql");
37+
myFixture.configureByFiles("schema-two/schema-excluded-two.graphql");
38+
}
39+
40+
@Override
41+
protected String getTestDataPath() {
42+
return "test-resources/testData/graphql/graphql-config";
43+
}
44+
45+
// ---- completion ----
46+
47+
@Test
48+
public void testCompletionSchemaOne() {
49+
doTestCompletion("schema-one/query-one.graphql", Lists.newArrayList("fieldOne"));
50+
}
51+
52+
@Test
53+
public void testCompletionSchemaTwo() {
54+
doTestCompletion("schema-two/query-two.graphql", Lists.newArrayList("fieldTwo"));
55+
}
56+
57+
58+
private void doTestCompletion(String sourceFile, List<String> expectedCompletions) {
59+
myFixture.configureByFiles(sourceFile);
60+
myFixture.complete(CompletionType.BASIC, 1);
61+
final List<String> completions = myFixture.getLookupElementStrings();
62+
assertEquals("Wrong completions", expectedCompletions, completions);
63+
ApplicationManager.getApplication().runWriteAction(() -> {
64+
myFixture.getEditor().getDocument().setText(""); // blank out the file so it doesn't affect other tests
65+
PsiDocumentManager.getInstance(myFixture.getProject()).commitAllDocuments();
66+
});
67+
}
68+
69+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"extensions": {}
3+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
<caret>
3+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
type Query {
2+
fieldOne: String
3+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"includes": ["*.graphql"],
3+
"excludes": ["*excluded*.graphql"]
4+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
<caret>
3+
}

0 commit comments

Comments
 (0)