Skip to content

Commit d114582

Browse files
committed
Add local RBS interface tests
1 parent fc49cca commit d114582

File tree

3 files changed

+313
-0
lines changed

3 files changed

+313
-0
lines changed

Gemfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ source "https://rubygems.org"
33
gemspec
44

55
gem "rake"
6+
gem "rbs"
67
gem "steep"
78
gem "test-unit"
89
gem "test-unit-ruby-core"

test/lib/rbs_test_helper.rb

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
require "pathname"
2+
require "rbs"
3+
require "rbs/test"
4+
require "rbs/unit_test/spy"
5+
require "rbs/unit_test/type_assertions"
6+
7+
module NetHTTPRBSTestHelper
8+
extend self
9+
10+
LOCAL_SIG_DIR = Pathname(__dir__).join("..", "..", "sig").expand_path
11+
SUPPORT_LIBRARIES = %w[
12+
cgi
13+
net-protocol
14+
open-uri
15+
openssl
16+
resolv
17+
securerandom
18+
socket
19+
strscan
20+
tempfile
21+
timeout
22+
uri
23+
zlib
24+
].freeze
25+
26+
def env
27+
@env ||= begin
28+
loader = RBS::EnvironmentLoader.new
29+
loader.add(path: LOCAL_SIG_DIR)
30+
SUPPORT_LIBRARIES.each do |library|
31+
loader.add(library: library, version: nil)
32+
end
33+
RBS::Environment.from_loader(loader).resolve_type_names
34+
end
35+
end
36+
end
37+
38+
class NetHTTPRBSTestCase < Test::Unit::TestCase
39+
include RBS::UnitTest::TypeAssertions
40+
41+
def self.env
42+
NetHTTPRBSTestHelper.env
43+
end
44+
45+
def self.builder
46+
@builder ||= RBS::DefinitionBuilder.new(env: env)
47+
end
48+
end

test/rbs/test_net_http_rbs.rb

