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.
Files changed (62) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +16 -1
  3. data/.rubocop_todo.yml +20 -38
  4. data/README.adoc +51 -0
  5. data/Rakefile +3 -3
  6. data/demo/rate_limiting_demo.rb +135 -0
  7. data/demo/test_embed_functionality.rb +31 -30
  8. data/demo/test_improved_embed_functionality.rb +92 -0
  9. data/examples/rate_limiting_stress_test.rb +239 -0
  10. data/exe/w3c_api +1 -1
  11. data/lib/w3c_api/cli.rb +29 -28
  12. data/lib/w3c_api/client.rb +8 -7
  13. data/lib/w3c_api/commands/affiliation.rb +15 -12
  14. data/lib/w3c_api/commands/ecosystem.rb +22 -15
  15. data/lib/w3c_api/commands/group.rb +32 -25
  16. data/lib/w3c_api/commands/output_formatter.rb +1 -1
  17. data/lib/w3c_api/commands/participation.rb +11 -9
  18. data/lib/w3c_api/commands/series.rb +11 -9
  19. data/lib/w3c_api/commands/specification.rb +59 -45
  20. data/lib/w3c_api/commands/specification_version.rb +21 -12
  21. data/lib/w3c_api/commands/translation.rb +7 -6
  22. data/lib/w3c_api/commands/user.rb +36 -24
  23. data/lib/w3c_api/embed.rb +7 -7
  24. data/lib/w3c_api/hal.rb +168 -133
  25. data/lib/w3c_api/models/account.rb +3 -3
  26. data/lib/w3c_api/models/affiliation.rb +8 -7
  27. data/lib/w3c_api/models/affiliation_index.rb +3 -2
  28. data/lib/w3c_api/models/call_for_translation.rb +4 -3
  29. data/lib/w3c_api/models/chair_index.rb +2 -2
  30. data/lib/w3c_api/models/charter.rb +5 -5
  31. data/lib/w3c_api/models/charter_index.rb +3 -2
  32. data/lib/w3c_api/models/connected_account.rb +2 -2
  33. data/lib/w3c_api/models/deliverer_index.rb +3 -2
  34. data/lib/w3c_api/models/ecosystem.rb +8 -6
  35. data/lib/w3c_api/models/ecosystem_index.rb +3 -2
  36. data/lib/w3c_api/models/editor_index.rb +2 -2
  37. data/lib/w3c_api/models/evangelist_index.rb +3 -2
  38. data/lib/w3c_api/models/group.rb +16 -13
  39. data/lib/w3c_api/models/group_index.rb +2 -2
  40. data/lib/w3c_api/models/groups.rb +2 -2
  41. data/lib/w3c_api/models/participant_index.rb +3 -2
  42. data/lib/w3c_api/models/participation.rb +6 -5
  43. data/lib/w3c_api/models/participation_index.rb +3 -2
  44. data/lib/w3c_api/models/photo.rb +1 -1
  45. data/lib/w3c_api/models/serie.rb +6 -4
  46. data/lib/w3c_api/models/serie_index.rb +3 -2
  47. data/lib/w3c_api/models/spec_version.rb +10 -7
  48. data/lib/w3c_api/models/spec_version_index.rb +3 -2
  49. data/lib/w3c_api/models/spec_version_predecessor_index.rb +3 -2
  50. data/lib/w3c_api/models/spec_version_successor_index.rb +3 -2
  51. data/lib/w3c_api/models/specification.rb +17 -9
  52. data/lib/w3c_api/models/specification_index.rb +3 -2
  53. data/lib/w3c_api/models/team_contact_index.rb +3 -2
  54. data/lib/w3c_api/models/testimonial.rb +2 -2
  55. data/lib/w3c_api/models/translation.rb +4 -4
  56. data/lib/w3c_api/models/translation_index.rb +3 -2
  57. data/lib/w3c_api/models/user.rb +16 -11
  58. data/lib/w3c_api/models/user_index.rb +2 -2
  59. data/lib/w3c_api/models.rb +52 -37
  60. data/lib/w3c_api/version.rb +1 -1
  61. data/lib/w3c_api.rb +8 -8
  62. metadata +8 -5
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7c02121c87a6a5fc2c0f6c5c3f64a8c9fc559dd462819b38a4a5a08e18a2fec6
4
- data.tar.gz: 722806176722df8e4d8ee75cf6af95ceb0f9fbb629d89fc7b70cd93366f03d97
3
+ metadata.gz: a4dbcfdf9468b2cea332e93d7302cce5238e3530b231bccfa848f77ef4ca106d
4
+ data.tar.gz: d481729a09d328bc716b34b577957f60bc16dd2a8ff303c0cff9109fced13bcf
5
5
  SHA512:
6
- metadata.gz: b89d639121544a8212b3b13489cb537cf83b4ccb99c7b85cacacc38697f9d60a03d574bb6ece148f076840213ae5d07aac5b5e913daa9d0efc64b355d98c60f6
7
- data.tar.gz: 3e180168c74b46b140328aae3736573e668f3653c4fa96196acf0a0b410aab8a0d8c66de784d479fe5c94b986d95bec5bec2b6297da5598d10e03e8028083fc0
6
+ metadata.gz: f7d6c35088901039ebfdf75f29e42c004ebe486e03fb9053e83e0599f33f8ae50c4b571097ce7cf63887b98d0fc7a4c4a1fbcacfb3a25d32b7a0b118a83b6fea
7
+ data.tar.gz: fbfcae8e668f7ccf48b8c355d7f6819f40acac18e0be02a706a926c6e6d74aaeef8b83f5a047fa3f02b7f70e6da831bc17ea05fb4cc4491db3095a9f813c54d9
data/.rubocop.yml CHANGED
@@ -1 +1,16 @@
1
- inherit_from: .rubocop_todo.yml
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-08 17:28:03 UTC using RuboCop version 1.78.0.
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: 1
10
- # This cop supports safe autocorrection (--autocorrect).
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
- Max: 121
19
-
20
- # Offense count: 51
21
- # Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns.
22
- # AllowedMethods: refine
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: CountBlocks, CountModifierForms.
28
- Metrics/BlockNesting:
29
- Max: 4
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: 2
24
+ # Offense count: 3
37
25
  # Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns.
38
26
  Metrics/MethodLength:
39
- Max: 339
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
- # Offense count: 32
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 'bundler/gem_tasks'
4
- require 'rspec/core/rake_task'
3
+ require "bundler/gem_tasks"
4
+ require "rspec/core/rake_task"
5
5
 
6
6
  RSpec::Core::RakeTask.new(:spec)
7
7
 
8
- require 'rubocop/rake_task'
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 'bundler/setup'
5
- require_relative 'lib/w3c_api'
4
+ require "bundler/setup"
5
+ require_relative "lib/w3c_api"
6
6
 
7
- puts 'Testing W3C API Embed Functionality'
8
- puts '=' * 40
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?('groups')
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('groups')
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?('specifications')
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('specifications')
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?('groups')
57
- puts ' ✓ Embed functionality working correctly!'
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 ' ⚠ Embed parameter accepted but no embedded content returned'
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 'Backtrace:'
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"