will_filter 3.1.7 → 3.1.8

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.
Files changed (35) hide show
  1. data/.rspec +1 -0
  2. data/.watchr +18 -0
  3. data/Gemfile.lock +79 -104
  4. data/README.rdoc +17 -1
  5. data/VERSION +1 -0
  6. data/app/controllers/will_filter/filter_controller.rb +1 -0
  7. data/app/models/will_filter/filter.rb +47 -7
  8. data/app/views/will_filter/common/_results_table.html.erb +81 -48
  9. data/lib/will_filter/extensions/action_view_extension.rb +19 -19
  10. data/lib/will_filter/extensions/array_extension.rb +6 -0
  11. data/lib/will_filter/filter_condition.rb +2 -2
  12. data/lib/will_filter/version.rb +1 -1
  13. data/spec/{containers → lib/will_filter/containers}/double_spec.rb +10 -5
  14. data/spec/{extensions → lib/will_filter/extensions}/active_record_extension_spec.rb +7 -2
  15. data/spec/models/will_filter/filter_spec.rb +249 -0
  16. data/spec/spec_helper.rb +26 -26
  17. data/test/dummy/.sass-cache/f9cb1ef521115be73f1c61d3d5d64f66c947af63/actions.css.scssc +0 -0
  18. data/test/dummy/.sass-cache/f9cb1ef521115be73f1c61d3d5d64f66c947af63/results.css.scssc +0 -0
  19. data/test/dummy/app/controllers/application_controller.rb +5 -0
  20. data/test/dummy/app/models/merchant/order.rb +1 -1
  21. data/test/dummy/app/models/merchant/order_item.rb +1 -1
  22. data/test/dummy/app/views/advanced/event_members.html.erb +1 -1
  23. data/test/dummy/app/views/advanced/events.html.erb +1 -1
  24. data/test/dummy/app/views/advanced/users.html.erb +1 -1
  25. data/test/dummy/app/views/advanced/users_with_actions.html.erb +1 -1
  26. data/test/dummy/app/views/common/_event_members.html.erb +14 -1
  27. data/test/dummy/app/views/common/_events.html.erb +1 -0
  28. data/test/dummy/app/views/common/_menu.html.erb +2 -2
  29. data/test/dummy/app/views/common/_users.html.erb +39 -1
  30. data/test/dummy/app/views/simple/event_members.html.erb +1 -1
  31. data/test/dummy/app/views/simple/events.html.erb +1 -1
  32. data/test/dummy/app/views/simple/users.html.erb +1 -1
  33. data/will_filter.gemspec +5 -9
  34. metadata +42 -62
  35. data/spec/fake_app.rb +0 -51
@@ -1,12 +1,17 @@
1
- require File.expand_path('../spec_helper', File.dirname(__FILE__))
1
+ require File.expand_path('../../../spec_helper', File.dirname(__FILE__))
2
2
 
3
3
  describe WillFilter::Containers::Double do
4
4
  describe '#filter' do
5
- before :all do
6
- 5.times {|i| User.create(:first_name => "User #{i}")}
7
- end
8
-
9
5
  context "filtering with is operator" do
6
+
7
+ before :all do
8
+ 5.times {|i| User.create(:first_name => "User #{i}")}
9
+ end
10
+
11
+ after :all do
12
+ User.delete_all
13
+ end
14
+
10
15
  it "should return a single result" do
11
16
  User.filter(:params => {:wf_c0 => "first_name", :wf_o0 => "is", :wf_v0_0 => "User 1"}).total_count.should == 1
12
17
  end
@@ -1,11 +1,16 @@
1
- require File.expand_path('../spec_helper', File.dirname(__FILE__))
1
+ require File.expand_path('../../../spec_helper', File.dirname(__FILE__))
2
2
 
3
3
  describe WillFilter::ActiveRecordExtension do
4
- describe '#filter' do
4
+ describe 'filter' do
5
+
5
6
  before :all do
6
7
  5.times {|i| User.create(:first_name => "User #{i}")}
7
8
  end
8
9
 
10
+ after :all do
11
+ User.delete_all
12
+ end
13
+
9
14
  context "filtering with no params" do
