-
Notifications
You must be signed in to change notification settings - Fork 42
[OpenAPI] Validator Task #163
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
rsamoilov
merged 12 commits into
rage-rb:main
from
alex-rogachev:openapi-validation-task
Aug 12, 2026
Merged
Changes from all commits
Commits
Show all changes
12 commits
Select commit
Hold shift + click to select a range
14384de
Added thor task that builds openapi spec and returns errors if any
alex-rogachev e62337b
Moved openapi validation task from cli to tasks.rb
alex-rogachev f49f551
Use Rage.openapi instead of Rage::OpeAPI
alex-rogachev f5314fa
Removed unnecessary errors reset
alex-rogachev dfc9d09
Merge branch 'master' into openapi-validation-task
alex-rogachev d42cdd0
Merge branch 'master' into openapi-validation-task
alex-rogachev 74ecb30
Tests for the OpenAPI validator task
alex-rogachev 605c595
Removed warnings from the task output.
alex-rogachev 0e55d60
Merge branch 'master' into openapi-validation-task
alex-rogachev 9517876
Added CHANGELOG.md entry
alex-rogachev e3c675b
[OpenAPI] Scope openapi:validate warnings to a single build and rejec…
alex-rogachev 24b86a8
Tests cleanup
alex-rogachev File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| namespace :openapi do | ||
| desc "Validate OpenAPI tags and fail if any warnings were produced" | ||
| task :validate do | ||
| abort "OpenAPI validation requires a booted application." unless Rage.config.internal.initialized? | ||
|
|
||
| warnings = Rage::OpenAPI.__collect_warnings { Rage::OpenAPI.build } | ||
|
|
||
| if warnings.any? | ||
| abort "OpenAPI validation failed with #{warnings.size} warning(s)." | ||
| else | ||
| puts "OpenAPI validation passed without warnings." | ||
| end | ||
| end | ||
| end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,123 @@ | ||
| # frozen_string_literal: true | ||
|
|
||
| require "rake" | ||
| require "rage/tasks" | ||
|
|
||
| RSpec.describe Rage::Tasks do | ||
| # `Rake.application` is a process-wide singleton owning the task registry; a fresh one per example | ||
| # keeps the registry empty and tasks re-invokable, while restoring it avoids leaking into other specs. | ||
| around do |example| | ||
| original_application = Rake.application | ||
| Rake.application = Rake::Application.new | ||
| example.run | ||
| ensure | ||
| Rake.application = original_application | ||
| end | ||
|
|
||
| describe ".load_rage_tasks" do | ||
| it "loads the openapi:validate task" do | ||
| expect(Rake::Task.task_defined?("openapi:validate")).to eq(false) | ||
|
|
||
| described_class.send(:load_rage_tasks) | ||
|
|
||
| expect(Rake::Task.task_defined?("openapi:validate")).to eq(true) | ||
| end | ||
| end | ||
| end | ||
|
|
||
| RSpec.describe "openapi:validate" do | ||
| include_context "mocked_classes" | ||
| include_context "mocked_rage_routes" | ||
|
|
||
| around do |example| | ||
| original_application = Rake.application | ||
| Rake.application = Rake::Application.new | ||
| Rage::Tasks.send(:load_rage_tasks) | ||
| example.run | ||
| ensure | ||
| Rake.application = original_application | ||
| end | ||
|
|
||
| before do | ||
| allow(Rage.config.internal).to receive(:initialized?).and_return(true) | ||
| end | ||
|
|
||
| let(:routes) do | ||
| { "GET /users" => "UsersController#index" } | ||
| end | ||
|
|
||
| # returns the `SystemExit` error the task exited with, or `nil` if it didn't exit | ||
| subject(:invoke_task) do | ||
| Rake::Task["openapi:validate"].invoke | ||
| nil | ||
| rescue SystemExit => e | ||
| e | ||
| end | ||
|
|
||
| context "when the application is not booted" do | ||
| before do | ||
| allow(Rage.config.internal).to receive(:initialized?).and_return(false) | ||
| end | ||
|
|
||
| it "doesn't build the spec" do | ||
| expect(Rage::OpenAPI).not_to receive(:build) | ||
|
|
||
| expect { invoke_task }. | ||
| to output(/OpenAPI validation requires a booted application\./).to_stderr | ||
| end | ||
|
|
||
| it "exits with status 1" do | ||
| exit_error = nil | ||
|
|
||
| expect { exit_error = invoke_task }.to output.to_stderr | ||
|
|
||
| expect(exit_error.status).to eq(1) | ||
| end | ||
| end | ||
|
|
||
| context "when the spec builds without warnings" do | ||
| let_class("UsersController", parent: RageController::API) do | ||
| <<~'RUBY' | ||
| # @response { id: Integer, full_name: String } | ||
| def index | ||
| end | ||
| RUBY | ||
| end | ||
|
|
||
| it "prints a success message" do | ||
| expect { invoke_task }.to output(/OpenAPI validation passed without warnings\./).to_stdout | ||
| end | ||
|
|
||
| it "doesn't exit with an error" do | ||
| allow($stdout).to receive(:puts) | ||
|
|
||
| expect(invoke_task).to be_nil | ||
| end | ||
| end | ||
|
|
||
| context "when the build produces warnings" do | ||
| let_class("UsersController", parent: RageController::API) do | ||
| <<~'RUBY' | ||
| # @response UnknownResource | ||
| def index | ||
| end | ||
| RUBY | ||
| end | ||
|
|
||
| it "prints the warnings and the number of failures" do | ||
| expect { invoke_task }. | ||
| to output(/unrecognized `@response` tag detected/).to_stdout. | ||
| and output(/OpenAPI validation failed with 1 warning\(s\)\./).to_stderr | ||
| end | ||
|
|
||
| it "exits with status 1" do | ||
| allow($stdout).to receive(:puts) | ||
|
|
||
| exit_error = nil | ||
|
|
||
| expect { exit_error = invoke_task }.to output.to_stderr | ||
|
|
||
| expect(exit_error.status).to eq(1) | ||
| end | ||
| end | ||
| end |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hello @rsamoilov
What do you think about implementing the warnings accumulator as a wrapper around
Rage::OpenAPI.build? I feel like this approach works well because the additional logic doesn't add overhead to the original__log_warnimplementation and remains optional, which aligns with the idea that new features shouldn't affect performance for users who don't use them.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like the current approach, but I'm not entirely sure what a wrapper around
Rage::OpenAPI.buildwould look like.I've approved the PR and will be happy to merge it. Let me know if you'd like to rebuild it though.