ball_gag 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- ball_gag (0.0.1)
4
+ ball_gag (0.0.2)
5
5
 
6
6
  GEM
7
7
  remote: http://rubygems.org/
data/Readme.md CHANGED
@@ -24,7 +24,7 @@ end
24
24
  Post.new('That was some damn good watermelon').body_gagged?
25
25
  # true
26
26
 
27
- Post.new('That was some fine watermelon.').body_gagged?
27
+ Post.new('That was some fine watermelon').body_gagged?
28
28
  # false
29
29
  ````
30
30
 
@@ -40,12 +40,20 @@ Now a <tt>NotGaggedValidator</tt> is available which you can use like this.
40
40
  ````ruby
41
41
  class Post < ActiveRecord::Base
42
42
  include BallGag
43
- gag :body { |body| !/damn/.match body }
43
+ gag(:body) { |body| !/damn/.match body }
44
44
 
45
45
  validates :body, :not_gagged => true
46
46
  end
47
47
  ````
48
48
 
49
+ ````ruby
50
+ Post.new(body: 'That was some damn good watermelon').valid?
51
+ # false
52
+
53
+ Post.new(body: 'That was some fine watermelon').valid?
54
+ # true
55
+ ````
56
+
49
57
  ## Engines / Global configuration
50
58
  Each gagged attribute can be provided its own block to call when checking acceptability, or a global engine can be provided. Set a global engine like this.
51
59
 
@@ -102,10 +110,9 @@ class ModerationServiceEngine
102
110
  return call(options[:attr] => fields, options)
103
111
  end
104
112
 
105
- gag_options = options[:options]
113
+ gag_options, instance = options.values_at(:options, :instance)
106
114
 
107
- sender = gag_options[:sender].
108
- bind(instance).call
115
+ sender = gag_options[:sender].bind(instance).call
109
116
 
110
117
  response = new(*MyApp::ApplicationConfig.moderation_service_credentials).
111
118
  get('/moderate', query: { fields: fields, user: sender })
@@ -2,6 +2,8 @@ require 'ball_gag/version'
2
2
  require 'ball_gag/gag'
3
3
  require 'ball_gag/engine'
4
4
  require 'ball_gag/errors'
5
+ require 'ball_gag/cloak'
6
+ require 'ball_gag/bowling_ball'
5
7
 
6
8
  begin
7
9
  require 'ball_gag/validations'
@@ -0,0 +1,36 @@
1
+ module BowlingBall
2
+ class << self
3
+ def included base
4
+ base.send(:include, BallGag)
5
+ end
6
+
7
+ def engine
8
+ BallGag.engine
9
+ end
10
+
11
+ def engine= engine
12
+ BallGag.engine = engine
13
+ end
14
+
15
+ def verb
16
+ BallGag.verb
17
+ end
18
+
19
+ def verb= verb
20
+ BallGag.verb= verb
21
+ end
22
+
23
+ def preterite
24
+ BallGag.preterite
25
+ end
26
+
27
+ def preterite= preterite
28
+ BallGag.preterite = preterite
29
+ end
30
+
31
+ def negative_preterite= preterite
32
+ BallGag.negative_preterite = preterite
33
+ end
34
+ end
35
+ end
36
+
@@ -0,0 +1,74 @@
1
+ module BallGag
2
+ module Cloak
3
+ def verb
4
+ @verb || 'gag'
5
+ end
6
+
7
+ def verb= verb
8
+ old_verb = @verb
9
+ @verb = verb
10
+
11
+ BallGag::ClassMethods.instance_eval do
12
+ if verb
13
+ define_method verb do |*args|
14
+ gag *args
15
+ end
16
+ elsif old_verb
17
+ remove_method old_verb
18
+ end
19
+ end
20
+ end
21
+
22
+ def preterite
23
+ @preterite || 'gagged'
24
+ end
25
+
26
+ def preterite= preterite
27
+ set_preterite preterite
28
+ @preterite_negative = false
29
+ end
30
+
31
+ def negative_preterite= preterite
32
+ set_preterite preterite
33
+ @preterite_negative = true
34
+ end
35
+
36
+ def preterite_negative?
37
+ @preterite_negative
38
+ end
39
+
40
+ private
41
+ def set_preterite preterite
42
+ undefine_old_preterite_validators @preterite
43
+ define_preterite_validators preterite
44
+
45
+ @preterite = preterite
46
+ end
47
+
48
+ def define_preterite_validators preterite
49
+ return unless preterite
50
+
51
+ Kernel.const_set(validator_name(preterite), Class.new(GaggedValidator))
52
+ Kernel.const_set(not_validator_name(preterite), Class.new(NotGaggedValidator))
53
+ end
54
+
55
+ def undefine_old_preterite_validators preterite
56
+ return unless preterite
57
+
58
+ Kernel.send(:remove_const, validator_name(preterite))
59
+ Kernel.send(:remove_const, not_validator_name(preterite))
60
+ end
61
+
62
+ def validator_name preterite
63
+ "#{preterite.to_s.capitalize}Validator"
64
+ end
65
+
66
+ def not_validator_name preterite
67
+ "Not#{validator_name(preterite)}"
68
+ end
69
+
70
+ end
71
+
72
+ extend Cloak
73
+ end
74
+
@@ -64,19 +64,16 @@ module BallGag
64
64
  if 1 == arity
65
65
  fn = lambda { |it, attr| callable.call(output.call(it, attr)) }
66
66
  else
67
- options = {}
68
67
  fn = lambda do |it, attr|
69
68
  callable.call(output.call(it, attr),
70
69
  { options: gag_options,
71
70
  instance: it,
72
71
  attr: attr,
73
72
  single: one_attribute
74
- }
75
- )
73
+ })
76
74
  end
77
75
  end
78
76
 
79
-
80
77
  attributes.each do |attr|
81
78
  @gagged_attributes_methods.send(:define_method,
82
79
  gagged_attribute_negative_interpellation_name(attr)) do
@@ -112,16 +109,23 @@ module BallGag
112
109
  end
113
110
 
114
111
  def gagged_attribute_interpellation_name attribute
115
- "#{attribute}_gagged?"
112
+ gagged_attribute_preterite_interpellation_name(
113
+ attribute, !BallGag.preterite_negative?)
116
114
  end
117
115
 
118
116
  def gagged_attribute_negative_interpellation_name attribute
119
- "#{attribute}_not_gagged?"
117
+ gagged_attribute_preterite_interpellation_name(
118
+ attribute, BallGag.preterite_negative?)
119
+ end
120
+
121
+ def gagged_attribute_preterite_interpellation_name attribute, negative
122
+ negative ?
123
+ "#{attribute}_#{BallGag.preterite}?" :
124
+ "#{attribute}_not_#{BallGag.preterite}?"
120
125
  end
121
126
 
122
127
  def undefine_gagged_attributes_methods
123
128
  @gagged_attributes.keys.each do |attribute|
124
-
125
129
  @gagged_attributes_methods.send(:remove_method,
126
130
  gagged_attribute_interpellation_name(attribute))
127
131
 
@@ -1,8 +1,28 @@
1
- class NotGaggedValidator < ActiveModel::EachValidator
1
+ class GaggedValidator < ActiveModel::EachValidator
2
2
  def validate_each object, attribute, value
3
- if object.method("#{attribute}_gagged?").call
4
- object.errors[attribute] << (options[:message] || 'is gagged')
3
+ unless object.method(condition_method_name(attribute)).call
4
+ object.errors[attribute] << (options[:message] || default_message)
5
5
  end
6
6
  end
7
+
8
+ private
9
+ def condition_method_name attribute
10
+ "#{attribute}_#{BallGag.preterite}?"
11
+ end
12
+
13
+ def default_message
14
+ "is not #{BallGag.preterite}"
15
+ end
16
+ end
17
+
18
+ class NotGaggedValidator < GaggedValidator
19
+ private
20
+ def condition_method_name attribute
21
+ "#{attribute}_not_#{BallGag.preterite}?"
22
+ end
23
+
24
+ def default_message
25
+ "is #{BallGag.preterite}"
26
+ end
7
27
  end
8
28
 
@@ -1,4 +1,4 @@
1
1
  module BallGag
2
- VERSION = '0.0.1'
2
+ VERSION = '0.0.2'
3
3
  end
4
4
 
@@ -0,0 +1,16 @@
1
+ require 'spec_helper'
2
+
3
+ describe BowlingBall do
4
+ after { Kernel.send(:remove_const, :BowlingBallIncluder) }
5
+
6
+ context 'when included' do
7
+ it 'should include BallGag' do
8
+ class Kernel::BowlingBallIncluder
9
+ include BowlingBall
10
+ end
11
+
12
+ BowlingBallIncluder.included_modules.should include BallGag
13
+ end
14
+ end
15
+ end
16
+
@@ -0,0 +1,133 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'BallGag cloaking' do
4
+ before do
5
+ ExampleModel.clear_gagged_attributes
6
+ ExampleActiveModel.reset_callbacks :validate
7
+ ExampleActiveModel.clear_gagged_attributes
8
+ BallGag.verb = nil
9
+ BallGag.preterite = nil
10
+ end
11
+
12
+ after do
13
+ ExampleModel.clear_gagged_attributes
14
+ ExampleActiveModel.clear_gagged_attributes
15
+ BallGag.verb = nil
16
+ BallGag.preterite = nil
17
+ end
18
+
19
+ it 'should have default verb' do
20
+ BallGag.verb.should eq 'gag'
21
+ end
22
+
23
+ it 'should accept new verb' do
24
+ BallGag.verb = 'censor'
25
+ BallGag.verb.should eq 'censor'
26
+ end
27
+
28
+ it 'should provide verb as class method' do
29
+ BallGag.verb = 'censor'
30
+ ExampleModel.should respond_to :censor
31
+ end
32
+
33
+ it 'should gag attribute when custom verb is used' do
34
+ BallGag.verb = 'censor'
35
+ ExampleModel.censor :words
36
+ ExampleModel.gagged_attributes.should include :words
37
+ end
38
+
39
+ it 'should remove custom verb method when verb is cleared' do
40
+ BallGag.verb = 'censor'
41
+ BallGag.verb = nil
42
+ ExampleModel.should_not respond_to :censor
43
+ end
44
+
45
+ it 'should have preterite' do
46
+ BallGag.preterite.should eq 'gagged'
47
+ end
48
+
49
+ it 'should accept new preterite' do
50
+ BallGag.preterite = 'censored'
51
+ BallGag.preterite.should eq 'censored'
52
+ end
53
+
54
+ it 'should define #{attribute}_#{preterite}? method on instance' do
55
+ BallGag.preterite = 'censored'
56
+ ExampleModel.gag :words
57
+ ExampleModel.new.should respond_to :words_censored?
58
+ end
59
+
60
+ it 'should define #{attribute}_not_#{preterite}? method on instance' do
61
+ BallGag.preterite = 'censored'
62
+ ExampleModel.gag :words
63
+ ExampleModel.new.should respond_to :words_not_censored?
64
+ end
65
+
66
+ it 'should have non-negative preterite' do
67
+ BallGag.preterite_negative?.should be_false
68
+ end
69
+
70
+ it 'should accept negative preterite' do
71
+ BallGag.negative_preterite = 'acceptable'
72
+ BallGag.preterite_negative?.should be_true
73
+ end
74
+
75
+ context 'when preterite is negative' do
76
+ it 'should invert meaning of #{attribute}_#{preterite}?' do
77
+ BallGag.negative_preterite = 'acceptable'
78
+ ExampleModel.gag(:words) { |words| true }
79
+ ExampleModel.new.words_acceptable?.should be_true
80
+ end
81
+
82
+ it 'should invert meaning of #{attribute}_not_#{preterite}?' do
83
+ BallGag.negative_preterite = 'acceptable'
84
+ ExampleModel.gag(:words) { |words| true }
85
+ ExampleModel.new.words_not_acceptable?.should be_false
86
+ end
87
+ end
88
+
89
+ describe 'validators' do
90
+ specify 'custom preterite should create validator' do
91
+ BallGag.preterite = 'censored'
92
+ ExampleActiveModel.gag(:words) { |words| true }
93
+ ExampleActiveModel.validates :words, censored: true
94
+ instance = ExampleActiveModel.new
95
+ instance.valid?
96
+ instance.errors[:words].should include 'is not censored'
97
+ end
98
+
99
+ specify 'custom preterite should create Not validator' do
100
+ BallGag.preterite = 'censored'
101
+ ExampleActiveModel.gag(:words) { |words| false }
102
+ ExampleActiveModel.validates :words, not_censored: true
103
+ instance = ExampleActiveModel.new
104
+ instance.valid?
105
+ instance.errors[:words].should include 'is censored'
106
+ end
107
+ end
108
+
109
+ describe BowlingBall do
110
+ it 'should set verb' do
111
+ BowlingBall.verb = 'censor'
112
+ BallGag.verb.should eq 'censor'
113
+ end
114
+
115
+ it 'should set preterite' do
116
+ BowlingBall.preterite = 'censored'
117
+ BallGag.preterite.should eq 'censored'
118
+ end
119
+
120
+ it 'should set negative preterite' do
121
+ BowlingBall.negative_preterite = 'acceptable'
122
+ BallGag.preterite.should eq 'acceptable'
123
+ BallGag.preterite_negative?.should be_true
124
+ end
125
+
126
+ it 'should set engine' do
127
+ mock_engine = mock('engine')
128
+ BowlingBall.engine = mock_engine
129
+ BallGag.engine.should eq mock_engine
130
+ end
131
+ end
132
+ end
133
+
@@ -3,6 +3,8 @@ require 'spec_helper'
3
3
  describe ExampleModel do
