Fix number comparison bug in value

This commit is contained in:
Alexander Nozik 2021-11-02 10:50:38 +03:00
parent 387ab8747e
commit d178c4ff0d
12 changed files with 80 additions and 24 deletions

View File

@ -12,6 +12,7 @@
### Fixed ### Fixed
- MutableMetaImpl attachment and checks - MutableMetaImpl attachment and checks
- Listeners in observable meta are replaced by lists - Listeners in observable meta are replaced by lists
- JS number comparison bug.
### Security ### Security
## [0.5.0] ## [0.5.0]

View File

@ -4,7 +4,7 @@ plugins {
allprojects { allprojects {
group = "space.kscience" group = "space.kscience"
version = "0.5.2-dev-1" version = "0.5.2-dev-3"
repositories{ repositories{
mavenCentral() mavenCentral()
} }

View File

@ -11,7 +11,7 @@ kscience {
kotlin { kotlin {
sourceSets { sourceSets {
val commonMain by getting{ val commonMain by getting {
dependencies { dependencies {
api(project(":dataforge-meta")) api(project(":dataforge-meta"))
} }
@ -30,6 +30,6 @@ kotlin {
} }
} }
readme{ readme {
maturity = ru.mipt.npm.gradle.Maturity.DEVELOPMENT maturity = ru.mipt.npm.gradle.Maturity.DEVELOPMENT
} }

View File

@ -1,6 +1,7 @@
package space.kscience.dataforge.data package space.kscience.dataforge.data
import kotlinx.coroutines.* import kotlinx.coroutines.*
import space.kscience.dataforge.misc.DFExperimental
import kotlin.coroutines.CoroutineContext import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.EmptyCoroutineContext import kotlin.coroutines.EmptyCoroutineContext
@ -66,6 +67,7 @@ public open class LazyGoal<T>(
* If [GoalExecutionRestriction] is present in the [coroutineScope] context, the call could produce a error a warning * If [GoalExecutionRestriction] is present in the [coroutineScope] context, the call could produce a error a warning
* depending on the settings. * depending on the settings.
*/ */
@OptIn(DFExperimental::class)
override fun async(coroutineScope: CoroutineScope): Deferred<T> { override fun async(coroutineScope: CoroutineScope): Deferred<T> {
val log = coroutineScope.coroutineContext[GoalLogger] val log = coroutineScope.coroutineContext[GoalLogger]
// Check if context restricts goal computation // Check if context restricts goal computation

View File

@ -10,7 +10,6 @@ import space.kscience.dataforge.meta.Meta
import space.kscience.dataforge.meta.get import space.kscience.dataforge.meta.get
import space.kscience.dataforge.meta.string import space.kscience.dataforge.meta.string
import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.Name
import space.kscience.dataforge.names.asName
import kotlin.reflect.KClass import kotlin.reflect.KClass
public class IOPlugin(meta: Meta) : AbstractPlugin(meta) { public class IOPlugin(meta: Meta) : AbstractPlugin(meta) {
@ -74,11 +73,13 @@ public class IOPlugin(meta: Meta) : AbstractPlugin(meta) {
} }
} }
internal val ioContext = Context("IO") {
plugin(IOPlugin)
}
public val Context.io: IOPlugin public val Context.io: IOPlugin
get() = if (this == Global) { get() = if (this == Global) {
Global.buildContext("IO".asName()) { ioContext.fetch(IOPlugin)
plugin(IOPlugin)
}.fetch(IOPlugin)
} else { } else {
fetch(IOPlugin) fetch(IOPlugin)
} }

View File

@ -140,14 +140,17 @@ public class NumberValue(public val number: Number) : Value {
val otherNumber = other.numberOrNull ?: return false val otherNumber = other.numberOrNull ?: return false
if(number == otherNumber) return true
//Do not change the order of comparison. On JS number is the instance of all types
return when (numberOrNull) { return when (numberOrNull) {
is Short -> number.toShort() == otherNumber.toShort()
is Long -> number.toLong() == otherNumber.toLong()
is Byte -> number.toByte() == otherNumber.toByte()
is Int -> number.toInt() == otherNumber.toInt()
is Float -> number.toFloat() == otherNumber.toFloat()
is Double -> number.toDouble() == otherNumber.toDouble() is Double -> number.toDouble() == otherNumber.toDouble()
else -> number.toString() == otherNumber.toString() is Float -> number.toFloat() == otherNumber.toFloat()
is Long -> number.toLong() == otherNumber.toLong()
is Short -> number.toShort() == otherNumber.toShort()
is Int -> number.toInt() == otherNumber.toInt()
is Byte -> number.toByte() == otherNumber.toByte()
else -> false
} }
} }
@ -188,9 +191,7 @@ public class ListValue(override val list: List<Value>) : Value, Iterable<Value>
return list == other.list return list == other.list
} }
override fun hashCode(): Int { override fun hashCode(): Int = list.hashCode()
return list.hashCode()
}
public companion object { public companion object {
public val EMPTY: ListValue = ListValue(emptyList()) public val EMPTY: ListValue = ListValue(emptyList())

View File

@ -36,9 +36,7 @@ public class DoubleArrayValue(override val value: DoubleArray) : Value, Iterable
} }
} }
override fun hashCode(): Int { override fun hashCode(): Int = value.contentHashCode()
return value.contentHashCode()
}
override fun toString(): String = list.joinToString(prefix = "[", postfix = "]") override fun toString(): String = list.joinToString(prefix = "[", postfix = "]")

View File

@ -1,8 +1,11 @@
package space.kscience.dataforge.meta package space.kscience.dataforge.meta
import space.kscience.dataforge.misc.DFExperimental import space.kscience.dataforge.misc.DFExperimental
import space.kscience.dataforge.values.ListValue
import space.kscience.dataforge.values.Value
import kotlin.test.Test import kotlin.test.Test
import kotlin.test.assertEquals import kotlin.test.assertEquals
import kotlin.test.assertNotNull
@DFExperimental @DFExperimental
class SchemeTest { class SchemeTest {
@ -33,4 +36,16 @@ class SchemeTest {
scheme.a = 2 scheme.a = 2
assertEquals(2, flag) assertEquals(2, flag)
} }
@Test
fun testListSubscription(){
val scheme = TestScheme.empty()
var value: Value? = null
scheme.v = ListValue(0.0,0.0,0.0)
scheme.useProperty(TestScheme::v){
value = it
}
scheme.v = ListValue(1.0, 2.0, 3.0)
assertNotNull(value)
}
} }

View File

@ -9,6 +9,8 @@ internal class TestScheme : Scheme() {
var a by int() var a by int()
var b by string() var b by string()
var v by value()
companion object : SchemeSpec<TestScheme>(::TestScheme) companion object : SchemeSpec<TestScheme>(::TestScheme)
} }

View File

@ -0,0 +1,32 @@
package space.kscience.dataforge.values
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertNotEquals
class ValueEqualityTest {
@Test
fun numberValueNotEquals(){
val a = 0.33.asValue()
val b = 0.34.asValue()
println(a.number == b.number)
assertNotEquals(a,b)
}
@Test
fun arrayEqualsList() {
val v1 = doubleArrayOf(1.0, 2.0, 3.0).asValue()
val v2 = listOf(1, 2, 3).map { it.asValue() }.asValue()
assertEquals(v1, v2)
}
@Test
fun notEquals() {
val v1 = doubleArrayOf(1.0, 2.0, 3.0).asValue()
val v2 = listOf(1, 2, 6).map { it.asValue() }.asValue()
assertNotEquals(v1, v2)
}
}

View File

@ -18,7 +18,7 @@ import space.kscience.dataforge.names.asName
import kotlin.properties.PropertyDelegateProvider import kotlin.properties.PropertyDelegateProvider
import kotlin.properties.ReadOnlyProperty import kotlin.properties.ReadOnlyProperty
public data class TaskReference<T: Any>(public val taskName: Name, public val task: Task<T>): DataSelector<T>{ public data class TaskReference<T : Any>(public val taskName: Name, public val task: Task<T>) : DataSelector<T> {
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
override suspend fun select(workspace: Workspace, meta: Meta): DataSet<T> { override suspend fun select(workspace: Workspace, meta: Meta): DataSet<T> {
@ -35,7 +35,6 @@ public interface TaskContainer {
public fun registerTask(taskName: Name, task: Task<*>) public fun registerTask(taskName: Name, task: Task<*>)
} }
public inline fun <reified T : Any> TaskContainer.registerTask( public inline fun <reified T : Any> TaskContainer.registerTask(
name: String, name: String,
noinline descriptorBuilder: MetaDescriptorBuilder.() -> Unit = {}, noinline descriptorBuilder: MetaDescriptorBuilder.() -> Unit = {},
@ -43,15 +42,20 @@ public inline fun <reified T : Any> TaskContainer.registerTask(
): Unit = registerTask(Name.parse(name), Task(MetaDescriptor(descriptorBuilder), builder)) ): Unit = registerTask(Name.parse(name), Task(MetaDescriptor(descriptorBuilder), builder))
public inline fun <reified T : Any> TaskContainer.task( public inline fun <reified T : Any> TaskContainer.task(
noinline descriptorBuilder: MetaDescriptorBuilder.() -> Unit = {}, descriptor: MetaDescriptor,
noinline builder: suspend TaskResultBuilder<T>.() -> Unit, noinline builder: suspend TaskResultBuilder<T>.() -> Unit,
): PropertyDelegateProvider<Any?, ReadOnlyProperty<Any?, TaskReference<T>>> = PropertyDelegateProvider { _, property -> ): PropertyDelegateProvider<Any?, ReadOnlyProperty<Any?, TaskReference<T>>> = PropertyDelegateProvider { _, property ->
val taskName = Name.parse(property.name) val taskName = Name.parse(property.name)
val task = Task(MetaDescriptor(descriptorBuilder), builder) val task = Task(descriptor, builder)
registerTask(taskName, task) registerTask(taskName, task)
ReadOnlyProperty { _, _ -> TaskReference(taskName, task) } ReadOnlyProperty { _, _ -> TaskReference(taskName, task) }
} }
public inline fun <reified T : Any> TaskContainer.task(
noinline descriptorBuilder: MetaDescriptorBuilder.() -> Unit = {},
noinline builder: suspend TaskResultBuilder<T>.() -> Unit,
): PropertyDelegateProvider<Any?, ReadOnlyProperty<Any?, TaskReference<T>>> =
task(MetaDescriptor(descriptorBuilder), builder)
public class WorkspaceBuilder(private val parentContext: Context = Global) : TaskContainer { public class WorkspaceBuilder(private val parentContext: Context = Global) : TaskContainer {
private var context: Context? = null private var context: Context? = null

View File

@ -5,7 +5,7 @@ pluginManagement {
gradlePluginPortal() gradlePluginPortal()
} }
val toolsVersion = "0.10.4" val toolsVersion = "0.10.5"
plugins { plugins {
id("ru.mipt.npm.gradle.project") version toolsVersion id("ru.mipt.npm.gradle.project") version toolsVersion