spec/async/node_spec.rb in async-1.24.2 vs spec/async/node_spec.rb in async-1.25.0

- old
+ new

@@ -18,11 +18,11 @@ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -require 'benchmark' +require 'async/node' RSpec.describe Async::Node do describe '#parent=' do let(:child) {Async::Node.new(subject)} @@ -91,8 +91,85 @@ it 'can assign annotation' do subject.annotate(annotation) expect(subject.annotation).to be == annotation + end + end + + describe '#transient' do + it 'can move transient child to parent' do + # This example represents a persistent web connection (middle) with a background reader (child). We look at how when that connection goes out of scope, what happens to the child. + + # subject -> middle -> child (transient) + + middle = Async::Node.new(subject) + child = Async::Node.new(middle, transient: true) + + expect(child).to be_transient + expect(middle).to be_finished + + allow(child).to receive(:finished?).and_return(false) + + middle.consume + + # subject -> child (transient) + expect(child.parent).to be subject + expect(subject.children).to include(child) + expect(subject.children).to_not include(middle) + + expect(child).to_not be_finished + expect(subject).to be_finished + + expect(child).to receive(:stop) + subject.stop + end + + it 'can move transient sibling to parent' do + # This example represents a server task (middle) which has a single task listening on incoming connections (child2), and a transient task which is monitoring those connections/some shared resource (child1). We look at what happens when the server listener finishes. + + # subject -> middle -> child1 (transient) + # -> child2 + middle = Async::Node.new(subject) + child1 = Async::Node.new(middle, transient: true) + child2 = Async::Node.new(middle) + + allow(child1).to receive(:finished?).and_return(false) + + middle.consume + + # subject -> middle -> child1 (transient) + # -> child2 + expect(child1.parent).to be middle + expect(child2.parent).to be middle + expect(middle.parent).to be subject + expect(subject.children).to include(middle) + expect(middle.children).to include(child1) + expect(middle.children).to include(child2) + + child2.consume + + # subject -> child1 (transient) + expect(child1.parent).to be subject + expect(child2.parent).to be_nil + expect(middle.parent).to be_nil + expect(subject.children).to include(child1) + expect(middle.children).to be_nil + end + + it 'ignores non-transient children of transient parent' do + # subject -> middle (transient) -> child + middle = Async::Node.new(subject, transient: true) + child = Async::Node.new(middle) + + allow(middle).to receive(:finished?).and_return(false) + + child.consume + + # subject -> middle (transient) + expect(child.parent).to be_nil + expect(middle.parent).to be subject + expect(subject.children).to include(middle) + expect(middle.children).to be_empty end end end