Skip to content

Commit 3989cd6

Browse files
committed
100% documentation coverage.
1 parent 623d8d9 commit 3989cd6

File tree

6 files changed

+110
-8
lines changed

6 files changed

+110
-8
lines changed

context/index.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
description: Provides abstractions for working with URLs.
55
metadata:
66
source_code_uri: https://github.com/socketry/protocol-url.git
7+
documentation_uri: https://socketry.github.io/protocol-url/
78
files:
89
- path: getting-started.md
910
title: Getting Started

lib/protocol/url/absolute.rb

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,13 @@ module URL
1010
# Represents an absolute URL with scheme and/or authority.
1111
# Examples: "https://example.com/path", "//cdn.example.com/lib.js", "http://localhost/"
1212
class Absolute < Relative
13+
# Initialize a new absolute URL.
14+
#
15+
# @parameter scheme [String] The URL scheme (e.g., "https", "http").
16+
# @parameter authority [String] The authority component (e.g., "example.com", "user@host:port").
17+
# @parameter path [String] The path component (defaults to "/").
18+
# @parameter query [String, nil] The query string.
19+
# @parameter fragment [String, nil] The fragment identifier.
1320
def initialize(scheme, authority, path = "/", query = nil, fragment = nil)
1421
@scheme = scheme
1522
@authority = authority
@@ -18,13 +25,22 @@ def initialize(scheme, authority, path = "/", query = nil, fragment = nil)
1825
super(path, query, fragment)
1926
end
2027

28+
# @attribute [String] The URL scheme.
2129
attr :scheme
30+
31+
# @attribute [String] The authority component.
2232
attr :authority
2333

34+
# Check if the URL has a non-empty scheme.
35+
#
36+
# @returns [Boolean] True if a scheme is present and non-empty.
2437
def scheme?
2538
@scheme and !@scheme.empty?
2639
end
2740

41+
# Check if the URL has a non-empty authority.
42+
#
43+
# @returns [Boolean] True if an authority is present and non-empty.
2844
def authority?
2945
@authority and !@authority.empty?
3046
end
@@ -93,8 +109,6 @@ def append(buffer = String.new)
93109
super(buffer)
94110
end
95111

