Skip to content

Commit 219e5ab

Browse files
committed
Improved test coverage.
1 parent c207151 commit 219e5ab

File tree

4 files changed

+128
-133
lines changed

4 files changed

+128
-133
lines changed

fixtures/async/bus/a_server.rb

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# frozen_string_literal: true
2+
3+
# Released under the MIT License.
4+
# Copyright, 2025, by Samuel Williams.
5+
6+
require "async/bus/server"
7+
require "async/bus/client"
8+
9+
require "sus/fixtures/async"
10+
require "io/endpoint/bound_endpoint"
11+
require "tmpdir"
12+
13+
module Async
14+
module Bus
15+
AServer = Sus::Shared("a server") do
16+
include Sus::Fixtures::Async::ReactorContext
17+
18+
let(:ipc_path) {File.join(@root, "bus.ipc")}
19+
let(:endpoint) {Async::Bus::Protocol.local_endpoint(ipc_path)}
20+
21+
def around(&block)
22+
Dir.mktmpdir do |directory|
23+
@root = directory
24+
super(&block)
25+
end
26+
end
27+
28+
def before
29+
@bound_endpoint = endpoint.bound
30+
end
31+
32+
def after(error = nil)
33+
@bound_endpoint&.close
34+
end
35+
36+
let(:server) {Async::Bus::Server.new(@bound_endpoint)}
37+
let(:client) {Async::Bus::Client.new(endpoint)}
38+
end
39+
end
40+
end

lib/async/bus/protocol/connection.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ def run
130130
end
131131
end
132132
ensure
133-
finalizer_task.stop
133+
finalizer_task&.stop
134134

135135
@transactions.each do |id, transaction|
136136
transaction.close

lib/async/bus/protocol/proxy.rb

Lines changed: 7 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,14 @@
66
module Async
77
module Bus
88
module Protocol
9+
# A proxy object that forwards method calls to a remote object.
10+
#
11+
# We must be extremely careful not to invoke any methods on the proxy object that would recursively call the proxy object.
912
class Proxy < BasicObject
13+
# Create a new proxy object.
14+
#
15+
# @parameter connection [Connection] The connection to the remote object.
16+
# @parameter name [Symbol] The name (address) of the remote object.
1017
def initialize(connection, name)
1118
@connection = connection
1219
@name = name
@@ -28,24 +35,7 @@ def != object
2835
@connection.invoke(@name, [:!=, object])
2936
end
3037

31-
def eql?(other)
32-
self.equal?(other)
33-
end
34-
35-
def methods(all = true)
36-
@connection.invoke(@name, [:methods, all])
37-
end
38-
39-
def protected_methods(all = true)
40-
@connection.invoke(@name, [:protected_methods, all])
41-
end
42-
43-
def public_methods(all = true)
44-
@connection.invoke(@name, [:public_methods, all])
45-
end
46-
4738
def method_missing(*arguments, **options, &block)
48-
$stderr.puts "invoke #{@name}.#{arguments}"
4939
@connection.invoke(@name, arguments, options, &block)
5040
end
5141

test/async/bus/server.rb

Lines changed: 80 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -3,152 +3,117 @@
33
# Released under the MIT License.
44
# Copyright, 2021-2025, by Samuel Williams.
55

6-
require "async/bus/server"
7-
require "async/bus/client"
8-
9-
require "sus/fixtures/async"
10-
require "tmpdir"
11-
require "io/endpoint/bound_endpoint"
12-
13-
class Counter
14-
def initialize(count = 0)
15-
@count = count
16-
end
17-
18-
attr :count
19-
20-
def increment
21-
@count += 1
22-
end
23-
24-
def each
25-
@count.times do
26-
yield Object.new
27-
end
28-
end
29-
30-
def make
31-
Object.new
32-
end
33-
34-
def itself(object)
35-
return object
36-
end
37-
38-
def error(message)
39-
raise message
40-
end
41-
end
6+
require "async/bus/a_server"
427

438
describe Async::Bus::Server do
44-
include Sus::Fixtures::Async::ReactorContext
45-
46-
let(:ipc_path) {File.join(@root, "bus.ipc")}
47-
let(:endpoint) {Async::Bus::Protocol.local_endpoint(ipc_path)}
48-
49-
def around(&block)
50-
Dir.mktmpdir do |directory|
51-
@root = directory
52-
super(&block)
9+
include Async::Bus::AServer
10+
11+
with "#bind" do
12+
it "can receive incoming clients and expose a bound object" do
13+
server_task = Async do
14+
server.accept do |connection|
15+
connection.bind(:object, Object.new)
16+
end
17+
end
18+
19+
client.connect do |connection|
20+
expect(connection[:object]).to be_a(Object)
21+
end
5322
end
5423
end
5524