10
15
  it "should return all of the results" do
11
16
  User.filter(:params => {}).total_count.should == User.count
@@ -0,0 +1,249 @@
1
+ require File.expand_path('../../spec_helper', File.dirname(__FILE__))
2
+
3
+ describe WillFilter::Filter do
4
+ describe 'creating new filter' do
5
+ context 'when filter extensions are enabled' do
6
+ context 'creating base filter' do
7
+ it 'should raise an exception' do
8
+ WillFilter::Config.stub!(:require_filter_extensions?).and_return(true)
9
+ expect { WillFilter::Filter.new(User) }.should raise_error
10
+ end
11
+ end
12
+ context 'creating extended filter' do
13
+ it 'should be fine' do
14
+ WillFilter::Config.stub!(:require_filter_extensions?).and_return(true)
15
+ filter = UserFilter.new
16
+ filter.should be_a(UserFilter)
17
+ filter.model_class.should eq(User)
18
+ end
19
+ end
20
+ end
21
+
22
+ context 'when filter extensions are disabled' do
23
+ it "should create a filter" do
24
+ WillFilter::Config.stub!(:require_filter_extensions?).and_return(false)
25
+ filter = WillFilter::Filter.new(User)
26
+ filter.should be_a(WillFilter::Filter)
27
+ filter.model_class_name.should eq('User')
28
+ filter.model_class.should eq(User)
29
+ filter.table_name.should eq('users')
30
+ end
31
+ end
32
+ end
33
+
34
+ describe 'filter methods' do
35
+ before :all do
36
+ @filter = WillFilter::Filter.new(User)
37
+ end
38
+
39
+ it 'definition should contain the right attributes' do
40
+ @filter.definition.keys.should eq([:id, :first_name, :last_name, :birthday, :sex, :created_at, :updated_at])
41
+ end
42
+
43
+ context 'container_by_sql_type' do
44
+ it 'should map the right containers' do
45
+ ['bigint', 'numeric', 'smallint', 'integer', 'int'].each do |type|
46
+ @filter.container_by_sql_type(type).should eq(["nil", "numeric", "numeric_range", "numeric_delimited"])
47
+ end
48
+
49
+ ['float', 'double'].each do |type|
50
+ @filter.container_by_sql_type(type).should eq(["nil", "double", "double_range", "double_delimited"])
51
+ end
52
+
53
+ ['timestamp', 'datetime'].each do |type|
54
+ @filter.container_by_sql_type(type).should eq(["nil", "date_time", "date_time_range", "single_date"])
55
+ end
56
+
57
+ ['date'].each do |type|
58
+ @filter.container_by_sql_type(type).should eq(["nil", "date", "date_range"])
59
+ end
60
+
61
+ ['char', 'character', 'varchar', 'text', 'text[]', 'bytea'].each do |type|
62
+ @filter.container_by_sql_type(type).should eq(["nil", "text", "text_delimited"])
63
+ end
64
+
65
+ ['boolean', 'tinyint'].each do |type|
66
+ @filter.container_by_sql_type(type).should eq(["nil", "boolean"])
67
+ end
68
+ end
69
+ end
70
+
71
+ context 'default_condition_definition_for' do
72
+ it 'should map the right containers' do
73
+ @filter.default_condition_definition_for('id', 'int').should eq({
74
+ :is_provided=>"nil",
75
+ :is_not_provided=>"nil",
76
+ :is=>"numeric",
77
+ :is_not=>"numeric",
78
+ :is_less_than=>"numeric",
79
+ :is_greater_than=>"numeric",
80
+ :is_in_the_range=>"numeric_range",
81
+ :is_in=>"numeric_delimited",
82
+ :is_filtered_by=>:filter_list
83
+ })
84
+
85
+ @filter.default_condition_definition_for('first_name', 'varchar').should eq({
86
+ :is_provided=>"nil",
87
+ :is_not_provided=>"nil",
88
+ :is=>"text",
89
+ :is_not=>"text",
90
+ :contains=>"text",
91
+ :does_not_contain=>"text",
92
+ :starts_with=>"text",
93
+ :ends_with=>"text",
94
+ :is_in=>"text_delimited",
95
+ :is_not_in=>"text_delimited"
96
+ })
97
+ end
98
+ end
99
+
100
+ context 'operator sorting' do
101
+ it 'should sort the operators according to default sort' do
102
+ WillFilter::Config.operator_order.should eq([
103
+ "is",
104
+ "is_not",
105
+ "is_on",
106
+ "is_in",
107
+ "is_provided",
108
+ "is_not_provided",
109
+ "is_after",
110
+ "is_before",
111
+ "is_in_the_range",
112
+ "contains",
113
+ "does_not_contain",
114
+ "starts_with",
115
+ "ends_with",
116
+ "is_greater_than",
117
+ "is_less_than",
118
+ "is_filtered_by"
119
+ ])
120
+
121
+ @filter.sorted_operators({
122
+ :is_provided=>"nil",
123
+ :is_not_provided=>"nil",
124
+ :is=>"numeric",
125
+ :is_not=>"numeric",
126
+ :is_less_than=>"numeric",
127
+ :is_greater_than=>"numeric",
128
+ :is_in_the_range=>"numeric_range",
129
+ :is_in=>"numeric_delimited",
130
+ :is_filtered_by=>:filter_list
131
+ }).should eq([
132
+ "is",
133
+ "is_not",
134
+ "is_in",
135
+ "is_provided",
136
+ "is_not_provided",
137
+ "is_in_the_range",
138
+ "is_greater_than",
139
+ "is_less_than",
140
+ "is_filtered_by"
141
+ ])
142
+ end
143
+ end
144
+ end
145
+
146
+ describe 'serialization' do
147
+ context 'serializing a default filter with no params' do
148
+ before :all do
149
+ @filter = WillFilter::Filter.new(User)
150
+ end
151
+
152
+ it 'should create a default filter hash' do
153
+ @filter.to_params.should eq({
154
+ "wf_type"=>"WillFilter::Filter",
155
+ "wf_match"=>:all,
156
+ "wf_model"=>"User",
157
+ "wf_order"=>"id",
158
+ "wf_order_type"=>"desc",
159
+ "wf_per_page"=>30,
160
+ "wf_export_fields"=>"",
161
+ "wf_export_format"=>:html
162
+ })
163
+ end
164
+ end
165
+
166
+ context 'serializing a filter with conditions' do
167
+ before :all do
168
+ @filter = WillFilter::Filter.new(User)
169
+ @filter.add_condition(:first_name, :is, "Alex")
170
+ @filter.add_condition(:sex, :is, "male")
171
+ end
172
+
173
+ it 'should create a default filter hash' do
174
+ @filter.to_params.should eq({
175
+ "wf_type"=>"WillFilter::Filter",
176
+ "wf_match"=>:all,
177
+ "wf_model"=>"User",
178
+ "wf_order"=>"id",
179
+ "wf_order_type"=>"desc",
180
+ "wf_per_page"=>30,
181
+ "wf_export_fields"=>"",
182
+ "wf_export_format"=>:html,
183
+ "wf_c0"=>:first_name,
184
+ "wf_o0"=>:is,
185
+ "wf_v0_0"=>"Alex",
186
+ "wf_c1"=>:sex,
187
+ "wf_o1"=>:is,
188
+ "wf_v1_0"=>"male"
189
+ })
190
+ end
191
+ end
192
+
193
+ context 'serializing a default filter with params' do
194
+ before :all do
195
+ @filter = WillFilter::Filter.new(User)
196
+ end
197
+
198
+ it 'should create a default filter hash' do
199
+ @filter.to_params(:extra => 'value').should eq({
200
+ "wf_type"=>"WillFilter::Filter",
201
+ "wf_match"=>:all,
202
+ "wf_model"=>"User",
203
+ "wf_order"=>"id",
204
+ "wf_order_type"=>"desc",
205
+ "wf_per_page"=>30,
206
+ "wf_export_fields"=>"",
207
+ "wf_export_format"=>:html,
208
+ "extra"=>"value"
209
+ })
210
+ end
211
+ end
212
+ end
213
+
214
+ describe 'deserialization' do
215
+
216
+ context 'deserializing a filter with conditions' do
217
+ before :all do
218
+ @filter = WillFilter::Filter.new(User)
219
+ end
220
+
221
+ it 'should create a default filter hash' do
222
+ @filter.from_params({
223
+ "wf_type"=>"WillFilter::Filter",
224
+ "wf_match"=>:all,
225
+ "wf_model"=>"User",
226
+ "wf_order"=>"first_name",
227
+ "wf_order_type"=>"asc",
228
+ "wf_per_page"=>30,
229
+ "wf_export_fields"=>"",
230
+ "wf_export_format"=>:html,
231
+ "wf_c0"=>:first_name,
232
+ "wf_o0"=>:is,
233
+ "wf_v0_0"=>"Alex",
234
+ "wf_c1"=>:sex,
235
+ "wf_o1"=>:is,
236
+ "wf_v1_0"=>"male"
237
+ })
238
+
239
+ @filter.order.should eq('first_name')
240
+ @filter.order_type.should eq('asc')
241
+ @filter.conditions.size.should eq(2)
242
+ @filter.conditions.first.key.should eq(:first_name)
243
+ @filter.conditions.first.operator.should eq(:is)
244
+ end
245
+ end
246
+
247
+ end
248
+
249
+ end
data/spec/spec_helper.rb CHANGED
@@ -1,28 +1,28 @@
1
- $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
- $LOAD_PATH.unshift(File.dirname(__FILE__))
3
- require 'rails'
4
- require 'kaminari'
5
- require 'database_cleaner'
6
- require 'will_filter'
7
-
8
- # Ensure we use 'syck' instead of 'psych' in 1.9.2
9
- # RubyGems >= 1.5.0 uses 'psych' on 1.9.2, but
10
- # Psych does not yet support YAML 1.1 merge keys.
11
- # Merge keys is often used in mongoid.yml
12
- # See: http://redmine.ruby-lang.org/issues/show/4300
13
- if RUBY_VERSION >= '1.9.2'
14
- YAML::ENGINE.yamler = 'syck'
1
+ ENV["RAILS_ENV"] = "test"
2
+
3
+ require 'pp'
4
+ require 'spork'
5
+
6
+ Spork.prefork do
7
+
8
+ require File.expand_path("../../test/dummy/config/environment.rb", __FILE__)
9
+ require 'rspec/rails'
10
+
11
+ ENGINE_RAILS_ROOT=File.join(File.dirname(__FILE__), '../')
12
+
13
+ # Requires supporting ruby files with custom matchers and macros, etc,
14
+ # in spec/support/ and its subdirectories.
15
+ Dir[File.join(ENGINE_RAILS_ROOT, "spec/support/**/*.rb")].each {|f| require f }
16
+
17
+ RSpec.configure do |config|
18
+ config.use_transactional_fixtures = true
19
+ config.use_instantiated_fixtures = false
20
+ end
21
+
15
22
  end
