Skip to content

Modernize code #4

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jul 1, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/documentation-coverage.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
- uses: actions/checkout@v4
- uses: ruby/setup-ruby@v1
with:
ruby-version: "3.3"
ruby-version: "3.4"
bundler-cache: true

- name: Validate coverage
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/documentation.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ jobs:

- uses: ruby/setup-ruby@v1
with:
ruby-version: "3.3"
ruby-version: "3.4"
bundler-cache: true

- name: Installing packages
Expand Down
20 changes: 4 additions & 16 deletions .github/workflows/rubocop.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Test External
name: RuboCop

on: [push, pull_request]

Expand All @@ -9,26 +9,14 @@ env:
CONSOLE_OUTPUT: XTerm

jobs:
test:
name: ${{matrix.ruby}} on ${{matrix.os}}
runs-on: ${{matrix.os}}-latest

strategy:
matrix:
os:
- ubuntu
- macos

ruby:
- "3.1"
- "3.2"
- "3.3"
check:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4
- uses: ruby/setup-ruby@v1
with:
ruby-version: ${{matrix.ruby}}
ruby-version: ruby
bundler-cache: true

- name: Run RuboCop
Expand Down
12 changes: 7 additions & 5 deletions .github/workflows/test-coverage.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jobs:
- macos

ruby:
- "3.3"
- "3.4"

steps:
- uses: actions/checkout@v4
Expand All @@ -33,9 +33,11 @@ jobs:
- name: Run tests
timeout-minutes: 5
run: bundle exec bake test

- uses: actions/upload-artifact@v3
- uses: actions/upload-artifact@v4
with:
include-hidden-files: true
if-no-files-found: error
name: coverage-${{matrix.os}}-${{matrix.ruby}}
path: .covered.db

Expand All @@ -47,10 +49,10 @@ jobs:
- uses: actions/checkout@v4
- uses: ruby/setup-ruby@v1
with:
ruby-version: "3.3"
ruby-version: "3.4"
bundler-cache: true

- uses: actions/download-artifact@v3
- uses: actions/download-artifact@v4

- name: Validate coverage
timeout-minutes: 5
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test-external.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ jobs:
- macos

ruby:
- "3.1"
- "3.2"
- "3.3"
- "3.4"

steps:
- uses: actions/checkout@v4
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ jobs:
- macos

ruby:
- "3.1"
- "3.2"
- "3.3"
- "3.4"

experimental: [false]

Expand Down
10 changes: 10 additions & 0 deletions .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ Layout/IndentationConsistency:
Enabled: true
EnforcedStyle: normal

Layout/BlockAlignment:
Enabled: true

Layout/EndAlignment:
Enabled: true
EnforcedStyleAlignWith: start_of_line
Expand All @@ -42,5 +45,12 @@ Layout/EmptyLinesAroundClassBody:
Layout/EmptyLinesAroundModuleBody:
Enabled: true

Layout/EmptyLineAfterMagicComment:
Enabled: true

Style/FrozenStringLiteralComment:
Enabled: true

Style/StringLiterals:
Enabled: true
EnforcedStyle: double_quotes
2 changes: 1 addition & 1 deletion config/sus.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@
# Released under the MIT License.
# Copyright, 2022-2023, by Samuel Williams.

require 'covered/sus'
require "covered/sus"
include Covered::Sus
17 changes: 15 additions & 2 deletions lib/sus/fixtures/async/http.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,18 @@
# Released under the MIT License.
# Copyright, 2022-2023, by Samuel Williams.

require_relative 'http/server_context'
require_relative 'http/version'
# @namespace
module Sus
# @namespace
module Fixtures
# @namespace
module Async
# @namespace
module HTTP
end
end
end
end

require_relative "http/server_context"
require_relative "http/version"
69 changes: 60 additions & 9 deletions lib/sus/fixtures/async/http/server_context.rb
Original file line number Diff line number Diff line change
@@ -1,28 +1,44 @@
# frozen_string_literal: true

# Released under the MIT License.
# Copyright, 2022-2024, by Samuel Williams.
# Copyright, 2022-2025, by Samuel Williams.

require 'sus/fixtures/async/reactor_context'
require "sus/fixtures/async/reactor_context"

require 'async/http/server'
require 'async/http/client'
require 'async/http/endpoint'
require "async/http/server"
require "async/http/client"
require "async/http/endpoint"

module Sus::Fixtures
module Async
module HTTP
# ServerContext provides a test fixture for HTTP server and client testing.
# It sets up an HTTP server with a bound endpoint and provides a corresponding client
# for making requests. This context handles the lifecycle of both server and client,
# ensuring proper setup and teardown.
#
# The context automatically:
# - Binds to an available port
# - Starts an HTTP server with configurable middleware
# - Creates a client configured to connect to the server
# - Handles cleanup of resources after tests
module ServerContext
include ReactorContext

# The HTTP protocol version to use for the server.
# @returns [Class] The protocol class (defaults to HTTP/1.1).
def protocol
::Async::HTTP::Protocol::HTTP1
end

# The base URL for the HTTP server.
# @returns [String] The URL string with host and port (defaults to localhost:0 for auto-assigned port).
def url
'http://localhost:0'
"http://localhost:0"
end

# Get all bound URLs for the server endpoints.
# @returns [Array(String)] Array of URLs the server is bound to, sorted alphabetically.
def bound_urls
urls = []

Expand All @@ -44,61 +60,94 @@ def bound_urls
return urls
end

