Skip to content

Instantly share code, notes, and snippets.

@bethesque
Last active August 29, 2015 14:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bethesque/45f9c0e635eb8527d44d to your computer and use it in GitHub Desktop.
Save bethesque/45f9c0e635eb8527d44d to your computer and use it in GitHub Desktop.
Reform writeable:false behaviour not the same as virtual: true
require 'minitest/autorun'
require 'date'
require 'reform' # 1.2.2
Person = Struct.new(:date_of_birth)
class DateForm < Reform::Form
property :day
property :month
property :year
validate :validate_date
def validate_date
# Need a more elegant way to add error to base of date_of_birth.
# Using :base will add the error to the Person object.
# Can't hardcode the message to "Date of birth ..."
# because this form can be used for
# more than one date property.
unless valid_date?
errors.add(:'', "is not a valid date")
end
end
def date
Date.parse("#{year}-#{month}-#{day}")
end
def valid_date?
date
true
rescue ArgumentError => e
false
end
end
class PersonForm < Reform::Form
NilDate = Struct.new(:year, :month, :day)
property :date_of_birth,
form: DateForm,
populate_if_empty: NilDate,
# virtual: true
writeable: false,
readable: false
def date_of_birth
super || DateForm.new(NilDate.new)
end
def sync
result = super
model.date_of_birth = date_of_birth.date
result
end
end
describe PersonForm do
let(:date) { nil }
let(:person) { Person.new(date) }
let(:form_data) do
{
"date_of_birth" => {
"day" => "2",
"month" => "1",
"year" => "2000",
}
}
end
subject { PersonForm.new(person) }
describe "date_of_birth" do
describe "with a date" do
let(:date) { Date.new(2014, 1, 2) }
it "is a DateForm" do
assert_kind_of(DateForm, subject.date_of_birth)
end
describe "day" do
it 'returns the day' do
assert_equal(2, subject.date_of_birth.day)
end
end
describe "month" do
it 'returns the month number' do
assert_equal(1, subject.date_of_birth.month)
end
end
describe "year" do
it 'returns the year' do
assert_equal(2014, subject.date_of_birth.year)
end
end
end
describe "with a nil date" do
it "is a DateForm" do
assert_kind_of(DateForm, subject.date_of_birth)
end
describe "day" do
it 'returns nil' do
assert_nil(subject.date_of_birth.day)
end
end
describe "month" do
it 'returns nil' do
assert_nil(subject.date_of_birth.month)
end
end
describe "year" do
it 'returns nil' do
assert_nil(subject.date_of_birth.year)
end
end
end
end
describe "validate" do
before do
subject.validate(form_data)
end
describe "with an invalid date" do
let(:form_data) do
{
"date_of_birth" => {
"day" => "30",
"month" => "2",
"year" => "2000",
}
}
end
it 'returns an error' do
assert_equal(["Date of birth is not a valid date"], subject.errors.full_messages)
end
end
describe "with a valid date" do
it "does not return an error" do
assert_empty(subject.errors)
end
end
end
describe "sync" do
before do
subject.validate(form_data)
subject.sync
end
describe "with an existing date" do
let(:date) { Date.new(2014, 3, 4) }
it "sets the date_of_birth" do
assert_equal(Date.new(2000, 1, 2), person.date_of_birth)
end
end
describe "with no existing date" do
it "sets the date_of_birth" do
assert_equal(Date.new(2000, 1, 2), person.date_of_birth)
end
end
end
end
1) Error:
PersonForm::sync::with no existing date#test_0001_sets the date_of_birth:
ArgumentError: invalid date
reform.rb:26:in `parse'
reform.rb:26:in `date'
reform.rb:54:in `sync'
reform.rb:161:in `block (3 levels) in <main>'
2) Failure:
PersonForm::date_of_birth::with a date::month#test_0001_returns the month number [reform.rb:93]:
Expected: 1
Actual: nil
3) Failure:
PersonForm::date_of_birth::with a date::year#test_0001_returns the year [reform.rb:98]:
Expected: 2014
Actual: nil
4) Error:
PersonForm::sync::with an existing date#test_0001_sets the date_of_birth:
ArgumentError: invalid date
reform.rb:26:in `parse'
reform.rb:26:in `date'
reform.rb:54:in `sync'
reform.rb:161:in `block (3 levels) in <main>'
5) Failure:
PersonForm::validate::with an invalid date#test_0001_returns an error [reform.rb:144]:
--- expected
+++ actual
@@ -1 +1 @@
-["Date of birth is not a valid date"]
+[]
6) Failure:
PersonForm::date_of_birth::with a date::day#test_0001_returns the day [reform.rb:88]:
Expected: 2
Actual: nil
12 runs, 11 assertions, 4 failures, 2 errors, 0 skips
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment