Skip to content

Commit

Permalink
feat(rust): init first content challedge for test code gen
Browse files Browse the repository at this point in the history
  • Loading branch information
phodal committed Jan 4, 2024
1 parent 070c74d commit 90e1367
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 10 deletions.
Original file line number Diff line number Diff line change
@@ -1,37 +1,77 @@
package cc.unitmesh.pick.builder.unittest.rust

import cc.unitmesh.core.SupportedLang
import cc.unitmesh.core.ast.NodeIdentifier
import cc.unitmesh.core.ast.NodeType
import cc.unitmesh.core.unittest.TestCodeBuilderType
import cc.unitmesh.core.unittest.TypedTestIns
import cc.unitmesh.pick.builder.unittest.base.BasicTestIns
import cc.unitmesh.pick.builder.unittest.base.UnitTestService
import cc.unitmesh.pick.spec.checkNamingStyle
import cc.unitmesh.pick.worker.job.JobContext
import chapi.domain.core.CodeContainer
import chapi.domain.core.CodeDataStruct
import chapi.domain.core.CodeFunction

class RustTestCodeService(val job: JobContext) : UnitTestService {
override fun isApplicable(dataStruct: CodeDataStruct): Boolean = false

override fun isApplicable(container: CodeContainer): Boolean = job.project.language == SupportedLang.RUST

override fun build(container: CodeContainer): List<TypedTestIns> {
val functionMap = container.DataStructures.map {
it.Functions.associateBy(::buildCanonicalName)
}

val testDataStruct = container.DataStructures.filter {
it.Module == "tests"
}
if (testDataStruct.isEmpty()) return emptyList()

val namingStyle = testDataStruct.first().checkNamingStyle()
val testCode = testDataStruct.map { dataStruct ->
dataStruct.Functions.filter { function -> function.Annotations.any { it.Name == "test" } }
}.flatten()

if (testCode.isEmpty()) return emptyList()

println(testCode)
testCode.forEach {
it.FunctionCalls.forEach { functionCall ->
// todo: lookup method call in Chapi
val result = testCode.mapNotNull { codeFunction ->
codeFunction.FunctionCalls.mapNotNull { codeCall ->
val canonicalName = buildCanonicalName(codeCall.NodeName, codeCall.FunctionName)
val underTestFunction = functionMap.firstNotNullOfOrNull { it[canonicalName] }
if (underTestFunction == null) {
null
} else {
BasicTestIns(
identifier = NodeIdentifier(
type = NodeType.METHOD,
name = underTestFunction.Package + " Class' " + underTestFunction.Name,
),
language = job.project.language,
underTestCode = underTestFunction.Content,
generatedCode = codeFunction.Content,
coreFrameworks = job.project.coreFrameworks,
testFrameworks = job.project.testFrameworks,
testType = TestCodeBuilderType.METHOD_UNIT,
relatedCode = listOf(),
specs = listOf(
"Test class should be named `${namingStyle}`."
)
)
}
}
}
}.flatten()

return emptyList()
return result
}

private fun buildCanonicalName(function: CodeFunction): String {
return buildCanonicalName(function.Package, function.Name)
}

private fun buildCanonicalName(nodeName: String, funcName: String): String {
val node = nodeName.ifEmpty { "main" }
return "$node::$funcName"
}

override fun build(dataStruct: CodeDataStruct): List<TypedTestIns> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ fun CodeContainer.buildSourceCode(codeLines: List<String>) {
position.StartLine = annotationPos.StartLine
position.StartLinePosition = annotationPos.StartLinePosition
}

it.Content = CodeDataStructUtil.contentByPosition(codeLines, it.Position)
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package cc.unitmesh.pick.builder.unittest.rust;

import cc.unitmesh.core.completion.CompletionBuilderType
import cc.unitmesh.pick.builder.unittest.base.BasicTestIns
import cc.unitmesh.pick.ext.buildSourceCode
import cc.unitmesh.pick.option.InsOutputConfig
import cc.unitmesh.pick.threshold.InsQualityThreshold
import cc.unitmesh.pick.worker.job.InstructionFileJob
Expand Down Expand Up @@ -45,9 +47,10 @@ class RustTestCodeServiceTest {
""".trimIndent()

val container = RustAnalyser().analysis(testCode, "lib.rs")
container.buildSourceCode(testCode.lines())

val testFileJob = InstructionFileJob(
FileJob(
),
FileJob(),
codeLines = testCode.lines(),
code = testCode,
container = container
Expand All @@ -64,9 +67,14 @@ class RustTestCodeServiceTest {
insQualityThreshold = InsQualityThreshold()
)
val rustTestCodeService = RustTestCodeService(context)
val build = rustTestCodeService.build(container)
val build: List<BasicTestIns> = rustTestCodeService.build(container) as List<BasicTestIns>

assertEquals(0, build.size)
assertEquals(1, build.size)
assertEquals("""fn init_semantic(model: Vec<u8>, tokenizer_data: Vec<u8>) -> Result<Arc<Semantic>, SemanticError> {
let result = Semantic::init_semantic(model, tokenizer_data)?;
Ok(Arc::new(result))
}""", build[0].underTestCode)
// assertEquals("test_init_semantic", build[0].generatedCode)
}

}

0 comments on commit 90e1367

Please sign in to comment.