# Get the first bound URL for the server.
# @returns [String] The first bound URL, typically used for single-endpoint testing.
def bound_url
bound_urls.first
end

# Options for configuring the HTTP endpoint.
# @returns [Hash] Hash of endpoint options including port reuse and protocol settings.
def endpoint_options
{reuse_port: true, protocol: protocol}
end

# The HTTP endpoint configuration.
# @returns [Async::HTTP::Endpoint] Parsed endpoint with configured options.
def endpoint
::Async::HTTP::Endpoint.parse(url, **endpoint_options)
end

# Number of retries for client requests.
# @returns [Integer] Number of retry attempts (defaults to 1).
def retries
1
end

# The HTTP application/middleware to serve.
# @returns [Object] The application object that handles HTTP requests (defaults to HelloWorld middleware).
def app
::Protocol::HTTP::Middleware::HelloWorld
end

# The middleware stack for the HTTP server.
# @returns [Object] The middleware configuration (defaults to the app).
def middleware
app
end

# Create the server endpoint from a bound endpoint.
# @parameter bound_endpoint [Async::HTTP::Endpoint] The bound endpoint.
# @returns [Async::HTTP::Endpoint] The server endpoint configuration.
def make_server_endpoint(bound_endpoint)
bound_endpoint
end

# Create an HTTP server instance.
# @parameter endpoint [Async::HTTP::Endpoint] The endpoint to bind the server to.
# @returns [Async::HTTP::Server] The configured HTTP server.
def make_server(endpoint)
::Async::HTTP::Server.new(middleware, endpoint)
end

# The HTTP server instance.
# @returns [Async::HTTP::Server] The running HTTP server.
def server
@server
end

# The HTTP client instance.
# @returns [Async::HTTP::Client] The HTTP client configured to connect to the server.
def client
@client
end

# The client endpoint configuration.
# @returns [Async::HTTP::Endpoint] The endpoint the client uses to connect to the server.
def client_endpoint
@client_endpoint
end

# Create a client endpoint from a bound endpoint.
# @parameter bound_endpoint [Async::HTTP::Endpoint] The bound server endpoint.
# @returns [Async::HTTP::Endpoint] The client endpoint with local address and timeout.
def make_client_endpoint(bound_endpoint)
# Pass through the timeout:
bound_endpoint.local_address_endpoint(timeout: endpoint.timeout)
end

# Create an HTTP client instance.
# @parameter endpoint [Async::HTTP::Endpoint] The endpoint to connect to.
# @parameter options [Hash] Additional client options.
# @returns [Async::HTTP::Client] The configured HTTP client.
def make_client(endpoint, **options)
options[:retries] = retries unless options.key?(:retries)

::Async::HTTP::Client.new(endpoint, **options)
end

# Set up the server and client before running tests.
# This method binds the endpoint, starts the server, and creates a client.
def before
super

Expand All @@ -115,9 +164,7 @@ def before

@server = make_server(@server_endpoint)

@server_task = Async do
@server.run
end
@server_task = @server.run

@client_endpoint = make_client_endpoint(@bound_endpoint)
mock(@client_endpoint) do |wrapper|
Expand All @@ -130,11 +177,15 @@ def before
@client = make_client(@client_endpoint)
end

# Clean up resources after running tests.
# This method closes the client, stops the server, and closes the bound endpoint.
# @parameter error [Exception | Nil] Any error that occurred during the test.
def after(error = nil)
# We add a timeout here, to avoid hanging in `@client.close`:
::Async::Task.current.with_timeout(1) do
@client&.close
@server_task&.stop
@server_task&.wait
@bound_endpoint&.close
end

Expand Down
2 changes: 1 addition & 1 deletion license.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# MIT License

Copyright, 2022-2024, by Samuel Williams.
Copyright, 2022-2025, by Samuel Williams.
Copyright, 2023, by Felix Yan.

Permission is hereby granted, free of charge, to any person obtaining a copy
Expand Down
8 changes: 4 additions & 4 deletions sus-fixtures-async-http.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ Gem::Specification.new do |spec|
spec.authors = ["Samuel Williams", "Felix Yan"]
spec.license = "MIT"

spec.cert_chain = ['release.cert']
spec.signing_key = File.expand_path('~/.gem/release.pem')
spec.cert_chain = ["release.cert"]
spec.signing_key = File.expand_path("~/.gem/release.pem")

spec.homepage = "https://github.com/suspecting/sus-fixtures-async-http"

Expand All @@ -21,9 +21,9 @@ Gem::Specification.new do |spec|
"source_code_uri" => "https://github.com/suspecting/sus-fixtures-async-http.git",
}

spec.files = Dir.glob(['{lib}/**/*', '*.md'], File::FNM_DOTMATCH, base: __dir__)
spec.files = Dir.glob(["{lib}/**/*", "*.md"], File::FNM_DOTMATCH, base: __dir__)

spec.required_ruby_version = ">= 3.1"
spec.required_ruby_version = ">= 3.2"

spec.add_dependency "async-http", "~> 0.54"
spec.add_dependency "sus", "~> 0.31"
Expand Down
4 changes: 2 additions & 2 deletions test/sus/fixtures/async/http.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
# Released under the MIT License.
# Copyright, 2022-2023, by Samuel Williams.

require 'sus/fixtures/async/http'
require "sus/fixtures/async/http"

describe Sus::Fixtures::Async::HTTP::VERSION do
it 'is a version string' do
it "is a version string" do
expect(subject).to be =~ /\d+\.\d+\.\d+/
end
end
Loading
Loading