From 7ce45f4ab11ed891861db1157c2cbf0094528831 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Wed, 27 Mar 2019 20:43:01 +0300 Subject: [PATCH] Js test configuration and JS meta implementation --- build.gradle.kts | 43 ++++++++++++- .../kotlin/hep/dataforge/meta/DynamicMeta.kt | 64 +++++++++++++++++++ .../kotlin/hep/dataforge/meta/jsMeta.kt | 26 -------- .../hep/dataforge/meta/DynamicMetaTest.kt | 22 +++++++ 4 files changed, 128 insertions(+), 27 deletions(-) create mode 100644 dataforge-meta/src/jsMain/kotlin/hep/dataforge/meta/DynamicMeta.kt delete mode 100644 dataforge-meta/src/jsMain/kotlin/hep/dataforge/meta/jsMeta.kt create mode 100644 dataforge-meta/src/jsTest/kotlin/hep/dataforge/meta/DynamicMetaTest.kt diff --git a/build.gradle.kts b/build.gradle.kts index 6765bc29..a423155c 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -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.tasks.Kotlin2JsCompile import org.jetbrains.kotlin.gradle.tasks.KotlinCompile buildscript { @@ -26,6 +30,7 @@ buildscript { plugins { 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 } @@ -62,6 +67,8 @@ subprojects { // classifier = "javadoc" // } + apply(plugin = "com.moowork.node") + // Create empty jar for sources classifier to satisfy maven requirements val stubSources by tasks.registering(Jar::class) { archiveClassifier.set("sources") @@ -74,7 +81,7 @@ subprojects { } tasks.withType { - kotlinOptions{ + kotlinOptions { jvmTarget = "1.8" } } @@ -109,6 +116,40 @@ subprojects { } } } + + + configure{ + 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 { diff --git a/dataforge-meta/src/jsMain/kotlin/hep/dataforge/meta/DynamicMeta.kt b/dataforge-meta/src/jsMain/kotlin/hep/dataforge/meta/DynamicMeta.kt new file mode 100644 index 00000000..2d96aede --- /dev/null +++ b/dataforge-meta/src/jsMain/kotlin/hep/dataforge/meta/DynamicMeta.kt @@ -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 + + 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? { + 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> + get() = keys().flatMap>> { key -> + val value = obj[key] ?: return@flatMap emptyList() + if (isArray(value)) { + return@flatMap (value as Array) + .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 } +} \ No newline at end of file diff --git a/dataforge-meta/src/jsMain/kotlin/hep/dataforge/meta/jsMeta.kt b/dataforge-meta/src/jsMain/kotlin/hep/dataforge/meta/jsMeta.kt deleted file mode 100644 index 849900a7..00000000 --- a/dataforge-meta/src/jsMain/kotlin/hep/dataforge/meta/jsMeta.kt +++ /dev/null @@ -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 -} \ No newline at end of file diff --git a/dataforge-meta/src/jsTest/kotlin/hep/dataforge/meta/DynamicMetaTest.kt b/dataforge-meta/src/jsTest/kotlin/hep/dataforge/meta/DynamicMetaTest.kt new file mode 100644 index 00000000..b7e003ad --- /dev/null +++ b/dataforge-meta/src/jsTest/kotlin/hep/dataforge/meta/DynamicMetaTest.kt @@ -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) + } + +} \ No newline at end of file