sus-fixtures-async-http 0.10.0 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7ca53e2286a46691cf27d9c9255bd10dabce31145376b7b9b0e64fda362b810a
4
- data.tar.gz: 432d75147545cd62dd857f03b3ec0c5b6eca775595571c01b3ceb83ddbaeeced
3
+ metadata.gz: a02a80acae8f8b6c8502986b21ca39d7e950dabfde21839d3632735213f11cc0
4
+ data.tar.gz: 1ae85d08937d7340805503b06f3559baaa3ebe7d70aca052bdb6216a508dab13
5
5
  SHA512:
6
- metadata.gz: 80b91bb25f1f2ec269fe0c382a308e2ca015c23c5aad40fa6a48f86d934dcea55595b368b3089790f476510128ba31f901d4efe3ad4155fb23889c72124f3a1a
7
- data.tar.gz: e40898d89d6c4125b914e47bcb46b4e4f315791e8b168db87fab9fc880cb66575295b3ec2b65b3c265cb873a1f5a5330b4a3ffcd8e38e107048f10a18e738521
6
+ metadata.gz: 9144f6a3c90fb80a07d1e5717591a47a6c73f001105241b3b4912d54a0a96f04383e9cc657190671ad8477295ac3f0672c48ed14bf285e6fef27d81793db62b8
7
+ data.tar.gz: 748af62b604a42f8b342e813502f2a372de16d0135e4c260b96141b95aa6f8d09fc7ecc11e361dbdc69389bfaeb64fdf5cd2897c801a9e3e86ac63b1104bd90a
checksums.yaml.gz.sig CHANGED
Binary file
@@ -0,0 +1,147 @@
1
+ # Getting Started
2
+
3
+ This guide explains how to use the `sus-fixtures-async-http` gem to test HTTP clients and servers.
4
+
5
+ ## Installation
6
+
7
+ Add the gem to your project:
8
+
9
+ ``` bash
10
+ $ bundle add sus-fixtures-async-http
11
+ ```
12
+
13
+ ## Usage
14
+
15
+ Here is a simple example showing how to test the default server:
16
+
17
+ ``` ruby
18
+ include Sus::Fixtures::Async::HTTP::ServerContext
19
+
20
+ let(:response) {client.get("/")}
21
+
22
+ it 'can perform a request' do
23
+ expect(response.read).to be == "Hello World!"
24
+ end
25
+ ```
26
+
27
+ ### Custom Applications
28
+
29
+ You can create a custom application to test your own HTTP handlers:
30
+
31
+ ``` ruby
32
+ include Sus::Fixtures::Async::HTTP::ServerContext
33
+
34
+ let(:app) do
35
+ Protocol::HTTP::Middleware.for do |request|
36
+ case request.path
37
+ when "/"
38
+ Protocol::HTTP::Response[200, {}, ["Home Page"]]
39
+ when "/api/status"
40
+ Protocol::HTTP::Response[200, {"content-type" => "application/json"}, ['{"status":"ok"}']]
41
+ else
42
+ Protocol::HTTP::Response[404, {}, ["Not Found"]]
43
+ end
44
+ end
45
+ end
46
+
47
+ it 'serves the home page' do
48
+ response = client.get("/")
49
+ expect(response.status).to be == 200
50
+ expect(response.read).to be == "Home Page"
51
+ end
52
+
53
+ it 'serves API endpoints' do
54
+ response = client.get("/api/status")
55
+ expect(response.status).to be == 200
56
+ expect(response.headers["content-type"]).to be == "application/json"
57
+ expect(response.read).to be == '{"status":"ok"}'
58
+ end
59
+
60
+ it 'returns 404 for unknown paths' do
61
+ response = client.get("/unknown")
62
+ expect(response.status).to be == 404
63
+ end
64
+ ```
65
+
66
+ ### Testing Different HTTP Methods
67
+
68
+ Test various HTTP methods and request bodies:
69
+
70
+ ``` ruby
71
+ include Sus::Fixtures::Async::HTTP::ServerContext
72
+
73
+ let(:app) do
74
+ Protocol::HTTP::Middleware.for do |request|
75
+ case [request.method, request.path]
76
+ when ["GET", "/users"]
77
+ Protocol::HTTP::Response[200, {}, ['[{"id":1,"name":"John"}]']]
78
+ when ["POST", "/users"]
79
+ body = request.body.read
80
+ Protocol::HTTP::Response[201, {}, ["Created: #{body}"]]
81
+ when ["PUT", "/users/1"]
82
+ body = request.body.read
83
+ Protocol::HTTP::Response[200, {}, ["Updated: #{body}"]]
84
+ when ["DELETE", "/users/1"]
85
+ Protocol::HTTP::Response[204, {}, [""]]
86
+ else
87
+ Protocol::HTTP::Response[404, {}, ["Not Found"]]
88
+ end
89
+ end
90
+ end
91
+
92
+ it 'handles GET requests' do
93
+ response = client.get("/users")
94
+ expect(response.status).to be == 200
95
+ end
96
+
97
+ it 'handles POST requests' do
98
+ response = client.post("/users", {}, ['{"name":"Alice"}'])
99
+ expect(response.status).to be == 201
100
+ expect(response.read).to be(:include?, "Alice")
101
+ end
102
+
103
+ it 'handles PUT requests' do
104
+ response = client.put("/users/1", {}, ['{"name":"Bob"}'])
105
+ expect(response.status).to be == 200
106
+ end
107
+
108
+ it 'handles DELETE requests' do
109
+ response = client.delete("/users/1")
110
+ expect(response.status).to be == 204
111
+ end
112
+ ```
113
+
114
+ ## Configuration Options
115
+
116
+ ### Custom URLs and Ports
117
+
118
+ Override the server URL and endpoint options:
119
+
120
+ ``` ruby
121
+ include Sus::Fixtures::Async::HTTP::ServerContext
122
+
123
+ let(:url) {"http://localhost:9999"}
124
+
125
+ let(:endpoint_options) do
126
+ {reuse_port: true, protocol: protocol, timeout: 30}
127
+ end
128
+
129
+ it 'uses custom configuration' do
130
+ expect(bound_url).to be(:include?, ":9999")
131
+ end
132
+ ```
133
+
134
+ ### Protocol Selection
135
+
136
+ Test with different HTTP protocol versions:
137
+
138
+ ``` ruby
139
+ include Sus::Fixtures::Async::HTTP::ServerContext
140
+
141
+ let(:protocol) {Async::HTTP::Protocol::HTTP2}
142
+
143
+ it 'uses HTTP/2 protocol' do
144
+ response = client.get("/")
145
+ expect(response).to have_attributes(version: "HTTP/2.0")
146
+ end
147
+ ```
@@ -0,0 +1,13 @@
1
+ # Automatically generated context index for Utopia::Project guides.
2
+ # Do not edit then files in this directory directly, instead edit the guides and then run `bake utopia:project:agent:context:update`.
3
+ ---
4
+ description: Test fixtures for running in Async::HTTP.
5
+ metadata:
6
+ documentation_uri: https://socketry.github.io/sus-fixtures-async-http/
7
+ funding_uri: https://github.com/sponsors/ioquatix/
8
+ source_code_uri: https://github.com/socketry/sus-fixtures-async-http.git
9
+ files:
10
+ - path: getting-started.md
11
+ title: Getting Started
12
+ description: This guide explains how to use the `sus-fixtures-async-http` gem to
13
+ test HTTP clients and servers.
@@ -1,28 +1,44 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # Released under the MIT License.
4
- # Copyright, 2022-2024, by Samuel Williams.
4
+ # Copyright, 2022-2025, by Samuel Williams.
5
5
 
6
- require 'sus/fixtures/async/reactor_context'
6
+ require "sus/fixtures/async/reactor_context"
7
7
 
8
- require 'async/http/server'
9
- require 'async/http/client'
10
- require 'async/http/endpoint'
8
+ require "async/http/server"
9
+ require "async/http/client"
10
+ require "async/http/endpoint"
11
11
 
12
12
  module Sus::Fixtures
13
13
  module Async
14
14
  module HTTP
15
+ # ServerContext provides a test fixture for HTTP server and client testing.
16
+ # It sets up an HTTP server with a bound endpoint and provides a corresponding client
17
+ # for making requests. This context handles the lifecycle of both server and client,
18
+ # ensuring proper setup and teardown.
19
+ #
20
+ # The context automatically:
21
+ # - Binds to an available port
22
+ # - Starts an HTTP server with configurable middleware
23
+ # - Creates a client configured to connect to the server
24
+ # - Handles cleanup of resources after tests
15
25
  module ServerContext
16
26
  include ReactorContext
17
27
 
28
+ # The HTTP protocol version to use for the server.
29
+ # @returns [Class] The protocol class (defaults to HTTP/1.1).
18
30
  def protocol
19
31
  ::Async::HTTP::Protocol::HTTP1
20
32
  end
21
33
 
