Skip to content

Conversation

@okuramasafumi
Copy link
Owner

@okuramasafumi okuramasafumi commented Jun 20, 2025

Ref: #440

Summary by CodeRabbit

  • New Features

    • Introduced JSON Schema generation for resources, including support for traits, associations, nested attributes, key transformations, and recursive definitions.
    • Added Rake tasks to generate schemas for all resources or a specific resource, with configurable output and a combined definitions file.
    • Enabled automatic loading of Alba-related Rake tasks.
  • Tests

    • Added comprehensive test suites covering core behavior, edge cases (circular references, custom types, deep nesting), and Rake task functionality.

The content of this commit is created by Claude Code with Claude 4
Sonnet. This commit message is written by human (me).
@okuramasafumi okuramasafumi requested a review from Copilot June 20, 2025 14:22
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR adds a feature to generate JSON Schema output for Alba resources. Key changes include:

  • New tests covering various resource schema generation scenarios.
  • Rake tasks for generating individual and combined JSON schemas.
  • Implementation of a JSON schema generator in the Alba module.

Reviewed Changes

Copilot reviewed 6 out of 8 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
test/rake_tasks_test.rb Introduces tests for schema filename generation and task handling.
test/json_schema_test.rb Adds comprehensive tests for different resource types and schema settings.
lib/tasks/alba.rake Defines rake tasks for generating JSON schemas for Alba resources.
lib/alba/json_schema.rb Implements JSON schema generation logic with support for associations, traits, and nested attributes.
lib/alba.rb Loads the JSON schema module.
Rakefile Loads the Alba rake tasks.

end

def transform_key(key)
return key.to_s unless @resource_class._transform_type != :none
Copy link

Copilot AI Jun 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] The condition 'return key.to_s unless @resource_class._transform_type != :none' uses a double negative that may be confusing. Consider rewriting it as 'return key.to_s if @resource_class._transform_type == :none' for clarity.

Suggested change
return key.to_s unless @resource_class._transform_type != :none
return key.to_s if @resource_class._transform_type == :none

Copilot uses AI. Check for mistakes.

def property_for_nested_attribute(nested_attr)
# Create a temporary resource class to evaluate the nested block
temp_class = Alba.resource_class
Copy link

Copilot AI Jun 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] For consistency with trait processing, consider using 'Class.new' to create a temporary class for evaluating the nested attribute block rather than relying on 'Alba.resource_class', which might be ambiguous.

Suggested change
temp_class = Alba.resource_class
temp_class = Class.new

Copilot uses AI. Check for mistakes.
@codecov
Copy link

codecov bot commented Jun 20, 2025

Codecov Report

❌ Patch coverage is 77.67442% with 48 lines in your changes missing coverage. Please review.
✅ Project coverage is 92.71%. Comparing base (5a5b81f) to head (a8e2bfe).
⚠️ Report is 58 commits behind head on main.

Files with missing lines Patch % Lines
lib/tasks/alba.rake 36.36% 42 Missing ⚠️
lib/alba/json_schema.rb 95.94% 6 Missing ⚠️

❌ Your patch check has failed because the patch coverage (77.67%) is below the target coverage (90.00%). You can increase the patch coverage or adjust the target coverage.

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #443      +/-   ##
==========================================
- Coverage   97.53%   92.71%   -4.83%     
==========================================
  Files          14       16       +2     
  Lines         650      865     +215     
  Branches      171      231      +60     
==========================================
+ Hits          634      802     +168     
- Misses         16       63      +47     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@okuramasafumi
Copy link
Owner Author

@coderabbitai full review

@coderabbitai
Copy link

coderabbitai bot commented Oct 12, 2025

✅ Actions performed

Full review triggered.

@coderabbitai
Copy link

coderabbitai bot commented Oct 12, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

Adds JSON Schema generation for Alba resources via a new Alba::JSONSchema class, integrates it into the library load path, and introduces Rake tasks to generate per-resource and combined schemas. The Rakefile now auto-loads tasks from lib/tasks. Extensive tests cover core, complex, and edge-case behaviors.

Changes

