search_fu 0.0.8.beta → 0.9.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/lib/search_fu.rb CHANGED
@@ -1,4 +1,4 @@
1
- require 'search_fu/model_additions'
2
1
  require 'search_fu/view_helper'
2
+ require 'search_fu/model_additions'
3
3
  require 'search_fu/controller_additions'
4
4
 
@@ -1,127 +1,132 @@
1
+ require 'search_fu_attributes'
2
+
1
3
  module SearchFu
2
- module ModelAdditions
3
- def self.included(base)
4
- base.extend ClassMethods
5
- base.class_eval do
6
- attr_accessor :_search_fu_attributes
7
- end
4
+
5
+ def self.included(base)
6
+ base.extend ClassMethods
7
+ end
8
+
9
+ module ClassMethods
10
+
11
+ def search_fu name, view_name=nil, query=nil
12
+ @search_fu_attrs ||= SearchFuAttributes.new
13
+ @search_fu_attrs << SearchFuAttribute.new(name, view_name, query)
8
14
  end
9
15
 
10
- module ClassMethods
11
- def search(hash)
12
- rtnval = respond_to?(:search_fu_before) ? search_fu_before : where("1=1")
13
- return rtnval unless hash
14
- @rel = [%q(where("1=1"))]
15
- hash.each do |k,v|
16
- search_fu_attr = @_search_fu_attributes.detect { |t| t[:name] == v[:name]}
17
- raise "Column '#{v[:name]}' not found." unless search_fu_attr
18
- @rel << generate_where(search_fu_attr, v[:value])
19
- end
20
- rtnval.instance_eval(@rel.join('.'))
21
- end
16
+ def search params={}
17
+ output = respond_to?(:search_fu_before) ? search_fu_before : where(nil)
18
+ params.each do |k, v|
19
+ query = search_fu_query(v[:name]).call(v[:value])
20
+ output = output.nil? ? query : output.merge(query)
21
+ end if params
22
+ output
23
+ end
22
24
 
23
- def search_fu_names
24
- a = []
25
- @_search_fu_attributes.each do |h|
26
- a << h[:name]
27
- end
28
- a
29
- end
25
+ def search_fu_view_names
26
+ @search_fu_attrs.view_names
27
+ end
30
28
 
31
- def search_fu(*args)
32
- @_search_fu_attributes ||= []
33
- c_attr = create_search_fu_attribute_hash(*args)
34
- @_search_fu_attributes << c_attr unless @_search_fu_attributes.detect { |t| t[:name] == c_attr[:name]}
35
- end
29
+ def eval_text text, *term
30
+ op_text = replace_operator_tag_with_sql_operator(text, term.join)
31
+ op_val_text = replace_value_tag_with_eval_text(op_text, term.join)
32
+ class_eval op_val_text
33
+ end
36
34
 
37
- private
38
-
39
- def generate_where(attr, value)
40
- a = grab_operator_value(value)
41
- op = a[0] || attr[:operator]
42
- return %q(where("1=1")) if a[1].blank?
43
- val = assign_like(op, a[1])
44
- val = attr[:convert].call(op, a[1]) if attr[:convert]
45
- if attr[:ar_query].class == Proc
46
- w = attr[:ar_query].call
47
- else
48
- w = attr[:ar_query]
49
- end
50
- w.gsub(/<op>/, op).gsub(/<value>/, val)
35
+ def where sql, *term
36
+ if use_fu_where? sql
37
+ op_sql = replace_operator_tag_with_sql_operator(sql, term.join)
38
+ op_val_sql = replace_value_tag_with_sql_value(op_sql, term.join)
39
+ super op_val_sql
40
+ else
41
+ super
51
42
  end
43
+ end
52
44
 
53
- def assign_like(op, val)
54
- op == "like" ? "%#{val.to_s}%" : val.to_s
55
- end
45
+ private
56
46
 
57
- def grab_operator_value(value)
58
- a = value.split(' ')
59
- operator = to_arel_operator(a[0])
60
- a.delete_at(0) if operator
61
- [operator, a.join(' ')]
62
- end
47
+ def search_fu_query name
48
+ query = @search_fu_attrs.find!(name).query || generate_query(name)
49
+ end
63
50
 