34
+ # The base URL for the HTTP server.
35
+ # @returns [String] The URL string with host and port (defaults to localhost:0 for auto-assigned port).
22
36
  def url
23
- 'http://localhost:0'
37
+ "http://localhost:0"
24
38
  end
25
39
 
40
+ # Get all bound URLs for the server endpoints.
41
+ # @returns [Array(String)] Array of URLs the server is bound to, sorted alphabetically.
26
42
  def bound_urls
27
43
  urls = []
28
44
 
@@ -44,61 +60,94 @@ module Sus::Fixtures
44
60
  return urls
45
61
  end
46
62
 
63
+ # Get the first bound URL for the server.
64
+ # @returns [String] The first bound URL, typically used for single-endpoint testing.
47
65
  def bound_url
48
66
  bound_urls.first
49
67
  end
50
68
 
69
+ # Options for configuring the HTTP endpoint.
70
+ # @returns [Hash] Hash of endpoint options including port reuse and protocol settings.
51
71
  def endpoint_options
52
72
  {reuse_port: true, protocol: protocol}
53
73
  end
54
74
 
75
+ # The HTTP endpoint configuration.
76
+ # @returns [Async::HTTP::Endpoint] Parsed endpoint with configured options.
55
77
  def endpoint
56
78
  ::Async::HTTP::Endpoint.parse(url, **endpoint_options)
57
79
  end
58
80
 
81
+ # Number of retries for client requests.
82
+ # @returns [Integer] Number of retry attempts (defaults to 1).
59
83
  def retries
60
84
  1
61
85
  end
62
86
 
87
+ # The HTTP application/middleware to serve.
88
+ # @returns [Object] The application object that handles HTTP requests (defaults to HelloWorld middleware).
63
89
  def app
64
90
  ::Protocol::HTTP::Middleware::HelloWorld
65
91
  end
66
92
 
93
+ # The middleware stack for the HTTP server.
94
+ # @returns [Object] The middleware configuration (defaults to the app).
67
95
  def middleware
68
96
  app
69
97
  end
70
98
 
99
+ # Create the server endpoint from a bound endpoint.
100
+ # @parameter bound_endpoint [Async::HTTP::Endpoint] The bound endpoint.
101
+ # @returns [Async::HTTP::Endpoint] The server endpoint configuration.
71
102
  def make_server_endpoint(bound_endpoint)
72
103
  bound_endpoint
73
104
  end
74
105
 
106
+ # Create an HTTP server instance.
107
+ # @parameter endpoint [Async::HTTP::Endpoint] The endpoint to bind the server to.
108
+ # @returns [Async::HTTP::Server] The configured HTTP server.
75
109
  def make_server(endpoint)
76
110
  ::Async::HTTP::Server.new(middleware, endpoint)
77
111
  end
78
112
 
113
+ # The HTTP server instance.
114
+ # @returns [Async::HTTP::Server] The running HTTP server.
79
115
  def server
80
116
  @server
81
117
  end
82
118
 
