Permalink
Browse files

create an entry for validates_uniquessness_of if one does not exist

  • Loading branch information...
1 parent f5f6482 commit b618275a9d113d591e6043f0bb36c37157e9055f @drapergeek drapergeek committed with Gabe Berke-Williams May 11, 2012
View
@@ -3,6 +3,10 @@
* Prefer Test::Unit to Minitest when loading integrations so that RubyMine is
happy (#88).
+* `validates_uniqueness_of` will now create a record if one does not exist.
+ Previously, users were required to create a record in the database before
+ using this matcher.
+
# v1.2.0
* `ensure_inclusion_of` now has an `in_array` parameter:
View
@@ -30,12 +30,7 @@ Matchers to test validations and mass assignments:
it { should validate_presence_of(:body).with_message(/wtf/) }
it { should validate_presence_of(:title) }
it { should validate_numericality_of(:user_id) }
-
- # validates_uniqueness_of requires an entry to be in the database already
- it "validates uniqueness of title" do
- Post.create!(title: "My Awesome Post", body: "whatever")
- should validate_uniqueness_of(:title)
- end
+ it { should validate_uniqueness_of(:title) }
end
describe User do
@@ -68,20 +68,25 @@ def description
def matches?(subject)
@subject = subject.class.new
@expected_message ||= :taken
- has_existing? &&
- set_scoped_attributes &&
+ set_scoped_attributes &&
validate_attribute? &&
validate_after_scope_change?
end
private
- def has_existing?
- if @existing = @subject.class.find(:first)
- true
- else
- @failure_message = "Can't find first #{class_name}"
- false
+ def existing
+ @existing ||= first_instance
+ end
+
+ def first_instance
+ @subject.class.first || create_instance_in_database
+ end
+
+ def create_instance_in_database
+ @subject.class.new.tap do |instance|
+ instance.send("#{@attribute}=", "arbitrary_string")
+ instance.save(:validate => false)
end
end
@@ -90,7 +95,7 @@ def set_scoped_attributes
@options[:scopes].all? do |scope|
setter = :"#{scope}="
if @subject.respond_to?(setter)
- @subject.send("#{scope}=", @existing.send(scope))
+ @subject.send("#{scope}=", existing.send(scope))
true
else
@failure_message = "#{class_name} doesn't seem to have a #{scope} attribute."
@@ -114,7 +119,7 @@ def validate_after_scope_change?
true
else
@options[:scopes].all? do |scope|
- previous_value = @existing.send(scope)
+ previous_value = existing.send(scope)
# Assume the scope is a foreign key if the field is nil
previous_value ||= 0
@@ -144,7 +149,7 @@ def class_name
end
def existing_value
- value = @existing.send(@attribute)
+ value = existing.send(@attribute)
if @options[:case_insensitive] && value.respond_to?(:swapcase!)
value.swapcase!
end
@@ -34,13 +34,8 @@
@matcher = validate_uniqueness_of(:attr)
end
- it "should fail to require a unique value" do
- @model.should_not @matcher
- end
-
- it "should alert the tester that an existing value is not present" do
- @matcher.matches?(@model)
- @matcher.negative_failure_message.should =~ /^Can't find first .*/
+ it "does not not require a created instance" do
+ @model.should @matcher
end
end
end

0 comments on commit b618275

Please sign in to comment.