dry_crud 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- data/MIT-LICENSE +19 -0
- data/README.rdoc +208 -0
- data/Rakefile +101 -0
- data/VERSION +1 -0
- data/rails_generators/dry_crud/USAGE +1 -0
- data/rails_generators/dry_crud/dry_crud_generator.rb +22 -0
- data/rails_generators/dry_crud/templates/INSTALL +13 -0
- data/rails_generators/dry_crud/templates/app/controllers/crud_controller.rb +182 -0
- data/rails_generators/dry_crud/templates/app/helpers/crud_helper.rb +45 -0
- data/rails_generators/dry_crud/templates/app/helpers/standard_helper.rb +209 -0
- data/rails_generators/dry_crud/templates/app/views/crud/_attrs.html.erb +1 -0
- data/rails_generators/dry_crud/templates/app/views/crud/_form.html.erb +1 -0
- data/rails_generators/dry_crud/templates/app/views/crud/_list.html.erb +1 -0
- data/rails_generators/dry_crud/templates/app/views/crud/edit.html.erb +8 -0
- data/rails_generators/dry_crud/templates/app/views/crud/index.html.erb +14 -0
- data/rails_generators/dry_crud/templates/app/views/crud/new.html.erb +7 -0
- data/rails_generators/dry_crud/templates/app/views/crud/show.html.erb +9 -0
- data/rails_generators/dry_crud/templates/app/views/layouts/crud.html.erb +20 -0
- data/rails_generators/dry_crud/templates/app/views/shared/_labeled.html.erb +5 -0
- data/rails_generators/dry_crud/templates/lib/crud_callbacks.rb +55 -0
- data/rails_generators/dry_crud/templates/lib/render_inheritable.rb +118 -0
- data/rails_generators/dry_crud/templates/lib/standard_form_builder.rb +161 -0
- data/rails_generators/dry_crud/templates/lib/standard_table_builder.rb +104 -0
- data/rails_generators/dry_crud/templates/public/stylesheets/crud.css +91 -0
- data/rails_generators/dry_crud/templates/test/crud_test_model.rb +124 -0
- data/rails_generators/dry_crud/templates/test/functional/crud_controller_test_helper.rb +172 -0
- data/rails_generators/dry_crud/templates/test/functional/crud_test_models_controller_test.rb +96 -0
- data/rails_generators/dry_crud/templates/test/unit/crud_helper_test.rb +57 -0
- data/rails_generators/dry_crud/templates/test/unit/render_inheritable_test.rb +161 -0
- data/rails_generators/dry_crud/templates/test/unit/standard_form_builder_test.rb +83 -0
- data/rails_generators/dry_crud/templates/test/unit/standard_helper_test.rb +183 -0
- data/rails_generators/dry_crud/templates/test/unit/standard_table_builder_test.rb +99 -0
- data/test/templates/app/controllers/ajax_controller.rb +7 -0
- data/test/templates/app/controllers/application_controller.rb +11 -0
- data/test/templates/app/controllers/cities_controller.rb +13 -0
- data/test/templates/app/controllers/people_controller.rb +7 -0
- data/test/templates/app/helpers/people_helper.rb +7 -0
- data/test/templates/app/models/city.rb +13 -0
- data/test/templates/app/models/person.rb +9 -0
- data/test/templates/app/views/ajax/_hello.html.erb +1 -0
- data/test/templates/app/views/ajax/ajax.js.rjs +1 -0
- data/test/templates/app/views/ajax/index.html.erb +9 -0
- data/test/templates/app/views/cities/_attrs.html.erb +1 -0
- data/test/templates/app/views/cities/_form.html.erb +4 -0
- data/test/templates/app/views/cities/_hello.html.erb +1 -0
- data/test/templates/app/views/cities/_list.html.erb +5 -0
- data/test/templates/config/routes.rb +11 -0
- data/test/templates/db/migrate/20100511174904_create_people_and_cities.rb +23 -0
- data/test/templates/test/fixtures/cities.yml +11 -0
- data/test/templates/test/fixtures/people.yml +14 -0
- data/test/templates/test/functional/cities_controller_test.rb +35 -0
- data/test/templates/test/functional/people_controller_test.rb +30 -0
- metadata +127 -0
@@ -0,0 +1,104 @@
|
|
1
|
+
# A simple helper to easily define tables listing several rows of the same data type.
|
2
|
+
#
|
3
|
+
# Example Usage:
|
4
|
+
# StandardTableBuilder.table(entries, template) do |t|
|
5
|
+
# t.col('My Header', :class => 'css') {|e| link_to 'Show', e }
|
6
|
+
# t.attrs :name, :city
|
7
|
+
# end
|
8
|
+
class StandardTableBuilder
|
9
|
+
attr_reader :entries, :cols, :template
|
10
|
+
|
11
|
+
# Delegate called methods to template.
|
12
|
+
# including StandardHelper would lead to problems with indirectly called methods.
|
13
|
+
delegate :content_tag, :format_attr, :column_type, :belongs_to_association,
|
14
|
+
:captionize, :tr_alt, :to => :template
|
15
|
+
|
16
|
+
def initialize(entries, template)
|
17
|
+
@entries = entries
|
18
|
+
@template = template
|
19
|
+
@cols = []
|
20
|
+
end
|
21
|
+
|
22
|
+
# Convenience method to directly generate a table. Renders a row for each entry in entries.
|
23
|
+
# Takes a block that gets the table object as parameter for configuration.
|
24
|
+
# Returns the generated html for the table.
|
25
|
+
def self.table(entries, template)
|
26
|
+
t = new(entries, template)
|
27
|
+
yield t
|
28
|
+
t.to_html
|
29
|
+
end
|
30
|
+
|
31
|
+
# Define a column for the table with the given header, the html_options used for
|
32
|
+
# each td and a block rendering the contents of a cell for the current entry.
|
33
|
+
# The columns appear in the order they are defined.
|
34
|
+
def col(header = '', html_options = {}, &block)
|
35
|
+
@cols << Col.new(header, html_options, @template, block)
|
36
|
+
end
|
37
|
+
|
38
|
+
# Convenience method to add one or more attribute columns.
|
39
|
+
# The attribute name will become the header, the cells will contain
|
40
|
+
# the formatted attribute value for the current entry.
|
41
|
+
def attrs(*attrs)
|
42
|
+
attrs.each do |a|
|
43
|
+
col(captionize(a, entry_class), :class => align_class(a)) { |e| format_attr(e, a) }
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
# Renders the table as HTML.
|
48
|
+
def to_html
|
49
|
+
content_tag :table, :class => 'list' do
|
50
|
+
[html_header] +
|
51
|
+
entries.collect { |e| html_row(e) }
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
# Returns css classes used for alignment of the cell data.
|
56
|
+
# Based on the column type of the attribute.
|
57
|
+
def align_class(attr)
|
58
|
+
entry = entries.first
|
59
|
+
case column_type(entry, attr)
|
60
|
+
when :integer, :float, :decimal
|
61
|
+
'right_align' unless belongs_to_association(entry, attr)
|
62
|
+
when :boolean
|
63
|
+
'center_align'
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
private
|
68
|
+
|
69
|
+
def html_header
|
70
|
+
content_tag :tr do
|
71
|
+
cols.collect { |c| c.html_header }
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def html_row(entry)
|
76
|
+
tr_alt do
|
77
|
+
cols.collect { |c| c.html_cell(entry) }
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def entry_class
|
82
|
+
entries.first.class
|
83
|
+
end
|
84
|
+
|
85
|
+
# Helper class to store column information.
|
86
|
+
class Col < Struct.new(:header, :html_options, :template, :block) #:nodoc:
|
87
|
+
|
88
|
+
delegate :content_tag, :to => :template
|
89
|
+
|
90
|
+
def content(entry)
|
91
|
+
block.call(entry)
|
92
|
+
end
|
93
|
+
|
94
|
+
def html_header
|
95
|
+
content_tag :th, header
|
96
|
+
end
|
97
|
+
|
98
|
+
def html_cell(entry)
|
99
|
+
content_tag :td, content(entry), html_options
|
100
|
+
end
|
101
|
+
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
body, div, p, td, th {
|
2
|
+
font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;
|
3
|
+
font-size: 11pt;
|
4
|
+
}
|
5
|
+
|
6
|
+
td {
|
7
|
+
vertical-align: top;
|
8
|
+
}
|
9
|
+
|
10
|
+
tr.even {
|
11
|
+
background-color: #DDD;
|
12
|
+
}
|
13
|
+
|
14
|
+
tr.odd {
|
15
|
+
background-color: #EEE;
|
16
|
+
}
|
17
|
+
|
18
|
+
table.list {}
|
19
|
+
|
20
|
+
/* div rendered if no entries available for list */
|
21
|
+
div.list {}
|
22
|
+
|
23
|
+
.right_align {
|
24
|
+
text-align: right;
|
25
|
+
}
|
26
|
+
|
27
|
+
.center_align {
|
28
|
+
text-align: center;
|
29
|
+
}
|
30
|
+
|
31
|
+
.labeled {
|
32
|
+
vertical-align: top;
|
33
|
+
margin: 1pt;
|
34
|
+
}
|
35
|
+
|
36
|
+
.labeled .caption {
|
37
|
+
font-style: italic;
|
38
|
+
width: 120pt;
|
39
|
+
padding-right: 5pt;
|
40
|
+
float: left;
|
41
|
+
}
|
42
|
+
|
43
|
+
.labeled .value {
|
44
|
+
margin-left: 125pt;
|
45
|
+
}
|
46
|
+
|
47
|
+
.labeled .value p {
|
48
|
+
margin: 0px;
|
49
|
+
}
|
50
|
+
|
51
|
+
.attributes {}
|
52
|
+
|
53
|
+
a.action {
|
54
|
+
color: red;
|
55
|
+
text-decoration: none;
|
56
|
+
}
|
57
|
+
|
58
|
+
a:hover.action {
|
59
|
+
text-decoration: underline;
|
60
|
+
}
|
61
|
+
|
62
|
+
a:visited.action {
|
63
|
+
color: red;
|
64
|
+
}
|
65
|
+
|
66
|
+
#flash_notice {
|
67
|
+
color: #663333;
|
68
|
+
}
|
69
|
+
|
70
|
+
div.errorExplanation {
|
71
|
+
border: solid 1px #999999;
|
72
|
+
margin: 10pt;
|
73
|
+
padding: 5pt;
|
74
|
+
background-color: #FFBBBB;
|
75
|
+
}
|
76
|
+
|
77
|
+
.errorExplanation h2 {
|
78
|
+
font-size: 12pt;
|
79
|
+
margin-top: 0pt;
|
80
|
+
}
|
81
|
+
|
82
|
+
.errorExplanation ul {
|
83
|
+
margin-bottom: 5pt;
|
84
|
+
}
|
85
|
+
|
86
|
+
div.fieldWithErrors {
|
87
|
+
background-color: #FFBBBB;
|
88
|
+
display: inline-block;
|
89
|
+
padding: 2px;
|
90
|
+
}
|
91
|
+
|
@@ -0,0 +1,124 @@
|
|
1
|
+
class CrudTestModel < ActiveRecord::Base #:nodoc:
|
2
|
+
validates_presence_of :name
|
3
|
+
|
4
|
+
default_scope :order => 'name'
|
5
|
+
|
6
|
+
belongs_to :companion, :class_name => 'CrudTestModel'
|
7
|
+
|
8
|
+
def label
|
9
|
+
name
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
class CrudTestModelsController < CrudController #:nodoc:
|
14
|
+
HANDLE_PREFIX = 'handle_'
|
15
|
+
|
16
|
+
before_create :possibly_redirect
|
17
|
+
before_create :handle_name
|
18
|
+
|
19
|
+
before_render_new :possibly_redirect
|
20
|
+
before_render_new :set_companions
|
21
|
+
|
22
|
+
attr_reader :called_callbacks
|
23
|
+
attr_accessor :should_redirect
|
24
|
+
|
25
|
+
hide_action :called_callbacks, :should_redirect, :should_redirect=
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
# custom callback
|
30
|
+
def handle_name
|
31
|
+
if @entry.name == 'illegal'
|
32
|
+
flash[:error] = "illegal name"
|
33
|
+
return false
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
[:create, :update, :save, :destroy].each do |a|
|
38
|
+
callback = "before_#{a.to_s}"
|
39
|
+
send(callback.to_sym, :"#{HANDLE_PREFIX}#{callback}")
|
40
|
+
callback = "after_#{a.to_s}"
|
41
|
+
send(callback.to_sym, :"#{HANDLE_PREFIX}#{callback}")
|
42
|
+
end
|
43
|
+
|
44
|
+
def method_missing(sym, *args)
|
45
|
+
called_callback(sym.to_s[HANDLE_PREFIX.size..-1].to_sym) if sym.to_s.starts_with?(HANDLE_PREFIX)
|
46
|
+
end
|
47
|
+
|
48
|
+
def possibly_redirect
|
49
|
+
redirect_to :action => 'index' if should_redirect && !performed?
|
50
|
+
!should_redirect
|
51
|
+
end
|
52
|
+
|
53
|
+
def set_companions
|
54
|
+
@companions = CrudTestModel.all :conditions => {:human => true}
|
55
|
+
end
|
56
|
+
|
57
|
+
def called_callback(callback)
|
58
|
+
@called_callbacks ||= []
|
59
|
+
@called_callbacks << callback
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
|
64
|
+
ActionController::Routing::Routes.draw do |map|
|
65
|
+
map.resources :crud_test_models
|
66
|
+
end
|
67
|
+
|
68
|
+
# A simple test helper to prepare the test database with a CrudTestModel model.
|
69
|
+
module CrudTestHelper
|
70
|
+
|
71
|
+
protected
|
72
|
+
|
73
|
+
# Sets up the test database with a crud_test_models table.
|
74
|
+
# Look at the source to view the column definition.
|
75
|
+
def setup_db
|
76
|
+
silence_stream(STDOUT) do
|
77
|
+
ActiveRecord::Base.connection.create_table :crud_test_models, :force => true do |t|
|
78
|
+
t.string :name, :null => false, :limit => 50
|
79
|
+
t.string :whatever
|
80
|
+
t.integer :children
|
81
|
+
t.integer :companion_id
|
82
|
+
t.float :rating
|
83
|
+
t.decimal :income, :precision => 14, :scale => 2
|
84
|
+
t.date :birthdate
|
85
|
+
t.boolean :human, :default => true
|
86
|
+
t.text :remarks
|
87
|
+
|
88
|
+
t.timestamps
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
# Removes the crud_test_models table from the database.
|
94
|
+
def reset_db
|
95
|
+
[:crud_test_models].each do |table|
|
96
|
+
ActiveRecord::Base.connection.drop_table(table) rescue nil
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
# Creates 6 dummy entries for the crud_test_models table.
|
101
|
+
def create_test_data
|
102
|
+
(1..6).inject(nil) {|prev, i| create(i, prev) }
|
103
|
+
end
|
104
|
+
|
105
|
+
# Fixture-style accessor method to get CrudTestModel instances by name
|
106
|
+
def crud_test_models(name)
|
107
|
+
CrudTestModel.find_by_name(name.to_s)
|
108
|
+
end
|
109
|
+
|
110
|
+
private
|
111
|
+
|
112
|
+
def create(index, companion)
|
113
|
+
c = (index + 64).chr * 5
|
114
|
+
CrudTestModel.create!(:name => c,
|
115
|
+
:children => index,
|
116
|
+
:companion => companion,
|
117
|
+
:rating => "#{index}.#{index}".to_f,
|
118
|
+
:income => 10000000 * index + 0.1 * index,
|
119
|
+
:birthdate => "#{1900 + 10 * index}-#{index}-#{index}",
|
120
|
+
:human => index % 2 == 0,
|
121
|
+
:remarks => "#{c} #{c} #{c}\n" * 3)
|
122
|
+
end
|
123
|
+
|
124
|
+
end
|
@@ -0,0 +1,172 @@
|
|
1
|
+
# A module to include into your functional tests for your crud controller subclasses.
|
2
|
+
# Simply implement the two methods :test_entry and :test_entry_attrs to test the basic
|
3
|
+
# crud functionality. Override the test methods if you changed the behaviour in your subclass
|
4
|
+
# controller.
|
5
|
+
module CrudControllerTestHelper
|
6
|
+
|
7
|
+
def test_index
|
8
|
+
get :index
|
9
|
+
assert_response :success
|
10
|
+
assert_template 'index'
|
11
|
+
assert_not_nil assigns(:entries)
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_index_xml
|
15
|
+
get :index, :format => 'xml'
|
16
|
+
assert_response :success
|
17
|
+
assert_not_nil assigns(:entries)
|
18
|
+
assert @response.body.starts_with?("<?xml")
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_show
|
22
|
+
get :show, :id => test_entry.id
|
23
|
+
assert_response :success
|
24
|
+
assert_template 'show'
|
25
|
+
assert_equal test_entry, assigns(:entry)
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_show_xml
|
29
|
+
get :show, :id => test_entry.id, :format => 'xml'
|
30
|
+
assert_response :success
|
31
|
+
assert_equal test_entry, assigns(:entry)
|
32
|
+
assert @response.body.starts_with?("<?xml")
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_show_with_not_existing_id_raises_RecordNotFound
|
36
|
+
assert_raise(ActiveRecord::RecordNotFound) do
|
37
|
+
get :show, :id => 9999
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_show_without_id_redirects_to_index
|
42
|
+
get :show
|
43
|
+
assert_redirected_to_index
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_new
|
47
|
+
get :new
|
48
|
+
assert_response :success
|
49
|
+
assert_template 'new'
|
50
|
+
assert assigns(:entry).new_record?
|
51
|
+
end
|
52
|
+
|
53
|
+
def test_create
|
54
|
+
assert_difference("#{model_class.name}.count") do
|
55
|
+
post :create, model_identifier => test_entry_attrs
|
56
|
+
end
|
57
|
+
assert_redirected_to assigns(:entry)
|
58
|
+
assert ! assigns(:entry).new_record?
|
59
|
+
assert_test_attrs_equal
|
60
|
+
end
|
61
|
+
|
62
|
+
def test_create_with_wrong_http_method_redirects
|
63
|
+
get :create, model_identifier => test_entry_attrs
|
64
|
+
assert_redirected_to_index
|
65
|
+
|
66
|
+
put :create, model_identifier => test_entry_attrs
|
67
|
+
assert_redirected_to_index
|
68
|
+
|
69
|
+
delete :create, model_identifier => test_entry_attrs
|
70
|
+
assert_redirected_to_index
|
71
|
+
end
|
72
|
+
|
73
|
+
def test_create_xml
|
74
|
+
assert_difference("#{model_class.name}.count") do
|
75
|
+
post :create, model_identifier => test_entry_attrs, :format => 'xml'
|
76
|
+
end
|
77
|
+
assert_response :success
|
78
|
+
assert @response.body.starts_with?("<?xml")
|
79
|
+
end
|
80
|
+
|
81
|
+
def test_edit
|
82
|
+
get :edit, :id => test_entry.id
|
83
|
+
assert_response :success
|
84
|
+
assert_template 'edit'
|
85
|
+
assert_equal test_entry, assigns(:entry)
|
86
|
+
end
|
87
|
+
|
88
|
+
def test_edit_without_id_raises_RecordNotFound
|
89
|
+
assert_raise(ActiveRecord::RecordNotFound) do
|
90
|
+
get :edit
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def test_update
|
95
|
+
assert_no_difference("#{model_class.name}.count") do
|
96
|
+
put :update, :id => test_entry.id, model_identifier => test_entry_attrs
|
97
|
+
end
|
98
|
+
assert_test_attrs_equal
|
99
|
+
assert_redirected_to assigns(:entry)
|
100
|
+
end
|
101
|
+
|
102
|
+
def test_update_with_wrong_http_method_redirects
|
103
|
+
get :update, :id => test_entry.id, model_identifier => test_entry_attrs
|
104
|
+
assert_redirected_to_index
|
105
|
+
|
106
|
+
delete :update, :id => test_entry.id, model_identifier => test_entry_attrs
|
107
|
+
assert_redirected_to_index
|
108
|
+
end
|
109
|
+
|
110
|
+
def test_update_xml
|
111
|
+
assert_no_difference("#{model_class.name}.count") do
|
112
|
+
put :update, :id => test_entry.id, model_identifier => test_entry_attrs, :format => 'xml'
|
113
|
+
end
|
114
|
+
assert_response :success
|
115
|
+
assert_equal "", @response.body.strip
|
116
|
+
end
|
117
|
+
|
118
|
+
def test_destroy
|
119
|
+
assert_difference("#{model_class.name}.count", -1) do
|
120
|
+
delete :destroy, :id => test_entry.id
|
121
|
+
end
|
122
|
+
assert_redirected_to_index
|
123
|
+
end
|
124
|
+
|
125
|
+
def test_destroy_with_wrong_http_method_redirects
|
126
|
+
get :destroy, :id => test_entry.id
|
127
|
+
assert_redirected_to_index
|
128
|
+
|
129
|
+
put :destroy, :id => test_entry.id
|
130
|
+
assert_redirected_to_index
|
131
|
+
end
|
132
|
+
|
133
|
+
def test_destroy_xml
|
134
|
+
assert_difference("#{model_class.name}.count", -1) do
|
135
|
+
delete :destroy, :id => test_entry.id, :format => 'xml'
|
136
|
+
end
|
137
|
+
assert_response :success
|
138
|
+
assert_equal "", @response.body.strip
|
139
|
+
end
|
140
|
+
|
141
|
+
protected
|
142
|
+
|
143
|
+
def assert_redirected_to_index
|
144
|
+
assert_redirected_to :action => 'index'
|
145
|
+
end
|
146
|
+
|
147
|
+
def assert_test_attrs_equal
|
148
|
+
test_entry_attrs.each do |key, value|
|
149
|
+
actual = assigns(:entry).send(key)
|
150
|
+
assert_equal value, actual, "#{key} is expected to be <#{value.inspect}>, got <#{actual.inspect}>"
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
def model_class
|
155
|
+
@controller.controller_name.classify.constantize
|
156
|
+
end
|
157
|
+
|
158
|
+
def model_identifier
|
159
|
+
@controller.controller_name.singularize.to_sym
|
160
|
+
end
|
161
|
+
|
162
|
+
# Test object used in several tests
|
163
|
+
def test_entry
|
164
|
+
raise "Implement this method in your test class"
|
165
|
+
end
|
166
|
+
|
167
|
+
# Attribute hash used in several tests
|
168
|
+
def test_entry_attrs
|
169
|
+
raise "Implement this method in your test class"
|
170
|
+
end
|
171
|
+
|
172
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'crud_test_model'
|
3
|
+
require File.join(File.dirname(__FILE__), 'crud_controller_test_helper')
|
4
|
+
|
5
|
+
class CrudTestModelsControllerTest < ActionController::TestCase
|
6
|
+
|
7
|
+
include CrudControllerTestHelper
|
8
|
+
include CrudTestHelper
|
9
|
+
|
10
|
+
attr_accessor :models
|
11
|
+
|
12
|
+
setup :reset_db, :setup_db, :create_test_data
|
13
|
+
|
14
|
+
teardown :reset_db
|
15
|
+
|
16
|
+
def test_setup
|
17
|
+
assert_equal 6, CrudTestModel.count
|
18
|
+
assert_equal CrudTestModelsController, @controller.class
|
19
|
+
assert_recognizes({:controller => 'crud_test_models', :action => 'index'}, '/crud_test_models')
|
20
|
+
assert_recognizes({:controller => 'crud_test_models', :action => 'show', :id => '1'}, '/crud_test_models/1')
|
21
|
+
assert_equal %w(index show new create edit update destroy).to_set, CrudTestModelsController.send(:action_methods)
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_index
|
25
|
+
super
|
26
|
+
assert_equal 6, assigns(:entries).size
|
27
|
+
assert_equal assigns(:entries).sort_by {|a| a.name }, assigns(:entries)
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_new
|
31
|
+
super
|
32
|
+
assert assigns(:companions)
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_create
|
36
|
+
super
|
37
|
+
assert_equal [:before_create, :before_save, :after_save, :after_create], @controller.called_callbacks
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_update
|
41
|
+
super
|
42
|
+
assert_equal [:before_update, :before_save, :after_save, :after_update], @controller.called_callbacks
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_destroy
|
46
|
+
super
|
47
|
+
assert_equal [:before_destroy, :after_destroy], @controller.called_callbacks
|
48
|
+
end
|
49
|
+
|
50
|
+
def test_create_with_before_callback
|
51
|
+
assert_no_difference("#{model_class.name}.count") do
|
52
|
+
post :create, :crud_test_model => {:name => 'illegal', :children => 2}
|
53
|
+
end
|
54
|
+
assert_template 'new'
|
55
|
+
assert assigns(:entry).new_record?
|
56
|
+
assert assigns(:companions)
|
57
|
+
assert flash[:error].present?
|
58
|
+
assert_equal 'illegal', assigns(:entry).name
|
59
|
+
assert_nil @controller.called_callbacks
|
60
|
+
end
|
61
|
+
|
62
|
+
def test_create_with_before_callback_redirect
|
63
|
+
@controller.should_redirect = true
|
64
|
+
assert_no_difference("#{model_class.name}.count") do
|
65
|
+
post :create, :crud_test_model => {:name => 'illegal', :children => 2}
|
66
|
+
end
|
67
|
+
assert_redirected_to :action => 'index'
|
68
|
+
assert_nil @controller.called_callbacks
|
69
|
+
end
|
70
|
+
|
71
|
+
def test_new_with_before_render_callback_redirect_does_not_set_companions
|
72
|
+
@controller.should_redirect = true
|
73
|
+
get :new
|
74
|
+
assert_redirected_to :action => 'index'
|
75
|
+
assert_nil assigns(:companions)
|
76
|
+
end
|
77
|
+
|
78
|
+
|
79
|
+
protected
|
80
|
+
|
81
|
+
def test_entry
|
82
|
+
crud_test_models(:AAAAA)
|
83
|
+
end
|
84
|
+
|
85
|
+
def test_entry_attrs
|
86
|
+
{:name => 'foo',
|
87
|
+
:children => 42,
|
88
|
+
:companion_id => 3,
|
89
|
+
:rating => 99.99,
|
90
|
+
:income => 2.42,
|
91
|
+
:birthdate => '31-12-1999'.to_date,
|
92
|
+
:human => true,
|
93
|
+
:remarks => "some custom\n\tremarks"}
|
94
|
+
end
|
95
|
+
|
96
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'crud_test_model'
|
3
|
+
|
4
|
+
class CrudHelperTest < ActionView::TestCase
|
5
|
+
|
6
|
+
include StandardHelper
|
7
|
+
include CrudTestHelper
|
8
|
+
|
9
|
+
setup :reset_db, :setup_db, :create_test_data
|
10
|
+
teardown :reset_db
|
11
|
+
|
12
|
+
def model_class
|
13
|
+
CrudTestModel
|
14
|
+
end
|
15
|
+
|
16
|
+
test "standard crud table" do
|
17
|
+
@entries = CrudTestModel.all
|
18
|
+
t = crud_table
|
19
|
+
assert_match /(<tr.+?<\/tr>){7}/m, t
|
20
|
+
assert_match /(<th.+?<\/th>){14}/m, t
|
21
|
+
assert_match /(<a href.+?<\/a>.*?){18}/m, t
|
22
|
+
end
|
23
|
+
|
24
|
+
test "custom crud table" do
|
25
|
+
@entries = CrudTestModel.all
|
26
|
+
t = crud_table do |t|
|
27
|
+
t.attrs :name, :children, :companion_id
|
28
|
+
t.col("head") {|e| content_tag :span, e.income.to_s }
|
29
|
+
end
|
30
|
+
assert_match /(<tr.+?<\/tr>){7}/m, t
|
31
|
+
assert_match /(<th.+?<\/th>){4}/m, t
|
32
|
+
assert_match /(<span>.+?<\/span>.*?){6}/m, t
|
33
|
+
assert_no_match /(<a href.+?<\/a>.*?)/m, t
|
34
|
+
end
|
35
|
+
|
36
|
+
test "crud form" do
|
37
|
+
@entry = CrudTestModel.first
|
38
|
+
f = capture { crud_form }
|
39
|
+
|
40
|
+
assert_match /form .*?action="\/crud_test_models\/#{@entry.id}"/, f
|
41
|
+
assert_match /input .*?name="crud_test_model\[name\]" .*?type="text"/, f
|
42
|
+
assert_match /input .*?name="crud_test_model\[whatever\]" .*?type="text"/, f
|
43
|
+
assert_match /input .*?name="crud_test_model\[children\]" .*?type="text"/, f
|
44
|
+
assert_match /input .*?name="crud_test_model\[rating\]" .*?type="text"/, f
|
45
|
+
assert_match /input .*?name="crud_test_model\[income\]" .*?type="text"/, f
|
46
|
+
assert_match /select .*?name="crud_test_model\[birthdate\(1i\)\]"/, f
|
47
|
+
assert_match /input .*?name="crud_test_model\[human\]" .*?type="checkbox"/, f
|
48
|
+
assert_match /select .*?name="crud_test_model\[companion_id\]"/, f
|
49
|
+
assert_match /textarea .*?name="crud_test_model\[remarks\]"/, f
|
50
|
+
end
|
51
|
+
|
52
|
+
test "default attributes do not include id" do
|
53
|
+
assert_equal [:name, :whatever, :children, :companion_id, :rating, :income,
|
54
|
+
:birthdate, :human, :remarks, :created_at, :updated_at], default_attrs
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|