119
+ # The HTTP client instance.
120
+ # @returns [Async::HTTP::Client] The HTTP client configured to connect to the server.
83
121
  def client
84
122
  @client
85
123
  end
86
124
 
125
+ # The client endpoint configuration.
126
+ # @returns [Async::HTTP::Endpoint] The endpoint the client uses to connect to the server.
87
127
  def client_endpoint
88
128
  @client_endpoint
89
129
  end
90
130
 
131
+ # Create a client endpoint from a bound endpoint.
132
+ # @parameter bound_endpoint [Async::HTTP::Endpoint] The bound server endpoint.
133
+ # @returns [Async::HTTP::Endpoint] The client endpoint with local address and timeout.
91
134
  def make_client_endpoint(bound_endpoint)
92
135
  # Pass through the timeout:
93
136
  bound_endpoint.local_address_endpoint(timeout: endpoint.timeout)
94
137
  end
95
138
 
139
+ # Create an HTTP client instance.
140
+ # @parameter endpoint [Async::HTTP::Endpoint] The endpoint to connect to.
141
+ # @parameter options [Hash] Additional client options.
142
+ # @returns [Async::HTTP::Client] The configured HTTP client.
96
143
  def make_client(endpoint, **options)
97
144
  options[:retries] = retries unless options.key?(:retries)
98
145
 
99
146
  ::Async::HTTP::Client.new(endpoint, **options)
100
147
  end
101
148
 
149
+ # Set up the server and client before running tests.
150
+ # This method binds the endpoint, starts the server, and creates a client.
102
151
  def before
103
152
  super
104
153
 
@@ -115,9 +164,7 @@ module Sus::Fixtures
115
164
 
116
165
  @server = make_server(@server_endpoint)
117
166
 
118
- @server_task = Async do
119
- @server.run
120
- end
167
+ @server_task = @server.run
121
168
 
122
169
  @client_endpoint = make_client_endpoint(@bound_endpoint)
123
170
  mock(@client_endpoint) do |wrapper|
@@ -130,11 +177,15 @@ module Sus::Fixtures
130
177
  @client = make_client(@client_endpoint)
131
178
  end
132
179
 
180
+ # Clean up resources after running tests.
181
+ # This method closes the client, stops the server, and closes the bound endpoint.
182
+ # @parameter error [Exception | Nil] Any error that occurred during the test.
133
183
  def after(error = nil)
134
184
  # We add a timeout here, to avoid hanging in `@client.close`:
135
185
  ::Async::Task.current.with_timeout(1) do
136
186
  @client&.close
137
187
  @server_task&.stop
188
+ @server_task&.wait
138
189
  @bound_endpoint&.close
139
190
  end
140
191
 
@@ -1,13 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # Released under the MIT License.
4
- # Copyright, 2022-2024, by Samuel Williams.
4
+ # Copyright, 2022-2025, by Samuel Williams.
5
5
 
6
6
  module Sus
7
7
  module Fixtures
8
8
  module Async
9
9
  module HTTP
10
- VERSION = "0.10.0"
10
+ VERSION = "0.12.0"
11
11
  end
12
12
  end
13
13
  end
@@ -1,7 +1,20 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # Released under the MIT License.
4
- # Copyright, 2022-2023, by Samuel Williams.
4
+ # Copyright, 2022-2025, by Samuel Williams.
5
5
 
6
- require_relative 'http/server_context'
7
- require_relative 'http/version'
6
+ # @namespace
7
+ module Sus
8
+ # @namespace
9
+ module Fixtures
10
+ # @namespace
11
+ module Async
12
+ # @namespace
13
+ module HTTP
14
+ end
15
+ end
16
+ end
17
+ end
18
+
19
+ require_relative "http/server_context"
20
+ require_relative "http/version"
data/license.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # MIT License
2
2
 
3
- Copyright, 2022-2024, by Samuel Williams.
3
+ Copyright, 2022-2025, by Samuel Williams.
4
4
  Copyright, 2023, by Felix Yan.
5
5
 
6
6
  Permission is hereby granted, free of charge, to any person obtaining a copy
