strip_attributes 1.5.1 → 1.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +37 -8
- data/lib/strip_attributes.rb +61 -45
- data/lib/strip_attributes/matchers.rb +2 -2
- data/lib/strip_attributes/version.rb +1 -1
- data/test/strip_attributes_test.rb +32 -3
- data/test/test_helper.rb +3 -0
- metadata +13 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ed934987322fa0c7a338d28649edd88a8520bf38
|
4
|
+
data.tar.gz: 2e1d75c6c7c5cb6b22e902cf3a80ebd22c5cf1aa
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 061fb3c3a5325750dc31a3e3c501a04c8d8da8dcb9516a2f76660ce5af1d920b0113ccf873f65065fa1be4242ab54f43432d3065b4d1b06482090ab8ea8b3764
|
7
|
+
data.tar.gz: 48a502af83d76d0e48b0e81e00aad261e50c46b31c265cc04d6d00d31a62da8a4a15371e423ef7b52eaa22497a126afad11bebab42c389851a163df12b52d744
|
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# StripAttributes [![Gem Version](
|
1
|
+
# StripAttributes [![Gem Version](http://img.shields.io/gem/v/strip_attributes.svg)](https://rubygems.org/gems/strip_attributes) [![Build Status](https://secure.travis-ci.org/rmm5t/strip_attributes.svg)](http://travis-ci.org/rmm5t/strip_attributes) [![Code Climate](http://img.shields.io/codeclimate/github/rmm5t/strip_attributes.svg)](https://codeclimate.com/github/rmm5t/strip_attributes)
|
2
2
|
|
3
3
|
StripAttributes is an ActiveModel extension that automatically strips all
|
4
4
|
attributes of leading and trailing whitespace before validation. If the
|
@@ -10,10 +10,26 @@ options can be used to limit which attributes are stripped. Both options accept
|
|
10
10
|
a single attribute (`:only => :field`) or arrays of attributes (`:except =>
|
11
11
|
[:field1, :field2, :field3]`).
|
12
12
|
|
13
|
-
|
13
|
+
## How You Can Help
|
14
14
|
|
15
|
-
|
16
|
-
|
15
|
+
**If you like this project, please help. [Donate via Gittip][gittip] or [buy me a coffee with Bitcoin][bitcoin].**<br>
|
16
|
+
[![Gratipay](http://img.shields.io/gratipay/rmm5t.svg)][gratipay]
|
17
|
+
[![Bitcoin](http://img.shields.io/badge/bitcoin-buy%20me%20a%20coffee-brightgreen.svg)][bitcoin]
|
18
|
+
|
19
|
+
**[Bitcoin][bitcoin]**: `1rmm5tv6f997JK5bLcGbRCZyVjZUPkQ2m`<br>
|
20
|
+
[![Bitcoin Donation][bitcoin-qr-small]][bitcoin-qr-big]
|
21
|
+
|
22
|
+
## Need Help?
|
23
|
+
|
24
|
+
**You can [book a session with me on Codementor][codementor].**<br>
|
25
|
+
[![Book a Codementor session](http://img.shields.io/badge/codementor-book%20a%20session-orange.svg)][codementor]
|
26
|
+
|
27
|
+
[gratipay]: https://gratipay.com/rmm5t/ "Donate to rmm5t for open source!"
|
28
|
+
[bitcoin]: https://blockchain.info/address/1rmm5tv6f997JK5bLcGbRCZyVjZUPkQ2m "Buy rmm5t a coffee for open source!"
|
29
|
+
[bitcoin-scheme]: bitcoin:1rmm5tv6f997JK5bLcGbRCZyVjZUPkQ2m?amount=0.01&label=Coffee%20to%20rmm5t%20for%20Open%20Source "Buy rmm5t a coffee for open source!"
|
30
|
+
[bitcoin-qr-small]: http://chart.apis.google.com/chart?cht=qr&chs=150x150&chl=bitcoin%3A1rmm5tv6f997JK5bLcGbRCZyVjZUPkQ2m%3Famount%3D0.01%26label%3DCoffee%2520to%2520rmm5t%2520for%2520Open%2520Source
|
31
|
+
[bitcoin-qr-big]: http://chart.apis.google.com/chart?cht=qr&chs=500x500&chl=bitcoin%3A1rmm5tv6f997JK5bLcGbRCZyVjZUPkQ2m%3Famount%3D0.01%26label%3DCoffee%2520to%2520rmm5t%2520for%2520Open%2520Source
|
32
|
+
[codementor]: https://www.codementor.io/rmm5t?utm_campaign=profile&utm_source=button-rmm5t&utm_medium=shields "Book a session with rmm5t on Codementor!"
|
17
33
|
|
18
34
|
## Installation
|
19
35
|
|
@@ -77,6 +93,8 @@ class User < ActiveRecord::Base
|
|
77
93
|
strip_attributes :only => [:first_name, :last_name], :regex => /[^[:alpha:]\s]/
|
78
94
|
# Strip off non-integers
|
79
95
|
strip_attributes :only => [:phone], :regex => /[^0-9]/
|
96
|
+
# Strip off all spaces and keep only alphabetic and numeric characters
|
97
|
+
strip_attributes :only => [:nick_name], :regex => /[^[:alnum:]\S]/
|
80
98
|
end
|
81
99
|
```
|
82
100
|
|
@@ -108,6 +126,17 @@ end
|
|
108
126
|
|
109
127
|
```
|
110
128
|
|
129
|
+
### Using it directly
|
130
|
+
|
131
|
+
```ruby
|
132
|
+
# where record is an ActiveModel isntance
|
133
|
+
StripAttributes.strip(record, :collapse_spaces => true)
|
134
|
+
|
135
|
+
# works directly on Strings too
|
136
|
+
StripAttributes.strip(" foo \t") #=> "foo"
|
137
|
+
StripAttributes.strip(" foo bar", :collapse_spaces => true) #=> "foo bar"
|
138
|
+
```
|
139
|
+
|
111
140
|
## Testing
|
112
141
|
|
113
142
|
StripAttributes provides an RSpec/Shoulda-compatible matcher for easier
|
@@ -146,13 +175,13 @@ end
|
|
146
175
|
|
147
176
|
### Writing Tests
|
148
177
|
|
149
|
-
**
|
178
|
+
**RSpec**:
|
150
179
|
|
151
180
|
```ruby
|
152
181
|
describe User do
|
153
|
-
it {
|
154
|
-
it {
|
155
|
-
it {
|
182
|
+
it { is_expected.to strip_attribute(:name).collapse_spaces }
|
183
|
+
it { is_expected.to strip_attribute :email }
|
184
|
+
it { is_expected.not_to strip_attribute :password }
|
156
185
|
end
|
157
186
|
```
|
158
187
|
|
data/lib/strip_attributes.rb
CHANGED
@@ -22,6 +22,67 @@ module StripAttributes
|
|
22
22
|
VALID_OPTIONS = [:only, :except, :allow_empty, :collapse_spaces, :regex]
|
23
23
|
MULTIBYTE_SUPPORTED = "\u0020" == " "
|
24
24
|
|
25
|
+
def self.strip(record_or_string, options = nil)
|
26
|
+
if record_or_string.respond_to?(:attributes)
|
27
|
+
strip_record(record_or_string, options)
|
28
|
+
else
|
29
|
+
strip_string(record_or_string, options)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.strip_record(record, options = nil)
|
34
|
+
attributes = narrow(record.attributes, options)
|
35
|
+
|
36
|
+
attributes.each do |attr, value|
|
37
|
+
original_value = value
|
38
|
+
value = strip_string(value, options)
|
39
|
+
record[attr] = value if original_value != value
|
40
|
+
end
|
41
|
+
|
42
|
+
record
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.strip_string(value, options = nil)
|
46
|
+
if options
|
47
|
+
allow_empty = options[:allow_empty]
|
48
|
+
collapse_spaces = options[:collapse_spaces]
|
49
|
+
regex = options[:regex]
|
50
|
+
end
|
51
|
+
|
52
|
+
if value.respond_to?(:strip)
|
53
|
+
value = (value.blank? && !allow_empty) ? nil : value.strip
|
54
|
+
end
|
55
|
+
|
56
|
+
if regex && value.respond_to?(:gsub!)
|
57
|
+
value.gsub!(regex, '')
|
58
|
+
end
|
59
|
+
|
60
|
+
if MULTIBYTE_SUPPORTED
|
61
|
+
# Remove leading and trailing Unicode invisible and whitespace characters.
|
62
|
+
# The POSIX character class [:space:] corresponds to the Unicode class Z
|
63
|
+
# ("separator"). We also include the following characters from Unicode class
|
64
|
+
# C ("control"), which are spaces or invisible characters that make no
|
65
|
+
# sense at the start or end of a string:
|
66
|
+
# U+180E MONGOLIAN VOWEL SEPARATOR
|
67
|
+
# U+200B ZERO WIDTH SPACE
|
68
|
+
# U+200C ZERO WIDTH NON-JOINER
|
69
|
+
# U+200D ZERO WIDTH JOINER
|
70
|
+
# U+2060 WORD JOINER
|
71
|
+
# U+FEFF ZERO WIDTH NO-BREAK SPACE
|
72
|
+
if value.respond_to?(:gsub!)
|
73
|
+
value.gsub!(/\A[[:space:]\u180E\u200B\u200C\u200D\u2060\uFEFF]+|[[:space:]\u180E\u200B\u200C\u200D\u2060\uFEFF]+\z/, '')
|
74
|
+
end
|
75
|
+
elsif value.respond_to?(:strip!)
|
76
|
+
value.strip!
|
77
|
+
end
|
78
|
+
|
79
|
+
if collapse_spaces && value.respond_to?(:squeeze!)
|
80
|
+
value.squeeze!(' ')
|
81
|
+
end
|
82
|
+
|
83
|
+
value
|
84
|
+
end
|
85
|
+
|
25
86
|
# Necessary because Rails has removed the narrowing of attributes using :only
|
26
87
|
# and :except on Base#attributes
|
27
88
|
def self.narrow(attributes, options = {})
|
@@ -36,51 +97,6 @@ module StripAttributes
|
|
36
97
|
end
|
37
98
|
end
|
38
99
|
|
39
|
-
def self.strip(record, options)
|
40
|
-
attributes = self.narrow(record.attributes, options)
|
41
|
-
|
42
|
-
if options
|
43
|
-
allow_empty = options[:allow_empty]
|
44
|
-
collapse_spaces = options[:collapse_spaces]
|
45
|
-
regex = options[:regex]
|
46
|
-
end
|
47
|
-
|
48
|
-
attributes.each do |attr, value|
|
49
|
-
original_value = value
|
50
|
-
|
51
|
-
if value.respond_to?(:strip)
|
52
|
-
value = (value.blank? && !allow_empty) ? nil : value.strip
|
53
|
-
end
|
54
|
-
|
55
|
-
if regex && value.respond_to?(:gsub!)
|
56
|
-
value.gsub!(regex, '')
|
57
|
-
end
|
58
|
-
|
59
|
-
if MULTIBYTE_SUPPORTED
|
60
|
-
# Remove leading and trailing Unicode invisible and whitespace characters.
|
61
|
-
# The POSIX character class [:space:] corresponds to the Unicode class Z
|
62
|
-
# ("separator"). We also include the following characters from Unicode class
|
63
|
-
# C ("control"), which are spaces or invisible characters that make no
|
64
|
-
# sense at the start or end of a string:
|
65
|
-
# U+180E MONGOLIAN VOWEL SEPARATOR
|
66
|
-
# U+200B ZERO WIDTH SPACE
|
67
|
-
# U+200C ZERO WIDTH NON-JOINER
|
68
|
-
# U+200D ZERO WIDTH JOINER
|
69
|
-
# U+2060 WORD JOINER
|
70
|
-
# U+FEFF ZERO WIDTH NO-BREAK SPACE
|
71
|
-
if value.respond_to?(:gsub!)
|
72
|
-
value.gsub!(/\A[[:space:]\u180E\u200B\u200C\u200D\u2060\uFEFF]+|[[:space:]\u180E\u200B\u200C\u200D\u2060\uFEFF]+\z/, '')
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
|
-
if collapse_spaces && value.respond_to?(:squeeze!)
|
77
|
-
value.squeeze!(' ')
|
78
|
-
end
|
79
|
-
|
80
|
-
record[attr] = value if original_value != value
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
100
|
def self.validate_options(options)
|
85
101
|
if keys = options && options.keys
|
86
102
|
unless (keys - VALID_OPTIONS).empty?
|
@@ -5,8 +5,8 @@ module StripAttributes
|
|
5
5
|
#
|
6
6
|
# RSpec Examples:
|
7
7
|
#
|
8
|
-
# it {
|
9
|
-
# it {
|
8
|
+
# it { is_expected.to strip_attribute(:first_name) }
|
9
|
+
# it { is_expected.not_to strip_attribute(:password) }
|
10
10
|
#
|
11
11
|
# Minitest Matchers Examples:
|
12
12
|
#
|
@@ -61,7 +61,7 @@ class StripRegexMockRecord < Tableless
|
|
61
61
|
strip_attributes :regex => /[\^\%&\*]/
|
62
62
|
end
|
63
63
|
|
64
|
-
class StripAttributesTest <
|
64
|
+
class StripAttributesTest < Minitest::Test
|
65
65
|
def setup
|
66
66
|
@init_params = { :foo => "\tfoo", :bar => "bar \t ", :biz => "\tbiz ", :baz => "", :bang => " ", :foz => " foz foz" }
|
67
67
|
end
|
@@ -181,9 +181,9 @@ class StripAttributesTest < MiniTest::Unit::TestCase
|
|
181
181
|
record.valid?
|
182
182
|
assert_equal "abc", record.foo
|
183
183
|
assert_equal "bar", record.bar
|
184
|
-
end
|
184
|
+
end
|
185
185
|
|
186
|
-
def
|
186
|
+
def test_should_strip_unicode
|
187
187
|
# This feature only works if multi-byte characters are supported by Ruby
|
188
188
|
return if "\u0020" != " "
|
189
189
|
# U200A - HAIR SPACE
|
@@ -192,4 +192,33 @@ class StripAttributesTest < MiniTest::Unit::TestCase
|
|
192
192
|
record.valid?
|
193
193
|
assert_equal "foo", record.foo
|
194
194
|
end
|
195
|
+
|
196
|
+
class ClassMethodsTest < Minitest::Test
|
197
|
+
def test_should_strip_whitespace
|
198
|
+
assert_equal nil, StripAttributes.strip("")
|
199
|
+
assert_equal nil, StripAttributes.strip(" \t ")
|
200
|
+
assert_equal "thirty six", StripAttributes.strip(" thirty six \t \n")
|
201
|
+
end
|
202
|
+
|
203
|
+
def test_should_allow_empty
|
204
|
+
assert_equal "", StripAttributes.strip("", :allow_empty => true)
|
205
|
+
assert_equal "", StripAttributes.strip(" \t ", :allow_empty => true)
|
206
|
+
end
|
207
|
+
|
208
|
+
def test_should_collapse_spaces
|
209
|
+
assert_equal "1 2 3", StripAttributes.strip(" 1 2 3\t ", :collapse_spaces => true)
|
210
|
+
end
|
211
|
+
|
212
|
+
def test_should_strip_regex
|
213
|
+
assert_equal "abc", StripAttributes.strip("^%&*abc ^ ", :regex => /[\^\%&\*]/)
|
214
|
+
end
|
215
|
+
|
216
|
+
def test_should_strip_unicode
|
217
|
+
# This feature only works if multi-byte characters are supported by Ruby
|
218
|
+
return if "\u0020" != " "
|
219
|
+
# U200A - HAIR SPACE
|
220
|
+
# U200B - ZERO WIDTH SPACE
|
221
|
+
assert_equal "foo", StripAttributes.strip("\u200A\u200B foo\u200A\u200B ")
|
222
|
+
end
|
223
|
+
end
|
195
224
|
end
|
data/test/test_helper.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: strip_attributes
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ryan McGeary
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2015-01-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activemodel
|
@@ -62,30 +62,36 @@ dependencies:
|
|
62
62
|
name: minitest
|
63
63
|
requirement: !ruby/object:Gem::Requirement
|
64
64
|
requirements:
|
65
|
-
- - "
|
65
|
+
- - ">="
|
66
66
|
- !ruby/object:Gem::Version
|
67
67
|
version: '4.7'
|
68
|
+
- - "<"
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
version: '6.0'
|
68
71
|
type: :development
|
69
72
|
prerelease: false
|
70
73
|
version_requirements: !ruby/object:Gem::Requirement
|
71
74
|
requirements:
|
72
|
-
- - "
|
75
|
+
- - ">="
|
73
76
|
- !ruby/object:Gem::Version
|
74
77
|
version: '4.7'
|
78
|
+
- - "<"
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
version: '6.0'
|
75
81
|
- !ruby/object:Gem::Dependency
|
76
82
|
name: rake
|
77
83
|
requirement: !ruby/object:Gem::Requirement
|
78
84
|
requirements:
|
79
85
|
- - "~>"
|
80
86
|
- !ruby/object:Gem::Version
|
81
|
-
version:
|
87
|
+
version: 10.1.1
|
82
88
|
type: :development
|
83
89
|
prerelease: false
|
84
90
|
version_requirements: !ruby/object:Gem::Requirement
|
85
91
|
requirements:
|
86
92
|
- - "~>"
|
87
93
|
- !ruby/object:Gem::Version
|
88
|
-
version:
|
94
|
+
version: 10.1.1
|
89
95
|
description: StripAttributes automatically strips all ActiveRecord model attributes
|
90
96
|
of leading and trailing whitespace before validation. If the attribute is blank,
|
91
97
|
it strips the value to nil.
|
@@ -124,7 +130,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
124
130
|
version: '0'
|
125
131
|
requirements: []
|
126
132
|
rubyforge_project:
|
127
|
-
rubygems_version: 2.
|
133
|
+
rubygems_version: 2.4.5
|
128
134
|
signing_key:
|
129
135
|
specification_version: 4
|
130
136
|
summary: Whitespace cleanup for ActiveModel attributes
|