rpheath / form_assistant

Rails plugin: a custom, template-based form builder that attempts to make your forms friendly (and maybe even fun!).

form_assistant / test / form_assistant_test.rb
100644 151 lines (122 sloc) 4.511 kb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
require 'test_helper'
 
module FormAssistantHelpers
  attr_accessor :render_options
  attr_accessor :view
  attr_accessor :response
  
  def view
    @view ||= ActionView::Base.new(Rails.configuration.view_path)
  end
  
  def render(options={})
    self.render_options = options
    @response = view.render(options)
  end
 
  def locals
    render_options[:locals] rescue {}
  end
 
  def expect_render(expected={})
    assert_hash_includes expected, render_options
  end
  
  def assert_hash_includes(expected, actual)
    expected.each do |k, v|
      assert_equal v, actual[k]
    end
  end
 
  def expect_locals(expected={})
    assert_hash_includes expected, locals
  end
 
  def template_root
    RPH::FormAssistant::FormBuilder.template_root
  end
  
  def template_path(name)
    File.join(template_root, name) + '.html.erb'
  end
end
 
class AddressBook < ActiveRecord::Base
  attr_accessor *%w(first_name nickname day month year)
  
  def self.columns
    Hash.new
  end
end
 
class FormAssistantTest < ActionView::TestCase
  include FormAssistantHelpers
  include ::RPH::FormAssistant::ActionView
  attr_accessor :form
 
  def setup
    Rails.configuration.view_path = File.expand_path(File.dirname(__FILE__))
 
    @address_book = AddressBook.new
    @form = RPH::FormAssistant::FormBuilder.new(:address_book, @address_book, self, {}, nil)
    RPH::FormAssistant::FormBuilder.template_root = File.expand_path(File.join(File.dirname(__FILE__), 'forms'))
  end
  
  test "should use template based on input type" do
    form.text_field :first_name
    expect_render :partial => template_path('text_field')
  end
  
  test "should use fallback template if no specific template is found" do
    form.text_field :first_name, :template => 'fancy_template_that_does_not_exist'
    expect_render :partial => template_path(form.fallback_template)
  end
  
  test "should render a valid field" do
    form.text_field :first_name
    expect_locals :errors => nil
  end
  
  test "should render an invalid field" do
    @address_book.errors.add(:first_name, 'cannot be root')
    form.text_field :first_name
    expect_locals :errors => ['First name cannot be root']
    assert_kind_of RPH::FormAssistant::FieldErrors, locals[:errors]
  end
  
  test "should render a field with a tip" do
    form.text_field :nickname, :tip => 'What should we call you?'
    expect_locals :tip => 'What should we call you?'
  end
  
  test "should render a field without a template" do
    result = form.text_field(:nickname, :template => false)
    assert_equal text_field(:address_book, :nickname), result
  end
  
  test "should create fieldset" do
    fieldset('Information') { "fields-go-here" }
    expect_render :partial => template_path('fieldset')
    expect_locals :legend => 'Information',
      :fields => 'fields-go-here'
  end
  
  test "should support I18n if available" do
    if Object.const_defined?(:I18n)
      I18n.backend = I18n::Backend::Simple.new
      I18n.backend.store_translations 'en', :activerecord => {
        :attributes => {
          :address_book => {
            :first_name => 'Given name'
          }
        }
      }
      
      @address_book.errors.add(:first_name, 'cannot be root')
      @address_book.errors.add(:first_name, 'cannot be admin')
      form.text_field :first_name
      expect_locals :errors => ['Given name cannot be root', 'Given name cannot be admin']
    end
  end
  
  test "should massage error messages when I18n isn't not available" do
    RPH::FormAssistant::Rules.expects(:has_I18n_support?).returns(false)
    @address_book.errors.add(:first_name, 'cannot be root')
    @address_book.errors.add(:first_name, 'cannot be admin')
    form.text_field :first_name
    expect_locals :errors => ['First name cannot be root and cannot be admin']
  end
  
  test "should create widget" do
    @address_book.errors.add(:birthday, 'is invalid')
    
    form.widget :birthday, :tip => 'Enter your birthday' do
      concat @day = form.select(:day, (1..31))
      concat @month = form.select(:month, (1..12))
      concat @year = form.select(:year, (1975...1985))
    end
    
    expect_locals :element => (@day + @month + @year),
      :errors => ['Birthday is invalid'],
      :tip => 'Enter your birthday',
      :helper => 'widget'
    
    expect_render :partial => template_path('field')
  end
  
  test "should pass extra locals" do
    form.text_field :first_name, :locals => { :nickname => true }
    expect_locals :nickname => true
  end
end