64
- def to_arel_operator(val)
65
- {"~" => "like", "=" => "=", ">=" => ">=", "<=" => "<=", "<" => "<", ">" => ">", "<>" => "<>"}[val]
66
- end
51
+ def generate_query name
52
+ colname = @search_fu_attrs.find!(name).column_name
53
+ lambda { |val| where("#{table_name}.#{colname} <_op_> <_val_>", val) }
54
+ end
67
55
 
68
- def create_search_fu_attribute_hash(*args)
69
- # args[0] - column name, args[1] - view name, args[3] - search_fu hash
70
- # args[0] - view name, args[1] - search_fu_hash
71
- # args[0] - column name, args[1] - view name
72
- # args[0] - column name
73
- hash = {}
74
- hash = args.delete args.last if args.last.class == Hash
75
-
76
- if args.size == 2
77
- search_fu_attribute_hash(args[1], ar_query(args[0], hash))
78
- elsif args.size == 1
79
- search_fu_attribute_hash(args[0].to_s.humanize, ar_query(args[0], hash))
80
- end
81
- end
56
+ def operator_hash
57
+ { "~" => "like", "=" => "=", "=>" => ">=", "=<" => "<=", ">=" => ">=",
58
+ "<=" => "<=", "<" => "<", ">" => ">", "<>" => "<>", "!=" => "<>" }
59
+ end
60
+
61
+ def operator_regexp
62
+ Regexp.new("^(" + operator_hash.map {|k, v| k }.sort_by {|t| 15 - t.length }.join("|") + ")?(.+)?")
63
+ end
82
64
 
83
- def ar_query(col_name, hash)
84
- arq = hash[:ar_query]
85
- operator = hash[:operator]
86
- converter = hash[:convert]
87
- col = columns.detect { |t| t.name == col_name.to_s }
88
- if col
89
- case
90
- when col.type == :string || col.type == :text
91
- operator ||= 'like'
92
- arq ||= %Q(where("upper(#{self.table_name}.#{col_name}) <op> upper('<value>')"))
93
- when col.type == :datetime || col.type == :date
94
- converter ||= Proc.new{ |op, val| Date.parse(val.to_s).to_s(:db) }
95
- arq ||= %Q(where("#{self.table_name}.#{col_name} <op> '<value>'"))
96
- when col.type == :decimal || col.type == :integer
97
- arq ||= %Q(where("#{self.table_name}.#{col_name} <op> <value>"))
98
- when col.type == :boolean
99
- converter ||= Proc.new { |op, val| ['t', 'y', 'true', 'yes'].include?(val.downcase) ? 'true' : 'false' }
100
- arq ||= %Q(where("#{self.table_name}.#{col_name} <op> <value>"))
101
- end
102
- end
103
- hsh = {}
104
- hsh.merge!(ar_query: arq)
105
- hsh.merge!(operator: operator || "=")
106
- hsh.merge!(convert: converter)
107
- return hsh
65
+ def replace_value_tag_with_eval_text string, term
66
+ value = to_sql_value(grab_value_from(term), to_sql_operator(grab_operator_from(term)), true)
67
+ return string.gsub(/\<_val_\>/, value) if value
68
+ string
69
+ end
70
+
71
+ def replace_value_tag_with_sql_value string, term
72
+ value = to_sql_value(grab_value_from(term), to_sql_operator(grab_operator_from(term)))
73
+ return string.gsub(/\<_val_\>/, value) if value
74
+ string
75
+ end
76
+
77
+ def replace_operator_tag_with_sql_operator string, term
78
+ string.gsub /\<_op_\>/, to_sql_operator(grab_operator_from(term))
79
+ end
80
+
81
+ def operator_by_value_type val
82
+ parse_float(val) || parse_date(val) ? "=" : "~" if val
83
+ end
84
+
85
+ def grab_value_from term
86
+ term.scan(operator_regexp).flatten.map { |t| t.nil? ? t : t.strip }[1]
87
+ end
88
+
89
+ def to_sql_value val, operator, no_wild_card=false
90
+ if operator != 'like' and val
91
+ parse_float(val) || parse_date(val) || "'#{val}'"
92
+ else
93
+ no_wild_card ? "'#{val}'" : "'%#{val}%'"
108
94
  end
95
+ end
109
96
 
