rear 0.2.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.
- 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/test__crud.rb
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
|
|
2
|
+
module RearTest__CRUD
|
|
3
|
+
class App < E
|
|
4
|
+
include Rear
|
|
5
|
+
model Book
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
Spec.new App do
|
|
9
|
+
orm = RearORM.new(app.model, app.pkey)
|
|
10
|
+
|
|
11
|
+
Should 'create new item' do
|
|
12
|
+
name, about = random_string, random_string
|
|
13
|
+
post :crud, name: name, about: about
|
|
14
|
+
is(last_response).ok?
|
|
15
|
+
id = last_response.body.to_i
|
|
16
|
+
|
|
17
|
+
item = orm[id]
|
|
18
|
+
check(item).instance_of?(app.model)
|
|
19
|
+
expect(item.id) == id
|
|
20
|
+
expect(item.name.to_s) == name
|
|
21
|
+
expect(item.about.to_s) == about
|
|
22
|
+
|
|
23
|
+
Then 'update it' do
|
|
24
|
+
new_name = random_string
|
|
25
|
+
put :crud, id, name: new_name
|
|
26
|
+
is(last_response).ok?
|
|
27
|
+
|
|
28
|
+
item.reload
|
|
29
|
+
refute(item.name.to_s) == name
|
|
30
|
+
check(item.name.to_s) == new_name
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
And 'finally delete it' do
|
|
34
|
+
delete :crud, id
|
|
35
|
+
is(last_response).ok?
|
|
36
|
+
item = app[id]
|
|
37
|
+
is(item).nil?
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
Testing 'multiple delete' do
|
|
42
|
+
|
|
43
|
+
ids = (1..10).inject([]) {|f,c| post(:crud); f << last_response.body.to_i}
|
|
44
|
+
expect(ids.size) == 10
|
|
45
|
+
items = orm.filter(conditions: {app.pkey => ids})
|
|
46
|
+
expect(items.size) == ids.size
|
|
47
|
+
|
|
48
|
+
delete :delete_selected, items: ids.join(' ')
|
|
49
|
+
is(last_response).ok?
|
|
50
|
+
items = orm.filter(conditions: {app.pkey => ids})
|
|
51
|
+
expect(items.size) == 0
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
class ReadOnlyBook < E
|
|
57
|
+
include Rear
|
|
58
|
+
model Book
|
|
59
|
+
readonly!
|
|
60
|
+
end
|
|
61
|
+
Spec.new ReadOnlyBook do
|
|
62
|
+
book, book_id = new_book
|
|
63
|
+
|
|
64
|
+
Should 'Prohibit items creation' do
|
|
65
|
+
name, about = random_string, random_string
|
|
66
|
+
post :crud, name: name, about: about
|
|
67
|
+
is(last_response).readonly_error?
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
Should 'prohibit updates' do
|
|
71
|
+
put :crud, book_id, name: random_string
|
|
72
|
+
is(last_response).readonly_error?
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
Should 'prohibit deletion' do
|
|
76
|
+
delete :crud, book_id
|
|
77
|
+
is(last_response).readonly_error?
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
end
|
|
81
|
+
end
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
|
|
2
|
+
module RearTest__CustomTemplates
|
|
3
|
+
|
|
4
|
+
class SharedTemplates < E
|
|
5
|
+
include Rear
|
|
6
|
+
model Book
|
|
7
|
+
rear_templates 'templates/shared'
|
|
8
|
+
ipp 1000
|
|
9
|
+
end
|
|
10
|
+
Spec.new self do
|
|
11
|
+
app E.new {
|
|
12
|
+
mount SharedTemplates
|
|
13
|
+
root File.expand_path('..', __FILE__)
|
|
14
|
+
}
|
|
15
|
+
map SharedTemplates.base_url
|
|
16
|
+
|
|
17
|
+
item, item_id = new_book
|
|
18
|
+
|
|
19
|
+
Testing :pane do
|
|
20
|
+
get
|
|
21
|
+
is(last_response).ok?
|
|
22
|
+
expect( extract_elements ).any? {|e|
|
|
23
|
+
e.children.any? {|c|
|
|
24
|
+
c.to_s == '<p class="custom-shared-template">%s</p>' % item[:name]
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
Testing :editor do
|
|
30
|
+
get :edit, item_id
|
|
31
|
+
is(last_response).ok?
|
|
32
|
+
expect( extract_elements ).any? { |e|
|
|
33
|
+
e.children.any? {|c|
|
|
34
|
+
c.to_s == '<input class="custom-shared-template" value="%s">' % item[:name]
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
class AdhocDefaultTemplate < E
|
|
41
|
+
include Rear
|
|
42
|
+
model Book
|
|
43
|
+
rear_templates 'templates/adhoc'
|
|
44
|
+
ipp 1000
|
|
45
|
+
end
|
|
46
|
+
Spec.new self do
|
|
47
|
+
app E.new {
|
|
48
|
+
mount AdhocDefaultTemplate
|
|
49
|
+
root File.expand_path('..', __FILE__)
|
|
50
|
+
}
|
|
51
|
+
map AdhocDefaultTemplate.base_url
|
|
52
|
+
|
|
53
|
+
item, item_id = new_book
|
|
54
|
+
|
|
55
|
+
Testing :pane do
|
|
56
|
+
get
|
|
57
|
+
is(last_response).ok?
|
|
58
|
+
expect( extract_elements ).any? {|e|
|
|
59
|
+
e.children.any? {|c|
|
|
60
|
+
c.to_s == '<p class="adhoc-default-template">%s</p>' % item[:name]
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
Testing :editor do
|
|
66
|
+
get :edit, item_id
|
|
67
|
+
is(last_response).ok?
|
|
68
|
+
expect( extract_elements ).any? { |e|
|
|
69
|
+
e.children.any? {|c|
|
|
70
|
+
c.to_s == '<input class="adhoc-default-template" value="%s">' % item[:name]
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
class AdhocGivenTemplate < E
|
|
77
|
+
include Rear
|
|
78
|
+
model Book
|
|
79
|
+
rear_templates 'templates/adhoc'
|
|
80
|
+
input :name do
|
|
81
|
+
editor_template :name
|
|
82
|
+
pane_template :name
|
|
83
|
+
end
|
|
84
|
+
ipp 1000
|
|
85
|
+
end
|
|
86
|
+
Spec.new self do
|
|
87
|
+
app E.new {
|
|
88
|
+
mount AdhocGivenTemplate
|
|
89
|
+
root File.expand_path('..', __FILE__)
|
|
90
|
+
}
|
|
91
|
+
map AdhocGivenTemplate.base_url
|
|
92
|
+
|
|
93
|
+
item, item_id = new_book
|
|
94
|
+
|
|
95
|
+
Testing :pane do
|
|
96
|
+
get
|
|
97
|
+
is(last_response).ok?
|
|
98
|
+
expect( extract_elements ).any? {|e|
|
|
99
|
+
e.children.any? {|c|
|
|
100
|
+
c.to_s == '<p class="adhoc-given-template">%s</p>' % item[:name]
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
Testing :editor do
|
|
106
|
+
get :edit, item_id
|
|
107
|
+
is(last_response).ok?
|
|
108
|
+
expect( extract_elements ).any? { |e|
|
|
109
|
+
e.children.any? {|c|
|
|
110
|
+
c.to_s == '<input class="adhoc-given-template" value="%s">' % item[:name]
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
class ProcTemplate < E
|
|
118
|
+
include Rear
|
|
119
|
+
model Book
|
|
120
|
+
input :name do
|
|
121
|
+
pane_template { item.name }
|
|
122
|
+
editor_template { item.about }
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
Spec.new ProcTemplate do
|
|
126
|
+
|
|
127
|
+
item, item_id = new_book()
|
|
128
|
+
|
|
129
|
+
Testing :pane do
|
|
130
|
+
get
|
|
131
|
+
is(last_response).ok?
|
|
132
|
+
expect( extract_elements ).any? {|e|
|
|
133
|
+
e.children.any? {|c| c.to_s == item[:name]}
|
|
134
|
+
}
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
Testing :editor do
|
|
138
|
+
get :edit, item_id
|
|
139
|
+
is(last_response).ok?
|
|
140
|
+
expect( extract_elements ).any? do |e|
|
|
141
|
+
e.children.any? {|c|
|
|
142
|
+
c.to_s == item[:about]
|
|
143
|
+
}
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
end
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
|
|
2
|
+
module RearTest__Filters
|
|
3
|
+
NAMES = %w[
|
|
4
|
+
Arthur Aaron Adler
|
|
5
|
+
Daniel Dante David
|
|
6
|
+
Edward Eliot Elvin
|
|
7
|
+
]
|
|
8
|
+
|
|
9
|
+
class BasicQuickFilterApp < E
|
|
10
|
+
include Rear
|
|
11
|
+
model Book
|
|
12
|
+
|
|
13
|
+
quick_filter :cover, :Soft, :Solid
|
|
14
|
+
quick_filter :colors, 'r' => 'Red Color', 'g' => :Green
|
|
15
|
+
end
|
|
16
|
+
Spec.new BasicQuickFilterApp do
|
|
17
|
+
|
|
18
|
+
Testing 'filters provided as arguments' do
|
|
19
|
+
%w[Soft Solid].map do |cover|
|
|
20
|
+
1.upto(rand(10)+1) { app.model.create(:cover => cover) }
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
cover = 'Soft'
|
|
24
|
+
items = count_books(:cover => cover)
|
|
25
|
+
expect(items) > 0
|
|
26
|
+
get quick_filters: {cover: cover}
|
|
27
|
+
is(last_response).ok?
|
|
28
|
+
expect(items) == extract_elements('.pane-item').size
|
|
29
|
+
|
|
30
|
+
cover = 'Solid'
|
|
31
|
+
items = count_books(cover: cover)
|
|
32
|
+
expect(items) > 0
|
|
33
|
+
get quick_filters: {cover: cover}
|
|
34
|
+
is(last_response).ok?
|
|
35
|
+
expect(items) == extract_elements('.pane-item').size
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
Testing 'filters provided as Hash' do
|
|
39
|
+
%w[r g].map do |color|
|
|
40
|
+
1.upto(rand(10)+1) { app.model.create(:colors => color) }
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
items = count_books( :colors => 'r')
|
|
44
|
+
expect(items) > 0
|
|
45
|
+
get quick_filters: {colors: 'Red Color'}
|
|
46
|
+
is(last_response).ok?
|
|
47
|
+
expect(items) == extract_elements('.pane-item').size
|
|
48
|
+
|
|
49
|
+
items = count_books( :colors => 'g')
|
|
50
|
+
expect(items) > 0
|
|
51
|
+
get quick_filters: {colors: 'Green'}
|
|
52
|
+
is(last_response).ok?
|
|
53
|
+
expect(items) == extract_elements('.pane-item').size
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
class AdvancedQuickFilterApp < E
|
|
60
|
+
include Rear
|
|
61
|
+
model Book
|
|
62
|
+
|
|
63
|
+
quick_filter :name, cmp: :like_, 'A' => :StartingwithA, 'Z' => 'Starting with Z'
|
|
64
|
+
quick_filter :colors, 'r' => :Red, [:like_, :g] => :GreenFirst
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
Spec.new AdvancedQuickFilterApp do
|
|
68
|
+
query_map = RearConstants::FILTERS__QUERY_MAP.call(app.orm)
|
|
69
|
+
|
|
70
|
+
Testing 'cmp passed as global option' do
|
|
71
|
+
%w[A Z].map do |letter|
|
|
72
|
+
1.upto(rand(10)+1) { app.model.create(:name => letter + random_string) }
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
query, value = query_map[:like_]
|
|
76
|
+
items = count_books( [query % :name, value % "A"])
|
|
77
|
+
expect(items) > 0
|
|
78
|
+
get quick_filters: {name: 'StartingwithA'}
|
|
79
|
+
is(last_response).ok?
|
|
80
|
+
expect(items) == extract_elements('.pane-item').size
|
|
81
|
+
|
|
82
|
+
items = count_books([query % :name, value % "Z"])
|
|
83
|
+
expect(items) > 0
|
|
84
|
+
get quick_filters: {name: 'Starting with Z'}
|
|
85
|
+
is(last_response).ok?
|
|
86
|
+
expect(items) == extract_elements('.pane-item').size
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
Testing 'cmp passed per filter' do
|
|
90
|
+
a = %w[
|
|
91
|
+
r
|
|
92
|
+
r,g
|
|
93
|
+
g
|
|
94
|
+
g,r
|
|
95
|
+
]
|
|
96
|
+
1.upto(50) do
|
|
97
|
+
app.model.create(:colors => a[rand(a.size)])
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
items = count_books( :colors => 'r')
|
|
101
|
+
expect(items) > 0
|
|
102
|
+
get quick_filters: {colors: 'Red'}
|
|
103
|
+
is(last_response).ok?
|
|
104
|
+
expect(items) == extract_elements('.pane-item').size
|
|
105
|
+
|
|
106
|
+
query, value = query_map[:like_]
|
|
107
|
+
items = count_books( [query % :colors, value % "g"])
|
|
108
|
+
expect(items) > 0
|
|
109
|
+
get quick_filters: {colors: 'GreenFirst'}
|
|
110
|
+
is(last_response).ok?
|
|
111
|
+
expect(items) == extract_elements('.pane-item').size
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
class LikeApp < E
|
|
116
|
+
include Rear
|
|
117
|
+
model Book
|
|
118
|
+
filter :name
|
|
119
|
+
filter :about, cmp: :unlike
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
Spec.new LikeApp do
|
|
123
|
+
|
|
124
|
+
query_map = RearConstants::FILTERS__QUERY_MAP.call(app.orm)
|
|
125
|
+
|
|
126
|
+
(items = %w[abc123 abc456 abc789 foo bar]).each do |val|
|
|
127
|
+
app.model.create :name => val, :about => val
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
Ensure 'all items displayed without filters' do
|
|
131
|
+
get
|
|
132
|
+
is(last_response).ok?
|
|
133
|
+
elements = extract_elements
|
|
134
|
+
items.each do |name|
|
|
135
|
+
expect(elements).any? {|c| c.text == name}
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
Testing :like do
|
|
140
|
+
query, value = query_map[:like]
|
|
141
|
+
items = count_books [query % :name, value % 'abc']
|
|
142
|
+
expect(items) > 0
|
|
143
|
+
get filters: {name: {like: 'abc'}}
|
|
144
|
+
is(last_response).ok?
|
|
145
|
+
elements = extract_elements('.pane-item')
|
|
146
|
+
expect(elements.size) == items
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
Testing :unlike do
|
|
150
|
+
query, value = query_map[:unlike]
|
|
151
|
+
items = count_books [query % :about, value % 'abc']
|
|
152
|
+
get filters: {about: {unlike: 'abc'}}
|
|
153
|
+
is(last_response).ok?
|
|
154
|
+
elements = extract_elements('.pane-item')
|
|
155
|
+
expect(elements.size) == items
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
class EqlApp < E
|
|
160
|
+
include Rear
|
|
161
|
+
model Book
|
|
162
|
+
filter :name, cmp: :eql
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
Spec.new EqlApp do
|
|
166
|
+
|
|
167
|
+
1.upto(10) { app.model.create name: random_string }
|
|
168
|
+
item, item_id = new_book()
|
|
169
|
+
|
|
170
|
+
get
|
|
171
|
+
is(last_response).ok?
|
|
172
|
+
expect(extract_elements('.pane-item').size) > 1
|
|
173
|
+
|
|
174
|
+
get filters: {name: {eql: item.name}}
|
|
175
|
+
is(last_response).ok?
|
|
176
|
+
expect(extract_elements('.pane-item').size) == 1
|
|
177
|
+
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
class DecorativeFiltersApp < E
|
|
181
|
+
include Rear
|
|
182
|
+
model Book
|
|
183
|
+
|
|
184
|
+
decorative_filter :letter, :select do
|
|
185
|
+
('A'..'Z').to_a
|
|
186
|
+
end
|
|
187
|
+
filter :name, :select, cmp: :like do
|
|
188
|
+
filter?(:letter) ?
|
|
189
|
+
NAMES.select {|n| n =~ /\A#{filter(:letter)}/} : {}
|
|
190
|
+
end
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
Spec.new DecorativeFiltersApp do
|
|
194
|
+
|
|
195
|
+
selector = '.selectable[name="filters[name][like]"]'
|
|
196
|
+
|
|
197
|
+
get :html_filters
|
|
198
|
+
filters = extract_elements(selector)
|
|
199
|
+
expect(filters.size) == 1
|
|
200
|
+
is(filters.first.children.select {|c| c.attr(:value).to_s.size > 0}).empty?
|
|
201
|
+
|
|
202
|
+
%w[A D E].each do |letter|
|
|
203
|
+
get :html_filters, filters: {letter: {decorative: letter}}
|
|
204
|
+
is(last_response).ok?
|
|
205
|
+
filters = extract_elements(selector)
|
|
206
|
+
expect(filters.size) == 1
|
|
207
|
+
children = filters.first.children.select {|c| c.attr(:value).to_s.size > 0}
|
|
208
|
+
check(children.map {|c| c.text }.sort) ==
|
|
209
|
+
NAMES.select {|n| n =~ /\A#{letter}/}.sort
|
|
210
|
+
end
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
class InheritedType < E
|
|
214
|
+
include Rear
|
|
215
|
+
model Book
|
|
216
|
+
filter :created_at
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
Spec.new InheritedType do
|
|
220
|
+
get
|
|
221
|
+
is(last_response).ok?
|
|
222
|
+
elements = extract_elements('.search-query')
|
|
223
|
+
expect(elements.select {|e|
|
|
224
|
+
e.attr(:name) == 'filters[created_at][eql]'
|
|
225
|
+
}.size) == 1
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
end
|