-
Notifications
You must be signed in to change notification settings - Fork 90
feat: Add NestedHandlerTest to validate Nested behavior and enhance A… #1493
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
Open
ahoy-jon
wants to merge
11
commits into
main
Choose a base branch
from
1412-bug-freeze-on-unnecessary-handling-for-var
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 3 commits
Commits
Show all changes
11 commits
Select commit
Hold shift + click to select a range
1ae5fd3
feat: Add NestedHandlerTest to validate Nested behavior and enhance A…
ahoy-jon 857eefc
refactor: Replace asInstanceOf with unsafeGet in ArrowEffect for impr…
ahoy-jon f6a102e
Merge branch 'main' into 1412-bug-freeze-on-unnecessary-handling-for-var
ahoy-jon a8bdff0
Merge branch 'main' into 1412-bug-freeze-on-unnecessary-handling-for-var
ahoy-jon 991e6a7
Merge branch 'main' into 1412-bug-freeze-on-unnecessary-handling-for-var
ahoy-jon 1261545
Merge branch 'main' into 1412-bug-freeze-on-unnecessary-handling-for-var
fwbrasil d397522
Merge branch 'main' into 1412-bug-freeze-on-unnecessary-handling-for-var
fwbrasil 9ba69f3
Update kyo-kernel/shared/src/test/scala/kyo/kernel/ArrowEffectNestedT…
ahoy-jon 9fbe250
chore: move tests as nested
ahoy-jon da7ed38
Merge branch 'main' into 1412-bug-freeze-on-unnecessary-handling-for-var
ahoy-jon 040bf7f
Delete kyo-prelude/shared/src/test/scala/kyo/kernel/internal/NestedHa…
ahoy-jon File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
171 changes: 171 additions & 0 deletions
171
kyo-kernel/shared/src/test/scala/kyo/kernel/ArrowEffectNestedTest.scala
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,171 @@ | ||
| package kyo.kernel | ||
|
|
||
| import kyo.* | ||
| import kyo.kernel.* | ||
| import kyo.kernel.internal.* | ||
|
|
||
| class ArrowEffectNestedTest extends Test: | ||
ahoy-jon marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| given [A, B]: CanEqual[A, B] = CanEqual.derived | ||
|
|
||
| sealed trait TestEffect extends ArrowEffect[Const[Int], Const[Int]] | ||
|
|
||
| def suspend(i: Int): Int < TestEffect = | ||
| ArrowEffect.suspend[Any](Tag[TestEffect], i) | ||
|
|
||
| val tag: Tag[TestEffect] = Tag[TestEffect] | ||
|
|
||
| def flatten[A, B, C](v: A < B < C): A < (B & C) = v.map(a => a) | ||
|
|
||
| "handle on Nested (unsafeGet path)" - { | ||
ahoy-jon marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| def handle[A, S](v: A < (S & TestEffect)): A < S = | ||
| ArrowEffect.handle(tag, v): | ||
| [C] => (input, cont) => cont(input * 10) | ||
|
|
||
| "unwraps Nested and returns inner suspension" in { | ||
| val comp: Int < TestEffect = suspend(5) | ||
| val nested: Int < TestEffect < Any = Nested(comp) | ||
| val result: Int < TestEffect < Any = handle(nested) | ||
|
|
||
| assert(result == nested, "handleSimple should return the nested computation") | ||
|
|
||
| val flattened = flatten(result) | ||
| val finalResult = handle(flattened) | ||
|
|
||
| assert(finalResult.eval == 50) | ||
| } | ||
| } | ||
|
|
||
| "handleFirst on Nested" - { | ||
|
|
||
| def handle[A, S](v: A < (S & TestEffect)): A < (S & TestEffect) = | ||
| ArrowEffect.handleFirst(tag, v)( | ||
| [C] => (input, cont) => cont(input * 10), | ||
| identity | ||
| ) | ||
|
|
||
| "done callback receives unwrapped value" in { | ||
| val comp = suspend(5) | ||
| val nested: Int < TestEffect < Any = Nested(comp) | ||
|
|
||
| val result = handle(nested) | ||
|
|
||
| assert(result == nested, "handleFirst should return the nested computation") | ||
|
|
||
| val flattened = flatten(result) | ||
| val finalResult: Int < TestEffect = handle(flattened) | ||
| assert(finalResult.evalNow == Maybe(50)) | ||
| } | ||
| } | ||
|
|
||
| "handleLoop (stateless) on Nested" - { | ||
|
|
||
| def handle[A, S](v: A < (S & TestEffect)): A < S = | ||
| ArrowEffect.handleLoop(Tag[TestEffect], v): | ||
| [C] => (input, cont) => Loop.continue(cont(input * 10)) | ||
|
|
||
| "unwraps Nested and handles inner suspension" in { | ||
| val comp: Int < TestEffect = suspend(5) | ||
| val nested: Int < TestEffect < Any = Nested(comp) | ||
|
|
||
| val result = handle(nested) | ||
| assert(result == nested, "handleLoop should return the nested computation") | ||
|
|
||
| val flattened = flatten(result) | ||
| val finalResult: Int < Any = handle(flattened) | ||
|
|
||
| assert(finalResult.eval == 50) | ||
| } | ||
| } | ||
|
|
||
| "handleLoop (stateful) on Nested" - { | ||
|
|
||
| def handle[A, S](v: A < (S & TestEffect)): A < S = | ||
| ArrowEffect.handleLoop(tag, 0, v)( | ||
| [C] => (input, state, cont) => Loop.continue(state + 1, cont((input + state) * 10)) | ||
| ) | ||
|
|
||
| "unwraps Nested and handles inner suspension" in { | ||
| val comp: Int < TestEffect = suspend(5) | ||
| val nested: Int < TestEffect < Any = Nested(comp) | ||
|
|
||
| val result = handle(nested) | ||
| assert(result == nested, "handleLoop should return the nested computation") | ||
|
|
||
| val flattened = flatten(result) | ||
| val finalResult: Int < Any = handle(flattened) | ||
|
|
||
| assert(finalResult.eval == 50) | ||
| } | ||
|
|
||
| } | ||
|
|
||
| "handleLoop (stateful + done) on Nested" - { | ||
|
|
||
| def handle[A, S](v: A < (S & TestEffect)): A < S = | ||
| ArrowEffect.handleLoop(tag, 0, v)( | ||
| [C] => (input, state, cont) => Loop.continue(state + 1, cont(input * 10)), | ||
| (state, v) => v | ||
| ) | ||
|
|
||
| "unwraps Nested and handles inner suspension" in { | ||
| val comp: Int < TestEffect = suspend(5) | ||
| val nested: Int < TestEffect < Any = Nested(comp) | ||
|
|
||
| val result = handle(nested) | ||
| assert(result == nested, "handleLoop should return the nested computation") | ||
|
|
||
| val flattened = flatten(result) | ||
| val finalResult: Int < Any = handle(flattened) | ||
|
|
||
| assert(finalResult.eval == 50) | ||
| } | ||
| } | ||
|
|
||
| "handleCatching on Nested" - { | ||
|
|
||
| def handle[A, S](v: A < (S & TestEffect)): A < S = | ||
| ArrowEffect.handleCatching(tag, v)( | ||
| [C] => (input, cont) => cont(input * 10), | ||
| recover = e => throw e | ||
| ) | ||
|
|
||
| "unwraps Nested and handles inner suspension" in { | ||
| val comp: Int < TestEffect = suspend(5) | ||
| val nested: Int < TestEffect < Any = Nested(comp) | ||
|
|
||
| val result = handle(nested) | ||
| assert(result == nested, "handleLoop should return the nested computation") | ||
|
|
||
| val flattened = flatten(result) | ||
| val finalResult: Int < Any = handle(flattened) | ||
|
|
||
| assert(finalResult.eval == 50) | ||
| } | ||
| } | ||
|
|
||
| "handlePartial on Nested" - { | ||
|
|
||
| def handle[A, S](v: A < (S & TestEffect)): A < (S & TestEffect) = | ||
| ArrowEffect.handlePartial(tag, tag, v, Context.empty)( | ||
| stop = | ||
| false, | ||
| [C] => (input, cont) => cont(input * 10), | ||
| [C] => (input, cont) => cont(input * 10) | ||
| ) | ||
|
|
||
| "unwraps Nested and handles inner suspension" in { | ||
| val comp: Int < TestEffect = suspend(5) | ||
| val nested: Int < TestEffect < Any = Nested(comp) | ||
|
|
||
| val result = handle(nested) | ||
| assert(result == nested, "handlePartial should return the nested computation") | ||
|
|
||
| val flattened = flatten(result) | ||
| val finalResult = handle(flattened) | ||
| assert(finalResult.evalNow == Maybe(50)) | ||
| } | ||
| } | ||
|
|
||
| end ArrowEffectNestedTest | ||
38 changes: 38 additions & 0 deletions
38
kyo-prelude/shared/src/test/scala/kyo/kernel/internal/NestedHandlerTest.scala
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,38 @@ | ||
| package kyo.kernel.internal | ||
|
|
||
| import kyo.* | ||
|
|
||
| class NestedHandlerTest extends Test: | ||
| "bug #1412 - handler on Nested" - { | ||
| "Var.update through lift/flatten/run" in { | ||
| var executed = false | ||
|
|
||
| val comp: Unit < Var[Int] = Var.update[Int] { x => | ||
| executed = true | ||
| x + 1 | ||
| }.unit | ||
|
|
||
| val lifted: Unit < Var[Int] < Any = Nested(comp) // Kyo.lift(comp) | ||
|
|
||
| def flatten[A, B, C](v: A < B < C): A < (B & C) = v.map(a => a) | ||
|
|
||
| val step1 = Var.run(0)(lifted) | ||
| val step2 = flatten(step1) | ||
| val step3 = Var.run(0)(step2) | ||
|
|
||
| step3.eval | ||
| assert(executed, "Var.update body should have been executed") | ||
| } | ||
|
|
||
| "details" in { | ||
| given [A, B]: CanEqual[A, B] = CanEqual.derived | ||
|
|
||
| val update: Int < Var[Int] = Var.update[Int](_ + 1) | ||
| val nested: Int < Var[Int] < Any = Nested(update) | ||
| val handled: Int < Var[Int] < Any = Var.run(0)(nested) | ||
|
|
||
| assert(handled == nested, "Var.run should return the nested computation") | ||
| } | ||
| } | ||
|
|
||
| end NestedHandlerTest |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.