110
- def search_fu_attribute_hash(name, hash)
111
- raise "No Query found in hash!" unless hash[:ar_query]
112
- {
113
- name: name,
114
- ar_query: hash[:ar_query],
115
- operator: hash[:operator],
116
- convert: hash[:convert]
117
- }
97
+ def grab_operator_from term
98
+ term.scan(operator_regexp).flatten.map{ |t| t.nil? ? t : t.strip }[0] ||
99
+ operator_by_value_type(grab_value_from(term))
100
+ end
101
+
102
+ def parse_float value
103
+ (Float value).to_s
104
+ rescue ArgumentError
105
+ nil
106
+ end
107
+
108
+ def parse_date value
109
+ regex = /^(\d{1,2}(\/|\-|\.)\d{1,2}(\/|\-|\.)\d{4})$|^(\d{4}(\/|\-|\.)\d{1,2}(\/|\-|\.)\d{1,2})$|^(\d{1,2}(\/|\-|\.)[a-z]{3}(\/|\-|\.)\d{4}$)/
110
+ if value =~ regex
111
+ "'#{Date.parse(value).to_s(:db)}'"
112
+ else
113
+ nil
118
114
  end
115
+ end
119
116
 
117
+ def to_sql_operator(val)
118
+ return '' if val.nil?
119
+ operator_hash[val]
120
120
  end
121
+
122
+ def use_fu_where? opts
123
+ if opts.kind_of? String
124
+ opts.scan(/\<_op_\>|\<_val_\>/).count > 0 ? true : false
125
+ else
126
+ false
127
+ end
128
+ end
129
+
121
130
  end
122
- end
123
131
 
124
- if defined?(ActiveRecord::Base)
125
- ActiveRecord::Base.send :include, SearchFu::ModelAdditions
126
132
  end
127
-
@@ -1,4 +1,4 @@
1
1
  module SearchFu
2
- VERSION = "0.0.8.beta"
2
+ VERSION = "0.9.0"
3
3
  end
4
4
 
@@ -27,7 +27,7 @@ module SearchFu
27
27
  (session["#{model_klass.name.underscore}_search_fu"] || params[:search_fu] || {}).each do |k,v|
28
28
  rand_id = (DateTime.now.to_i * rand * 100).to_i
29
29
  html << content_tag(:tr, id: "search_fu_row_new_#{rand_id}", class: "search_fu_rows") do
30
- content_tag(:td, select_tag("search_fu[_new_#{rand_id}][name]", options_for_select(model_klass.search_fu_names, v[:name]))) +
30
+ content_tag(:td, select_tag("search_fu[_new_#{rand_id}][name]", options_for_select(model_klass.search_fu_view_names, v[:name]))) +
31
31
  content_tag(:td, text_field_tag("search_fu[_new_#{rand_id}][value]", v[:value])) +
32
32
  content_tag(:td, link_to("X", "#", class: "search_fu_remove #{remove_button_class}"))
33
33
  end
@@ -53,7 +53,7 @@ module SearchFu
53
53
  content_tag(:table, style: "display:none") do
54
54
  content_tag(:tbody, id: "hidden_search_fields") do
55
55
  content_tag(:tr, id: "search_fu_row_NEW_", class: "search_fu_rows") do
56
- content_tag(:td, select_tag("search_fu[_NEW_][name]", options_for_select(model_klass.search_fu_names))) +
56
+ content_tag(:td, select_tag("search_fu[_NEW_][name]", options_for_select(model_klass.search_fu_view_names))) +
57
57
  content_tag(:td, text_field_tag("search_fu[_NEW_][value]")) +
58
58
  content_tag(:td, link_to("X", "#", class: "search_fu_remove #{remove_button_class}"))
59
59
  end
@@ -0,0 +1,25 @@
1
+ require 'active_support'
2
+
3
+ class SearchFuAttribute
4
+ attr_accessor :column_name, :view_name, :query
5
+
6
+ def initialize name, view_name=nil, query=nil
7
+ @column_name = name
8
+ @view_name = humanzie_symbol name
9
+ @query = query if query
10
+ @query = view_name if view_name.respond_to? :call
11
+ if view_name and !view_name.respond_to? :call
12
+ @view_name = humanzie_symbol view_name
13
+ end
14
+ end
15
+
16
+ private
17
+ def humanzie_symbol name
18
+ if name.kind_of? Symbol
19
+ ActiveSupport::Inflector.humanize name.to_s
20
+ else
21
+ name
22
+ end
23
+ end
24
+ end
25
+
@@ -0,0 +1,33 @@
1
+ require 'search_fu_attribute'
2
+
3
+ class SearchFuAttributes < Array
4
+ class DuplicateViewName < RuntimeError; end
5
+ class NotSearchFuAttribute < RuntimeError; end
6
+ class ViewNameNotFound < RuntimeError; end
7
+
8
+ def << value
9
+ raise NotSearchFuAttribute if !value.kind_of? SearchFuAttribute
10
+ if find value.view_name
11
+ raise DuplicateViewName
12
+ else
13
+ super
14
+ end
15
+ end
16
+
17
+ def view_names
18
+ self.map { |t| t.view_name }
19
+ end
20
+
21
+ def find view_name
22
+ self.detect { |t| t.view_name == view_name }
23
+ end
24
+
25
+ def find! view_name
26
+ a = find view_name
27
+ raise ViewNameNotFound unless a
28
+ a
29
+ end
30
+
31
+ end
32
+
33
+
data/search_fu.gemspec CHANGED
@@ -21,6 +21,7 @@ Gem::Specification.new do |s|
21
21
 
22
22
  s.add_development_dependency "sqlite3"
23
23
  s.add_development_dependency "rspec"
24
+ s.add_development_dependency "rake"
24
25
  s.add_dependency 'activerecord'
25
26
  s.add_dependency 'actionpack'
26
27
  end
