w3c_api 0.1.4 → 0.1.5
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 +4 -4
- data/.rubocop.yml +16 -1
- data/.rubocop_todo.yml +20 -38
- data/README.adoc +51 -0
- data/Rakefile +3 -3
- data/demo/rate_limiting_demo.rb +135 -0
- data/demo/test_embed_functionality.rb +31 -30
- data/demo/test_improved_embed_functionality.rb +92 -0
- data/examples/rate_limiting_stress_test.rb +239 -0
- data/exe/w3c_api +1 -1
- data/lib/w3c_api/cli.rb +29 -28
- data/lib/w3c_api/client.rb +8 -7
- data/lib/w3c_api/commands/affiliation.rb +15 -12
- data/lib/w3c_api/commands/ecosystem.rb +22 -15
- data/lib/w3c_api/commands/group.rb +32 -25
- data/lib/w3c_api/commands/output_formatter.rb +1 -1
- data/lib/w3c_api/commands/participation.rb +11 -9
- data/lib/w3c_api/commands/series.rb +11 -9
- data/lib/w3c_api/commands/specification.rb +59 -45
- data/lib/w3c_api/commands/specification_version.rb +21 -12
- data/lib/w3c_api/commands/translation.rb +7 -6
- data/lib/w3c_api/commands/user.rb +36 -24
- data/lib/w3c_api/embed.rb +7 -7
- data/lib/w3c_api/hal.rb +168 -133
- data/lib/w3c_api/models/account.rb +3 -3
- data/lib/w3c_api/models/affiliation.rb +8 -7
- data/lib/w3c_api/models/affiliation_index.rb +3 -2
- data/lib/w3c_api/models/call_for_translation.rb +4 -3
- data/lib/w3c_api/models/chair_index.rb +2 -2
- data/lib/w3c_api/models/charter.rb +5 -5
- data/lib/w3c_api/models/charter_index.rb +3 -2
- data/lib/w3c_api/models/connected_account.rb +2 -2
- data/lib/w3c_api/models/deliverer_index.rb +3 -2
- data/lib/w3c_api/models/ecosystem.rb +8 -6
- data/lib/w3c_api/models/ecosystem_index.rb +3 -2
- data/lib/w3c_api/models/editor_index.rb +2 -2
- data/lib/w3c_api/models/evangelist_index.rb +3 -2
- data/lib/w3c_api/models/group.rb +16 -13
- data/lib/w3c_api/models/group_index.rb +2 -2
- data/lib/w3c_api/models/groups.rb +2 -2
- data/lib/w3c_api/models/participant_index.rb +3 -2
- data/lib/w3c_api/models/participation.rb +6 -5
- data/lib/w3c_api/models/participation_index.rb +3 -2
- data/lib/w3c_api/models/photo.rb +1 -1
- data/lib/w3c_api/models/serie.rb +6 -4
- data/lib/w3c_api/models/serie_index.rb +3 -2
- data/lib/w3c_api/models/spec_version.rb +10 -7
- data/lib/w3c_api/models/spec_version_index.rb +3 -2
- data/lib/w3c_api/models/spec_version_predecessor_index.rb +3 -2
- data/lib/w3c_api/models/spec_version_successor_index.rb +3 -2
- data/lib/w3c_api/models/specification.rb +17 -9
- data/lib/w3c_api/models/specification_index.rb +3 -2
- data/lib/w3c_api/models/team_contact_index.rb +3 -2
- data/lib/w3c_api/models/testimonial.rb +2 -2
- data/lib/w3c_api/models/translation.rb +4 -4
- data/lib/w3c_api/models/translation_index.rb +3 -2
- data/lib/w3c_api/models/user.rb +16 -11
- data/lib/w3c_api/models/user_index.rb +2 -2
- data/lib/w3c_api/models.rb +52 -37
- data/lib/w3c_api/version.rb +1 -1
- data/lib/w3c_api.rb +8 -8
- metadata +8 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a4dbcfdf9468b2cea332e93d7302cce5238e3530b231bccfa848f77ef4ca106d
|
4
|
+
data.tar.gz: d481729a09d328bc716b34b577957f60bc16dd2a8ff303c0cff9109fced13bcf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f7d6c35088901039ebfdf75f29e42c004ebe486e03fb9053e83e0599f33f8ae50c4b571097ce7cf63887b98d0fc7a4c4a1fbcacfb3a25d32b7a0b118a83b6fea
|
7
|
+
data.tar.gz: fbfcae8e668f7ccf48b8c355d7f6819f40acac18e0be02a706a926c6e6d74aaeef8b83f5a047fa3f02b7f70e6da831bc17ea05fb4cc4491db3095a9f813c54d9
|
data/.rubocop.yml
CHANGED
@@ -1 +1,16 @@
|
|
1
|
-
inherit_from:
|
1
|
+
inherit_from:
|
2
|
+
- .rubocop_todo.yml
|
3
|
+
- https://raw.githubusercontent.com/riboseinc/oss-guides/main/ci/rubocop.yml
|
4
|
+
|
5
|
+
Layout/LineLength:
|
6
|
+
Max: 180
|
7
|
+
|
8
|
+
Metrics/MethodLength:
|
9
|
+
Exclude:
|
10
|
+
- 'demo/test_embed_functionality.rb'
|
11
|
+
- 'lib/w3c_api/commands/specification.rb'
|
12
|
+
- 'lib/w3c_api/hal.rb'
|
13
|
+
|
14
|
+
Metrics/ParameterLists:
|
15
|
+
Exclude:
|
16
|
+
- 'lib/w3c_api/hal.rb'
|
data/.rubocop_todo.yml
CHANGED
@@ -1,56 +1,38 @@
|
|
1
1
|
# This configuration was generated by
|
2
2
|
# `rubocop --auto-gen-config`
|
3
|
-
# on 2025-07-
|
3
|
+
# on 2025-07-09 06:57:51 UTC using RuboCop version 1.78.0.
|
4
4
|
# The point is for the user to remove these configuration records
|
5
5
|
# one by one as the offenses are removed from the code base.
|
6
6
|
# Note that changes in the inspected code, or installation of new
|
7
7
|
# versions of RuboCop, may require this file to be generated again.
|
8
8
|
|
9
|
-
# Offense count:
|
10
|
-
#
|
11
|
-
Lint/ScriptPermission:
|
12
|
-
Exclude:
|
13
|
-
- 'demo/test_improved_embed_functionality.rb'
|
14
|
-
|
15
|
-
# Offense count: 2
|
16
|
-
# Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes.
|
9
|
+
# Offense count: 4
|
10
|
+
# Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes, Max.
|
17
11
|
Metrics/AbcSize:
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
Metrics/BlockLength:
|
24
|
-
Max: 370
|
12
|
+
Exclude:
|
13
|
+
- 'demo/test_embed_functionality.rb'
|
14
|
+
- 'lib/w3c_api/commands/group.rb'
|
15
|
+
- 'lib/w3c_api/commands/specification.rb'
|
16
|
+
- 'lib/w3c_api/hal.rb'
|
25
17
|
|
26
18
|
# Offense count: 1
|
27
|
-
# Configuration parameters:
|
28
|
-
Metrics/
|
29
|
-
|
30
|
-
|
31
|
-
# Offense count: 2
|
32
|
-
# Configuration parameters: CountComments, CountAsOne.
|
33
|
-
Metrics/ClassLength:
|
34
|
-
Max: 407
|
19
|
+
# Configuration parameters: AllowedMethods, AllowedPatterns, Max.
|
20
|
+
Metrics/CyclomaticComplexity:
|
21
|
+
Exclude:
|
22
|
+
- 'demo/test_embed_functionality.rb'
|
35
23
|
|
36
|
-
# Offense count:
|
24
|
+
# Offense count: 3
|
37
25
|
# Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns.
|
38
26
|
Metrics/MethodLength:
|
39
|
-
Max:
|
27
|
+
Max: 351
|
28
|
+
Exclude:
|
29
|
+
- 'demo/test_embed_functionality.rb'
|
30
|
+
- 'lib/w3c_api/commands/specification.rb'
|
31
|
+
- 'lib/w3c_api/hal.rb'
|
40
32
|
|
41
33
|
# Offense count: 1
|
42
34
|
# Configuration parameters: CountKeywordArgs, MaxOptionalParameters.
|
43
35
|
Metrics/ParameterLists:
|
44
36
|
Max: 6
|
45
|
-
|
46
|
-
|
47
|
-
# Configuration parameters: AllowedConstants.
|
48
|
-
Style/Documentation:
|
49
|
-
Enabled: false
|
50
|
-
|
51
|
-
# Offense count: 13
|
52
|
-
# This cop supports safe autocorrection (--autocorrect).
|
53
|
-
# Configuration parameters: AllowHeredoc, AllowURI, AllowQualifiedName, URISchemes, IgnoreCopDirectives, AllowedPatterns, SplitStrings.
|
54
|
-
# URISchemes: http, https
|
55
|
-
Layout/LineLength:
|
56
|
-
Max: 457
|
37
|
+
Exclude:
|
38
|
+
- 'lib/w3c_api/hal.rb'
|
data/README.adoc
CHANGED
@@ -17,6 +17,7 @@ https://github.com/lutaml/lutaml-model[lutaml-model]
|
|
17
17
|
for all W3C API resources
|
18
18
|
* HAL (Hypertext Application Language) implementation for recursive resource
|
19
19
|
traversal
|
20
|
+
* Built-in rate limiting with exponential backoff for reliable API access
|
20
21
|
* A command-line interface using Thor following GitHub CLI patterns
|
21
22
|
|
22
23
|
The endpoint supported is at https://api.w3.org.
|
@@ -72,6 +73,56 @@ from `lutaml-hal`, showing multiple levels of automatic link resolution.
|
|
72
73
|
|
73
74
|
== Ruby API
|
74
75
|
|
76
|
+
=== Rate limiting
|
77
|
+
|
78
|
+
The W3C API client includes built-in rate limiting with exponential backoff to handle API rate limits gracefully. Rate limiting is enabled by default and works transparently with all API operations.
|
79
|
+
|
80
|
+
==== Quick start
|
81
|
+
|
82
|
+
[source,ruby]
|
83
|
+
----
|
84
|
+
require 'w3c_api'
|
85
|
+
|
86
|
+
# Rate limiting is enabled by default
|
87
|
+
client = W3cApi::Client.new
|
88
|
+
|
89
|
+
# Configure rate limiting if needed
|
90
|
+
W3cApi::Hal.instance.configure_rate_limiting(
|
91
|
+
max_retries: 5, # Maximum retry attempts
|
92
|
+
base_delay: 1.0, # Initial delay in seconds
|
93
|
+
max_delay: 60.0, # Maximum delay cap
|
94
|
+
backoff_factor: 2.0 # Exponential backoff multiplier
|
95
|
+
)
|
96
|
+
|
97
|
+
# Make requests - rate limiting works automatically
|
98
|
+
specifications = client.specifications
|
99
|
+
----
|
100
|
+
|
101
|
+
==== Demo and examples
|
102
|
+
|
103
|
+
To see rate limiting in action, run the included demonstration scripts:
|
104
|
+
|
105
|
+
[source,shell]
|
106
|
+
----
|
107
|
+
# Basic rate limiting demo
|
108
|
+
$ ruby demo/rate_limiting_demo.rb
|
109
|
+
|
110
|
+
# Advanced stress testing and performance analysis
|
111
|
+
$ ruby examples/rate_limiting_stress_test.rb
|
112
|
+
----
|
113
|
+
|
114
|
+
The demo script shows:
|
115
|
+
* Default rate limiting configuration
|
116
|
+
* Custom configuration examples
|
117
|
+
* Enabling/disabling rate limiting
|
118
|
+
* Status checking
|
119
|
+
|
120
|
+
The stress test example demonstrates:
|
121
|
+
* Rapid sequential requests
|
122
|
+
* Cross-endpoint performance analysis
|
123
|
+
* Dynamic configuration changes
|
124
|
+
* Bulk operation patterns
|
125
|
+
|
75
126
|
=== Embed support with auto-realize
|
76
127
|
|
77
128
|
==== General
|
data/Rakefile
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
3
|
+
require "bundler/gem_tasks"
|
4
|
+
require "rspec/core/rake_task"
|
5
5
|
|
6
6
|
RSpec::Core::RakeTask.new(:spec)
|
7
7
|
|
8
|
-
require
|
8
|
+
require "rubocop/rake_task"
|
9
9
|
|
10
10
|
RuboCop::RakeTask.new
|
11
11
|
|
@@ -0,0 +1,135 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require_relative "../lib/w3c_api"
|
5
|
+
|
6
|
+
# Demo script to demonstrate rate limiting functionality
|
7
|
+
puts "W3C API Rate Limiting Demo"
|
8
|
+
puts "=" * 40
|
9
|
+
|
10
|
+
puts "\nThis demo shows how to use the built-in rate limiting features"
|
11
|
+
puts "of the W3C API client to handle API rate limits gracefully."
|
12
|
+
|
13
|
+
# Create a client instance
|
14
|
+
client = W3cApi::Client.new
|
15
|
+
|
16
|
+
# Demo 1: Default rate limiting (enabled by default)
|
17
|
+
puts "\n1. Default Rate Limiting Configuration:"
|
18
|
+
puts " - Max retries: 3"
|
19
|
+
puts " - Base delay: 1.0s"
|
20
|
+
puts " - Max delay: 60.0s"
|
21
|
+
puts " - Backoff factor: 2.0"
|
22
|
+
|
23
|
+
begin
|
24
|
+
start_time = Time.now
|
25
|
+
|
26
|
+
puts "\n Making API requests with default rate limiting..."
|
27
|
+
|
28
|
+
# Fetch specifications
|
29
|
+
specs = client.specifications(items: 3)
|
30
|
+
puts " ✓ Retrieved #{specs.links.specifications.length} specifications"
|
31
|
+
|
32
|
+
# Fetch a specific specification
|
33
|
+
spec_detail = client.specification("html5")
|
34
|
+
puts " ✓ Retrieved specification: #{spec_detail.title}"
|
35
|
+
|
36
|
+
end_time = Time.now
|
37
|
+
puts " ⏱️ Total time: #{(end_time - start_time).round(2)}s"
|
38
|
+
rescue StandardError => e
|
39
|
+
puts " ✗ Error: #{e.message}"
|
40
|
+
end
|
41
|
+
|
42
|
+
# Demo 2: Custom rate limiting configuration
|
43
|
+
puts "\n2. Custom Rate Limiting Configuration:"
|
44
|
+
puts " Configuring more aggressive rate limiting for APIs with strict limits"
|
45
|
+
|
46
|
+
begin
|
47
|
+
# Configure custom rate limiting
|
48
|
+
W3cApi::Hal.instance.configure_rate_limiting(
|
49
|
+
max_retries: 5, # More retry attempts
|
50
|
+
base_delay: 0.5, # Shorter initial delay
|
51
|
+
max_delay: 30.0, # Lower maximum delay
|
52
|
+
backoff_factor: 1.5, # Gentler backoff
|
53
|
+
)
|
54
|
+
|
55
|
+
puts " ✓ Rate limiting reconfigured"
|
56
|
+
|
57
|
+
start_time = Time.now
|
58
|
+
|
59
|
+
# Make requests with custom configuration
|
60
|
+
groups = client.groups(items: 3)
|
61
|
+
puts " ✓ Retrieved #{groups.links.groups.length} groups"
|
62
|
+
|
63
|
+
end_time = Time.now
|
64
|
+
puts " ⏱️ Total time: #{(end_time - start_time).round(2)}s"
|
65
|
+
rescue StandardError => e
|
66
|
+
puts " ✗ Error: #{e.message}"
|
67
|
+
end
|
68
|
+
|
69
|
+
# Demo 3: Temporarily disable rate limiting
|
70
|
+
puts "\n3. Temporarily Disabling Rate Limiting:"
|
71
|
+
puts " Useful for bulk operations where you control the rate manually"
|
72
|
+
|
73
|
+
begin
|
74
|
+
# Disable rate limiting
|
75
|
+
W3cApi::Hal.instance.disable_rate_limiting
|
76
|
+
puts " ✓ Rate limiting disabled"
|
77
|
+
|
78
|
+
start_time = Time.now
|
79
|
+
|
80
|
+
# Make requests without rate limiting
|
81
|
+
series = client.series(items: 3)
|
82
|
+
puts " ✓ Retrieved #{series.links.series.length} series"
|
83
|
+
|
84
|
+
end_time = Time.now
|
85
|
+
puts " ⏱️ Total time: #{(end_time - start_time).round(2)}s"
|
86
|
+
rescue StandardError => e
|
87
|
+
puts " ✗ Error: #{e.message}"
|
88
|
+
end
|
89
|
+
|
90
|
+
# Demo 4: Re-enable rate limiting
|
91
|
+
puts "\n4. Re-enabling Rate Limiting:"
|
92
|
+
|
93
|
+
begin
|
94
|
+
# Re-enable rate limiting with default settings
|
95
|
+
W3cApi::Hal.instance.enable_rate_limiting
|
96
|
+
puts " ✓ Rate limiting re-enabled with default settings"
|
97
|
+
|
98
|
+
start_time = Time.now
|
99
|
+
|
100
|
+
ecosystems = client.ecosystems
|
101
|
+
puts " ✓ Retrieved #{ecosystems.links.ecosystems.length} ecosystems"
|
102
|
+
|
103
|
+
end_time = Time.now
|
104
|
+
puts " ⏱️ Total time: #{(end_time - start_time).round(2)}s"
|
105
|
+
rescue StandardError => e
|
106
|
+
puts " ✗ Error: #{e.message}"
|
107
|
+
end
|
108
|
+
|
109
|
+
# Demo 5: Check rate limiting status
|
110
|
+
puts "\n5. Checking Rate Limiting Status:"
|
111
|
+
|
112
|
+
if W3cApi::Hal.instance.rate_limiting_enabled?
|
113
|
+
puts " ✓ Rate limiting is currently ENABLED"
|
114
|
+
else
|
115
|
+
puts " ⚠️ Rate limiting is currently DISABLED"
|
116
|
+
end
|
117
|
+
|
118
|
+
puts "\n#{'=' * 40}"
|
119
|
+
puts "Rate Limiting Demo Completed! 🎉"
|
120
|
+
|
121
|
+
puts "\n📚 Key Takeaways:"
|
122
|
+
puts "• Rate limiting is enabled by default for reliable API access"
|
123
|
+
puts "• You can customize retry behavior for different API requirements"
|
124
|
+
puts "• Rate limiting can be temporarily disabled for bulk operations"
|
125
|
+
puts "• The system automatically handles 429 and 5xx errors with exponential backoff"
|
126
|
+
puts "• Retry-After headers from the server are automatically respected"
|
127
|
+
|
128
|
+
puts "\n🔧 Common Use Cases:"
|
129
|
+
puts "• Default settings work well for most applications"
|
130
|
+
puts "• Increase max_retries for critical operations"
|
131
|
+
puts "• Decrease delays for APIs with generous rate limits"
|
132
|
+
puts "• Disable temporarily for bulk data processing"
|
133
|
+
|
134
|
+
puts "\n📖 For more information, see the rate limiting documentation"
|
135
|
+
puts " in the lutaml-hal library or the W3C API documentation."
|
@@ -1,11 +1,29 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
-
require
|
5
|
-
require_relative
|
4
|
+
require "bundler/setup"
|
5
|
+
require_relative "lib/w3c_api"
|
6
6
|
|
7
|
-
|
8
|
-
|
7
|
+
def test_link_realization(groups_with_embed)
|
8
|
+
return unless groups_with_embed.respond_to?(:links) && groups_with_embed.links.respond_to?(:groups)
|
9
|
+
|
10
|
+
first_group_link = groups_with_embed.links.groups.first
|
11
|
+
return unless first_group_link
|
12
|
+
|
13
|
+
puts " First group link: #{first_group_link.href}"
|
14
|
+
return unless first_group_link.respond_to?(:realize)
|
15
|
+
|
16
|
+
begin
|
17
|
+
realized_group = first_group_link.realize(parent_resource: groups_with_embed)
|
18
|
+
puts " ✓ Link realization with embedded data successful"
|
19
|
+
puts " Realized group name: #{realized_group.name if realized_group.respond_to?(:name)}"
|
20
|
+
rescue StandardError => e
|
21
|
+
puts " ⚠ Link realization failed: #{e.message}"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
puts "Testing W3C API Embed Functionality"
|
26
|
+
puts "=" * 40
|
9
27
|
|
10
28
|
# Initialize the client
|
11
29
|
client = W3cApi::Client.new
|
@@ -17,10 +35,10 @@ begin
|
|
17
35
|
puts " Response type: #{groups_with_embed.class}"
|
18
36
|
puts " Has embedded content: #{groups_with_embed.respond_to?(:has_embedded?) && groups_with_embed.has_embedded?('groups')}"
|
19
37
|
|
20
|
-
if groups_with_embed.respond_to?(:has_embedded?) && groups_with_embed.has_embedded?(
|
38
|
+
if groups_with_embed.respond_to?(:has_embedded?) && groups_with_embed.has_embedded?("groups")
|
21
39
|
puts " Available methods: #{groups_with_embed.methods.grep(/embed/).join(', ')}"
|
22
40
|
|
23
|
-
embedded_groups = groups_with_embed.get_embedded(
|
41
|
+
embedded_groups = groups_with_embed.get_embedded("groups")
|
24
42
|
puts " Number of embedded groups: #{embedded_groups.length}"
|
25
43
|
puts " First embedded group: #{embedded_groups.first['name'] if embedded_groups.first}"
|
26
44
|
end
|
@@ -31,10 +49,10 @@ begin
|
|
31
49
|
puts " Response type: #{specs_with_embed.class}"
|
32
50
|
puts " Has embedded content: #{specs_with_embed.respond_to?(:has_embedded?) && specs_with_embed.has_embedded?('specifications')}"
|
33
51
|
|
34
|
-
if specs_with_embed.respond_to?(:has_embedded?) && specs_with_embed.has_embedded?(
|
52
|
+
if specs_with_embed.respond_to?(:has_embedded?) && specs_with_embed.has_embedded?("specifications")
|
35
53
|
puts " Available methods: #{specs_with_embed.methods.grep(/embed/).join(', ')}"
|
36
54
|
|
37
|
-
embedded_specs = specs_with_embed.get_embedded(
|
55
|
+
embedded_specs = specs_with_embed.get_embedded("specifications")
|
38
56
|
puts " Number of embedded specifications: #{embedded_specs.length}"
|
39
57
|
puts " First embedded spec: #{embedded_specs.first['title'] if embedded_specs.first}"
|
40
58
|
end
|
@@ -53,35 +71,18 @@ begin
|
|
53
71
|
with_embed_time = Time.now - start_time
|
54
72
|
puts " With embed: #{with_embed_time.round(3)}s"
|
55
73
|
|
56
|
-
if groups_with_embed.respond_to?(:has_embedded?) && groups_with_embed.has_embedded?(
|
57
|
-
puts
|
74
|
+
if groups_with_embed.respond_to?(:has_embedded?) && groups_with_embed.has_embedded?("groups")
|
75
|
+
puts " ✓ Embed functionality working correctly!"
|
58
76
|
else
|
59
|
-
puts
|
77
|
+
puts " ⚠ Embed parameter accepted but no embedded content returned"
|
60
78
|
end
|
61
79
|
|
62
80
|
puts "\n4. Testing link realization with embedded content..."
|
63
|
-
|
64
|
-
if groups_with_embed.respond_to?(:links) && groups_with_embed.links.respond_to?(:groups)
|
65
|
-
first_group_link = groups_with_embed.links.groups.first
|
66
|
-
if first_group_link
|
67
|
-
puts " First group link: #{first_group_link.href}"
|
68
|
-
|
69
|
-
# Test realization with parent_resource (should use embedded data)
|
70
|
-
if first_group_link.respond_to?(:realize)
|
71
|
-
begin
|
72
|
-
realized_group = first_group_link.realize(parent_resource: groups_with_embed)
|
73
|
-
puts ' ✓ Link realization with embedded data successful'
|
74
|
-
puts " Realized group name: #{realized_group.name if realized_group.respond_to?(:name)}"
|
75
|
-
rescue StandardError => e
|
76
|
-
puts " ⚠ Link realization failed: #{e.message}"
|
77
|
-
end
|
78
|
-
end
|
79
|
-
end
|
80
|
-
end
|
81
|
+
test_link_realization(groups_with_embed)
|
81
82
|
|
82
83
|
puts "\n✅ Embed functionality test completed successfully!"
|
83
84
|
rescue StandardError => e
|
84
85
|
puts "\n❌ Error during testing: #{e.message}"
|
85
|
-
puts
|
86
|
+
puts "Backtrace:"
|
86
87
|
puts e.backtrace.first(5).join("\n")
|
87
88
|
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require "stringio"
|
5
|
+
require_relative "../lib/w3c_api"
|
6
|
+
|
7
|
+
puts "=== W3C API Improved Embed Functionality Demo ==="
|
8
|
+
puts
|
9
|
+
|
10
|
+
# Test 1: List embed-supported endpoints
|
11
|
+
puts "1. Testing embed-supported endpoints discovery:"
|
12
|
+
supported_endpoints = W3cApi::Client.embed_supported_endpoints
|
13
|
+
puts " Embed-supported endpoints: #{supported_endpoints.join(', ')}"
|
14
|
+
puts
|
15
|
+
|
16
|
+
# Test 2: Check specific endpoint support
|
17
|
+
puts "2. Testing specific endpoint embed support:"
|
18
|
+
client = W3cApi::Client.new
|
19
|
+
puts " specifications supports embed: #{client.embed_supported?(:specification_index)}"
|
20
|
+
puts " groups supports embed: #{client.embed_supported?(:group_index)}"
|
21
|
+
puts " series supports embed: #{client.embed_supported?(:serie_index)}"
|
22
|
+
puts " specification_resource supports embed: #{client.embed_supported?(:specification_resource)}"
|
23
|
+
puts
|
24
|
+
|
25
|
+
# Test 3: Get embed information
|
26
|
+
puts "3. Testing embed information:"
|
27
|
+
embed_info = W3cApi::Embed.embed_info
|
28
|
+
puts " Supported endpoints: #{embed_info[:supported_endpoints].join(', ')}"
|
29
|
+
puts " Discovery: #{embed_info[:usage_example][:discovery]}"
|
30
|
+
puts " Usage: #{embed_info[:usage_example][:usage]}"
|
31
|
+
puts " Automatic realization: #{embed_info[:usage_example][:automatic_realization]}"
|
32
|
+
puts
|
33
|
+
|
34
|
+
# Test 4: Use Client methods with embed
|
35
|
+
puts "4. Testing Client methods with embed parameter:"
|
36
|
+
begin
|
37
|
+
puts " Fetching specifications with embed=true..."
|
38
|
+
specs = client.specifications(embed: true, items: 2)
|
39
|
+
puts " ✓ Successfully fetched #{specs.class}"
|
40
|
+
|
41
|
+
if specs.respond_to?(:embedded_data) && specs.embedded_data
|
42
|
+
puts " ✓ Has embedded data: #{specs.embedded_data.keys.join(', ')}"
|
43
|
+
else
|
44
|
+
puts " ⚠ No embedded data found"
|
45
|
+
end
|
46
|
+
|
47
|
+
# Test automatic embedded content detection
|
48
|
+
if specs.links.respond_to?(:specifications) && specs.links.specifications.any?
|
49
|
+
puts " Testing automatic embedded content detection..."
|
50
|
+
first_spec_link = specs.links.specifications.first
|
51
|
+
|
52
|
+
begin
|
53
|
+
# This should automatically use embedded content without parent_resource parameter
|
54
|
+
spec = first_spec_link.realize
|
55
|
+
puts " ✓ Successfully realized specification automatically"
|
56
|
+
puts " ✓ Specification class: #{spec.class}"
|
57
|
+
puts " ✓ Specification title: #{spec.title}" if spec.respond_to?(:title)
|
58
|
+
rescue StandardError => e
|
59
|
+
puts " ✗ Error realizing specification: #{e.message}"
|
60
|
+
end
|
61
|
+
end
|
62
|
+
rescue StandardError => e
|
63
|
+
puts " ✗ Error: #{e.message}"
|
64
|
+
end
|
65
|
+
puts
|
66
|
+
|
67
|
+
# Test 5: Test Embed module information methods
|
68
|
+
puts "5. Testing Embed module information methods:"
|
69
|
+
begin
|
70
|
+
puts " Testing supported_endpoints method..."
|
71
|
+
supported = W3cApi::Embed.supported_endpoints
|
72
|
+
puts " ✓ Supported endpoints: #{supported.join(', ')}"
|
73
|
+
|
74
|
+
puts " Testing supports_embed? method..."
|
75
|
+
puts " ✓ specifications supports embed: #{W3cApi::Embed.supports_embed?(:specification_index)}"
|
76
|
+
puts " ✓ groups supports embed: #{W3cApi::Embed.supports_embed?(:group_index)}"
|
77
|
+
|
78
|
+
puts " Testing endpoint_descriptions method..."
|
79
|
+
descriptions = W3cApi::Embed.endpoint_descriptions
|
80
|
+
puts " ✓ Available descriptions: #{descriptions.keys.join(', ')}"
|
81
|
+
rescue StandardError => e
|
82
|
+
puts " ✗ Error: #{e.message}"
|
83
|
+
end
|
84
|
+
puts
|
85
|
+
|
86
|
+
puts "=== Demo completed ==="
|
87
|
+
puts "Summary of improvements:"
|
88
|
+
puts "• ✓ Added embed-supported endpoints discovery methods"
|
89
|
+
puts "• ✓ Client methods now support embed parameter directly"
|
90
|
+
puts "• ✓ Automatic embedded content detection (no parent_resource needed)"
|
91
|
+
puts "• ✓ Enhanced Embed module with information methods"
|
92
|
+
puts "• ✓ Removed deprecated code for cleaner API"
|