acts_as_filterable 0.1.4 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc CHANGED
@@ -11,7 +11,7 @@ I'd like to expand the ruleset moving forward to support different schemes like
11
11
 
12
12
  == Install as a gem:
13
13
 
14
- config.gem "rares-acts_as_filterable", :source => "http://gems.github.com"
14
+ config.gem "acts_as_filterable", :source => "http://gemcutter.org"
15
15
 
16
16
  == To apply to fields on a model, add the following inside the class body:
17
17
 
data/Rakefile CHANGED
@@ -1,19 +1,18 @@
1
- require "rubygems"
2
1
  require "rake"
3
2
 
4
3
  begin
5
4
  require "jeweler"
6
5
  Jeweler::Tasks.new do |gem|
7
6
  gem.name = "acts_as_filterable"
8
- gem.summary = %Q{TODO}
7
+ gem.summary = %Q{Filter attributes and stuff.}
9
8
  gem.email = "rob.ares@gmail.com"
10
9
  gem.homepage = "http://github.com/rares/acts_as_filterable"
11
10
  gem.authors = ["Rob Ares"]
12
11
 
13
12
  gem.add_dependency("activerecord", ">= 1.15.0")
14
13
  gem.add_runtime_dependency("activesupport", ">= 1.4.4")
15
- gem.add_development_dependency("Shoulda")
16
- gem.add_development_dependency("matchy")
14
+ gem.add_development_dependency("Shoulda", ">= 0")
15
+ gem.add_development_dependency("matchy", ">= 0")
17
16
  end
18
17
  rescue LoadError
19
18
  puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
data/VERSION.yml CHANGED
@@ -1,4 +1,4 @@
1
1
  ---
2
2
  :major: 0
3
- :minor: 1
4
- :patch: 4
3
+ :minor: 2
4
+ :patch: 0
@@ -1,12 +1,15 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run `rake gemspec`
1
4
  # -*- encoding: utf-8 -*-
2
5
 
3
6
  Gem::Specification.new do |s|
4
7
  s.name = %q{acts_as_filterable}
5
- s.version = "0.1.4"
8
+ s.version = "0.2.0"
6
9
 
7
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
11
  s.authors = ["Rob Ares"]
9
- s.date = %q{2009-09-08}
12
+ s.date = %q{2009-10-29}
10
13
  s.email = %q{rob.ares@gmail.com}
11
14
  s.extra_rdoc_files = [
12
15
  "LICENSE",
@@ -25,16 +28,17 @@ Gem::Specification.new do |s|
25
28
  "lib/acts_as_filterable/base.rb",
26
29
  "rails/init.rb",
27
30
  "test/acts_as_filterable_integration_test.rb",
31
+ "test/filter_test.rb",
28
32
  "test/test_helper.rb"
29
33
  ]
