Skip to content

Commit b1fb03f

Browse files
authored
Merge pull request #412 from modelix/fix/modelql-unresolved-concept
MODELIX-714 ModelQl query on model-server fails with "issue getting concept"
2 parents bbee487 + fd8e483 commit b1fb03f

File tree

7 files changed

+216
-104
lines changed

7 files changed

+216
-104
lines changed

model-api-gen-gradle-test/ci.sh

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,19 @@
22

33
set -e
44
(
5-
cd "$(dirname "$0")"
6-
./gradlew build
5+
TEST_DIR="$(dirname "$(readlink -f "$0")")"
6+
cd "$TEST_DIR/../"
7+
if [ "${CI}" != "true" ]; then
8+
trap cleanup INT TERM EXIT
9+
cleanup () {
10+
kill "${MODEL_SERVER_PID}"
11+
exit
12+
}
13+
fi
14+
./gradlew :model-server:run --console=plain --args="-inmemory -port 28102" &
15+
MODEL_SERVER_PID=$!
16+
17+
curl -X GET --retry 30 --retry-connrefused --retry-delay 1 http://localhost:28102/health
18+
cd "$TEST_DIR"
19+
./gradlew build --console=plain --stacktrace
720
)

model-api-gen-gradle-test/kotlin-generation/src/test/kotlin/org/modelix/modelql/typed/TypedModelQLTest.kt

Lines changed: 58 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,6 @@
1313
*/
1414
package org.modelix.modelql.typed
1515

16-
import io.ktor.client.HttpClient
17-
import io.ktor.server.testing.testApplication
1816
import jetbrains.mps.baseLanguage.C_ClassConcept
1917
import jetbrains.mps.baseLanguage.C_IntegerType
2018
import jetbrains.mps.baseLanguage.C_MinusExpression
@@ -32,19 +30,12 @@ import jetbrains.mps.core.xml.C_XmlDocument
3230
import jetbrains.mps.core.xml.C_XmlFile
3331
import jetbrains.mps.lang.editor.imageGen.C_ImageGenerator
3432
import jetbrains.mps.lang.editor.imageGen.ImageGenerator
35-
import org.modelix.apigen.test.ApigenTestLanguages
3633
import org.modelix.metamodel.instanceOf
3734
import org.modelix.metamodel.typed
3835
import org.modelix.metamodel.untyped
39-
import org.modelix.model.api.IBranch
40-
import org.modelix.model.api.PBranch
41-
import org.modelix.model.api.getRootNode
36+
import org.modelix.model.api.INode
37+
import org.modelix.model.api.remove
4238
import org.modelix.model.api.resolve
43-
import org.modelix.model.client.IdGenerator
44-
import org.modelix.model.lazy.CLTree
45-
import org.modelix.model.lazy.ObjectStoreCache
46-
import org.modelix.model.persistent.MapBasedStore
47-
import org.modelix.model.server.light.LightModelServer
4839
import org.modelix.modelql.client.ModelQLClient
4940
import org.modelix.modelql.core.asMono
5041
import org.modelix.modelql.core.count
@@ -75,78 +66,62 @@ import org.modelix.modelql.gen.jetbrains.mps.lang.editor.imageGen.setNode
7566
import org.modelix.modelql.untyped.children
7667
import org.modelix.modelql.untyped.conceptReference
7768
import org.modelix.modelql.untyped.descendants
78-
import kotlin.test.BeforeTest
7969
import kotlin.test.Test
8070
import kotlin.test.assertEquals
8171
import kotlin.test.assertNotEquals
8272
import kotlin.test.assertNotNull
8373
import kotlin.test.assertNull
8474
import kotlin.test.assertTrue
8575