data/readme.md CHANGED
@@ -2,13 +2,60 @@
2
2
 
3
3
  Provides a convenient fixture for running a web server.
4
4
 
5
- [![Development Status](https://github.com/suspecting/sus-fixtures-async-http/workflows/Test/badge.svg)](https://github.com/suspecting/sus-fixtures-async-http/actions?workflow=Test)
5
+ [![Development Status](https://github.com/socketry/sus-fixtures-async-http/workflows/Test/badge.svg)](https://github.com/socketry/sus-fixtures-async-http/actions?workflow=Test)
6
6
 
7
7
  ## Usage
8
8
 
9
- Please see the [project documentation](https://suspecting.github.io/sus-fixtures-async-http/) for more details.
9
+ Please see the [project documentation](https://socketry.github.io/sus-fixtures-async-http/) for more details.
10
10
 
11
- - [Getting Started](https://suspecting.github.io/sus-fixtures-async-http/guides/getting-started/index) - This guide explains how to use the `sus-fixtures-async-http` gem to test HTTP clients and servers.
11
+ - [Getting Started](https://socketry.github.io/sus-fixtures-async-http/guides/getting-started/index) - This guide explains how to use the `sus-fixtures-async-http` gem to test HTTP clients and servers.
12
+
13
+ ## Releases
14
+
15
+ Please see the [project releases](https://socketry.github.io/sus-fixtures-async-http/releases/index) for all releases.
16
+
17
+ ### v0.12.0
18
+
19
+ - Add agent context.
20
+
21
+ ### v0.11.0
22
+
23
+ - 100% documentation coverage.
24
+ - Remove unused outer server task.
25
+
26
+ ### v0.10.0
27
+
28
+ - Make it easier to override endpoint options like `timeout`.
29
+ - Remove default connection timeout.
30
+
31
+ ### v0.9.1
32
+
33
+ - Remove default connection timeout.
34
+
35
+ ### v0.9.0
36
+
37
+ - Add optional `after(error)` argument.
38
+ - Add Getting Started guide.
39
+
40
+ ### v0.8.1
41
+
42
+ - Add a timeout to prevent hangs during `@client.close`.
43
+
44
+ ### v0.8.0
45
+
46
+ - Don't depend on `async-io` directly.
47
+
48
+ ### v0.7.0
49
+
50
+ - Pass through the timeout.
51
+
52
+ ### v0.6.0
53
+
54
+ - Expose `make_client` similar to `make_server`.
55
+
56
+ ### v0.5.0
57
+
58
+ - Fix `make_server` to use endpoint argument.
12
59
 
13
60
  ## Contributing
14
61
 
data/releases.md ADDED
@@ -0,0 +1,87 @@
1
+ # Releases
2
+
3
+ ## v0.12.0
4
+
5
+ - Add agent context.
6
+
7
+ ## v0.11.0
8
+
9
+ - 100% documentation coverage.
10
+ - Remove unused outer server task.
11
+
12
+ ## v0.10.0
13
+
14
+ - Make it easier to override endpoint options like `timeout`.
15
+ - Remove default connection timeout.
16
+
17
+ ## v0.9.1
18
+
19
+ - Remove default connection timeout.
20
+
21
+ ## v0.9.0
22
+
23
+ - Add optional `after(error)` argument.
24
+ - Add Getting Started guide.
25
+
26
+ ## v0.8.1
27
+
28
+ - Add a timeout to prevent hangs during `@client.close`.
29
+
30
+ ## v0.8.0
31
+
32
+ - Don't depend on `async-io` directly.
33
+
34
+ ## v0.7.0
35
+
36
+ - Pass through the timeout.
37
+
38
+ ## v0.6.0
39
+
40
+ - Expose `make_client` similar to `make_server`.
41
+
42
+ ## v0.5.0
43
+
44
+ - Fix `make_server` to use endpoint argument.
45
+
46
+ ## v0.4.0
47
+
48
+ - Add SSL support.
49
+ - Correct homepage in gemspec.
50
+
51
+ ## v0.3.0
52
+
53
+ - Sort bound URLs for more predictable tests.
54
+ - Add missing dependency on `async-http`.
55
+ - Expose url and bound\_urls.
56
+
57
+ ## v0.2.3
58
+
59
+ - Mock path on `client_endpoint`.
60
+
61
+ ## v0.2.2
62
+
63
+ - Fix timeout.
64
+
65
+ ## v0.2.1
66
+
67
+ - Fix `client_endpoint` and add tests.
68
+
69
+ ## v0.2.0
70
+
71
+ - Expose client endpoint.
72
+
73
+ ## v0.1.3
74
+
75
+ - Improve compatibility with simultaneous execution by using host-allocated ports.
76
+
77
+ ## v0.1.2
78
+
79
+ - Relax dependency.
80
+
81
+ ## v0.1.1
82
+
83
+ - Fix all the things.
84
+
85
+ ## v0.1.0
86
+
87
+ - Initial implementation.
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,12 +1,11 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sus-fixtures-async-http
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.10.0
4
+ version: 0.12.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Samuel Williams
8
8
  - Felix Yan
9
- autorequire:
10
9
  bindir: bin
11
10
  cert_chain:
12
11
  - |
@@ -38,7 +37,7 @@ cert_chain:
38
37
  Q2K9NVun/S785AP05vKkXZEFYxqG6EW012U4oLcFl5MySFajYXRYbuUpH6AY+HP8
39
38
  voD0MPg1DssDLKwXyt1eKD/+Fq0bFWhwVM/1XiAXL7lyYUyOq24KHgQ2Csg=
40
39
  -----END CERTIFICATE-----
41
- date: 2024-11-20 00:00:00.000000000 Z
40
+ date: 1980-01-02 00:00:00.000000000 Z
42
41
  dependencies:
43
42
  - !ruby/object:Gem::Dependency
44
43
  name: async-http
@@ -82,25 +81,25 @@ dependencies:
82
81
  - - "~>"
83
82
  - !ruby/object:Gem::Version
84
83
  version: '0.1'
85
- description:
86
- email:
87
84
  executables: []
88
85
  extensions: []
89
86
  extra_rdoc_files: []
90
87
  files:
88
+ - context/getting-started.md
89
+ - context/index.yaml
91
90
  - lib/sus/fixtures/async/http.rb
92
91
  - lib/sus/fixtures/async/http/server_context.rb
93
92
  - lib/sus/fixtures/async/http/version.rb
94
93
  - license.md
95
94
  - readme.md
96
- homepage: https://github.com/suspecting/sus-fixtures-async-http
95
+ - releases.md
96
+ homepage: https://github.com/socketry/sus-fixtures-async-http
97
97
  licenses:
98
98
  - MIT
99
99
  metadata:
100
- documentation_uri: https://suspecting.github.io/sus-fixtures-async-http/
100
+ documentation_uri: https://socketry.github.io/sus-fixtures-async-http/
101
101
  funding_uri: https://github.com/sponsors/ioquatix/
102
- source_code_uri: https://github.com/suspecting/sus-fixtures-async-http.git
103
- post_install_message:
102
+ source_code_uri: https://github.com/socketry/sus-fixtures-async-http.git
104
103
  rdoc_options: []
105
104
  require_paths:
106
105
  - lib
@@ -108,15 +107,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
108
107
  requirements:
109
108
  - - ">="
110
109
  - !ruby/object:Gem::Version
111
- version: '3.1'
110
+ version: '3.2'
112
111
  required_rubygems_version: !ruby/object:Gem::Requirement
113
112
  requirements:
114
113
  - - ">="
115
114
  - !ruby/object:Gem::Version
116
115
  version: '0'
117
116
  requirements: []
118
- rubygems_version: 3.5.22
119
- signing_key:
117
+ rubygems_version: 3.6.9
120
118
  specification_version: 4
121
119
  summary: Test fixtures for running in Async::HTTP.
122
120
  test_files: []
metadata.gz.sig CHANGED
Binary file