Js test configuration and JS meta implementation

This commit is contained in:
Alexander Nozik 2019-03-27 20:43:01 +03:00
parent 63cd209f58
commit 7ce45f4ab1
4 changed files with 128 additions and 27 deletions

View File

@ -1,4 +1,8 @@
import com.moowork.gradle.node.NodeExtension
import com.moowork.gradle.node.npm.NpmTask
import com.moowork.gradle.node.task.NodeTask
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
import org.jetbrains.kotlin.gradle.tasks.Kotlin2JsCompile
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
buildscript { buildscript {
@ -26,6 +30,7 @@ buildscript {
plugins { plugins {
id("com.jfrog.artifactory") version "4.8.1" apply false id("com.jfrog.artifactory") version "4.8.1" apply false
id("com.moowork.node") version "1.3.1" apply false
// id("org.jetbrains.kotlin.multiplatform") apply false // id("org.jetbrains.kotlin.multiplatform") apply false
} }
@ -62,6 +67,8 @@ subprojects {
// classifier = "javadoc" // classifier = "javadoc"
// } // }
apply(plugin = "com.moowork.node")
// Create empty jar for sources classifier to satisfy maven requirements // Create empty jar for sources classifier to satisfy maven requirements
val stubSources by tasks.registering(Jar::class) { val stubSources by tasks.registering(Jar::class) {
archiveClassifier.set("sources") archiveClassifier.set("sources")
@ -74,7 +81,7 @@ subprojects {
} }
tasks.withType<KotlinCompile> { tasks.withType<KotlinCompile> {
kotlinOptions{ kotlinOptions {
jvmTarget = "1.8" jvmTarget = "1.8"
} }
} }
@ -109,6 +116,40 @@ subprojects {
} }
} }
} }
configure<NodeExtension>{
nodeModulesDir = file("$buildDir/node_modules")
}
val compileKotlinJs by tasks.getting(Kotlin2JsCompile::class)
val compileTestKotlinJs by tasks.getting(Kotlin2JsCompile::class)
val populateNodeModules by tasks.registering(Copy::class) {
dependsOn(compileKotlinJs)
from(compileKotlinJs.destinationDir)
compilations["test"].runtimeDependencyFiles.forEach {
if (it.exists() && !it.isDirectory) {
from(zipTree(it.absolutePath).matching { include("*.js") })
}
}
into("$buildDir/node_modules")
}
val installMocha by tasks.registering(NpmTask::class) {
setWorkingDir(buildDir)
setArgs(listOf("install", "mocha"))
}
val runMocha by tasks.registering(NodeTask::class) {
dependsOn(compileTestKotlinJs, populateNodeModules, installMocha)
setScript(file("$buildDir/node_modules/mocha/bin/mocha"))
setArgs(listOf(compileTestKotlinJs.outputFile))
}
tasks["jsTest"].dependsOn(runMocha)
} }
sourceSets { sourceSets {

View File

@ -0,0 +1,64 @@
package hep.dataforge.meta
import hep.dataforge.names.NameToken
import hep.dataforge.values.Null
import hep.dataforge.values.Value
//TODO add Meta wrapper for dynamic
/**
* Represent or copy this [Meta] to dynamic object to be passed to JS libraries
*/
fun Meta.toDynamic(): dynamic {
if(this is DynamicMeta) return this.obj
fun MetaItem<*>.toDynamic(): dynamic = when (this) {
is MetaItem.ValueItem -> this.value.value.asDynamic()
is MetaItem.NodeItem -> this.node.toDynamic()
}
val res = js("{}")
this.items.entries.groupBy { it.key.body }.forEach { (key, value) ->
val list = value.map { it.value }
res[key] = when (list.size) {
1 -> list.first().toDynamic()
else -> list.map { it.toDynamic() }
}
}
return res
}
class DynamicMeta(val obj: dynamic) : Meta {
private fun keys() = js("Object.keys(this.obj)") as Array<String>
private fun isArray(obj: dynamic): Boolean = js("Array.isArray(obj)") as Boolean
//private fun isObject(obj: dynamic): Boolean = js("typeof obj === 'object'") as Boolean
private fun asItem(obj: dynamic): MetaItem<DynamicMeta>? {
if (obj == null) return MetaItem.ValueItem(Null)
return when (jsTypeOf(obj)) {
"boolean" -> MetaItem.ValueItem(Value.of(obj as Boolean))
"number" -> MetaItem.ValueItem(Value.of(obj as Number))
"string" -> MetaItem.ValueItem(Value.of(obj as String))
"object" -> MetaItem.NodeItem(DynamicMeta(obj))
else -> null
}
}
override val items: Map<NameToken, MetaItem<DynamicMeta>>
get() = keys().flatMap<String, Pair<NameToken, MetaItem<DynamicMeta>>> { key ->
val value = obj[key] ?: return@flatMap emptyList()
if (isArray(value)) {
return@flatMap (value as Array<dynamic>)
.mapIndexedNotNull() { index, it ->
val item = asItem(it) ?: return@mapIndexedNotNull null
NameToken(key, index.toString()) to item
}
} else {
val item = asItem(value) ?: return@flatMap emptyList()
listOf(NameToken(key) to item)
}
}.associate { it }
}

View File

@ -1,26 +0,0 @@
package hep.dataforge.meta
//TODO add Meta wrapper for dynamic
/**
* Represent or copy this [Meta] to dynamic object to be passed to JS libraries
*/
fun Meta.toDynamic(): dynamic {
//if(this is DynamicMeta) return this.obj
fun MetaItem<*>.toDynamic(): dynamic = when (this) {
is MetaItem.ValueItem -> this.value.value.asDynamic()
is MetaItem.NodeItem -> this.node.toDynamic()
}
val res = js("{}")
this.items.entries.groupBy { it.key.body }.forEach { (key, value) ->
val list = value.map { it.value }
res[key] = when (list.size) {
1 -> list.first().toDynamic()
else -> list.map { it.toDynamic() }
}
}
return res
}

View File

@ -0,0 +1,22 @@
package hep.dataforge.meta
import kotlin.test.Test
import kotlin.test.assertEquals
class DynamicMetaTest {
@Test
fun testDynamicMeta() {
val d = js("{}")
d.a = 22
d.b = "myString"
d.ob = js("{}")
d.ob.childNode = 18
d.ob.booleanNode = true
val meta = DynamicMeta(d)
assertEquals(true, meta["ob.booleanNode"].boolean)
}
}