suspenders 20240516.0 → 20251219.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. checksums.yaml +4 -4
  2. data/.ruby-version +1 -0
  3. data/CODEOWNERS +9 -0
  4. data/CONTRIBUTING.md +71 -0
  5. data/FEATURES.md +177 -0
  6. data/GOALS.md +65 -0
  7. data/LICENSE +21 -0
  8. data/NEWS.md +808 -0
  9. data/README.md +73 -60
  10. data/RELEASING.md +18 -0
  11. data/Rakefile +7 -10
  12. data/SECURITY.md +19 -0
  13. data/exe/suspenders +38 -0
  14. data/lib/suspenders/cli.rb +64 -0
  15. data/lib/suspenders/version.rb +4 -4
  16. data/lib/suspenders.rb +5 -6
  17. data/lib/templates/Procfile +3 -0
  18. data/lib/templates/Procfile.dev +2 -0
  19. data/lib/{generators/templates/views/flashes.html.erb → templates/app/views/application/_flashes.html.erb} +4 -2
  20. data/lib/templates/app/views/application/_form_errors.html.erb +11 -0
  21. data/lib/templates/config/initializers/sidekiq.rb +14 -0
  22. data/lib/templates/lib/development/seeder.rb +21 -0
  23. data/lib/templates/lib/tasks/development.rake +15 -0
  24. data/lib/templates/spec/support/action_mailer.rb +11 -0
  25. data/lib/{generators/templates/factories/factory_bot_rspec.rb → templates/spec/support/factory_bot.rb} +0 -2
  26. data/lib/templates/web.rb +544 -0
  27. data/sig/suspenders.rbs +4 -0
  28. metadata +34 -120
  29. data/lib/generators/suspenders/accessibility_generator.rb +0 -24
  30. data/lib/generators/suspenders/advisories_generator.rb +0 -32
  31. data/lib/generators/suspenders/ci_generator.rb +0 -57
  32. data/lib/generators/suspenders/email_generator.rb +0 -56
  33. data/lib/generators/suspenders/environments/development_generator.rb +0 -50
  34. data/lib/generators/suspenders/environments/production_generator.rb +0 -27
  35. data/lib/generators/suspenders/environments/test_generator.rb +0 -39
  36. data/lib/generators/suspenders/factories_generator.rb +0 -64
  37. data/lib/generators/suspenders/inline_svg_generator.rb +0 -24
  38. data/lib/generators/suspenders/install/web_generator.rb +0 -71
  39. data/lib/generators/suspenders/jobs_generator.rb +0 -34
  40. data/lib/generators/suspenders/lint_generator.rb +0 -94
  41. data/lib/generators/suspenders/prerequisites_generator.rb +0 -19
  42. data/lib/generators/suspenders/rake_generator.rb +0 -25
  43. data/lib/generators/suspenders/setup_generator.rb +0 -14
  44. data/lib/generators/suspenders/styles_generator.rb +0 -84
  45. data/lib/generators/suspenders/tasks_generator.rb +0 -20
  46. data/lib/generators/suspenders/testing_generator.rb +0 -113
  47. data/lib/generators/suspenders/views_generator.rb +0 -38
  48. data/lib/generators/templates/ci/ci.yml.tt +0 -148
  49. data/lib/generators/templates/ci/dependabot.yml +0 -7
  50. data/lib/generators/templates/email/email_interceptor.rb +0 -11
  51. data/lib/generators/templates/factories/factories.rb +0 -2
  52. data/lib/generators/templates/factories/factories_test.rb +0 -9
  53. data/lib/generators/templates/inline_svg/inline_svg.rb +0 -3
  54. data/lib/generators/templates/install/web/CONTRIBUTING.md +0 -94
  55. data/lib/generators/templates/lint/config_better_html.yml +0 -2
  56. data/lib/generators/templates/lint/config_initializers_better_html.rb +0 -9
  57. data/lib/generators/templates/lint/erb-lint.yml +0 -63
  58. data/lib/generators/templates/lint/erblint.rake +0 -47
  59. data/lib/generators/templates/lint/eslintrc.json +0 -7
  60. data/lib/generators/templates/lint/package.json +0 -4
  61. data/lib/generators/templates/lint/prettierignore +0 -1
  62. data/lib/generators/templates/lint/prettierrc +0 -11
  63. data/lib/generators/templates/lint/rubocop.yml.tt +0 -7
  64. data/lib/generators/templates/lint/stylelintrc.json +0 -3
  65. data/lib/generators/templates/prerequisites/node-version.tt +0 -1
  66. data/lib/generators/templates/setup/bin_setup.rb +0 -39
  67. data/lib/generators/templates/styles/postcss.config.js +0 -11
  68. data/lib/generators/templates/tasks/dev.rake +0 -12
  69. data/lib/generators/templates/testing/action_mailer.rb +0 -5
  70. data/lib/install/web.rb +0 -54
  71. data/lib/suspenders/cleanup/generate_readme.rb +0 -165
  72. data/lib/suspenders/cleanup/organize_gemfile.rb +0 -134
  73. data/lib/suspenders/engine.rb +0 -5
  74. data/lib/suspenders/generators.rb +0 -126
  75. data/lib/suspenders/railtie.rb +0 -4
  76. data/lib/tasks/suspenders.rake +0 -37
  77. /data/lib/{generators/templates/factories → templates/spec}/factories_spec.rb +0 -0
  78. /data/lib/{generators/templates/testing → templates/spec/support}/driver.rb +0 -0
  79. /data/lib/{generators/templates/testing → templates/spec/support}/i18n.rb +0 -0
  80. /data/lib/{generators/templates/testing → templates/spec/support}/shoulda_matchers.rb +0 -0