Cohort / File(s) Summary
Task loading in Rake
Rakefile
Loads all .rake files under lib/tasks early, enabling Alba Rake tasks without manual requires.
Library entrypoint update
lib/alba.rb
Requires alba/json_schema, wiring JSON Schema support into the main library load path.
JSON Schema generator
lib/alba/json_schema.rb
Introduces Alba::JSONSchema with class/instance generation APIs. Builds JSON Schemas for resources, handling attributes, typed attributes, associations, nested attributes, traits, key transforms, root key wrapping, and recursive $defs with cycle protection.
Rake tasks for schemas
lib/tasks/alba.rake
Adds alba:generate_schemas (discover all resources, emit per-resource and combined schemas) and alba:generate_schema[ResourceName]. Includes helpers: resource discovery, filename generation, combined schema assembly. Uses ENV['OUTPUT_DIR'].
Core tests
test/json_schema_test.rb
Tests base behaviors: simple/nested resources, traits, key transforms, root key, custom types, computed attributes, required fields, titles/descriptions, and $defs presence.
Complex/edge-case tests
test/json_schema_complex_test.rb, test/json_schema_edge_cases_test.rb
Validates complex associations, recursive refs, traits, deeply nested structures, conditional attrs, custom inflectors/types, proc-based associations, symbol/string keys, empty blocks, nil associations, helpers, and anonymous resources.
Rake task tests
test/rake_tasks_test.rb
Verifies task presence, helper behaviors (filename generation, resource discovery, combined schema), and task loading isolation.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor Dev as Developer
  participant AR as Alba::Resource subclass
  participant JS as Alba::JSONSchema
  participant Gen as Generator Instance
  participant Defs as $defs Registry

  Dev->>JS: .generate(AR, **options)
  JS->>Gen: new(AR, **options)
  JS->>Gen: generate
  Gen->>Gen: build base schema ($schema, type: object)
  Gen->>AR: read attributes/associations/traits
  alt Attributes
    Gen->>Gen: map types (string/integer/number/boolean/array)
  end
  alt Associations
    Gen->>Defs: add_resource_definition(target)
    Note over Defs: Prevent cycles via processing Set
    Gen->>Gen: add $ref to definition
  end
  alt Nested attributes
    Gen->>Gen: evaluate nested block into properties
  end
  opt Root key wrapping
    Gen->>Gen: wrap properties under root key
  end
  Gen-->>JS: schema hash
  JS-->>Dev: JSON Schema
Loading
sequenceDiagram
  autonumber
  actor Dev as Developer
  participant R as Rake
  participant T as alba:generate_schemas
  participant OS as ObjectSpace
  participant JS as Alba::JSONSchema
  participant FS as File System

  Dev->>R: rake alba:generate_schemas
  R->>T: invoke
  T->>OS: find_alba_resources
  loop each resource
    T->>JS: generate(resource)
    JS-->>T: schema
    T->>FS: write schemas/<name>.json
    Note over T,FS: Continue on per-resource errors
  end
  T->>T: generate_combined_schema(resources)
  T->>FS: write schemas/combined.json
  T-->>R: done
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Poem

I thump my paw at schema dawn,
Arrays and objects neatly drawn.
With $defs burrowed, refs that loop,
I dodge the cycles, hop the hoop.
Rake bells ring, the files align—
JSON meadows, crisp and fine.
Carrot-typed, the keys all shine. 🥕✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 2.94% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title succinctly identifies the primary change—adding JSON Schema output support to Alba—without unrelated noise or vague phrasing. It is concise, clearly reflects the main goal of the changeset, and should be understandable to reviewers scanning the history.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch json-schema

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5a5b81f and a8e2bfe.

📒 Files selected for processing (8)
  • Rakefile (1 hunks)
  • lib/alba.rb (1 hunks)
  • lib/alba/json_schema.rb (1 hunks)
  • lib/tasks/alba.rake (1 hunks)
  • test/json_schema_complex_test.rb (1 hunks)
  • test/json_schema_edge_cases_test.rb (1 hunks)
  • test/json_schema_test.rb (1 hunks)
  • test/rake_tasks_test.rb (1 hunks)
🧰 Additional context used
🪛 GitHub Check: codecov/patch
lib/tasks/alba.rake

[warning] 8-8: lib/tasks/alba.rake#L8
Added line #L8 was not covered by tests


[warning] 10-11: lib/tasks/alba.rake#L10-L11
Added lines #L10 - L11 were not covered by tests


[warning] 14-14: lib/tasks/alba.rake#L14
Added line #L14 was not covered by tests


[warning] 18-18: lib/tasks/alba.rake#L18
Added line #L18 was not covered by tests


[warning] 21-21: lib/tasks/alba.rake#L21
Added line #L21 was not covered by tests


[warning] 23-23: lib/tasks/alba.rake#L23
Added line #L23 was not covered by tests


[warning] 25-26: lib/tasks/alba.rake#L25-L26
Added lines #L25 - L26 were not covered by tests


[warning] 28-29: lib/tasks/alba.rake#L28-L29
Added lines #L28 - L29 were not covered by tests