@@ -0,0 +1,135 @@
1
+ require 'active_record'
2
+ require 'search_fu'
3
+ require 'spec_helper'
4
+
5
+ describe "SearchFu module" do
6
+ class Payment < ActiveRecord::Base
7
+ include SearchFu
8
+ belongs_to :account
9
+ scope :search_fu_before, where("10=10")
10
+ search_fu :note, "Description"
11
+ search_fu "Debit Account Name", lambda { |val| where("accounts.name1 <_op_> <_val_>", val).joins(:account) }
12
+ search_fu "Credit Account Name", lambda { |val| eval_text(%(where("note <_op_> <_val_>")), val) }
13
+ end
14
+
15
+ class Account < ActiveRecord::Base
16
+ include SearchFu
17
+ has_many :payments
18
+ search_fu :name1, lambda { |val| where("name1 <_op_> <_val_>", val) }
19
+ search_fu :name2, lambda { |val| where("name2 <_op_> <_val_>", val) }
20
+ search_fu :status, "Current Status"
21
+ search_fu :description
22
+ end
23
+
24
+ it "#search should retrun where(nil) if params == nil or params not provided" do
25
+ Account.search.to_sql.should == Account.where(nil).to_sql
26
+ Account.search(nil).to_sql.should == Account.where(nil).to_sql
27
+ end
28
+
29
+ it "search_fu_before should be where(nil) if not provided" do
30
+ Account.search.to_sql.should == Account.where(nil).to_sql
31
+ end
32
+
33
+ it "eval_text should change op val and eval result" do
34
+ Payment.search( a: { name: "Credit Account Name", value: "haha" } ).to_sql.should ==
35
+ Payment.where("10=10").where("note like 'haha'").to_sql
36
+ end
37
+
38
+ it "should combine search_fu_before scope, if exists" do
39
+ Payment.search( a: { name: "Debit Account Name", value: "haha" } ).to_sql.should ==
40
+ Payment.where("10=10").where("accounts.name1 like '%haha%'").joins(:account).to_sql
41
+ end
42
+
43
+ context "#search" do
44
+ context "will generate default query" do
45
+ it "if not provided, type C" do
46
+ Payment.search( a: { name: "Debit Account Name", value: "haha" } ).to_sql.should ==
47
+ Payment.where("10=10").where("accounts.name1 like '%haha%'").joins(:account).to_sql
48
+ end
49
+
50
+ it "if not provided, type A" do
51
+ Account.search( a: { name: "Current Status", value: "haha" } ).to_sql.should ==
52
+ Account.where("accounts.status like '%haha%'").to_sql
53
+ end
54
+
55
+ it "if not provided, type B" do
56
+ Account.search( a: { name: "Description", value: "haha" } ).to_sql.should ==
57
+ Account.where("accounts.description like '%haha%'").to_sql
58
+ end
59
+ end
60
+
61
+ it "should return ActiveRecord::Relation" do
62
+ Account.search( a: { name: "Name1", value: "stuff" }).class.should == ActiveRecord::Relation
63
+ end
64
+
65
+ it "should call search_fu lambda" do
66
+ Account.search( a: { name: "Name1", value: "stuff" }).to_sql.should ==
67
+ Account.where("name1 like '%stuff%'").to_sql
68
+ end
69
+
70
+ it "should combine lambda if more than 1 search_fu params" do
71
+ Account.search(a: { name: "Name1", value: "stuff"}, b: { name: "Name2", value: "stuff1"}).to_sql.should ==
72
+ Account.where("name1 like '%stuff%'").where("name2 like '%stuff1%'").to_sql
73
+ end
74
+ end
75
+
76
+ context "#where should provide default operator" do
77
+ it "= for numeric value and convert value to float" do
78
+ Account.where("name1 <_op_> <_val_>", "32").to_sql.should ==
79
+ Account.where("name1 = 32.0").to_sql
80
+ end
81
+
82
+ it "= for date value and convert value to db date format" do
83
+ Account.where("name1 <_op_> <_val_>", "31-dec-2011").to_sql.should ==
84
+ Account.where("name1 = '2011-12-31'").to_sql
85
+ end
86
+
87
+ it "like for string value and convert value to %value%" do
88
+ Account.where("name1 <_op_> <_val_>", "jimmy").to_sql.should ==
89
+ Account.where("name1 like '%jimmy%'").to_sql
90
+ end
91
+ end
92
+
93
+ context "#where replace <_val_>" do
94
+ it "should quote string" do
95
+ Account.where("name1 <_op_> <_val_>", "= somevalue").to_sql.should ==
96
+ Account.where("name1 = 'somevalue'").to_sql
97
+ end
98
+
99
+ it "should convert and quote date" do
100
+ Account.where("name1 <_op_> <_val_>", "= 31-dec-2011").to_sql.should ==
101
+ Account.where("name1 = '2011-12-31'").to_sql
102
+ end
103
+
104
+ it "should convert to float and not quote numeric" do
105
+ Account.where("name1 <_op_> <_val_>", "= 2011").to_sql.should ==
106
+ Account.where("name1 = 2011.0").to_sql
107
+ end
108
+ end
109
+
110
+ context "#where should replace <_op_>" do
111
+ { "~" => "like", "=" => "=", "=>" => ">=", "=<" => "<=", ">=" => ">=", "<=" => "<=",
112
+ "<" => "<", ">" => ">", "<>" => "<>", "!=" => "<>" }.each do |fc_op, sql_op|
113
+ it "#{fc_op} to #{sql_op}" do
114
+ Account.where("name1 <_op_> 'somevalue'", "#{fc_op}").to_sql.should ==
115
+ Account.where("name1 #{sql_op} 'somevalue'").to_sql
116
+ end
117
+ end
118
+ end
119
+
120
+ it "#where should not replace <_op_> if not provided" do
121
+ Account.where("name1 <_op_> 'somevalue'", '').to_sql.should ==
122
+ Account.where("name1 <_op_> 'somevalue'").to_sql
123
+ end
124
+
125
+ it "#where should not replace operator if no <_op_>" do
126
+ Account.where("name1 = 'somevalue'", '<>').to_sql.should ==
127
+ Account.where("name1 = 'somevalue'").to_sql
128
+ end
129
+
130
+ it "#search_fu_view_names should has a view_names" do
131
+ Account.search_fu_view_names.should == ["Name1", "Name2", "Current Status", "Description"]
132
+ Payment.search_fu_view_names.should == ["Description", "Debit Account Name", "Credit Account Name"]
133
+ end
134
+
135
+ end
data/spec/schema.rb CHANGED
@@ -3,26 +3,17 @@ ActiveRecord::Schema.define do
3
3
  create_table "accounts", :force => true do |t|
4
4
  t.string "name1", :null => false
5
5
  t.string "name2"
6
- t.integer "institution_id", :null => false
7
- t.string "account_type_id", :null => false
8
6
  t.text "description"
