From 994ff45d40d7fb411c3aa207a0e429ac74a740c0 Mon Sep 17 00:00:00 2001 From: Steve Polito Date: Thu, 11 Dec 2025 06:20:52 -0500 Subject: [PATCH 1/5] Re-introduce system executable Similar to the last rewrite, we generate a new gem and do a directory swap, while making sure to preserve important files like NEWS.md. This branch will serve as a new base for us to merge into while we build up an [application template][template]. This approach is largely inspired by [staples][]. [template]: https://guides.rubyonrails.org/generators.html#application-templates [staples]: https://github.com/stevepolitodesign/staples --- .github/workflows/main.yml | 86 ++++++-- .gitignore | 14 +- .rspec | 3 + .standard.yml | 8 +- CONTRIBUTING.md | 22 +- Gemfile | 13 +- Gemfile.lock | 192 ++-------------- NEWS.md | 2 + README.md | 107 +++------ Rakefile | 19 +- bin/console | 11 + bin/rails | 14 -- bin/setup | 3 + bin/test | 5 - exe/suspenders | 24 ++ .../suspenders/accessibility_generator.rb | 24 -- .../suspenders/advisories_generator.rb | 32 --- lib/generators/suspenders/ci_generator.rb | 54 ----- lib/generators/suspenders/email_generator.rb | 56 ----- .../environments/development_generator.rb | 50 ----- .../environments/production_generator.rb | 27 --- .../suspenders/environments/test_generator.rb | 39 ---- .../suspenders/factories_generator.rb | 64 ------ .../suspenders/inline_svg_generator.rb | 24 -- .../suspenders/install/web_generator.rb | 85 ------- lib/generators/suspenders/jobs_generator.rb | 34 --- lib/generators/suspenders/lint_generator.rb | 94 -------- .../suspenders/prerequisites_generator.rb | 19 -- lib/generators/suspenders/rake_generator.rb | 25 --- lib/generators/suspenders/setup_generator.rb | 14 -- lib/generators/suspenders/styles_generator.rb | 84 ------- lib/generators/suspenders/tasks_generator.rb | 20 -- .../suspenders/testing_generator.rb | 113 ---------- lib/generators/suspenders/views_generator.rb | 38 ---- lib/generators/templates/ci/ci.yml.tt | 148 ------------- .../templates/email/email_interceptor.rb | 11 - .../templates/factories/factories.rb | 2 - .../templates/factories/factories_spec.rb | 7 - .../templates/factories/factories_test.rb | 9 - .../templates/factories/factory_bot_rspec.rb | 5 - .../templates/inline_svg/inline_svg.rb | 3 - .../templates/install/web/CONTRIBUTING.md | 94 -------- .../templates/lint/config_better_html.yml | 2 - .../lint/config_initializers_better_html.rb | 9 - lib/generators/templates/lint/erb-lint.yml | 63 ------ lib/generators/templates/lint/erblint.rake | 47 ---- lib/generators/templates/lint/eslintrc.json | 7 - lib/generators/templates/lint/package.json | 4 - lib/generators/templates/lint/prettierignore | 1 - lib/generators/templates/lint/prettierrc | 11 - lib/generators/templates/lint/rubocop.yml.tt | 7 - .../templates/lint/stylelintrc.json | 3 - .../templates/prerequisites/node-version.tt | 1 - lib/generators/templates/setup/bin_setup.rb | 39 ---- .../templates/styles/postcss.config.js | 11 - lib/generators/templates/tasks/dev.rake | 12 - .../templates/testing/action_mailer.rb | 5 - lib/generators/templates/testing/driver.rb | 5 - lib/generators/templates/testing/i18n.rb | 3 - .../templates/testing/shoulda_matchers.rb | 6 - .../templates/views/flashes.html.erb | 7 - lib/install/web.rb | 70 ------ lib/suspenders.rb | 11 +- lib/suspenders/cleanup/generate_readme.rb | 165 -------------- lib/suspenders/cleanup/organize_gemfile.rb | 134 ------------ lib/suspenders/cli.rb | 45 ++++ lib/suspenders/engine.rb | 5 - lib/suspenders/generators.rb | 126 ----------- lib/suspenders/railtie.rb | 4 - lib/suspenders/version.rb | 8 +- lib/tasks/suspenders.rake | 37 ---- lib/templates/web.rb | 32 +++ sig/suspenders.rbs | 4 + spec/spec_helper.rb | 15 ++ spec/suspenders_spec.rb | 89 ++++++++ suspenders.gemspec | 17 +- test/dummy/Rakefile | 6 - test/dummy/app/assets/images/.keep | 0 .../app/assets/stylesheets/application.css | 1 - .../app/channels/application_cable/channel.rb | 4 - .../channels/application_cable/connection.rb | 4 - .../app/controllers/application_controller.rb | 2 - test/dummy/app/controllers/concerns/.keep | 0 test/dummy/app/helpers/application_helper.rb | 2 - test/dummy/app/jobs/application_job.rb | 7 - test/dummy/app/mailers/application_mailer.rb | 4 - test/dummy/app/models/application_record.rb | 3 - test/dummy/app/models/concerns/.keep | 0 .../app/views/layouts/application.html.erb | 15 -- test/dummy/app/views/layouts/mailer.html.erb | 13 -- test/dummy/app/views/layouts/mailer.text.erb | 1 - test/dummy/bin/dev | 2 - test/dummy/bin/rails | 4 - test/dummy/bin/rake | 4 - test/dummy/bin/rubocop | 8 - test/dummy/bin/setup | 34 --- test/dummy/bin/thrust | 5 - test/dummy/config.ru | 6 - test/dummy/config/application.rb | 26 --- test/dummy/config/boot.rb | 4 - test/dummy/config/cable.yml | 10 - test/dummy/config/database.yml | 25 --- test/dummy/config/environment.rb | 5 - test/dummy/config/environments/development.rb | 72 ------ test/dummy/config/environments/production.rb | 89 -------- test/dummy/config/environments/test.rb | 53 ----- .../initializers/content_security_policy.rb | 25 --- .../initializers/filter_parameter_logging.rb | 8 - test/dummy/config/initializers/inflections.rb | 16 -- .../new_framework_defaults_8_0.rb | 30 --- .../config/initializers/permissions_policy.rb | 13 -- test/dummy/config/locales/en.yml | 31 --- test/dummy/config/puma.rb | 41 ---- test/dummy/config/routes.rb | 10 - test/dummy/config/storage.yml | 34 --- ..._to_active_storage_blobs.active_storage.rb | 22 -- ..._storage_variant_records.active_storage.rb | 28 --- ...e_storage_blobs_checksum.active_storage.rb | 8 - test/dummy/db/schema.rb | 14 -- test/dummy/lib/assets/.keep | 0 test/dummy/log/.keep | 0 test/dummy/public/400.html | 114 ---------- test/dummy/public/404.html | 114 ---------- .../dummy/public/406-unsupported-browser.html | 114 ---------- test/dummy/public/422.html | 114 ---------- test/dummy/public/500.html | 114 ---------- .../public/apple-touch-icon-precomposed.png | 0 test/dummy/public/apple-touch-icon.png | 0 test/dummy/public/favicon.ico | 0 test/dummy/public/icon.png | Bin 4166 -> 0 bytes test/dummy/public/icon.svg | 3 - test/dummy/public/robots.txt | 1 - test/dummy/storage/.keep | 0 test/dummy/tmp/.keep | 0 test/dummy/tmp/pids/.keep | 0 test/dummy/tmp/storage/.keep | 0 test/fixtures/files/Rakefile | 10 - test/fixtures/files/Rakefile_advisories | 8 - test/fixtures/files/_flashes.html.erb | 7 - test/fixtures/files/action_mailer.rb | 5 - test/fixtures/files/better_html.rb | 9 - test/fixtures/files/driver.rb | 5 - test/fixtures/files/email_interceptor.rb | 11 - .../files/email_interceptor_initializer.rb | 5 - .../files/environments/development.rb | 2 - .../fixtures/files/environments/production.rb | 2 - test/fixtures/files/environments/test.rb | 2 - test/fixtures/files/erb-lint.yml | 63 ------ test/fixtures/files/eslintrc.json | 7 - test/fixtures/files/factories.rb | 2 - test/fixtures/files/factories_spec_lint.rb | 7 - test/fixtures/files/factories_test_lint.rb | 9 - test/fixtures/files/gemfile_clean | 85 ------- test/fixtures/files/gemfile_messy | 101 --------- test/fixtures/files/i18n.rb | 3 - test/fixtures/files/inline_svg.rb | 3 - test/fixtures/files/postcss.config.js | 11 - test/fixtures/files/prettierignore | 1 - test/fixtures/files/prettierrc.json | 11 - test/fixtures/files/rails_helper.rb | 21 -- test/fixtures/files/shoulda_matchers.rb | 6 - test/fixtures/files/spec_helper.rb | 23 -- test/fixtures/files/stylelintrc.json | 3 - test/fixtures/files/test_helper.rb | 15 -- .../accessibility_generator_test.rb | 70 ------ .../suspenders/advisories_generator_test.rb | 62 ------ .../suspenders/ci_generator_test.rb | 41 ---- .../suspenders/email_generator_test.rb | 69 ------ .../development_generator_test.rb | 95 -------- .../environments/production_generator_test.rb | 47 ---- .../environments/test_generator_test.rb | 69 ------ .../suspenders/factories_generator_test.rb | 173 --------------- .../suspenders/inline_svg_generator_test.rb | 76 ------- .../suspenders/install/web_generator_test.rb | 63 ------ .../suspenders/jobs_generator_test.rb | 83 ------- .../suspenders/lint_generator_test.rb | 207 ------------------ .../prerequisites_generator_test.rb | 61 ------ .../suspenders/rake_generator_test.rb | 37 ---- .../suspenders/setup_generator_test.rb | 39 ---- .../suspenders/styles_generator_test.rb | 139 ------------ .../suspenders/tasks_generator_test.rb | 43 ---- .../suspenders/testing_generator_test.rb | 140 ------------ .../suspenders/views_generator_test.rb | 100 --------- .../cleanup/generate_readme_test.rb | 80 ------- .../cleanup/organize_gemfile_test.rb | 23 -- test/suspenders/generators_test.rb | 35 --- test/suspenders_test.rb | 19 -- test/test_helper.rb | 122 ----------- 188 files changed, 390 insertions(+), 5906 deletions(-) create mode 100644 .rspec create mode 100755 bin/console delete mode 100755 bin/rails delete mode 100755 bin/test create mode 100755 exe/suspenders delete mode 100644 lib/generators/suspenders/accessibility_generator.rb delete mode 100644 lib/generators/suspenders/advisories_generator.rb delete mode 100644 lib/generators/suspenders/ci_generator.rb delete mode 100644 lib/generators/suspenders/email_generator.rb delete mode 100644 lib/generators/suspenders/environments/development_generator.rb delete mode 100644 lib/generators/suspenders/environments/production_generator.rb delete mode 100644 lib/generators/suspenders/environments/test_generator.rb delete mode 100644 lib/generators/suspenders/factories_generator.rb delete mode 100644 lib/generators/suspenders/inline_svg_generator.rb delete mode 100644 lib/generators/suspenders/install/web_generator.rb delete mode 100644 lib/generators/suspenders/jobs_generator.rb delete mode 100644 lib/generators/suspenders/lint_generator.rb delete mode 100644 lib/generators/suspenders/prerequisites_generator.rb delete mode 100644 lib/generators/suspenders/rake_generator.rb delete mode 100644 lib/generators/suspenders/setup_generator.rb delete mode 100644 lib/generators/suspenders/styles_generator.rb delete mode 100644 lib/generators/suspenders/tasks_generator.rb delete mode 100644 lib/generators/suspenders/testing_generator.rb delete mode 100644 lib/generators/suspenders/views_generator.rb delete mode 100644 lib/generators/templates/ci/ci.yml.tt delete mode 100644 lib/generators/templates/email/email_interceptor.rb delete mode 100644 lib/generators/templates/factories/factories.rb delete mode 100644 lib/generators/templates/factories/factories_spec.rb delete mode 100644 lib/generators/templates/factories/factories_test.rb delete mode 100644 lib/generators/templates/factories/factory_bot_rspec.rb delete mode 100644 lib/generators/templates/inline_svg/inline_svg.rb delete mode 100644 lib/generators/templates/install/web/CONTRIBUTING.md delete mode 100644 lib/generators/templates/lint/config_better_html.yml delete mode 100644 lib/generators/templates/lint/config_initializers_better_html.rb delete mode 100644 lib/generators/templates/lint/erb-lint.yml delete mode 100644 lib/generators/templates/lint/erblint.rake delete mode 100644 lib/generators/templates/lint/eslintrc.json delete mode 100644 lib/generators/templates/lint/package.json delete mode 100644 lib/generators/templates/lint/prettierignore delete mode 100644 lib/generators/templates/lint/prettierrc delete mode 100644 lib/generators/templates/lint/rubocop.yml.tt delete mode 100644 lib/generators/templates/lint/stylelintrc.json delete mode 100644 lib/generators/templates/prerequisites/node-version.tt delete mode 100755 lib/generators/templates/setup/bin_setup.rb delete mode 100644 lib/generators/templates/styles/postcss.config.js delete mode 100644 lib/generators/templates/tasks/dev.rake delete mode 100644 lib/generators/templates/testing/action_mailer.rb delete mode 100644 lib/generators/templates/testing/driver.rb delete mode 100644 lib/generators/templates/testing/i18n.rb delete mode 100644 lib/generators/templates/testing/shoulda_matchers.rb delete mode 100644 lib/generators/templates/views/flashes.html.erb delete mode 100644 lib/install/web.rb delete mode 100644 lib/suspenders/cleanup/generate_readme.rb delete mode 100644 lib/suspenders/cleanup/organize_gemfile.rb create mode 100644 lib/suspenders/cli.rb delete mode 100644 lib/suspenders/engine.rb delete mode 100644 lib/suspenders/generators.rb delete mode 100644 lib/suspenders/railtie.rb delete mode 100644 lib/tasks/suspenders.rake create mode 100644 lib/templates/web.rb create mode 100644 sig/suspenders.rbs create mode 100644 spec/spec_helper.rb create mode 100644 spec/suspenders_spec.rb delete mode 100644 test/dummy/Rakefile delete mode 100644 test/dummy/app/assets/images/.keep delete mode 100644 test/dummy/app/assets/stylesheets/application.css delete mode 100644 test/dummy/app/channels/application_cable/channel.rb delete mode 100644 test/dummy/app/channels/application_cable/connection.rb delete mode 100644 test/dummy/app/controllers/application_controller.rb delete mode 100644 test/dummy/app/controllers/concerns/.keep delete mode 100644 test/dummy/app/helpers/application_helper.rb delete mode 100644 test/dummy/app/jobs/application_job.rb delete mode 100644 test/dummy/app/mailers/application_mailer.rb delete mode 100644 test/dummy/app/models/application_record.rb delete mode 100644 test/dummy/app/models/concerns/.keep delete mode 100644 test/dummy/app/views/layouts/application.html.erb delete mode 100644 test/dummy/app/views/layouts/mailer.html.erb delete mode 100644 test/dummy/app/views/layouts/mailer.text.erb delete mode 100755 test/dummy/bin/dev delete mode 100755 test/dummy/bin/rails delete mode 100755 test/dummy/bin/rake delete mode 100755 test/dummy/bin/rubocop delete mode 100755 test/dummy/bin/setup delete mode 100755 test/dummy/bin/thrust delete mode 100644 test/dummy/config.ru delete mode 100644 test/dummy/config/application.rb delete mode 100644 test/dummy/config/boot.rb delete mode 100644 test/dummy/config/cable.yml delete mode 100644 test/dummy/config/database.yml delete mode 100644 test/dummy/config/environment.rb delete mode 100644 test/dummy/config/environments/development.rb delete mode 100644 test/dummy/config/environments/production.rb delete mode 100644 test/dummy/config/environments/test.rb delete mode 100644 test/dummy/config/initializers/content_security_policy.rb delete mode 100644 test/dummy/config/initializers/filter_parameter_logging.rb delete mode 100644 test/dummy/config/initializers/inflections.rb delete mode 100644 test/dummy/config/initializers/new_framework_defaults_8_0.rb delete mode 100644 test/dummy/config/initializers/permissions_policy.rb delete mode 100644 test/dummy/config/locales/en.yml delete mode 100644 test/dummy/config/puma.rb delete mode 100644 test/dummy/config/routes.rb delete mode 100644 test/dummy/config/storage.yml delete mode 100644 test/dummy/db/migrate/20241129142620_add_service_name_to_active_storage_blobs.active_storage.rb delete mode 100644 test/dummy/db/migrate/20241129142621_create_active_storage_variant_records.active_storage.rb delete mode 100644 test/dummy/db/migrate/20241129142622_remove_not_null_on_active_storage_blobs_checksum.active_storage.rb delete mode 100644 test/dummy/db/schema.rb delete mode 100644 test/dummy/lib/assets/.keep delete mode 100644 test/dummy/log/.keep delete mode 100644 test/dummy/public/400.html delete mode 100644 test/dummy/public/404.html delete mode 100644 test/dummy/public/406-unsupported-browser.html delete mode 100644 test/dummy/public/422.html delete mode 100644 test/dummy/public/500.html delete mode 100644 test/dummy/public/apple-touch-icon-precomposed.png delete mode 100644 test/dummy/public/apple-touch-icon.png delete mode 100644 test/dummy/public/favicon.ico delete mode 100644 test/dummy/public/icon.png delete mode 100644 test/dummy/public/icon.svg delete mode 100644 test/dummy/public/robots.txt delete mode 100644 test/dummy/storage/.keep delete mode 100644 test/dummy/tmp/.keep delete mode 100644 test/dummy/tmp/pids/.keep delete mode 100644 test/dummy/tmp/storage/.keep delete mode 100644 test/fixtures/files/Rakefile delete mode 100644 test/fixtures/files/Rakefile_advisories delete mode 100644 test/fixtures/files/_flashes.html.erb delete mode 100644 test/fixtures/files/action_mailer.rb delete mode 100644 test/fixtures/files/better_html.rb delete mode 100644 test/fixtures/files/driver.rb delete mode 100644 test/fixtures/files/email_interceptor.rb delete mode 100644 test/fixtures/files/email_interceptor_initializer.rb delete mode 100644 test/fixtures/files/environments/development.rb delete mode 100644 test/fixtures/files/environments/production.rb delete mode 100644 test/fixtures/files/environments/test.rb delete mode 100644 test/fixtures/files/erb-lint.yml delete mode 100644 test/fixtures/files/eslintrc.json delete mode 100644 test/fixtures/files/factories.rb delete mode 100644 test/fixtures/files/factories_spec_lint.rb delete mode 100644 test/fixtures/files/factories_test_lint.rb delete mode 100644 test/fixtures/files/gemfile_clean delete mode 100644 test/fixtures/files/gemfile_messy delete mode 100644 test/fixtures/files/i18n.rb delete mode 100644 test/fixtures/files/inline_svg.rb delete mode 100644 test/fixtures/files/postcss.config.js delete mode 100644 test/fixtures/files/prettierignore delete mode 100644 test/fixtures/files/prettierrc.json delete mode 100644 test/fixtures/files/rails_helper.rb delete mode 100644 test/fixtures/files/shoulda_matchers.rb delete mode 100644 test/fixtures/files/spec_helper.rb delete mode 100644 test/fixtures/files/stylelintrc.json delete mode 100644 test/fixtures/files/test_helper.rb delete mode 100644 test/generators/suspenders/accessibility_generator_test.rb delete mode 100644 test/generators/suspenders/advisories_generator_test.rb delete mode 100644 test/generators/suspenders/ci_generator_test.rb delete mode 100644 test/generators/suspenders/email_generator_test.rb delete mode 100644 test/generators/suspenders/environments/development_generator_test.rb delete mode 100644 test/generators/suspenders/environments/production_generator_test.rb delete mode 100644 test/generators/suspenders/environments/test_generator_test.rb delete mode 100644 test/generators/suspenders/factories_generator_test.rb delete mode 100644 test/generators/suspenders/inline_svg_generator_test.rb delete mode 100644 test/generators/suspenders/install/web_generator_test.rb delete mode 100644 test/generators/suspenders/jobs_generator_test.rb delete mode 100644 test/generators/suspenders/lint_generator_test.rb delete mode 100644 test/generators/suspenders/prerequisites_generator_test.rb delete mode 100644 test/generators/suspenders/rake_generator_test.rb delete mode 100644 test/generators/suspenders/setup_generator_test.rb delete mode 100644 test/generators/suspenders/styles_generator_test.rb delete mode 100644 test/generators/suspenders/tasks_generator_test.rb delete mode 100644 test/generators/suspenders/testing_generator_test.rb delete mode 100644 test/generators/suspenders/views_generator_test.rb delete mode 100644 test/suspenders/cleanup/generate_readme_test.rb delete mode 100644 test/suspenders/cleanup/organize_gemfile_test.rb delete mode 100644 test/suspenders/generators_test.rb delete mode 100644 test/suspenders_test.rb delete mode 100644 test/test_helper.rb diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 5f20d0cdc..be8c35867 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -8,28 +8,78 @@ on: pull_request: jobs: - lint: + build: runs-on: ubuntu-latest + name: Ruby ${{ matrix.ruby }} + strategy: + matrix: + ruby: + - '3.4.7' steps: - - uses: actions/checkout@v4 - - name: Set up Ruby - uses: ruby/setup-ruby@v1 - with: - bundler-cache: true + - uses: actions/checkout@v4 + with: + persist-credentials: false + - name: Set up Ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: ${{ matrix.ruby }} + bundler-cache: true + - name: Run the default task + run: bundle exec rake - - name: Lint - run: bin/rails standard - - test: + test-template: runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: Set up Ruby - uses: ruby/setup-ruby@v1 - with: - bundler-cache: true + services: + postgres: + image: postgres + env: + POSTGRES_USER: postgres + POSTGRES_PASSWORD: postgres + ports: + - 5432:5432 + options: --health-cmd="pg_isready" --health-interval=10s --health-timeout=5s --health-retries=3 - - name: Run tests - run: bin/rails test + steps: + - name: Checkout template + uses: actions/checkout@v4 + - name: Set up Ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: '3.4.7' + bundler-cache: false + - name: Install Rails + run: gem install rails + - name: Install dependencies + run: bundle install + - name: Install Staples + run: bundle exec rake install + - name: Generate new Rails app with template + run: | + cd /tmp + suspenders test_app + - name: Set up generated app + env: + DATABASE_URL: postgres://postgres:postgres@localhost:5432 + working-directory: /tmp/test_app + run: | + bundle install + bin/setup --skip-server + bin/rails db:migrate + - name: Run tests in generated app + env: + RAILS_ENV: test + DATABASE_URL: postgres://postgres:postgres@localhost:5432 + working-directory: /tmp/test_app + run: | + bin/rails db:test:prepare + bin/rails test:all + - name: Verify app can start + env: + DATABASE_URL: postgres://postgres:postgres@localhost:5432 + working-directory: /tmp/test_app + run: | + timeout 10 bin/rails server > /dev/null 2>&1 & + sleep 5 + curl -f http://localhost:3000 || exit 1 diff --git a/.gitignore b/.gitignore index 7906d705f..b04a8c840 100644 --- a/.gitignore +++ b/.gitignore @@ -1,11 +1,11 @@ /.bundle/ +/.yardoc +/_yardoc/ +/coverage/ /doc/ -/log/*.log /pkg/ +/spec/reports/ /tmp/ -/test/dummy/db/*.sqlite3 -/test/dummy/db/*.sqlite3-* -/test/dummy/log/*.log -/test/dummy/storage/ -/test/dummy/tmp/ -node_modules + +# rspec failure tracking +.rspec_status diff --git a/.rspec b/.rspec new file mode 100644 index 000000000..34c5164d9 --- /dev/null +++ b/.rspec @@ -0,0 +1,3 @@ +--format documentation +--color +--require spec_helper diff --git a/.standard.yml b/.standard.yml index a7d4f9bed..1c922d72d 100644 --- a/.standard.yml +++ b/.standard.yml @@ -1,5 +1,3 @@ -ruby_version: 3.0.5 -ignore: - - "templates/partials/db_optimizations_configuration.rb" - - "templates/partials/pull_requests_config.rb" - - "templates/partials/email_smtp.rb" +# For available configuration options, see: +# https://github.com/standardrb/standard +ruby_version: 3.2 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 2cacaaa49..b4c6d3232 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -20,16 +20,10 @@ Run the setup script. ./bin/setup ``` -Make sure the tests pass: +Make sure everything passes: ``` -bin/rails test -``` - -Make sure there are no linting violations: - -``` -bin/rails standard +bundle exec rake ``` Make your change, with new passing tests. @@ -46,16 +40,10 @@ This is a time for discussion and improvements, and making the necessary changes will be required before we can merge the contribution. -## Testing Generators - -There is a smaller dummy application at `test/dummy`. This application is used -as a mounting point for the engine, to make testing the engine extremely simple. - -There are a number of [assertions][] and [helpers][] that make testing -generators easier. +## Testing the executable Locally -[assertions]: https://api.rubyonrails.org/classes/Rails/Generators/Testing/Assertions.html -[helpers]: https://api.rubyonrails.org/classes/Rails/Generators/Testing/Behavior.html +To install this gem onto your local machine, run `bundle exec rake install`. +From there, you can run `suspenders ` to test the current code. ## Publishing to RubyGems diff --git a/Gemfile b/Gemfile index 35eb9624a..1222e4b15 100644 --- a/Gemfile +++ b/Gemfile @@ -1,12 +1,13 @@ +# frozen_string_literal: true + source "https://rubygems.org" -git_source(:github) { |repo| "https://github.com/#{repo}.git" } -# Specify your gem's dependencies in suspenders.gemspec. +# Specify your gem's dependencies in suspenders.gemspec gemspec -gem "puma" +gem "irb" +gem "rake", "~> 13.0" -gem "sqlite3", ">= 2.1" +gem "rspec", "~> 3.0" -# Start debugger with binding.b [https://github.com/ruby/debug] -# gem "debug", ">= 1.0.0" +gem "standard", "~> 1.3" diff --git a/Gemfile.lock b/Gemfile.lock index 00941efa8..58c67ee5e 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,99 +1,15 @@ PATH remote: . specs: - suspenders (20250317.0) - rails (~> 8.0) + suspenders (20251211.0) GEM remote: https://rubygems.org/ specs: - actioncable (8.0.1) - actionpack (= 8.0.1) - activesupport (= 8.0.1) - nio4r (~> 2.0) - websocket-driver (>= 0.6.1) - zeitwerk (~> 2.6) - actionmailbox (8.0.1) - actionpack (= 8.0.1) - activejob (= 8.0.1) - activerecord (= 8.0.1) - activestorage (= 8.0.1) - activesupport (= 8.0.1) - mail (>= 2.8.0) - actionmailer (8.0.1) - actionpack (= 8.0.1) - actionview (= 8.0.1) - activejob (= 8.0.1) - activesupport (= 8.0.1) - mail (>= 2.8.0) - rails-dom-testing (~> 2.2) - actionpack (8.0.1) - actionview (= 8.0.1) - activesupport (= 8.0.1) - nokogiri (>= 1.8.5) - rack (>= 2.2.4) - rack-session (>= 1.0.1) - rack-test (>= 0.6.3) - rails-dom-testing (~> 2.2) - rails-html-sanitizer (~> 1.6) - useragent (~> 0.16) - actiontext (8.0.1) - actionpack (= 8.0.1) - activerecord (= 8.0.1) - activestorage (= 8.0.1) - activesupport (= 8.0.1) - globalid (>= 0.6.0) - nokogiri (>= 1.8.5) - actionview (8.0.1) - activesupport (= 8.0.1) - builder (~> 3.1) - erubi (~> 1.11) - rails-dom-testing (~> 2.2) - rails-html-sanitizer (~> 1.6) - activejob (8.0.1) - activesupport (= 8.0.1) - globalid (>= 0.3.6) - activemodel (8.0.1) - activesupport (= 8.0.1) - activerecord (8.0.1) - activemodel (= 8.0.1) - activesupport (= 8.0.1) - timeout (>= 0.4.0) - activestorage (8.0.1) - actionpack (= 8.0.1) - activejob (= 8.0.1) - activerecord (= 8.0.1) - activesupport (= 8.0.1) - marcel (~> 1.0) - activesupport (8.0.1) - base64 - benchmark (>= 0.3) - bigdecimal - concurrent-ruby (~> 1.0, >= 1.3.1) - connection_pool (>= 2.2.5) - drb - i18n (>= 1.6, < 2) - logger (>= 1.4.2) - minitest (>= 5.1) - securerandom (>= 0.3) - tzinfo (~> 2.0, >= 2.0.5) - uri (>= 0.13.1) ast (2.4.2) base64 (0.1.2) - benchmark (0.4.0) - bigdecimal (3.1.9) - builder (3.3.0) - climate_control (1.2.0) - concurrent-ruby (1.3.5) - connection_pool (2.5.0) - crass (1.0.6) date (3.4.1) - drb (2.2.1) - erubi (1.13.1) - globalid (1.2.1) - activesupport (>= 6.1) - i18n (1.14.7) - concurrent-ruby (~> 1.0) + diff-lcs (1.6.2) io-console (0.8.0) irb (1.15.1) pp (>= 0.6.0) @@ -102,34 +18,6 @@ GEM json (2.6.3) language_server-protocol (3.17.0.3) lint_roller (1.1.0) - logger (1.6.6) - loofah (2.24.0) - crass (~> 1.0.2) - nokogiri (>= 1.12.0) - mail (2.8.1) - mini_mime (>= 0.1.1) - net-imap - net-pop - net-smtp - marcel (1.0.4) - mini_mime (1.1.5) - minitest (5.25.4) - mocha (2.1.0) - ruby2_keywords (>= 0.0.5) - net-imap (0.5.6) - date - net-protocol - net-pop (0.1.2) - net-protocol - net-protocol (0.2.2) - timeout - net-smtp (0.5.1) - net-protocol - nio4r (2.7.4) - nokogiri (1.18.2-arm64-darwin) - racc (~> 1.4) - nokogiri (1.18.2-x86_64-linux-gnu) - racc (~> 1.4) parallel (1.23.0) parser (3.2.2.4) ast (~> 2.4.1) @@ -140,46 +28,7 @@ GEM psych (5.2.3) date stringio - puma (6.4.0) - nio4r (~> 2.0) racc (1.8.1) - rack (3.1.10) - rack-session (2.1.0) - base64 (>= 0.1.0) - rack (>= 3.0.0) - rack-test (2.2.0) - rack (>= 1.3) - rackup (2.2.1) - rack (>= 3) - rails (8.0.1) - actioncable (= 8.0.1) - actionmailbox (= 8.0.1) - actionmailer (= 8.0.1) - actionpack (= 8.0.1) - actiontext (= 8.0.1) - actionview (= 8.0.1) - activejob (= 8.0.1) - activemodel (= 8.0.1) - activerecord (= 8.0.1) - activestorage (= 8.0.1) - activesupport (= 8.0.1) - bundler (>= 1.15.0) - railties (= 8.0.1) - rails-dom-testing (2.2.0) - activesupport (>= 5.0.0) - minitest - nokogiri (>= 1.6) - rails-html-sanitizer (1.6.2) - loofah (~> 2.21) - nokogiri (>= 1.15.7, != 1.16.7, != 1.16.6, != 1.16.5, != 1.16.4, != 1.16.3, != 1.16.2, != 1.16.1, != 1.16.0.rc1, != 1.16.0) - railties (8.0.1) - actionpack (= 8.0.1) - activesupport (= 8.0.1) - irb (~> 1.13) - rackup (>= 1.0.0) - rake (>= 12.2) - thor (~> 1.0, >= 1.2.2) - zeitwerk (~> 2.6) rainbow (3.1.1) rake (13.2.1) rdoc (6.12.0) @@ -188,6 +37,19 @@ GEM reline (0.6.0) io-console (~> 0.5) rexml (3.2.6) + rspec (3.13.2) + rspec-core (~> 3.13.0) + rspec-expectations (~> 3.13.0) + rspec-mocks (~> 3.13.0) + rspec-core (3.13.6) + rspec-support (~> 3.13.0) + rspec-expectations (3.13.5) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.13.0) + rspec-mocks (3.13.7) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.13.0) + rspec-support (3.13.6) rubocop (1.56.4) base64 (~> 0.1.1) json (~> 2.3) @@ -206,10 +68,6 @@ GEM rubocop (>= 1.7.0, < 2.0) rubocop-ast (>= 0.4.0) ruby-progressbar (1.13.0) - ruby2_keywords (0.0.5) - securerandom (0.4.1) - sqlite3 (2.3.1-arm64-darwin) - sqlite3 (2.3.1-x86_64-linux-gnu) standard (1.31.2) language_server-protocol (~> 3.17.0.2) lint_roller (~> 1.0) @@ -223,18 +81,7 @@ GEM lint_roller (~> 1.1) rubocop-performance (~> 1.19.1) stringio (3.1.3) - thor (1.3.2) - timeout (0.4.3) - tzinfo (2.0.6) - concurrent-ruby (~> 1.0) unicode-display_width (2.5.0) - uri (1.0.2) - useragent (0.16.11) - websocket-driver (0.7.7) - base64 - websocket-extensions (>= 0.1.0) - websocket-extensions (0.1.5) - zeitwerk (2.7.1) PLATFORMS arm64-darwin-21 @@ -243,11 +90,10 @@ PLATFORMS x86_64-linux DEPENDENCIES - climate_control - mocha - puma - sqlite3 (>= 2.1) - standard + irb + rake (~> 13.0) + rspec (~> 3.0) + standard (~> 1.3) suspenders! BUNDLED WITH diff --git a/NEWS.md b/NEWS.md index ee055605f..cb231d1ec 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,7 @@ Unreleased +Rewrite + 20250317.0 (March 17, 2025) Support Rails 8. diff --git a/README.md b/README.md index d7d0650d4..c0261965c 100644 --- a/README.md +++ b/README.md @@ -2,111 +2,62 @@ [![CI](https://github.com/thoughtbot/suspenders/actions/workflows/main.yml/badge.svg)](https://github.com/thoughtbot/suspenders/actions/workflows/main.yml) -Suspenders is a [Rails Engine][] containing generators for configuring Rails -applications with these [features][]. +Suspenders is intended to create a new Rails applications with these +[features][], and is optimised for deployment to Heroku. -It is used by thoughtbot to get a jump start on a new or existing app. Use -Suspenders if you're in a rush to build something amazing; don't use it if you -like missing deadlines. +It is used by thoughtbot to get a jump start on new apps. Use Suspenders if +you're in a rush to build something amazing; don't use it if you like missing +deadlines. -[Rails Engine]: https://guides.rubyonrails.org/engines.html [features]: ./FEATURES.md ![Suspenders boy](https://media.tumblr.com/1TEAMALpseh5xzf0Jt6bcwSMo1_400.png) ## Requirements -- Rails `~> 8.0` -- Ruby `>= 3.1` -- Node `>= 20.0.0` +Suspenders requires the latest version of [Rails][rails] and its dependencies. -## Usage - -Suspenders can be used to create a new Rails application, or to enhance an -existing Rails application. - -### With New Rails Applications - -This approach uses an [application template][] to generate a new Rails -application with Suspenders. +Additionally, Suspenders requires [yarn][yarn], [PostgreSQL][postgresql] and +[Redis][redis]. -We skip the [default test framework][] in favor of [RSpec][], and [prefer -PostgreSQL][] as our database. - -We skip [RuboCop rules by default][] in favor of our [holistic linting rules][]. +[rails]: https://guides.rubyonrails.org/install_ruby_on_rails.html +[yarn]: https://yarnpkg.com/getting-started/install +[postgresql]: https://formulae.brew.sh/formula/postgresql@17 +[redis]: https://formulae.brew.sh/formula/redis -#### Use the latest suspenders release: +## Installation ``` -rails new app_name \ - --skip-rubocop \ - --skip-test \ - -d=postgresql \ - -m=https://raw.githubusercontent.com/thoughtbot/suspenders/main/lib/install/web.rb +gem install suspenders ``` -#### OR use the current (possibly unreleased) `main` branch of suspenders: +## Usage ``` -rails new app_name \ - --suspenders-main \ - --skip-rubocop \ - --skip-test \ - -d=postgresql \ - -m=https://raw.githubusercontent.com/thoughtbot/suspenders/main/lib/install/web.rb +suspenders ``` -Then run `bin/setup` within the newly generated application. - -Alternatively, if you're using our [dotfiles][], then you can just run `rails new -app_name`, or create your own [railsrc][] file with the following configuration: +Under the hood, Suspenders uses an [application template][] to generate a new Rails +application like so: ``` ---skip-rubocop ---skip-test ---database=postgresql --m=https://raw.githubusercontent.com/thoughtbot/suspenders/main/lib/install/web.rb +rails new \ + -d=postgresql \ + --skip-test \ + --skip-solid \ + --m=~/path/to/template.rb ``` +We skip the [default test framework][] in favor of [RSpec][], and [prefer +PostgreSQL][] as our database. We skip the Solid ecosystm since we prefer +[Sidekiq][], and because Solid Queue has [performance issues][] on Heroku. + [application template]: https://guides.rubyonrails.org/rails_application_templates.html [default test framework]: https://guides.rubyonrails.org/testing.html [RSpec]: http://rspec.info [prefer PostgreSQL]: https://github.com/thoughtbot/dotfiles/pull/728 -[dotfiles]: https://github.com/thoughtbot/dotfiles -[railsrc]: https://github.com/rails/rails/blob/7f7f9df8641e35a076fe26bd097f6a1b22cb4e2d/railties/lib/rails/generators/rails/app/USAGE#L5C1-L7 -[RuboCop rules by default]: https://guides.rubyonrails.org/v7.2/7_2_release_notes.html#add-omakase-rubocop-rules-by-default -[holistic linting rules]: https://github.com/thoughtbot/suspenders/blob/main/FEATURES.md#linting - -### With Existing Rails Applications - -Suspenders can be used on an existing Rails application by adding it to the -`:development` and `:test` group. - -```ruby -group :development, :test do - gem "suspenders" -end -``` - -Once installed, you can invoke the web installation generator, which will -invoke all generators. - -``` -bin/rails g suspenders:install:web -``` - -Or, you can invoke generators individually. To see a list of available -generators run: - -``` -bin/rails g | grep suspenders -``` - -To learn more about a generator, run: - -``` -bin/rails g suspenders:[generator_name] --help -``` +[Sidekiq]: https://github.com/sidekiq/sidekiq/ +[performance issues]: https://github.com/rails/solid_queue/issues/330 ### Available Tasks diff --git a/Rakefile b/Rakefile index 7b7eb735c..df406778c 100644 --- a/Rakefile +++ b/Rakefile @@ -1,17 +1,10 @@ -require "bundler/setup" -require "bundler/gem_tasks" -require "minitest/test_task" -require "standard/rake" +# frozen_string_literal: true -require File.expand_path("test/dummy/config/application", __dir__) +require "bundler/gem_tasks" +require "rspec/core/rake_task" -Rails.application.load_tasks +RSpec::Core::RakeTask.new(:spec) -Minitest::TestTask.create(:test) do |t| - t.libs << "test" - t.libs << "lib" - t.warning = false - t.test_globs = ["test/**/*_test.rb"] -end +require "standard/rake" -task default: %i[test standard] +task default: %i[spec standard] diff --git a/bin/console b/bin/console new file mode 100755 index 000000000..1b8fbdfef --- /dev/null +++ b/bin/console @@ -0,0 +1,11 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true + +require "bundler/setup" +require "suspenders" + +# You can add fixtures and/or initialization code here to make experimenting +# with your gem easier. You can also use a different console, if you like. + +require "irb" +IRB.start(__FILE__) diff --git a/bin/rails b/bin/rails deleted file mode 100755 index af2f41909..000000000 --- a/bin/rails +++ /dev/null @@ -1,14 +0,0 @@ -#!/usr/bin/env ruby -# This command will automatically be run when you run "rails" with Rails gems -# installed from the root of your application. - -ENGINE_ROOT = File.expand_path("..", __dir__) -ENGINE_PATH = File.expand_path("../lib/suspenders/engine", __dir__) -APP_PATH = File.expand_path("../test/dummy/config/application", __dir__) - -# Set up gems listed in the Gemfile. -ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__) -require "bundler/setup" if File.exist?(ENV["BUNDLE_GEMFILE"]) - -require "rails/all" -require "rails/engine/commands" diff --git a/bin/setup b/bin/setup index cf4ad25e1..68cb49610 100755 --- a/bin/setup +++ b/bin/setup @@ -4,3 +4,6 @@ IFS=$'\n\t' set -vx bundle install + +# Do any other automated setup that you need to do here +chmod +x exe/suspenders diff --git a/bin/test b/bin/test deleted file mode 100755 index 5516a12bc..000000000 --- a/bin/test +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env ruby -$: << File.expand_path("../test", __dir__) - -require "bundler/setup" -require "rails/plugin/test" diff --git a/exe/suspenders b/exe/suspenders new file mode 100755 index 000000000..60168e7e6 --- /dev/null +++ b/exe/suspenders @@ -0,0 +1,24 @@ +#!/usr/bin/env ruby + +require_relative "../lib/suspenders" + +if ARGV[0].nil? || ARGV[0].empty? + puts "Error: Application name required" + puts "Usage: suspenders APP_NAME" + exit 1 +end + +if ARGV.length > 1 + puts "Error: Too many arguments (#{ARGV.length} given)" + puts "Usage: suspenders APP_NAME" + exit 1 +end + +app_name = ARGV[0] + +begin + Suspenders::CLI.run(app_name) + exit 0 +rescue Suspenders::Error => e + abort "Error: #{e.message}" +end diff --git a/lib/generators/suspenders/accessibility_generator.rb b/lib/generators/suspenders/accessibility_generator.rb deleted file mode 100644 index 0428b33c2..000000000 --- a/lib/generators/suspenders/accessibility_generator.rb +++ /dev/null @@ -1,24 +0,0 @@ -module Suspenders - module Generators - class AccessibilityGenerator < Rails::Generators::Base - include Suspenders::Generators::APIAppUnsupported - - desc <<~MARKDOWN - Uses [capybara_accessibility_audit][] and - [capybara_accessible_selectors][] to encourage and enforce accessibility best - practices. - - [capybara_accessibility_audit]: https://github.com/thoughtbot/capybara_accessibility_audit - [capybara_accessible_selectors]: https://github.com/citizensadvice/capybara_accessible_selectors - MARKDOWN - - def add_capybara_gems - gem_group :test do - gem "capybara_accessibility_audit", github: "thoughtbot/capybara_accessibility_audit" - gem "capybara_accessible_selectors", github: "citizensadvice/capybara_accessible_selectors", tag: "v0.12.0" - end - Bundler.with_unbundled_env { run "bundle install" } - end - end - end -end diff --git a/lib/generators/suspenders/advisories_generator.rb b/lib/generators/suspenders/advisories_generator.rb deleted file mode 100644 index 82c5100a2..000000000 --- a/lib/generators/suspenders/advisories_generator.rb +++ /dev/null @@ -1,32 +0,0 @@ -module Suspenders - module Generators - class AdvisoriesGenerator < Rails::Generators::Base - source_root File.expand_path("../../templates/advisories", __FILE__) - desc <<~MARKDOWN - Uses [bundler-audit][] to update the local security database and show - any relevant issues with the app's dependencies via a Rake task. - - [bundler-audit]: https://github.com/rubysec/bundler-audit - MARKDOWN - - def add_bundler_audit - gem_group :development, :test do - gem "bundler-audit", ">= 0.7.0", require: false - end - Bundler.with_unbundled_env { run "bundle install" } - end - - def modify_rakefile - content = <<~RUBY - - if Rails.env.local? - require "bundler/audit/task" - Bundler::Audit::Task.new - end - RUBY - - insert_into_file "Rakefile", content, after: /require_relative "config\/application"\n/ - end - end - end -end diff --git a/lib/generators/suspenders/ci_generator.rb b/lib/generators/suspenders/ci_generator.rb deleted file mode 100644 index 843e518d0..000000000 --- a/lib/generators/suspenders/ci_generator.rb +++ /dev/null @@ -1,54 +0,0 @@ -module Suspenders - module Generators - class CiGenerator < Rails::Generators::Base - include Suspenders::Generators::DatabaseUnsupported - include Suspenders::Generators::Helpers - - source_root File.expand_path("../../templates/ci", __FILE__) - desc <<~MARKDOWN - Uses [GitHub Actions][] for CI - - [GitHub Actions]: https://docs.github.com/en/actions - MARKDOWN - - def ci_files - template "ci.yml", ".github/workflows/ci.yml", force: true - end - - private - - def scan_ruby? - has_gem? "bundler-audit" - end - - def scan_js? - File.exist?("bin/importmap") && using_node? - end - - def lint? - using_node? && has_gem?("standard") && has_yarn_script?("lint") - end - - def using_node? - File.exist? "package.json" - end - - def has_gem?(name) - Bundler.rubygems.find_name(name).any? - end - - def using_rspec? - File.exist? "spec" - end - - def has_yarn_script?(name) - return false if !using_node? - - content = File.read("package.json") - json = JSON.parse(content) - - json.dig("scripts", name) - end - end - end -end diff --git a/lib/generators/suspenders/email_generator.rb b/lib/generators/suspenders/email_generator.rb deleted file mode 100644 index f46536acc..000000000 --- a/lib/generators/suspenders/email_generator.rb +++ /dev/null @@ -1,56 +0,0 @@ -module Suspenders - module Generators - class EmailGenerator < Rails::Generators::Base - source_root File.expand_path("../../templates/email", __FILE__) - desc <<~MARKDOWN - [Intercept][] emails in non-production environments by setting `INTERCEPTOR_ADDRESSES`. - - ```sh - INTERCEPTOR_ADDRESSES="user_1@example.com,user_2@example.com" bin/rails s - ``` - - Configuration can be found at `config/initializers/email_interceptor.rb`. - - Interceptor can be found at `app/mailers/email_interceptor.rb`. - - [Intercept]: https://guides.rubyonrails.org/action_mailer_basics.html#intercepting-emails - MARKDOWN - - def create_email_interceptor - copy_file "email_interceptor.rb", "app/mailers/email_interceptor.rb" - end - - def create_email_interceptor_initializer - initializer "email_interceptor.rb", <<~RUBY - Rails.application.configure do - if ENV["INTERCEPTOR_ADDRESSES"].present? - config.action_mailer.interceptors = %w[EmailInterceptor] - end - end - RUBY - end - - def configure_email_interceptor - environment do - %( - config.to_prepare do - EmailInterceptor.config.interceptor_addresses = ENV.fetch("INTERCEPTOR_ADDRESSES", "").split(",") - end - ) - end - end - - # TODO: Remove once https://github.com/rails/rails/pull/51191 is in latest - # Rails release - def configure_development_environment - environment %(config.action_mailer.default_url_options = { host: "localhost", port: 3000 }), env: "development" - end - - # TODO: Remove once https://github.com/rails/rails/pull/51191 is in latest - # Rails release - def configure_test_environment - environment %(config.action_mailer.default_url_options = { host: "www.example.com" }), env: "test" - end - end - end -end diff --git a/lib/generators/suspenders/environments/development_generator.rb b/lib/generators/suspenders/environments/development_generator.rb deleted file mode 100644 index c0824dada..000000000 --- a/lib/generators/suspenders/environments/development_generator.rb +++ /dev/null @@ -1,50 +0,0 @@ -module Suspenders - module Generators - module Environments - class DevelopmentGenerator < Rails::Generators::Base - desc <<~MARKDOWN - - Enables [raise_on_missing_translations][]. - - Enables [annotate_rendered_view_with_filenames][]. - - Enables [i18n_customize_full_message][]. - - Enables [query_log_tags_enabled][]. - - [raise_on_missing_translations]: https://guides.rubyonrails.org/configuring.html#config-i18n-raise-on-missing-translations - [annotate_rendered_view_with_filenames]: https://guides.rubyonrails.org/configuring.html#config-action-view-annotate-rendered-view-with-filenames - [i18n_customize_full_message]: https://guides.rubyonrails.org/configuring.html#config-active-model-i18n-customize-full-message - [query_log_tags_enabled]: https://guides.rubyonrails.org/configuring.html#config-active-record-query-log-tags-enabled - MARKDOWN - - def raise_on_missing_translations - if development_config.match?(/^\s#\s*config\.i18n\.raise_on_missing_translations/) - uncomment_lines "config/environments/development.rb", "config.i18n.raise_on_missing_translations = true" - else - environment %(config.i18n.raise_on_missing_translations = true), env: "development" - end - end - - def annotate_render_view_with_filename - if development_config.match?(/^\s#\s*config\.action_view\.annotate_render_view_with_filename/) - uncomment_lines "config/environments/development.rb", - "config.action_view.annotate_rendered_view_with_filenames = true" - else - environment %(config.action_view.annotate_rendered_view_with_filenames = true), env: "development" - end - end - - def enable_i18n_customize_full_message - environment %(config.active_model.i18n_customize_full_message = true), env: "development" - end - - def enable_query_log_tags_enabled - environment %(config.active_record.query_log_tags_enabled = true), env: "development" - end - - private - - def development_config - File.read(Rails.root.join("config/environments/development.rb")) - end - end - end - end -end diff --git a/lib/generators/suspenders/environments/production_generator.rb b/lib/generators/suspenders/environments/production_generator.rb deleted file mode 100644 index 0c64084dc..000000000 --- a/lib/generators/suspenders/environments/production_generator.rb +++ /dev/null @@ -1,27 +0,0 @@ -module Suspenders - module Generators - module Environments - class ProductionGenerator < Rails::Generators::Base - desc <<~MARKDOWN - - Enables [require_master_key][]. - - [require_master_key]: https://guides.rubyonrails.org/configuring.html#config-require-master-key - MARKDOWN - - def require_master_key - if production_config.match?(/^\s*#\s*config\.require_master_key\s*=\s*true/) - uncomment_lines "config/environments/production.rb", /config\.require_master_key\s*=\s*true/ - else - environment %(config.require_master_key = true), env: "production" - end - end - - private - - def production_config - File.read(Rails.root.join("config/environments/production.rb")) - end - end - end - end -end diff --git a/lib/generators/suspenders/environments/test_generator.rb b/lib/generators/suspenders/environments/test_generator.rb deleted file mode 100644 index 61f1528b9..000000000 --- a/lib/generators/suspenders/environments/test_generator.rb +++ /dev/null @@ -1,39 +0,0 @@ -module Suspenders - module Generators - module Environments - class TestGenerator < Rails::Generators::Base - desc <<~MARKDOWN - - Enables [raise_on_missing_translations][]. - - Disables [action_dispatch.show_exceptions][]. - - [raise_on_missing_translations]: https://guides.rubyonrails.org/configuring.html#config-i18n-raise-on-missing-translations - [action_dispatch.show_exceptions]: https://edgeguides.rubyonrails.org/configuring.html#config-action-dispatch-show-exceptions - MARKDOWN - - def raise_on_missing_translations - if test_config.match?(/^\s*#\s*config\.i18n\.raise_on_missing_translations\s*=\s*true/) - uncomment_lines "config/environments/test.rb", /config\.i18n\.raise_on_missing_translations\s*=\s*true/ - else - environment %(config.i18n.raise_on_missing_translations = true), env: "test" - end - end - - def disable_action_dispatch_show_exceptions - if test_config.match?(/^\s*config\.action_dispatch\.show_exceptions\s*=\s*:rescuable/) - gsub_file "config/environments/test.rb", /^\s*config\.action_dispatch\.show_exceptions\s*=\s*:rescuable/, - "config.action_dispatch.show_exceptions = :none" - gsub_file "config/environments/test.rb", /^\s*#\s*Raise exceptions instead of rendering exception templates/i, "" - else - environment %(config.action_dispatch.show_exceptions = :none), env: "test" - end - end - - private - - def test_config - File.read(Rails.root.join("config/environments/test.rb")) - end - end - end - end -end diff --git a/lib/generators/suspenders/factories_generator.rb b/lib/generators/suspenders/factories_generator.rb deleted file mode 100644 index 48fb06a39..000000000 --- a/lib/generators/suspenders/factories_generator.rb +++ /dev/null @@ -1,64 +0,0 @@ -module Suspenders - module Generators - class FactoriesGenerator < Rails::Generators::Base - include Suspenders::Generators::Helpers - - source_root File.expand_path("../../templates/factories", __FILE__) - desc <<~MARKDOWN - Uses [FactoryBot][] as an alternative to [Fixtures][] to help you define - dummy and test data for your test suite. The `create`, `build`, and - `build_stubbed` class methods are directly available to all tests. - - Place FactoryBot definitions in `spec/factories.rb`, at least until it - grows unwieldy. This helps reduce confusion around circular dependencies and - makes it easy to jump between definitions. - - [FactoryBot]: https://github.com/thoughtbot/factory_bot - [Fixtures]: https://guides.rubyonrails.org/testing.html#the-low-down-on-fixtures - MARKDOWN - - def add_factory_bot - gem_group :development, :test do - gem "factory_bot_rails" - end - - Bundler.with_unbundled_env { run "bundle install" } - end - - def set_up_factory_bot - if default_test_helper_present? - insert_into_file Rails.root.join("test/test_helper.rb"), after: "class TestCase" do - "\n include FactoryBot::Syntax::Methods" - end - elsif rspec_test_helper_present? - copy_file "factory_bot_rspec.rb", "spec/support/factory_bot.rb" - insert_into_file Rails.root.join("spec/rails_helper.rb") do - %(Dir[Rails.root.join("spec/support/**/*.rb")].sort.each { |file| require file }) - end - end - end - - def generate_empty_factories_file - if default_test_suite? - copy_file "factories.rb", "test/factories.rb" - elsif rspec_test_suite? - copy_file "factories.rb", "spec/factories.rb" - end - end - - def remove_fixture_definitions - if default_test_helper_present? - comment_lines "test/test_helper.rb", /fixtures :all/ - end - end - - def create_linting_test - if default_test_suite? - copy_file "factories_test.rb", "test/factory_bots/factories_test.rb" - elsif rspec_test_suite? - copy_file "factories_spec.rb", "spec/factory_bots/factories_spec.rb" - end - end - end - end -end diff --git a/lib/generators/suspenders/inline_svg_generator.rb b/lib/generators/suspenders/inline_svg_generator.rb deleted file mode 100644 index 0728e4276..000000000 --- a/lib/generators/suspenders/inline_svg_generator.rb +++ /dev/null @@ -1,24 +0,0 @@ -module Suspenders - module Generators - class InlineSvgGenerator < Rails::Generators::Base - include Suspenders::Generators::APIAppUnsupported - source_root File.expand_path("../../templates/inline_svg", __FILE__) - desc <<~MARKDOWN - Uses [inline_svg][] for embedding SVG documents into views. - - Configuration can be found at `config/initializers/inline_svg.rb` - - [inline_svg]: https://github.com/jamesmartin/inline_svg - MARKDOWN - - def add_inline_svg_gem - gem "inline_svg" - Bundler.with_unbundled_env { run "bundle install" } - end - - def configure_inline_svg - copy_file "inline_svg.rb", "config/initializers/inline_svg.rb" - end - end - end -end diff --git a/lib/generators/suspenders/install/web_generator.rb b/lib/generators/suspenders/install/web_generator.rb deleted file mode 100644 index cb31be332..000000000 --- a/lib/generators/suspenders/install/web_generator.rb +++ /dev/null @@ -1,85 +0,0 @@ -module Suspenders - module Generators - module Install - class WebGenerator < Rails::Generators::Base - include Suspenders::Generators::APIAppUnsupported - include Suspenders::Generators::DatabaseUnsupported - include Suspenders::Generators::NodeNotInstalled - include Suspenders::Generators::NodeVersionUnsupported - - source_root File.expand_path("../../../templates/install/web", __FILE__) - desc <<~MARKDOWN - Invokes all necessary generators for new Rails applications generated with Suspenders. - - This generatator is intended to be invoked as part of an [application template][]. - - #### Use the latest suspenders release: - - ``` - rails new \\ - --skip-rubocop \\ - --skip-test \\ - -d=postgresql \\ - -m=https://raw.githubusercontent.com/thoughtbot/suspenders/main/lib/install/web.rb - ``` - - #### OR use the current (possibly unreleased) `main` branch of suspenders: - - ``` - rails new app_name \\ - --suspenders-main \\ - --skip-rubocop \\ - --skip-test \\ - -d=postgresql \\ - -m=https://raw.githubusercontent.com/thoughtbot/suspenders/main/lib/install/web.rb - ``` - - [application template]: https://guides.rubyonrails.org/rails_application_templates.html - MARKDOWN - - def invoke_generators - # This needs to go first, since it configures `.node-version` - generate "suspenders:prerequisites" - - generate "suspenders:accessibility" - generate "suspenders:advisories" - generate "suspenders:email" - generate "suspenders:factories" - generate "suspenders:inline_svg" - generate "suspenders:lint" - generate "suspenders:rake" - generate "suspenders:setup" - generate "suspenders:tasks" - generate "suspenders:testing" - generate "suspenders:views" - - # suspenders:jobs needs to be invoked before suspenders:styles, since - # suspenders:styles generator creates Procfile.dev - generate "suspenders:styles" - generate "suspenders:jobs" - - # Needs to run after other generators, since some touch the - # configuration files. - generate "suspenders:environments:test" - generate "suspenders:environments:development" - generate "suspenders:environments:production" - - # Needs to be run last since it depends on lint, testing, and - # advisories - generate "suspenders:ci" - end - - def cleanup - rake "suspenders:cleanup:organize_gemfile" - rake "suspenders:cleanup:generate_readme" - copy_file "CONTRIBUTING.md", "CONTRIBUTING.md" - end - - def lint - run "yarn run fix:prettier" - run "bundle exec rake standard:fix_unsafely" - end - end - end - end -end diff --git a/lib/generators/suspenders/jobs_generator.rb b/lib/generators/suspenders/jobs_generator.rb deleted file mode 100644 index 2f8af96af..000000000 --- a/lib/generators/suspenders/jobs_generator.rb +++ /dev/null @@ -1,34 +0,0 @@ -module Suspenders - module Generators - class JobsGenerator < Rails::Generators::Base - desc <<~MARKDOWN - Uses [Sidekiq][] for [background job][] processing. - - Configures the `test` environment to use the [inline][] adapter. - - [Sidekiq]: https://github.com/sidekiq/sidekiq - [background job]: https://guides.rubyonrails.org/active_job_basics.html - [inline]: https://api.rubyonrails.org/classes/ActiveJob/QueueAdapters/InlineAdapter.html - MARKDOWN - - def add_sidekiq_gem - gem "sidekiq" - Bundler.with_unbundled_env { run "bundle install" } - end - - def configure_active_job - environment "config.active_job.queue_adapter = :sidekiq" - environment "config.active_job.queue_adapter = :inline", env: "test" - end - - def configure_procfile - if Rails.root.join("Procfile.dev").exist? - append_to_file "Procfile.dev", "worker: bundle exec sidekiq" - else - say "Add default Procfile.dev" - create_file "Procfile.dev", "worker: bundle exec sidekiq" - end - end - end - end -end diff --git a/lib/generators/suspenders/lint_generator.rb b/lib/generators/suspenders/lint_generator.rb deleted file mode 100644 index 65a6e53ca..000000000 --- a/lib/generators/suspenders/lint_generator.rb +++ /dev/null @@ -1,94 +0,0 @@ -module Suspenders - module Generators - class LintGenerator < Rails::Generators::Base - include Suspenders::Generators::Helpers - - source_root File.expand_path("../../templates/lint", __FILE__) - desc <<~MARKDOWN - - Uses [@thoughtbot/eslint-config][] for JavaScript linting. - - Uses [@thoughtbot/stylelint-config][] for CSS linting. - - Uses [prettier][] for additional linting. - - Uses [better_html][], [erb_lint][], and [erblint-github][] for ERB linting. - - Uses [standard][] for Ruby linting. - - **Available Commands** - - - Run `yarn lint` to lint front-end code. - - Run `yarn fix:prettier` to automatically fix prettier violations. - - Run `bin/rails standard` to lint ERB and Ruby code. - - Run `bundle exec standardrb --fix` to fix standard violations. - - [@thoughtbot/eslint-config]: https://github.com/thoughtbot/eslint-config - [@thoughtbot/stylelint-config]: https://github.com/thoughtbot/stylelint-config - [prettier]: https://prettier.io - [better_html]: https://github.com/Shopify/better-html - [erb_lint]: https://github.com/Shopify/erb-lint - [erblint-github]: https://github.com/github/erblint-github - [standard]: https://github.com/standardrb/standard - MARKDOWN - - def check_package_json - unless File.exist? Rails.root.join("package.json") - copy_file "package.json", "package.json" - end - end - - # TODO: Remove eslint version pin once the follownig is solved - # https://github.com/thoughtbot/eslint-config/issues/10 - def install_dependencies - run "yarn add stylelint eslint@^8.9.0 @thoughtbot/stylelint-config @thoughtbot/eslint-config npm-run-all prettier --dev" - end - - def install_gems - gem_group :development, :test do - gem "better_html", require: false - gem "erb_lint", require: false - gem "erblint-github", require: false - gem "standard" - end - Bundler.with_unbundled_env { run "bundle install" } - end - - def configure_stylelint - copy_file "stylelintrc.json", ".stylelintrc.json" - end - - def configure_eslint - copy_file "eslintrc.json", ".eslintrc.json" - end - - def configure_prettier - copy_file "prettierrc", ".prettierrc" - copy_file "prettierignore", ".prettierignore" - end - - def configure_erb_lint - copy_file "erb-lint.yml", ".erb-lint.yml" - copy_file "config_better_html.yml", "config/better_html.yml" - copy_file "config_initializers_better_html.rb", "config/initializers/better_html.rb" - copy_file "erblint.rake", "lib/tasks/erblint.rake" - template "rubocop.yml.tt", ".rubocop.yml" - end - - def update_package_json - content = File.read package_json - json = JSON.parse content - json["scripts"] ||= {} - - json["scripts"]["lint"] = "run-p lint:eslint lint:stylelint lint:prettier" - json["scripts"]["lint:eslint"] = "eslint --max-warnings=0 --no-error-on-unmatched-pattern 'app/javascript/**/*.js'" - json["scripts"]["lint:stylelint"] = "stylelint 'app/assets/stylesheets/**/*.css'" - json["scripts"]["lint:prettier"] = "prettier --check '**/*' --ignore-unknown" - json["scripts"]["fix:prettier"] = "prettier --write '**/*' --ignore-unknown" - - File.write package_json, JSON.pretty_generate(json) - end - - private - - def package_json - Rails.root.join("package.json") - end - end - end -end diff --git a/lib/generators/suspenders/prerequisites_generator.rb b/lib/generators/suspenders/prerequisites_generator.rb deleted file mode 100644 index fd0e064df..000000000 --- a/lib/generators/suspenders/prerequisites_generator.rb +++ /dev/null @@ -1,19 +0,0 @@ -module Suspenders - module Generators - class PrerequisitesGenerator < Rails::Generators::Base - include Suspenders::Generators::Helpers - include Suspenders::Generators::NodeNotInstalled - include Suspenders::Generators::NodeVersionUnsupported - - source_root File.expand_path("../../templates/prerequisites", __FILE__) - - desc <<~MARKDOWN - Creates `.node-version` file set to the current LTS version. - MARKDOWN - - def set_node_version - template "node-version", ".node-version" - end - end - end -end diff --git a/lib/generators/suspenders/rake_generator.rb b/lib/generators/suspenders/rake_generator.rb deleted file mode 100644 index ec0bce016..000000000 --- a/lib/generators/suspenders/rake_generator.rb +++ /dev/null @@ -1,25 +0,0 @@ -module Suspenders - module Generators - class RakeGenerator < Rails::Generators::Base - source_root File.expand_path("../../templates/rake", __FILE__) - desc <<~MARKDOWN - Adds default Raketask wich is a wrapper for `suspenders:rake`. - - This will do the following: - - - Run the test suite. - - Run a Ruby and ERB linter. - - Scan the Ruby codebase for any dependency vulnerabilities. - MARKDOWN - - def configure_default_rake_task - append_to_file "Rakefile", <<~RUBY - - if Rails.env.local? - task default: "suspenders:rake" - end - RUBY - end - end - end -end diff --git a/lib/generators/suspenders/setup_generator.rb b/lib/generators/suspenders/setup_generator.rb deleted file mode 100644 index 7ab6fc79a..000000000 --- a/lib/generators/suspenders/setup_generator.rb +++ /dev/null @@ -1,14 +0,0 @@ -module Suspenders - module Generators - class SetupGenerator < Rails::Generators::Base - source_root File.expand_path("../../templates/setup", __FILE__) - desc <<~MARKDOWN - Run `bin/setup` to install dependencies and seed development data. - MARKDOWN - - def replace_bin_setup - copy_file "bin_setup.rb", "bin/setup", force: true - end - end - end -end diff --git a/lib/generators/suspenders/styles_generator.rb b/lib/generators/suspenders/styles_generator.rb deleted file mode 100644 index 59712f43e..000000000 --- a/lib/generators/suspenders/styles_generator.rb +++ /dev/null @@ -1,84 +0,0 @@ -module Suspenders - module Generators - class StylesGenerator < Rails::Generators::Base - include Suspenders::Generators::APIAppUnsupported - - source_root File.expand_path("../../templates/styles", __FILE__) - desc <<~MARKDOWN - - Uses [PostCSS][] via [cssbundling-rails][]. - - Uses [modern-normalize][] to normalize browsers' default style. - - Configuration can be found at `postcss.config.js`. - - Adds the following stylesheet structure. - - ``` - app/assets/stylesheets/base.css - app/assets/stylesheets/components.css - app/assets/stylesheets/utilities.css - ``` - - Adds `app/assets/static` so that [postcss-url][] has a directory to copy - assets to. - - [PostCSS]: https://postcss.org - [cssbundling-rails]: https://github.com/rails/cssbundling-rails - [modern-normalize]: https://github.com/sindresorhus/modern-normalize - [postcss-url]: https://github.com/postcss/postcss-url - MARKDOWN - - def add_cssbundling_rails_gem - gem "cssbundling-rails" - - Bundler.with_unbundled_env { run "bundle install" } - run "bin/rails css:install:postcss" - end - - def build_directory_structure - create_file "app/assets/stylesheets/base.css" - append_to_file "app/assets/stylesheets/base.css", "/* Base Styles */" - - create_file "app/assets/stylesheets/components.css" - append_to_file "app/assets/stylesheets/components.css", "/* Component Styles */" - - create_file "app/assets/stylesheets/utilities.css" - append_to_file "app/assets/stylesheets/utilities.css", "/* Utility Styles */" - end - - def configure_application_stylesheet - run "yarn add modern-normalize" - - append_to_file "app/assets/stylesheets/application.postcss.css" do - <<~TEXT - @import "modern-normalize"; - @import "base.css"; - @import "components.css"; - @import "utilities.css"; - TEXT - end - end - - def install_postcss_url - run "yarn add postcss-url" - end - - def configures_postcss - begin - File.delete(postcss_config) - rescue Errno::ENOENT - end - - empty_directory "app/assets/static" - create_file "app/assets/static/.gitkeep" - - copy_file "postcss.config.js", "postcss.config.js" - end - - private - - def postcss_config - Rails.root.join("postcss.config.js") - end - end - end -end diff --git a/lib/generators/suspenders/tasks_generator.rb b/lib/generators/suspenders/tasks_generator.rb deleted file mode 100644 index 924879e7c..000000000 --- a/lib/generators/suspenders/tasks_generator.rb +++ /dev/null @@ -1,20 +0,0 @@ -module Suspenders - module Generators - class TasksGenerator < Rails::Generators::Base - source_root File.expand_path("../../templates/tasks", __FILE__) - desc <<~MARKDOWN - Creates `lib/tasks/dev.rake` which contains the following tasks: - - `bin/rails dev:prime` which loads sample data for local development. - MARKDOWN - - def create_dev_rake - if Bundler.rubygems.find_name("factory_bot").any? - copy_file "dev.rake", "lib/tasks/dev.rake" - else - say "This generator requires Factory Bot" - end - end - end - end -end diff --git a/lib/generators/suspenders/testing_generator.rb b/lib/generators/suspenders/testing_generator.rb deleted file mode 100644 index be4bdfd5b..000000000 --- a/lib/generators/suspenders/testing_generator.rb +++ /dev/null @@ -1,113 +0,0 @@ -module Suspenders - module Generators - class TestingGenerator < Rails::Generators::Base - source_root File.expand_path("../../templates/testing", __FILE__) - desc <<~MARKDOWN - Uses [RSpec][] and [RSpec Rails][] in favor of the [default test suite][]. - - The test suite can be run with `bin/rails spec`. - - Configuration can be found in the following files: - - ``` - spec/rails_helper.rb - spec/spec_helper.rb - spec/support/action_mailer.rb - spec/support/driver.rb - spec/support/i18n.rb - spec/support/shoulda_matchers.rb - ``` - - - Uses [action_dispatch-testing-integration-capybara][] to introduce Capybara assertions into Request specs. - - Uses [shoulda-matchers][] for simple one-liner tests for common Rails functionality. - - Uses [webmock][] for stubbing and setting expectations on HTTP requests in Ruby. - - [RSpec]: http://rspec.info - [RSpec Rails]: https://github.com/rspec/rspec-rails - [default test suite]: https://guides.rubyonrails.org/testing.html - [action_dispatch-testing-integration-capybara]: https://github.com/thoughtbot/action_dispatch-testing-integration-capybara - [shoulda-matchers]: https://github.com/thoughtbot/shoulda-matchers - [webmock]: https://github.com/bblimke/webmock - MARKDOWN - - def add_gems - gem_group :development, :test do - gem "rspec-rails", "~> 6.1.0" - end - - gem_group :test do - gem "capybara" - gem "action_dispatch-testing-integration-capybara", - github: "thoughtbot/action_dispatch-testing-integration-capybara", tag: "v0.1.1", - require: "action_dispatch/testing/integration/capybara/rspec" - gem "selenium-webdriver" - gem "shoulda-matchers", "~> 6.0" - gem "webmock" - end - - Bundler.with_unbundled_env { run "bundle install" } - end - - def run_rspec_installation_script - rails_command "generate rspec:install" - end - - def modify_rails_helper - insert_into_file "spec/rails_helper.rb", - "\s\sconfig.infer_base_class_for_anonymous_controllers = false\n", - after: "RSpec.configure do |config|\n" - - uncomment_lines "spec/rails_helper.rb", /Rails\.root\.glob/ - end - - def modify_spec_helper - persistence_file_path = "\s\sconfig.example_status_persistence_file_path = \"tmp/rspec_examples.txt\"\n" - order = "\s\sconfig.order = :random\n\n" - webmock_config = <<~RUBY - - WebMock.disable_net_connect!( - allow_localhost: true, - allow: [ - /(chromedriver|storage).googleapis.com/, - "googlechromelabs.github.io" - ] - ) - RUBY - - insert_into_file "spec/spec_helper.rb", - persistence_file_path + order, - after: "RSpec.configure do |config|\n" - - insert_into_file "spec/spec_helper.rb", "require \"webmock/rspec\"\n\n", before: "RSpec.configure do |config|" - insert_into_file "spec/spec_helper.rb", webmock_config - end - - def create_system_spec_dir - empty_directory "spec/system" - create_file "spec/system/.gitkeep" - end - - def configure_chromedriver - copy_file "driver.rb", "spec/support/driver.rb" - end - - def configure_i18n_helper - copy_file "i18n.rb", "spec/support/i18n.rb" - end - - def configure_shoulda_matchers - copy_file "shoulda_matchers.rb", "spec/support/shoulda_matchers.rb" - end - - def configure_action_mailer_helpers - # https://guides.rubyonrails.org/testing.html#the-basic-test-case - # - # The ActionMailer::Base.deliveries array is only reset automatically in - # ActionMailer::TestCase and ActionDispatch::IntegrationTest tests. If - # you want to have a clean slate outside these test cases, you can reset - # it manually with: ActionMailer::Base.deliveries.clear - copy_file "action_mailer.rb", "spec/support/action_mailer.rb" - end - end - end -end diff --git a/lib/generators/suspenders/views_generator.rb b/lib/generators/suspenders/views_generator.rb deleted file mode 100644 index 533d6568b..000000000 --- a/lib/generators/suspenders/views_generator.rb +++ /dev/null @@ -1,38 +0,0 @@ -module Suspenders - module Generators - class ViewsGenerator < Rails::Generators::Base - include Suspenders::Generators::APIAppUnsupported - - source_root File.expand_path("../../templates/views", __FILE__) - desc <<~MARKDOWN - - A [partial][] for [flash messages][] is located in `app/views/application/_flashes.html.erb`. - - Sets [lang][] attribute on `` element to `en` via `I18n.local`. - - Dynamically sets `` via the [title][] gem. - - Disables Turbo's [Prefetch][] in an effort to reduce unnecessary network requests. - - [partial]: https://guides.rubyonrails.org/layouts_and_rendering.html#using-partials - [flash messages]: https://guides.rubyonrails.org/action_controller_overview.html#the-flash - [lang]: https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/lang - [title]: https://github.com/calebhearth/title - [Prefetch]: https://turbo.hotwired.dev/handbook/drive#prefetching-links-on-hover - MARKDOWN - - def install_gems - gem "title" - - Bundler.with_unbundled_env { run "bundle install" } - end - - def create_views - copy_file "flashes.html.erb", "app/views/application/_flashes.html.erb" - end - - def update_application_layout - insert_into_file "app/views/layouts/application.html.erb", " <%= render \"flashes\" -%>\n", after: "<body>\n" - gsub_file "app/views/layouts/application.html.erb", /<html>/, "<html lang=\"<%= I18n.locale %>\">" - gsub_file "app/views/layouts/application.html.erb", /<title>.*<\/title>/, "<title><%= title %>" - insert_into_file "app/views/layouts/application.html.erb", " \n", after: "" - end - end - end -end diff --git a/lib/generators/templates/ci/ci.yml.tt b/lib/generators/templates/ci/ci.yml.tt deleted file mode 100644 index 240bbe040..000000000 --- a/lib/generators/templates/ci/ci.yml.tt +++ /dev/null @@ -1,148 +0,0 @@ -name: CI - -on: - pull_request: - push: - branches: [main] - -jobs: -<%- if scan_ruby? -%> - scan_ruby: - runs-on: ubuntu-latest - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Set up Ruby - uses: ruby/setup-ruby@v1 - with: - ruby-version: .ruby-version - bundler-cache: true - - - name: Scan for security vulnerabilities in Ruby dependencies - run: | - bin/rails bundle:audit:update - bin/rails bundle:audit -<% end -%> - -<%- if scan_js? -%> - scan_js: - runs-on: ubuntu-latest - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Set up Ruby - uses: ruby/setup-ruby@v1 - with: - ruby-version: .ruby-version - bundler-cache: true - - - name: Setup Node - uses: actions/setup-node@v4 - with: - node-version-file: .node-version - - - name: Install modules - run: yarn install - - - name: Scan for security vulnerabilities in JavaScript dependencies - run: | - bin/importmap audit - yarn audit -<% end -%> - -<%- if lint? -%> - lint: - runs-on: ubuntu-latest - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Set up Ruby - uses: ruby/setup-ruby@v1 - with: - ruby-version: .ruby-version - bundler-cache: true - - - name: Setup Node - uses: actions/setup-node@v4 - with: - node-version-file: .node-version - - - name: Install modules - run: yarn install - - - name: Lint Ruby code for consistent style - run: bin/rails standard - - - name: Lint front-end code for consistent style - run: yarn lint -<% end -%> - - test: - runs-on: ubuntu-latest - - services: - postgres: - image: postgres - env: - POSTGRES_USER: postgres - POSTGRES_PASSWORD: postgres - ports: - - 5432:5432 - options: --health-cmd="pg_isready" --health-interval=10s --health-timeout=5s --health-retries=3 - - # redis: - # image: redis - # ports: - # - 6379:6379 - # options: --health-cmd "redis-cli ping" --health-interval 10s --health-timeout 5s --health-retries 5 - - steps: - - name: Install packages - run: sudo apt-get update && sudo apt-get install --no-install-recommends -y google-chrome-stable curl libjemalloc2 libvips postgresql-client libpq-dev - - - name: Checkout code - uses: actions/checkout@v4 - - - name: Set up Ruby - uses: ruby/setup-ruby@v1 - with: - ruby-version: .ruby-version - bundler-cache: true - - <%- if using_node? -%> - - name: Setup Node - uses: actions/setup-node@v4 - with: - node-version-file: .node-version - - - name: Install modules - run: yarn install - <%- end -%> - - - name: Run tests - env: - RAILS_ENV: test - DATABASE_URL: postgres://postgres:postgres@localhost:5432 - # REDIS_URL: redis://localhost:6379/0 - <%- if using_rspec? -%> - run: bin/rails db:setup spec - <%- else -%> - run: bin/rails db:setup test test:system - <%- end -%> - - - name: Keep screenshots from failed system tests - uses: actions/upload-artifact@v4 - if: failure() - with: - name: screenshots - <%- if using_rspec? -%> - path: ${{ github.workspace }}/tmp/capybara - <%- else -%> - path: ${{ github.workspace }}/tmp/screenshots - <%- end -%> - if-no-files-found: ignore diff --git a/lib/generators/templates/email/email_interceptor.rb b/lib/generators/templates/email/email_interceptor.rb deleted file mode 100644 index 8ad791abd..000000000 --- a/lib/generators/templates/email/email_interceptor.rb +++ /dev/null @@ -1,11 +0,0 @@ -class EmailInterceptor - include ActiveSupport::Configurable - - config_accessor :interceptor_addresses, default: [] - - def self.delivering_email(message) - to = interceptor_addresses - - message.to = to if to.any? - end -end diff --git a/lib/generators/templates/factories/factories.rb b/lib/generators/templates/factories/factories.rb deleted file mode 100644 index 3bfcbd203..000000000 --- a/lib/generators/templates/factories/factories.rb +++ /dev/null @@ -1,2 +0,0 @@ -FactoryBot.define do -end diff --git a/lib/generators/templates/factories/factories_spec.rb b/lib/generators/templates/factories/factories_spec.rb deleted file mode 100644 index 91418c607..000000000 --- a/lib/generators/templates/factories/factories_spec.rb +++ /dev/null @@ -1,7 +0,0 @@ -require "rails_helper" - -RSpec.describe "Factories" do - it "has valid factoties" do - FactoryBot.lint traits: true - end -end diff --git a/lib/generators/templates/factories/factories_test.rb b/lib/generators/templates/factories/factories_test.rb deleted file mode 100644 index 23b78663d..000000000 --- a/lib/generators/templates/factories/factories_test.rb +++ /dev/null @@ -1,9 +0,0 @@ -require "test_helper" - -class FactoryBotsTest < ActiveSupport::TestCase - class FactoryLintingTest < FactoryBotsTest - test "linting of factories" do - FactoryBot.lint traits: true - end - end -end diff --git a/lib/generators/templates/factories/factory_bot_rspec.rb b/lib/generators/templates/factories/factory_bot_rspec.rb deleted file mode 100644 index 4943f172e..000000000 --- a/lib/generators/templates/factories/factory_bot_rspec.rb +++ /dev/null @@ -1,5 +0,0 @@ -FactoryBot.use_parent_strategy = true - -RSpec.configure do |config| - config.include FactoryBot::Syntax::Methods -end diff --git a/lib/generators/templates/inline_svg/inline_svg.rb b/lib/generators/templates/inline_svg/inline_svg.rb deleted file mode 100644 index d6cd050ae..000000000 --- a/lib/generators/templates/inline_svg/inline_svg.rb +++ /dev/null @@ -1,3 +0,0 @@ -InlineSvg.configure do |config| - config.raise_on_file_not_found = true -end diff --git a/lib/generators/templates/install/web/CONTRIBUTING.md b/lib/generators/templates/install/web/CONTRIBUTING.md deleted file mode 100644 index edf3161e6..000000000 --- a/lib/generators/templates/install/web/CONTRIBUTING.md +++ /dev/null @@ -1,94 +0,0 @@ -# Contributing - -## Accessibility Tooling - -Building accessible applications is a complex, multi-faceted, and mission critical endeavor. While tooling cannot guarantee an accessible experience, it can help raise the bar for the baseline experience in important ways. - -In addition to the W3C's [WAI Overview][], [WAI Authoring Practices Guide][], and [WAI-ARIA Specification][], along with MDN's [Accessibility Documentation][], the [thoughtbot handbook][] includes some high-level technical guidance. - -[WAI Overview]: https://www.w3.org/WAI/standards-guidelines/aria/ -[WAI Authoring Practices Guide]: https://www.w3.org/WAI/ARIA/apg/ -[WAI-ARIA Specification]: https://www.w3.org/TR/wai-aria/ -[Accessibility Documentation]: https://developer.mozilla.org/en-US/docs/Web/Accessibility -[thoughtbot guides]: https://github.com/thoughtbot/guides/blob/main/accessibility/README.md#development - -### Capybara and the System Test Suite - -[Capybara][] is responsible for driving the application's [System Test][] suite through Real Life browser sessions. - -Capybara drives the page and makes assertions about its state and content through utilities called [Selectors][]. They're a layer of abstraction that's a blend of HTML tag names and ARIA role semantics. For example, Capybara uses the `:link` selector whether it needs to locate and click on an `` element through a call to [click_link][] or make an assertion about the presence and content of an `` element through a call to [assert_link][]. - -Out of the box, Capybara provides a wide range of [built-in selectors][] that cover the majority of a System Test harness' needs. In addition to the out of the box selectors, this project also depends on the [capybara_accessible_selectors][] gem to expand Capybara's set of selectors. - -If you find yourself in a situation where you're reaching for CSS selectors or other means of resolving nodes, you might benefit from a built-in selector or one provided by `capybara_accessible_selectors`. Take this test block, for example: - -```ruby -#
-# Some fields -# -# -# -# -#
- -# BEFORE -within ".some-css .selector-chain" do - find(".my-button").click - find(".my-text-field").set "Hello, world" -end - -# AFTER -within :fieldset, "Some field" do - click_button "Click me" - fill_in "Fill me in", with: "Hello, world" -end -``` - -The [Testing RSpec][] section of the `thoughtbot/guides` provides some general guidance for automated Acceptance Testing. - -[Capybara]: https://rubydoc.info/github/teamcapybara/capybara/master/ -[System Test]: https://guides.rubyonrails.org/testing.html#system-testing -[Selectors]: https://rubydoc.info/github/teamcapybara/capybara/master#selectors -[click_link]: https://rubydoc.info/github/teamcapybara/capybara/master/Capybara/Node/Actions:click_link -[assert_link]: https://rubydoc.info/github/teamcapybara/capybara/master/Capybara/Minitest/Assertions:assert_link -[built-in selectors]: https://rubydoc.info/github/teamcapybara/capybara/master/Capybara/Selector#built-in-selectors -[capybara_accessible_selectors]: https://github.com/citizensadvice/capybara_accessible_selectors -[Testing RSpec]: https://github.com/thoughtbot/guides/blob/main/testing-rspec/README.md#acceptance-tests - -### `capybara_accessibility_audit` and `axe.js` - -This project depends on the [capybara_accessibility_audit][] gem to enhance the application's System Test suite to audit the browser's DOM for statically detectable accessibility violations. Under the hood, `capybara_accessibility_audit` utilizes [axe.js][] for auditing. - -The categories of violation that `capybara_accessibility_audit` can detect span a wide range from insufficient [color contrast][] to invalid or insufficient [landmark-based information hierarchy][landmark], to [unnamed form controls][] and beyond. - -Out of the box, `capybara_accessibility_audit` will extend Capybara to conduct an accessibility audit after a variety of actions like `visit` and `click_link`. That project can [be configured to suit this application's needs][capybara_accessibility_audit-configuration]. - -If you can integrate `capybara_accessibility_audit` from the project's inception, you can start with (and maintain!) accessibility violation bankruptcy. - -[capybara_accessibility_audit]: https://github.com/thoughtbot/capybara_accessibility_audit -[capybara_accessibility_audit-configuration]: https://github.com/thoughtbot/capybara_accessibility_audit?tab=readme-ov-file#frequently-asked-questions -[axe.js]: https://www.deque.com/axe/ -[color contrast]: https://developer.mozilla.org/en-US/docs/Web/Accessibility/Understanding_WCAG/Perceivable/Color_contrast -[landmark]: https://developer.mozilla.org/en-US/blog/aria-accessibility-html-landmark-roles/ -[unnamed form controls]: https://developer.mozilla.org/en-US/docs/Web/Accessibility/Understanding_WCAG/Text_labels_and_names#form_elements_must_be_labeled - -### VoiceOver on macos - -VoiceOver is a screen reader integrated directly into the macOS operating system. You can learn more from [Apple's Accessibility Support][]. - -VoiceOver and Safari are tightly integrated. If you're developing this -application on a Mac, you should familiarize yourself with how to navigate in -Safari using VoiceOver. You can learn more about how to use VoiceOver from the -[Get started with VoiceOver on Mac][]. You might also enjoy [Screen Reader -Basics: VoiceOver][] in the A11ycasts series of videos from the "Chrome for Developers" YouTube channel. - -[![Watch Screen Reader Basics: VoiceOver](https://img.youtube.com/vi/5R-6WvAihms/maxresdefault.jpg)](https://www.youtube.com/watch?v=5R-6WvAihms) - -After you've written a System Test or have completed a feature, it can be **extremely** valuable to navigate to that part of the application and try your best to recreate the experience based on keyboard navigation and screen reader announcements alone. - -[Apple's Accessibility Support]: https://support.apple.com/accessibility -[Get started with VoiceOver on Mac]: https://support.apple.com/guide/voiceover/get-started-vo4be8816d70/10/mac/14.0 -[Screen Reader Basics: VoiceOver]: https://www.youtube.com/watch?v=5R-6WvAihms diff --git a/lib/generators/templates/lint/config_better_html.yml b/lib/generators/templates/lint/config_better_html.yml deleted file mode 100644 index eb6826cff..000000000 --- a/lib/generators/templates/lint/config_better_html.yml +++ /dev/null @@ -1,2 +0,0 @@ ---- -allow_single_quoted_attributes: false diff --git a/lib/generators/templates/lint/config_initializers_better_html.rb b/lib/generators/templates/lint/config_initializers_better_html.rb deleted file mode 100644 index b117fade8..000000000 --- a/lib/generators/templates/lint/config_initializers_better_html.rb +++ /dev/null @@ -1,9 +0,0 @@ -Rails.configuration.to_prepare do - if Rails.env.test? - require "better_html" - - BetterHtml.config = BetterHtml::Config.new(Rails.configuration.x.better_html) - - BetterHtml.config.template_exclusion_filter = proc { |filename| !filename.start_with?(Rails.root.to_s) } - end -end diff --git a/lib/generators/templates/lint/erb-lint.yml b/lib/generators/templates/lint/erb-lint.yml deleted file mode 100644 index aac222c15..000000000 --- a/lib/generators/templates/lint/erb-lint.yml +++ /dev/null @@ -1,63 +0,0 @@ ---- -glob: "app/views/**/*.{html,turbo_stream}{+*,}.erb" - -linters: - AllowedScriptType: - enabled: true - allowed_types: - - "module" - - "text/javascript" - ErbSafety: - enabled: true - better_html_config: "config/better_html.yml" - GitHub::Accessibility::AvoidBothDisabledAndAriaDisabledCounter: - enabled: true - GitHub::Accessibility::AvoidGenericLinkTextCounter: - enabled: true - GitHub::Accessibility::DisabledAttributeCounter: - enabled: true - GitHub::Accessibility::IframeHasTitleCounter: - enabled: true - GitHub::Accessibility::ImageHasAltCounter: - enabled: true - GitHub::Accessibility::LandmarkHasLabelCounter: - enabled: true - GitHub::Accessibility::LinkHasHrefCounter: - enabled: true - GitHub::Accessibility::NestedInteractiveElementsCounter: - enabled: true - GitHub::Accessibility::NoAriaLabelMisuseCounter: - enabled: true - GitHub::Accessibility::NoPositiveTabIndexCounter: - enabled: true - GitHub::Accessibility::NoRedundantImageAltCounter: - enabled: true - GitHub::Accessibility::NoTitleAttributeCounter: - enabled: true - GitHub::Accessibility::SvgHasAccessibleTextCounter: - enabled: true - Rubocop: - enabled: true - rubocop_config: - inherit_from: - - .rubocop.yml - - Lint/EmptyBlock: - Enabled: false - Layout/InitialIndentation: - Enabled: false - Layout/TrailingEmptyLines: - Enabled: false - Layout/TrailingWhitespace: - Enabled: false - Layout/LeadingEmptyLines: - Enabled: false - Style/FrozenStringLiteralComment: - Enabled: false - Style/MultilineTernaryOperator: - Enabled: false - Lint/UselessAssignment: - Exclude: - - "app/views/**/*" - -EnableDefaultLinters: true diff --git a/lib/generators/templates/lint/erblint.rake b/lib/generators/templates/lint/erblint.rake deleted file mode 100644 index 804f572fc..000000000 --- a/lib/generators/templates/lint/erblint.rake +++ /dev/null @@ -1,47 +0,0 @@ -module ERBLint - module RakeSupport - # Allow command line flags set in STANDARDOPTS (like MiniTest's TESTOPTS) - def self.argvify - if ENV["ERBLINTOPTS"] - ENV["ERBLINTOPTS"].split(/\s+/) - else - [] - end - end - - # DELETE THIS FILE AFTER MERGE: - # - # * https://github.com/Shopify/better-html/pull/95 - # - def self.backport! - BetterHtml::TestHelper::SafeErb::AllowedScriptType::VALID_JAVASCRIPT_TAG_TYPES.push("module") - end - end -end - -desc "Lint templates with erb_lint" -task "erblint" do - require "erb_lint/cli" - require "erblint-github/linters" - - ERBLint::RakeSupport.backport! - - cli = ERBLint::CLI.new - success = cli.run(ERBLint::RakeSupport.argvify + ["--lint-all", "--format=compact"]) - fail unless success -end - -desc "Lint and automatically fix templates with erb_lint" -task "erblint:autocorrect" do - require "erb_lint/cli" - require "erblint-github/linters" - - ERBLint::RakeSupport.backport! - - cli = ERBLint::CLI.new - success = cli.run(ERBLint::RakeSupport.argvify + ["--lint-all", "--autocorrect"]) - fail unless success -end - -task "standard" => "erblint" -task "standard:fix" => "erblint:autocorrect" diff --git a/lib/generators/templates/lint/eslintrc.json b/lib/generators/templates/lint/eslintrc.json deleted file mode 100644 index 48e5b597f..000000000 --- a/lib/generators/templates/lint/eslintrc.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "extends": ["@thoughtbot/eslint-config/prettier"], - "parserOptions": { - "ecmaVersion": "latest", - "sourceType": "module" - } -} diff --git a/lib/generators/templates/lint/package.json b/lib/generators/templates/lint/package.json deleted file mode 100644 index dcd25e6e3..000000000 --- a/lib/generators/templates/lint/package.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "name": "app", - "private": "true" -} diff --git a/lib/generators/templates/lint/prettierignore b/lib/generators/templates/lint/prettierignore deleted file mode 100644 index f2056e58e..000000000 --- a/lib/generators/templates/lint/prettierignore +++ /dev/null @@ -1 +0,0 @@ -vendor/bundle/** diff --git a/lib/generators/templates/lint/prettierrc b/lib/generators/templates/lint/prettierrc deleted file mode 100644 index 1e8fc8e24..000000000 --- a/lib/generators/templates/lint/prettierrc +++ /dev/null @@ -1,11 +0,0 @@ -{ - "singleQuote": true, - "overrides": [ - { - "files": ["**/*.css", "**/*.scss", "**/*.html"], - "options": { - "singleQuote": false - } - } - ] -} diff --git a/lib/generators/templates/lint/rubocop.yml.tt b/lib/generators/templates/lint/rubocop.yml.tt deleted file mode 100644 index d6983a491..000000000 --- a/lib/generators/templates/lint/rubocop.yml.tt +++ /dev/null @@ -1,7 +0,0 @@ -AllCops: - TargetRubyVersion: <%= RUBY_VERSION %> - -require: standard - -inherit_gem: - standard: config/base.yml diff --git a/lib/generators/templates/lint/stylelintrc.json b/lib/generators/templates/lint/stylelintrc.json deleted file mode 100644 index 3171f405a..000000000 --- a/lib/generators/templates/lint/stylelintrc.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "extends": "@thoughtbot/stylelint-config" -} diff --git a/lib/generators/templates/prerequisites/node-version.tt b/lib/generators/templates/prerequisites/node-version.tt deleted file mode 100644 index e31b5f423..000000000 --- a/lib/generators/templates/prerequisites/node-version.tt +++ /dev/null @@ -1 +0,0 @@ -<%= node_version %> diff --git a/lib/generators/templates/setup/bin_setup.rb b/lib/generators/templates/setup/bin_setup.rb deleted file mode 100755 index a1ad3adfb..000000000 --- a/lib/generators/templates/setup/bin_setup.rb +++ /dev/null @@ -1,39 +0,0 @@ -#!/usr/bin/env ruby -require "fileutils" -require "bundler" - -# path to your application root. -APP_ROOT = File.expand_path("..", __dir__) - -def system!(*args) - system(*args, exception: true) -end - -def using_node? - File.exist? "package.json" -end - -FileUtils.chdir APP_ROOT do - puts "== Installing dependencies ==" - system! "gem install bundler --conservative" - system("bundle check") || system!("bundle install") - system("yarn install --check-files") if using_node? - - puts "\n== Preparing database and adding development seed data ==" - if File.exist? "lib/tasks/dev.rake" - system! "bin/rails dev:prime" - else - system! "bin/rails db:prepare" - end - - if Bundler.rubygems.find_name("sprockets") - puts "\n== Generating assets ==" - system! "bin/rails assets:clobber assets:precompile" - end - - puts "\n== Removing old logs and tempfiles ==" - system! "bin/rails log:clear tmp:clear" - - puts "\n== Restarting application server ==" - system! "bin/rails restart" -end diff --git a/lib/generators/templates/styles/postcss.config.js b/lib/generators/templates/styles/postcss.config.js deleted file mode 100644 index 9c48e607b..000000000 --- a/lib/generators/templates/styles/postcss.config.js +++ /dev/null @@ -1,11 +0,0 @@ -module.exports = { - plugins: [ - require('postcss-import'), - require('postcss-nesting'), - require('autoprefixer'), - require('postcss-url')({ - url: 'copy', - assetsPath: 'app/assets/static' - }) - ], -} diff --git a/lib/generators/templates/tasks/dev.rake b/lib/generators/templates/tasks/dev.rake deleted file mode 100644 index 7a94175f1..000000000 --- a/lib/generators/templates/tasks/dev.rake +++ /dev/null @@ -1,12 +0,0 @@ -if Rails.env.development? || Rails.env.test? - require "factory_bot" - - namespace :dev do - desc "Sample data for local development environment" - task prime: "db:setup" do - include FactoryBot::Syntax::Methods - - # create(:user, email: "user@example.com", password: "password") - end - end -end diff --git a/lib/generators/templates/testing/action_mailer.rb b/lib/generators/templates/testing/action_mailer.rb deleted file mode 100644 index b9563a3bc..000000000 --- a/lib/generators/templates/testing/action_mailer.rb +++ /dev/null @@ -1,5 +0,0 @@ -RSpec.configure do |config| - config.before(:each) do - ActionMailer::Base.deliveries.clear - end -end diff --git a/lib/generators/templates/testing/driver.rb b/lib/generators/templates/testing/driver.rb deleted file mode 100644 index 91e275b49..000000000 --- a/lib/generators/templates/testing/driver.rb +++ /dev/null @@ -1,5 +0,0 @@ -RSpec.configure do |config| - config.before(:each, type: :system) do - driven_by :selenium, using: :headless_chrome, screen_size: [1400, 1400] - end -end diff --git a/lib/generators/templates/testing/i18n.rb b/lib/generators/templates/testing/i18n.rb deleted file mode 100644 index 0c61ce662..000000000 --- a/lib/generators/templates/testing/i18n.rb +++ /dev/null @@ -1,3 +0,0 @@ -RSpec.configure do |config| - config.include ActionView::Helpers::TranslationHelper -end diff --git a/lib/generators/templates/testing/shoulda_matchers.rb b/lib/generators/templates/testing/shoulda_matchers.rb deleted file mode 100644 index 7d045f359..000000000 --- a/lib/generators/templates/testing/shoulda_matchers.rb +++ /dev/null @@ -1,6 +0,0 @@ -Shoulda::Matchers.configure do |config| - config.integrate do |with| - with.test_framework :rspec - with.library :rails - end -end diff --git a/lib/generators/templates/views/flashes.html.erb b/lib/generators/templates/views/flashes.html.erb deleted file mode 100644 index ae9805a03..000000000 --- a/lib/generators/templates/views/flashes.html.erb +++ /dev/null @@ -1,7 +0,0 @@ -<% if flash.any? %> -
- <% flash.each do |type, message| -%> -
<%= message %>
- <% end -%> -
-<% end %> diff --git a/lib/install/web.rb b/lib/install/web.rb deleted file mode 100644 index 1796f474a..000000000 --- a/lib/install/web.rb +++ /dev/null @@ -1,70 +0,0 @@ -def node_version - ENV["NODE_VERSION"] || `node --version`[/\d+\.\d+\.\d+/] -end - -def node_not_installed? - !node_version.present? -end - -def node_version_unsupported? - node_version < "20.0.0" -end - -def apply_template! - if node_not_installed? || node_version_unsupported? - message = <<~ERROR - - - === Node version unsupported === - - Suspenders requires Node >= 20.0.0 - ERROR - - fail Rails::Generators::Error, message - end - if options[:database] == "postgresql" && options[:skip_test] && options[:skip_rubocop] - after_bundle do - gem_group :development, :test do - if ARGV.include?("--suspenders-main") - gem "suspenders", github: "thoughtbot/suspenders", branch: "main" - else - gem "suspenders" - end - end - - run "bundle install" - - generate "suspenders:install:web" - rails_command "db:prepare" - rails_command "db:migrate" - - say "\nCongratulations! You just pulled our suspenders." - end - else - message = <<~ERROR - - - === Please use the correct options === - - # Use the latest suspenders release: - rails new \\ - --skip-rubocop \\ - --skip-test \\ - -d=postgresql \\ - -m=https://raw.githubusercontent.com/thoughtbot/suspenders/main/lib/install/web.rb - - # OR use the current (possibly unreleased) `main` branch of suspenders: - rails new \\ - --suspenders-main \\ - --skip-rubocop \\ - --skip-test \\ - -d=postgresql \\ - -m=https://raw.githubusercontent.com/thoughtbot/suspenders/main/lib/install/web.rb - - ERROR - - fail Rails::Generators::Error, message - end -end - -apply_template! diff --git a/lib/suspenders.rb b/lib/suspenders.rb index 5042db8bf..1642f84d0 100644 --- a/lib/suspenders.rb +++ b/lib/suspenders.rb @@ -1,10 +1,9 @@ -require "suspenders/version" -require "suspenders/engine" -require "suspenders/railtie" -require "suspenders/generators" -require "suspenders/cleanup/organize_gemfile" -require "suspenders/cleanup/generate_readme" +# frozen_string_literal: true + +require_relative "suspenders/version" +require_relative "suspenders/cli" module Suspenders + class Error < StandardError; end # Your code goes here... end diff --git a/lib/suspenders/cleanup/generate_readme.rb b/lib/suspenders/cleanup/generate_readme.rb deleted file mode 100644 index a37e6be65..000000000 --- a/lib/suspenders/cleanup/generate_readme.rb +++ /dev/null @@ -1,165 +0,0 @@ -require "rails/generators" -require_relative "../../generators/suspenders/environments/development_generator" -require_relative "../../generators/suspenders/environments/test_generator" -require_relative "../../generators/suspenders/environments/production_generator" -require_relative "../../generators/suspenders/accessibility_generator" -require_relative "../../generators/suspenders/advisories_generator" -require_relative "../../generators/suspenders/email_generator" -require_relative "../../generators/suspenders/factories_generator" -require_relative "../../generators/suspenders/inline_svg_generator" -require_relative "../../generators/suspenders/jobs_generator" -require_relative "../../generators/suspenders/lint_generator" -require_relative "../../generators/suspenders/styles_generator" -require_relative "../../generators/suspenders/testing_generator" -require_relative "../../generators/suspenders/views_generator" - -module Suspenders - module Cleanup - class GenerateReadme - include Suspenders::Generators::Helpers - - def self.perform(readme, app_name) - new(readme, app_name).perform - end - - attr_reader :readme, :app_name - - def initialize(readme, app_name) - @readme = readme - @app_name = app_name - end - - def perform - File.open(readme, "w+") do |file| - @file = file - - heading app_name.titleize, level: 1 - - prerequisites - - local_development - - heading "Configuration", level: 2 - - heading "Test", level: 3 - description_for Suspenders::Generators::Environments::TestGenerator - - heading "Development", level: 3 - description_for Suspenders::Generators::Environments::DevelopmentGenerator - - heading "Production", level: 3 - description_for Suspenders::Generators::Environments::ProductionGenerator - - heading "Linting", level: 3 - description_for Suspenders::Generators::LintGenerator - - heading "Testing", level: 2 - description_for Suspenders::Generators::TestingGenerator - - heading "Factories", level: 3 - description_for Suspenders::Generators::FactoriesGenerator - - heading "Accessibility", level: 2 - description_for Suspenders::Generators::AccessibilityGenerator - content <<~MARKDOWN - For more information, review the [Accessibility Tooling][] section in - the [CONTRIBUTING][] guide. - - [Accessibility Tooling]: ./CONTRIBUTING.md#accessibility-tooling - [CONTRIBUTING]: ./CONTRIBUTING.md - MARKDOWN - new_line - - heading "Advisories", level: 2 - description_for Suspenders::Generators::AdvisoriesGenerator - - heading "Mailers", level: 2 - description_for Suspenders::Generators::EmailGenerator - - heading "Jobs", level: 2 - description_for Suspenders::Generators::JobsGenerator - - heading "Layout and Assets", level: 2 - - heading "Stylesheets", level: 3 - description_for Suspenders::Generators::StylesGenerator - - heading "Inline SVG", level: 3 - description_for Suspenders::Generators::InlineSvgGenerator - - heading "Layout", level: 3 - description_for Suspenders::Generators::ViewsGenerator - end - end - - private - - def content(text) - @file.write text - end - - def new_line - @file.write "\n" - end - - def heading(text, level:) - @file.write "#{"#" * level} #{text}\n" - new_line - end - - def description_for(generator) - @file.write generator.desc - new_line - end - - def local_development - @file.write <<~MARKDOWN - ## Local Development - - ### Initial Setup - - ``` - bin/setup - ``` - - ### Running the Development Server - - ``` - bin/dev - ``` - - ### Seed Data - - - Use `db/seeds.rb` to create records that need to exist in all environments. - - Use `lib/tasks/dev.rake` to create records that only need to exist in development. - - Running `bin/setup` will run `dev:prime`. - - ### Tasks - - - Use `bin/rails suspenders:db:migrate` to run [database migrations][]. This script ensures they are [reversible][]. - - Use `bin/rails suspenders:cleanup:organize_gemfile` to automatically organize the project's Gemfile. - - Use `bin/rails default` to run the default Rake task. This will do the following: - - Run the test suite. - - Run a Ruby and ERB linter. - - Scan the Ruby codebase for any dependency vulnerabilities. - - [database migrations]: https://edgeguides.rubyonrails.org/active_record_migrations.html#running-migrations - [reversible]: https://edgeguides.rubyonrails.org/active_record_migrations.html#making-the-irreversible-possible - - MARKDOWN - end - - def prerequisites - heading "Prerequisites", level: 2 - - @file.write <<~MARKDOWN - Ruby: `#{Suspenders::MINIMUM_RUBY_VERSION}` - Node: `#{node_version}` - MARKDOWN - - new_line - end - end - end -end diff --git a/lib/suspenders/cleanup/organize_gemfile.rb b/lib/suspenders/cleanup/organize_gemfile.rb deleted file mode 100644 index bc5b59e43..000000000 --- a/lib/suspenders/cleanup/organize_gemfile.rb +++ /dev/null @@ -1,134 +0,0 @@ -module Suspenders - module Cleanup - class OrganizeGemfile - def self.perform(gemfile) - new(gemfile).perform - end - - attr_reader :gemfile, :current_lines, :new_lines, :new_line_markers, - :current_group, :gem_groups - - def initialize(gemfile) - @gemfile = gemfile - - @current_lines = File.read(gemfile).lines - @new_lines = [] - @new_line_markers = [] - - @current_group = nil - @gem_groups = {} - end - - def perform - remove_line_breaks - sort_gems_and_groups - add_gem_groups_to_gemfile - add_line_breaks - cleanup - - File.open(gemfile, "w+") { _1.write new_lines.join } - end - - private - - def remove_line_breaks - current_lines.delete("\n") - end - - def sort_gems_and_groups - current_lines.each do |line| - if line.starts_with?(/group/) - @current_group = line - end - - # Consolidate gem groups - if current_group - if line.starts_with?(/end/) - @current_group = nil - elsif !line.starts_with?(/group/) - gem_groups[current_group] ||= [] - gem_groups[current_group] << line - end - # Add non-grouped gems - elsif !line.starts_with?(/\n/) - new_lines << line - @current_group = nil - end - end - end - - def add_gem_groups_to_gemfile - gem_groups.keys.each do |group| - gems = gem_groups[group] - - gems.each_with_index do |gem, index| - if index == 0 - new_lines << group - end - - new_lines << gem - - if gems.size == (index + 1) - new_lines << "end\n" - end - end - end - end - - def add_line_breaks - new_lines.each_with_index do |line, index| - previous_line = new_lines[index - 1] if index > 0 - next_line = new_lines[index + 1] - marker = index + 1 - - # Add line break if it's a gem and the next line is commented out - if (line.starts_with?(/\s*gem/) || line.starts_with?(/\s*\#\s*gem/)) && next_line&.starts_with?(/\s*\#/) - new_line_markers << marker - end - - # Add line break if it's a commented out gem and the next line is a gem - if line.starts_with?(/\s*\#\s*gem/) && next_line&.starts_with?(/\s*gem/) - new_line_markers << marker - end - - # Add line break if it's a gem with a comment and the next line is a gem - if previous_line&.starts_with?(/\s*\#/) \ - && line.starts_with?(/\s*gem/) \ - && next_line&.starts_with?(/\s*gem/) \ - && !previous_line.starts_with?(/\s*\#\s*gem/) - new_line_markers << marker - end - - # Add a line break if it's /end/ - if line.starts_with?(/end/) - new_line_markers << marker - end - - # Add a line break if it's a gem and the next line is a group - if line.starts_with?(/gem/) && next_line&.starts_with?(/group/) - new_line_markers << marker - end - - # Add line break if it's /source/ or /ruby/ - if line.starts_with?(/\w/) && !line.starts_with?(/\s*(gem|group|end)/) - new_line_markers << marker - end - end - - new_line_markers.each_with_index do |marker, index| - # Each time we insert, the original marker if off by 1 - marker_offset = marker + index - - new_lines.insert(marker_offset, "\n") - end - end - - def cleanup - # Remove last line - if /\n/.match?(new_lines.last) - new_lines.pop - end - end - end - end -end diff --git a/lib/suspenders/cli.rb b/lib/suspenders/cli.rb new file mode 100644 index 000000000..bc48362d0 --- /dev/null +++ b/lib/suspenders/cli.rb @@ -0,0 +1,45 @@ +# frozen_string_literal: true + +module Suspenders + class CLI + BASE_OPTIONS = [ + "-d=postgresql", + "--skip-test", + "--skip-solid" + ] + + def initialize(app_name) + @app_name = app_name + end + + def self.run(app_name) + new(app_name).run + end + + def run + verify_rails_exists! + generate_new_rails_app + end + + private + + attr_reader :app_name + + def verify_rails_exists! + unless system("which", "rails", out: File::NULL, err: File::NULL) + raise Error, "Rails not found. Install with: gem install rails" + end + end + + def generate_new_rails_app + template_path = File.expand_path("../templates/web.rb", __dir__) + options = BASE_OPTIONS + ["-m=#{template_path}"] + + if system("rails", "new", app_name, *options) + true + else + raise Error, "Failed to create Rails app" + end + end + end +end diff --git a/lib/suspenders/engine.rb b/lib/suspenders/engine.rb deleted file mode 100644 index 3b3f851f6..000000000 --- a/lib/suspenders/engine.rb +++ /dev/null @@ -1,5 +0,0 @@ -module Suspenders - class Engine < ::Rails::Engine - isolate_namespace Suspenders - end -end diff --git a/lib/suspenders/generators.rb b/lib/suspenders/generators.rb deleted file mode 100644 index 9d3426044..000000000 --- a/lib/suspenders/generators.rb +++ /dev/null @@ -1,126 +0,0 @@ -require "active_support/concern" - -module Suspenders - module Generators - module Helpers - def default_test_suite? - File.exist? Rails.root.join("test") - end - - def rspec_test_suite? - File.exist? Rails.root.join("spec/spec_helper.rb") - end - - def default_test_helper_present? - File.exist? Rails.root.join("test/test_helper.rb") - end - - def rspec_test_helper_present? - File.exist? Rails.root.join("spec/rails_helper.rb") - end - - def node_version - ENV["NODE_VERSION"] || `node --version`[/\d+\.\d+\.\d+/] - end - - def node_not_installed? - !node_version.present? - end - - def node_version_unsupported? - node_version < Suspenders::MINIMUM_NODE_VERSION - end - end - - 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 - - module DatabaseUnsupported - include Helpers - - class Error < StandardError - def message - "This generator requires PostgreSQL" - end - end - - extend ActiveSupport::Concern - - included do - def raise_if_database_unsupported - if database_unsupported? - raise Suspenders::Generators::DatabaseUnsupported::Error - end - end - - private - - def database_unsupported? - configuration = File.read(Rails.root.join("config/database.yml")) - configuration = YAML.safe_load(configuration, aliases: true) - adapter = configuration["default"]["adapter"] - - adapter != "postgresql" - end - end - end - - module NodeNotInstalled - class Error < StandardError - def message - "This generator requires Node" - end - end - - extend ActiveSupport::Concern - - included do - def raise_if_node_not_installed - if node_not_installed? - raise Suspenders::Generators::NodeNotInstalled::Error - end - end - end - end - - module NodeVersionUnsupported - class Error < StandardError - def message - "This generator requires Node >= #{Suspenders::MINIMUM_NODE_VERSION}" - end - end - - extend ActiveSupport::Concern - - included do - def raise_if_node_version_unsupported - if node_version_unsupported? - raise Suspenders::Generators::NodeVersionUnsupported::Error - end - end - end - end - end -end diff --git a/lib/suspenders/railtie.rb b/lib/suspenders/railtie.rb deleted file mode 100644 index 7f02195b1..000000000 --- a/lib/suspenders/railtie.rb +++ /dev/null @@ -1,4 +0,0 @@ -module Suspenders - class Railtie < ::Rails::Railtie - end -end diff --git a/lib/suspenders/version.rb b/lib/suspenders/version.rb index 66d87f777..c107946b8 100644 --- a/lib/suspenders/version.rb +++ b/lib/suspenders/version.rb @@ -1,6 +1,6 @@ +# frozen_string_literal: true + module Suspenders - VERSION = "20250317.0".freeze - RAILS_VERSION = "~> 8.0".freeze - MINIMUM_RUBY_VERSION = ">= 3.1".freeze - MINIMUM_NODE_VERSION = "20.0.0".freeze + VERSION = "20251211.0" + MINIMUM_RUBY_VERSION = ">= 3.2.0" end diff --git a/lib/tasks/suspenders.rake b/lib/tasks/suspenders.rake deleted file mode 100644 index d01d99470..000000000 --- a/lib/tasks/suspenders.rake +++ /dev/null @@ -1,37 +0,0 @@ -namespace :suspenders do - desc "Extend the default Rails Rake task" - task :rake do - if Bundler.rubygems.find_name("bundler-audit").any? - Rake::Task[:"bundle:audit"].invoke - end - - if Bundler.rubygems.find_name("standard").any? - Rake::Task[:standard].invoke - end - end - - desc "Ensure a migration is reversible" - namespace :db do - task :migrate do - Rake::Task["db:migrate"].invoke - Rake::Task["db:rollback"].invoke - - Rake::Task["db:migrate"].reenable - Rake::Task["db:migrate"].invoke - - Rake::Task["db:test:prepare"].invoke - end - end - - namespace :cleanup do - desc "Organizes Gemfile" - task organize_gemfile: :environment do - Suspenders::Cleanup::OrganizeGemfile.perform(Rails.root.join("Gemfile")) - end - - desc "Generate README" - task :generate_readme do - Suspenders::Cleanup::GenerateReadme.perform(Rails.root.join("README.md"), Rails.application.class.module_parent_name) - end - end -end diff --git a/lib/templates/web.rb b/lib/templates/web.rb new file mode 100644 index 000000000..5b9fc0006 --- /dev/null +++ b/lib/templates/web.rb @@ -0,0 +1,32 @@ +# Methods like `copy_file` will accept relative paths to the template's location. +def source_paths + Array(super) + [__dir__] +end + +def install_gems +end + +install_gems + +after_bundle do + # Finalization + run_migrations + lint_codebase + + print_message +end + +def run_migrations + rails_command "db:create" + rails_command "db:migrate" +end + +def lint_codebase + run "bin/rubocop -a" +end + +def print_message + say "*" * 50 + say "Congratulations! You just pulled our suspenders." + say "*" * 50 +end diff --git a/sig/suspenders.rbs b/sig/suspenders.rbs new file mode 100644 index 000000000..d579cbc31 --- /dev/null +++ b/sig/suspenders.rbs @@ -0,0 +1,4 @@ +module Suspenders + VERSION: String + # See the writing guide of rbs: https://github.com/ruby/rbs#guides +end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb new file mode 100644 index 000000000..8992dec19 --- /dev/null +++ b/spec/spec_helper.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +require "suspenders" + +RSpec.configure do |config| + # Enable flags like --only-failures and --next-failure + config.example_status_persistence_file_path = ".rspec_status" + + # Disable RSpec exposing methods globally on `Module` and `main` + config.disable_monkey_patching! + + config.expect_with :rspec do |c| + c.syntax = :expect + end +end diff --git a/spec/suspenders_spec.rb b/spec/suspenders_spec.rb new file mode 100644 index 000000000..e36fe9d56 --- /dev/null +++ b/spec/suspenders_spec.rb @@ -0,0 +1,89 @@ +# frozen_string_literal: true + +RSpec.describe Suspenders do + it "has a version number" do + expect(Suspenders::VERSION).not_to be nil + end + + describe Suspenders::CLI do + let(:stub_success) { + allow_any_instance_of(Suspenders::CLI).to receive(:system).and_return(true) + } + + before do + stub_success + end + + describe ".run" do + it "calls rails new with expected arguments" do + template_path = File.expand_path("../lib/templates/web.rb", __dir__) + args = [ + "rails", + "new", + "app_name", + "-d=postgresql", + "--skip-test", + "--skip-solid", + "-m=#{template_path}" + ] + + expect_any_instance_of(Suspenders::CLI).to receive(:system).with(*args) + + Suspenders::CLI.run("app_name") + end + + it "returns true" do + result = Suspenders::CLI.run("app_name") + + expect(result).to eq true + end + + context "when rails does not exist" do + let(:stub_failure) { + allow_any_instance_of(Suspenders::CLI).to receive(:system).with( + "which", "rails", out: File::NULL, err: File::NULL + ).and_return(false) + } + + before do + stub_failure + end + + it "raises" do + expect { + Suspenders::CLI.run("app_name") + }.to raise_error(Suspenders::Error, "Rails not found. Install with: gem install rails") + end + end + + context "when rails fails to install" do + let(:app_name) { "app_name" } + let(:template_path) { File.expand_path("../lib/templates/web.rb", __dir__) } + let(:args) { + [ + "rails", + "new", + app_name, + "-d=postgresql", + "--skip-test", + "--skip-solid", + "-m=#{template_path}" + ] + } + let(:stub_failure) { + allow_any_instance_of(Suspenders::CLI).to receive(:system).with(*args).and_return(false) + } + + before do + stub_failure + end + + it "raises" do + expect { + Suspenders::CLI.run(app_name) + }.to raise_error(Suspenders::Error, "Failed to create Rails app") + end + end + end + end +end diff --git a/suspenders.gemspec b/suspenders.gemspec index c6fc589fa..4fbb7c101 100644 --- a/suspenders.gemspec +++ b/suspenders.gemspec @@ -21,13 +21,14 @@ Gem::Specification.new do |spec| spec.metadata["source_code_uri"] = spec.homepage spec.metadata["changelog_uri"] = "https://github.com/thoughtbot/suspenders/blob/main/NEWS.md" - spec.files = Dir.chdir(File.expand_path(__dir__)) do - Dir["{app,config,db,lib}/**/*", "MIT-LICENSE", "Rakefile", "README.md"] + gemspec = File.basename(__FILE__) + spec.files = IO.popen(%w[git ls-files -z], chdir: __dir__, err: IO::NULL) do |ls| + ls.readlines("\x0", chomp: true).reject do |f| + (f == gemspec) || + f.start_with?(*%w[bin/ Gemfile .gitignore .rspec spec/ .github/ .standard.yml]) + end end - - spec.add_dependency "rails", Suspenders::RAILS_VERSION - - spec.add_development_dependency "climate_control" - spec.add_development_dependency "mocha" - spec.add_development_dependency "standard" + spec.bindir = "exe" + spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) } + spec.require_paths = ["lib"] end diff --git a/test/dummy/Rakefile b/test/dummy/Rakefile deleted file mode 100644 index 9a5ea7383..000000000 --- a/test/dummy/Rakefile +++ /dev/null @@ -1,6 +0,0 @@ -# Add your own tasks in files placed in lib/tasks ending in .rake, -# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. - -require_relative "config/application" - -Rails.application.load_tasks diff --git a/test/dummy/app/assets/images/.keep b/test/dummy/app/assets/images/.keep deleted file mode 100644 index e69de29bb..000000000 diff --git a/test/dummy/app/assets/stylesheets/application.css b/test/dummy/app/assets/stylesheets/application.css deleted file mode 100644 index dcd72732e..000000000 --- a/test/dummy/app/assets/stylesheets/application.css +++ /dev/null @@ -1 +0,0 @@ -/* Application styles */ diff --git a/test/dummy/app/channels/application_cable/channel.rb b/test/dummy/app/channels/application_cable/channel.rb deleted file mode 100644 index d67269728..000000000 --- a/test/dummy/app/channels/application_cable/channel.rb +++ /dev/null @@ -1,4 +0,0 @@ -module ApplicationCable - class Channel < ActionCable::Channel::Base - end -end diff --git a/test/dummy/app/channels/application_cable/connection.rb b/test/dummy/app/channels/application_cable/connection.rb deleted file mode 100644 index 0ff5442f4..000000000 --- a/test/dummy/app/channels/application_cable/connection.rb +++ /dev/null @@ -1,4 +0,0 @@ -module ApplicationCable - class Connection < ActionCable::Connection::Base - end -end diff --git a/test/dummy/app/controllers/application_controller.rb b/test/dummy/app/controllers/application_controller.rb deleted file mode 100644 index 09705d12a..000000000 --- a/test/dummy/app/controllers/application_controller.rb +++ /dev/null @@ -1,2 +0,0 @@ -class ApplicationController < ActionController::Base -end diff --git a/test/dummy/app/controllers/concerns/.keep b/test/dummy/app/controllers/concerns/.keep deleted file mode 100644 index e69de29bb..000000000 diff --git a/test/dummy/app/helpers/application_helper.rb b/test/dummy/app/helpers/application_helper.rb deleted file mode 100644 index de6be7945..000000000 --- a/test/dummy/app/helpers/application_helper.rb +++ /dev/null @@ -1,2 +0,0 @@ -module ApplicationHelper -end diff --git a/test/dummy/app/jobs/application_job.rb b/test/dummy/app/jobs/application_job.rb deleted file mode 100644 index d394c3d10..000000000 --- a/test/dummy/app/jobs/application_job.rb +++ /dev/null @@ -1,7 +0,0 @@ -class ApplicationJob < ActiveJob::Base - # Automatically retry jobs that encountered a deadlock - # retry_on ActiveRecord::Deadlocked - - # Most jobs are safe to ignore if the underlying records are no longer available - # discard_on ActiveJob::DeserializationError -end diff --git a/test/dummy/app/mailers/application_mailer.rb b/test/dummy/app/mailers/application_mailer.rb deleted file mode 100644 index 3c34c8148..000000000 --- a/test/dummy/app/mailers/application_mailer.rb +++ /dev/null @@ -1,4 +0,0 @@ -class ApplicationMailer < ActionMailer::Base - default from: "from@example.com" - layout "mailer" -end diff --git a/test/dummy/app/models/application_record.rb b/test/dummy/app/models/application_record.rb deleted file mode 100644 index b63caeb8a..000000000 --- a/test/dummy/app/models/application_record.rb +++ /dev/null @@ -1,3 +0,0 @@ -class ApplicationRecord < ActiveRecord::Base - primary_abstract_class -end diff --git a/test/dummy/app/models/concerns/.keep b/test/dummy/app/models/concerns/.keep deleted file mode 100644 index e69de29bb..000000000 diff --git a/test/dummy/app/views/layouts/application.html.erb b/test/dummy/app/views/layouts/application.html.erb deleted file mode 100644 index f72b4ef0e..000000000 --- a/test/dummy/app/views/layouts/application.html.erb +++ /dev/null @@ -1,15 +0,0 @@ - - - - Dummy - - <%= csrf_meta_tags %> - <%= csp_meta_tag %> - - <%= stylesheet_link_tag "application" %> - - - - <%= yield %> - - diff --git a/test/dummy/app/views/layouts/mailer.html.erb b/test/dummy/app/views/layouts/mailer.html.erb deleted file mode 100644 index 3aac9002e..000000000 --- a/test/dummy/app/views/layouts/mailer.html.erb +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - <%= yield %> - - diff --git a/test/dummy/app/views/layouts/mailer.text.erb b/test/dummy/app/views/layouts/mailer.text.erb deleted file mode 100644 index 37f0bddbd..000000000 --- a/test/dummy/app/views/layouts/mailer.text.erb +++ /dev/null @@ -1 +0,0 @@ -<%= yield %> diff --git a/test/dummy/bin/dev b/test/dummy/bin/dev deleted file mode 100755 index 5f91c2054..000000000 --- a/test/dummy/bin/dev +++ /dev/null @@ -1,2 +0,0 @@ -#!/usr/bin/env ruby -exec "./bin/rails", "server", *ARGV diff --git a/test/dummy/bin/rails b/test/dummy/bin/rails deleted file mode 100755 index efc037749..000000000 --- a/test/dummy/bin/rails +++ /dev/null @@ -1,4 +0,0 @@ -#!/usr/bin/env ruby -APP_PATH = File.expand_path("../config/application", __dir__) -require_relative "../config/boot" -require "rails/commands" diff --git a/test/dummy/bin/rake b/test/dummy/bin/rake deleted file mode 100755 index 4fbf10b96..000000000 --- a/test/dummy/bin/rake +++ /dev/null @@ -1,4 +0,0 @@ -#!/usr/bin/env ruby -require_relative "../config/boot" -require "rake" -Rake.application.run diff --git a/test/dummy/bin/rubocop b/test/dummy/bin/rubocop deleted file mode 100755 index 40330c0ff..000000000 --- a/test/dummy/bin/rubocop +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env ruby -require "rubygems" -require "bundler/setup" - -# explicit rubocop config increases performance slightly while avoiding config confusion. -ARGV.unshift("--config", File.expand_path("../.rubocop.yml", __dir__)) - -load Gem.bin_path("rubocop", "rubocop") diff --git a/test/dummy/bin/setup b/test/dummy/bin/setup deleted file mode 100755 index 3de958a14..000000000 --- a/test/dummy/bin/setup +++ /dev/null @@ -1,34 +0,0 @@ -#!/usr/bin/env ruby -require "fileutils" - -APP_ROOT = File.expand_path("..", __dir__) - -def system!(*args) - system(*args, exception: true) -end - -FileUtils.chdir APP_ROOT do - # This script is a way to set up or update your development environment automatically. - # This script is idempotent, so that you can run it at any time and get an expectable outcome. - # Add necessary setup steps to this file. - - puts "== Installing dependencies ==" - system("bundle check") || system!("bundle install") - - # puts "\n== Copying sample files ==" - # unless File.exist?("config/database.yml") - # FileUtils.cp "config/database.yml.sample", "config/database.yml" - # end - - puts "\n== Preparing database ==" - system! "bin/rails db:prepare" - - puts "\n== Removing old logs and tempfiles ==" - system! "bin/rails log:clear tmp:clear" - - unless ARGV.include?("--skip-server") - puts "\n== Starting development server ==" - $stdout.flush # flush the output before exec(2) so that it displays - exec "bin/dev" - end -end diff --git a/test/dummy/bin/thrust b/test/dummy/bin/thrust deleted file mode 100755 index 36bde2d83..000000000 --- a/test/dummy/bin/thrust +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env ruby -require "rubygems" -require "bundler/setup" - -load Gem.bin_path("thruster", "thrust") diff --git a/test/dummy/config.ru b/test/dummy/config.ru deleted file mode 100644 index 4a3c09a68..000000000 --- a/test/dummy/config.ru +++ /dev/null @@ -1,6 +0,0 @@ -# This file is used by Rack-based servers to start the application. - -require_relative "config/environment" - -run Rails.application -Rails.application.load_server diff --git a/test/dummy/config/application.rb b/test/dummy/config/application.rb deleted file mode 100644 index 636d329c2..000000000 --- a/test/dummy/config/application.rb +++ /dev/null @@ -1,26 +0,0 @@ -require_relative "boot" - -require "rails/all" - -# Require the gems listed in Gemfile, including any gems -# you've limited to :test, :development, or :production. -Bundler.require(*Rails.groups) - -module Dummy - class Application < Rails::Application - config.load_defaults Rails::VERSION::STRING.to_f - - # Please, add to the `ignore` list any other `lib` subdirectories that do - # not contain `.rb` files, or that should not be reloaded or eager loaded. - # Common ones are `templates`, `generators`, or `middleware`, for example. - config.autoload_lib(ignore: %w[assets tasks]) - - # Configuration for the application, engines, and railties goes here. - # - # These settings can be overridden in specific environments using the files - # in config/environments, which are processed later. - # - # config.time_zone = "Central Time (US & Canada)" - # config.eager_load_paths << Rails.root.join("extras") - end -end diff --git a/test/dummy/config/boot.rb b/test/dummy/config/boot.rb deleted file mode 100644 index ee3b04d2c..000000000 --- a/test/dummy/config/boot.rb +++ /dev/null @@ -1,4 +0,0 @@ -# Set up gems listed in the Gemfile. -ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../../Gemfile", __dir__) - -require "bundler/setup" # Set up gems listed in the Gemfile. diff --git a/test/dummy/config/cable.yml b/test/dummy/config/cable.yml deleted file mode 100644 index 98367f895..000000000 --- a/test/dummy/config/cable.yml +++ /dev/null @@ -1,10 +0,0 @@ -development: - adapter: async - -test: - adapter: test - -production: - adapter: redis - url: <%= ENV.fetch("REDIS_URL") { "redis://localhost:6379/1" } %> - channel_prefix: dummy_production diff --git a/test/dummy/config/database.yml b/test/dummy/config/database.yml deleted file mode 100644 index 796466ba2..000000000 --- a/test/dummy/config/database.yml +++ /dev/null @@ -1,25 +0,0 @@ -# SQLite. Versions 3.8.0 and up are supported. -# gem install sqlite3 -# -# Ensure the SQLite 3 gem is defined in your Gemfile -# gem "sqlite3" -# -default: &default - adapter: sqlite3 - pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> - timeout: 5000 - -development: - <<: *default - database: storage/development.sqlite3 - -# Warning: The database defined as "test" will be erased and -# re-generated from your development database when you run "rake". -# Do not set this db to the same as development or production. -test: - <<: *default - database: storage/test.sqlite3 - -production: - <<: *default - database: storage/production.sqlite3 diff --git a/test/dummy/config/environment.rb b/test/dummy/config/environment.rb deleted file mode 100644 index cac531577..000000000 --- a/test/dummy/config/environment.rb +++ /dev/null @@ -1,5 +0,0 @@ -# Load the Rails application. -require_relative "application" - -# Initialize the Rails application. -Rails.application.initialize! diff --git a/test/dummy/config/environments/development.rb b/test/dummy/config/environments/development.rb deleted file mode 100644 index 4ba93a0c1..000000000 --- a/test/dummy/config/environments/development.rb +++ /dev/null @@ -1,72 +0,0 @@ -require "active_support/core_ext/integer/time" - -Rails.application.configure do - # Settings specified here will take precedence over those in config/application.rb. - - # Make code changes take effect immediately without server restart. - config.enable_reloading = true - - # Do not eager load code on boot. - config.eager_load = false - - # Show full error reports. - config.consider_all_requests_local = true - - # Enable server timing. - config.server_timing = true - - # Enable/disable Action Controller caching. By default Action Controller caching is disabled. - # Run rails dev:cache to toggle Action Controller caching. - if Rails.root.join("tmp/caching-dev.txt").exist? - config.action_controller.perform_caching = true - config.action_controller.enable_fragment_cache_logging = true - config.public_file_server.headers = {"cache-control" => "public, max-age=#{2.days.to_i}"} - else - config.action_controller.perform_caching = false - end - - # Change to :null_store to avoid any caching. - config.cache_store = :memory_store - - # Store uploaded files on the local file system (see config/storage.yml for options). - config.active_storage.service = :local - - # Don't care if the mailer can't send. - config.action_mailer.raise_delivery_errors = false - - # Make template changes take effect immediately. - config.action_mailer.perform_caching = false - - # Set localhost to be used by links generated in mailer templates. - config.action_mailer.default_url_options = {host: "localhost", port: 3000} - - # Print deprecation notices to the Rails logger. - config.active_support.deprecation = :log - - # Raise an error on page load if there are pending migrations. - config.active_record.migration_error = :page_load - - # Highlight code that triggered database queries in logs. - config.active_record.verbose_query_logs = true - - # Append comments with runtime information tags to SQL queries in logs. - config.active_record.query_log_tags_enabled = true - - # Highlight code that enqueued background job in logs. - config.active_job.verbose_enqueue_logs = true - - # Raises error for missing translations. - # config.i18n.raise_on_missing_translations = true - - # Annotate rendered view with file names. - config.action_view.annotate_rendered_view_with_filenames = true - - # Uncomment if you wish to allow Action Cable access from any origin. - # config.action_cable.disable_request_forgery_protection = true - - # Raise error when a before_action's only/except options reference missing actions. - config.action_controller.raise_on_missing_callback_actions = true - - # Apply autocorrection by RuboCop to files generated by `bin/rails generate`. - # config.generators.apply_rubocop_autocorrect_after_generate! -end diff --git a/test/dummy/config/environments/production.rb b/test/dummy/config/environments/production.rb deleted file mode 100644 index aec64cdf3..000000000 --- a/test/dummy/config/environments/production.rb +++ /dev/null @@ -1,89 +0,0 @@ -require "active_support/core_ext/integer/time" - -Rails.application.configure do - # Settings specified here will take precedence over those in config/application.rb. - - # Code is not reloaded between requests. - config.enable_reloading = false - - # Eager load code on boot for better performance and memory savings (ignored by Rake tasks). - config.eager_load = true - - # Full error reports are disabled. - config.consider_all_requests_local = false - - # Turn on fragment caching in view templates. - config.action_controller.perform_caching = true - - # Cache assets for far-future expiry since they are all digest stamped. - config.public_file_server.headers = {"cache-control" => "public, max-age=#{1.year.to_i}"} - - # Enable serving of images, stylesheets, and JavaScripts from an asset server. - # config.asset_host = "http://assets.example.com" - - # Store uploaded files on the local file system (see config/storage.yml for options). - config.active_storage.service = :local - - # Assume all access to the app is happening through a SSL-terminating reverse proxy. - config.assume_ssl = true - - # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. - config.force_ssl = true - - # Skip http-to-https redirect for the default health check endpoint. - # config.ssl_options = { redirect: { exclude: ->(request) { request.path == "/up" } } } - - # Log to STDOUT with the current request id as a default log tag. - config.log_tags = [:request_id] - config.logger = ActiveSupport::TaggedLogging.logger($stdout) - - # Change to "debug" to log everything (including potentially personally-identifiable information!) - config.log_level = ENV.fetch("RAILS_LOG_LEVEL", "info") - - # Prevent health checks from clogging up the logs. - config.silence_healthcheck_path = "/up" - - # Don't log any deprecations. - config.active_support.report_deprecations = false - - # Replace the default in-process memory cache store with a durable alternative. - # config.cache_store = :mem_cache_store - - # Replace the default in-process and non-durable queuing backend for Active Job. - # config.active_job.queue_adapter = :resque - - # Ignore bad email addresses and do not raise email delivery errors. - # Set this to true and configure the email server for immediate delivery to raise delivery errors. - # config.action_mailer.raise_delivery_errors = false - - # Set host to be used by links generated in mailer templates. - config.action_mailer.default_url_options = {host: "example.com"} - - # Specify outgoing SMTP server. Remember to add smtp/* credentials via rails credentials:edit. - # config.action_mailer.smtp_settings = { - # user_name: Rails.application.credentials.dig(:smtp, :user_name), - # password: Rails.application.credentials.dig(:smtp, :password), - # address: "smtp.example.com", - # port: 587, - # authentication: :plain - # } - - # Enable locale fallbacks for I18n (makes lookups for any locale fall back to - # the I18n.default_locale when a translation cannot be found). - config.i18n.fallbacks = true - - # Do not dump schema after migrations. - config.active_record.dump_schema_after_migration = false - - # Only use :id for inspections in production. - config.active_record.attributes_for_inspect = [:id] - - # Enable DNS rebinding protection and other `Host` header attacks. - # config.hosts = [ - # "example.com", # Allow requests from example.com - # /.*\.example\.com/ # Allow requests from subdomains like `www.example.com` - # ] - # - # Skip DNS rebinding protection for the default health check endpoint. - # config.host_authorization = { exclude: ->(request) { request.path == "/up" } } -end diff --git a/test/dummy/config/environments/test.rb b/test/dummy/config/environments/test.rb deleted file mode 100644 index 0fb6d30c1..000000000 --- a/test/dummy/config/environments/test.rb +++ /dev/null @@ -1,53 +0,0 @@ -# The test environment is used exclusively to run your application's -# test suite. You never need to work with it otherwise. Remember that -# your test database is "scratch space" for the test suite and is wiped -# and recreated between test runs. Don't rely on the data there! - -Rails.application.configure do - # Settings specified here will take precedence over those in config/application.rb. - - # While tests run files are not watched, reloading is not necessary. - config.enable_reloading = false - - # Eager loading loads your entire application. When running a single test locally, - # this is usually not necessary, and can slow down your test suite. However, it's - # recommended that you enable it in continuous integration systems to ensure eager - # loading is working properly before deploying your code. - config.eager_load = ENV["CI"].present? - - # Configure public file server for tests with cache-control for performance. - config.public_file_server.headers = {"cache-control" => "public, max-age=3600"} - - # Show full error reports. - config.consider_all_requests_local = true - config.cache_store = :null_store - - # Render exception templates for rescuable exceptions and raise for other exceptions. - config.action_dispatch.show_exceptions = :rescuable - - # Disable request forgery protection in test environment. - config.action_controller.allow_forgery_protection = false - - # Store uploaded files on the local file system in a temporary directory. - config.active_storage.service = :test - - # Tell Action Mailer not to deliver emails to the real world. - # The :test delivery method accumulates sent emails in the - # ActionMailer::Base.deliveries array. - config.action_mailer.delivery_method = :test - - # Set host to be used by links generated in mailer templates. - config.action_mailer.default_url_options = {host: "example.com"} - - # Print deprecation notices to the stderr. - config.active_support.deprecation = :stderr - - # Raises error for missing translations. - # config.i18n.raise_on_missing_translations = true - - # Annotate rendered view with file names. - # config.action_view.annotate_rendered_view_with_filenames = true - - # Raise error when a before_action's only/except options reference missing actions. - config.action_controller.raise_on_missing_callback_actions = true -end diff --git a/test/dummy/config/initializers/content_security_policy.rb b/test/dummy/config/initializers/content_security_policy.rb deleted file mode 100644 index b3076b38f..000000000 --- a/test/dummy/config/initializers/content_security_policy.rb +++ /dev/null @@ -1,25 +0,0 @@ -# Be sure to restart your server when you modify this file. - -# Define an application-wide content security policy. -# See the Securing Rails Applications Guide for more information: -# https://guides.rubyonrails.org/security.html#content-security-policy-header - -# Rails.application.configure do -# config.content_security_policy do |policy| -# policy.default_src :self, :https -# policy.font_src :self, :https, :data -# policy.img_src :self, :https, :data -# policy.object_src :none -# policy.script_src :self, :https -# policy.style_src :self, :https -# # Specify URI for violation reports -# # policy.report_uri "/csp-violation-report-endpoint" -# end -# -# # Generate session nonces for permitted importmap, inline scripts, and inline styles. -# config.content_security_policy_nonce_generator = ->(request) { request.session.id.to_s } -# config.content_security_policy_nonce_directives = %w(script-src style-src) -# -# # Report violations without enforcing the policy. -# # config.content_security_policy_report_only = true -# end diff --git a/test/dummy/config/initializers/filter_parameter_logging.rb b/test/dummy/config/initializers/filter_parameter_logging.rb deleted file mode 100644 index c0b717f7e..000000000 --- a/test/dummy/config/initializers/filter_parameter_logging.rb +++ /dev/null @@ -1,8 +0,0 @@ -# Be sure to restart your server when you modify this file. - -# Configure parameters to be partially matched (e.g. passw matches password) and filtered from the log file. -# Use this to limit dissemination of sensitive information. -# See the ActiveSupport::ParameterFilter documentation for supported notations and behaviors. -Rails.application.config.filter_parameters += [ - :passw, :email, :secret, :token, :_key, :crypt, :salt, :certificate, :otp, :ssn, :cvv, :cvc -] diff --git a/test/dummy/config/initializers/inflections.rb b/test/dummy/config/initializers/inflections.rb deleted file mode 100644 index 3860f659e..000000000 --- a/test/dummy/config/initializers/inflections.rb +++ /dev/null @@ -1,16 +0,0 @@ -# Be sure to restart your server when you modify this file. - -# Add new inflection rules using the following format. Inflections -# are locale specific, and you may define rules for as many different -# locales as you wish. All of these examples are active by default: -# ActiveSupport::Inflector.inflections(:en) do |inflect| -# inflect.plural /^(ox)$/i, "\\1en" -# inflect.singular /^(ox)en/i, "\\1" -# inflect.irregular "person", "people" -# inflect.uncountable %w( fish sheep ) -# end - -# These inflection rules are supported but not enabled by default: -# ActiveSupport::Inflector.inflections(:en) do |inflect| -# inflect.acronym "RESTful" -# end diff --git a/test/dummy/config/initializers/new_framework_defaults_8_0.rb b/test/dummy/config/initializers/new_framework_defaults_8_0.rb deleted file mode 100644 index 92efa9515..000000000 --- a/test/dummy/config/initializers/new_framework_defaults_8_0.rb +++ /dev/null @@ -1,30 +0,0 @@ -# Be sure to restart your server when you modify this file. -# -# This file eases your Rails 8.0 framework defaults upgrade. -# -# Uncomment each configuration one by one to switch to the new default. -# Once your application is ready to run with all new defaults, you can remove -# this file and set the `config.load_defaults` to `8.0`. -# -# Read the Guide for Upgrading Ruby on Rails for more info on each option. -# https://guides.rubyonrails.org/upgrading_ruby_on_rails.html - -### -# Specifies whether `to_time` methods preserve the UTC offset of their receivers or preserves the timezone. -# If set to `:zone`, `to_time` methods will use the timezone of their receivers. -# If set to `:offset`, `to_time` methods will use the UTC offset. -# If `false`, `to_time` methods will convert to the local system UTC offset instead. -#++ -# Rails.application.config.active_support.to_time_preserves_timezone = :zone - -### -# When both `If-Modified-Since` and `If-None-Match` are provided by the client -# only consider `If-None-Match` as specified by RFC 7232 Section 6. -# If set to `false` both conditions need to be satisfied. -#++ -# Rails.application.config.action_dispatch.strict_freshness = true - -### -# Set `Regexp.timeout` to `1`s by default to improve security over Regexp Denial-of-Service attacks. -#++ -# Regexp.timeout = 1 diff --git a/test/dummy/config/initializers/permissions_policy.rb b/test/dummy/config/initializers/permissions_policy.rb deleted file mode 100644 index 7db3b9577..000000000 --- a/test/dummy/config/initializers/permissions_policy.rb +++ /dev/null @@ -1,13 +0,0 @@ -# Be sure to restart your server when you modify this file. - -# Define an application-wide HTTP permissions policy. For further -# information see: https://developers.google.com/web/updates/2018/06/feature-policy - -# Rails.application.config.permissions_policy do |policy| -# policy.camera :none -# policy.gyroscope :none -# policy.microphone :none -# policy.usb :none -# policy.fullscreen :self -# policy.payment :self, "https://secure.example.com" -# end diff --git a/test/dummy/config/locales/en.yml b/test/dummy/config/locales/en.yml deleted file mode 100644 index 6c349ae5e..000000000 --- a/test/dummy/config/locales/en.yml +++ /dev/null @@ -1,31 +0,0 @@ -# Files in the config/locales directory are used for internationalization and -# are automatically loaded by Rails. If you want to use locales other than -# English, add the necessary files in this directory. -# -# To use the locales, use `I18n.t`: -# -# I18n.t "hello" -# -# In views, this is aliased to just `t`: -# -# <%= t("hello") %> -# -# To use a different locale, set it with `I18n.locale`: -# -# I18n.locale = :es -# -# This would use the information in config/locales/es.yml. -# -# To learn more about the API, please read the Rails Internationalization guide -# at https://guides.rubyonrails.org/i18n.html. -# -# Be aware that YAML interprets the following case-insensitive strings as -# booleans: `true`, `false`, `on`, `off`, `yes`, `no`. Therefore, these strings -# must be quoted to be interpreted as strings. For example: -# -# en: -# "yes": yup -# enabled: "ON" - -en: - hello: "Hello world" diff --git a/test/dummy/config/puma.rb b/test/dummy/config/puma.rb deleted file mode 100644 index a248513b2..000000000 --- a/test/dummy/config/puma.rb +++ /dev/null @@ -1,41 +0,0 @@ -# This configuration file will be evaluated by Puma. The top-level methods that -# are invoked here are part of Puma's configuration DSL. For more information -# about methods provided by the DSL, see https://puma.io/puma/Puma/DSL.html. -# -# Puma starts a configurable number of processes (workers) and each process -# serves each request in a thread from an internal thread pool. -# -# You can control the number of workers using ENV["WEB_CONCURRENCY"]. You -# should only set this value when you want to run 2 or more workers. The -# default is already 1. -# -# The ideal number of threads per worker depends both on how much time the -# application spends waiting for IO operations and on how much you wish to -# prioritize throughput over latency. -# -# As a rule of thumb, increasing the number of threads will increase how much -# traffic a given process can handle (throughput), but due to CRuby's -# Global VM Lock (GVL) it has diminishing returns and will degrade the -# response time (latency) of the application. -# -# The default is set to 3 threads as it's deemed a decent compromise between -# throughput and latency for the average Rails application. -# -# Any libraries that use a connection pool or another resource pool should -# be configured to provide at least as many connections as the number of -# threads. This includes Active Record's `pool` parameter in `database.yml`. -threads_count = ENV.fetch("RAILS_MAX_THREADS", 3) -threads threads_count, threads_count - -# Specifies the `port` that Puma will listen on to receive requests; default is 3000. -port ENV.fetch("PORT", 3000) - -# Allow puma to be restarted by `bin/rails restart` command. -plugin :tmp_restart - -# Run the Solid Queue supervisor inside of Puma for single-server deployments -plugin :solid_queue if ENV["SOLID_QUEUE_IN_PUMA"] - -# Specify the PID file. Defaults to tmp/pids/server.pid in development. -# In other environments, only set the PID file if requested. -pidfile ENV["PIDFILE"] if ENV["PIDFILE"] diff --git a/test/dummy/config/routes.rb b/test/dummy/config/routes.rb deleted file mode 100644 index 9f768e57d..000000000 --- a/test/dummy/config/routes.rb +++ /dev/null @@ -1,10 +0,0 @@ -Rails.application.routes.draw do - # Define your application routes per the DSL in https://guides.rubyonrails.org/routing.html - - # Reveal health status on /up that returns 200 if the app boots with no exceptions, otherwise 500. - # Can be used by load balancers and uptime monitors to verify that the app is live. - get "up" => "rails/health#show", :as => :rails_health_check - - # Defines the root path route ("/") - # root "posts#index" -end diff --git a/test/dummy/config/storage.yml b/test/dummy/config/storage.yml deleted file mode 100644 index 4942ab669..000000000 --- a/test/dummy/config/storage.yml +++ /dev/null @@ -1,34 +0,0 @@ -test: - service: Disk - root: <%= Rails.root.join("tmp/storage") %> - -local: - service: Disk - root: <%= Rails.root.join("storage") %> - -# Use bin/rails credentials:edit to set the AWS secrets (as aws:access_key_id|secret_access_key) -# amazon: -# service: S3 -# access_key_id: <%= Rails.application.credentials.dig(:aws, :access_key_id) %> -# secret_access_key: <%= Rails.application.credentials.dig(:aws, :secret_access_key) %> -# region: us-east-1 -# bucket: your_own_bucket-<%= Rails.env %> - -# Remember not to checkin your GCS keyfile to a repository -# google: -# service: GCS -# project: your_project -# credentials: <%= Rails.root.join("path/to/gcs.keyfile") %> -# bucket: your_own_bucket-<%= Rails.env %> - -# Use bin/rails credentials:edit to set the Azure Storage secret (as azure_storage:storage_access_key) -# microsoft: -# service: AzureStorage -# storage_account_name: your_account_name -# storage_access_key: <%= Rails.application.credentials.dig(:azure_storage, :storage_access_key) %> -# container: your_container_name-<%= Rails.env %> - -# mirror: -# service: Mirror -# primary: local -# mirrors: [ amazon, google, microsoft ] diff --git a/test/dummy/db/migrate/20241129142620_add_service_name_to_active_storage_blobs.active_storage.rb b/test/dummy/db/migrate/20241129142620_add_service_name_to_active_storage_blobs.active_storage.rb deleted file mode 100644 index 0267f1287..000000000 --- a/test/dummy/db/migrate/20241129142620_add_service_name_to_active_storage_blobs.active_storage.rb +++ /dev/null @@ -1,22 +0,0 @@ -# This migration comes from active_storage (originally 20190112182829) -class AddServiceNameToActiveStorageBlobs < ActiveRecord::Migration[6.0] - def up - return unless table_exists?(:active_storage_blobs) - - unless column_exists?(:active_storage_blobs, :service_name) - add_column :active_storage_blobs, :service_name, :string - - if (configured_service = ActiveStorage::Blob.service.name) - ActiveStorage::Blob.unscoped.update_all(service_name: configured_service) - end - - change_column :active_storage_blobs, :service_name, :string, null: false - end - end - - def down - return unless table_exists?(:active_storage_blobs) - - remove_column :active_storage_blobs, :service_name - end -end diff --git a/test/dummy/db/migrate/20241129142621_create_active_storage_variant_records.active_storage.rb b/test/dummy/db/migrate/20241129142621_create_active_storage_variant_records.active_storage.rb deleted file mode 100644 index 95fd27fa6..000000000 --- a/test/dummy/db/migrate/20241129142621_create_active_storage_variant_records.active_storage.rb +++ /dev/null @@ -1,28 +0,0 @@ -# This migration comes from active_storage (originally 20191206030411) -class CreateActiveStorageVariantRecords < ActiveRecord::Migration[6.0] - def change - return unless table_exists?(:active_storage_blobs) - - # Use Active Record's configured type for primary key - create_table :active_storage_variant_records, id: primary_key_type, if_not_exists: true do |t| - t.belongs_to :blob, null: false, index: false, type: blobs_primary_key_type - t.string :variation_digest, null: false - - t.index %i[blob_id variation_digest], name: "index_active_storage_variant_records_uniqueness", unique: true - t.foreign_key :active_storage_blobs, column: :blob_id - end - end - - private - - def primary_key_type - config = Rails.configuration.generators - config.options[config.orm][:primary_key_type] || :primary_key - end - - def blobs_primary_key_type - pkey_name = connection.primary_key(:active_storage_blobs) - pkey_column = connection.columns(:active_storage_blobs).find { |c| c.name == pkey_name } - pkey_column.bigint? ? :bigint : pkey_column.type - end -end diff --git a/test/dummy/db/migrate/20241129142622_remove_not_null_on_active_storage_blobs_checksum.active_storage.rb b/test/dummy/db/migrate/20241129142622_remove_not_null_on_active_storage_blobs_checksum.active_storage.rb deleted file mode 100644 index 93c8b85ad..000000000 --- a/test/dummy/db/migrate/20241129142622_remove_not_null_on_active_storage_blobs_checksum.active_storage.rb +++ /dev/null @@ -1,8 +0,0 @@ -# This migration comes from active_storage (originally 20211119233751) -class RemoveNotNullOnActiveStorageBlobsChecksum < ActiveRecord::Migration[6.0] - def change - return unless table_exists?(:active_storage_blobs) - - change_column_null(:active_storage_blobs, :checksum, true) - end -end diff --git a/test/dummy/db/schema.rb b/test/dummy/db/schema.rb deleted file mode 100644 index aad0f2389..000000000 --- a/test/dummy/db/schema.rb +++ /dev/null @@ -1,14 +0,0 @@ -# This file is auto-generated from the current state of the database. Instead -# of editing this file, please use the migrations feature of Active Record to -# incrementally modify your database, and then regenerate this schema definition. -# -# This file is the source Rails uses to define your schema when running `bin/rails -# db:schema:load`. When creating a new database, `bin/rails db:schema:load` tends to -# be faster and is potentially less error prone than running all of your -# migrations from scratch. Old migrations may fail to apply correctly if those -# migrations use external dependencies or application code. -# -# It's strongly recommended that you check this file into your version control system. - -ActiveRecord::Schema[8.0].define(version: 2024_11_29_142622) do -end diff --git a/test/dummy/lib/assets/.keep b/test/dummy/lib/assets/.keep deleted file mode 100644 index e69de29bb..000000000 diff --git a/test/dummy/log/.keep b/test/dummy/log/.keep deleted file mode 100644 index e69de29bb..000000000 diff --git a/test/dummy/public/400.html b/test/dummy/public/400.html deleted file mode 100644 index 282dbc8cc..000000000 --- a/test/dummy/public/400.html +++ /dev/null @@ -1,114 +0,0 @@ - - - - - - - The server cannot process the request due to a client error (400 Bad Request) - - - - - - - - - - - - - -
-
- -
-
-