30
- s.has_rdoc = true
31
34
  s.homepage = %q{http://github.com/rares/acts_as_filterable}
32
35
  s.rdoc_options = ["--charset=UTF-8"]
33
36
  s.require_paths = ["lib"]
34
- s.rubygems_version = %q{1.3.2}
35
- s.summary = %q{An ActiveRecord plugin that allows attribute-based filtering in order to normalize numeric data}
37
+ s.rubygems_version = %q{1.3.5}
38
+ s.summary = %q{Filter attributes and stuff.}
36
39
  s.test_files = [
37
40
  "test/acts_as_filterable_integration_test.rb",
41
+ "test/filter_test.rb",
38
42
  "test/test_helper.rb"
39
43
  ]
40
44
 
@@ -1,5 +1,12 @@
1
1
  module ActsAsFilterable
2
2
 
3
+ Filters = returning Hash.new([]) do |f|
4
+ f[:digits] = lambda { |attr| attr.gsub!(/[^\d]*/, "") }
5
+ f[:lowercase] = lambda { |attr| attr.downcase! }
6
+ f[:uppercase] = lambda { |attr| attr.upcase! }
7
+ f[:whitespace] = lambda { |attr| attr.gsub!(/\s+/, " "); attr.strip! }
8
+ end.freeze
9
+
3
10
  module ActiveRecordExt
4
11
 
5
12
  module Base
@@ -9,57 +16,38 @@ module ActsAsFilterable
9
16
  klazz.before_validation :apply_filters
10
17
  end
11
18
 
12
- private
13
-
14
- module Language
15
-
16
- def filter(&blk)
17
- instance_eval blk
18
- end
19
-
20
- def digits(*args)
21
- filtered_attributes[:digits] |= args unless args.empty?
22
- end
23
-
24
- def lowercase(*args)
25
- filtered_attributes[:lowercase] |= args unless args.empty?
26
- end
27
-
28
- end
29
-
30
19
  module ClassMethods
31
20
 
32
- def filter_for_digits(*args)
33
- filtered_attributes[:digits] |= args unless args.empty?
34
- end
35
-
36
- def filters
37
- @filters ||= returning(Hash.new([])) do |f|
38
- f[:digits] = Commands::Digits.new
39
- f[:lowercase] = Commands::Lowercase.new
40
- end.freeze
21
+ def self.extended(klazz)
22
+ ActsAsFilterable::Filters.each_key do |key|
23
+ klazz.class_eval <<-MACROS, __FILE__, __LINE__ + 1
24
+ def self.filter_for_#{key}(*args)
25
+ filtered_attributes[:#{key}] |= args unless args.empty?
26
+ end
27
+ MACROS
28
+ end
41
29
  end
42
30
 
43
31
  def filtered_attributes
44
32
  @filtered_attributes ||= Hash.new []
45
33
  end
46
-
34
+
47
35
  end
48
36
 
49
37
  protected
50
-
38
+
51
39
  def apply_filters
52
40
  self.class.filtered_attributes.each do |key, value|
53
41
  value.each do |attr|
54
- apply_filter self.class.filters[key], attr
42
+ apply_filter self, attr, ActsAsFilterable::Filters[key]
55
43
  end
56
44
  end
57
45
  end
58
46
 
59
47
  private
60
48
 
61
- def apply_filter(filter, attr)
62
- filter.apply self, attr
49
+ def apply_filter(record, attr, filter)
50
+ filter.call(record[attr]) if record[attr].is_a?(String)
63
51
  end
64
52
 
65
53
  end
@@ -1,7 +1,6 @@
1
1
  module ActsAsFilterable
2
2
  module ActiveRecordExt
3
3
  autoload :Base, "acts_as_filterable/base"
4
- autoload :Commands, "acts_as_filterable/commands"
5
4
  end
6
5
  end
7
6
 
@@ -1,7 +1,7 @@
1
1
  require "test_helper"
2
2
 
3
3
  class ActsAsFilterableIntegrationTest < Test::Unit::TestCase
4
-
4
+
5
5
  context "An ActiveRecord model using acts_as_filterable" do
6
6
  setup do
7
7
  @model = ContactDetail.new do |cd|
@@ -19,25 +19,13 @@ class ActsAsFilterableIntegrationTest < Test::Unit::TestCase
19
19
  ContactDetail.respond_to?(:filtered_attributes).should be(true)
20
20
  end
21
21
 
22
- should "make it's filters available" do
23
- ContactDetail.respond_to?(:filters).should be(true)
24
- end
25
-
26
- should "default filters that don't exist to an empty array" do
27
- ContactDetail.filters[:test].empty?.should be(true)
28
- end
29
-
30
- should "contain some filters initially" do
31
- ContactDetail.filters[:numeric].nil?.should_not be(true)
32
- end
33
-
34
- should "freeze the macro collection so it cannot be mutated" do
35
- lambda { ContactDetail.filters.store(:test, /./) }.should raise_error
36
- end
37
-
38
22
  should "add a macro to filter non-numeric values from string fields" do
39
23
  ContactDetail.respond_to?(:filter_for_digits).should be(true)
40
24
  end
25
+
26
+ should "add a macro to filter values to lowercase from string fields" do
27
+ ContactDetail.respond_to?(:filter_for_lowercase).should be(true)
28
+ end
41
29
 
42
30
  should "be savable with valid data" do
43
31
  @model.save.should be(true)
@@ -74,12 +62,12 @@ class ActsAsFilterableIntegrationTest < Test::Unit::TestCase
74
62
  end
75
63
  end
76
64
 
77
- context "with non-character attributes" do
65
+ context "with non-string attributes" do
78
66
  setup do
79
67
  ContactDetail.filter_for_digits :discount
80
68
  end
81
69
 
82
- should "not raise any errors due to a non-character attribute value" do
70
+ should "not raise any errors due to a non-string attribute value" do
83
71
  lambda { @model.valid? }.should_not raise_error
84
72
  end
85
73
 
@@ -90,7 +78,7 @@ class ActsAsFilterableIntegrationTest < Test::Unit::TestCase
90
78
 
91
79
  end
92
80
 
93
- context "with an attribute value that contains no non-numeric values to be stripped" do
81
+ context "with an attribute value that contains no values to be stripped" do
94
82
  setup do
95
83
  @model.phone_number = "2223334444"
96
84
  @model.valid?
@@ -104,15 +92,11 @@ class ActsAsFilterableIntegrationTest < Test::Unit::TestCase
104
92
  context "that has filtered attribute names that are identical to another filtered model" do
105
93
 
106
94
  should "hold seperate collections of filtered_attributes" do
107
- User.filtered_attributes.should_not == ContactDetail.filtered_attributes
95
+ User.filtered_attributes.should_not === ContactDetail.filtered_attributes
108
96
  end
109
97
 
110
- should "not overwrite attributes for other models" do
111
- ContactDetail.filtered_attributes.include?(:fax_number).should_not be(nil)
112
- end
113
-
114
- should "not add filtered attributes to models that they are not intended for" do
115
- User.filtered_attributes.include?(:phone_number).should_not be(true)
98
+ should "not add attributes to other models errantly" do
99
+ ContactDetail.filtered_attributes[:digits].should_not include(:handle)
116
100
  end
117
101
 
118
102
  end
@@ -0,0 +1,129 @@
1
+ require "test_helper"
2
+
3
+ class FilterTest < Test::Unit::TestCase
4
+
5
+ def assert_identity_after_filter(filter, value)
6
+ identity = value.object_id
7
+ filter.call(value)
8
+ identity.should == value.object_id
9
+ end
10
+
11
+ context "Filters" do
12
+ should "default filters that don't exist to an empty array" do
13
+ ActsAsFilterable::Filters[:test].empty?.should be(true)
14
+ end
15
+
16
+ should "contain some filters initially" do
17
+ ActsAsFilterable::Filters[:numeric].nil?.should_not be(true)
18
+ ActsAsFilterable::Filters[:lowercase].nil?.should_not be(true)
19
+ end
20
+
21
+ should "freeze the macro collection so it cannot be mutated" do
22
+ lambda { ActsAsFilterable::Filters.store(:test, /./) }.should raise_error
23
+ end
24
+ end
25
+
26
+ context "When applying the" do
27
+
28
+ context "digit filter, it" do
29
+ setup do
30
+ @filter = ActsAsFilterable::Filters[:digits]
31
+ end
32
+
33
+ should "strip any non-digit values from the string" do
34
+ value = "45tr.,2"
35
+ @filter.call(value)
36
+ value.should be("452")
37
+ end
38
+
39
+ should "not lose digit values" do
40
+ value = "432099132"
41
+ @filter.call(value)
42
+ value.should be("432099132")
43
+ end
44
+
45
+ should "return a coercable numerica value" do
46
+ value = "4"
47
+ @filter.call(value)
48
+ value.to_i.should be(4)
49
+ end
50
+
51
+ should "not create extra string objects when replacing values" do
52
+ assert_identity_after_filter @filter, "54tr"
53
+ end
54
+
55
+ should "not create extra string objects when no values are to be replaced" do
56
+ assert_identity_after_filter @filter, "54"
57
+ end
58
+
59
+ end
60
+
61
+ context "lowercase filter, it" do
62
+ setup do
63
+ @filter = ActsAsFilterable::Filters[:lowercase]
64
+ end
65
+
66
+ should "lowercase all alpha values" do
67
+ value = "FAIl STRING"
68
+ @filter.call(value)
69
+ value.should be("fail string")
70
+ end
71
+
72
+ should "not create extra string objects when replacing values" do
73
+ assert_identity_after_filter @filter, "TRANSLATE"
74
+ end
75
+
76
+ should "not create extra string objects when no values are to be replaced" do
77
+ assert_identity_after_filter @filter, "43"
78
+ end
79
+ end
80
+
81
+ context "uppercase filter, it" do
82
+ setup do
83
+ @filter = ActsAsFilterable::Filters[:uppercase]
84
+ end
85
+
86
+ should "uppercase all alpha values" do
87
+ value = "lowercase string"
88
+ @filter.call(value)
89
+ value.should be("LOWERCASE STRING")
90
+ end
91
+
92
+ should "not create extra string objects when replacing values" do
93
+ assert_identity_after_filter @filter, "translate"
94
+ end
95
+
96
+ should "not create extra string objects when no values are to be replaced" do
97
+ assert_identity_after_filter @filter, "43"
98
+ end
99
+ end
100
+
101
+ context "whitesapce filter, it" do
102
+ setup do
103
+ @filter = ActsAsFilterable::Filters[:whitespace]
104
+ end
105
+
106
+ should "replace all un-neccessary whitespace" do
107
+ value = "\t hai! this is neat\n\nok? \t"
108
+ @filter.call(value)
109
+ value.should be("hai! this is neat ok?")
110
+ end
111
+
112
+ should "trim the ends of the string" do
113
+ value = " this "
114
+ @filter.call(value)
115
+ value.should be("this")
116
+ end
117
+
118
+ should "not create extra string objects when replacing values" do
119
+ assert_identity_after_filter @filter, "TRANSLATE"
120
+ end
121
+
122
+ should "not create extra string objects when no values are to be replaced" do
123
+ assert_identity_after_filter @filter, "43"
124
+ end
125
+ end
126
+
127
+ end
128
+
129
+ end
data/test/test_helper.rb CHANGED
@@ -16,7 +16,7 @@ ActiveRecord::Schema.define do
16
16
  t.float :discount
17
17
  end
18
18
 
19
- create_table :user do |t|
19
+ create_table :users, :force => true do |t|
20
20
  t.string :handle
21
21
  t.string :phone_number
22
22
  end
@@ -28,6 +28,7 @@ end
28
28
 
29
29
  class User < ActiveRecord::Base
30
30
  filter_for_digits :phone_number
31
+ filter_for_lowercase :handle
31
32
  end
32
33
 
33
34
  class Test::Unit::TestCase
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: acts_as_filterable
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rob Ares
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-09-08 00:00:00 -04:00
12
+ date: 2009-10-29 00:00:00 -04:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -74,6 +74,7 @@ files:
74
74
  - lib/acts_as_filterable/base.rb
75
75
  - rails/init.rb
76
76
  - test/acts_as_filterable_integration_test.rb
77
+ - test/filter_test.rb
77
78
  - test/test_helper.rb
78
79
  has_rdoc: true
79
80
  homepage: http://github.com/rares/acts_as_filterable
@@ -99,10 +100,11 @@ required_rubygems_version: !ruby/object:Gem::Requirement
99
100
  requirements: []
100
101
 
101
102
  rubyforge_project:
102
- rubygems_version: 1.3.4
103
+ rubygems_version: 1.3.5
103
104
  signing_key:
104
105
  specification_version: 3
105
- summary: An ActiveRecord plugin that allows attribute-based filtering in order to normalize numeric data
106
+ summary: Filter attributes and stuff.
106
107
  test_files:
107
108
  - test/acts_as_filterable_integration_test.rb
109
+ - test/filter_test.rb
108
110
  - test/test_helper.rb