listings 0.1.4 → 0.1.5
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +66 -0
- data/app/assets/javascripts/listings.js +37 -6
- data/app/controllers/listings/listings_controller.rb +5 -2
- data/app/views/listings/_listing.html.haml +1 -1
- data/app/views/listings/_table_content.html.haml +1 -1
- data/app/views/listings/twitter-bootstrap-2/_side_filters.html.haml +1 -1
- data/app/views/listings/twitter-bootstrap-2/_top_filters.html.haml +1 -1
- data/app/views/listings/twitter-bootstrap-3/_side_filters.html.haml +1 -1
- data/app/views/listings/twitter-bootstrap-3/_top_filters.html.haml +1 -1
- data/lib/listings/action_view_extensions.rb +8 -2
- data/lib/listings/base.rb +15 -3
- data/lib/listings/base_field_view.rb +4 -0
- data/lib/listings/configuration.rb +2 -0
- data/lib/listings/configuration_methods.rb +7 -1
- data/lib/listings/custom_filter_descriptor.rb +19 -0
- data/lib/listings/custom_filter_view.rb +25 -0
- data/lib/listings/filter_descriptor.rb +4 -0
- data/lib/listings/filter_view.rb +8 -0
- data/lib/listings/kaminari_helpers_tag_patch.rb +17 -8
- data/lib/listings/rspec.rb +5 -0
- data/lib/{rspec → listings/rspec}/listings_helpers.rb +0 -0
- data/lib/listings/sources/active_record_data_source.rb +29 -15
- data/lib/listings/sources/data_source.rb +4 -0
- data/lib/listings/sources/object_data_source.rb +4 -0
- data/lib/listings/version.rb +1 -1
- data/lib/listings/view_helper_methods.rb +2 -0
- data/spec/dummy/app/listings/tracks_listing.rb +5 -0
- data/spec/dummy/config/initializers/listings.rb +3 -0
- data/spec/dummy/db/seeds.rb +4 -1
- data/spec/factories/tracks.rb +2 -2
- data/spec/factories/traits.rb +4 -0
- data/spec/lib/filter_parser_spec.rb +7 -1
- data/spec/spec_helper.rb +1 -2
- metadata +8 -10
- data/lib/rspec.rb +0 -1
data/README.md
CHANGED
@@ -22,6 +22,7 @@ A listing data source have built in support for ActiveRecord and Arrays.
|
|
22
22
|
* [paginates_per](#paginates_per)
|
23
23
|
* [export](#export)
|
24
24
|
* [css](#css)
|
25
|
+
* [Testing](#testing)
|
25
26
|
* [i18n](#i18n)
|
26
27
|
* [Templates](#templates)
|
27
28
|
* [Javascript api](#javascript-api)
|
@@ -63,6 +64,7 @@ Create `config/initializers/listings.rb` file to make general configurations. Li
|
|
63
64
|
# file: config/initializers/listings.rb
|
64
65
|
Listings.configure do |config|
|
65
66
|
config.theme = 'twitter-bootstrap-3' # defaults to 'twitter-bootstrap-2'
|
67
|
+
config.push_url = true # User html5 history push_state to allow back/forward navigation. defaults to false
|
66
68
|
end
|
67
69
|
```
|
68
70
|
|
@@ -241,12 +243,26 @@ It supports `title:` and a block
|
|
241
243
|
end
|
242
244
|
```
|
243
245
|
|
246
|
+
Also `render:` option can be used to suppress the rendering of the filter, but allowing the user to filter by it. For example to filter by the id:
|
247
|
+
|
248
|
+
```ruby
|
249
|
+
filter :id, render: false
|
250
|
+
```
|
251
|
+
|
244
252
|
Filters are rendered by default by the side of the listing. With `layout` method you can change this and render them on the top.
|
245
253
|
|
246
254
|
```ruby
|
247
255
|
layout filters: :top
|
248
256
|
```
|
249
257
|
|
258
|
+
Custom filters allows definition of custom meaning to a key. This filters are not rendered.
|
259
|
+
|
260
|
+
```ruby
|
261
|
+
custom_filter :order_lte do |items, value|
|
262
|
+
items.where('"order" <= ?', value.to_i)
|
263
|
+
end
|
264
|
+
```
|
265
|
+
|
250
266
|
### paginates_per
|
251
267
|
|
252
268
|
Page size can be specified by `paginates_per`
|
@@ -303,6 +319,32 @@ A `column` also support a `class` option to specify a css class to be applied on
|
|
303
319
|
column :title, class: 'title-style'
|
304
320
|
```
|
305
321
|
|
322
|
+
## Testing
|
323
|
+
|
324
|
+
Include `listings/rspec` in your `spec_helper.rb`
|
325
|
+
|
326
|
+
```ruby
|
327
|
+
# file: spec/spec_helper.rb
|
328
|
+
require 'listings/rspec'
|
329
|
+
```
|
330
|
+
|
331
|
+
Ensure listing is able to render
|
332
|
+
|
333
|
+
```ruby
|
334
|
+
# file: spec/listings/tracks_listing_spec.rb
|
335
|
+
require 'spec_helper'
|
336
|
+
|
337
|
+
RSpec.describe TracksListing, type: :listing do
|
338
|
+
let(:listing) { query_listing :tracks }
|
339
|
+
|
340
|
+
it 'should get tracks' do
|
341
|
+
# ... data setup ...
|
342
|
+
items = listing.items.to_a
|
343
|
+
# ... assert expected items ...
|
344
|
+
end
|
345
|
+
end
|
346
|
+
```
|
347
|
+
|
306
348
|
## i18n
|
307
349
|
|
308
350
|
Although titles can be specified in the listing definition, i18n support is available. Add to your locales:
|
@@ -336,6 +378,30 @@ use
|
|
336
378
|
refreshListing('tracks')
|
337
379
|
```
|
338
380
|
|
381
|
+
Change filters
|
382
|
+
|
383
|
+
```
|
384
|
+
$('#tracks.listings').trigger("listings:filter:key:clear", 'album_name')
|
385
|
+
$('#tracks.listings').trigger("listings:filter:key:set", ['album_name', 'Best of'])
|
386
|
+
```
|
387
|
+
|
388
|
+
## View Helpers
|
389
|
+
|
390
|
+
Use `render_listing` helper to include the listing by its `name`.
|
391
|
+
|
392
|
+
```
|
393
|
+
= render_listing :tracks
|
394
|
+
```
|
395
|
+
|
396
|
+
Use `listings_link_to_filter` helper to render a link that will set a filter. Used to example when you want the user to be able to click on a cell value to filter upon that.
|
397
|
+
|
398
|
+
```ruby
|
399
|
+
column artist: :name do |album, value|
|
400
|
+
listings_link_to_filter(value, :artist_id, album.artist_id)
|
401
|
+
end
|
402
|
+
```
|
403
|
+
|
404
|
+
|
339
405
|
## Templates
|
340
406
|
|
341
407
|
There are a number of templates involved in rendering the listing. These templates can be rendered by the hosting app per listing or theme basis.
|
@@ -120,20 +120,17 @@ $(function(){
|
|
120
120
|
$('.listing').on('click', 'a.filter, .filter a', function(e) {
|
121
121
|
elem = $(this);
|
122
122
|
var listingElement = elem.closest('.listing');
|
123
|
-
clearSelectedItems(listingElement);
|
124
|
-
|
125
123
|
var key = elem.data('key');
|
126
124
|
var value = elem.data('value');
|
127
125
|
|
128
126
|
var search_data = listingElement.data('search');
|
129
127
|
if (search_data.filters[key] == value) {
|
130
|
-
|
128
|
+
listingElement.trigger("listings:filter:key:clear", key)
|
131
129
|
} else {
|
132
|
-
|
130
|
+
listingElement.trigger("listings:filter:key:set", [key, value])
|
133
131
|
}
|
134
132
|
|
135
|
-
|
136
|
-
updateListingFromSearchData(listingElement);
|
133
|
+
e.preventDefault();
|
137
134
|
}).on("listings:loaded", function(e){
|
138
135
|
// highlight current filter
|
139
136
|
var listingElement = $(this).closest('.listing');
|
@@ -145,8 +142,42 @@ $(function(){
|
|
145
142
|
listingElement.find(filerLinkSelector).closest('.filter').addClass('active');
|
146
143
|
}
|
147
144
|
|
145
|
+
if (listingElement.data('config').push_url && listingElement.data('skip-push-url') !== true) {
|
146
|
+
listingElement.data('skip-push-url', false);
|
147
|
+
var url = listingElement.data('url');
|
148
|
+
var queryStringStart = url.indexOf('?');
|
149
|
+
var queryString = queryStringStart == -1 ? '' : url.substring(queryStringStart);
|
150
|
+
history.pushState({listing: '#' + listingElement.attr('id')}, document.title, location.href.split('?')[0] + queryString);
|
151
|
+
}
|
152
|
+
|
153
|
+
}).on("listings:filter:key:set", function(event, key, value) {
|
154
|
+
var listingElement = $(this).closest('.listing');
|
155
|
+
clearSelectedItems(listingElement);
|
156
|
+
|
157
|
+
var search_data = listingElement.data('search');
|
158
|
+
search_data.filters[key] = value;
|
159
|
+
listingElement.data('search', search_data);
|
160
|
+
|
161
|
+
updateListingFromSearchData(listingElement);
|
162
|
+
}).on("listings:filter:key:clear", function(event, key) {
|
163
|
+
var listingElement = $(this).closest('.listing');
|
164
|
+
clearSelectedItems(listingElement);
|
165
|
+
|
166
|
+
var search_data = listingElement.data('search');
|
167
|
+
delete search_data.filters[key];
|
168
|
+
listingElement.data('search', search_data);
|
169
|
+
|
170
|
+
updateListingFromSearchData(listingElement);
|
148
171
|
});
|
149
172
|
|
173
|
+
window.onpopstate = function(event) {
|
174
|
+
if (event.state && event.state.listing) {
|
175
|
+
var listing = $(event.state.listing);
|
176
|
+
listing.data('skip-push-url', true);
|
177
|
+
$.get(listing.data('url').split('?')[0] + '?' + document.location.href.split('?')[1]);
|
178
|
+
}
|
179
|
+
};
|
180
|
+
|
150
181
|
function searchEscape(value) {
|
151
182
|
if (value.toString().indexOf(" ") == -1) {
|
152
183
|
return value;
|
@@ -16,8 +16,11 @@ module Listings
|
|
16
16
|
@listing = prepare_listing params, view_context, false
|
17
17
|
|
18
18
|
respond_to do |format|
|
19
|
-
format.csv { send_data @listing.to_csv, filename:
|
20
|
-
format.xls
|
19
|
+
format.csv { send_data @listing.to_csv, filename: @listing.export_filename(:csv) }
|
20
|
+
format.xls do
|
21
|
+
headers["Content-Disposition"] = "attachment; filename=\"#{@listing.export_filename(:xls)}\""
|
22
|
+
render 'listings/export'
|
23
|
+
end
|
21
24
|
end
|
22
25
|
end
|
23
26
|
|
@@ -1,4 +1,4 @@
|
|
1
|
-
.listing{:id => listing.name, :'data-url' => listing.url, :'data-search' => listing.search_data.to_json }
|
1
|
+
.listing{:id => listing.name, :'data-url' => listing.url, :'data-search' => listing.search_data.to_json, :'data-config' => listing.client_config.to_json }
|
2
2
|
= listings_partial_render 'table_full', listing
|
3
3
|
|
4
4
|
:javascript
|
@@ -5,7 +5,13 @@ module Listings
|
|
5
5
|
options.reverse_merge! :params => {}
|
6
6
|
params_for_listing = {:listing => key}.merge(params).merge(options[:params]).with_indifferent_access
|
7
7
|
listing = prepare_listing(params_for_listing, self)
|
8
|
-
listings_partial_render 'listing', listing
|
8
|
+
res = listings_partial_render 'listing', listing
|
9
|
+
Kaminari::Helpers::Tag.paginate_with_listings(nil)
|
10
|
+
res
|
11
|
+
end
|
12
|
+
|
13
|
+
def listings_link_to_filter(text, key, value)
|
14
|
+
link_to text, '#', onclick: "$(this).closest('.listing').trigger('listings:filter:key:set', ['#{key}', '#{escape_javascript(value)}']);return false;"
|
9
15
|
end
|
10
16
|
|
11
17
|
def listings_partial_render(view, listing, options = {})
|
@@ -22,7 +28,7 @@ module Listings
|
|
22
28
|
params.delete :controller
|
23
29
|
params.delete :action
|
24
30
|
|
25
|
-
Kaminari::Helpers::Tag.
|
31
|
+
Kaminari::Helpers::Tag.paginate_with_listings(view_context.listings)
|
26
32
|
|
27
33
|
listing_class = lookup_listing_class(params[:listing])
|
28
34
|
listing_class.new.tap do |listing|
|
data/lib/listings/base.rb
CHANGED
@@ -46,7 +46,7 @@ module Listings
|
|
46
46
|
|
47
47
|
def parse_filter(text, filter_keys)
|
48
48
|
filters = {}
|
49
|
-
filter_keys.each do |key|
|
49
|
+
filter_keys.sort_by {|k| -k.length }.each do |key|
|
50
50
|
text = collect_filter text, key, filters
|
51
51
|
end
|
52
52
|
|
@@ -88,12 +88,12 @@ module Listings
|
|
88
88
|
end
|
89
89
|
|
90
90
|
if filterable?
|
91
|
-
|
91
|
+
filters_to_render.each do |filter_view|
|
92
92
|
filter_view.values # prepare values
|
93
93
|
end
|
94
94
|
|
95
95
|
self.search_filters.each do |key, filter_value|
|
96
|
-
|
96
|
+
filter_with_key(key).apply_filter(filter_value)
|
97
97
|
end
|
98
98
|
end
|
99
99
|
|
@@ -217,5 +217,17 @@ module Listings
|
|
217
217
|
def theme
|
218
218
|
Listings.configuration.theme
|
219
219
|
end
|
220
|
+
|
221
|
+
def export_filename(format)
|
222
|
+
"#{kind.gsub(' ', '_')}_#{Time.now.to_s.gsub(' ', '_')}.#{format}"
|
223
|
+
end
|
224
|
+
|
225
|
+
def filters_to_render
|
226
|
+
filters.select { |f| f.render? }
|
227
|
+
end
|
228
|
+
|
229
|
+
def client_config
|
230
|
+
{ push_url: Listings.configuration.push_url }
|
231
|
+
end
|
220
232
|
end
|
221
233
|
end
|
@@ -13,9 +13,11 @@ module Listings
|
|
13
13
|
|
14
14
|
class Configuration
|
15
15
|
attr_accessor :theme
|
16
|
+
attr_accessor :push_url # use html5 pushState to allow back navigation of listings. default false.
|
16
17
|
|
17
18
|
def initialize
|
18
19
|
@theme = 'twitter-bootstrap-2'
|
20
|
+
@push_url = false
|
19
21
|
end
|
20
22
|
end
|
21
23
|
end
|
@@ -5,6 +5,8 @@ require 'listings/column_descriptor'
|
|
5
5
|
require 'listings/column_view'
|
6
6
|
require 'listings/filter_descriptor'
|
7
7
|
require 'listings/filter_view'
|
8
|
+
require 'listings/custom_filter_descriptor'
|
9
|
+
require 'listings/custom_filter_view'
|
8
10
|
|
9
11
|
module Listings
|
10
12
|
module ConfigurationMethods
|
@@ -57,7 +59,7 @@ module Listings
|
|
57
59
|
|
58
60
|
def filters
|
59
61
|
@filters ||= self.class.filters.map do |fd|
|
60
|
-
|
62
|
+
fd.build(self)
|
61
63
|
end
|
62
64
|
end
|
63
65
|
end
|
@@ -162,6 +164,10 @@ module Listings
|
|
162
164
|
filters << FilterDescriptor.new(path, props, proc)
|
163
165
|
end
|
164
166
|
|
167
|
+
def custom_filter(key, &proc)
|
168
|
+
filters << CustomFilterDescriptor.new(key, proc)
|
169
|
+
end
|
170
|
+
|
165
171
|
def layout(props = {})
|
166
172
|
@layout_options = props
|
167
173
|
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Listings
|
2
|
+
class CustomFilterDescriptor
|
3
|
+
attr_reader :key
|
4
|
+
attr_reader :proc
|
5
|
+
|
6
|
+
def initialize(key, proc)
|
7
|
+
@key = key
|
8
|
+
@proc = proc
|
9
|
+
end
|
10
|
+
|
11
|
+
def build(listing)
|
12
|
+
CustomFilterView.new(listing, self)
|
13
|
+
end
|
14
|
+
|
15
|
+
def apply_filter(value)
|
16
|
+
data_source.filter(field, value)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Listings
|
2
|
+
class CustomFilterView
|
3
|
+
attr_reader :listing
|
4
|
+
attr_reader :descriptor
|
5
|
+
|
6
|
+
def initialize(listing, descriptor)
|
7
|
+
@listing = listing
|
8
|
+
@descriptor = descriptor
|
9
|
+
end
|
10
|
+
|
11
|
+
def key
|
12
|
+
@descriptor.key
|
13
|
+
end
|
14
|
+
|
15
|
+
def render?
|
16
|
+
false
|
17
|
+
end
|
18
|
+
|
19
|
+
def apply_filter(value)
|
20
|
+
listing.data_source.transform_items do |items|
|
21
|
+
listing.instance_exec items, value, &@descriptor.proc
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/lib/listings/filter_view.rb
CHANGED
@@ -1,20 +1,29 @@
|
|
1
1
|
module Kaminari
|
2
2
|
module Helpers
|
3
3
|
class Tag
|
4
|
+
def self.paginate_with_listings(val)
|
5
|
+
Thread.current[:listings] = val
|
6
|
+
end
|
4
7
|
|
5
|
-
def self.
|
6
|
-
|
8
|
+
def self.listings_to_paginate_with
|
9
|
+
Thread.current[:listings]
|
7
10
|
end
|
8
11
|
|
9
12
|
# patch kaminari helpers
|
10
13
|
# passing options of mountable engine routes seems to not be working
|
11
|
-
def
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
14
|
+
def page_url_for_with_listing(page)
|
15
|
+
if Kaminari::Helpers::Tag.listings_to_paginate_with
|
16
|
+
@params.delete :page
|
17
|
+
params = {@param_name => page}.merge(@params).with_indifferent_access
|
18
|
+
params.delete :controller
|
19
|
+
params.delete :action
|
20
|
+
Kaminari::Helpers::Tag.listings_to_paginate_with.listing_content_url(params)
|
21
|
+
else
|
22
|
+
page_url_for_without_listing(page)
|
23
|
+
end
|
17
24
|
end
|
25
|
+
|
26
|
+
alias_method_chain :page_url_for, :listing
|
18
27
|
end
|
19
28
|
end
|
20
29
|
end
|
File without changes
|
@@ -29,6 +29,10 @@ module Listings::Sources
|
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
32
|
+
def transform_items
|
33
|
+
@items = yield @items
|
34
|
+
end
|
35
|
+
|
32
36
|
def scope
|
33
37
|
@items = yield @items
|
34
38
|
@items_for_filter = yield @items_for_filter
|
@@ -39,7 +43,7 @@ module Listings::Sources
|
|
39
43
|
end
|
40
44
|
|
41
45
|
def values_for_filter(field)
|
42
|
-
|
46
|
+
field.all_values(@items_for_filter)
|
43
47
|
end
|
44
48
|
|
45
49
|
def search(fields, value)
|
@@ -62,7 +66,6 @@ module Listings::Sources
|
|
62
66
|
|
63
67
|
def joins(relation)
|
64
68
|
@items = @items.eager_load(relation)
|
65
|
-
@items_for_filter = @items_for_filter.joins(relation)
|
66
69
|
end
|
67
70
|
|
68
71
|
def build_field(path)
|
@@ -89,10 +92,28 @@ module Listings::Sources
|
|
89
92
|
end
|
90
93
|
end
|
91
94
|
|
92
|
-
class
|
95
|
+
class BaseActiveRecordField < Field
|
93
96
|
delegate :connection, to: :data_source
|
94
97
|
delegate :quote_table_name, :quote_column_name, to: :connection
|
95
98
|
|
99
|
+
def initialize(data_source)
|
100
|
+
super(data_source)
|
101
|
+
end
|
102
|
+
|
103
|
+
def all_values(items)
|
104
|
+
prepare_pluck(items).reorder(query_column).pluck("distinct #{query_column}").reject(&:nil?)
|
105
|
+
end
|
106
|
+
|
107
|
+
def prepare_pluck(items)
|
108
|
+
items
|
109
|
+
end
|
110
|
+
|
111
|
+
def sort(items, direction)
|
112
|
+
items.reorder("#{query_column} #{direction}")
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
class ActiveRecordField < BaseActiveRecordField
|
96
117
|
def initialize(attribute_name, data_source)
|
97
118
|
super(data_source)
|
98
119
|
@attribute_name = attribute_name
|
@@ -106,10 +127,6 @@ module Listings::Sources
|
|
106
127
|
"#{quote_table_name(data_source.items.table_name)}.#{quote_column_name(@attribute_name)}"
|
107
128
|
end
|
108
129
|
|
109
|
-
def sort(items, direction)
|
110
|
-
items.reorder("#{query_column} #{direction}")
|
111
|
-
end
|
112
|
-
|
113
130
|
def key
|
114
131
|
@attribute_name.to_s
|
115
132
|
end
|
@@ -119,10 +136,7 @@ module Listings::Sources
|
|
119
136
|
end
|
120
137
|
end
|
121
138
|
|
122
|
-
class ActiveRecordAssociationField <
|
123
|
-
delegate :connection, to: :data_source
|
124
|
-
delegate :quote_table_name, :quote_column_name, to: :connection
|
125
|
-
|
139
|
+
class ActiveRecordAssociationField < BaseActiveRecordField
|
126
140
|
def initialize(path, data_source)
|
127
141
|
super(data_source)
|
128
142
|
@path = path
|
@@ -130,6 +144,10 @@ module Listings::Sources
|
|
130
144
|
data_source.joins(path[0])
|
131
145
|
end
|
132
146
|
|
147
|
+
def prepare_pluck(items)
|
148
|
+
items.joins(@path[0])
|
149
|
+
end
|
150
|
+
|
133
151
|
def value_for(item)
|
134
152
|
result = item
|
135
153
|
@path.each do |attribute_name|
|
@@ -144,10 +162,6 @@ module Listings::Sources
|
|
144
162
|
"#{quote_table_name(association.reflection.table_name)}.#{quote_column_name(@path[1])}"
|
145
163
|
end
|
146
164
|
|
147
|
-
def sort(items, direction)
|
148
|
-
items.reorder("#{query_column} #{direction}")
|
149
|
-
end
|
150
|
-
|
151
165
|
def key
|
152
166
|
@path.join('_')
|
153
167
|
end
|
@@ -8,6 +8,10 @@ module Listings::Sources
|
|
8
8
|
def items
|
9
9
|
end
|
10
10
|
|
11
|
+
# free transform items. used usually to filter the result with logic given by a block
|
12
|
+
def transform_items
|
13
|
+
end
|
14
|
+
|
11
15
|
# applies filter to the items
|
12
16
|
# scope will be called with a block with the ongoing items
|
13
17
|
# the result of the block is used as the narrowed items
|
data/lib/listings/version.rb
CHANGED
@@ -19,6 +19,8 @@ module Listings
|
|
19
19
|
view_context.listings.listing_export_url build_params(:format => format)
|
20
20
|
end
|
21
21
|
|
22
|
+
# TODO add url_for_filter that will build the search string
|
23
|
+
|
22
24
|
def build_params(more_params)
|
23
25
|
res = view_context.params.merge(:listing => self.name).merge(params).merge(more_params)
|
24
26
|
res.delete param_page
|
@@ -6,6 +6,11 @@ class TracksListing < Listings::Base
|
|
6
6
|
filter album: :id, title: 'The Album Id' do |value|
|
7
7
|
"#{value}!"
|
8
8
|
end
|
9
|
+
filter :order, render: false
|
10
|
+
|
11
|
+
custom_filter :order_lte do |items, value|
|
12
|
+
items.where('"order" <= ?', value.to_i)
|
13
|
+
end
|
9
14
|
|
10
15
|
column :order
|
11
16
|
column :title, searchable: true
|
data/spec/dummy/db/seeds.rb
CHANGED
@@ -5,7 +5,10 @@ require 'factory_girl'
|
|
5
5
|
Post.create! title: "post n-#{sn}", author: "john-#{(sn % 4) + 1}", category: "category-#{(sn % 3) + 1}"
|
6
6
|
end
|
7
7
|
|
8
|
-
|
9
8
|
(1..10).each do |sn|
|
10
9
|
FactoryGirl.create :album
|
11
10
|
end
|
11
|
+
|
12
|
+
(1..10).each do |sn|
|
13
|
+
FactoryGirl.create :track, album: nil
|
14
|
+
end
|
data/spec/factories/tracks.rb
CHANGED
data/spec/factories/traits.rb
CHANGED
@@ -28,12 +28,18 @@ describe Listings do
|
|
28
28
|
assert_parse_filter "album_name:'me 2' ", {album_name: "me 2"}, ""
|
29
29
|
|
30
30
|
assert_parse_filter "album_name:me-1", {album_name: "me-1"}, ""
|
31
|
+
|
32
|
+
assert_parse_filter_with_keys "project_id:3", [:id, :project_id], {project_id:"3"}, ""
|
31
33
|
end
|
32
34
|
|
33
35
|
def assert_parse_filter(text, hash, left_text)
|
36
|
+
assert_parse_filter_with_keys(text, hash.keys, hash, left_text)
|
37
|
+
end
|
38
|
+
|
39
|
+
def assert_parse_filter_with_keys(text, keys, hash, left_text)
|
34
40
|
listing = Listings::Base.new
|
35
41
|
|
36
|
-
filters, s = listing.parse_filter text,
|
42
|
+
filters, s = listing.parse_filter text, keys
|
37
43
|
|
38
44
|
s.should eq(left_text)
|
39
45
|
filters.should eq(hash)
|
data/spec/spec_helper.rb
CHANGED
@@ -4,7 +4,7 @@ require File.expand_path("../dummy/config/environment", __FILE__)
|
|
4
4
|
require 'rspec/rails'
|
5
5
|
require 'rspec/autorun'
|
6
6
|
require 'factory_girl_rails'
|
7
|
-
require File.expand_path("../../lib/rspec", __FILE__)
|
7
|
+
require File.expand_path("../../lib/listings/rspec", __FILE__)
|
8
8
|
|
9
9
|
# Requires supporting ruby files with custom matchers and macros, etc,
|
10
10
|
# in spec/support/ and its subdirectories.
|
@@ -42,5 +42,4 @@ RSpec.configure do |config|
|
|
42
42
|
config.order = "random"
|
43
43
|
|
44
44
|
config.include FactoryGirl::Syntax::Methods
|
45
|
-
config.include RSpec::ListingsHelpers, type: :listing
|
46
45
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: listings
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.5
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2015-06-
|
12
|
+
date: 2015-06-29 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rails
|
@@ -210,12 +210,16 @@ files:
|
|
210
210
|
- lib/listings/column_view.rb
|
211
211
|
- lib/listings/configuration.rb
|
212
212
|
- lib/listings/configuration_methods.rb
|
213
|
+
- lib/listings/custom_filter_descriptor.rb
|
214
|
+
- lib/listings/custom_filter_view.rb
|
213
215
|
- lib/listings/dynamic_binding.rb
|
214
216
|
- lib/listings/engine.rb
|
215
217
|
- lib/listings/filter_descriptor.rb
|
216
218
|
- lib/listings/filter_view.rb
|
217
219
|
- lib/listings/filters/base.rb
|
218
220
|
- lib/listings/kaminari_helpers_tag_patch.rb
|
221
|
+
- lib/listings/rspec/listings_helpers.rb
|
222
|
+
- lib/listings/rspec.rb
|
219
223
|
- lib/listings/scope_descriptor.rb
|
220
224
|
- lib/listings/sources/active_record_data_source.rb
|
221
225
|
- lib/listings/sources/data_source.rb
|
@@ -224,8 +228,6 @@ files:
|
|
224
228
|
- lib/listings/version.rb
|
225
229
|
- lib/listings/view_helper_methods.rb
|
226
230
|
- lib/listings.rb
|
227
|
-
- lib/rspec/listings_helpers.rb
|
228
|
-
- lib/rspec.rb
|
229
231
|
- lib/tasks/listings_tasks.rake
|
230
232
|
- LICENSE
|
231
233
|
- Rakefile
|
@@ -265,6 +267,7 @@ files:
|
|
265
267
|
- spec/dummy/config/environments/test.rb
|
266
268
|
- spec/dummy/config/initializers/backtrace_silencers.rb
|
267
269
|
- spec/dummy/config/initializers/inflections.rb
|
270
|
+
- spec/dummy/config/initializers/listings.rb
|
268
271
|
- spec/dummy/config/initializers/mime_types.rb
|
269
272
|
- spec/dummy/config/initializers/secret_token.rb
|
270
273
|
- spec/dummy/config/initializers/session_store.rb
|
@@ -313,18 +316,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
313
316
|
- - ! '>='
|
314
317
|
- !ruby/object:Gem::Version
|
315
318
|
version: '0'
|
316
|
-
segments:
|
317
|
-
- 0
|
318
|
-
hash: 3767681349647885791
|
319
319
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
320
320
|
none: false
|
321
321
|
requirements:
|
322
322
|
- - ! '>='
|
323
323
|
- !ruby/object:Gem::Version
|
324
324
|
version: '0'
|
325
|
-
segments:
|
326
|
-
- 0
|
327
|
-
hash: 3767681349647885791
|
328
325
|
requirements: []
|
329
326
|
rubyforge_project:
|
330
327
|
rubygems_version: 1.8.23.2
|
@@ -367,6 +364,7 @@ test_files:
|
|
367
364
|
- spec/dummy/config/environments/test.rb
|
368
365
|
- spec/dummy/config/initializers/backtrace_silencers.rb
|
369
366
|
- spec/dummy/config/initializers/inflections.rb
|
367
|
+
- spec/dummy/config/initializers/listings.rb
|
370
368
|
- spec/dummy/config/initializers/mime_types.rb
|
371
369
|
- spec/dummy/config/initializers/secret_token.rb
|
372
370
|
- spec/dummy/config/initializers/session_store.rb
|
data/lib/rspec.rb
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
require "rspec/listings_helpers"
|