56-
def before
57-
@bound_endpoint = endpoint.bound
58-
end
59-
60-
def after(error = nil)
61-
@bound_endpoint&.close
62-
end
63-
64-
let(:server) {Async::Bus::Server.new(@bound_endpoint)}
65-
let(:client) {Async::Bus::Client.new(endpoint)}
66-
67-
it "can receive incoming clients" do
68-
server_task = Async do
69-
server.accept do |connection|
70-
connection.bind(:counter, Counter.new)
25+
with "a bound Array instance" do
26+
let(:array) {Array.new}
27+
28+
def before
29+
super
30+
31+
@server_task = Async do
32+
server.accept do |connection|
33+
connection.bind(:array, array)
34+
end
7135
end
7236
end
7337

74-
client.connect do |connection|
75-
3.times do
76-
connection[:counter].increment
38+
def after(error = nil)
39+
@server_task.stop
40+
41+
super
42+
end
43+
44+
it "can add items to the array" do
45+
client.connect do |connection|
46+
connection[:array] << 1
7747
end
7848

79-
expect(connection[:counter].count).to be == 3
49+
expect(array).to be == [1]
8050
end
81-
end
82-
83-
it "can return proxy objects" do
84-
server_task = Async do
85-
server.accept do |connection|
86-
connection.bind(:counter, Counter)
51+
52+
it "can use equality operators" do
53+
array << 1
54+
55+
client.connect do |connection|
56+
expect(connection[:array] == [1]).to be_truthy
57+
expect(connection[:array] != [2]).to be_truthy
8758
end
8859
end
8960

90-
client.connect do |connection|
91-
counter = connection[:counter].new
61+
it "can enumerate items in the array" do
62+
array << 1 << 2 << 3
63+
enumerated = []
9264

93-
3.times do
94-
counter.increment
65+
client.connect do |connection|
66+
connection[:array].each do |item|
67+
enumerated << item
68+
end
9569
end
9670

97-
expect(counter.count).to be == 3
71+
expect(enumerated).to be == [1, 2, 3]
9872
end
99-
end
100-
101-
it "can return the original object" do
102-
server_task = Async do
103-
server.accept do |connection|
104-
connection.bind(:counter, Counter)
73+
74+
it "can raise an exception" do
75+
client.connect do |connection|
76+
expect do
77+
connection[:array]["one"]
78+
end.to raise_exception(TypeError, message: be =~ /no implicit conversion of String into Integer/)
10579
end
10680
end
10781

108-
client.connect do |connection|
109-
counter = connection[:counter].new
110-
object = Object.new
111-
112-
object2 = counter.itself(object)
113-
114-
expect(object).to be_equal(object2)
82+
it "can get all methods" do
83+
client.connect do |connection|
84+
expect(connection[:array].methods).to be == array.methods
85+
expect(connection[:array].public_methods).to be == array.public_methods
86+
expect(connection[:array].protected_methods).to be == array.protected_methods
87+
expect(connection[:array].private_methods).to be == array.private_methods
88+
end
11589
end
116-
end
117-
118-
it "can raise error" do
119-
server_task = Async do
120-
server.accept do |connection|
121-
connection.bind(:counter, Counter)
90+
91+
it "can check if it responds to methods" do
92+
client.connect do |connection|
93+
expect(connection[:array].respond_to?(:each)).to be_truthy
94+
expect(connection[:array].respond_to?(:no_such_method)).to be_falsey
12295
end
12396
end
12497

125-
client.connect do |connection|
126-
counter = connection[:counter].new
98+
it "can get a method instance and call it" do
99+
array << 1 << 2 << 3
100+
enumerated = []
127101

128-
expect do
129-
counter.error("Hello")
130-
end.to raise_exception(RuntimeError, message: be =~ /Hello/)
131-
end
132-
end
133-
134-
it "can release proxy objects" do
135-
server_task = Async do
136-
server.accept do |connection|
137-
connection.bind(:counter, Counter)
102+
client.connect do |connection|
103+
method = connection[:array].method(:each)
138104

139-
connection.bind(:objects, connection.objects)
105+
method.call do |item|
106+
enumerated << item
107+
end
140108
end
109+
110+
expect(enumerated).to be == [1, 2, 3]
141111
end
142112

143-
client.connect do |connection|
144-
counter = connection[:counter].new(10)
145-
146-
10.times do
147-
counter.make
148-
GC.start
113+
it "has a __name__" do
114+
client.connect do |connection|
115+
expect(connection[:array].__name__).to be == :array
149116
end
150-
151-
expect(connection[:objects].size).to be < 10
152117
end
153118
end
154119
end

0 commit comments

Comments
 (0)