86-
class TypedModelQLTest {
87-
private lateinit var branch: IBranch
88-
89-
private fun runTest(block: suspend (HttpClient) -> Unit) = testApplication {
90-
application {
91-
LightModelServer(80, branch.getRootNode()).apply { installHandlers() }
92-
}
93-
val httpClient = createClient {
94-
}
95-
block(httpClient)
96-
}
97-
98-
@BeforeTest
99-
fun setup() {
100-
ApigenTestLanguages.registerAll()
101-
val tree = CLTree(ObjectStoreCache(MapBasedStore()))
102-
branch = PBranch(tree, IdGenerator.getInstance(1))
103-
val rootNode = branch.getRootNode()
104-
branch.runWrite {
105-
val cls1 = rootNode.addNewChild("classes", -1, C_ClassConcept.untyped()).typed<ClassConcept>()
106-
cls1.apply {
107-
name = "Math"
108-
member.addNew(C_StaticMethodDeclaration).apply {
109-
name = "plus"
110-
returnType.setNew(C_IntegerType)
111-
visibility.setNew(C_PublicVisibility)
112-
val a = parameter.addNew().apply {
113-
name = "a"
114-
type.setNew(C_IntegerType)
115-
}
116-
val b = parameter.addNew().apply {
117-
name = "b"
118-
type.setNew(C_IntegerType)
119-
}
120-
body.setNew().apply {
121-
statement.addNew(C_ReturnStatement).apply {
122-
expression.setNew(C_PlusExpression).apply {
123-
leftExpression.setNew(C_VariableReference).apply {
124-
variableDeclaration = a
125-
}
126-
rightExpression.setNew(C_VariableReference).apply {
127-
variableDeclaration = b
128-
}
76+
abstract class TypedModelQLTest {
77+
78+
abstract fun runTest(block: suspend (ModelQLClient) -> Unit)
79+
80+
protected fun createTestData(rootNode: INode) {
81+
rootNode.allChildren.forEach { it.remove() }
82+
val cls1 = rootNode.addNewChild("classes", -1, C_ClassConcept.untyped()).typed<ClassConcept>()
83+
cls1.apply {
84+
name = "Math"
85+
member.addNew(C_StaticMethodDeclaration).apply {
86+
name = "plus"
87+
returnType.setNew(C_IntegerType)
88+
visibility.setNew(C_PublicVisibility)
89+
val a = parameter.addNew().apply {
90+
name = "a"
91+
type.setNew(C_IntegerType)
92+
}
93+
val b = parameter.addNew().apply {
94+
name = "b"
95+
type.setNew(C_IntegerType)
96+
}
97+
body.setNew().apply {
98+
statement.addNew(C_ReturnStatement).apply {
99+
expression.setNew(C_PlusExpression).apply {
100+
leftExpression.setNew(C_VariableReference).apply {
101+
variableDeclaration = a
102+
}
103+
rightExpression.setNew(C_VariableReference).apply {
104+
variableDeclaration = b
129105
}
130106
}
131107
}
132108
}
133109
}
134-
// Example for optional reference
135-
rootNode.addNewChild("imageGen", -1, C_ImageGenerator.untyped())
136-
.typed<ImageGenerator>()
137-
.apply { node = cls1 }
110+
}
111+
// Example for optional reference
112+
rootNode.addNewChild("imageGen", -1, C_ImageGenerator.untyped())
113+
.typed<ImageGenerator>()
114+
.apply { node = cls1 }
138115

139-
// Example for single non-abstract child
140-
rootNode.addNewChild("xmlFile", -1, C_XmlFile.untyped())
116+
// Example for single non-abstract child
117+
rootNode.addNewChild("xmlFile", -1, C_XmlFile.untyped())
141118

142-
// Example for mulitple non-abstract child
143-
rootNode.addNewChild("xmlComment", -1, C_XmlComment.untyped())
144-
}
119+
// Example for mulitple non-abstract child
120+
rootNode.addNewChild("xmlComment", -1, C_XmlComment.untyped())
145121
}
146122

147123
@Test
148-
fun simpleTest() = runTest { httpClient ->
149-
val client = ModelQLClient.builder().url("http://localhost/query").httpClient(httpClient).build()
124+
fun `simple query`() = runTest { client ->
150125
val result: Int = client.query { root ->
151126
root.children("classes").ofConcept(C_ClassConcept)
152127
.member
@@ -157,22 +132,22 @@ class TypedModelQLTest {
157132
}
158133

159134
@Test
160-
fun test() = runTest { httpClient ->
161-
val client = ModelQLClient.builder().url("http://localhost/query").httpClient(httpClient).build()
135+
fun `complex query`() = runTest { client ->
162136
val result: List<Pair<String, String>> = client.query { root ->
163137
root.children("classes").ofConcept(C_ClassConcept)
164138
.member
165139
.ofConcept(C_StaticMethodDeclaration)
166140
.filter { it.visibility.instanceOf(C_PublicVisibility) }
167141
.map { it.name.zip(it.parameter.name.toList(), it.untyped().conceptReference()) }
168142
.toList()
169-
}.map { it.first to it.first + "(" + it.second.joinToString(", ") + ") [" + it.third?.resolve()?.getLongName() + "]" }
143+
}.map {
144+
it.first to it.first + "(" + it.second.joinToString(", ") + ") [" + it.third?.resolve()?.getLongName() + "]"
145+
}
170146
assertEquals(listOf("plus" to "plus(a, b) [jetbrains.mps.baseLanguage.StaticMethodDeclaration]"), result)
171147
}
172148

173149
@Test
174-
fun `get references`() = runTest { httpClient ->
175-
val client = ModelQLClient.builder().url("http://localhost/query").httpClient(httpClient).build()
150+
fun `get references`() = runTest { client ->
176151
val usedVariables: Set<String> = client.query { root ->
177152
root.children("classes").ofConcept(C_ClassConcept)
178153
.member
@@ -187,8 +162,7 @@ class TypedModelQLTest {
187162
}
188163

189164
@Test
190-
fun `get references - fqName`() = runTest { httpClient ->
191-
val client = ModelQLClient.builder().url("http://localhost/query").httpClient(httpClient).build()
165+
fun `get references - fqName`() = runTest { client ->
192166
val usedVariables: Set<String> = client.query { root ->
193167
root.children("classes").ofConcept(C_ClassConcept)
194168
.member
@@ -210,8 +184,7 @@ class TypedModelQLTest {
210184
}
211185

212186
@Test
213-
fun `node serialization`() = runTest { httpClient ->
214-
val client = ModelQLClient.builder().url("http://localhost/query").httpClient(httpClient).build()
187+
fun `node serialization`() = runTest { client ->
215188
val result: List<StaticMethodDeclaration> = client.query { root ->
216189
root.children("classes").ofConcept(C_ClassConcept)
217190
.member
@@ -220,25 +193,23 @@ class TypedModelQLTest {
220193
.untyped()
221194
.toList()
222195
}.map { it.typed<StaticMethodDeclaration>() }
223-
assertEquals("plus", branch.computeRead { result[0].name })
196+
assertEquals("plus", result[0].name)
224197
}
225198

226199
@Test
227-
fun `return typed node`() = runTest { httpClient ->
228-
val client = ModelQLClient.builder().url("http://localhost/query").httpClient(httpClient).build()
200+
fun `return typed node`() = runTest { client ->
229201
val result: List<StaticMethodDeclaration> = client.query { root ->
230202
root.children("classes").ofConcept(C_ClassConcept)
231203
.member
232204
.ofConcept(C_StaticMethodDeclaration)
233205
.filter { it.visibility.instanceOf(C_PublicVisibility) }
234206
.toList()
235207
}
236-
assertEquals("plus", branch.computeRead { result[0].name })
208+
assertEquals("plus", result[0].name)
237209
}
238210

239211
@Test
240-
fun `set property`() = runTest { httpClient ->
241-
val client = ModelQLClient.builder().url("http://localhost/query").httpClient(httpClient).build()
212+
fun `set property`() = runTest { client ->
242213
val expected = "myRenamedMethod"
243214
client.query { root ->
244215
root.children("classes").ofConcept(C_ClassConcept)
@@ -257,9 +228,7 @@ class TypedModelQLTest {
257228
}
258229

259230
@Test
260-
fun `set reference`() = runTest { httpClient ->
261-
val client = ModelQLClient.builder().url("http://localhost/query").httpClient(httpClient).build()
262-
231+
fun `set reference`() = runTest { client ->
263232
val oldValue = client.query { root ->
264233
root.children("classes").ofConcept(C_ClassConcept)
265234
.member
@@ -298,8 +267,7 @@ class TypedModelQLTest {
298267
}
299268

300269
@Test
301-
fun `set reference - null`() = runTest { httpClient ->
302-
val client = ModelQLClient.builder().url("http://localhost/query").httpClient(httpClient).build()
270+
fun `set reference - null`() = runTest { client ->
303271
val oldValue = client.query { root ->
304272
root.children("imageGen").ofConcept(C_ImageGenerator).first().node
305273
}
@@ -316,9 +284,7 @@ class TypedModelQLTest {
316284
}
317285

318286
@Test
319-
fun `add new child`() = runTest { httpClient ->
320-
val client = ModelQLClient.builder().url("http://localhost/query").httpClient(httpClient).build()
321-
287+
fun `add new child`() = runTest { client ->
322288
val oldNumChildren = client.query { root ->
323289
root.children("classes").ofConcept(C_ClassConcept)
324290
.first()
@@ -346,8 +312,7 @@ class TypedModelQLTest {
346312
}
347313

348314
@Test
349-
fun `add new child - default concept`() = runTest { httpClient ->
350-
val client = ModelQLClient.builder().url("http://localhost/query").httpClient(httpClient).build()
315+
fun `add new child - default concept`() = runTest { client ->
351316
client.query { root ->
352317
root.descendants().ofConcept(C_XmlComment)
353318
.first()
@@ -365,9 +330,7 @@ class TypedModelQLTest {
365330
}
366331

367332
@Test
368-
fun `set child`() = runTest { httpClient ->
369-
val client = ModelQLClient.builder().url("http://localhost/query").httpClient(httpClient).build()
370-
333+
fun `set child`() = runTest { client ->
371334
client.query { root ->
372335
root.descendants().ofConcept(C_ReturnStatement)
373336
.first()
@@ -382,8 +345,7 @@ class TypedModelQLTest {
382345
}
383346

384347
@Test
385-
fun `set child - default concept`() = runTest { httpClient ->
386-
val client = ModelQLClient.builder().url("http://localhost/query").httpClient(httpClient).build()
348+
fun `set child - default concept`() = runTest { client ->
387349
client.query { root ->
388350
root.descendants().ofConcept(C_XmlFile)
389351
.first()
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/*
2+
* Licensed under the Apache License, Version 2.0 (the "License");
3+
* you may not use this file except in compliance with the License.
4+
* You may obtain a copy of the License at
5+
*
6+
* http://www.apache.org/licenses/LICENSE-2.0
7+
*
8+
* Unless required by applicable law or agreed to in writing, software
9+
* distributed under the License is distributed on an "AS IS" BASIS,
10+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
* See the License for the specific language governing permissions and
12+
* limitations under the License.
13+
*/
14+
package org.modelix.modelql.typed
15+
16+
import io.ktor.server.testing.testApplication
17+
import org.modelix.apigen.test.ApigenTestLanguages
18+
import org.modelix.model.api.IBranch
19+
import org.modelix.model.api.PBranch
20+
import org.modelix.model.api.getRootNode
21+
import org.modelix.model.client.IdGenerator
22+
import org.modelix.model.lazy.CLTree
23+
import org.modelix.model.lazy.ObjectStoreCache
24+
import org.modelix.model.persistent.MapBasedStore
25+
import org.modelix.model.server.light.LightModelServer
26+
import org.modelix.modelql.client.ModelQLClient
27+
import kotlin.test.BeforeTest
28+
29+
class TypedModelQLTestWithLightModelServer : TypedModelQLTest() {
30+
private lateinit var branch: IBranch
31+
32+
override fun runTest(block: suspend (ModelQLClient) -> Unit) = testApplication {
33+
application {
34+
LightModelServer(80, branch.getRootNode()).apply { installHandlers() }
35+
}
36+
val httpClient = createClient {
37+
}
38+
val modelQlClient = ModelQLClient.builder().url("http://localhost/query").httpClient(httpClient).build()
39+
block(modelQlClient)
40+
}
41+
42+
@BeforeTest
43+
fun setup() {
44+
ApigenTestLanguages.registerAll()
45+
val tree = CLTree(ObjectStoreCache(MapBasedStore()))
46+
branch = PBranch(tree, IdGenerator.getInstance(1))
47+
branch.runWrite {
48+
createTestData(branch.getRootNode())
49+
}
50+
}
51+
}

0 commit comments

Comments
 (0)