The server cannot process the request due to a client error. Please check the request and try again. If you’re the application owner check the logs for more information.

-
-
- - - - diff --git a/test/dummy/public/404.html b/test/dummy/public/404.html deleted file mode 100644 index c0670bc87..000000000 --- a/test/dummy/public/404.html +++ /dev/null @@ -1,114 +0,0 @@ - - - - - - - The page you were looking for doesn’t exist (404 Not found) - - - - - - - - - - - - - -
-
- -
-
-

The page you were looking for doesn’t exist. You may have mistyped the address or the page may have moved. If you’re the application owner check the logs for more information.

-
-
- - - - diff --git a/test/dummy/public/406-unsupported-browser.html b/test/dummy/public/406-unsupported-browser.html deleted file mode 100644 index 9532a9ccd..000000000 --- a/test/dummy/public/406-unsupported-browser.html +++ /dev/null @@ -1,114 +0,0 @@ - - - - - - - Your browser is not supported (406 Not Acceptable) - - - - - - - - - - - - - -
-
- -
-
-

Your browser is not supported.
Please upgrade your browser to continue.

-
-
- - - - diff --git a/test/dummy/public/422.html b/test/dummy/public/422.html deleted file mode 100644 index 8bcf06014..000000000 --- a/test/dummy/public/422.html +++ /dev/null @@ -1,114 +0,0 @@ - - - - - - - The change you wanted was rejected (422 Unprocessable Entity) - - - - - - - - - - - - - -
-
- -
-
-

The change you wanted was rejected. Maybe you tried to change something you didn’t have access to. If you’re the application owner check the logs for more information.

-
-
- - - - diff --git a/test/dummy/public/500.html b/test/dummy/public/500.html deleted file mode 100644 index d77718c3a..000000000 --- a/test/dummy/public/500.html +++ /dev/null @@ -1,114 +0,0 @@ - - - - - - - We’re sorry, but something went wrong (500 Internal Server Error) - - - - - - - - - - - - - -
-
- -
-
-

We’re sorry, but something went wrong.
If you’re the application owner check the logs for more information.

-
-
- - - - diff --git a/test/dummy/public/apple-touch-icon-precomposed.png b/test/dummy/public/apple-touch-icon-precomposed.png deleted file mode 100644 index e69de29bb..000000000 diff --git a/test/dummy/public/apple-touch-icon.png b/test/dummy/public/apple-touch-icon.png deleted file mode 100644 index e69de29bb..000000000 diff --git a/test/dummy/public/favicon.ico b/test/dummy/public/favicon.ico deleted file mode 100644 index e69de29bb..000000000 diff --git a/test/dummy/public/icon.png b/test/dummy/public/icon.png deleted file mode 100644 index c4c9dbfbbd2f7c1421ffd5727188146213abbcef..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4166 zcmd6qU;WFw?|v@m)Sk^&NvB8tcujdV-r1b=i(NJxn&7{KTb zX$3(M+3TP2o^#KAo{#tIjl&t~(8D-k004kqPglzn0HFG(Q~(I*AKsD#M*g7!XK0T7 zN6P7j>HcT8rZgKl$v!xr806dyN19Bd4C0x_R*I-a?#zsTvb_89cyhuC&T**i|Rc zq5b8M;+{8KvoJ~uj9`u~d_f6`V&3+&ZX9x5pc8s)d175;@pjm(?dapmBcm0&vl9+W zx1ZD2o^nuyUHWj|^A8r>lUorO`wFF;>9XL-Jy!P}UXC{(z!FO%SH~8k`#|9;Q|eue zqWL0^Bp(fg_+Pkm!fDKRSY;+^@BF?AJE zCUWpXPst~hi_~u)SzYBDZroR+Z4xeHIlm_3Yc_9nZ(o_gg!jDgVa=E}Y8uDgem9`b zf=mfJ_@(BXSkW53B)F2s!&?_R4ptb1fYXlF++@vPhd=marQgEGRZS@B4g1Mu?euknL= z67P~tZ?*>-Hmi7GwlisNHHJDku-dSm7g@!=a}9cSL6Pa^w^2?&?$Oi8ibrr>w)xqx zOH_EMU@m05)9kuNR>>4@H%|){U$^yvVQ(YgOlh;5oU_-vivG-p4=LrN-k7D?*?u1u zsWly%tfAzKd6Fb=`eU2un_uaTXmcT#tlOL+aRS=kZZf}A7qT8lvcTx~7j` z*b>=z)mwg7%B2_!D0!1IZ?Nq{^Y$uI4Qx*6T!E2Col&2{k?ImCO=dD~A&9f9diXy^$x{6CwkBimn|1E09 zAMSezYtiL?O6hS37KpvDM?22&d{l)7h-!F)C-d3j8Z`c@($?mfd{R82)H>Qe`h{~G z!I}(2j(|49{LR?w4Jspl_i!(4T{31|dqCOpI52r5NhxYV+cDAu(xp*4iqZ2e-$YP= zoFOPmm|u*7C?S{Fp43y+V;>~@FFR76bCl@pTtyB93vNWy5yf;HKr8^0d7&GVIslYm zo3Tgt@M!`8B6IW&lK{Xk>%zp41G%`(DR&^u z5^pwD4>E6-w<8Kl2DzJ%a@~QDE$(e87lNhy?-Qgep!$b?5f7+&EM7$e>|WrX+=zCb z=!f5P>MxFyy;mIRxjc(H*}mceXw5a*IpC0PEYJ8Y3{JdoIW)@t97{wcUB@u+$FCCO z;s2Qe(d~oJC^`m$7DE-dsha`glrtu&v&93IZadvl_yjp!c89>zo;Krk+d&DEG4?x$ zufC1n+c1XD7dolX1q|7}uelR$`pT0Z)1jun<39$Sn2V5g&|(j~Z!wOddfYiZo7)A< z!dK`aBHOOk+-E_xbWCA3VR-+o$i5eO9`rMI#p_0xQ}rjEpGW;U!&&PKnivOcG(|m9 z!C8?WC6nCXw25WVa*eew)zQ=h45k8jSIPbq&?VE{oG%?4>9rwEeB4&qe#?-y_es4c|7ufw%+H5EY#oCgv!Lzv291#-oNlX~X+Jl5(riC~r z=0M|wMOP)Tt8@hNg&%V@Z9@J|Q#K*hE>sr6@oguas9&6^-=~$*2Gs%h#GF@h)i=Im z^iKk~ipWJg1VrvKS;_2lgs3n1zvNvxb27nGM=NXE!D4C!U`f*K2B@^^&ij9y}DTLB*FI zEnBL6y{jc?JqXWbkIZd7I16hA>(f9T!iwbIxJj~bKPfrO;>%*5nk&Lf?G@c2wvGrY&41$W{7HM9+b@&XY@>NZM5s|EK_Dp zQX60CBuantx>|d#DsaZ*8MW(we|#KTYZ=vNa#d*DJQe6hr~J6{_rI#?wi@s|&O}FR zG$kfPxheXh1?IZ{bDT-CWB4FTvO-k5scW^mi8?iY5Q`f8JcnnCx
iy@m@D-%lO;y0pTLhh6i6l@x52j=#^$5_U^os}OFg zzdHbo(QI`%9#o*r8GCW~T3UdV`szO#~)^&X_(VW>o~umY9-ns9-V4lf~j z`QBD~pJ4a#b`*6bJ^3RS5y?RAgF7K5$ll97Y8#WZduZ`j?IEY~H(s^doZg>7-tk*t z4_QE1%%bb^p~4F5SB$t2i1>DBG1cIo;2(xTaj*Y~hlM{tSDHojL-QPg%Mo%6^7FrpB*{ z4G0@T{-77Por4DCMF zB_5Y~Phv%EQ64W8^GS6h?x6xh;w2{z3$rhC;m+;uD&pR74j+i22P5DS-tE8ABvH(U~indEbBUTAAAXfHZg5QpB@TgV9eI<)JrAkOI z8!TSOgfAJiWAXeM&vR4Glh;VxH}WG&V$bVb`a`g}GSpwggti*&)taV1@Ak|{WrV|5 zmNYx)Ans=S{c52qv@+jmGQ&vd6>6yX6IKq9O$3r&0xUTdZ!m1!irzn`SY+F23Rl6# zFRxws&gV-kM1NX(3(gnKpGi0Q)Dxi~#?nyzOR9!en;Ij>YJZVFAL*=R%7y%Mz9hU% zs>+ZB?qRmZ)nISx7wxY)y#cd$iaC~{k0avD>BjyF1q^mNQ1QcwsxiTySe<6C&cC6P zE`vwO9^k-d`9hZ!+r@Jnr+MF*2;2l8WjZ}DrwDUHzSF{WoG zucbSWguA!3KgB3MU%HH`R;XqVv0CcaGq?+;v_A5A2kpmk5V%qZE3yzQ7R5XWhq=eR zyUezH=@V)y>L9T-M-?tW(PQYTRBKZSVb_!$^H-Pn%ea;!vS_?M<~Tm>_rWIW43sPW z=!lY&fWc1g7+r?R)0p8(%zp&vl+FK4HRkns%BW+Up&wK8!lQ2~bja|9bD12WrKn#M zK)Yl9*8$SI7MAwSK$%)dMd>o+1UD<2&aQMhyjS5R{-vV+M;Q4bzl~Z~=4HFj_#2V9 zB)Gfzx3ncy@uzx?yzi}6>d%-?WE}h7v*w)Jr_gBl!2P&F3DX>j_1#--yjpL%<;JMR z*b70Gr)MMIBWDo~#<5F^Q0$VKI;SBIRneuR7)yVsN~A9I@gZTXe)E?iVII+X5h0~H zx^c(fP&4>!*q>fb6dAOC?MI>Cz3kld#J*;uik+Ps49cwm1B4 zZc1|ZxYyTv;{Z!?qS=D)sgRKx^1AYf%;y_V&VgZglfU>d+Ufk5&LV$sKv}Hoj+s; xK3FZRYdhbXT_@RW*ff3@`D1#ps#~H)p+y&j#(J|vk^lW{fF9OJt5(B-_&*Xgn9~3N diff --git a/test/dummy/public/icon.svg b/test/dummy/public/icon.svg deleted file mode 100644 index 04b34bf83..000000000 --- a/test/dummy/public/icon.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/test/dummy/public/robots.txt b/test/dummy/public/robots.txt deleted file mode 100644 index c19f78ab6..000000000 --- a/test/dummy/public/robots.txt +++ /dev/null @@ -1 +0,0 @@ -# See https://www.robotstxt.org/robotstxt.html for documentation on how to use the robots.txt file diff --git a/test/dummy/storage/.keep b/test/dummy/storage/.keep deleted file mode 100644 index e69de29bb..000000000 diff --git a/test/dummy/tmp/.keep b/test/dummy/tmp/.keep deleted file mode 100644 index e69de29bb..000000000 diff --git a/test/dummy/tmp/pids/.keep b/test/dummy/tmp/pids/.keep deleted file mode 100644 index e69de29bb..000000000 diff --git a/test/dummy/tmp/storage/.keep b/test/dummy/tmp/storage/.keep deleted file mode 100644 index e69de29bb..000000000 diff --git a/test/fixtures/files/Rakefile b/test/fixtures/files/Rakefile deleted file mode 100644 index 772ac90ac..000000000 --- a/test/fixtures/files/Rakefile +++ /dev/null @@ -1,10 +0,0 @@ -# Add your own tasks in files placed in lib/tasks ending in .rake, -# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. - -require_relative "config/application" - -Rails.application.load_tasks - -if Rails.env.local? - task default: "suspenders:rake" -end diff --git a/test/fixtures/files/Rakefile_advisories b/test/fixtures/files/Rakefile_advisories deleted file mode 100644 index 61430bb02..000000000 --- a/test/fixtures/files/Rakefile_advisories +++ /dev/null @@ -1,8 +0,0 @@ -require_relative "config/application" - -if Rails.env.local? - require "bundler/audit/task" - Bundler::Audit::Task.new -end - -Rails.application.load_tasks diff --git a/test/fixtures/files/_flashes.html.erb b/test/fixtures/files/_flashes.html.erb deleted file mode 100644 index ae9805a03..000000000 --- a/test/fixtures/files/_flashes.html.erb +++ /dev/null @@ -1,7 +0,0 @@ -<% if flash.any? %> -
- <% flash.each do |type, message| -%> -
<%= message %>
- <% end -%> -
-<% end %> diff --git a/test/fixtures/files/action_mailer.rb b/test/fixtures/files/action_mailer.rb deleted file mode 100644 index b9563a3bc..000000000 --- a/test/fixtures/files/action_mailer.rb +++ /dev/null @@ -1,5 +0,0 @@ -RSpec.configure do |config| - config.before(:each) do - ActionMailer::Base.deliveries.clear - end -end diff --git a/test/fixtures/files/better_html.rb b/test/fixtures/files/better_html.rb deleted file mode 100644 index b117fade8..000000000 --- a/test/fixtures/files/better_html.rb +++ /dev/null @@ -1,9 +0,0 @@ -Rails.configuration.to_prepare do - if Rails.env.test? - require "better_html" - - BetterHtml.config = BetterHtml::Config.new(Rails.configuration.x.better_html) - - BetterHtml.config.template_exclusion_filter = proc { |filename| !filename.start_with?(Rails.root.to_s) } - end -end diff --git a/test/fixtures/files/driver.rb b/test/fixtures/files/driver.rb deleted file mode 100644 index 91e275b49..000000000 --- a/test/fixtures/files/driver.rb +++ /dev/null @@ -1,5 +0,0 @@ -RSpec.configure do |config| - config.before(:each, type: :system) do - driven_by :selenium, using: :headless_chrome, screen_size: [1400, 1400] - end -end diff --git a/test/fixtures/files/email_interceptor.rb b/test/fixtures/files/email_interceptor.rb deleted file mode 100644 index 8ad791abd..000000000 --- a/test/fixtures/files/email_interceptor.rb +++ /dev/null @@ -1,11 +0,0 @@ -class EmailInterceptor - include ActiveSupport::Configurable - - config_accessor :interceptor_addresses, default: [] - - def self.delivering_email(message) - to = interceptor_addresses - - message.to = to if to.any? - end -end diff --git a/test/fixtures/files/email_interceptor_initializer.rb b/test/fixtures/files/email_interceptor_initializer.rb deleted file mode 100644 index 71b2ef4cd..000000000 --- a/test/fixtures/files/email_interceptor_initializer.rb +++ /dev/null @@ -1,5 +0,0 @@ -Rails.application.configure do - if ENV["INTERCEPTOR_ADDRESSES"].present? - config.action_mailer.interceptors = %w[EmailInterceptor] - end -end diff --git a/test/fixtures/files/environments/development.rb b/test/fixtures/files/environments/development.rb deleted file mode 100644 index edd263557..000000000 --- a/test/fixtures/files/environments/development.rb +++ /dev/null @@ -1,2 +0,0 @@ -Rails.application.configure do -end diff --git a/test/fixtures/files/environments/production.rb b/test/fixtures/files/environments/production.rb deleted file mode 100644 index edd263557..000000000 --- a/test/fixtures/files/environments/production.rb +++ /dev/null @@ -1,2 +0,0 @@ -Rails.application.configure do -end diff --git a/test/fixtures/files/environments/test.rb b/test/fixtures/files/environments/test.rb deleted file mode 100644 index edd263557..000000000 --- a/test/fixtures/files/environments/test.rb +++ /dev/null @@ -1,2 +0,0 @@ -Rails.application.configure do -end diff --git a/test/fixtures/files/erb-lint.yml b/test/fixtures/files/erb-lint.yml deleted file mode 100644 index aac222c15..000000000 --- a/test/fixtures/files/erb-lint.yml +++ /dev/null @@ -1,63 +0,0 @@ ---- -glob: "app/views/**/*.{html,turbo_stream}{+*,}.erb" - -linters: - AllowedScriptType: - enabled: true - allowed_types: - - "module" - - "text/javascript" - ErbSafety: - enabled: true - better_html_config: "config/better_html.yml" - GitHub::Accessibility::AvoidBothDisabledAndAriaDisabledCounter: - enabled: true - GitHub::Accessibility::AvoidGenericLinkTextCounter: - enabled: true - GitHub::Accessibility::DisabledAttributeCounter: - enabled: true - GitHub::Accessibility::IframeHasTitleCounter: - enabled: true - GitHub::Accessibility::ImageHasAltCounter: - enabled: true - GitHub::Accessibility::LandmarkHasLabelCounter: - enabled: true - GitHub::Accessibility::LinkHasHrefCounter: - enabled: true - GitHub::Accessibility::NestedInteractiveElementsCounter: - enabled: true - GitHub::Accessibility::NoAriaLabelMisuseCounter: - enabled: true - GitHub::Accessibility::NoPositiveTabIndexCounter: - enabled: true - GitHub::Accessibility::NoRedundantImageAltCounter: - enabled: true - GitHub::Accessibility::NoTitleAttributeCounter: - enabled: true - GitHub::Accessibility::SvgHasAccessibleTextCounter: - enabled: true - Rubocop: - enabled: true - rubocop_config: - inherit_from: - - .rubocop.yml - - Lint/EmptyBlock: - Enabled: false - Layout/InitialIndentation: - Enabled: false - Layout/TrailingEmptyLines: - Enabled: false - Layout/TrailingWhitespace: - Enabled: false - Layout/LeadingEmptyLines: - Enabled: false - Style/FrozenStringLiteralComment: - Enabled: false - Style/MultilineTernaryOperator: - Enabled: false - Lint/UselessAssignment: - Exclude: - - "app/views/**/*" - -EnableDefaultLinters: true diff --git a/test/fixtures/files/eslintrc.json b/test/fixtures/files/eslintrc.json deleted file mode 100644 index 48e5b597f..000000000 --- a/test/fixtures/files/eslintrc.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "extends": ["@thoughtbot/eslint-config/prettier"], - "parserOptions": { - "ecmaVersion": "latest", - "sourceType": "module" - } -} diff --git a/test/fixtures/files/factories.rb b/test/fixtures/files/factories.rb deleted file mode 100644 index 3bfcbd203..000000000 --- a/test/fixtures/files/factories.rb +++ /dev/null @@ -1,2 +0,0 @@ -FactoryBot.define do -end diff --git a/test/fixtures/files/factories_spec_lint.rb b/test/fixtures/files/factories_spec_lint.rb deleted file mode 100644 index 91418c607..000000000 --- a/test/fixtures/files/factories_spec_lint.rb +++ /dev/null @@ -1,7 +0,0 @@ -require "rails_helper" - -RSpec.describe "Factories" do - it "has valid factoties" do - FactoryBot.lint traits: true - end -end diff --git a/test/fixtures/files/factories_test_lint.rb b/test/fixtures/files/factories_test_lint.rb deleted file mode 100644 index 23b78663d..000000000 --- a/test/fixtures/files/factories_test_lint.rb +++ /dev/null @@ -1,9 +0,0 @@ -require "test_helper" - -class FactoryBotsTest < ActiveSupport::TestCase - class FactoryLintingTest < FactoryBotsTest - test "linting of factories" do - FactoryBot.lint traits: true - end - end -end diff --git a/test/fixtures/files/gemfile_clean b/test/fixtures/files/gemfile_clean deleted file mode 100644 index 30c5d0c3a..000000000 --- a/test/fixtures/files/gemfile_clean +++ /dev/null @@ -1,85 +0,0 @@ -source "https://rubygems.org" - -ruby "3.3.0" - -# Bundle edge Rails instead: gem "rails", github: "rails/rails", branch: "main" -gem "rails", "~> 7.1.3", ">= 7.1.3.2" - -# The original asset pipeline for Rails [https://github.com/rails/sprockets-rails] -gem "sprockets-rails" - -# Use postgresql as the database for Active Record -gem "pg", "~> 1.1" - -# Use the Puma web server [https://github.com/puma/puma] -gem "puma", ">= 5.0" - -# Use JavaScript with ESM import maps [https://github.com/rails/importmap-rails] -gem "importmap-rails" - -# Hotwire's SPA-like page accelerator [https://turbo.hotwired.dev] -gem "turbo-rails" - -# Hotwire's modest JavaScript framework [https://stimulus.hotwired.dev] -gem "stimulus-rails" - -# Build JSON APIs with ease [https://github.com/rails/jbuilder] -gem "jbuilder" - -# Use Redis adapter to run Action Cable in production -gem "redis", ">= 4.0.1" - -# Use Kredis to get higher-level data types in Redis [https://github.com/rails/kredis] -# gem "kredis" - -# Use Active Model has_secure_password [https://guides.rubyonrails.org/active_model_basics.html#securepassword] -# gem "bcrypt", "~> 3.1.7" - -# Windows does not include zoneinfo files, so bundle the tzinfo-data gem -gem "tzinfo-data", platforms: %i[windows jruby] - -# Reduces boot times through caching; required in config/boot.rb -gem "bootsnap", require: false - -# Use Active Storage variants [https://guides.rubyonrails.org/active_storage_overview.html#transforming-images] -# gem "image_processing", "~> 1.2" - -gem "cssbundling-rails" -gem "inline_svg" -gem "sidekiq" -gem "title" - -group :development, :test do - # See https://guides.rubyonrails.org/debugging_rails_applications.html#debugging-with-the-debug-gem - gem "debug", platforms: %i[mri windows] - - gem "suspenders", github: "thoughtbot/suspenders", branch: "suspenders-3-0-0-web-generator" - gem "bundler-audit", ">= 0.7.0", require: false - gem "factory_bot_rails" - gem "rspec-rails", "~> 6.1.0" - gem "better_html", require: false - gem "erb_lint", require: false - gem "erblint-github", require: false - gem "standard" -end - -group :development do - # Use console on exceptions pages [https://github.com/rails/web-console] - gem "web-console" - - # Add speed badges [https://github.com/MiniProfiler/rack-mini-profiler] - # gem "rack-mini-profiler" - - # Speed up commands on slow machines / big apps [https://github.com/rails/spring] - # gem "spring" -end - -group :test do - gem "capybara_accessibility_audit" - gem "capybara_accessible_selectors", github: "citizensadvice/capybara_accessible_selectors" - gem "capybara" - gem "action_dispatch-testing-integration-capybara", github: "thoughtbot/action_dispatch-testing-integration-capybara", tag: "v0.1.1", require: "action_dispatch/testing/integration/capybara/rspec" - gem "selenium-webdriver" - gem "shoulda-matchers", "~> 6.0" - gem "webmock" -end diff --git a/test/fixtures/files/gemfile_messy b/test/fixtures/files/gemfile_messy deleted file mode 100644 index 7e19e3c1b..000000000 --- a/test/fixtures/files/gemfile_messy +++ /dev/null @@ -1,101 +0,0 @@ -source "https://rubygems.org" - -ruby "3.3.0" - -# Bundle edge Rails instead: gem "rails", github: "rails/rails", branch: "main" -gem "rails", "~> 7.1.3", ">= 7.1.3.2" - -# The original asset pipeline for Rails [https://github.com/rails/sprockets-rails] -gem "sprockets-rails" - -# Use postgresql as the database for Active Record -gem "pg", "~> 1.1" - -# Use the Puma web server [https://github.com/puma/puma] -gem "puma", ">= 5.0" - -# Use JavaScript with ESM import maps [https://github.com/rails/importmap-rails] -gem "importmap-rails" - -# Hotwire's SPA-like page accelerator [https://turbo.hotwired.dev] -gem "turbo-rails" - -# Hotwire's modest JavaScript framework [https://stimulus.hotwired.dev] -gem "stimulus-rails" - -# Build JSON APIs with ease [https://github.com/rails/jbuilder] -gem "jbuilder" - -# Use Redis adapter to run Action Cable in production -gem "redis", ">= 4.0.1" - -# Use Kredis to get higher-level data types in Redis [https://github.com/rails/kredis] -# gem "kredis" - -# Use Active Model has_secure_password [https://guides.rubyonrails.org/active_model_basics.html#securepassword] -# gem "bcrypt", "~> 3.1.7" - -# Windows does not include zoneinfo files, so bundle the tzinfo-data gem -gem "tzinfo-data", platforms: %i[windows jruby] - -# Reduces boot times through caching; required in config/boot.rb -gem "bootsnap", require: false - -# Use Active Storage variants [https://guides.rubyonrails.org/active_storage_overview.html#transforming-images] -# gem "image_processing", "~> 1.2" - -group :development, :test do - # See https://guides.rubyonrails.org/debugging_rails_applications.html#debugging-with-the-debug-gem - gem "debug", platforms: %i[mri windows] -end - -group :development do - # Use console on exceptions pages [https://github.com/rails/web-console] - gem "web-console" - - # Add speed badges [https://github.com/MiniProfiler/rack-mini-profiler] - # gem "rack-mini-profiler" - - # Speed up commands on slow machines / big apps [https://github.com/rails/spring] - # gem "spring" -end - -group :development, :test do - gem "suspenders", github: "thoughtbot/suspenders", branch: "suspenders-3-0-0-web-generator" -end - -group :test do - gem "capybara_accessibility_audit" - gem "capybara_accessible_selectors", github: "citizensadvice/capybara_accessible_selectors" -end -gem "cssbundling-rails" - -group :development, :test do - gem "bundler-audit", ">= 0.7.0", require: false -end -gem "inline_svg" - -group :development, :test do - gem "factory_bot_rails" -end -gem "sidekiq" -gem "title" - -group :development, :test do - gem "rspec-rails", "~> 6.1.0" -end - -group :test do - gem "capybara" - gem "action_dispatch-testing-integration-capybara", github: "thoughtbot/action_dispatch-testing-integration-capybara", tag: "v0.1.1", require: "action_dispatch/testing/integration/capybara/rspec" - gem "selenium-webdriver" - gem "shoulda-matchers", "~> 6.0" - gem "webmock" -end - -group :development, :test do - gem "better_html", require: false - gem "erb_lint", require: false - gem "erblint-github", require: false - gem "standard" -end diff --git a/test/fixtures/files/i18n.rb b/test/fixtures/files/i18n.rb deleted file mode 100644 index 0c61ce662..000000000 --- a/test/fixtures/files/i18n.rb +++ /dev/null @@ -1,3 +0,0 @@ -RSpec.configure do |config| - config.include ActionView::Helpers::TranslationHelper -end diff --git a/test/fixtures/files/inline_svg.rb b/test/fixtures/files/inline_svg.rb deleted file mode 100644 index d6cd050ae..000000000 --- a/test/fixtures/files/inline_svg.rb +++ /dev/null @@ -1,3 +0,0 @@ -InlineSvg.configure do |config| - config.raise_on_file_not_found = true -end diff --git a/test/fixtures/files/postcss.config.js b/test/fixtures/files/postcss.config.js deleted file mode 100644 index 9c48e607b..000000000 --- a/test/fixtures/files/postcss.config.js +++ /dev/null @@ -1,11 +0,0 @@ -module.exports = { - plugins: [ - require('postcss-import'), - require('postcss-nesting'), - require('autoprefixer'), - require('postcss-url')({ - url: 'copy', - assetsPath: 'app/assets/static' - }) - ], -} diff --git a/test/fixtures/files/prettierignore b/test/fixtures/files/prettierignore deleted file mode 100644 index f2056e58e..000000000 --- a/test/fixtures/files/prettierignore +++ /dev/null @@ -1 +0,0 @@ -vendor/bundle/** diff --git a/test/fixtures/files/prettierrc.json b/test/fixtures/files/prettierrc.json deleted file mode 100644 index 1e8fc8e24..000000000 --- a/test/fixtures/files/prettierrc.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "singleQuote": true, - "overrides": [ - { - "files": ["**/*.css", "**/*.scss", "**/*.html"], - "options": { - "singleQuote": false - } - } - ] -} diff --git a/test/fixtures/files/rails_helper.rb b/test/fixtures/files/rails_helper.rb deleted file mode 100644 index b2a2310da..000000000 --- a/test/fixtures/files/rails_helper.rb +++ /dev/null @@ -1,21 +0,0 @@ -require "spec_helper" -ENV["RAILS_ENV"] ||= "test" -require_relative "../config/environment" - -abort("The Rails environment is running in production mode!") if Rails.env.production? -require "rspec/rails" - -# Rails.root.glob("spec/support/**/*.rb").sort.each { |f| require f } - -begin - ActiveRecord::Migration.maintain_test_schema! -rescue ActiveRecord::PendingMigrationError => e - abort e.to_s.strip -end -RSpec.configure do |config| - config.fixture_path = "#{::Rails.root}/spec/fixtures" - config.use_transactional_fixtures = true - config.infer_spec_type_from_file_location! - config.filter_rails_from_backtrace! -end -Dir[Rails.root.join("spec/support/**/*.rb")].sort.each { |file| require file } diff --git a/test/fixtures/files/shoulda_matchers.rb b/test/fixtures/files/shoulda_matchers.rb deleted file mode 100644 index 7d045f359..000000000 --- a/test/fixtures/files/shoulda_matchers.rb +++ /dev/null @@ -1,6 +0,0 @@ -Shoulda::Matchers.configure do |config| - config.integrate do |with| - with.test_framework :rspec - with.library :rails - end -end diff --git a/test/fixtures/files/spec_helper.rb b/test/fixtures/files/spec_helper.rb deleted file mode 100644 index 7e663af5b..000000000 --- a/test/fixtures/files/spec_helper.rb +++ /dev/null @@ -1,23 +0,0 @@ -require "webmock/rspec" - -RSpec.configure do |config| - config.example_status_persistence_file_path = "tmp/rspec_examples.txt" - config.order = :random - - config.expect_with :rspec do |expectations| - expectations.include_chain_clauses_in_custom_matcher_descriptions = true - end - - config.mock_with :rspec do |mocks| - mocks.verify_partial_doubles = true - end - config.shared_context_metadata_behavior = :apply_to_host_groups -end - -WebMock.disable_net_connect!( - allow_localhost: true, - allow: [ - /(chromedriver|storage).googleapis.com/, - "googlechromelabs.github.io" - ] -) diff --git a/test/fixtures/files/stylelintrc.json b/test/fixtures/files/stylelintrc.json deleted file mode 100644 index 3171f405a..000000000 --- a/test/fixtures/files/stylelintrc.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "extends": "@thoughtbot/stylelint-config" -} diff --git a/test/fixtures/files/test_helper.rb b/test/fixtures/files/test_helper.rb deleted file mode 100644 index 0c22470ec..000000000 --- a/test/fixtures/files/test_helper.rb +++ /dev/null @@ -1,15 +0,0 @@ -ENV["RAILS_ENV"] ||= "test" -require_relative "../config/environment" -require "rails/test_help" - -module ActiveSupport - class TestCase - # Run tests in parallel with specified workers - parallelize(workers: :number_of_processors) - - # Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order. - fixtures :all - - # Add more helper methods to be used by all tests here... - end -end diff --git a/test/generators/suspenders/accessibility_generator_test.rb b/test/generators/suspenders/accessibility_generator_test.rb deleted file mode 100644 index a95bfa98a..000000000 --- a/test/generators/suspenders/accessibility_generator_test.rb +++ /dev/null @@ -1,70 +0,0 @@ -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 commented_out: true do - 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", github: "thoughtbot/capybara_accessibility_audit" - gem "capybara_accessible_selectors", github: "citizensadvice/capybara_accessible_selectors", tag: "v0.12.0" - end - RUBY - - run_generator - - assert_file app_root("Gemfile") do |file| - assert_match(expected_output, file) - end - end - - test "installs gems with Bundler" do - output = run_generator - - assert_match(/bundle install/, output) - end - - private - - def prepare_destination - touch "Gemfile" - end - - def restore_destination - remove_file_if_exists "Gemfile" - end - end - end -end diff --git a/test/generators/suspenders/advisories_generator_test.rb b/test/generators/suspenders/advisories_generator_test.rb deleted file mode 100644 index dc6b79352..000000000 --- a/test/generators/suspenders/advisories_generator_test.rb +++ /dev/null @@ -1,62 +0,0 @@ -require "test_helper" -require "generators/suspenders/advisories_generator" - -module Suspenders - module Generators - class AdvisoriesGeneratorTest < Rails::Generators::TestCase - include Suspenders::TestHelpers - - tests Suspenders::Generators::AdvisoriesGenerator - destination Rails.root - setup :prepare_destination - teardown :restore_destination - - test "adds gems to Gemfile" do - expected_output = <<~RUBY - group :development, :test do - gem "bundler-audit", ">= 0.7.0", require: false - end - RUBY - - run_generator - - assert_file app_root("Gemfile") do |file| - assert_match(expected_output, file) - end - end - - test "installs gems with Bundler" do - output = run_generator - - assert_match(/bundle install/, output) - end - - test "modifies Rakefile" do - touch "Rakefile", content: <<~TEXT - require_relative "config/application" - - Rails.application.load_tasks - TEXT - expected_rakefile = file_fixture("Rakefile_advisories").read - - run_generator - - assert_file app_root("Rakefile") do |file| - assert_equal expected_rakefile, file - end - end - - private - - def prepare_destination - touch "Gemfile" - backup_file "Rakefile" - end - - def restore_destination - remove_file_if_exists "Gemfile" - restore_file "Rakefile" - end - end - end -end diff --git a/test/generators/suspenders/ci_generator_test.rb b/test/generators/suspenders/ci_generator_test.rb deleted file mode 100644 index 920eb1e9c..000000000 --- a/test/generators/suspenders/ci_generator_test.rb +++ /dev/null @@ -1,41 +0,0 @@ -require "test_helper" -require "generators/suspenders/ci_generator" - -module Suspenders - module Generators - class CiGeneratorTest < Rails::Generators::TestCase - include Suspenders::TestHelpers - - tests Suspenders::Generators::CiGenerator - destination Rails.root - teardown :restore_destination - - test "generates CI files" do - mkdir(".github/workflows") - touch(".github/workflows/ci.yml") - - with_database "postgresql" do - run_generator - - assert_file app_root(".github/workflows/ci.yml") - end - end - - test "raises if PostgreSQL is not the adapter" do - with_database "unsupported" do - assert_raises Suspenders::Generators::DatabaseUnsupported::Error, match: "This generator requires PostgreSQL" do - run_generator - - assert_no_file app_root(".github/workflows/ci.yml") - end - end - end - - private - - def restore_destination - remove_dir_if_exists ".github" - end - end - end -end diff --git a/test/generators/suspenders/email_generator_test.rb b/test/generators/suspenders/email_generator_test.rb deleted file mode 100644 index 56fd93139..000000000 --- a/test/generators/suspenders/email_generator_test.rb +++ /dev/null @@ -1,69 +0,0 @@ -require "test_helper" -require "generators/suspenders/email_generator" - -module Suspenders - module Generators - class EmailGeneratorTest < Rails::Generators::TestCase - include Suspenders::TestHelpers - - tests Suspenders::Generators::EmailGenerator - destination Rails.root - setup :prepare_destination - teardown :restore_destination - - test "creates a mailer intercepter" do - expected = file_fixture("email_interceptor.rb").read - - run_generator - - assert_file app_root("app/mailers/email_interceptor.rb") do |file| - assert_equal expected, file - end - end - - test "creates initializer" do - expected = file_fixture("email_interceptor_initializer.rb").read - - run_generator - - assert_file app_root("config/initializers/email_interceptor.rb") do |file| - assert_equal expected, file - end - end - - test "configures application to user email intercepter" do - run_generator - - assert_file app_root("config/application.rb"), /config\.to_prepare\s*do.\s*EmailInterceptor\.config\.interceptor_addresses\s*=\s*ENV\.fetch\("INTERCEPTOR_ADDRESSES",\s*""\)\.split\(","\).\s*end/m - end - - test "configures action mailer in development" do - run_generator - - assert_file app_root("config/environments/development.rb"), /config\.action_mailer\.default_url_options\s*=\s*{\s*host:\s*"localhost",\s*port:\s*3000\s*}/ - end - - test "configures action mailer in test" do - run_generator - - assert_file app_root("config/environments/test.rb"), /config\.action_mailer\.default_url_options\s*=\s*{\s*host:\s*"www\.example\.com"\s*}/ - end - - private - - def prepare_destination - backup_file "config/application.rb" - backup_file "config/environments/development.rb" - backup_file "config/environments/test.rb" - end - - def restore_destination - restore_file "config/application.rb" - restore_file "config/environments/development.rb" - restore_file "config/environments/test.rb" - remove_file_if_exists "app/mailers/email_interceptor.rb" - remove_file_if_exists "config/initializers/email_interceptor.rb" - end - end - end -end diff --git a/test/generators/suspenders/environments/development_generator_test.rb b/test/generators/suspenders/environments/development_generator_test.rb deleted file mode 100644 index ef594657a..000000000 --- a/test/generators/suspenders/environments/development_generator_test.rb +++ /dev/null @@ -1,95 +0,0 @@ -require "test_helper" -require "generators/suspenders/environments/development_generator" - -module Suspenders - module Generators - module Environments - class DevelopmentGenerator::DefaultTest < Rails::Generators::TestCase - include Suspenders::TestHelpers - - tests Suspenders::Generators::Environments::DevelopmentGenerator - destination Rails.root - setup :prepare_destination - teardown :restore_destination - - test "raise on missing translations" do - run_generator - - assert_file app_root("config/environments/development.rb") do |file| - assert_match( - /^ +config.i18n.raise_on_missing_translations = true$/, - file - ) - end - end - - test "raise on missing translations (when config is not commented out)" do - content = file_fixture("environments/development.rb").read - remove_file_if_exists "config/environments/development.rb" - touch "config/environments/development.rb", content: content - - run_generator - - assert_file app_root("config/environments/development.rb") do |file| - assert_match( - /^ +config.i18n.raise_on_missing_translations = true$/, - file - ) - end - end - - test "annotate rendered view with file names" do - run_generator - - assert_file app_root("config/environments/development.rb") do |file| - assert_match( - /^ +config.action_view.annotate_rendered_view_with_filenames = true$/, - file - ) - end - end - - test "annotate rendered view with file names (when config is not commented out)" do - content = file_fixture("environments/development.rb").read - remove_file_if_exists "config/environments/development.rb" - touch "config/environments/development.rb", content: content - - run_generator - - assert_file app_root("config/environments/development.rb") do |file| - assert_match( - /^ +config.action_view.annotate_rendered_view_with_filenames = true$/, - file - ) - end - end - - test "enable active_model.i18n_customize_full_message" do - run_generator - - assert_file app_root("config/environments/development.rb") do |file| - assert_match(/^\s*config\.active_model\.i18n_customize_full_message\s*=\s*true/, file) - end - end - - test "enable active_record.query_log_tags_enabled" do - run_generator - - assert_file app_root("config/environments/development.rb") do |file| - assert_match(/^\s*config\.active_record\.query_log_tags_enabled\s*=\s*true/, file) - end - end - - private - - def prepare_destination - backup_file "config/environments/development.rb" - end - - def restore_destination - restore_file "config/environments/development.rb" - end - end - end - end -end diff --git a/test/generators/suspenders/environments/production_generator_test.rb b/test/generators/suspenders/environments/production_generator_test.rb deleted file mode 100644 index 79082ca4e..000000000 --- a/test/generators/suspenders/environments/production_generator_test.rb +++ /dev/null @@ -1,47 +0,0 @@ -require "test_helper" -require "generators/suspenders/environments/production_generator" - -module Suspenders - module Generators - module Environments - class ProductionGeneratorTest < Rails::Generators::TestCase - include Suspenders::TestHelpers - - tests Suspenders::Generators::Environments::ProductionGenerator - destination Rails.root - setup :prepare_destination - teardown :restore_destination - - test "requires master key" do - run_generator - - assert_file app_root("config/environments/production.rb") do |file| - assert_match(/^\s*config\.require_master_key\s*=\s*true/, file) - end - end - - test "requires master key (when config is not commented out)" do - content = file_fixture("environments/production.rb").read - remove_file_if_exists "config/environments/production.rb" - touch "config/environments/production.rb", content: content - - run_generator - - assert_file app_root("config/environments/production.rb") do |file| - assert_match(/^\s*config\.require_master_key\s*=\s*true/, file) - end - end - - private - - def prepare_destination - backup_file "config/environments/production.rb" - end - - def restore_destination - restore_file "config/environments/production.rb" - end - end - end - end -end diff --git a/test/generators/suspenders/environments/test_generator_test.rb b/test/generators/suspenders/environments/test_generator_test.rb deleted file mode 100644 index 6e31e48e0..000000000 --- a/test/generators/suspenders/environments/test_generator_test.rb +++ /dev/null @@ -1,69 +0,0 @@ -require "test_helper" -require "generators/suspenders/environments/test_generator" - -module Suspenders - module Generators - module Environments - class TestGeneratorTest < Rails::Generators::TestCase - include Suspenders::TestHelpers - - tests Suspenders::Generators::Environments::TestGenerator - destination Rails.root - setup :prepare_destination - teardown :restore_destination - - test "raise on missing translations" do - run_generator - - assert_file app_root("config/environments/test.rb") do |file| - assert_match(/^\s*config\.i18n\.raise_on_missing_translations\s*=\s*true/, file) - end - end - - test "raise on missing translations (when config is not commented out)" do - content = file_fixture("environments/test.rb").read - remove_file_if_exists "config/environments/test.rb" - touch "config/environments/test.rb", content: content - - run_generator - - assert_file app_root("config/environments/test.rb") do |file| - assert_match(/^\s*config\.i18n\.raise_on_missing_translations\s*=\s*true/, file) - end - end - - test "disable action_dispatch.show_exceptions" do - run_generator - - assert_file app_root("config/environments/test.rb") do |file| - assert_match(/^\s*config\.action_dispatch\.show_exceptions\s*=\s*:none/, file) - assert_no_match(/^\s*config\.action_dispatch\.show_exceptions\s*=\s*:rescuable/, file) - assert_no_match(/^\s*#\s*Raise exceptions instead of rendering exception templates/i, file) - end - end - - test "disable action_dispatch.show_exceptions (when config does not exist)" do - content = file_fixture("environments/test.rb").read - remove_file_if_exists "config/environments/test.rb" - touch "config/environments/test.rb", content: content - - run_generator - - assert_file app_root("config/environments/test.rb") do |file| - assert_match(/^\s*config\.action_dispatch\.show_exceptions\s*=\s*:none/, file) - end - end - - private - - def prepare_destination - backup_file "config/environments/test.rb" - end - - def restore_destination - restore_file "config/environments/test.rb" - end - end - end - end -end diff --git a/test/generators/suspenders/factories_generator_test.rb b/test/generators/suspenders/factories_generator_test.rb deleted file mode 100644 index 9b6797fab..000000000 --- a/test/generators/suspenders/factories_generator_test.rb +++ /dev/null @@ -1,173 +0,0 @@ -require "test_helper" -require "generators/suspenders/factories_generator" - -module Suspenders - module Generators - class FactoriesGenerator::DefaultTest < Rails::Generators::TestCase - include Suspenders::TestHelpers - - tests Suspenders::Generators::FactoriesGenerator - destination Rails.root - setup :prepare_destination - teardown :restore_destination - - test "installs gem with Bundler" do - with_test_suite :minitest do - output = run_generator - - assert_match(/bundle install/, output) - end - end - - test "removes fixture definitions" do - with_test_suite :minitest do - run_generator - - assert_file app_root("test/test_helper.rb") do |file| - assert_match(/# fixtures :all/, file) - end - end - end - - test "adds gem to Gemfile" do - with_test_suite :minitest do - run_generator - - assert_file app_root("Gemfile") do |file| - assert_match(/group :development, :test do\n gem "factory_bot_rails"\nend/, file) - end - end - end - - test "includes syntax methods" do - with_test_suite :minitest do - run_generator - - assert_file app_root("test/test_helper.rb") do |file| - assert_match(/class TestCase\n include FactoryBot::Syntax::Methods/, file) - end - end - end - - test "creates definition file" do - with_test_suite :minitest do - definition_file = file_fixture("factories.rb").read - - run_generator - - assert_file app_root("test/factories.rb") do |file| - assert_match definition_file, file - end - end - end - - test "creates linting test" do - with_test_suite :minitest do - factories_test = file_fixture("factories_test_lint.rb").read - - run_generator - - assert_file app_root("test/factory_bots/factories_test.rb") do |file| - assert_match factories_test, file - end - end - end - - private - - def prepare_destination - touch "Gemfile" - end - - def restore_destination - remove_file_if_exists "Gemfile" - remove_dir_if_exists "lib/tasks" - end - - def test_helper - file_fixture("test_helper.rb").read - end - end - - class FactoriesGenerator::RSpecTest < Rails::Generators::TestCase - include Suspenders::TestHelpers - - tests Suspenders::Generators::FactoriesGenerator - destination Rails.root - setup :prepare_destination - teardown :restore_destination - - test "includes syntax methods" do - with_test_suite :rspec do - touch("spec/rails_helper.rb") - factory_bot_config = <<~RUBY - FactoryBot.use_parent_strategy = true - - RSpec.configure do |config| - config.include FactoryBot::Syntax::Methods - end - RUBY - - run_generator - - assert_file app_root("spec/support/factory_bot.rb") do |file| - assert_match factory_bot_config, file - end - assert_file app_root("spec/rails_helper.rb") do |file| - assert_match(/Dir\[Rails\.root\.join\("spec\/support\/\*\*\/\*\.rb"\)\]\.sort\.each { \|file\| require file }/, file) - end - end - end - - test "creates definition file" do - with_test_suite :rspec do - definition_file = file_fixture("factories.rb").read - - run_generator - - assert_file app_root("spec/factories.rb") do |file| - assert_match definition_file, file - end - end - end - - test "does not modify rails_helper if it's configured to include support files" do - with_test_suite :rspec do - rails_helper = <<~RUBY - Dir[Rails.root.join("spec/support/**/*.rb")].sort.each { |file| require file } - RUBY - touch "spec/rails_helper.rb", content: rails_helper - - run_generator - - assert_file app_root("spec/rails_helper.rb") do |file| - assert_equal rails_helper, file - end - end - end - - test "creates linting test" do - with_test_suite :rspec do - factories_spec = file_fixture("factories_spec_lint.rb").read - - run_generator - - assert_file app_root("spec/factory_bots/factories_spec.rb") do |file| - assert_match factories_spec, file - end - end - end - - private - - def prepare_destination - touch "Gemfile" - end - - def restore_destination - remove_file_if_exists "Gemfile" - remove_dir_if_exists "lib/tasks" - end - end - end -end diff --git a/test/generators/suspenders/inline_svg_generator_test.rb b/test/generators/suspenders/inline_svg_generator_test.rb deleted file mode 100644 index b50fd5539..000000000 --- a/test/generators/suspenders/inline_svg_generator_test.rb +++ /dev/null @@ -1,76 +0,0 @@ -require "test_helper" -require "generators/suspenders/inline_svg_generator" - -module Suspenders - module Generators - class InlinveSvgGeneratorTest < Rails::Generators::TestCase - include Suspenders::TestHelpers - - tests Suspenders::Generators::InlineSvgGenerator - 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 "inline_svg", file - end - end - end - - test "does not raise if API configuration is commented out" do - within_api_only_app commented_out: true do - run_generator - - assert_file app_root("Gemfile") do |file| - assert_match "inline_svg", file - end - end - end - - test "adds gems to Gemfile" do - expected_output = <<~RUBY - gem "inline_svg" - RUBY - - run_generator - - assert_file app_root("Gemfile") do |file| - assert_match(expected_output, file) - end - end - - test "installs gems with Bundler" do - output = run_generator - - assert_match(/bundle install/, output) - end - - test "configures raising an error when an SVG file is not found" do - expected_configuration = file_fixture("inline_svg.rb").read - - run_generator - - assert_file app_root("config/initializers/inline_svg.rb") do |file| - assert_match(expected_configuration, file) - end - end - - private - - def prepare_destination - touch "Gemfile" - end - - def restore_destination - remove_file_if_exists "Gemfile" - remove_file_if_exists "config/initializers/inline_svg.rb" - end - end - end -end diff --git a/test/generators/suspenders/install/web_generator_test.rb b/test/generators/suspenders/install/web_generator_test.rb deleted file mode 100644 index b27407329..000000000 --- a/test/generators/suspenders/install/web_generator_test.rb +++ /dev/null @@ -1,63 +0,0 @@ -require "test_helper" -require "generators/suspenders/install/web_generator" - -module Suspenders - module Generators - module Install - class WebGeneratorTest < Rails::Generators::TestCase - include Suspenders::TestHelpers - - tests Suspenders::Generators::Install::WebGenerator - 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 - end - end - - test "raises if PostgreSQL is not the adapter" do - with_database "unsupported" do - assert_raises Suspenders::Generators::DatabaseUnsupported::Error do - run_generator - end - end - end - - test "raises if Node is not installed" do - Object.any_instance.stubs(:`).returns("") - - with_database "postgresql" do - assert_raises Suspenders::Generators::NodeNotInstalled::Error do - run_generator - end - end - end - - test "raises if Node is unsupported" do - Object.any_instance.stubs(:`).returns("v19.9.9\n") - - with_database "postgresql" do - assert_raises Suspenders::Generators::NodeVersionUnsupported::Error do - run_generator - end - end - end - - private - - def prepare_destination - touch "Gemfile" - end - - def restore_destination - remove_file_if_exists "Gemfile" - end - end - end - end -end diff --git a/test/generators/suspenders/jobs_generator_test.rb b/test/generators/suspenders/jobs_generator_test.rb deleted file mode 100644 index d2ae73d00..000000000 --- a/test/generators/suspenders/jobs_generator_test.rb +++ /dev/null @@ -1,83 +0,0 @@ -require "test_helper" -require "generators/suspenders/jobs_generator" - -module Suspenders - module Generators - class JobsGeneratorTest < Rails::Generators::TestCase - include Suspenders::TestHelpers - - tests Suspenders::Generators::JobsGenerator - destination Rails.root - setup :prepare_destination - teardown :restore_destination - - test "adds gems to Gemfile" do - expected_output = <<~RUBY - gem "sidekiq" - RUBY - - run_generator - - assert_file app_root("Gemfile") do |file| - assert_match(expected_output, file) - end - end - - test "installs gems with Bundler" do - output = run_generator - - assert_match(/bundle install/, output) - end - - test "adds ActiveJob configuration to the application file" do - run_generator - - assert_file app_root("config/application.rb") do |file| - assert_match(/config.active_job.queue_adapter = :sidekiq/, file) - end - end - - test "adds ActiveJob configuration to the test environment file" do - run_generator - - assert_file app_root("config/environments/test.rb") do |file| - assert_match(/config.active_job.queue_adapter = :inline/, file) - end - end - - test "creates a Procfile.dev with Sidekiq configuration" do - run_generator - - assert_file app_root("Procfile.dev") do |file| - assert_match(/worker: bundle exec sidekiq/, file) - end - end - - test "adds Sidekiq configuration if procfile exists" do - touch "Procfile.dev" - - run_generator - - assert_file app_root("Procfile.dev") do |file| - assert_match(/worker: bundle exec sidekiq/, file) - end - end - - private - - def prepare_destination - touch "Gemfile" - backup_file "config/application.rb" - backup_file "config/environments/test.rb" - end - - def restore_destination - remove_file_if_exists "Gemfile" - remove_file_if_exists "config/initializers/active_job.rb" - remove_file_if_exists "Procfile.dev" - restore_file "config/application.rb" - restore_file "config/environments/test.rb" - end - end - end -end diff --git a/test/generators/suspenders/lint_generator_test.rb b/test/generators/suspenders/lint_generator_test.rb deleted file mode 100644 index 91c91731e..000000000 --- a/test/generators/suspenders/lint_generator_test.rb +++ /dev/null @@ -1,207 +0,0 @@ -require "test_helper" -require "generators/suspenders/lint_generator" - -module Suspenders - module Generators - class LintGeneratorTest < Rails::Generators::TestCase - include Suspenders::TestHelpers - - tests Suspenders::Generators::LintGenerator - destination Rails.root - setup :prepare_destination - teardown :restore_destination - - test "installs dependencies" do - capture(:stderr) do - output = run_generator - - assert_match(/yarn add stylelint eslint@\^8\.9\.0 @thoughtbot\/stylelint-config @thoughtbot\/eslint-config npm-run-all prettier --dev/, output) - end - end - - test "installs gems" do - capture(:stderr) do - expected_gemfile = <<~TEXT - group :development, :test do - gem "better_html", require: false - gem "erb_lint", require: false - gem "erblint-github", require: false - gem "standard" - end - TEXT - - output = run_generator - - assert_match(/bundle install/, output) - assert_file app_root "Gemfile" do |file| - assert_match expected_gemfile, file - end - end - end - - test "configures stylelint" do - expected_content = file_fixture("stylelintrc.json").read - - capture(:stderr) { run_generator } - - assert_file app_root(".stylelintrc.json") do |file| - assert_equal expected_content, file - end - end - - test "configures eslint" do - expected_content = file_fixture("eslintrc.json").read - - capture(:stderr) { run_generator } - - assert_file app_root(".eslintrc.json") do |file| - assert_equal expected_content, file - end - end - - test "configures prettier" do - prettierrc = file_fixture("prettierrc.json").read - prettierignore = file_fixture("prettierignore").read - - capture(:stderr) { run_generator } - - assert_file app_root(".prettierrc") do |file| - assert_equal prettierrc, file - end - - assert_file app_root(".prettierignore") do |file| - assert_equal prettierignore, file - end - end - - test "configures erb-lint" do - capture(:stderr) { run_generator } - - assert_file app_root(".erb-lint.yml") - assert_file app_root("config/better_html.yml") - assert_file app_root("config/initializers/better_html.rb") - assert_file app_root("lib/tasks/erblint.rake") - end - - test "erb-lint.yml configuration" do - expected_content = file_fixture("erb-lint.yml").read - - capture(:stderr) { run_generator } - - assert_file app_root(".erb-lint.yml") do |file| - assert_equal expected_content, file - end - end - - test "better html configuration" do - expected_content = file_fixture("better_html.rb").read - - capture(:stderr) { run_generator } - - assert_file app_root("config/initializers/better_html.rb") do |file| - assert_equal expected_content, file - end - end - - test "generates .rubocop.yml" do - expected_content = <<~YAML - AllCops: - TargetRubyVersion: #{RUBY_VERSION} - - require: standard - - inherit_gem: - standard: config/base.yml - YAML - - capture(:stderr) { run_generator } - - assert_file app_root(".rubocop.yml") do |file| - assert_equal expected_content, file - end - end - - test "updates package.json" do - touch "package.json", content: package_json - - capture(:stderr) { run_generator } - - assert_file "package.json" do |file| - assert_equal expected_package_json, file - end - end - - test "updates package.json if script key does not exist" do - touch "package.json", content: package_json(empty: true) - - capture(:stderr) { run_generator } - - assert_file "package.json" do |file| - assert_equal expected_package_json, file - end - end - - test "created package.json if one does not exist" do - remove_file_if_exists "package.json" - - capture(:stderr) { run_generator } - - assert_file app_root("package.json") - end - - private - - def prepare_destination - touch "Gemfile" - touch "package.json", content: package_json(empty: true) - end - - def restore_destination - remove_file_if_exists "Gemfile" - remove_file_if_exists ".stylelintrc.json" - remove_file_if_exists ".eslintrc.json" - remove_file_if_exists ".prettierrc" - remove_file_if_exists ".prettierignore" - remove_file_if_exists "package.json" - remove_file_if_exists ".erb-lint.yml" - remove_file_if_exists "config/better_html.yml" - remove_file_if_exists "config/initializers/better_html.rb" - remove_file_if_exists ".rubocop.yml" - remove_file_if_exists "package.json", root: true - remove_file_if_exists "yarn.lock", root: true - remove_dir_if_exists "lib/tasks" - remove_dir_if_exists "test" - remove_dir_if_exists "spec" - end - - def package_json(empty: false) - if empty - <<~JSON.chomp - { - } - JSON - else - <<~JSON.chomp - { - "scripts": {} - } - JSON - end - end - - def expected_package_json - <<~JSON.chomp - { - "scripts": { - "lint": "run-p lint:eslint lint:stylelint lint:prettier", - "lint:eslint": "eslint --max-warnings=0 --no-error-on-unmatched-pattern 'app/javascript/**/*.js'", - "lint:stylelint": "stylelint 'app/assets/stylesheets/**/*.css'", - "lint:prettier": "prettier --check '**/*' --ignore-unknown", - "fix:prettier": "prettier --write '**/*' --ignore-unknown" - } - } - JSON - end - end - end -end diff --git a/test/generators/suspenders/prerequisites_generator_test.rb b/test/generators/suspenders/prerequisites_generator_test.rb deleted file mode 100644 index 1c0bd4958..000000000 --- a/test/generators/suspenders/prerequisites_generator_test.rb +++ /dev/null @@ -1,61 +0,0 @@ -require "test_helper" -require "climate_control" -require "generators/suspenders/prerequisites_generator" - -module Suspenders - module Generators - class PrerequisitesGeneratorTest < Rails::Generators::TestCase - include Suspenders::TestHelpers - - tests Suspenders::Generators::PrerequisitesGenerator - destination Rails.root - teardown :restore_destination - - test "generates .node-version file (from ENV)" do - ClimateControl.modify NODE_VERSION: "20.0.0" do - run_generator - - assert_file app_root(".node-version") do |file| - assert_match(/20\.0\.0/, file) - end - end - end - - test "generates .node-version file (from system)" do - Object.any_instance.stubs(:`).returns("v20.0.0\n") - - run_generator - - assert_file app_root(".node-version") do |file| - assert_match(/20\.0\.0/, file) - end - end - - test "raises if Node is not installed" do - Object.any_instance.stubs(:`).returns("") - - assert_raises Suspenders::Generators::NodeNotInstalled::Error do - run_generator - end - - assert_no_file app_root(".node-version") - end - - test "raises if Node is unsupported" do - Object.any_instance.stubs(:`).returns("v19.9.9\n") - - assert_raises Suspenders::Generators::NodeVersionUnsupported::Error do - run_generator - end - - assert_no_file app_root(".node-version") - end - - private - - def restore_destination - remove_file_if_exists ".node-version" - end - end - end -end diff --git a/test/generators/suspenders/rake_generator_test.rb b/test/generators/suspenders/rake_generator_test.rb deleted file mode 100644 index d098c0118..000000000 --- a/test/generators/suspenders/rake_generator_test.rb +++ /dev/null @@ -1,37 +0,0 @@ -require "test_helper" -require "generators/suspenders/rake_generator" - -module Suspenders - module Generators - class RakeGeneratorTest < Rails::Generators::TestCase - include Suspenders::TestHelpers - - tests Suspenders::Generators::RakeGenerator - destination Rails.root - setup :prepare_destination - teardown :restore_destination - - test "modifies existing Rakefile" do - content = file_fixture("Rakefile").read - - run_generator - - assert_file app_root("Rakefile") do |file| - assert_equal content, file - end - end - - private - - def prepare_destination - touch "Gemfile" - backup_file "Rakefile" - end - - def restore_destination - remove_file_if_exists "Gemfile" - restore_file "Rakefile" - end - end - end -end diff --git a/test/generators/suspenders/setup_generator_test.rb b/test/generators/suspenders/setup_generator_test.rb deleted file mode 100644 index 0fff4136a..000000000 --- a/test/generators/suspenders/setup_generator_test.rb +++ /dev/null @@ -1,39 +0,0 @@ -require "test_helper" -require "generators/suspenders/setup_generator" - -module Suspenders - module Generators - class SetupGeneratorTest < Rails::Generators::TestCase - include Suspenders::TestHelpers - - tests Suspenders::Generators::SetupGenerator - destination Rails.root - setup :prepare_destination - teardown :restore_destination - - test "modifies bin/setup" do - expected = bin_setup - - run_generator - - assert_file app_root("bin/setup") do |file| - assert_equal expected, file - end - end - - private - - def prepare_destination - backup_file "bin/setup" - end - - def restore_destination - restore_file "bin/setup" - end - - def bin_setup - File.read("./lib/generators/templates/setup/bin_setup.rb") - end - end - end -end diff --git a/test/generators/suspenders/styles_generator_test.rb b/test/generators/suspenders/styles_generator_test.rb deleted file mode 100644 index 8a0e8c46b..000000000 --- a/test/generators/suspenders/styles_generator_test.rb +++ /dev/null @@ -1,139 +0,0 @@ -require "test_helper" -require "generators/suspenders/styles_generator" - -module Suspenders - module Generators - class StylesGeneratorTest < Rails::Generators::TestCase - include Suspenders::TestHelpers - - tests Suspenders::Generators::StylesGenerator - 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 - end - end - - test "does not raise if API configuration is commented out" do - within_api_only_app(commented_out: true) do - capture(:stderr) { run_generator } - end - end - - test "adds gems to Gemfile" do - capture(:stderr) { run_generator } - - assert_file app_root("Gemfile") do |file| - assert_match "cssbundling-rails", file - end - end - - test "installs gems with Bundler" do - capture(:stderr) do - output = run_generator - - assert_match(/bundle install/, output) - end - end - - test "runs install script" do - capture(:stderr) do - output = run_generator - - assert_match(/bin\/rails css:install:postcss/, output) - end - end - - test "installs modern-normalize and imports stylesheets" do - capture(:stderr) do - output = run_generator - application_stylesheet = <<~TEXT - @import "modern-normalize"; - @import "base.css"; - @import "components.css"; - @import "utilities.css"; - TEXT - - assert_match(/add.*modern-normalize/, output) - - assert_file app_root("app/assets/stylesheets/application.postcss.css") do |file| - assert_equal application_stylesheet, file - end - end - end - - test "creates stylesheets" do - capture(:stderr) { run_generator } - - assert_file app_root("app/assets/stylesheets/base.css") do |file| - assert_equal "/* Base Styles */", file - end - assert_file app_root("app/assets/stylesheets/components.css") do |file| - assert_equal "/* Component Styles */", file - end - assert_file app_root("app/assets/stylesheets/utilities.css") do |file| - assert_equal "/* Utility Styles */", file - end - end - - test "installs postcss-url" do - capture(:stderr) do - output = run_generator - - assert_match(/add\s*postcss-url/, output) - end - end - - test "configures postcss.config.js" do - expected = file_fixture("postcss.config.js").read - - capture(:stderr) { run_generator } - - assert_file app_root("postcss.config.js") do |file| - assert_equal expected, file - end - end - - test "overrides existing postcss.config.js" do - touch "postcss.config.js", content: "unexpected" - expected = file_fixture("postcss.config.js").read - - capture(:stderr) { run_generator } - - assert_file app_root("postcss.config.js") do |file| - assert_equal expected, file - end - end - - test "creates directory to store static assets generated from postcss-url" do - capture(:stderr) { run_generator } - - assert_file app_root("app/assets/static/.gitkeep") - end - - private - - def prepare_destination - touch "Gemfile" - touch "app/assets/stylesheets/application.postcss.css" - end - - def restore_destination - remove_file_if_exists "Gemfile" - remove_file_if_exists "package.json", root: true - remove_file_if_exists "yarn.lock", root: true - remove_file_if_exists "app/assets/stylesheets/application.postcss.css" - remove_file_if_exists "app/assets/stylesheets/base.css" - remove_file_if_exists "app/assets/stylesheets/components.css" - remove_file_if_exists "app/assets/stylesheets/utilities.css" - remove_file_if_exists "postcss.config.js" - remove_dir_if_exists "app/assets/static" - end - end - end -end diff --git a/test/generators/suspenders/tasks_generator_test.rb b/test/generators/suspenders/tasks_generator_test.rb deleted file mode 100644 index 0f2e1d1f0..000000000 --- a/test/generators/suspenders/tasks_generator_test.rb +++ /dev/null @@ -1,43 +0,0 @@ -require "test_helper" -require "generators/suspenders/tasks_generator" - -module Suspenders - module Generators - class TasksGeneratorTest < Rails::Generators::TestCase - include Suspenders::TestHelpers - - tests Suspenders::Generators::TasksGenerator - destination Rails.root - teardown :restore_destination - - test "creates dev.rake file" do - Bundler.rubygems.stubs(:find_name).with("factory_bot").returns([true]) - - expected = dev_rake - - run_generator - - assert_file app_root("lib/tasks/dev.rake") do |file| - assert_equal expected, file - end - end - - test "returns early if factory_bot_rails is not installed" do - output = run_generator - - assert_match(/This generator requires Factory Bot/, output) - assert_no_file app_root("lib/tasks/dev.rake") - end - - private - - def dev_rake - File.read("./lib/generators/templates/tasks/dev.rake") - end - - def restore_destination - remove_file_if_exists "lib/tasks/dev.rake" - end - end - end -end diff --git a/test/generators/suspenders/testing_generator_test.rb b/test/generators/suspenders/testing_generator_test.rb deleted file mode 100644 index 8b4b06ae6..000000000 --- a/test/generators/suspenders/testing_generator_test.rb +++ /dev/null @@ -1,140 +0,0 @@ -require "test_helper" -require "generators/suspenders/testing_generator" - -module Suspenders - module Generators - class TestingGeneratorTest < Rails::Generators::TestCase - include Suspenders::TestHelpers - - tests Suspenders::Generators::TestingGenerator - destination Rails.root - setup :prepare_destination - teardown :restore_destination - - test "adds gems to Gemfile" do - expected = <<~RUBY - group :development, :test do - gem "rspec-rails", "~> 6.1.0" - end - - group :test do - gem "capybara" - gem "action_dispatch-testing-integration-capybara", github: "thoughtbot/action_dispatch-testing-integration-capybara", tag: "v0.1.1", require: "action_dispatch/testing/integration/capybara/rspec" - gem "selenium-webdriver" - gem "shoulda-matchers", "~> 6.0" - gem "webmock" - end - RUBY - - run_generator - - assert_file app_root("Gemfile") do |file| - assert_match(expected, file) - end - end - - test "installs gems with Bundler" do - output = run_generator - - assert_match(/bundle install/, output) - end - - test "runs RSpec installation script" do - output = run_generator - - assert_match(/generate rspec:install/, output) - end - - test "configures rails_helper" do - touch "spec/rails_helper.rb", content: rails_helper - - run_generator - - assert_file "spec/rails_helper.rb" do |file| - assert_match(/RSpec\.configure do \|config\|\s{3}config\.infer_base_class_for_anonymous_controllers\s*=\s*false/m, - file) - assert_match(/^\#{0}\s*Rails\.root\.glob\("spec\/support\/\*\*\/\*\.rb"\)\.sort\.each { \|f\| require f }/, file) - end - end - - test "configures spec_helper" do - touch "spec/spec_helper.rb", content: spec_helper - expected = file_fixture("spec_helper.rb").read - - run_generator - - assert_file app_root("spec/spec_helper.rb") do |file| - assert_equal expected, file - end - end - - test "configures driver" do - expected = file_fixture("driver.rb").read - - run_generator - - assert_file app_root("spec/support/driver.rb") do |file| - assert_equal expected, file - end - end - - test "creates system spec directory" do - run_generator - - assert_file app_root("spec/system/.gitkeep") - end - - test "configures Should Matchers" do - expected = file_fixture("shoulda_matchers.rb").read - - run_generator - - assert_file app_root("spec/support/shoulda_matchers.rb") do |file| - assert_equal expected, file - end - end - - test "configures i18n" do - expected = file_fixture("i18n.rb").read - - run_generator - - assert_file app_root("spec/support/i18n.rb") do |file| - assert_equal expected, file - end - end - - test "configures Action Mailer" do - expected = file_fixture("action_mailer.rb").read - - run_generator - - assert_file app_root("spec/support/action_mailer.rb") do |file| - assert_equal expected, file - end - end - - private - - def prepare_destination - touch "Gemfile" - mkdir "spec" - touch "spec/rails_helper.rb" - touch "spec/spec_helper.rb" - end - - def restore_destination - remove_file_if_exists "Gemfile" - remove_dir_if_exists "spec" - end - - def rails_helper - file_fixture("rails_helper.rb").read - end - - def spec_helper - file_fixture("spec_helper.rb").read - end - end - end -end diff --git a/test/generators/suspenders/views_generator_test.rb b/test/generators/suspenders/views_generator_test.rb deleted file mode 100644 index ddd26554e..000000000 --- a/test/generators/suspenders/views_generator_test.rb +++ /dev/null @@ -1,100 +0,0 @@ -require "test_helper" -require "generators/suspenders/views_generator" - -module Suspenders - module Generators - class ViewsGeneratorTest < Rails::Generators::TestCase - include Suspenders::TestHelpers - - tests Suspenders::Generators::ViewsGenerator - 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 "title", file - end - end - end - - test "creates flash partial" do - expected = file_fixture("_flashes.html.erb").read - - run_generator - - assert_file app_root("app/views/application/_flashes.html.erb") do |file| - assert_equal expected, file - end - end - - test "includes flash partial in layout" do - run_generator - - assert_file app_root("app/views/layouts/application.html.erb") do |file| - assert_match(/\s{5}<%= render "flashes" -%>$/, file) - end - end - - test "sets the language" do - run_generator - - assert_file app_root("app/views/layouts/application.html.erb") do |file| - assert_match(//, file) - end - end - - test "adds gems to Gemfile" do - expected_output = <<~RUBY - gem "title" - RUBY - - run_generator - - assert_file app_root("Gemfile") do |file| - assert_match(expected_output, file) - end - end - - test "installs gems with Bundler" do - output = run_generator - - assert_match(/bundle install/, output) - end - - test "sets title" do - run_generator - - assert_file app_root("app/views/layouts/application.html.erb") do |file| - assert_match(/<%= title %><\/title>/, file) - end - end - - test "disables InstantClick" do - run_generator - - assert_file app_root("app/views/layouts/application.html.erb") do |file| - assert_match(/<head>.*<\/title>\s{4}<meta\s*name="turbo-prefetch"\s*content=\s*"false">/m, file) - end - end - - private - - def prepare_destination - touch "Gemfile" - backup_file "app/views/layouts/application.html.erb" - end - - def restore_destination - remove_file_if_exists "Gemfile" - remove_file_if_exists "app/views/application/_flashes.html.erb" - restore_file "app/views/layouts/application.html.erb" - end - end - end -end diff --git a/test/suspenders/cleanup/generate_readme_test.rb b/test/suspenders/cleanup/generate_readme_test.rb deleted file mode 100644 index adad61ce1..000000000 --- a/test/suspenders/cleanup/generate_readme_test.rb +++ /dev/null @@ -1,80 +0,0 @@ -require "test_helper" -require "tempfile" -require_relative "../../../lib/suspenders/cleanup/generate_readme" - -module Suspenders - module Cleanup - class GenerateReadmeTest < ActiveSupport::TestCase - test "generates README using generator descriptions" do - Object.any_instance.stubs(:`).returns("v20.0.0\n") - - Tempfile.create "README.md" do |readme| - path = readme.path - - Suspenders::Cleanup::GenerateReadme.perform(path, "ExpectedAppName") - - readme.rewind - readme = readme.read - - assert_match "# Expected App Name", readme - - assert_match "## Prerequisites", readme - assert_match Suspenders::MINIMUM_RUBY_VERSION, readme - assert_match "Node: `20.0.0`", readme - - assert_match "## Configuration", readme - assert_match "### Test", readme - assert_match Suspenders::Generators::Environments::TestGenerator.desc, readme - assert_match "### Development", readme - assert_match Suspenders::Generators::Environments::DevelopmentGenerator.desc, readme - assert_match "### Production", readme - assert_match Suspenders::Generators::Environments::ProductionGenerator.desc, readme - - assert_match "### Linting", readme - assert_match Suspenders::Generators::LintGenerator.desc, readme - - assert_match "## Testing", readme - assert_match Suspenders::Generators::TestingGenerator.desc, readme - assert_match "### Factories", readme - assert_match Suspenders::Generators::FactoriesGenerator.desc, readme - - assert_match "## Accessibility", readme - assert_match Suspenders::Generators::AccessibilityGenerator.desc, readme - - assert_match "## Advisories", readme - assert_match Suspenders::Generators::AdvisoriesGenerator.desc, readme - - assert_match "## Mailers", readme - assert_match Suspenders::Generators::EmailGenerator.desc, readme - - assert_match "## Jobs", readme - assert_match Suspenders::Generators::JobsGenerator.desc, readme - - assert_match "## Layout and Assets", readme - - assert_match "### Stylesheets", readme - assert_match Suspenders::Generators::StylesGenerator.desc, readme - assert_match "### Inline SVG", readme - assert_match Suspenders::Generators::InlineSvgGenerator.desc, readme - assert_match "### Layout", readme - assert_match Suspenders::Generators::ViewsGenerator.desc, readme - end - end - - test "replaces existing README" do - Tempfile.create "README.md" do |readme| - path = readme.path - readme.write "Unexpected Content" - readme.rewind - - Suspenders::Cleanup::GenerateReadme.perform(path, "App") - - readme.rewind - readme = readme.read - - assert_no_match "Unexpected Content", readme - end - end - end - end -end diff --git a/test/suspenders/cleanup/organize_gemfile_test.rb b/test/suspenders/cleanup/organize_gemfile_test.rb deleted file mode 100644 index b405ea375..000000000 --- a/test/suspenders/cleanup/organize_gemfile_test.rb +++ /dev/null @@ -1,23 +0,0 @@ -require "test_helper" -require "tempfile" -require_relative "../../../lib/suspenders/cleanup/organize_gemfile" - -module Suspenders - module Cleanup - class OrganizeGemfileTest < ActiveSupport::TestCase - test "organizes Gemfile by group" do - original = file_fixture("gemfile_messy").read - modified = file_fixture("gemfile_clean").read - - Tempfile.create "Gemfile" do |gemfile| - gemfile.write original - gemfile.rewind - - Suspenders::Cleanup::OrganizeGemfile.perform(gemfile.path) - - assert_equal modified, gemfile.read - end - end - end - end -end diff --git a/test/suspenders/generators_test.rb b/test/suspenders/generators_test.rb deleted file mode 100644 index daf5cbd98..000000000 --- a/test/suspenders/generators_test.rb +++ /dev/null @@ -1,35 +0,0 @@ -require "test_helper" - -class Suspenders::GeneratorsTest < ActiveSupport::TestCase - class APIAppUnsupportedTest < ActiveSupport::TestCase - 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 - - class DatabaseUnsupportedTest < ActiveSupport::TestCase - test "message returns a custom message" do - expected = "This generator requires PostgreSQL" - - assert_equal expected, Suspenders::Generators::DatabaseUnsupported::Error.new.message - end - end - - class NodeNotInstalledTest < ActiveSupport::TestCase - test "message returns a custom message" do - expected = "This generator requires Node" - - assert_equal expected, Suspenders::Generators::NodeNotInstalled::Error.new.message - end - end - - class NodeVersionUnsupportedTest < ActiveSupport::TestCase - test "message returns a custom message" do - expected = "This generator requires Node >= #{Suspenders::MINIMUM_NODE_VERSION}" - - assert_equal expected, Suspenders::Generators::NodeVersionUnsupported::Error.new.message - end - end -end diff --git a/test/suspenders_test.rb b/test/suspenders_test.rb deleted file mode 100644 index 580ffde15..000000000 --- a/test/suspenders_test.rb +++ /dev/null @@ -1,19 +0,0 @@ -require "test_helper" - -class SuspendersTest < ActiveSupport::TestCase - test "it has a version number" do - assert Suspenders::VERSION - end - - test "it has a Rails version number" do - assert Suspenders::RAILS_VERSION - end - - test "it has a Minimum Ruby version number" do - assert Suspenders::MINIMUM_RUBY_VERSION - end - - test "it has a Minimum Node version number" do - assert Suspenders::MINIMUM_NODE_VERSION - end -end diff --git a/test/test_helper.rb b/test/test_helper.rb deleted file mode 100644 index 40b962fef..000000000 --- a/test/test_helper.rb +++ /dev/null @@ -1,122 +0,0 @@ -# Configure Rails Environment -ENV["RAILS_ENV"] = "test" - -require_relative "../test/dummy/config/environment" -ActiveRecord::Migrator.migrations_paths = [File.expand_path("../test/dummy/db/migrate", __dir__)] -require "rails/test_help" -require "mocha/minitest" - -# Load fixtures from the engine -if ActiveSupport::TestCase.respond_to?(:fixture_paths=) - ActiveSupport::TestCase.fixture_paths = [File.expand_path("fixtures", __dir__)] - ActionDispatch::IntegrationTest.fixture_paths = ActiveSupport::TestCase.fixture_paths - ActiveSupport::TestCase.file_fixture_path = File.expand_path("fixtures", __dir__) + "/files" - ActiveSupport::TestCase.fixtures :all -end - -module Suspenders::TestHelpers - def app_root(path) - Rails.root.join path - end - - def remove_file_if_exists(file, **options) - root = options[:root] - path = root ? file : app_root(file) - - FileUtils.rm path if File.exist? path - end - - def remove_dir_if_exists(dir) - path = app_root dir - - FileUtils.rm_r path if File.exist? path - end - - def mkdir(dir) - path = app_root dir - - FileUtils.mkdir_p path - end - - def touch(file, **options) - content = options[:content] - path = app_root file - - FileUtils.touch path - - if content - File.write app_root(path), content - end - end - - def within_api_only_app(**options, &block) - commented_out = options[:commented_out] - set_config = if commented_out == true - "# config.api_only = true" - else - "config.api_only = true" - end - - 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)) - - #{set_config} - end - end - RUBY - File.open(app_root("config/application.rb"), "w") { _1.write application_config } - - yield - ensure - restore_file "config/application.rb" - end - - def with_test_suite(test_suite, &block) - case test_suite - when :minitest - mkdir "test" - touch "test/test_helper.rb", content: file_fixture("test_helper.rb").read - when :rspec - mkdir "spec" - touch "spec/spec_helper.rb" - else - raise ArgumentError, "unknown test suite: #{test_suite.inspect}" - end - - yield - ensure - remove_dir_if_exists "test" - remove_dir_if_exists "spec" - end - - def with_database(database, &block) - backup_file "config/database.yml" - configuration = File.read app_root("config/database.yml") - configuration = YAML.safe_load(configuration, aliases: true) - configuration["default"]["adapter"] = database - File.open(app_root("config/database.yml"), "w") { _1.write configuration.to_yaml } - - yield - ensure - restore_file "config/database.yml" - end - - def backup_file(file) - FileUtils.copy app_root(file), app_root("#{file}.bak") - end - - def restore_file(file) - remove_file_if_exists(file) - FileUtils.mv app_root("#{file}.bak"), app_root(file) - end -end From 71a76db2186bbb961bef34a10e6e93c9d8ed8ed8 Mon Sep 17 00:00:00 2001 From: Steve Polito <stevepolitodesign@users.noreply.github.com> Date: Thu, 11 Dec 2025 07:44:27 -0500 Subject: [PATCH 2/5] Optimize for Heroku (#1260) Introduces [Procfile][1] to automatically start the server and run migrations during the [release phase][2]. Additionally, we update our [database connection preference][3] to account for [nuance in connecting with Heroku][4]. [1]: https://devcenter.heroku.com/articles/getting-started-with-rails8#create-a-procfile [2]: https://devcenter.heroku.com/articles/release-phase [3]: https://guides.rubyonrails.org/configuring.html#connection-preference [4]: https://discuss.rubyonrails.org/t/brainstorming-approaches-to-reconcile-rails-8s-default-multi-db-setup-with-database-url/86769 --- lib/templates/Procfile | 2 ++ lib/templates/web.rb | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+) create mode 100644 lib/templates/Procfile diff --git a/lib/templates/Procfile b/lib/templates/Procfile new file mode 100644 index 000000000..e63f0560b --- /dev/null +++ b/lib/templates/Procfile @@ -0,0 +1,2 @@ +release: bundle exec rails db:migrate; bundle exec rails db:seed +web: bundle exec puma -C config/puma.rb diff --git a/lib/templates/web.rb b/lib/templates/web.rb index 5b9fc0006..e75db372e 100644 --- a/lib/templates/web.rb +++ b/lib/templates/web.rb @@ -9,6 +9,12 @@ def install_gems install_gems after_bundle do + # Initializers & Configuration + configure_database + + # Deployment + add_procfiles + # Finalization run_migrations lint_codebase @@ -16,6 +22,18 @@ def install_gems print_message end +def configure_database + gsub_file "config/database.yml", /^production:.*?password:.*?\n/m, <<~YAML + production: + <<: *default + url: <%= ENV["DATABASE_URL"] %> + YAML +end + +def add_procfiles + copy_file "Procfile" +end + def run_migrations rails_command "db:create" rails_command "db:migrate" From 1759e23a40187c9f3e149b6c98ae08a0a8f2ac52 Mon Sep 17 00:00:00 2001 From: Rob Whittaker <rob@thoughtbot.com> Date: Thu, 11 Dec 2025 17:54:49 +0000 Subject: [PATCH 3/5] Potential introduction of actions --- Gemfile | 1 + Gemfile.lock | 2 + lib/suspenders.rb | 1 + .../test/raise_on_missing_translations.rb | 45 +++++++++++++++++++ .../raise_on_missing_translations_spec.rb | 32 +++++++++++++ 5 files changed, 81 insertions(+) create mode 100644 lib/suspenders/actions/environments/test/raise_on_missing_translations.rb create mode 100644 spec/suspenders/actions/environments/test/raise_on_missing_translations_spec.rb diff --git a/Gemfile b/Gemfile index 1222e4b15..1e8bacc04 100644 --- a/Gemfile +++ b/Gemfile @@ -11,3 +11,4 @@ gem "rake", "~> 13.0" gem "rspec", "~> 3.0" gem "standard", "~> 1.3" +gem "thor" diff --git a/Gemfile.lock b/Gemfile.lock index 58c67ee5e..c557d684e 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -81,6 +81,7 @@ GEM lint_roller (~> 1.1) rubocop-performance (~> 1.19.1) stringio (3.1.3) + thor (1.4.0) unicode-display_width (2.5.0) PLATFORMS @@ -95,6 +96,7 @@ DEPENDENCIES rspec (~> 3.0) standard (~> 1.3) suspenders! + thor BUNDLED WITH 2.4.19 diff --git a/lib/suspenders.rb b/lib/suspenders.rb index 1642f84d0..357ebe95b 100644 --- a/lib/suspenders.rb +++ b/lib/suspenders.rb @@ -2,6 +2,7 @@ require_relative "suspenders/version" require_relative "suspenders/cli" +require_relative "suspenders/actions/environments/test/raise_on_missing_translations" module Suspenders class Error < StandardError; end diff --git a/lib/suspenders/actions/environments/test/raise_on_missing_translations.rb b/lib/suspenders/actions/environments/test/raise_on_missing_translations.rb new file mode 100644 index 000000000..4a03a90c4 --- /dev/null +++ b/lib/suspenders/actions/environments/test/raise_on_missing_translations.rb @@ -0,0 +1,45 @@ +require "thor/actions" + +module Suspenders + module Actions + module Environments + module Test + class RaiseOnMissingTranslations + include Thor::Actions + + PATTERN = /config\.i18n\.raise_on_missing_translations = true/ + TARGET_FILE = "config/environments/test.rb" + + attr_reader :destination_root + + def initialize(app_path) + @destination_root = app_path + self.behavior = :invoke + end + + def apply + uncomment_lines file_path, PATTERN + end + + def file_path + File.join(@destination_root, TARGET_FILE) + end + + private + + def options + {} + end + + def relative_to_original_destination_root(path, remove_dot = true) + path + end + + def say_status(...) + # Silence output + end + end + end + end + end +end diff --git a/spec/suspenders/actions/environments/test/raise_on_missing_translations_spec.rb b/spec/suspenders/actions/environments/test/raise_on_missing_translations_spec.rb new file mode 100644 index 000000000..b84df7ff9 --- /dev/null +++ b/spec/suspenders/actions/environments/test/raise_on_missing_translations_spec.rb @@ -0,0 +1,32 @@ +require "tmpdir" +require "spec_helper" + +RSpec.describe Suspenders::Actions::Environments::Test::RaiseOnMissingTranslations do + describe "#apply" do + it "enables the raising of errors for missing translations" do + within_temp_app do |app_dir| + action = Suspenders::Actions::Environments::Test::RaiseOnMissingTranslations.new app_dir + write_file action.file_path, <<~RUBY + # Raises error for missing translations. + # config.i18n.raise_on_missing_translations = true + RUBY + + action.apply + + content = File.read(action.file_path) + expect(content).to match(/^\s*config\.i18n\.raise_on_missing_translations = true/) + end + end + end + + def within_temp_app + Dir.mktmpdir do |dir| + yield dir + end + end + + def write_file(file_path, content) + FileUtils.mkdir_p File.dirname(file_path) + File.write file_path, content + end +end From 4900263f2a1444f356263fb38890490acdb1ba19 Mon Sep 17 00:00:00 2001 From: Rob Whittaker <rob@thoughtbot.com> Date: Fri, 12 Dec 2025 10:03:07 +0000 Subject: [PATCH 4/5] fixup! Potential introduction of actions --- lib/suspenders.rb | 2 +- .../test/raise_on_missing_translations.rb | 45 ------------------- .../actions/test/raise_i18n_error.rb | 28 ++++++++++++ .../raise_i18n_error_spec.rb} | 8 ++-- 4 files changed, 33 insertions(+), 50 deletions(-) delete mode 100644 lib/suspenders/actions/environments/test/raise_on_missing_translations.rb create mode 100644 lib/suspenders/actions/test/raise_i18n_error.rb rename spec/suspenders/actions/{environments/test/raise_on_missing_translations_spec.rb => test/raise_i18n_error_spec.rb} (64%) diff --git a/lib/suspenders.rb b/lib/suspenders.rb index 357ebe95b..ca2cc93ce 100644 --- a/lib/suspenders.rb +++ b/lib/suspenders.rb @@ -2,7 +2,7 @@ require_relative "suspenders/version" require_relative "suspenders/cli" -require_relative "suspenders/actions/environments/test/raise_on_missing_translations" +require_relative "suspenders/actions/test/raise_i18n_error" module Suspenders class Error < StandardError; end diff --git a/lib/suspenders/actions/environments/test/raise_on_missing_translations.rb b/lib/suspenders/actions/environments/test/raise_on_missing_translations.rb deleted file mode 100644 index 4a03a90c4..000000000 --- a/lib/suspenders/actions/environments/test/raise_on_missing_translations.rb +++ /dev/null @@ -1,45 +0,0 @@ -require "thor/actions" - -module Suspenders - module Actions - module Environments - module Test - class RaiseOnMissingTranslations - include Thor::Actions - - PATTERN = /config\.i18n\.raise_on_missing_translations = true/ - TARGET_FILE = "config/environments/test.rb" - - attr_reader :destination_root - - def initialize(app_path) - @destination_root = app_path - self.behavior = :invoke - end - - def apply - uncomment_lines file_path, PATTERN - end - - def file_path - File.join(@destination_root, TARGET_FILE) - end - - private - - def options - {} - end - - def relative_to_original_destination_root(path, remove_dot = true) - path - end - - def say_status(...) - # Silence output - end - end - end - end - end -end diff --git a/lib/suspenders/actions/test/raise_i18n_error.rb b/lib/suspenders/actions/test/raise_i18n_error.rb new file mode 100644 index 000000000..ef4619ad1 --- /dev/null +++ b/lib/suspenders/actions/test/raise_i18n_error.rb @@ -0,0 +1,28 @@ +require "thor" + +module Suspenders + module Actions + module Test + class RaiseI18nError < Thor::Group + include Thor::Actions + + PATTERN = /config\.i18n\.raise_on_missing_translations = true/ + TARGET_FILE = "config/environments/test.rb" + + argument :app_path + + def self.destination_root + app_path + end + + def apply + uncomment_lines file_path, PATTERN, verbose: false + end + + def file_path + File.join(app_path, TARGET_FILE) + end + end + end + end +end diff --git a/spec/suspenders/actions/environments/test/raise_on_missing_translations_spec.rb b/spec/suspenders/actions/test/raise_i18n_error_spec.rb similarity index 64% rename from spec/suspenders/actions/environments/test/raise_on_missing_translations_spec.rb rename to spec/suspenders/actions/test/raise_i18n_error_spec.rb index b84df7ff9..ffe43702e 100644 --- a/spec/suspenders/actions/environments/test/raise_on_missing_translations_spec.rb +++ b/spec/suspenders/actions/test/raise_i18n_error_spec.rb @@ -1,11 +1,11 @@ require "tmpdir" require "spec_helper" -RSpec.describe Suspenders::Actions::Environments::Test::RaiseOnMissingTranslations do +RSpec.describe Suspenders::Actions::Test::RaiseI18nError do describe "#apply" do it "enables the raising of errors for missing translations" do within_temp_app do |app_dir| - action = Suspenders::Actions::Environments::Test::RaiseOnMissingTranslations.new app_dir + action = Suspenders::Actions::Test::RaiseI18nError.new([app_dir]) write_file action.file_path, <<~RUBY # Raises error for missing translations. # config.i18n.raise_on_missing_translations = true @@ -13,8 +13,8 @@ action.apply - content = File.read(action.file_path) - expect(content).to match(/^\s*config\.i18n\.raise_on_missing_translations = true/) + expect(File.read(action.file_path)) + .to match(/^\s*config\.i18n\.raise_on_missing_translations = true/) end end end From e665db56362217b37dea5c91685500795a62f96f Mon Sep 17 00:00:00 2001 From: Rob Whittaker <rob@thoughtbot.com> Date: Fri, 12 Dec 2025 13:23:35 +0000 Subject: [PATCH 5/5] fixup! Potential introduction of actions --- lib/suspenders/actions/test/raise_i18n_error.rb | 12 +----------- lib/templates/web.rb | 9 +++++++++ .../suspenders/actions/test/raise_i18n_error_spec.rb | 8 +++++--- 3 files changed, 15 insertions(+), 14 deletions(-) diff --git a/lib/suspenders/actions/test/raise_i18n_error.rb b/lib/suspenders/actions/test/raise_i18n_error.rb index ef4619ad1..f64e9a716 100644 --- a/lib/suspenders/actions/test/raise_i18n_error.rb +++ b/lib/suspenders/actions/test/raise_i18n_error.rb @@ -9,18 +9,8 @@ class RaiseI18nError < Thor::Group PATTERN = /config\.i18n\.raise_on_missing_translations = true/ TARGET_FILE = "config/environments/test.rb" - argument :app_path - - def self.destination_root - app_path - end - def apply - uncomment_lines file_path, PATTERN, verbose: false - end - - def file_path - File.join(app_path, TARGET_FILE) + uncomment_lines TARGET_FILE, PATTERN, verbose: false end end end diff --git a/lib/templates/web.rb b/lib/templates/web.rb index e75db372e..0152f93aa 100644 --- a/lib/templates/web.rb +++ b/lib/templates/web.rb @@ -1,3 +1,5 @@ +require_relative "suspenders/actions/test/raise_i18n_error" + # Methods like `copy_file` will accept relative paths to the template's location. def source_paths Array(super) + [__dir__] @@ -12,6 +14,9 @@ def install_gems # Initializers & Configuration configure_database + # Test Environment + configure_test_environment + # Deployment add_procfiles @@ -30,6 +35,10 @@ def configure_database YAML end +def configure_test_environment + invoke Suspenders::Actions::Test::RaiseI18nError +end + def add_procfiles copy_file "Procfile" end diff --git a/spec/suspenders/actions/test/raise_i18n_error_spec.rb b/spec/suspenders/actions/test/raise_i18n_error_spec.rb index ffe43702e..f3bc3eea4 100644 --- a/spec/suspenders/actions/test/raise_i18n_error_spec.rb +++ b/spec/suspenders/actions/test/raise_i18n_error_spec.rb @@ -5,15 +5,17 @@ describe "#apply" do it "enables the raising of errors for missing translations" do within_temp_app do |app_dir| - action = Suspenders::Actions::Test::RaiseI18nError.new([app_dir]) - write_file action.file_path, <<~RUBY + action = Suspenders::Actions::Test::RaiseI18nError.new + action.destination_root = app_dir + file_path = File.join(app_dir, Suspenders::Actions::Test::RaiseI18nError::TARGET_FILE) + write_file file_path, <<~RUBY # Raises error for missing translations. # config.i18n.raise_on_missing_translations = true RUBY action.apply - expect(File.read(action.file_path)) + expect(File.read(file_path)) .to match(/^\s*config\.i18n\.raise_on_missing_translations = true/) end end