Lines changed: 264 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,264 @@
1+
require "net/http"
2+
require "socket"
3+
require "stringio"
4+
require "uri"
5+
require "rbs_test_helper"
6+
7+
module NetHTTPTypeTestSupport
8+
class Server
9+
attr_reader :uri
10+
11+
def initialize(host = "127.0.0.1")
12+
@server = TCPServer.open(host, 0)
13+
@uri = URI("http://#{host}:#{@server.local_address.ip_port}/")
14+
@thread = Thread.new do
15+
loop do
16+
handle_session(@server.accept)
17+
end
18+
rescue IOError, Errno::EBADF
19+
end
20+
end
21+
22+
def finish
23+
@thread.kill
24+
@thread.join
25+
@server.close
26+
rescue IOError, Errno::EBADF
27+
end
28+
29+
private
30+
31+
def handle_session(socket)
32+
content_length = nil
33+
34+
while (line = socket.gets)
35+
content_length = line.split(":", 2)[1].strip.to_i if line.start_with?("Content-Length:")
36+
break if line == "\r\n"
37+
end
38+
39+
socket.read(content_length) if content_length
40+
41+
body = "ok"
42+
socket.write(
43+
"HTTP/1.1 200 OK\r\n" \
44+
"Content-Type: text/plain\r\n" \
45+
"Set-Cookie: session=1\r\n" \
46+
"Content-Length: #{body.bytesize}\r\n" \
47+
"\r\n" \
48+
"#{body}"
49+
)
50+
ensure
51+
socket.close
52+
end
53+
end
54+
55+
def with_server(host = "127.0.0.1")
56+
server = Server.new(host)
57+
yield server.uri
58+
ensure
59+
server&.finish
60+
end
61+
end
62+
63+
class NetHTTPSingletonRBSTest < NetHTTPRBSTestCase
64+
include NetHTTPTypeTestSupport
65+
66+
testing "singleton(::Net::HTTP)"
67+
68+
def test_singleton_api
69+
previous_stdout = $stdout
70+
$stdout = StringIO.new
71+
72+
with_server do |uri|
73+
assert_send_type "(URI::Generic) -> nil",
74+
Net::HTTP, :get_print, uri
75+
assert_send_type "(String, String, Integer) -> nil",
76+
Net::HTTP, :get_print, uri.host, "/", uri.port
77+
assert_send_type "(URI::Generic, Hash[String, String]) -> String",
78+
Net::HTTP, :get, uri, { "Accept" => "text/plain" }
79+
assert_send_type "(URI::Generic, Hash[Symbol, String]) -> Net::HTTPResponse",
80+
Net::HTTP, :get_response, uri, { Accept: "text/plain" }
81+
assert_send_type "(URI, String, Hash[String, String]) -> Net::HTTPResponse",
82+
Net::HTTP, :post, uri, "payload", "Content-Type" => "text/plain"
83+
assert_send_type "(URI, Hash[String, Symbol]) -> Net::HTTPResponse",
84+
Net::HTTP, :post_form, uri, { "q" => :ruby }
85+
86+
http = assert_send_type "(String, Integer) -> Net::HTTP",
87+
Net::HTTP, :start, uri.host, uri.port
88+
http.finish if http.started?
89+
90+
assert_send_type "(String, Integer) { (Net::HTTP) -> Class } -> Class",
91+
Net::HTTP, :start, uri.host, uri.port do |net_http|
92+
net_http.class
93+
end
94+
end
95+
96+
assert_send_type "(String, Integer, nil, nil, nil, nil, nil) -> Net::HTTP",
97+
Net::HTTP, :new, "127.0.0.1", 80, nil, nil, nil, nil, nil
98+
ensure
99+
$stdout = previous_stdout
100+
end
101+
end
102+
103+
class NetHTTPInstanceRBSTest < NetHTTPRBSTestCase
104+
include NetHTTPTypeTestSupport
105+
106+
testing "::Net::HTTP"
107+
108+
def test_attribute_api
109+
http = Net::HTTP.new("127.0.0.1", 80)
110+
111+
assert_send_type "() -> String", http, :inspect
112+
assert_send_type "() -> String", http, :address
113+
assert_send_type "() -> Integer", http, :port
114+
assert_send_type "() -> nil", http, :ipaddr
115+
assert_send_type "(String) -> void", http, :ipaddr=, "127.0.0.1"
116+
assert_send_type "() -> Integer", http, :open_timeout
117+
assert_send_type "() -> Integer", http, :read_timeout
118+
assert_send_type "(Integer) -> void", http, :read_timeout=, 10
119+
assert_send_type "() -> Integer", http, :write_timeout
120+
assert_send_type "(Integer) -> void", http, :write_timeout=, 10
121+
assert_send_type "() -> nil", http, :continue_timeout
122+
assert_send_type "(Integer) -> void", http, :continue_timeout=, 10
123+
assert_send_type "() -> Integer", http, :max_retries
124+
assert_send_type "(Integer) -> void", http, :max_retries=, 10
125+
assert_send_type "() -> Integer", http, :keep_alive_timeout
126+
assert_send_type "() -> bool", http, :started?
127+
assert_send_type "() -> bool", http, :active?
128+
assert_send_type "() -> bool", http, :use_ssl?
129+
assert_send_type "(bool) -> void", http, :use_ssl=, true
130+
assert_send_type "() -> bool", http, :proxy?
131+
assert_send_type "() -> bool", http, :proxy_from_env?
132+
assert_send_type "() -> nil", http, :proxy_uri
133+
assert_send_type "() -> nil", http, :proxy_address
134+
assert_send_type "() -> nil", http, :proxy_port
135+
assert_send_type "() -> nil", http, :proxy_user
136+
assert_send_type "() -> nil", http, :proxy_pass
137+
assert_send_type "(IO) -> void", http, :set_debug_output, $stderr
138+
end
139+
140+
def test_request_api
141+
with_server do |uri|
142+
http = Net::HTTP.start(uri.host, uri.port)
143+
144+
assert_send_type "(String) -> Net::HTTPResponse", http, :get, "/"
145+
assert_send_type "(String, Hash[String, String]) -> Net::HTTPResponse",
146+
http, :get, "/", { "Accept" => "text/plain" }
147+
assert_send_type "(String) { (String) -> String } -> Net::HTTPResponse",
148+
http, :get, "/" do |body|
149+
body
150+
end
151+
assert_send_type "(String) -> Net::HTTPResponse", http, :head, "/"
152+
assert_send_type "(String, String) -> Net::HTTPResponse", http, :post, "/", "payload"
153+
assert_send_type "(String, String, Hash[String, String]) -> Net::HTTPResponse",
154+
http, :request_post, "/", "payload", { "Content-Type" => "text/plain" }
155+
assert_send_type "(String) { (Net::HTTPResponse) -> String? } -> Net::HTTPResponse",
156+
http, :request_get, "/" do |response|
157+
response.body
158+
end
159+
assert_send_type "(String, String) -> Net::HTTPResponse",
160+
http, :send_request, "GET", "/"
161+
assert_send_type "(Net::HTTPRequest) -> Net::HTTPResponse",
162+
http, :request, Net::HTTP::Get.new(uri)
163+
ensure
164+
http.finish if http&.started?
165+
end
166+
end
167+
end
168+
169+
class NetHTTPRequestRBSTest < NetHTTPRBSTestCase
170+
include NetHTTPTypeTestSupport
171+
172+
testing "::Net::HTTPRequest"
173+
174+
def test_request_attributes_and_headers
175+
uri = URI("http://127.0.0.1/")
176+
request = Net::HTTP::Get.new(uri)
177+
178+
assert_send_type "() -> String", request, :inspect
179+
assert_send_type "() -> String", request, :method
180+
assert_send_type "() -> String", request, :path
181+
assert_send_type "() -> URI::Generic", request, :uri
182+
assert_send_type "() -> bool", request, :decode_content
183+
assert_send_type "() -> bool", request, :request_body_permitted?
184+
assert_send_type "() -> bool", request, :response_body_permitted?
185+
assert_send_type "() -> nil", request, :body
186+
assert_send_type "(String) -> void", request, :body=, "payload"
187+
assert_send_type "() -> nil", request, :body_stream
188+
assert_send_type "(untyped) -> untyped", request, :body_stream=, StringIO.new
189+
assert_send_type "(String) -> nil", request, :[], "Content-Type"
190+
assert_send_type "(String, untyped) -> void", request, :[]=, "Content-Type", "text/plain"
191+
assert_send_type "(String, untyped) -> void", request, :add_field, "X-Test", "1"
192+
assert_send_type "(String) -> bool", request, :key?, "X-Test"
193+
assert_send_type "() -> nil", request, :range
194+
assert_send_type "(Range[Integer]) -> Range[Integer]", request, :set_range, 0..10
195+
assert_send_type "(Integer) -> void", request, :content_length=, 10
196+
assert_send_type "(String) -> void", request, :set_content_type, "text/plain"
197+
assert_send_type "(Hash[untyped, untyped]) -> void", request, :set_form_data, { "q" => "ruby" }
198+
assert_send_type "(Hash[untyped, untyped]) -> void", request, :set_form, { "q" => "ruby" }
199+
assert_send_type "(String account, String password) -> void",
200+
request, :basic_auth, "username", "password"
201+
assert_send_type "(String account, String password) -> void",
202+
request, :proxy_basic_auth, "username", "password"
203+
assert_send_type "() -> bool", request, :connection_close?
204+
assert_send_type "() -> bool", request, :connection_keep_alive?
205+
assert_send_type "() { (String, String) -> String } -> Hash[String, Array[String]]",
206+
request, :each_header do |key, value|
207+
"#{key}:#{value}"
208+
end
209+
assert_send_type "() -> Enumerator[[String, String], Hash[String, Array[String]]]",
210+
request, :each_header
211+
assert_send_type "() -> Hash[String, Array[String]]", request, :to_hash
212+
end
213+
214+
def test_response_header_helpers
215+
with_server do |uri|
216+
response = Net::HTTP.start(uri.host, uri.port) { |http| http.request_get("/") }
217+
218+
assert_send_type "(String) -> Array[String]",
219+
response, :get_fields, "Set-Cookie"
220+
assert_send_type "(String) { (String) -> String } -> String",
221+
response, :fetch, "Set-Cookie" do |value|
222+
value
223+
end
224+
assert_send_type "(String) -> Array[String]",
225+
response, :delete, "Set-Cookie"
226+
end
227+
end
228+
end
229+
230+
class NetHTTPResponseRBSTest < NetHTTPRBSTestCase
231+
include NetHTTPTypeTestSupport
232+
233+
testing "::Net::HTTPResponse"
234+
235+
class SingletonTest < NetHTTPRBSTestCase
236+
testing "singleton(::Net::HTTPResponse)"
237+
238+
def test_singleton_api
239+
assert_send_type "() -> bool", Net::HTTPSuccess, :body_permitted?
240+
end
241+
end
242+
243+
def response
244+
with_server do |uri|
245+
Net::HTTP.get_response(uri)
246+
end
247+
end
248+
249+
def test_response_api
250+
assert_send_type "() -> String", response, :http_version
251+
assert_send_type "() -> String", response, :code
252+
assert_send_type "() -> String", response, :message
253+
assert_send_type "() -> String", response, :msg
254+
assert_send_type "() -> URI::Generic", response, :uri
255+
assert_send_type "() -> bool", response, :decode_content
256+
assert_send_type "() -> String", response, :inspect
257+
assert_send_type "() -> untyped", response, :code_type
258+
assert_send_type "() -> nil", response, :value
259+
assert_send_type "(URI::Generic) -> void", response, :uri=, URI("http://127.0.0.1/next")
260+
assert_send_type "() -> String", response, :body
261+
assert_send_type "(String) -> void", response, :body=, "payload"
262+
assert_send_type "() -> String", response, :entity
263+
end
264+
end

0 commit comments

Comments
 (0)