16
- require File.join(File.dirname(__FILE__), 'fake_app')
17
-
18
- require 'rspec/rails'
19
- # Requires supporting files with custom matchers and macros, etc,
20
- # in ./support/ and its subdirectories.
21
- Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
22
-
23
- RSpec.configure do |config|
24
- config.mock_with :rr
25
- config.before :all do
26
- CreateAllTables.up unless ActiveRecord::Base.connection.table_exists? 'users'
27
- end
23
+
24
+
25
+ Spork.each_run do
26
+ # This code will be run each time you run your specs.
27
+
28
28
  end
@@ -1,6 +1,11 @@
1
1
  class ApplicationController < ActionController::Base
2
2
  protect_from_forgery
3
3
 
4
+ rescue_from StandardError do |e|
5
+ pp e.backtrace
6
+ raise e
7
+ end
8
+
4
9
  def current_user
5
10
  # for testing purposes we just create a user and store it in the db
6
11
  @current_user ||= begin
@@ -1,6 +1,6 @@
1
1
  module Merchant
2
2
  class Order < ActiveRecord::Base
3
- set_table_name :merchant_orders
3
+ self.table_name = :merchant_orders
4
4
  belongs_to :user
5
5
  has_many :order_items
6
6
  end
@@ -1,6 +1,6 @@
1
1
  module Merchant
2
2
  class OrderItem < ActiveRecord::Base
3
- set_table_name :merchant_order_items
3
+ self.table_name = :merchant_order_items
4
4
  belongs_to :order, :class_name => "Merchant::Order"
5
5
  end
6
6
  end
@@ -1,2 +1,2 @@
1
- <h1>Advanced Event Members Filter</h1>
1
+ <h1>Event Member Filter</h1>
2
2
  <%= render :partial=> "/common/event_members" %>
@@ -1,2 +1,2 @@
1
- <h1>Advanced Events Filter</h1>
1
+ <h1>Event Filter</h1>
2
2
  <%= render :partial=> "/common/events" %>
@@ -1,2 +1,2 @@
1
- <h1>Advanced Users Filter</h1>
1
+ <h1>User Filter</h1>
2
2
  <%= render :partial=> "/common/users" %>
@@ -1,4 +1,4 @@
1
- <h1>Advanced Users Filter</h1>
1
+ <h1>User Filter with Action Bar</h1>
2
2
  <%= will_filter_tag(@users) %>
3
3
  <%= will_filter_table_tag(@users, :columns => [
4
4
  [:checkbox, 'users'],
@@ -1,2 +1,15 @@
1
1
  <%= will_filter_tag(@event_users)%>
2
- <%= will_filter_table_tag(@event_users) %>
2
+
3
+ <%= will_filter_table_tag(@event_users, :columns => [
4
+ :id,
5
+ [:event_id, lambda { |obj|
6
+ link_to(obj.event ? obj.event.name : obj.event_id, @event_users.add_filter_condition(:event_id, :is, obj.event_id).to_params)
7
+ }],
8
+ [:user_id, lambda { |obj|
9
+ link_to(obj.user_id ? obj.user.name : obj.user_id, @event_users.add_filter_condition(:user_id, :is, obj.user_id).to_params)
10
+ }, {
11
+ :title => 'User Name',
12
+ :style => 'font-weight:bold'
13
+ }],
14
+ :created_at
15
+ ]) %>
@@ -1,2 +1,3 @@
1
1
  <%= will_filter_tag(@events)%>
2
+
2
3
  <%= will_filter_table_tag(@events) %>
@@ -12,9 +12,9 @@
12
12
  </td>
13
13
  <td style="text-align:right;">
14
14
  <% if controller.controller_name == 'simple' %>
15
- <%=link_to("Switch to Advanced Mode", :controller => :advanced, :action => :users) %>
15
+ <%=link_to("Extended Filters", :controller => :advanced, :action => :users) %>
16
16
  <% else %>
17
- <%=link_to("Switch to Simple Mode", :controller => :simple, :action => :users) %>
17
+ <%=link_to("Basic Filters", :controller => :simple, :action => :users) %>
18
18
  <% end %>
19
19
  </td>
20
20
  </tr>
@@ -1,2 +1,40 @@
1
1
  <%= will_filter_tag(@users) %>
2
- <%= will_filter_table_tag(@users) %>
2
+
3
+ <%= will_filter_table_tag(@users, :columns => [
4
+ :id,
5
+ {:key => :name,
6
+ :value => lambda{ |obj|
7
+ if @users.wf_filter.column_sorted?(:last_name)
8
+ raw("<span style='font-weight:normal'>#{h(obj.first_name)} <strong>#{h(obj.last_name)}</strong></span>")
9
+ elsif @users.wf_filter.column_sorted?(:first_name)
10
+ raw("<span style='font-weight:normal'><strong>#{h(obj.first_name)}</strong> #{h(obj.last_name)}</span>")
11
+ else
12
+ "#{obj.first_name} #{obj.last_name}"
13
+ end
14
+ },
15
+ :title => lambda{ |filter|
16
+ if filter.column_sorted?(:last_name)
17
+ first_name_link = link_to("First Name", filter.to_params(:wf_order => :first_name, :wf_order_type => 'asc'), :title => "sort by first name ascending")
18
+ last_name_link = link_to("Last Name", filter.to_params(:wf_order => :last_name, :wf_order_type => (filter.order_type == 'asc' ? 'desc' : 'asc')),
19
+ :title => "sort by last name #{(filter.order_type == 'asc' ? 'descending' : 'ascending')}",
20
+ :style=>'color:black;font-weight:bold')
21
+
22
+ elsif filter.column_sorted?(:first_name)
23
+ last_name_link = link_to("Last Name", filter.to_params(:wf_order => :last_name, :wf_order_type => 'asc'), :title => "sort by last name ascending")
24
+ first_name_link = link_to("First Name", filter.to_params(:wf_order => :first_name, :wf_order_type => (filter.order_type == 'asc' ? 'desc' : 'asc')),
25
+ :title => "sort by first name #{(filter.order_type == 'asc' ? 'descending' : 'ascending')}",
26
+ :style=>'color:black;font-weight:bold')
27
+
28
+ else
29
+ last_name_link = link_to("Last Name", filter.to_params(:wf_order => :last_name, :wf_order_type => 'asc'), :title => "sort by last name ascending")
30
+ first_name_link = link_to("First Name", filter.to_params(:wf_order => :first_name, :wf_order_type => 'asc'), :title => "sort by first name ascending")
31
+ end
32
+
33
+ [first_name_link, last_name_link].join(' / ').html_safe
34
+ },
35
+ :sortable => true,
36
+ :sort_key => lambda{ |filter| filter.column_sorted?(:first_name) ? :first_name : :last_name}
37
+ },
38
+ :birthday,
39
+ { :key => :sex, :title => 'Gender' }
40
+ ]) %>
@@ -1,2 +1,2 @@
1
- <h1>Simple Event Members Filter</h1>
1
+ <h1>Basic Filter with EventMember Model</h1>
2
2
  <%= render :partial=> "/common/event_members" %>
@@ -1,3 +1,3 @@
1
- <h1>Simple Events Filter</h1>
1
+ <h1>Basic Filter with Event Model</h1>
2
2
  <%= render :partial=> "/common/events" %>
3
3
 
@@ -1,2 +1,2 @@
1
- <h1>Simple Users Filter</h1>
1
+ <h1>Basic Filter with User Model</h1>
2
2
  <%= render :partial=> "/common/users" %>
data/will_filter.gemspec CHANGED
@@ -13,8 +13,6 @@ Gem::Specification.new do |s|
13
13
  s.summary = "A filtering engine plugin for Rails 3.1"
14
14
  s.description = "will_filter is a powerful customizable framework for filtering active_record models."
15
15
 
16
- s.rubyforge_project = 'will_filter'
17
-
18
16
  s.files = `git ls-files`.split("\n")
19
17
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
20
18
  s.extra_rdoc_files = ['README.rdoc']
@@ -22,17 +20,15 @@ Gem::Specification.new do |s|
22
20
 
23
21
  s.licenses = ['MIT']
24
22
 
25
- s.add_dependency 'rails', ['>= 3.1.0']
23
+ s.add_dependency 'rails', ['>= 3.2.3']
26
24
  s.add_dependency 'kaminari', ['>= 0']
27
25
  s.add_dependency 'sass', ['>= 0']
28
- s.add_dependency 'coffee-script', ['>= 0']
26
+ s.add_development_dependency 'pry', ['>= 0']
29
27
  s.add_development_dependency 'bundler', ['>= 1.0.0']
30
28
  s.add_development_dependency 'sqlite3', ['>= 0']
31
29
  s.add_development_dependency 'rspec', ['>= 0']
32
- s.add_development_dependency 'rspec-rails', ['>= 0']
33
- s.add_development_dependency 'factory_girl', ['>= 0']
30
+ s.add_development_dependency 'rspec-rails', ['>= 2.1.0']
31
+ s.add_development_dependency 'spork', ['>= 0']
32
+ s.add_development_dependency 'watchr', ['>= 0']
34
33
  s.add_development_dependency 'rr', ['>= 0']
35
- s.add_development_dependency 'steak', ['>= 0']
36
- s.add_development_dependency 'capybara', ['>= 0']
37
- s.add_development_dependency 'database_cleaner', ['>= 0']
38
34
  end