From d76627fbab6991a02ff7fe4fefc653f105b62190 Mon Sep 17 00:00:00 2001 From: Patrik Wenger Date: Mon, 27 Jan 2025 19:37:06 +0100 Subject: [PATCH] Variable: add #reject, #rejected? and raise in #wait --- lib/async/variable.rb | 20 ++++++++++++++++++-- test/async/variable.rb | 24 ++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/lib/async/variable.rb b/lib/async/variable.rb index 9dffc550..f9efa967 100644 --- a/lib/async/variable.rb +++ b/lib/async/variable.rb @@ -30,24 +30,40 @@ def resolve(value = true) condition.signal(value) end + + def reject(error) + @error = error + condition = @condition + @condition = nil + + self.freeze + + condition.signal # signal without value + end # Alias for {#resolve}. def value=(value) self.resolve(value) end - + # Whether the value has been resolved. # # @returns [Boolean] Whether the value has been resolved. def resolved? - @condition.nil? + @condition.nil? && @error.nil? + end + + def rejected? + @condition.nil? && !!@error end # Wait for the value to be resolved. # # @returns [Object] The resolved value. + # @raises [Exception] The error with which this Variable was rejected def wait @condition&.wait + raise @error if @error return @value end diff --git a/test/async/variable.rb b/test/async/variable.rb index b8cdfd9a..479f951b 100644 --- a/test/async/variable.rb +++ b/test/async/variable.rb @@ -21,6 +21,14 @@ variable.resolve(value) end + + it "can wait for the value to be resolved using setter" do + Async do + expect(variable.wait).to be == value + end + + variable.value = value + end it "can't resolve it a 2nd time" do variable.resolve(value) @@ -28,6 +36,22 @@ variable.resolve(value) end.to raise_exception(FrozenError) end + + it "can reject with an exception" do + variable.reject RuntimeError.new("boom") + expect(variable).not.to be(:resolved?) + expect(variable).to be(:rejected?) + end + + it "can wait for a rejection with an error" do + Async do + expect do + variable.wait + end.to raise_exception(RuntimeError) + end + + variable.reject(RuntimeError.new) + end end include Sus::Fixtures::Async::ReactorContext