Skip to content

Commit

Permalink
Merge pull request #10 from yahoo/sal/optionalvalues
Browse files Browse the repository at this point in the history
Value is a nullable return type
  • Loading branch information
slevin authored Sep 23, 2024
2 parents f46e22d + b8e4566 commit d97eb1a
Show file tree
Hide file tree
Showing 6 changed files with 21 additions and 36 deletions.
2 changes: 1 addition & 1 deletion behavior-graph/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ import com.vanniktech.maven.publish.SonatypeHost
mavenPublishing {
configure(new KotlinJvm(new JavadocJar.Dokka("dokkaHtml"), true))
publishToMavenCentral(SonatypeHost.CENTRAL_PORTAL)
coordinates("com.yahoo.behaviorgraph", "bgjvm", "0.8.0")
coordinates("com.yahoo.behaviorgraph", "bgjvm", "0.9.0")
pom {
name = 'Behavior Graph'
description = 'Behavior Graph lets you build your programs out of small, easily understood pieces in a way that lets the computer do more of the work for you.'
Expand Down
22 changes: 6 additions & 16 deletions behavior-graph/src/main/kotlin/behaviorgraph/TypedMoment.kt
Original file line number Diff line number Diff line change
Expand Up @@ -16,29 +16,19 @@ class TypedMoment<T> @JvmOverloads constructor(extent: Extent<*>, debugName: Str

/**
* Is there a current event and if the moment updated then what is the associated data.
* Otherwise throws an error.
* Will return null if the moment did not update this event.
* Be careful: It is possible that T is also an optional type itself
* So this typedMoment could be called with .update(null).
* In that case justUpdated will be true and value will also be null.
* A behavior must demand this resource to access its value.
*/
@get:JvmName("value")
val value: T
val value: T?
get() {
assertValidAccessor()
if (!_happened) { throw BehaviorGraphException("Cannot access moment value when it did not update.")
}
return this._happenedValue!!
return this._happenedValue
}

/**
* Optional version value() property which may be more convenient.
* Returns T if justUpdated is true, null otherwise
* Be careful: It is possible that T is also an optional type itself
* So this typedMoment could be called with .update(null).
* In that case justUpdated will be true but justUpdatedValue would be null.
*/
@get:JvmName("justUpdatedValue")
val justUpdatedValue: T?
get() = _happenedValue

/**
* If this Moment has ever been update what was the last Event it was updated.
* A behavior must demand this resource to access this property.
Expand Down
25 changes: 10 additions & 15 deletions behavior-graph/src/test/kotlin/behaviorgraph/MomentTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,8 @@ class MomentTest : AbstractBehaviorGraphTest() {
// |> Then the data is visible in subsequent behaviors
assertEquals(1, afterUpdate)
assertTrue(updatedToOne)
// but is an Exception outside event loop
assertBehaviorGraphException { mr1.value }
// but null after event
assertNull(mr1.value)
}

@Test
Expand All @@ -81,19 +81,14 @@ class MomentTest : AbstractBehaviorGraphTest() {
}

@Test
fun `updatedValue returns optional wrapped value`() {
// In some cases justUpdatedValue may be easier to work with
// than checking for justUpdated and getting the value
// however kotlin collapses the nulls, so there's no notion of
// unwrapping as you might find in
fun `value is optional`() {
val mr1: TypedMoment<String> = ext.typedMoment()
val mr2: TypedMoment<String?> = ext.typedMoment()

g.action {
g.sideEffect {
// mr1 was not just updated, so justUpdatedValue is null
assertNull(mr1.justUpdatedValue)
var run = false
// mr1 was not just updated, so value is null
assertNull(mr1.value)
}
}

Expand All @@ -102,15 +97,15 @@ class MomentTest : AbstractBehaviorGraphTest() {
mr2.update(null)

g.sideEffect {
// mr1 was updated and it's value was hello so justUpdatedValue is hello
assertEquals("hello", mr1.justUpdatedValue)
// mr1 was updated, and it's value was hello so value is hello
assertEquals("hello", mr1.value)
// mr2 was also just updated, but with a value of null
assertTrue(mr2.justUpdated)
// however justUpdatedValue is null, so ?.let pattern will not run
assertNull(mr2.value)
// because is null, so ?.let pattern will not run
var run = false
mr2.justUpdatedValue?.let {
mr2.value?.let {
run = true
assertNull(it)
}
assertFalse(run)
}
Expand Down
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ buildscript {
}
dependencies {
// Build system
classpath 'com.android.tools.build:gradle:8.2.0'
classpath 'com.android.tools.build:gradle:8.5.2'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath "org.jetbrains.dokka:dokka-gradle-plugin:1.9.20"
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,9 +86,9 @@ class LoginExtent(var loginActivityBG: LoginActivityBG, graph: Graph) : Extent<L
if (loggingIn.value) {
status = "Logging in...";
} else if (loggingIn.justUpdatedTo(false)) {
if (loginComplete.justUpdated && loginComplete.value) {
if (loginComplete.value == true) {
status = "Login Success";
} else if (loginComplete.justUpdated && !loginComplete.value) {
} else if (loginComplete.value == false) {
status = "Login Failed";
}
}
Expand Down
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#Mon Aug 23 11:41:29 PDT 2021
distributionBase=GRADLE_USER_HOME
distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
distributionPath=wrapper/dists
zipStorePath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME

0 comments on commit d97eb1a

Please sign in to comment.