Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Add FactoryGirl.lint to ensure all factories are valid

This commit adds FactoryGirl.lint, which iterates over each defined
factory, builds it, and ensures it is valid. If any factories are
invalid, an exception is raised and includes the names of each invalid
factory.
  • Loading branch information...
commit 6a692fe711a43f3654480190af3110533786c29b 1 parent fea0ad1
@joshuaclayton joshuaclayton authored
View
20 lib/factory_girl.rb
@@ -54,6 +54,26 @@ def self.reset_configuration
@configuration = nil
end
+ def self.lint
+ invalid_factories = FactoryGirl.factories.select do |factory|
+ built_factory = FactoryGirl.build(factory.name)
+
+ if built_factory.respond_to?(:valid?)
+ !built_factory.valid?
+ end
+ end
+
+ if invalid_factories.any?
+ error_message = <<-ERROR_MESSAGE.strip
+The following factories are invalid:
+
+#{invalid_factories.map {|factory| "* #{factory.name}" }.join("\n")}
+ ERROR_MESSAGE
+
+ raise InvalidFactoryError, error_message
+ end
+ end
+
class << self
delegate :factories, :sequences, :traits, :callbacks, :strategies, :callback_names,
:to_create, :skip_create, :initialize_with, :constructor, :duplicate_attribute_assignment_from_initialize_with,
View
3  lib/factory_girl/errors.rb
@@ -19,4 +19,7 @@ class AttributeDefinitionError < RuntimeError; end
# Raised when a method is defined in a factory or trait with arguments
class MethodDefinitionError < RuntimeError; end
+
+ # Raised when any factory is considered invalid
+ class InvalidFactoryError < RuntimeError; end
end
View
55 spec/acceptance/lint_spec.rb
@@ -0,0 +1,55 @@
+require 'spec_helper'
+
+describe 'FactoryGirl.lint' do
+ it 'raises when a factory is invalid' do
+ define_model 'User', name: :string do
+ validates :name, presence: true
+ end
+
+ define_model 'AlwaysValid'
+
+ FactoryGirl.define do
+ factory :user do
+ factory :admin_user
+ end
+
+ factory :always_valid
+ end
+
+ error_message = <<-ERROR_MESSAGE.strip
+The following factories are invalid:
+
+* user
+* admin_user
+ ERROR_MESSAGE
+
+ expect do
+ FactoryGirl.lint
+ end.to raise_error FactoryGirl::InvalidFactoryError, error_message
+ end
+
+ it 'does not raise when all factories are valid' do
+ define_model 'User', name: :string do
+ validates :name, presence: true
+ end
+
+ FactoryGirl.define do
+ factory :user do
+ name 'assigned'
+ end
+ end
+
+ expect { FactoryGirl.lint }.not_to raise_error
+ end
+
+ it 'supports models which do not respond to #valid?' do
+ define_class 'Thing'
+
+ FactoryGirl.define do
+ factory :thing
+ end
+
+ expect(Thing.new).not_to respond_to(:valid?)
+ expect { FactoryGirl.lint }.not_to raise_error
+ end
+end

3 comments on commit 6a692fe

@hosamaly

Calling the lint method as suggested would cause all specs to stop if any factory is incorrect. I believe it's important to have an except option for the lint method to disable broken factories, similar to tagging some rspec tests as :broken.

Please sign in to comment.
Something went wrong with that request. Please try again.