data/README.md CHANGED
@@ -2,103 +2,114 @@
2
2
 
3
3
  [![CI](https://github.com/thoughtbot/suspenders/actions/workflows/main.yml/badge.svg)](https://github.com/thoughtbot/suspenders/actions/workflows/main.yml)
4
4
 
5
- Suspenders is a [Rails Engine][] containing generators for configuring Rails
6
- applications with these [features][].
5
+ Suspenders is intended to create a new Rails applications with these
6
+ [features][], and is optimised for deployment on Heroku.
7
7
 
8
- It is used by thoughtbot to get a jump start on a new or existing app. Use
9
- Suspenders if you're in a rush to build something amazing; don't use it if you
10
- like missing deadlines.
8
+ It is used by thoughtbot to get a jump start on new apps. Use Suspenders if
9
+ you're in a rush to build something amazing; don't use it if you like missing
10
+ deadlines.
11
11
 
12
- [Rails Engine]: https://guides.rubyonrails.org/engines.html
13
12
  [features]: ./FEATURES.md
14
13
 
15
14
  ![Suspenders boy](https://media.tumblr.com/1TEAMALpseh5xzf0Jt6bcwSMo1_400.png)
16
15
 
17
- ## Requirements
16
+ ## Prerequisites
18
17
 
19
- - Rails `~> 7.0`
20
- - Ruby `>= 3.1`
21
- - Node `>= 20.0.0`
18
+ Suspenders requires the **latest** version of [Rails][] and its dependencies.
19
+
20
+ Additionally, Suspenders requires [PostgreSQL][] and [Redis][].
21
+
22
+ [Rails]: https://guides.rubyonrails.org/install_ruby_on_rails.html
23
+ [PostgreSQL]: https://formulae.brew.sh/formula/postgresql@17
24
+ [Redis]: https://formulae.brew.sh/formula/redis
25
+
26
+ ## Installation
27
+
28
+ ```
29
+ gem install suspenders
30
+ ```
22
31
 
23
32
  ## Usage
24
33
 
25
- Suspenders can be used to create a new Rails application, or to enhance an
26
- existing Rails application.
34
+ First, make sure you're on the latest version of Rails.
27
35
 
28
- ### With New Rails Applications
36
+ ```
37
+ gem update rails
38
+ ```
29
39
 
30
- This approach uses an [application template][] to generate a new Rails
31
- application with Suspenders.
40
+ Then, create a new application with Suspenders.
32
41
 
33
- We skip the [default test framework][] in favor of [RSpec][], and [prefer
34
- PostgreSQL][] as our database.
42
+ ```
43
+ suspenders new <app_name>
44
+ ```
45
+
46
+ Under the hood, Suspenders uses an [application template][] to generate a new Rails
47
+ application like so:
35
48
 
36
49
  ```
37
- rails new app_name \
38
- --skip-test \
50
+ rails new <app_name> \
39
51
  -d=postgresql \
40
- -m=https://raw.githubusercontent.com/thoughtbot/suspenders/main/lib/install/web.rb
52
+ --skip-test \
53
+ --skip-solid \
54
+ --m=~/path/to/template.rb
41
55
  ```
42
56
 
43
- Then run `bin/setup` within the newly generated application.
57
+ We skip the [default test framework][] in favor of [RSpec][], and [prefer
58
+ PostgreSQL][] as our database. We skip the Solid ecosystem since we prefer
59
+ [Sidekiq][], and because Solid Queue has [performance issues][] on Heroku.
44
60
 
45
- Alternatively, if you're using our [dotfiles][], then you can just run `rails new
46
- app_name`, or create your own [railsrc][] file with the following configuration:
61
+ > [!IMPORTANT]
62
+ > Since Suspenders generates an application that enables `require_master_key`,
63
+ > you'll need to add it to GitHub as a [secret][] in order for GitHub Actions to
64
+ > work.
47
65
 
48
66
  ```
49
- --skip-test
50
- --database=postgresql
51
- -m=https://raw.githubusercontent.com/thoughtbot/suspenders/main/lib/install/web.rb
67
+ cd <app_name>
68
+
69
+ gh secret set RAILS_MASTER_KEY value-from-config-master.key
52
70
  ```
53
71
 
54
72
  [application template]: https://guides.rubyonrails.org/rails_application_templates.html
55
73
  [default test framework]: https://guides.rubyonrails.org/testing.html
56
74
  [RSpec]: http://rspec.info
57
75
  [prefer PostgreSQL]: https://github.com/thoughtbot/dotfiles/pull/728
58
- [dotfiles]: https://github.com/thoughtbot/dotfiles
59
- [railsrc]: https://github.com/rails/rails/blob/7f7f9df8641e35a076fe26bd097f6a1b22cb4e2d/railties/lib/rails/generators/rails/app/USAGE#L5C1-L7
76
+ [Sidekiq]: https://github.com/sidekiq/sidekiq/
77
+ [performance issues]: https://github.com/rails/solid_queue/issues/330
78
+ [secret]: https://docs.github.com/en/actions/how-tos/write-workflows/choose-what-workflows-do/use-secrets
60
79
 
61
- ### With Existing Rails Applications
80
+ ## Initial deployment to Heroku
62
81
 
63
- Suspenders can be used on an existing Rails application by adding it to the
64
- `:development` and `:test` group.
82
+ Once your application is generated, you can deploy to Heroku with [Heroku CLI][cli].
65
83
 
66
- ```ruby
67
- group :development, :test do
68
- gem "suspenders"
69
- end
70
- ```
71
84
 
72
- Once installed, you can invoke the web installation generator, which will
73
- invoke all generators.
74
-
75
- ```
76
- bin/rails g suspenders:install:web
77
85
  ```
86
+ cd <app_name>
78
87
 
79
- Or, you can invoke generators individually. To see a list of available
80
- generators run:
88
+ heroku apps:create
81
89
 
82
- ```
83
- bin/rails g | grep suspenders
90
+ heroku buildpacks:set heroku/ruby
91
+
92
+ heroku addons:create heroku-postgresql:essential-0
93
+ heroku addons:create heroku-redis:mini
84
94
  ```
85
95
 
86
- To learn more about a generator, run:
96
+ Once the application is provisioned, you'll want to set the following required
97
+ environment variables.
87
98
 
88
99
  ```
89
- bin/rails g suspenders:[generator_name] --help
100
+ heroku config:set \
101
+ APPLICATION_HOST=value-from-heroku
102
+ RAILS_MASTER_KEY=value-from-config-master.key
90
103
  ```
91
104
 
92
- ### Available Tasks
93
-
94
- Suspenders ships with several custom Rake tasks.
105
+ Finally, don't forget to enable the `worker`.
95
106
 
96
107
  ```
97
- bin/rails suspenders:rake
98
- bin/rails suspenders:db:migrate
99
- bin/rails suspenders:cleanup:organize_gemfile
108
+ heroku ps:scale worker=1
100
109
  ```
101
110
 
111
+ [cli]: https://devcenter.heroku.com/articles/heroku-cli
112
+
102
113
  ## Contributing
103
114
 
104
115
  See the [CONTRIBUTING] document.
@@ -115,18 +126,20 @@ under the terms specified in the [LICENSE] file.
115
126
 
116
127
  [LICENSE]: /LICENSE
117
128
 
118
- ## About
129
+ <!-- START /templates/footer.md -->
130
+ ## About thoughtbot
119
131
 
120
- Suspenders is maintained by [thoughtbot].
132
+ ![thoughtbot](https://thoughtbot.com/thoughtbot-logo-for-readmes.svg)
121
133
 
122
- ![thoughtbot](https://thoughtbot.com/brand_assets/93:44.svg)
123
-
124
- Suspenders is maintained and funded by thoughtbot, inc.
134
+ This repo is maintained and funded by thoughtbot, inc.
125
135
  The names and logos for thoughtbot are trademarks of thoughtbot, inc.
126
136
 
127
137
  We love open source software!
128
- See [our other projects][community]
129
- or [hire us][hire] to help build your product.
138
+ See [our other projects][community].
139
+ We are [available for hire][hire].
130
140
 
131
141
  [community]: https://thoughtbot.com/community?utm_source=github
132
142
  [hire]: https://thoughtbot.com/hire-us?utm_source=github
143
+
144
+
145
+ <!-- END /templates/footer.md -->
data/RELEASING.md ADDED
@@ -0,0 +1,18 @@
1
+ # Releasing
2
+
3
+ 1. Update `NEWS.md` to reflect the changes since last release.
4
+ 2. Update `lib/suspenders/version.rb` file accordingly.
5
+ 3. Commit changes. There shouldn't be code changes, and thus CI doesn't need to
6
+ run; you can add `[ci skip]` to the commit message.
7
+ 4. Tag the release: `git tag vVERSION -a -s`. The tag message should contain the
8
+ appropriate `NEWS.md` subsection.
9
+ 5. Push changes: `git push --tags`
10
+ 6. Build and publish to rubygems:
11
+ ```sh
12
+ gem build suspenders.gemspec
13
+ gem push suspenders-*.gem
14
+ ```
15
+ 7. Add a new GitHub release:
16
+ https://github.com/thoughtbot/suspenders/releases/new?tag=vVERSION
17
+ 8. Announce the new release, making sure to thank the contributors who helped
18
+ shape this version!
data/Rakefile CHANGED
@@ -1,13 +1,10 @@
1
- require "bundler/setup"
1
+ # frozen_string_literal: true
2
+
2
3
  require "bundler/gem_tasks"
3
- require "minitest/test_task"
4
- require "standard/rake"
4
+ require "rspec/core/rake_task"
5
5
 
6
- Minitest::TestTask.create(:test) do |t|
7
- t.libs << "test"
8
- t.libs << "lib"
9
- t.warning = false
10
- t.test_globs = ["test/**/*_test.rb"]
11
- end
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ require "standard/rake"
12
9
 
13
- task default: %i[test standard]
10
+ task default: %i[spec standard]
data/SECURITY.md ADDED
@@ -0,0 +1,19 @@
1
+ <!-- START /templates/security.md -->
2
+ # Security Policy
3
+
4
+ ## Supported Versions
5
+
6
+ Only the the latest version of this project is supported at a given time. If
7
+ you find a security issue with an older version, please try updating to the
8
+ latest version first.
9
+
10
+ If for some reason you can't update to the latest version, please let us know
11
+ your reasons so that we can have a better understanding of your situation.
12
+
13
+ ## Reporting a Vulnerability
14
+
15
+ For security inquiries or vulnerability reports, visit
16
+ <https://thoughtbot.com/security>.
17
+
18
+ If you have any suggestions to improve this policy, visit <https://thoughtbot.com/security>.
19
+ <!-- END /templates/security.md -->
data/exe/suspenders ADDED
@@ -0,0 +1,38 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require_relative "../lib/suspenders"
4
+
5
+ if ARGV.length > 2 || ARGV.length == 0
6
+ puts "Error: Invalid command"
7
+ puts "Available commands are"
8
+ puts "suspenders new APP_NAME"
9
+ puts "suspenders -v"
10
+ exit 1
11
+ end
12
+
13
+ command = ARGV[0]
14
+ app_name = ARGV[1]
15
+
16
+ if ["-v", "--version"].include?(command)
17
+ puts Suspenders::VERSION
18
+ exit 0
19
+ elsif ["new"].include?(command)
20
+ if app_name.nil? || app_name.empty?
21
+ puts "Error: Application name required"
22
+ puts "Usage: suspenders new APP_NAME"
23
+ exit 1
24
+ end
25
+ else
26
+ puts "Error: Invalid command"
27
+ puts "Available commands are"
28
+ puts "suspenders new APP_NAME"
29
+ puts "suspenders -v"
30
+ exit 1
31
+ end
32
+
33
+ begin
34
+ Suspenders::CLI.run(app_name)
35
+ exit 0
36
+ rescue Suspenders::Error => e
37
+ abort "Error: #{e.message}"
38
+ end
@@ -0,0 +1,64 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Suspenders
4
+ # Command-line interface for generating Rails applications with Suspenders.
5
+ # This class handles the creation of new Rails apps using a custom template
6
+ # and predefined configuration options.
7
+ class CLI
8
+ # Base options passed to the Rails generator for all new applications.
9
+ # These options configure PostgreSQL as the database, skip test setup,
10
+ # and skip Solid-related features.
11
+ BASE_OPTIONS = [
12
+ "-d=postgresql",
13
+ "--skip-test",
14
+ "--skip-solid"
15
+ ]
16
+
17
+ # Initializes a new CLI instance.
18
+ #
19
+ # @param app_name [String] the name of the Rails application to create
20
+ def initialize(app_name)
21
+ @app_name = app_name
22
+ end
23
+
24
+ # Creates and runs a new CLI instance for the given application name.
25
+ #
26
+ # @param app_name [String] the name of the Rails application to create
27
+ # @return [Boolean] true if the Rails app was created successfully
28
+ # @raise [Error] if Rails is not installed or app creation fails
29
+ def self.run(app_name)
30
+ new(app_name).run
31
+ end
32
+
33
+ # Executes the CLI workflow to generate a new Rails application.
34
+ # Verifies Rails installation and generates the app with Suspenders template.
35
+ #
36
+ # @return [Boolean] true if the Rails app was created successfully
37
+ # @raise [Error] if Rails is not installed or app creation fails
38
+ def run
39
+ verify_rails_exists!
40
+ generate_new_rails_app
41
+ end
42
+
43
+ private
44
+
45
+ attr_reader :app_name
46
+
47
+ def verify_rails_exists!
48
+ unless system("which", "rails", out: File::NULL, err: File::NULL)
49
+ raise Error, "Rails not found. Install with: gem install rails"
50
+ end
51
+ end
52
+
53
+ def generate_new_rails_app
54
+ template_path = File.expand_path("../templates/web.rb", __dir__)
55
+ options = BASE_OPTIONS + ["-m=#{template_path}"]
56
+
57
+ if system("rails", "new", app_name, *options)
58
+ true
59
+ else
60
+ raise Error, "Failed to create Rails app"
61
+ end
62
+ end
63
+ end
64
+ end
@@ -1,6 +1,6 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Suspenders
2
- VERSION = "20240516.0".freeze
3
- RAILS_VERSION = "~> 7.0".freeze
4
- MINIMUM_RUBY_VERSION = ">= 3.1".freeze
5
- MINIMUM_NODE_VERSION = "20.0.0".freeze
4
+ VERSION = "20251219.0"
5
+ MINIMUM_RUBY_VERSION = ">= 3.2.0"
6
6
  end
data/lib/suspenders.rb CHANGED
@@ -1,10 +1,9 @@
1
- require "suspenders/version"
2
- require "suspenders/engine"
3
- require "suspenders/railtie"
4
- require "suspenders/generators"
5
- require "suspenders/cleanup/organize_gemfile"
6
- require "suspenders/cleanup/generate_readme"
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "suspenders/version"
4
+ require_relative "suspenders/cli"
7
5
 
8
6
  module Suspenders
7
+ class Error < StandardError; end
9
8
  # Your code goes here...
10
9
  end
@@ -0,0 +1,3 @@
1
+ release: bundle exec rails db:migrate; bundle exec rails db:seed
2
+ web: bundle exec puma -C config/puma.rb
3
+ worker: bundle exec sidekiq -c 10
@@ -0,0 +1,2 @@
1
+ web: env RUBY_DEBUG_OPEN=true bin/rails server
2
+ worker: bundle exec sidekiq
@@ -1,7 +1,9 @@
1
1
  <% if flash.any? %>
2
- <div class="flashes">
2
+ <div>
3
3
  <% flash.each do |type, message| -%>
4
- <div class="flash-<%= type %>"><%= message %></div>
4
+ <div role="alert">
5
+ <%= message %>
6
+ </div>
5
7
  <% end -%>
6
8
  </div>
7
9
  <% end %>
@@ -0,0 +1,11 @@
1
+ <%# locals: (resource: ) %>
2
+
3
+ <% if resource.errors.any? %>
4
+ <div id="error_explanation" role="alert" data-turbo-cache="false">
5
+ <ul>
6
+ <% resource.errors.full_messages.each do |message| %>
7
+ <li><%= message %></li>
8
+ <% end %>
9
+ </ul>
10
+ </div>
11
+ <% end %>
@@ -0,0 +1,14 @@
1
+ # https://github.com/sidekiq/sidekiq/wiki/Heroku
2
+
3
+ SIDEKIQ_REDIS_CONFIGURATION = {
4
+ url: ENV.fetch(ENV.fetch("REDIS_PROVIDER", "REDIS_URL"), nil), # use REDIS_PROVIDER for Redis environment variable name, defaulting to REDIS_URL
5
+ ssl_params: {verify_mode: OpenSSL::SSL::VERIFY_NONE} # we must trust Heroku and AWS here
6
+ }
7
+
8
+ Sidekiq.configure_server do |config|
9
+ config.redis = SIDEKIQ_REDIS_CONFIGURATION
10
+ end
11
+
12
+ Sidekiq.configure_client do |config|
13
+ config.redis = SIDEKIQ_REDIS_CONFIGURATION
14
+ end
@@ -0,0 +1,21 @@
1
+ # This file should ensure the existence of records required to run the application in development.
2
+ # The code here should be idempotent so that it can be executed at any point in development.
3
+ # The data can then be loaded with the bin/rails development:db:seed command.
4
+
5
+ module Development
6
+ class Seeder
7
+ def self.load_seeds
8
+ if Rails.env.development?
9
+ new.load_seeds
10
+ else
11
+ raise "Development::Seeder can only be run in a development environment."
12
+ end
13
+ end
14
+
15
+ def load_seeds
16
+ # ["Ruby", "Ralph"].each do |name|
17
+ # User.find_or_create_by!(name:)
18
+ # end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,15 @@
1
+ if Rails.env.development?
2
+ namespace :development do
3
+ namespace :db do
4
+ desc "Loads seed data into development."
5
+ task seed: ["environment", "db:seed"] do
6
+ Development::Seeder.load_seeds
7
+ end
8
+
9
+ namespace :seed do
10
+ desc "Truncate tables of each database for development and loads seed data."
11
+ task replant: ["environment", "db:truncate_all", "development:db:seed"]
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,11 @@
1
+ RSpec.configure do |config|
2
+ # https://guides.rubyonrails.org/testing.html#the-basic-test-case
3
+ #
4
+ # The ActionMailer::Base.deliveries array is only reset automatically in
5
+ # ActionMailer::TestCase and ActionDispatch::IntegrationTest tests. If
6
+ # you want to have a clean slate outside these test cases, you can reset
7
+ # it manually with: ActionMailer::Base.deliveries.clear
8
+ config.before(:each) do
9
+ ActionMailer::Base.deliveries.clear
10
+ end
11
+ end
@@ -1,5 +1,3 @@
1
- FactoryBot.use_parent_strategy = true
2
-
3
1
  RSpec.configure do |config|
4
2
  config.include FactoryBot::Syntax::Methods
5
3
  end