[warning] 31-31: lib/tasks/alba.rake#L31
Added line #L31 was not covered by tests


[warning] 33-33: lib/tasks/alba.rake#L33
Added line #L33 was not covered by tests


[warning] 39-42: lib/tasks/alba.rake#L39-L42
Added lines #L39 - L42 were not covered by tests


[warning] 44-44: lib/tasks/alba.rake#L44
Added line #L44 was not covered by tests


[warning] 47-47: lib/tasks/alba.rake#L47
Added line #L47 was not covered by tests


[warning] 52-52: lib/tasks/alba.rake#L52
Added line #L52 was not covered by tests


[warning] 54-54: lib/tasks/alba.rake#L54
Added line #L54 was not covered by tests


[warning] 58-59: lib/tasks/alba.rake#L58-L59
Added lines #L58 - L59 were not covered by tests


[warning] 63-63: lib/tasks/alba.rake#L63
Added line #L63 was not covered by tests


[warning] 67-67: lib/tasks/alba.rake#L67
Added line #L67 was not covered by tests


[warning] 70-71: lib/tasks/alba.rake#L70-L71
Added lines #L70 - L71 were not covered by tests


[warning] 73-74: lib/tasks/alba.rake#L73-L74
Added lines #L73 - L74 were not covered by tests


[warning] 76-77: lib/tasks/alba.rake#L76-L77
Added lines #L76 - L77 were not covered by tests


[warning] 79-79: lib/tasks/alba.rake#L79
Added line #L79 was not covered by tests


[warning] 81-81: lib/tasks/alba.rake#L81
Added line #L81 was not covered by tests


[warning] 83-83: lib/tasks/alba.rake#L83
Added line #L83 was not covered by tests


[warning] 100-100: lib/tasks/alba.rake#L100
Added line #L100 was not covered by tests


[warning] 103-103: lib/tasks/alba.rake#L103
Added line #L103 was not covered by tests


[warning] 110-110: lib/tasks/alba.rake#L110
Added line #L110 was not covered by tests


[warning] 112-112: lib/tasks/alba.rake#L112
Added line #L112 was not covered by tests


[warning] 114-114: lib/tasks/alba.rake#L114
Added line #L114 was not covered by tests

lib/alba/json_schema.rb

[warning] 156-157: lib/alba/json_schema.rb#L156-L157
Added lines #L156 - L157 were not covered by tests

Comment on lines +117 to +138
type = typed_attr.instance_variable_get(:@type)
type_name = type&.name

if type_name == String
schema['type'] = 'string'
elsif type_name == Integer
schema['type'] = 'integer'
elsif type_name == :Boolean
schema['type'] = 'boolean'
elsif type_name == Float
schema['type'] = 'number'
elsif type_name.to_s =~ /\AArrayOf(.+)\z/
element_type = Regexp.last_match(1).downcase
schema = {
'type' => 'array',
'items' => { 'type' => element_type }
}
else
# Custom type or unknown type
schema['type'] = 'string'
schema['description'] = "Custom type: #{type_name}"
end
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Fix typed attribute handling for symbols.

type&.name blows up when the underlying type is a Symbol (e.g., :Boolean), so schema generation currently raises NoMethodError as soon as we hit :Boolean attributes like published in ArticleResource. Even when it doesn’t raise, the comparisons against String/Integer never match because type&.name returns a String, so we silently fall back to the “Custom type” branch and emit the wrong schema. Please normalize the type up front (fall back to type.to_s when name is unavailable) and branch on the normalized string so primitives such as String, Integer, Float, Boolean, and ArrayOf* map to the correct JSON Schema types.

Apply this diff:

-      type = typed_attr.instance_variable_get(:@type)
-      type_name = type&.name
-
-      if type_name == String
-        schema['type'] = 'string'
-      elsif type_name == Integer
-        schema['type'] = 'integer'
-      elsif type_name == :Boolean
-        schema['type'] = 'boolean'
-      elsif type_name == Float
-        schema['type'] = 'number'
-      elsif type_name.to_s =~ /\AArrayOf(.+)\z/
-        element_type = Regexp.last_match(1).downcase
-        schema = {
-          'type' => 'array',
-          'items' => { 'type' => element_type }
-        }
-      else
-        # Custom type or unknown type
-        schema['type'] = 'string'
-        schema['description'] = "Custom type: #{type_name}"
-      end
+      type = typed_attr.instance_variable_get(:@type)
+      type_name =
+        if type.respond_to?(:name) && type.name
+          type.name
+        else
+          type.to_s
+        end
+
+      case type_name
+      when 'String'
+        schema['type'] = 'string'
+      when 'Integer'
+        schema['type'] = 'integer'
+      when 'Float'
+        schema['type'] = 'number'
+      when 'Boolean', ':Boolean', 'TrueClass', 'FalseClass'
+        schema['type'] = 'boolean'
+      when /\AArrayOf(.+)\z/
+        element = Regexp.last_match(1).downcase
+        element = 'number' if element == 'float'
+        schema = {
+          'type' => 'array',
+          'items' => { 'type' => element }
+        }
+      else
+        schema['type'] = 'string'
+        schema['description'] = "Custom type: #{type_name}"
+      end
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
type = typed_attr.instance_variable_get(:@type)
type_name = type&.name
if type_name == String
schema['type'] = 'string'
elsif type_name == Integer
schema['type'] = 'integer'
elsif type_name == :Boolean
schema['type'] = 'boolean'
elsif type_name == Float
schema['type'] = 'number'
elsif type_name.to_s =~ /\AArrayOf(.+)\z/
element_type = Regexp.last_match(1).downcase
schema = {
'type' => 'array',
'items' => { 'type' => element_type }
}
else
# Custom type or unknown type
schema['type'] = 'string'
schema['description'] = "Custom type: #{type_name}"
end
type = typed_attr.instance_variable_get(:@type)
type_name =
if type.respond_to?(:name) && type.name
type.name
else
type.to_s
end
case type_name
when 'String'
schema['type'] = 'string'
when 'Integer'
schema['type'] = 'integer'
when 'Float'
schema['type'] = 'number'
when 'Boolean', ':Boolean', 'TrueClass', 'FalseClass'
schema['type'] = 'boolean'
when /\AArrayOf(.+)\z/
element = Regexp.last_match(1).downcase
element = 'number' if element == 'float'
schema = {
'type' => 'array',
'items' => { 'type' => element }
}
else
schema['type'] = 'string'
schema['description'] = "Custom type: #{type_name}"
end
🤖 Prompt for AI Agents
In lib/alba/json_schema.rb around lines 117 to 138, normalize the detected type
before branching: set type_name to type.name.to_s when available, otherwise to
type.to_s, then use that normalized string for comparisons (e.g. compare against
"String", "Integer", "Float", "Boolean") and detect arrays with a
case-insensitive regex like /\AArrayOf(.+)\z/i so Symbol types (e.g. :Boolean)
and String-returning names are handled consistently and map to the correct JSON
Schema types.

Comment on lines +253 to +300
def generate_definition_name(resource_class)
return resource_class.to_s if resource_class.is_a?(String)

name = if resource_class.respond_to?(:name) && resource_class.name
resource_class.name
else
'AnonymousResource'
end

# Remove namespacing and common suffixes
name = name.split('::').last if name.include?('::')
name.gsub(/Resource$|Serializer$/, '')
end

def add_resource_definition(name, resource_class)
return if @definitions.key?(name)
return unless resource_class.respond_to?(:_attributes)

# Check if we're already processing this resource to prevent infinite recursion
resource_key = resource_class.object_id
return if @processing.include?(resource_key)

# Mark this resource as being processed
@processing.add(resource_key)

# Add a placeholder to prevent infinite recursion in self-references
@definitions[name] = { 'type' => 'object', 'properties' => {} }

# Generate schema for the referenced resource with shared definitions
options = @options.reject { |k, _| [:title, :description].include?(k) }
options[:_definitions] = @definitions
options[:_processing] = @processing

definition_generator = self.class.new(resource_class, **options)
definition_schema = definition_generator.generate

# Remove the $schema key from definition
definition_schema.delete('$schema')

# Merge any nested definitions into our main definitions hash
if definition_schema['$defs']
@definitions.merge!(definition_schema['$defs'])
definition_schema.delete('$defs')
end

# Replace the placeholder with the actual schema
@definitions[name] = definition_schema

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Prevent $defs collisions for anonymous resources.

generate_definition_name returns the literal "AnonymousResource" whenever the resource class lacks a name, so every inline association (e.g., simple_association vs. collection_items in JSONSchemaEdgeCasesTest) shares the same $defs/AnonymousResource. The second association therefore short-circuits add_resource_definition, and both references point to the first schema, silently dropping fields like value. Please make the fallback name unique—using the class’ object_id is enough—so each anonymous resource gets its own definition.

Apply this diff:

-      name = if resource_class.respond_to?(:name) && resource_class.name
-               resource_class.name
-             else
-               'AnonymousResource'
-             end
-
-      # Remove namespacing and common suffixes
-      name = name.split('::').last if name.include?('::')
-      name.gsub(/Resource$|Serializer$/, '')
+      if resource_class.respond_to?(:name) && resource_class.name && !resource_class.name.empty?
+        name = resource_class.name.split('::').last
+        return name.gsub(/Resource$|Serializer$/, '')
+      end
+
+      "AnonymousResource#{resource_class.object_id}"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
def generate_definition_name(resource_class)
return resource_class.to_s if resource_class.is_a?(String)
name = if resource_class.respond_to?(:name) && resource_class.name
resource_class.name
else
'AnonymousResource'
end
# Remove namespacing and common suffixes
name = name.split('::').last if name.include?('::')
name.gsub(/Resource$|Serializer$/, '')
end
def add_resource_definition(name, resource_class)
return if @definitions.key?(name)
return unless resource_class.respond_to?(:_attributes)
# Check if we're already processing this resource to prevent infinite recursion
resource_key = resource_class.object_id
return if @processing.include?(resource_key)
# Mark this resource as being processed
@processing.add(resource_key)
# Add a placeholder to prevent infinite recursion in self-references
@definitions[name] = { 'type' => 'object', 'properties' => {} }
# Generate schema for the referenced resource with shared definitions
options = @options.reject { |k, _| [:title, :description].include?(k) }
options[:_definitions] = @definitions
options[:_processing] = @processing
definition_generator = self.class.new(resource_class, **options)
definition_schema = definition_generator.generate
# Remove the $schema key from definition
definition_schema.delete('$schema')
# Merge any nested definitions into our main definitions hash
if definition_schema['$defs']
@definitions.merge!(definition_schema['$defs'])
definition_schema.delete('$defs')
end
# Replace the placeholder with the actual schema
@definitions[name] = definition_schema
def generate_definition_name(resource_class)
return resource_class.to_s if resource_class.is_a?(String)
if resource_class.respond_to?(:name) && resource_class.name && !resource_class.name.empty?
name = resource_class.name.split('::').last
return name.gsub(/Resource$|Serializer$/, '')
end
"AnonymousResource#{resource_class.object_id}"
end
🤖 Prompt for AI Agents
In lib/alba/json_schema.rb around lines 253 to 300, generate_definition_name
currently returns the literal "AnonymousResource" for unnamed classes which
causes $defs name collisions for multiple anonymous resources; change the
fallback to produce a unique name (for example "AnonymousResource_<object_id>"
or include resource_class.object_id) so each anonymous resource gets its own
definition, and ensure any code that relies on the returned name continues to
work (no behavior changes other than uniqueness).

Comment on lines +100 to +107
name = resource_class.name

# Convert CamelCase to snake_case and remove common suffixes
name.gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
.gsub(/([a-z\d])([A-Z])/, '\1_\2')
.downcase
.gsub(/_resource$|_serializer$/, '')
end
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Handle namespaced resource names when building filenames

generate_schema_filename leaves Ruby namespace separators (::) intact (e.g., Admin::UserResourceadmin::user). On Windows this results in invalid filenames due to the colon, and even on UNIX it creates awkward names that break combined-schema $defs titles. Replace namespace separators up front (e.g., name = resource_class.name.gsub('::', '_')) before the snake_case conversion so generated files and definition titles are portable.

Apply this diff:

-    name = resource_class.name
+    name = resource_class.name.gsub('::', '_')
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
name = resource_class.name
# Convert CamelCase to snake_case and remove common suffixes
name.gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
.gsub(/([a-z\d])([A-Z])/, '\1_\2')
.downcase
.gsub(/_resource$|_serializer$/, '')
end
name = resource_class.name.gsub('::', '_')
# Convert CamelCase to snake_case and remove common suffixes
name.gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
.gsub(/([a-z\d])([A-Z])/, '\1_\2')
.downcase
.gsub(/_resource$|_serializer$/, '')
end
🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 100-100: lib/tasks/alba.rake#L100
Added line #L100 was not covered by tests


[warning] 103-103: lib/tasks/alba.rake#L103
Added line #L103 was not covered by tests

🤖 Prompt for AI Agents
In lib/tasks/alba.rake around lines 100 to 107, generate_schema_filename
currently preserves Ruby namespace separators (::) which yields invalid or
awkward filenames/titles; update the method to replace namespace separators up
front (e.g., set name = resource_class.name.gsub('::', '_')) before performing
the CamelCase→snake_case and suffix removal so generated filenames and $defs
titles are portable across platforms and free of colons.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants