Skip to content

Commit

Permalink
Introduce suspenders:accessibility generator (#1137)
Browse files Browse the repository at this point in the history
Ported over from #1105

Installs [capybara_accessibility_audit] and
[capybara_accessible_selectors].

`./bin/rails g suspenders:accessibility`

Introduces `Suspenders::Generators::APIAppUnsupported` module for
generators that cannot be run in an [API only][] application.

This uses a [concern][] to ensure we raise an error before the generator
including the module invokes any of its methods.

[capybara_accessibility_audit]: https://github.com/thoughtbot/capybara_accessibility_audit
[capybara_accessible_selectors]: https://github.com/citizensadvice/capybara_accessible_selectors
[API only]: https://guides.rubyonrails.org/api_app.html
[concern]: https://api.rubyonrails.org/classes/ActiveSupport/Concern.html
  • Loading branch information
stevepolitodesign committed May 10, 2024
1 parent 65ca6b0 commit 0bd31c9
Show file tree
Hide file tree
Showing 8 changed files with 189 additions and 1 deletion.
2 changes: 2 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
Unreleased

* Remove `suspenders` system executable
* Introduce `suspenders:accessibility` generator
* Introduce `Suspenders::Generators::APIAppUnsupported` module and concern

20230113.0 (January, 13, 2023)

Expand Down
9 changes: 8 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,14 @@ end

## Generators

TODO
### Accessibility

Installs [capybara_accessibility_audit] and [capybara_accessible_selectors]

`./bin/rails g suspenders:accessibility`

[capybara_accessibility_audit]: https://github.com/thoughtbot/capybara_accessibility_audit
[capybara_accessible_selectors]: https://github.com/citizensadvice/capybara_accessible_selectors

## Contributing

Expand Down
17 changes: 17 additions & 0 deletions lib/generators/suspenders/accessibility_generator.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
module Suspenders
module Generators
class AccessibilityGenerator < Rails::Generators::Base
include Suspenders::Generators::APIAppUnsupported

desc "Installs capybara_accessibility_audit and capybara_accessible_selectors"

def add_capybara_gems
gem_group :test do
gem "capybara_accessibility_audit"
gem "capybara_accessible_selectors", github: "citizensadvice/capybara_accessible_selectors"
end
Bundler.with_unbundled_env { run "bundle install" }
end
end
end
end
1 change: 1 addition & 0 deletions lib/suspenders.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
require "suspenders/version"
require "suspenders/railtie"
require "suspenders/generators"

module Suspenders
# Your code goes here...
Expand Down
30 changes: 30 additions & 0 deletions lib/suspenders/generators.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
require "active_support/concern"

module Suspenders
module Generators
module APIAppUnsupported
class Error < StandardError
def message
"This generator cannot be used on API only applications."
end
end

extend ActiveSupport::Concern

included do
def raise_if_api_only_app
if api_only_app?
raise Suspenders::Generators::APIAppUnsupported::Error
end
end
end

private

def api_only_app?
File.read(Rails.root.join("config/application.rb"))
.match?(/^\s*config\.api_only\s*=\s*true/i)
end
end
end
end
83 changes: 83 additions & 0 deletions test/generators/suspenders/accessibility_generator_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
require "test_helper"
require "generators/suspenders/accessibility_generator"

module Suspenders
module Generators
class AccessibilityGeneratorTest < Rails::Generators::TestCase
include Suspenders::TestHelpers

tests Suspenders::Generators::AccessibilityGenerator
destination Rails.root
setup :prepare_destination
teardown :restore_destination

test "raises if API only application" do
within_api_only_app do
assert_raises Suspenders::Generators::APIAppUnsupported::Error do
run_generator
end

assert_file app_root("Gemfile") do |file|
assert_no_match "capybara_accessibility_audit", file
assert_no_match "capybara_accessible_selectors", file
end
end
end

test "does not raise if API configuration is commented out" do
within_api_only_app do
path = app_root("config/application.rb")
content = File.binread(path).gsub!("config.api_only = true", "# config.api_only = true")
File.binwrite(path, content)

run_generator

assert_file app_root("Gemfile") do |file|
assert_match "capybara_accessibility_audit", file
assert_match "capybara_accessible_selectors", file
end
end
end

test "adds gems to Gemfile" do
expected_output = <<~RUBY
group :test do
gem "capybara_accessibility_audit"
gem "capybara_accessible_selectors", github: "citizensadvice/capybara_accessible_selectors"
end
RUBY

run_generator

assert_file app_root("Gemfile") do |file|
assert_match(expected_output, file)
end
end

test "installs gems with Bundler" do
Bundler.stubs(:with_unbundled_env).yields
generator.expects(:run).with("bundle install").once

capture(:stdout) do
generator.add_capybara_gems
end
end

test "generator has a description" do
description = "Installs capybara_accessibility_audit and capybara_accessible_selectors"

assert_equal description, Suspenders::Generators::AccessibilityGenerator.desc
end

private

def prepare_destination
touch "Gemfile"
end

def restore_destination
remove_file_if_exists "Gemfile"
end
end
end
end
11 changes: 11 additions & 0 deletions test/suspenders/generators_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
require "test_helper"

class Suspenders::GeneratorsTest < ActiveSupport::TestCase
class APIAppUnsupportedTest < Suspenders::GeneratorsTest
test "message returns a custom message" do
expected = "This generator cannot be used on API only applications."

assert_equal expected, Suspenders::Generators::APIAppUnsupported::Error.new.message
end
end
end
37 changes: 37 additions & 0 deletions test/test_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,41 @@ def touch(file)

FileUtils.touch path
end

def within_api_only_app(&block)
backup_file "config/application.rb"
application_config = <<~RUBY
require_relative "boot"
require "rails/all"
Bundler.require(*Rails.groups)
module Dummy
class Application < Rails::Application
config.load_defaults 7.1
config.autoload_lib(ignore: %w(assets tasks))
config.api_only = true
end
end
RUBY
File.open(app_root("config/application.rb"), "w") { _1.write application_config }

yield
ensure
restore_file "config/application.rb"
end

private

def backup_file(file)
FileUtils.mv app_root(file), app_root("#{file}.bak")
touch file
end

def restore_file(file)
remove_file_if_exists(file)
FileUtils.mv app_root("#{file}.bak"), app_root(file)
end
end

0 comments on commit 0bd31c9

Please sign in to comment.