rear 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/.travis.yml +7 -0
- data/CHANGELOG.md +7 -0
- data/Gemfile +20 -0
- data/LICENSE +19 -0
- data/README.md +101 -0
- data/Rakefile +79 -0
- data/assets/api.js +307 -0
- data/assets/bootstrap-datetimepicker/css/bootstrap-datetimepicker.min.css +8 -0
- data/assets/bootstrap-datetimepicker/js/bootstrap-datetimepicker.min.js +26 -0
- data/assets/bootstrap/css/bootstrap-responsive.min.css +9 -0
- data/assets/bootstrap/css/bootstrap.min.css +9 -0
- data/assets/bootstrap/img/glyphicons-halflings-white.png +0 -0
- data/assets/bootstrap/img/glyphicons-halflings.png +0 -0
- data/assets/bootstrap/js/bootstrap.min.js +6 -0
- data/assets/jquery.js +5 -0
- data/assets/noty/jquery.noty.js +520 -0
- data/assets/noty/layouts/top.js +34 -0
- data/assets/noty/layouts/topRight.js +43 -0
- data/assets/noty/promise.js +432 -0
- data/assets/noty/themes/default.js +156 -0
- data/assets/select2-bootstrap.css +86 -0
- data/assets/select2/select2-spinner.gif +0 -0
- data/assets/select2/select2.css +652 -0
- data/assets/select2/select2.min.js +22 -0
- data/assets/select2/select2.png +0 -0
- data/assets/select2/select2x2.png +0 -0
- data/assets/ui.css +75 -0
- data/assets/xhr.js +4 -0
- data/bin/rear +65 -0
- data/docs/Assocs.md +100 -0
- data/docs/Columns.md +404 -0
- data/docs/Deploy.md +62 -0
- data/docs/FileManager.md +75 -0
- data/docs/Filters.md +341 -0
- data/docs/Setup.md +201 -0
- data/lib/rear.rb +13 -0
- data/lib/rear/actions.rb +98 -0
- data/lib/rear/constants.rb +61 -0
- data/lib/rear/controller_setup.rb +249 -0
- data/lib/rear/helpers.rb +17 -0
- data/lib/rear/helpers/class.rb +46 -0
- data/lib/rear/helpers/columns.rb +68 -0
- data/lib/rear/helpers/filters.rb +147 -0
- data/lib/rear/helpers/generic.rb +73 -0
- data/lib/rear/helpers/order.rb +47 -0
- data/lib/rear/helpers/pager.rb +35 -0
- data/lib/rear/helpers/render.rb +37 -0
- data/lib/rear/home_controller.rb +10 -0
- data/lib/rear/input.rb +341 -0
- data/lib/rear/orm.rb +73 -0
- data/lib/rear/rear.rb +74 -0
- data/lib/rear/setup.rb +9 -0
- data/lib/rear/setup/associations.rb +33 -0
- data/lib/rear/setup/columns.rb +109 -0
- data/lib/rear/setup/filters.rb +314 -0
- data/lib/rear/setup/generic.rb +59 -0
- data/lib/rear/setup/menu.rb +39 -0
- data/lib/rear/templates/editor/ace.slim +7 -0
- data/lib/rear/templates/editor/assocs.slim +10 -0
- data/lib/rear/templates/editor/boolean.slim +5 -0
- data/lib/rear/templates/editor/bulk_edit.slim +75 -0
- data/lib/rear/templates/editor/checkbox.slim +5 -0
- data/lib/rear/templates/editor/ckeditor.slim +7 -0
- data/lib/rear/templates/editor/date.slim +9 -0
- data/lib/rear/templates/editor/datetime.slim +9 -0
- data/lib/rear/templates/editor/layout.slim +103 -0
- data/lib/rear/templates/editor/password.slim +1 -0
- data/lib/rear/templates/editor/radio.slim +5 -0
- data/lib/rear/templates/editor/select.slim +3 -0
- data/lib/rear/templates/editor/string.slim +1 -0
- data/lib/rear/templates/editor/text.slim +1 -0
- data/lib/rear/templates/editor/time.slim +9 -0
- data/lib/rear/templates/error.slim +36 -0
- data/lib/rear/templates/filters/boolean.slim +10 -0
- data/lib/rear/templates/filters/checkbox.slim +15 -0
- data/lib/rear/templates/filters/date.slim +10 -0
- data/lib/rear/templates/filters/datetime.slim +10 -0
- data/lib/rear/templates/filters/layout.slim +26 -0
- data/lib/rear/templates/filters/radio.slim +14 -0
- data/lib/rear/templates/filters/select.slim +9 -0
- data/lib/rear/templates/filters/string.slim +3 -0
- data/lib/rear/templates/filters/text.slim +3 -0
- data/lib/rear/templates/filters/time.slim +10 -0
- data/lib/rear/templates/home.slim +0 -0
- data/lib/rear/templates/layout.slim +78 -0
- data/lib/rear/templates/pager.slim +22 -0
- data/lib/rear/templates/pane/ace.slim +2 -0
- data/lib/rear/templates/pane/assocs.slim +62 -0
- data/lib/rear/templates/pane/boolean.slim +2 -0
- data/lib/rear/templates/pane/checkbox.slim +5 -0
- data/lib/rear/templates/pane/ckeditor.slim +2 -0
- data/lib/rear/templates/pane/date.slim +2 -0
- data/lib/rear/templates/pane/datetime.slim +2 -0
- data/lib/rear/templates/pane/layout.slim +111 -0
- data/lib/rear/templates/pane/password.slim +2 -0
- data/lib/rear/templates/pane/quickview.slim +21 -0
- data/lib/rear/templates/pane/radio.slim +5 -0
- data/lib/rear/templates/pane/select.slim +5 -0
- data/lib/rear/templates/pane/string.slim +2 -0
- data/lib/rear/templates/pane/text.slim +2 -0
- data/lib/rear/templates/pane/time.slim +2 -0
- data/lib/rear/utils.rb +288 -0
- data/rear.gemspec +27 -0
- data/test/helpers.rb +33 -0
- data/test/models/ar.rb +52 -0
- data/test/models/dm.rb +53 -0
- data/test/models/sq.rb +58 -0
- data/test/setup.rb +4 -0
- data/test/templates/adhoc/book/editor/name.slim +1 -0
- data/test/templates/adhoc/book/editor/string.slim +1 -0
- data/test/templates/adhoc/book/pane/name.slim +1 -0
- data/test/templates/adhoc/book/pane/string.slim +1 -0
- data/test/templates/shared/shared-templates/editor/string.slim +1 -0
- data/test/templates/shared/shared-templates/pane/string.slim +1 -0
- data/test/test__assocs.rb +249 -0
- data/test/test__columns.rb +269 -0
- data/test/test__crud.rb +81 -0
- data/test/test__custom_templates.rb +147 -0
- data/test/test__filters.rb +228 -0
- metadata +220 -0
data/test/models/sq.rb
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
connection = Sequel.sqlite
|
2
|
+
Sequel::Model.db = connection
|
3
|
+
|
4
|
+
connection.create_table :books_genres do |t|
|
5
|
+
t.integer :book_id
|
6
|
+
t.integer :genre_id
|
7
|
+
end
|
8
|
+
|
9
|
+
connection.create_table :genres do |t|
|
10
|
+
primary_key :id
|
11
|
+
t.string :name
|
12
|
+
end
|
13
|
+
|
14
|
+
connection.create_table :authors do |t|
|
15
|
+
primary_key :id
|
16
|
+
t.string :name
|
17
|
+
end
|
18
|
+
|
19
|
+
connection.create_table :books do |t|
|
20
|
+
primary_key :id
|
21
|
+
t.integer :author_id
|
22
|
+
t.string :name
|
23
|
+
t.text :about
|
24
|
+
t.string :cover
|
25
|
+
t.string :colors
|
26
|
+
t.date :created_at
|
27
|
+
end
|
28
|
+
|
29
|
+
connection.create_table :states do |t|
|
30
|
+
primary_key :id
|
31
|
+
t.string :name
|
32
|
+
t.string :code
|
33
|
+
end
|
34
|
+
|
35
|
+
connection.create_table :cities do |t|
|
36
|
+
primary_key :id
|
37
|
+
t.string :name
|
38
|
+
t.string :state_code
|
39
|
+
end
|
40
|
+
|
41
|
+
class Author < Sequel::Model
|
42
|
+
end
|
43
|
+
|
44
|
+
class Genre < Sequel::Model
|
45
|
+
end
|
46
|
+
|
47
|
+
class Book < Sequel::Model
|
48
|
+
many_to_one :author
|
49
|
+
many_to_many :genres
|
50
|
+
end
|
51
|
+
|
52
|
+
class State < Sequel::Model
|
53
|
+
one_to_many :cities, key: :state_code, primary_key: :code
|
54
|
+
end
|
55
|
+
|
56
|
+
class City < Sequel::Model
|
57
|
+
many_to_one :state, key: :state_code, primary_key: :code
|
58
|
+
end
|
data/test/setup.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
input.adhoc-given-template value=value
|
@@ -0,0 +1 @@
|
|
1
|
+
input.adhoc-default-template value=value
|
@@ -0,0 +1 @@
|
|
1
|
+
p.adhoc-given-template = value
|
@@ -0,0 +1 @@
|
|
1
|
+
p.adhoc-default-template = value
|
@@ -0,0 +1 @@
|
|
1
|
+
input.custom-shared-template value=value
|
@@ -0,0 +1 @@
|
|
1
|
+
p.custom-shared-template = value
|
@@ -0,0 +1,249 @@
|
|
1
|
+
module RearTest__Assocs
|
2
|
+
class Books < E
|
3
|
+
include Rear
|
4
|
+
model Book
|
5
|
+
end
|
6
|
+
|
7
|
+
class Authors < E
|
8
|
+
include Rear
|
9
|
+
model Author
|
10
|
+
end
|
11
|
+
|
12
|
+
class Genres < E
|
13
|
+
include Rear
|
14
|
+
model Genre
|
15
|
+
end
|
16
|
+
|
17
|
+
Spec.new Authors do
|
18
|
+
Books.mount
|
19
|
+
|
20
|
+
book, book_id = new_book()
|
21
|
+
args = [
|
22
|
+
:reverse_assoc,
|
23
|
+
RearTest__Assocs::Books,
|
24
|
+
:belongs_to,
|
25
|
+
:author,
|
26
|
+
book_id
|
27
|
+
]
|
28
|
+
|
29
|
+
Ensure 'no author attached' do
|
30
|
+
get app.route(*args, :attached)
|
31
|
+
is(last_response).ok?
|
32
|
+
are(extract_elements).empty?
|
33
|
+
end
|
34
|
+
|
35
|
+
author = Author.create(name: rand(2**64).to_s)
|
36
|
+
|
37
|
+
Should 'attach given author' do
|
38
|
+
post app.route(*args, target_item_id: author.id.to_s)
|
39
|
+
is(last_response).ok?
|
40
|
+
|
41
|
+
Ensure 'model updated' do
|
42
|
+
book.reload
|
43
|
+
expect(book.author_id) == author.id
|
44
|
+
end
|
45
|
+
|
46
|
+
Ensure 'frontend reflects updates' do
|
47
|
+
get app.route(*args, :attached)
|
48
|
+
is(last_response).ok?
|
49
|
+
expect { extract_elements.children }.any? do |c|
|
50
|
+
c.text == author.name.to_s
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
Should 'detach given author' do
|
56
|
+
delete app.route(*args)
|
57
|
+
|
58
|
+
Ensure 'model updated' do
|
59
|
+
book.reload
|
60
|
+
refute(book.author_id) == author.id
|
61
|
+
end
|
62
|
+
|
63
|
+
Ensure 'frontend reflects updates' do
|
64
|
+
get app.route(*args, :attached)
|
65
|
+
is(last_response).ok?
|
66
|
+
are(extract_elements).empty?
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
|
72
|
+
Spec.new Genres do
|
73
|
+
|
74
|
+
book, book_id = new_book()
|
75
|
+
args = [
|
76
|
+
:reverse_assoc,
|
77
|
+
RearTest__Assocs::Books,
|
78
|
+
:has_many,
|
79
|
+
:genres,
|
80
|
+
book_id
|
81
|
+
]
|
82
|
+
|
83
|
+
Ensure 'no genres attached' do
|
84
|
+
get app.route(*args, :attached)
|
85
|
+
is(last_response).ok?
|
86
|
+
are(extract_elements).empty?
|
87
|
+
end
|
88
|
+
|
89
|
+
genre = Genre.create(name: rand(2**64).to_s)
|
90
|
+
|
91
|
+
Should 'attach given genre' do
|
92
|
+
post app.route(*args, target_item_id: genre.id.to_s)
|
93
|
+
|
94
|
+
Ensure 'model updated' do
|
95
|
+
book.reload
|
96
|
+
does(book.genres).include? genre
|
97
|
+
end
|
98
|
+
|
99
|
+
Ensure 'frontend reflects updates' do
|
100
|
+
get app.route(*args, :attached)
|
101
|
+
is(last_response).ok?
|
102
|
+
expect { extract_elements.children }.any? do |c|
|
103
|
+
c.text == genre.name.to_s
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
end
|
108
|
+
|
109
|
+
Should 'detach given genre' do
|
110
|
+
delete app.route(*args, target_item_id: genre.id.to_s)
|
111
|
+
|
112
|
+
Ensure 'model updated' do
|
113
|
+
book.reload
|
114
|
+
refute(book.genres).include? genre
|
115
|
+
end
|
116
|
+
|
117
|
+
Ensure 'frontend reflects updates' do
|
118
|
+
get app.route(*args, :attached)
|
119
|
+
is(last_response).ok?
|
120
|
+
are(extract_elements).empty?
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
class CustomKeys
|
126
|
+
class Child < E
|
127
|
+
include Rear
|
128
|
+
model City
|
129
|
+
end
|
130
|
+
|
131
|
+
class Parent < E
|
132
|
+
include Rear
|
133
|
+
model State
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
Spec.new CustomKeys::Parent do
|
138
|
+
CustomKeys::Child.mount
|
139
|
+
|
140
|
+
state = State.create(name: 'California', code: 'CA')
|
141
|
+
city = City.create
|
142
|
+
args = [
|
143
|
+
:reverse_assoc,
|
144
|
+
CustomKeys::Child,
|
145
|
+
:belongs_to,
|
146
|
+
:state,
|
147
|
+
city.id
|
148
|
+
]
|
149
|
+
|
150
|
+
Should 'set state to CA' do
|
151
|
+
post app.route(*args, target_item_id: state.id.to_s)
|
152
|
+
|
153
|
+
Ensure 'city updated' do
|
154
|
+
city.reload
|
155
|
+
expect(city.state_code) == state.code
|
156
|
+
end
|
157
|
+
|
158
|
+
Ensure 'frontend reflects updates' do
|
159
|
+
get app.route(*args, :attached)
|
160
|
+
is(last_response).ok?
|
161
|
+
expect { extract_elements.children }.any? do |c|
|
162
|
+
c.text == state.name
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
Spec.new CustomKeys::Child do
|
170
|
+
|
171
|
+
state = State.create(name: 'New York', code: 'NY')
|
172
|
+
cities = ['Fulton', 'Niagara Falls'].map {|c| City.create(name: c)}
|
173
|
+
args = [
|
174
|
+
:reverse_assoc,
|
175
|
+
CustomKeys::Parent,
|
176
|
+
:has_many,
|
177
|
+
:cities,
|
178
|
+
state.id
|
179
|
+
]
|
180
|
+
|
181
|
+
Should 'attach cities to New York' do
|
182
|
+
cities.each do |city|
|
183
|
+
post app.route(*args, target_item_id: city.id.to_s)
|
184
|
+
end
|
185
|
+
|
186
|
+
Ensure 'cities updated' do
|
187
|
+
cities.each do |city|
|
188
|
+
city.reload
|
189
|
+
is(city.state_code) == state.code
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
Ensure 'frontend reflects updates' do
|
194
|
+
get app.route(*args, :attached)
|
195
|
+
is(last_response).ok?
|
196
|
+
cities_html = extract_elements.children
|
197
|
+
cities.each do |city|
|
198
|
+
expect(cities_html).any? do |c|
|
199
|
+
c.text == city.name
|
200
|
+
end
|
201
|
+
end
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
end
|
206
|
+
|
207
|
+
module ReadOnly
|
208
|
+
class Books < E
|
209
|
+
include Rear
|
210
|
+
model Book
|
211
|
+
readonly_assoc :author
|
212
|
+
end
|
213
|
+
class Authors < E
|
214
|
+
include Rear
|
215
|
+
model Author
|
216
|
+
end
|
217
|
+
Spec.new Authors do
|
218
|
+
Books.mount
|
219
|
+
|
220
|
+
book, book_id = new_book()
|
221
|
+
args = [
|
222
|
+
:reverse_assoc,
|
223
|
+
Books,
|
224
|
+
:belongs_to,
|
225
|
+
:author,
|
226
|
+
book_id
|
227
|
+
]
|
228
|
+
|
229
|
+
Ensure 'no author attached' do
|
230
|
+
get app.route(*args, :attached)
|
231
|
+
is(last_response).ok?
|
232
|
+
are(extract_elements).empty?
|
233
|
+
end
|
234
|
+
|
235
|
+
author = Author.create(name: rand(2**64).to_s)
|
236
|
+
|
237
|
+
Should 'prohibit attaching' do
|
238
|
+
post app.route(*args, target_item_id: author.id.to_s)
|
239
|
+
is(last_response).readonly_error?
|
240
|
+
end
|
241
|
+
|
242
|
+
Should 'prohibit detaching' do
|
243
|
+
delete app.route(*args)
|
244
|
+
is(last_response).readonly_error?
|
245
|
+
end
|
246
|
+
end
|
247
|
+
end
|
248
|
+
|
249
|
+
end
|
@@ -0,0 +1,269 @@
|
|
1
|
+
|
2
|
+
module RearTest__Columns
|
3
|
+
|
4
|
+
class BasicApp < E
|
5
|
+
include Rear
|
6
|
+
model Book
|
7
|
+
end
|
8
|
+
Spec.new BasicApp do
|
9
|
+
|
10
|
+
item, item_id = new_book()
|
11
|
+
|
12
|
+
Testing :pane do
|
13
|
+
get
|
14
|
+
is(last_response).ok?
|
15
|
+
expect(extract_elements('.pane-item').size) > 0
|
16
|
+
|
17
|
+
elements = extract_elements
|
18
|
+
expect( elements ).any? {|e| e.text == item[:name].to_s }
|
19
|
+
expect( elements ).any? {|e| e.text == item[:about].to_s}
|
20
|
+
end
|
21
|
+
|
22
|
+
Testing :editor do
|
23
|
+
get :edit, item_id
|
24
|
+
is(last_response).ok?
|
25
|
+
elements = extract_elements
|
26
|
+
expect( elements ).any? do |e|
|
27
|
+
e.children.any? {|c| c.name == 'input' && c.attr(:value) == item[:name].to_s }
|
28
|
+
end
|
29
|
+
expect( elements ).any? do |e|
|
30
|
+
e.children.any? {|c| c.name == 'textarea' && c.text == item[:about].to_s }
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
|
36
|
+
class SelectType < E
|
37
|
+
include Rear
|
38
|
+
model Book
|
39
|
+
input :cover, :select do
|
40
|
+
options('Solid', 'Soft')
|
41
|
+
end
|
42
|
+
end
|
43
|
+
Spec.new SelectType do
|
44
|
+
|
45
|
+
item, item_id = new_book( :cover => 'Soft')
|
46
|
+
|
47
|
+
Testing :pane do
|
48
|
+
get
|
49
|
+
check( extract_elements ).any? {|e| e.text == 'Soft'}
|
50
|
+
end
|
51
|
+
|
52
|
+
Testing :editor do
|
53
|
+
get :edit, item_id
|
54
|
+
is(last_response).ok?
|
55
|
+
check( extract_elements ).any? { |e|
|
56
|
+
e.children.any? do |c|
|
57
|
+
c.name == 'select' && c.attr(:name) == 'cover' &&
|
58
|
+
c.children.any? {|cc|
|
59
|
+
cc.attr(:value) == 'Soft' && cc.attr(:selected)
|
60
|
+
}
|
61
|
+
end
|
62
|
+
}
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
|
67
|
+
|
68
|
+
class MultiSelectType < E
|
69
|
+
include Rear
|
70
|
+
model Book
|
71
|
+
|
72
|
+
on_save do
|
73
|
+
params['colors'] = params['colors'].join(',')
|
74
|
+
end
|
75
|
+
|
76
|
+
input :colors, :select, :multiple => true do
|
77
|
+
options 'r' => 'Reg', 'g' => 'Green', 'b' => 'Blue' do
|
78
|
+
item.colors.to_s.split(',')
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
Spec.new MultiSelectType do
|
83
|
+
|
84
|
+
item, item_id = new_book( :colors => 'r,g')
|
85
|
+
|
86
|
+
Testing :pane do
|
87
|
+
|
88
|
+
get
|
89
|
+
is(last_response).ok?
|
90
|
+
check( extract_elements ).any? {|e|
|
91
|
+
e.text =~ /Red/ || e.text =~ /Green/
|
92
|
+
}
|
93
|
+
end
|
94
|
+
|
95
|
+
Testing :editor do
|
96
|
+
get :edit, item_id
|
97
|
+
is(last_response).ok?
|
98
|
+
check( extract_elements ).any? { |e|
|
99
|
+
e.children.any? do |c|
|
100
|
+
c.name == 'select' && c.attr(:name) == 'colors[]' &&
|
101
|
+
c.children.any? {|cc|
|
102
|
+
cc.attr(:value) == 'r' && cc.attr(:selected)
|
103
|
+
} && c.children.any? {|cc|
|
104
|
+
cc.attr(:value) == 'g' && cc.attr(:selected)
|
105
|
+
}
|
106
|
+
end
|
107
|
+
}
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
|
112
|
+
class CheckboxType < E
|
113
|
+
include Rear
|
114
|
+
model Book
|
115
|
+
|
116
|
+
on_save do
|
117
|
+
params['colors'] = params['colors'].join(',')
|
118
|
+
end
|
119
|
+
|
120
|
+
input :colors, :checkbox do
|
121
|
+
options 'r' => 'Reg', 'g' => 'Green', 'b' => 'Blue' do
|
122
|
+
item.colors.to_s.split(',')
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
Spec.new CheckboxType do
|
127
|
+
|
128
|
+
item, item_id = new_book( :colors => 'g,b')
|
129
|
+
Testing :pane do
|
130
|
+
get
|
131
|
+
check( extract_elements ).any? {|e|
|
132
|
+
e.text =~ /Green/ || e.text =~ /Blue/
|
133
|
+
}
|
134
|
+
end
|
135
|
+
|
136
|
+
Testing :editor do
|
137
|
+
|
138
|
+
get :edit, item_id
|
139
|
+
is(last_response).ok?
|
140
|
+
elements = extract_elements('.editor-checkbox_container')
|
141
|
+
item.colors.split(',').each do |color|
|
142
|
+
check( elements ).any? { |e|
|
143
|
+
e.children.any? { |c|
|
144
|
+
c.name == 'input' &&
|
145
|
+
c.attr(:type) == 'checkbox' &&
|
146
|
+
c.attr(:name) == 'colors[]' &&
|
147
|
+
c.attr(:value) == color && c.attr(:checked)
|
148
|
+
}
|
149
|
+
}
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
|
155
|
+
class RadioType < E
|
156
|
+
include Rear
|
157
|
+
model Book
|
158
|
+
input :cover, :radio do
|
159
|
+
options('Solid', 'Soft') { item.cover }
|
160
|
+
end
|
161
|
+
end
|
162
|
+
Spec.new RadioType do
|
163
|
+
|
164
|
+
item, item_id = new_book( :cover => 'Solid')
|
165
|
+
Testing :pane do
|
166
|
+
get
|
167
|
+
is(last_response).ok?
|
168
|
+
check( extract_elements ).any? {|e| e.text == 'Solid' }
|
169
|
+
end
|
170
|
+
|
171
|
+
Testing :editor do
|
172
|
+
get :edit, item_id
|
173
|
+
is(last_response).ok?
|
174
|
+
elements = extract_elements('.editor-radio_container')
|
175
|
+
{'Solid' => true, 'Soft' => false}.each_pair do |value, status|
|
176
|
+
check( elements ).any? { |e|
|
177
|
+
e.children.any? do |c|
|
178
|
+
c.name == 'input' &&
|
179
|
+
c.attr(:type) == 'radio' &&
|
180
|
+
c.attr(:name) == 'cover' &&
|
181
|
+
c.attr(:value) == value &&
|
182
|
+
(status ? c.attr(:checked) : true)
|
183
|
+
end
|
184
|
+
}
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
|
190
|
+
class AttrsApp < E
|
191
|
+
include Rear
|
192
|
+
model Book
|
193
|
+
input :name, style: 'width: 100%;'
|
194
|
+
input :about, cols: 10
|
195
|
+
end
|
196
|
+
Spec.new AttrsApp do
|
197
|
+
|
198
|
+
item, item_id = new_book()
|
199
|
+
|
200
|
+
get :edit, item_id
|
201
|
+
is(last_response).ok?
|
202
|
+
elements = extract_elements
|
203
|
+
expect( elements ).any? { |e|
|
204
|
+
e.children.any? {|c|
|
205
|
+
c.name == 'input' && c.attr(:style) == 'width: 100%;'
|
206
|
+
}
|
207
|
+
}
|
208
|
+
expect( elements ).any? { |e|
|
209
|
+
e.children.any? {|c| c.name == 'textarea' && c.attr(:cols) == '10' }
|
210
|
+
}
|
211
|
+
|
212
|
+
end
|
213
|
+
|
214
|
+
class DisablerApp < E
|
215
|
+
include Rear
|
216
|
+
model Book
|
217
|
+
|
218
|
+
input :name do
|
219
|
+
pane false
|
220
|
+
end
|
221
|
+
|
222
|
+
input :about do
|
223
|
+
editor false
|
224
|
+
end
|
225
|
+
|
226
|
+
end
|
227
|
+
Spec.new DisablerApp do
|
228
|
+
|
229
|
+
item, item_id = new_book()
|
230
|
+
|
231
|
+
Testing :pane do
|
232
|
+
get
|
233
|
+
is(last_response).ok?
|
234
|
+
elements = extract_elements
|
235
|
+
Should 'show :about column' do
|
236
|
+
expect( elements ).any? {|e|
|
237
|
+
e.children.any? {|c| c.to_s =~ /#{item[:about]}/}
|
238
|
+
}
|
239
|
+
end
|
240
|
+
Should 'NOT show :name column' do
|
241
|
+
refute do
|
242
|
+
elements.any? do |e|
|
243
|
+
e.children.any? {|c| c.text == item[:name]}
|
244
|
+
end
|
245
|
+
end == true
|
246
|
+
end
|
247
|
+
end
|
248
|
+
|
249
|
+
Testing :editor do
|
250
|
+
get :edit, item_id
|
251
|
+
is(last_response).ok?
|
252
|
+
elements = extract_elements
|
253
|
+
Should 'show :name column' do
|
254
|
+
expect( elements ).any? { |e|
|
255
|
+
e.children.any? do |c|
|
256
|
+
c.name == 'input' && c.attr(:value) == item[:name].to_s
|
257
|
+
end
|
258
|
+
}
|
259
|
+
end
|
260
|
+
Should 'NOT show :about column' do
|
261
|
+
refute do
|
262
|
+
elements.any? do |e|
|
263
|
+
e.children.any? {|c| c.name == 'textarea'}
|
264
|
+
end
|
265
|
+
end == true
|
266
|
+
end
|
267
|
+
end
|
268
|
+
end
|
269
|
+
end
|