-
-
Notifications
You must be signed in to change notification settings - Fork 530
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Introduce
suspenders:factory_bot
generator
Maintains functionally with the [existing generator][] while adding support for the [default Rails test suite]. With this change, the generator can be invoked on a Rails application that use RSpec and the default Rails test suite. Adds generator which adds a test to lint all Factories in an effort to improve developer experience. Additionally, we remove the generation of the `dev:prime` task as we felt that should be the responsibly of another generator. [existing generator]: https://github.com/thoughtbot/suspenders/blob/main/lib/suspenders/generators/factories_generator.rb [default Rails test suite]: https://guides.rubyonrails.org/testing.html
- Loading branch information
1 parent
2a0f7ff
commit e93890a
Showing
8 changed files
with
305 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
module Suspenders | ||
module Generators | ||
class FactoryBotGenerator < Rails::Generators::Base | ||
source_root File.expand_path("../../templates/factory_bot", __FILE__) | ||
desc "Installs and configures factory_bot_rails. Supports the default test suite and RSpec." | ||
|
||
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 | ||
|
||
private | ||
|
||
def default_test_suite? | ||
File.exist? Rails.root.join("test") | ||
end | ||
|
||
def rspec_test_suite? | ||
File.exist? Rails.root.join("spec") | ||
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 | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
FactoryBot.define do | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
require "rails_helper" | ||
|
||
RSpec.describe "Factories" do | ||
it "has valid factoties" do | ||
FactoryBot.lint traits: true | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
require "test_helper" | ||
|
||
class FactoryBotsTest < ActiveSupport::TestCase | ||
class FactoryLintingTest < FactoryBotsTest | ||
test "linting of factories" do | ||
FactoryBot.lint traits: true | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
FactoryBot.use_parent_strategy = true | ||
|
||
RSpec.configure do |config| | ||
config.include FactoryBot::Syntax::Methods | ||
end |
203 changes: 203 additions & 0 deletions
203
test/generators/suspenders/factory_bot_generator_test.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,203 @@ | ||
require "test_helper" | ||
require "generators/suspenders/factory_bot_generator" | ||
|
||
module Suspenders | ||
module Generators | ||
class FactoryBotGenerator::DefaultTest < Rails::Generators::TestCase | ||
include Suspenders::TestHelpers | ||
|
||
tests Suspenders::Generators::FactoryBotGenerator | ||
destination Rails.root | ||
setup :prepare_destination | ||
teardown :restore_destination | ||
|
||
test "generator runs without errors" do | ||
assert_nothing_raised do | ||
run_generator | ||
end | ||
end | ||
|
||
test "generator has a description" do | ||
description = "Installs and configures factory_bot_rails. Supports the default test suite and RSpec." | ||
|
||
assert_equal description, FactoryBotGenerator.desc | ||
end | ||
|
||
test "installs gem with Bundler" do | ||
Bundler.stubs(:with_unbundled_env).yields | ||
generator.expects(:run).with("bundle install").once | ||
|
||
capture(:stdout) do | ||
generator.add_factory_bot | ||
end | ||
end | ||
|
||
test "removes fixture definitions" do | ||
File.open(app_root("test/test_helper.rb"), "w") { _1.write test_helper } | ||
|
||
run_generator | ||
|
||
assert_file app_root("test/test_helper.rb") do |file| | ||
assert_match(/# fixtures :all/, file) | ||
end | ||
end | ||
|
||
test "adds gem to Gemfile" 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 | ||
|
||
test "includes syntax methods" do | ||
File.open(app_root("test/test_helper.rb"), "w") { _1.write test_helper } | ||
|
||
run_generator | ||
|
||
assert_file app_root("test/test_helper.rb") do |file| | ||
assert_match(/class TestCase\n include FactoryBot::Syntax::Methods/, file) | ||
end | ||
end | ||
|
||
test "creates definition file" do | ||
definition_file = <<~RUBY | ||
FactoryBot.define do | ||
end | ||
RUBY | ||
|
||
run_generator | ||
|
||
assert_file app_root("test/factories.rb") do |file| | ||
assert_match definition_file, file | ||
end | ||
end | ||
|
||
test "creates linting test" do | ||
factories_test = <<~RUBY | ||
require "test_helper" | ||
class FactoryBotsTest < ActiveSupport::TestCase | ||
class FactoryLintingTest < FactoryBotsTest | ||
test "linting of factories" do | ||
FactoryBot.lint traits: true | ||
end | ||
end | ||
end | ||
RUBY | ||
|
||
run_generator | ||
|
||
assert_file app_root("test/factory_bots/factories_test.rb") do |file| | ||
assert_match factories_test, file | ||
end | ||
end | ||
|
||
private | ||
|
||
def prepare_destination | ||
mkdir "test" | ||
touch "Gemfile" | ||
end | ||
|
||
def restore_destination | ||
remove_dir_if_exists "test" | ||
remove_file_if_exists "Gemfile" | ||
remove_dir_if_exists "lib/tasks" | ||
end | ||
|
||
def test_helper | ||
<<~RUBY | ||
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 | ||
RUBY | ||
end | ||
end | ||
|
||
class FactoryBotGenerator::RSpecTest < Rails::Generators::TestCase | ||
include Suspenders::TestHelpers | ||
|
||
tests Suspenders::Generators::FactoryBotGenerator | ||
destination Rails.root | ||
setup :prepare_destination | ||
teardown :restore_destination | ||
|
||
test "includes syntax methods" 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 | ||
|
||
test "creates definition file" do | ||
definition_file = <<~RUBY | ||
FactoryBot.define do | ||
end | ||
RUBY | ||
|
||
run_generator | ||
|
||
assert_file app_root("spec/factories.rb") do |file| | ||
assert_match definition_file, file | ||
end | ||
end | ||
|
||
test "creates linting test" do | ||
factories_spec = <<~RUBY | ||
require "rails_helper" | ||
RSpec.describe "Factories" do | ||
it "has valid factoties" do | ||
FactoryBot.lint traits: true | ||
end | ||
end | ||
RUBY | ||
|
||
run_generator | ||
|
||
assert_file app_root("spec/factory_bots/factories_spec.rb") do |file| | ||
assert_match factories_spec, file | ||
end | ||
end | ||
|
||
private | ||
|
||
def prepare_destination | ||
mkdir "spec" | ||
touch "Gemfile" | ||
end | ||
|
||
def restore_destination | ||
remove_dir_if_exists "spec" | ||
remove_file_if_exists "Gemfile" | ||
remove_dir_if_exists "lib/tasks" | ||
end | ||
end | ||
end | ||
end |