dry_crud 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|