4
4
  before do
5
5
  BallGag.engine = nil
6
+ BallGag.verb = nil
7
+ BallGag.preterite = nil
6
8
  ExampleModel.clear_gagged_attributes
7
9
  end
8
10
 
@@ -3,31 +3,44 @@ require 'spec_helper'
3
3
  describe 'ActiveModel::Validations integration' do
4
4
  before do
5
5
  ExampleActiveModel.reset_callbacks :validate
6
+ ExampleActiveModel.clear_gagged_attributes
6
7
  end
7
8
 
8
- it 'should call #{attribute}_gagged?' do
9
- ExampleActiveModel.validates :words, not_gagged: true
9
+ describe NotGaggedValidator do
10
+ it 'should call #{attribute}_gagged?' do
11
+ ExampleActiveModel.validates :words, not_gagged: true
10
12
 
11
- instance = ExampleActiveModel.new
12
- instance.should_receive(:words_gagged?)
13
- instance.valid?
14
- end
13
+ instance = ExampleActiveModel.new
14
+ instance.should_receive(:words_not_gagged?)
15
+ instance.valid?
16
+ end
17
+
18
+ it 'should add default error message' do
19
+ ExampleActiveModel.validates :words, not_gagged: true
20
+ instance = ExampleActiveModel.new
21
+ instance.stub!(words_not_gagged?: false)
22
+ instance.valid?
23
+ instance.errors[:words].should include 'is gagged'
24
+ end
15
25
 
16
- it 'should add default error message' do
17
- ExampleActiveModel.validates :words, not_gagged: true
18
- instance = ExampleActiveModel.new
19
- instance.stub!(words_gagged?: true)
20
- instance.valid?
21
- instance.errors[:words].should include 'is gagged'
26
+ it 'should respect custom error message' do
27
+ ExampleActiveModel.validates :words,
28
+ not_gagged: { message: 'is not acceptable' }
29
+ instance = ExampleActiveModel.new
30
+ instance.stub!(words_not_gagged?: false)
31
+ instance.valid?
32
+ instance.errors[:words].should include 'is not acceptable'
33
+ end
22
34
  end
23
35
 
24
- it 'should respect custom error message' do
25
- ExampleActiveModel.validates :words,
26
- not_gagged: { message: 'is not acceptable' }
27
- instance = ExampleActiveModel.new
28
- instance.stub!(words_gagged?: true)
29
- instance.valid?
30
- instance.errors[:words].should include 'is not acceptable'
36
+ describe GaggedValidator do
37
+ it 'should add default error message' do
38
+ ExampleActiveModel.validates :words, gagged: true
39
+ instance = ExampleActiveModel.new
40
+ instance.stub!(words_gagged?: false)
41
+ instance.valid?
42
+ instance.errors[:words].should include 'is not gagged'
43
+ end
31
44
  end
32
45
  end
33
46
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ball_gag
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-11-07 00:00:00.000000000 Z
12
+ date: 2011-11-08 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec
16
- requirement: &70285274103000 !ruby/object:Gem::Requirement
16
+ requirement: &70299098639740 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,7 +21,7 @@ dependencies:
21
21
  version: '0'
22
22
  type: :development
23
23
  prerelease: false
24
- version_requirements: *70285274103000
24
+ version_requirements: *70299098639740
25
25
  description: Validate user input using pluggable back-ends
26
26
  email:
27
27
  - duncan@dweebd.com
@@ -38,11 +38,15 @@ files:
38
38
  - Readme.md
39
39
  - ball_gag.gemspec
40
40
  - lib/ball_gag.rb
41
+ - lib/ball_gag/bowling_ball.rb
42
+ - lib/ball_gag/cloak.rb
41
43
  - lib/ball_gag/engine.rb
42
44
  - lib/ball_gag/errors.rb
43
45
  - lib/ball_gag/gag.rb
44
46
  - lib/ball_gag/validations.rb
45
47
  - lib/ball_gag/version.rb
48
+ - spec/bowling_ball_spec.rb
49
+ - spec/cloak_spec.rb
46
50
  - spec/engine_spec.rb
47
51
  - spec/gag_spec.rb
48
52
  - spec/spec_helper.rb
@@ -73,6 +77,8 @@ signing_key:
73
77
  specification_version: 3
74
78
  summary: Pluggable User-Content Validation
75
79
  test_files:
80
+ - spec/bowling_ball_spec.rb
81
+ - spec/cloak_spec.rb
76
82
  - spec/engine_spec.rb
77
83
  - spec/gag_spec.rb
78
84
  - spec/spec_helper.rb