-
Notifications
You must be signed in to change notification settings - Fork 14
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Refactoring + adding new tests to increase code coverage. #351
Conversation
JaCoCo Code Coverage 83.63% ✅
Generated by 🚫 Danger |
673c99d
to
a8669da
Compare
@@ -3,16 +3,6 @@ package com.instacart.formula | |||
/** | |||
* Used within [Action] to receive a cancel event and perform clean up. | |||
*/ | |||
interface Cancelable { | |||
companion object { | |||
inline operator fun invoke(crossinline cancel: () -> Unit): Cancelable { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not needed with fun interface
@@ -5,13 +5,13 @@ package com.instacart.formula | |||
*/ | |||
class DeferredAction<Event>( | |||
val key: Any, | |||
val action: Action<Event>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Make it private to reduce coverage requirements
override fun equals(other: Any?): Boolean { | ||
if (this === other) return true | ||
if (javaClass != other?.javaClass) return false |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Simplify this as add tests
} | ||
|
||
override fun hashCode(): Int { | ||
return initial.hashCode() | ||
} | ||
|
||
fun keyAsString(): String { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not used
@@ -123,12 +123,12 @@ abstract class FormulaContext<out Input, State> internal constructor( | |||
internal abstract fun <Event> eventListener( | |||
key: Any, | |||
useIndex: Boolean = true, | |||
executionType: Transition.ExecutionType? = null, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Default parameter not needed
transition: Transition<Input, State, Event> | ||
): Listener<Event> | ||
|
||
// Internal key scope management | ||
@PublishedApi internal abstract fun enterScope(key: Any) | ||
@PublishedApi internal abstract fun endScope() | ||
@PublishedApi internal abstract fun createScopedKey(type: KClass<*>, key: Any? = null): Any |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Default parameter not needed
@@ -17,14 +17,14 @@ class FormulaRuntime<Input : Any, Output : Any>( | |||
private val formula: IFormula<Input, Output>, | |||
private val onOutput: (Output) -> Unit, | |||
private val onError: (Throwable) -> Unit, | |||
config: RuntimeConfig?, | |||
config: RuntimeConfig, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of having default values here as well, lets just use non-null config
} else { | ||
pendingEvaluation = pendingEvaluation || evaluate | ||
} | ||
pendingEvaluation = pendingEvaluation || evaluate |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added runIfNeeded
that checks effects and pending evaluation (shared with executeBatch)
a8669da
to
a76f428
Compare
@@ -255,9 +253,10 @@ class FormulaRuntime<Input : Any, Output : Any>( | |||
} catch (e: Throwable) { | |||
isRunning = false | |||
|
|||
manager?.markAsTerminated() | |||
val manager = requireManager() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not possible to enter this block with null manager
8ecdc4a
to
63c552c
Compare
@@ -91,15 +86,6 @@ internal class SnapshotImpl<out Input, State> internal constructor( | |||
} | |||
|
|||
fun <Event> dispatch(transition: Transition<Input, State, Event>, event: Event) { | |||
if (!running) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't need this check as transitions are controlled with a queue mechanism (lives in FormulaManager).
throw IllegalStateException("Transitions are not allowed during evaluation") | ||
} | ||
|
||
if (!delegate.isTerminated() && delegate.isEvaluationNeeded(associatedEvaluationId)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't need this check as transitions are controlled with a queue mechanism (lives in FormulaManager).
@Volatile internal var manager: FormulaManagerImpl<Input, State, *>? = null | ||
@Volatile internal var snapshotImpl: SnapshotImpl<Input, State>? = null | ||
@Volatile internal var executionType: Transition.ExecutionType? = null | ||
@Volatile private var manager: FormulaManagerImpl<Input, State, *>? = null |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Making private since getters are not needed
@@ -11,11 +9,10 @@ import com.instacart.formula.Transition | |||
*/ | |||
class DeferredTransition<Input, State, EventT> internal constructor( | |||
private val listener: ListenerImpl<Input, State, EventT>, | |||
private val transition: Transition<Input, State, EventT>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is more of a potential bug fix: we should use mutable transition
that lives in ListenerImpl
instead relying on fixed value. With dispatching, this value could be out of date by the time we call execute
@@ -41,7 +41,7 @@ internal class ActionBuilderImpl<out Input, State> internal constructor( | |||
|
|||
private fun <Event> toBoundStream( | |||
stream: Action<Event>, | |||
executionType: Transition.ExecutionType? = null, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need for default value
|
||
if (evaluate) { | ||
var shouldRun = true | ||
while (shouldRun) { | ||
val localInputId = inputId | ||
if (!manager.isTerminated()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not possible to hit this case because evaluate
will be false if the manager is terminated
// Terminated manager with input change indicates that formula | ||
// key changed and we are resetting formula state. We need to | ||
// start a new formula manager. | ||
if (localInputId != inputId) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need to check if localInputId != inputId
63c552c
to
a901953
Compare
a901953
to
9b7fb8c
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good! A few questions I have, but no issues.
observer.output { assertThat(this).isEqualTo(1) } | ||
|
||
// Check that termination was called | ||
assertThat(terminationCallback.values()).containsExactly(0).inOrder() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is interesting behavior. Took me a few read-throughs to understand why this happens. I wonder if we should alert devs somehow when this occurs?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you elaborate on the interesting part?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Triggering onTerminate was surprising to me. I thought it would just discard the current evaluation and re-evaluate.
Also I've seen a lot of people trigger side-effects in an onEvent block like this and I'm thinking if that side-effect triggers a new input this would similarly surprise people.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It terminates because I have key
defined for the formula
override fun key(input: Int): Any {
return input
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, I see now, that makes more sense.
} | ||
|
||
observer = runtime.test(root) | ||
observer.input(0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we assert the output value here? Should be 0, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There should be no output given formula exited before producing one.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, I thought there would be a single evaluation, with the transition running afterward?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was, but since formula was terminated during transition, we don't emit an output.
} | ||
|
||
observer = runtime.test(root) | ||
observer.input(0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This wouldn't have a valid output after terminating, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point, will validate
9b7fb8c
to
0040fff
Compare
0040fff
to
0e9595a
Compare
What
Miscellaneous non-behavior changes to increase coverage.