9
7
  t.string "status", :default => "Active"
10
8
  t.integer "lock_version"
11
9
  end
12
10
 
13
11
  create_table "payments", :force => true do |t|
14
- t.integer "institution_id"
15
12
  t.date "date"
16
13
  t.string "collector"
17
14
  t.integer "to_account_id"
18
15
  t.integer "from_account_id"
19
- t.string "cheque_no"
20
- t.date "cheque_date"
21
- t.string "currency"
22
16
  t.integer "c_amount", :default => 0
23
- t.integer "charges_account_id"
24
- t.string "charges_particulars"
25
- t.integer "c_charges_amount", :default => 0
26
17
  t.text "note"
27
18
  t.string "status"
28
19
  t.integer "lock_version", :default => 0
@@ -0,0 +1,51 @@
1
+ require 'search_fu_attribute'
2
+
3
+ describe SearchFuAttribute do
4
+
5
+ it "should have attr_accessor :view_name" do
6
+ SearchFuAttribute.new(:haha).respond_to?(:view_name).should be_true
7
+ SearchFuAttribute.new(:haha).respond_to?(:view_name=).should be_true
8
+ end
9
+
10
+ it "should have attr_accessor :query" do
11
+ SearchFuAttribute.new(:haha).respond_to?(:query).should be_true
12
+ SearchFuAttribute.new(:haha).respond_to?(:query=).should be_true
13
+ end
14
+
15
+ context "initialize" do
16
+
17
+ it "" do
18
+ SearchFuAttribute.new(:haha_baba).view_name.should == "Haha baba"
19
+ end
20
+
21
+ context "name != nil, view_name != nil, query == nil" do
22
+ it "should store humanize view_name or plain view_name" do
23
+ SearchFuAttribute.new(:haha, "HAHA BABA").view_name.should == "HAHA BABA"
24
+ SearchFuAttribute.new(:haha, :mama_papa).view_name.should == "Mama papa"
25
+ end
26
+ end
27
+
28
+ context "name != nil, view_name == query, query == nil" do
29
+ it "should store humanize name as view_name and store view_name as query" do
30
+ a = SearchFuAttribute.new("HAHA BABA", lambda { 123 })
31
+ a.view_name.should == "HAHA BABA"
32
+ a.query.call.should == 123
33
+ b = SearchFuAttribute.new(:mama_papa, lambda { 321})
34
+ b.view_name.should == "Mama papa"
35
+ b.query.call.should == 321
36
+ end
37
+ end
38
+
39
+ context "name != nil, view_name != nil, query != nil" do
40
+ it "should store view_name and store query" do
41
+ a = SearchFuAttribute.new(:haha, "HAHA BABA", lambda { 123 })
42
+ a.view_name.should == "HAHA BABA"
43
+ a.query.call.should == 123
44
+ b = SearchFuAttribute.new(:haha, :mama_papa, lambda { 321})
45
+ b.view_name.should == "Mama papa"
46
+ b.query.call.should == 321
47
+ end
48
+ end
49
+
50
+ end
51
+ end
@@ -0,0 +1,73 @@
1
+ require 'search_fu_attributes'
2
+ require 'search_fu_attribute'
3
+
4
+ describe SearchFuAttributes do
5
+
6
+ it "should raise error if insert class is not SearchFuAttribute" do
7
+ a = SearchFuAttributes.new
8
+ expect do
9
+ a << "fdsfsa"
10
+ end.to raise_error SearchFuAttributes::NotSearchFuAttribute
11
+ end
12
+
13
+ it "should not raise error if insert class is SearchFuAttribute" do
14
+ a = SearchFuAttributes.new
15
+ expect do
16
+ a << SearchFuAttribute.new(:fdsfas)
17
+ end.not_to raise_error SearchFuAttributes::NotSearchFuAttribute
18
+ end
19
+
20
+ it "should raise error if duplicate view_name was added" do
21
+ a = SearchFuAttributes.new
22
+ a << SearchFuAttribute.new(:aaaa)
23
+ expect do
24
+ a << SearchFuAttribute.new(:aaaa)
25
+ end.to raise_error SearchFuAttributes::DuplicateViewName
26
+ a.count.should == 1
27
+ end
28
+
29
+ it "should not raise error if not duplicate view_name was added" do
30
+ a = SearchFuAttributes.new
31
+ a << SearchFuAttribute.new(:aaaa)
32
+ a << SearchFuAttribute.new(:bbbb)
33
+ a.count.should == 2
34
+ end
35
+
36
+ it "find should return nil" do
37
+ a = SearchFuAttributes.new
38
+ a << SearchFuAttribute.new(:aaaa)
39
+ a << SearchFuAttribute.new(:bbbb)
40
+ a.find("AAAA").should be_nil
41
+ end
42
+
43
+ it "find should return Aaaa" do
44
+ a = SearchFuAttributes.new
45
+ a << SearchFuAttribute.new(:aaaa)
46
+ a << SearchFuAttribute.new(:bbbb)
47
+ a.find("Aaaa").should == a[0]
48
+ end
49
+
50
+ it "find! should raise error" do
51
+ a = SearchFuAttributes.new
52
+ a << SearchFuAttribute.new(:aaaa)
53
+ a << SearchFuAttribute.new(:bbbb)
54
+ expect { a.find!("AAAA") }.to raise_error SearchFuAttributes::ViewNameNotFound
55
+ end
56
+
57
+ it "find! should return Aaaa" do
58
+ a = SearchFuAttributes.new
59
+ a << SearchFuAttribute.new(:aaaa)
60
+ a << SearchFuAttribute.new(:bbbb)
61
+ a.find!("Aaaa").should == a[0]
62
+ end
63
+
64
+ it "view_names should return Aaaa" do
65
+ a = SearchFuAttributes.new
66
+ a << SearchFuAttribute.new(:aaaa)
67
+ a << SearchFuAttribute.new(:bbbb)
68
+ a.view_names.should == ["Aaaa", "Bbbb"]
69
+ end
70
+
71
+ end
72
+
73
+
data/spec/spec_helper.rb CHANGED
@@ -1,6 +1,4 @@
1
- require 'rubygems'
2
1
  require 'active_record'