96-
UNSPECIFIED = Object.new
97-
98112
# Create a new Absolute URL with modified components.
99113
#
100114
# @parameter scheme [String, nil] The scheme to use (nil to remove scheme).
@@ -118,14 +132,24 @@ def with(scheme: @scheme, authority: @authority, path: nil, query: @query, fragm
118132
self.class.new(scheme, authority, Path.expand(@path, path, pop), query, fragment)
119133
end
120134

135+
# Convert the URL to an array representation.
136+
#
137+
# @returns [Array] An array of `[scheme, authority, path, query, fragment]`.
121138
def to_ary
122139
[@scheme, @authority, @path, @query, @fragment]
123140
end
124141

142+
# Compare this URL with another for sorting purposes.
143+
#
144+
# @parameter other [Absolute] The URL to compare with.
145+
# @returns [Integer] -1, 0, or 1 based on component-wise comparison.
125146
def <=>(other)
126147
to_ary <=> other.to_ary
127148
end
128149

150+
# Convert the URL to its string representation.
151+
#
152+
# @returns [String] The formatted absolute URL string.
129153
def to_s
130154
append
131155
end

lib/protocol/url/reference.rb

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,35 @@ module URL
1717
class Reference < Relative
1818
include Comparable
1919

20+
# Coerce a value into a {Reference} instance.
21+
#
22+
# This method provides flexible conversion from various types into a {Reference}.
23+
# When given a {String}, it parses the URL-encoded path, query, and fragment components
24+
# and unescapes them for internal storage. When given a {Relative}, it converts the
25+
# encoded values to unescaped form suitable for {Reference} instances.
26+
#
27+
# @parameter value [String | Relative | Nil] The value to coerce.
28+
# @parameter parameters [Hash | Nil] Optional user-supplied parameters to append to the query string.
29+
#
30+
# @returns [Reference | Nil] A new reference instance, or `nil` if the input is `nil`.
31+
#
32+
# @raises [ArgumentError] If the string contains whitespace or control characters.
33+
# @raises [ArgumentError] If the value cannot be coerced to a {Reference}.
34+
#
35+
# @example Coerce a string with path, query, and fragment.
36+
# reference = Reference["/search?q=ruby#results"]
37+
# reference.path # => "/search"
38+
# reference.query # => "q=ruby"
39+
# reference.fragment # => "results"
40+
#
41+
# @example Coerce with additional parameters.
42+
# reference = Reference["/search", {"limit" => "10"}]
43+
# reference.to_s # => "/search?limit=10"
44+
#
45+
# @example Coerce a Relative instance.
46+
# relative = Relative.new("/path%20with%20spaces", nil, "top")
47+
# reference = Reference[relative]
48+
# reference.path # => "/path with spaces"
2049
def self.[](value, parameters = nil)
2150
case value
2251
when String
@@ -25,7 +54,7 @@ def self.[](value, parameters = nil)
2554
query = match[:query]
2655
fragment = match[:fragment]
2756

28-
# Unescape path and fragment for user-friendly internal storage
57+
# Unescape path and fragment for user-friendly internal storage:
2958
# Query strings are kept as-is since they contain = and & syntax
3059
path = Encoding.unescape(path) if path && !path.empty?
3160
fragment = Encoding.unescape(fragment) if fragment
@@ -35,7 +64,7 @@ def self.[](value, parameters = nil)
3564
raise ArgumentError, "Invalid URL (contains whitespace or control characters): #{value.inspect}"
3665
end
3766
when Relative
38-
# Relative stores encoded values, so we need to unescape them for Reference
67+
# Relative stores encoded values, so we need to unescape them for Reference:
3968
path = value.path
4069
fragment = value.fragment
4170

lib/protocol/url/relative.rb

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,29 @@ module URL
1212
class Relative
1313
include Comparable
1414

15+
# Initialize a new relative URL.
16+
#
17+
# @parameter path [String] The path component.
18+
# @parameter query [String, nil] The query string.
19+
# @parameter fragment [String, nil] The fragment identifier.
1520
def initialize(path, query = nil, fragment = nil)
1621
@path = path.to_s
1722
@query = query
1823
@fragment = fragment
1924
end
2025

26+
# @attribute [String] The path component of the URL.
2127
attr :path
28+
29+
# @attribute [String, nil] The query string component.
2230
attr :query
31+
32+
# @attribute [String, nil] The fragment identifier.
2333
attr :fragment
2434

35+
# Convert the URL path to a local filesystem path.
36+
#
37+
# @returns [String] The local filesystem path.
2538
def to_local_path
2639
Path.to_local_path(@path)
2740
end
@@ -131,42 +144,76 @@ def append(buffer = String.new)
131144
return buffer
132145
end
133146

147+
# Convert the URL to an array representation.
148+
#
149+
# @returns [Array] An array of `[path, query, fragment]`.
134150
def to_ary
135151
[@path, @query, @fragment]
136152
end
137153

154+
# Compute a hash value for the URL based on its components.
155+
#
156+
# @returns [Integer] The hash value.
138157
def hash
139158
to_ary.hash
140159
end
141160

161+
# Check if this URL is equal to another URL by comparing components.
162+
#
163+
# @parameter other [Relative] The URL to compare with.
164+
# @returns [Boolean] True if the URLs have identical components.
142165
def equal?(other)
143166
to_ary == other.to_ary
144167
end
145168

169+
# Compare this URL with another for sorting purposes.
170+
#
171+
# @parameter other [Relative] The URL to compare with.
172+
# @returns [Integer] -1, 0, or 1 based on component-wise comparison.
146173
def <=>(other)
147174
to_ary <=> other.to_ary
148175
end
149176

177+
# Check structural equality by comparing components.
178+
#
179+
# @parameter other [Relative] The URL to compare with.
180+
# @returns [Boolean] True if the URLs have identical components.
150181
def ==(other)
151182
to_ary == other.to_ary
152183
end
153184

185+
# Check string equality, useful for case statements.
186+
#
187+
# @parameter other [String, Relative] The value to compare with.
188+
# @returns [Boolean] True if the string representations match.
154189
def ===(other)
155190
to_s === other
156191
end
157192

193+
# Convert the URL to its string representation.
194+
#
195+
# @returns [String] The formatted URL string.
158196
def to_s
159197
append
160198
end
161199

200+
# Convert the URL to a JSON-compatible representation.
201+
#
202+
# @returns [String] The URL as a string.
162203
def as_json(...)
163204
to_s
164205
end
165206

207+
# Convert the URL to JSON.
208+
#
209+
# @returns [String] The JSON-encoded URL.
166210
def to_json(...)
167211
as_json.to_json(...)
168212
end
169213

214+
# Generate a human-readable representation for debugging.
215+
#
216+
# @returns [String] A string like `#<Protocol::URL::Relative /path?query#fragment>`.
170217
def inspect
171218
"#<#{self.class} #{to_s}>"
172219
end

protocol-url.gemspec

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ Gem::Specification.new do |spec|
1717

1818
spec.metadata = {
1919
"source_code_uri" => "https://github.com/socketry/protocol-url.git",
20+
"documentation_uri" => "https://socketry.github.io/protocol-url/",
2021
}
2122

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

readme.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@ Provides abstractions for working with URLs.
66

77
## Usage
88

9-
Please see the [project documentation](https://github.com/socketry/protocol-url) for more details.
9+
Please see the [project documentation](https://socketry.github.io/protocol-url/) for more details.
1010

11-
- [Getting Started](https://github.com/socketry/protocol-urlguides/getting-started/index) - This guide explains how to get started with `protocol-url` for parsing, manipulating, and constructing URLs in Ruby.
11+
- [Getting Started](https://socketry.github.io/protocol-url/guides/getting-started/index) - This guide explains how to get started with `protocol-url` for parsing, manipulating, and constructing URLs in Ruby.
1212

13-
- [Working with References](https://github.com/socketry/protocol-urlguides/working-with-references/index) - This guide explains how to use <code class="language-ruby">Protocol::URL::Reference</code> for managing URLs with query parameters and fragments.
13+
- [Working with References](https://socketry.github.io/protocol-url/guides/working-with-references/index) - This guide explains how to use <code class="language-ruby">Protocol::URL::Reference</code> for managing URLs with query parameters and fragments.
1414

1515
## Contributing
1616

@@ -32,7 +32,7 @@ This project is best served by a collaborative and respectful environment. Treat
3232

3333
## Releases
3434

35-
Please see the [project releases](https://github.com/socketry/protocol-urlreleases/index) for all releases.
35+
Please see the [project releases](https://socketry.github.io/protocol-url/releases/index) for all releases.
3636

3737
### v0.4.0
3838

0 commit comments

Comments
 (0)