Skip to content

Commit

Permalink
WIP: Configure Factory Bot
Browse files Browse the repository at this point in the history
  • Loading branch information
stevepolitodesign committed Oct 27, 2023
1 parent 44f783e commit 856e821
Show file tree
Hide file tree
Showing 6 changed files with 305 additions and 0 deletions.
66 changes: 66 additions & 0 deletions lib/generators/factory_bot/factory_bot_generator.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
class Suspenders::FactoryBotGenerator < Rails::Generators::Base
source_root File.expand_path("templates", __dir__)

def install_gem
gem_group :development, :test do
gem "factory_bot_rails"
end

Bundler.with_unbundled_env { run "bundle install" }
end

def remove_fixture_definitions
if default_test_helper_present?
comment_lines "test/test_helper.rb", /fixtures :all/
end
end

def include_syntax_methods
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 create_linting_test
if default_test_suite?
copy_file "factories_test.rb", "test/factory_bots/factories_test.rb"
end
end

def provide_dev_prime_task
copy_file "dev.rake", "lib/tasks/dev.rake"
end

def create_definition_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

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
12 changes: 12 additions & 0 deletions lib/generators/factory_bot/templates/dev.rake
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
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: "[email protected]", password: "password")
end
end
end
2 changes: 2 additions & 0 deletions lib/generators/factory_bot/templates/factories.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
FactoryBot.define do
end
9 changes: 9 additions & 0 deletions lib/generators/factory_bot/templates/factories_test.rb
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
5 changes: 5 additions & 0 deletions lib/generators/factory_bot/templates/factory_bot_rspec.rb
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
211 changes: 211 additions & 0 deletions test/lib/generators/factory_bot/factory_bot_generator_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,211 @@
require "test_helper"
require "generators/factory_bot/factory_bot_generator"

class Suspenders::FactoryBotGenerator::DefaultTest < Rails::Generators::TestCase
include Suspenders::TestHelpers

tests Suspenders::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 "installs gem with Bundler" do
Bundler.stubs(:with_unbundled_env).yields
generator.expects(:run).with("bundle install").once

capture(:stdout) do
generator.install_gem
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
run_generator

assert_file app_root("test/factories.rb") do |file|
assert_match definition_file, file
end
end

test "creates linting test" do
run_generator

assert_file app_root("test/factory_bots/factories_test.rb") do |file|
assert_match factories_test, file
end
end

test "creates dev prime task" do
run_generator

assert_file app_root("lib/tasks/dev.rake") do |file|
assert_match dev_rake, file
end
end

private

def prepare_destination
mkdir "test"
touch "Gemfile"
end

def restore_destination
remove_dir_if_exists "test"
remove_dir_if_exists "spec"
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

def 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
end

def definition_file
<<~RUBY
FactoryBot.define do
end
RUBY
end

def dev_rake
<<~RUBY
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: "[email protected]", password: "password")
end
end
end
RUBY
end
end

class Suspenders::FactoryBotGenerator::RSpecTest < Rails::Generators::TestCase
include Suspenders::TestHelpers

tests Suspenders::FactoryBotGenerator
destination Rails.root
setup :prepare_destination
teardown :restore_destination

test "includes syntax methods" do
touch("spec/rails_helper.rb")

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
run_generator

assert_file app_root("spec/factories.rb") do |file|
assert_match definition_file, file
end
end

private

def prepare_destination
mkdir "spec"
touch "Gemfile"
end

def restore_destination
remove_dir_if_exists "test"
remove_dir_if_exists "spec"
remove_file_if_exists "Gemfile"
remove_dir_if_exists "lib/tasks"
end

def factory_bot_config
<<~RUBY
FactoryBot.use_parent_strategy = true
RSpec.configure do |config|
config.include FactoryBot::Syntax::Methods
end
RUBY
end

def definition_file
<<~RUBY
FactoryBot.define do
end
RUBY
end
end

0 comments on commit 856e821

Please sign in to comment.