3
- require 'search_fu'
4
2
 
5
3
  ActiveRecord::Base.establish_connection(
6
4
  :adapter => 'sqlite3',
@@ -14,21 +12,4 @@ end
14
12
 
15
13
  RSpec.configure do |config|
16
14
  config.mock_with :rspec
17
- config.before(:each) do
18
- Payment.delete_all
19
- Account.delete_all
20
- end
21
15
  end
22
-
23
- class Payment < ActiveRecord::Base
24
- belongs_to :to_account, :class_name => "Account", :foreign_key => :to_account_id
25
- belongs_to :from_account, :class_name => "Account", :foreign_key => :from_account_id
26
- belongs_to :charges_account, :class_name => "Account", :foreign_key => :charges_account_id
27
- end
28
-
29
- class Account < ActiveRecord::Base
30
- has_many :to_payments, :class_name => 'Payment', :foreign_key => 'to_account_id'
31
- has_many :from_payments, :class_name => 'Payment', :foreign_key => 'from_account_id'
32
- has_many :charges_payments, :class_name => 'Payment', :foreign_key => 'charges_account_id'
33
- end
34
-
metadata CHANGED
@@ -1,19 +1,19 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: search_fu
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.8.beta
5
- prerelease: 6
4
+ version: 0.9.0
5
+ prerelease:
6
6
  platform: ruby
7
7
  authors:
8
8
  - Tan Kwang How
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-02-05 00:00:00.000000000 Z
12
+ date: 2012-04-14 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: sqlite3
16
- requirement: &77688230 !ruby/object:Gem::Requirement
16
+ requirement: !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,15 @@ dependencies:
21
21
  version: '0'
22
22
  type: :development
23
23
  prerelease: false
24
- version_requirements: *77688230
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
25
30
  - !ruby/object:Gem::Dependency
26
31
  name: rspec
27
- requirement: &77688020 !ruby/object:Gem::Requirement
32
+ requirement: !ruby/object:Gem::Requirement
28
33
  none: false
29
34
  requirements:
30
35
  - - ! '>='
@@ -32,10 +37,31 @@ dependencies:
32
37
  version: '0'
33
38
  type: :development
34
39
  prerelease: false
35
- version_requirements: *77688020
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: rake
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
36
62
  - !ruby/object:Gem::Dependency
37
63
  name: activerecord
38
- requirement: &77687810 !ruby/object:Gem::Requirement
64
+ requirement: !ruby/object:Gem::Requirement
39
65
  none: false
40
66
  requirements:
41
67
  - - ! '>='
@@ -43,10 +69,15 @@ dependencies:
43
69
  version: '0'
44
70
  type: :runtime
45
71
  prerelease: false
46
- version_requirements: *77687810
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
47
78
  - !ruby/object:Gem::Dependency
48
79
  name: actionpack
49
- requirement: &77687600 !ruby/object:Gem::Requirement
80
+ requirement: !ruby/object:Gem::Requirement
50
81
  none: false
51
82
  requirements:
52
83
  - - ! '>='
@@ -54,7 +85,12 @@ dependencies:
54
85
  version: '0'
55
86
  type: :runtime
56
87
  prerelease: false
57
- version_requirements: *77687600
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
58
94
  description: A ActiveRecord method to allow user specify and combine query in views
59
95
  email:
60
96
  - tankwanghow@gmail.com
@@ -72,9 +108,13 @@ files:
72
108
  - lib/search_fu/model_additions.rb
73
109
  - lib/search_fu/version.rb
74
110
  - lib/search_fu/view_helper.rb
111
+ - lib/search_fu_attribute.rb
112
+ - lib/search_fu_attributes.rb
75
113
  - search_fu.gemspec
114
+ - spec/model_additions_spec.rb
76
115
  - spec/schema.rb
77
- - spec/search_fu_spec.rb
116
+ - spec/search_fu_attribute_spec.rb
117
+ - spec/search_fu_attributes_spec.rb
78
118
  - spec/spec_helper.rb
79
119
  homepage: http://github.com/tankwanghow
80
120
  licenses: []
@@ -88,15 +128,21 @@ required_ruby_version: !ruby/object:Gem::Requirement
88
128
  - - ! '>='
89
129
  - !ruby/object:Gem::Version
90
130
  version: '0'
131
+ segments:
132
+ - 0
133
+ hash: -403552339
91
134
  required_rubygems_version: !ruby/object:Gem::Requirement
92
135
  none: false
93
136
  requirements:
94
- - - ! '>'
137
+ - - ! '>='
95
138
  - !ruby/object:Gem::Version
96
- version: 1.3.1
139
+ version: '0'
140
+ segments:
141
+ - 0
142
+ hash: -403552339
97
143
  requirements: []
98
144
  rubyforge_project: search_fu
99
- rubygems_version: 1.8.10
145
+ rubygems_version: 1.8.21
100
146
  signing_key:
101
147
  specification_version: 3
102
148
  summary: Combine query in views
@@ -1,31 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe SearchFu::ModelAdditions do
4
- describe '.search_fu_attribute_hash' do
5
- it "should raise error if hash[:ar_query] not found" do
6
- lambda { SearchFu.search_fu_attribute_hash('name', {}) }.should raise_error("No Query found in hash!")
7
- end
8
-
9
- it "should not rails error if hash[:ar_query] exists" do
10
- lambda { SearchFu.search_fu_attribute_hash('name', ar_query: 3) }.should_not raise_error("No Query found in hash!")
11
- end
12
-
13
- describe 'return hash' do
14
- it "should be hashed correctly" do
15
- SearchFu.search_fu_attribute_hash("stuff", ar_query: 'haha').should ==
16
- { name: 'stuff', ar_query: 'haha', operator: nil, convert: nil }
17
-
18
- SearchFu.search_fu_attribute_hash("stuff", ar_query: 'haha', operator: 'kaka').should ==
19
- { name: 'stuff', ar_query: 'haha', operator: 'kaka', convert: nil }
20
-
21
- SearchFu.search_fu_attribute_hash("stuff", ar_query: 'haha', convert: 'caca').should ==
22
- { name: 'stuff', ar_query: 'haha', operator: nil, convert: 'caca' }
23
-
24
- SearchFu.search_fu_attribute_hash("stuff", ar_query: 'haha', convert: 'caca', operator: 'kaka' ).should ==
25
- { name: 'stuff', ar_query: 'haha', operator: 'kaka', convert: 'caca' }
26
- end
27
- end
28
- end
29
-
30
- end
31
-