tiny_sweeper 0.0.5 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.ruby-version +1 -1
- data/.travis.yml +2 -0
- data/ChangeLog +13 -0
- data/Gemfile +4 -2
- data/Gemfile.lock +20 -0
- data/README.md +67 -22
- data/Rakefile +6 -0
- data/lib/tiny_sweeper.rb +18 -5
- data/lib/tiny_sweeper/broom_closet.rb +40 -0
- data/lib/tiny_sweeper/brooms.rb +25 -0
- data/lib/tiny_sweeper/version.rb +1 -1
- data/spec/spec_helper.rb +17 -12
- data/spec/tiny_sweeper/broom_closet_spec.rb +38 -0
- data/spec/tiny_sweeper_spec.rb +105 -28
- data/tiny-sweeper.png +0 -0
- data/tiny_sweeper.gemspec +2 -0
- metadata +37 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0c248480c222e8e718c8ef21fec9e827e856abd9
|
4
|
+
data.tar.gz: b027e8f57d02cc452b8517fe2551b1e8a12be2d2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 00515ecb8ad22531a197c0df408bce1d9911b21dbbabf51a8490c7b3cde151fba641003d941fc5fc32297e839802acf5e9fddcde3b1f78c57c5e549520e411a2
|
7
|
+
data.tar.gz: 95301659fb178850356d405eec7624146124ac4d6e8536422b1b96733f35311bf01e0d4245e9ad9a08538621b754e5ec14ca3e6cffb003529fd79ba17eb82dbe
|
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
ruby-2.
|
1
|
+
ruby-2.3.0
|
data/.travis.yml
CHANGED
data/ChangeLog
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
tiny_sweeper (1.0.0) stable; urgency=low
|
2
|
+
|
3
|
+
* Change `sweep` to only take one attribute name, followed by zero or more
|
4
|
+
"brooms" (symbols that name a pre-configured way to sweep a value), and an
|
5
|
+
optional sweeping block.
|
6
|
+
* Add `TinySweeper::Brooms.add(name, &block)` for registering custom brooms.
|
7
|
+
|
8
|
+
tiny_sweeper (0.0.5) stable; urgency=low
|
9
|
+
|
10
|
+
* First public stable release
|
11
|
+
* Define sweeping rules with `sweep`, which takes multiple field names, and
|
12
|
+
a block
|
13
|
+
* Sweep all attributes of a class with `sweep_up!`
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,7 +1,16 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
tiny_sweeper (0.0.5)
|
5
|
+
|
1
6
|
GEM
|
2
7
|
remote: https://rubygems.org/
|
3
8
|
specs:
|
9
|
+
codeclimate-test-reporter (0.6.0)
|
10
|
+
simplecov (>= 0.7.1, < 1.0.0)
|
4
11
|
diff-lcs (1.2.5)
|
12
|
+
docile (1.1.5)
|
13
|
+
json (2.0.2)
|
5
14
|
rake (10.4.2)
|
6
15
|
rspec (3.2.0)
|
7
16
|
rspec-core (~> 3.2.0)
|
@@ -16,10 +25,21 @@ GEM
|
|
16
25
|
diff-lcs (>= 1.2.0, < 2.0)
|
17
26
|
rspec-support (~> 3.2.0)
|
18
27
|
rspec-support (3.2.0)
|
28
|
+
simplecov (0.12.0)
|
29
|
+
docile (~> 1.1.0)
|
30
|
+
json (>= 1.8, < 3)
|
31
|
+
simplecov-html (~> 0.10.0)
|
32
|
+
simplecov-html (0.10.0)
|
19
33
|
|
20
34
|
PLATFORMS
|
21
35
|
ruby
|
22
36
|
|
23
37
|
DEPENDENCIES
|
38
|
+
bundler (~> 1.5)
|
39
|
+
codeclimate-test-reporter
|
24
40
|
rake
|
25
41
|
rspec
|
42
|
+
tiny_sweeper!
|
43
|
+
|
44
|
+
BUNDLED WITH
|
45
|
+
1.12.5
|
data/README.md
CHANGED
@@ -2,19 +2,22 @@
|
|
2
2
|
|
3
3
|
TinySweeper keeps your objects tidy!
|
4
4
|
|
5
|
+
![Hold me closer, Tiny Sweeper](https://github.com/ContinuityControl/tiny_sweeper/raw/master/tiny-sweeper.png)
|
6
|
+
|
5
7
|
It's a handy way to clean attributes on your Rails models, though it's independent of Rails, and can be used in any Ruby project. It gives you a light-weigt way to override your methods and declare how their inputs should be cleaned.
|
6
8
|
|
7
9
|
[![Build Status](https://travis-ci.org/ContinuityControl/tiny_sweeper.png?branch=master)](https://travis-ci.org/ContinuityControl/tiny_sweeper)
|
8
10
|
[![Code Climate](https://codeclimate.com/github/ContinuityControl/tiny_sweeper/badges/gpa.svg)](https://codeclimate.com/github/ContinuityControl/tiny_sweeper)
|
11
|
+
[![Test Coverage](https://codeclimate.com/github/ContinuityControl/tiny_sweeper/badges/coverage.svg)](https://codeclimate.com/github/ContinuityControl/tiny_sweeper/coverage)
|
9
12
|
|
10
13
|
## How Do I Use It?
|
11
14
|
|
12
15
|
```ruby
|
13
16
|
class Sundae
|
14
|
-
attr_accessor :ice_cream
|
17
|
+
attr_accessor :ice_cream
|
15
18
|
|
16
19
|
include TinySweeper
|
17
|
-
sweep(:ice_cream
|
20
|
+
sweep(:ice_cream) { |flavor| flavor.strip.downcase }
|
18
21
|
end
|
19
22
|
```
|
20
23
|
|
@@ -23,9 +26,7 @@ Now your Sundae toppings will be tidied up:
|
|
23
26
|
```ruby
|
24
27
|
dessert = Sundae.new
|
25
28
|
dessert.ice_cream = ' CHOCOlate '
|
26
|
-
dessert.topping = ' ButTTERscotCH '
|
27
29
|
dessert.ice_cream #=> 'chocolate'. Tidy!
|
28
|
-
dessert.topping #=> 'butterscotch'. Tidy!
|
29
30
|
```
|
30
31
|
|
31
32
|
TinySweeper will not bother you about your nil values; they're your job to handle.
|
@@ -34,42 +35,86 @@ TinySweeper will not bother you about your nil values; they're your job to handl
|
|
34
35
|
Sundae.new.topping = nil # No topping? TinySweeper won't sweep it.
|
35
36
|
```
|
36
37
|
|
37
|
-
If
|
38
|
+
If lots of attributes need to be swept the same way, you can pass an array of field names:
|
38
39
|
|
39
40
|
```ruby
|
40
|
-
|
41
|
-
|
42
|
-
Sundae.sweep_up!(dessert)
|
43
|
-
```
|
41
|
+
class Sundae
|
42
|
+
attr_accessor :ice_cream, :topping, :nuts
|
44
43
|
|
45
|
-
|
44
|
+
include TinySweeper
|
45
|
+
sweep [:ice_cream, :topping, :nuts] { |item| item.strip.downcase }
|
46
|
+
end
|
46
47
|
|
47
|
-
|
48
|
+
dessert = Sundae.new
|
49
|
+
dessert.ice_cream = ' CHOCOlate '
|
50
|
+
dessert.topping = ' ButTTERscotCH '
|
51
|
+
dessert.nuts = ' CRUSHED peaNUtS '
|
52
|
+
dessert.ice_cream #=> 'chocolate'
|
53
|
+
dessert.topping #=> 'butterscotch'
|
54
|
+
dessert.nuts #=> 'crushed peanuts'
|
55
|
+
```
|
48
56
|
|
49
|
-
|
57
|
+
TinySweeper already knows a few sweeping tricks, and you can ask for them by name:
|
50
58
|
|
51
59
|
```ruby
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
60
|
+
class Sundae
|
61
|
+
attr_accessor :ice_cream
|
62
|
+
|
63
|
+
include TinySweeper
|
64
|
+
sweep :ice_cream, :blanks_to_nil
|
65
|
+
end
|
66
|
+
|
67
|
+
dessert = Sundae.new
|
68
|
+
dessert.ice_cream = ""
|
69
|
+
dessert.ice_cream #=> nil
|
70
|
+
```
|
56
71
|
|
72
|
+
You can use as many as you need, and TinySweeper will apply them all, left-to-right:
|
73
|
+
|
74
|
+
```ruby
|
57
75
|
class Sundae
|
58
|
-
|
76
|
+
attr_accessor :ice_cream
|
77
|
+
|
78
|
+
include TinySweeper
|
79
|
+
sweep :ice_cream, :strip, :blanks_to_nil
|
80
|
+
|
81
|
+
dessert = Sundae.new
|
82
|
+
dessert.ice_cream = " "
|
83
|
+
dessert.ice_cream #=> nil
|
59
84
|
end
|
60
85
|
```
|
61
86
|
|
62
|
-
|
87
|
+
TinySweeper currently only knows a few tricks...
|
88
|
+
|
89
|
+
* `blanks_to_nil`: turn empty strings into nils
|
90
|
+
* `strip`: just like `String#strip`: removes trailing and leading whitespace
|
91
|
+
* `dumb_quotes`: replace [Smart Quotes](https://en.wikipedia.org/wiki/Quotation_marks_in_English) with their simpler siblings
|
92
|
+
|
93
|
+
...but you can teach it new ones:
|
94
|
+
|
95
|
+
```ruby
|
96
|
+
TinySweeper::Brooms.add(:strip_html) { |value| Nokogiri::HTML(value).text }
|
97
|
+
```
|
98
|
+
|
99
|
+
And you can always combine the built-in tricks with a block:
|
63
100
|
|
64
101
|
```ruby
|
65
102
|
class Sundae
|
66
|
-
|
67
|
-
sweep
|
68
|
-
# ...would be the same as this:
|
69
|
-
sweep :topping { |t| t.strip }
|
103
|
+
...
|
104
|
+
sweep(:topping, :strip, :dumb_quotes) { |topping| topping.downcase }
|
70
105
|
end
|
71
106
|
```
|
72
107
|
|
108
|
+
If you have an object with lots of attributes that need cleaning (because, say, they were loaded from the database), you can do that, too:
|
109
|
+
|
110
|
+
```ruby
|
111
|
+
dessert.sweep_up!
|
112
|
+
# or:
|
113
|
+
Sundae.sweep_up!(dessert)
|
114
|
+
```
|
115
|
+
|
116
|
+
### Future Ideas
|
117
|
+
|
73
118
|
#### Other Ways to Sweep
|
74
119
|
|
75
120
|
Rails models are clearly the natural use-case for this. So it would make sense to have an easy way to auto-clean up models in a table. We'll see. Right now, this works (though it's slow):
|
data/Rakefile
CHANGED
data/lib/tiny_sweeper.rb
CHANGED
@@ -1,13 +1,21 @@
|
|
1
|
+
require 'tiny_sweeper/brooms'
|
2
|
+
require 'tiny_sweeper/broom_closet'
|
3
|
+
|
1
4
|
module TinySweeper
|
2
5
|
module ClassMethods
|
3
|
-
def sweep(
|
6
|
+
def sweep(field_names, *broom_names, &sweeper)
|
4
7
|
Array(field_names).each do |field_name|
|
5
8
|
stop_if_we_have_seen_this_before!(field_name)
|
9
|
+
warn_about_missing_brooms(broom_names)
|
6
10
|
|
7
11
|
overrides_module.module_eval do
|
8
12
|
define_method("#{field_name}=") do |value|
|
9
13
|
if value
|
10
|
-
|
14
|
+
cleaned_up = broom_names.inject(value) { |accum, broom_name|
|
15
|
+
::TinySweeper::Brooms.fetch(broom_name).call(accum)
|
16
|
+
}
|
17
|
+
cleaned_up = sweeper.call(cleaned_up) if sweeper
|
18
|
+
super(cleaned_up)
|
11
19
|
else
|
12
20
|
super(value)
|
13
21
|
end
|
@@ -41,6 +49,14 @@ module TinySweeper
|
|
41
49
|
|
42
50
|
@swept_fields << field_name
|
43
51
|
end
|
52
|
+
|
53
|
+
def warn_about_missing_brooms(brooms)
|
54
|
+
brooms.each do |broom|
|
55
|
+
unless ::TinySweeper::Brooms.has_broom?(broom)
|
56
|
+
warn "TinySweeper doesn't have this broom: #{broom}"
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
44
60
|
end
|
45
61
|
|
46
62
|
def self.included(base)
|
@@ -51,6 +67,3 @@ module TinySweeper
|
|
51
67
|
self.class.sweep_up!(self)
|
52
68
|
end
|
53
69
|
end
|
54
|
-
|
55
|
-
# Do it on all fields, by default? Or be explicit?
|
56
|
-
# TODO: add EagerSweeper, which loops over attributes. But how would it sweep?
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module TinySweeper
|
2
|
+
module BroomCloset
|
3
|
+
def self.blanks_to_nil(value)
|
4
|
+
if value == ''
|
5
|
+
nil
|
6
|
+
else
|
7
|
+
value
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.strip(value)
|
12
|
+
value && value.strip
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.dumb_quotes(value)
|
16
|
+
return nil if value.nil?
|
17
|
+
|
18
|
+
# Stolen shamelessly from
|
19
|
+
# https://github.com/yob/dumb_quotes/blob/master/lib/dumb_quotes/ar_extend.rb:
|
20
|
+
|
21
|
+
# single quotes
|
22
|
+
value = value.gsub("\xE2\x80\x98","'") # U+2018
|
23
|
+
value = value.gsub("\xE2\x80\x99","'") # U+2019
|
24
|
+
value = value.gsub("\xCA\xBC","'") # U+02BC
|
25
|
+
|
26
|
+
# double quotes
|
27
|
+
value = value.gsub("\xE2\x80\x9C",'"') # U+201C
|
28
|
+
value = value.gsub("\xE2\x80\x9D",'"') # U+201D
|
29
|
+
value = value.gsub("\xCB\xAE",'"') # U+02EE
|
30
|
+
|
31
|
+
value
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
BroomCloset.methods.each do |broom|
|
36
|
+
Brooms.add(broom) { |value|
|
37
|
+
BroomCloset.send(broom, value)
|
38
|
+
}
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module TinySweeper
|
2
|
+
module Brooms
|
3
|
+
def self.add(broom_name, &block)
|
4
|
+
(@brooms ||= {})[broom_name] = block
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.has_broom?(broom_name)
|
8
|
+
(@brooms ||= {}).has_key?(broom_name)
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.fetch(broom_name)
|
12
|
+
if has_broom?(broom_name)
|
13
|
+
(@brooms ||= {})[broom_name]
|
14
|
+
else
|
15
|
+
raise MissingBroomException, broom_name
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
class MissingBroomException < ::StandardError
|
21
|
+
def initialize(broom_name)
|
22
|
+
super("TinySweeper doesn't have this broom: #{broom_name}")
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/lib/tiny_sweeper/version.rb
CHANGED
data/spec/spec_helper.rb
CHANGED
@@ -1,3 +1,8 @@
|
|
1
|
+
require "codeclimate-test-reporter"
|
2
|
+
CodeClimate::TestReporter.start
|
3
|
+
|
4
|
+
require 'tiny_sweeper'
|
5
|
+
|
1
6
|
# This file was generated by the `rspec --init` command. Conventionally, all
|
2
7
|
# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
|
3
8
|
# The generated `.rspec` file contains `--require spec_helper` which will cause
|
@@ -50,17 +55,6 @@ RSpec.configure do |config|
|
|
50
55
|
config.filter_run :focus
|
51
56
|
config.run_all_when_everything_filtered = true
|
52
57
|
|
53
|
-
# Limits the available syntax to the non-monkey patched syntax that is
|
54
|
-
# recommended. For more details, see:
|
55
|
-
# - http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax
|
56
|
-
# - http://teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
|
57
|
-
# - http://myronmars.to/n/dev-blog/2014/05/notable-changes-in-rspec-3#new__config_option_to_disable_rspeccore_monkey_patching
|
58
|
-
config.disable_monkey_patching!
|
59
|
-
|
60
|
-
# This setting enables warnings. It's recommended, but in some cases may
|
61
|
-
# be too noisy due to issues in dependencies.
|
62
|
-
config.warnings = true
|
63
|
-
|
64
58
|
# Many RSpec users commonly either run the entire suite or an individual
|
65
59
|
# file, and it's useful to allow more verbose output when running an
|
66
60
|
# individual spec file.
|
@@ -75,6 +69,18 @@ RSpec.configure do |config|
|
|
75
69
|
# end of the spec run, to help surface which specs are running
|
76
70
|
# particularly slow.
|
77
71
|
config.profile_examples = 10
|
72
|
+
=end
|
73
|
+
|
74
|
+
# This setting enables warnings. It's recommended, but in some cases may
|
75
|
+
# be too noisy due to issues in dependencies.
|
76
|
+
config.warnings = true
|
77
|
+
|
78
|
+
# Limits the available syntax to the non-monkey patched syntax that is
|
79
|
+
# recommended. For more details, see:
|
80
|
+
# - http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax
|
81
|
+
# - http://teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
|
82
|
+
# - http://myronmars.to/n/dev-blog/2014/05/notable-changes-in-rspec-3#new__config_option_to_disable_rspeccore_monkey_patching
|
83
|
+
config.disable_monkey_patching!
|
78
84
|
|
79
85
|
# Run specs in random order to surface order dependencies. If you find an
|
80
86
|
# order dependency and want to debug it, you can fix the order by providing
|
@@ -87,5 +93,4 @@ RSpec.configure do |config|
|
|
87
93
|
# test failures related to randomization by passing the same `--seed` value
|
88
94
|
# as the one that triggered the failure.
|
89
95
|
Kernel.srand config.seed
|
90
|
-
=end
|
91
96
|
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
RSpec.describe 'the brooms in the BroomCloset' do
|
2
|
+
describe 'blanks_to_nil' do
|
3
|
+
it 'turns empty strings into nil' do
|
4
|
+
expect(TinySweeper::BroomCloset.blanks_to_nil('')).to be_nil
|
5
|
+
end
|
6
|
+
it 'leaves nil values alone' do
|
7
|
+
expect(TinySweeper::BroomCloset.blanks_to_nil(nil)).to be_nil
|
8
|
+
end
|
9
|
+
it 'leaves whitespace-y strings alone' do
|
10
|
+
expect(TinySweeper::BroomCloset.blanks_to_nil(' ')).to eq(' ')
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
describe 'strip' do
|
15
|
+
it 'strips leading and/or trailing whitespace' do
|
16
|
+
expect(TinySweeper::BroomCloset.strip(' hello')).to eq('hello')
|
17
|
+
expect(TinySweeper::BroomCloset.strip('hello ')).to eq('hello')
|
18
|
+
expect(TinySweeper::BroomCloset.strip(' hello ')).to eq('hello')
|
19
|
+
end
|
20
|
+
it 'leaves nil values alone' do
|
21
|
+
expect(TinySweeper::BroomCloset.strip(nil)).to be_nil
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe 'dumb_quotes' do
|
26
|
+
it 'replaces smart quotes with dumb quotes in strings' do
|
27
|
+
expect(TinySweeper::BroomCloset.dumb_quotes("abc‘")).to eq(%q{abc'})
|
28
|
+
expect(TinySweeper::BroomCloset.dumb_quotes("abc’")).to eq(%q{abc'})
|
29
|
+
expect(TinySweeper::BroomCloset.dumb_quotes("abcʼ")).to eq(%q{abc'})
|
30
|
+
expect(TinySweeper::BroomCloset.dumb_quotes("abc“")).to eq(%q{abc"})
|
31
|
+
expect(TinySweeper::BroomCloset.dumb_quotes("abc”")).to eq(%q{abc"})
|
32
|
+
expect(TinySweeper::BroomCloset.dumb_quotes("abcˮ")).to eq(%q{abc"})
|
33
|
+
end
|
34
|
+
it 'leaves nil values alone' do
|
35
|
+
expect(TinySweeper::BroomCloset.dumb_quotes(nil)).to be_nil
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
data/spec/tiny_sweeper_spec.rb
CHANGED
@@ -1,7 +1,4 @@
|
|
1
|
-
|
2
|
-
require 'tiny_sweeper'
|
3
|
-
|
4
|
-
describe 'cleaning fields' do
|
1
|
+
RSpec.describe 'cleaning fields' do
|
5
2
|
class Contract
|
6
3
|
attr_accessor :name, :notes
|
7
4
|
|
@@ -32,27 +29,6 @@ describe 'cleaning fields' do
|
|
32
29
|
expect(contract.notes).to be_nil
|
33
30
|
end
|
34
31
|
|
35
|
-
describe 'sweeping up ALL the fields at once' do
|
36
|
-
let(:the_contract) {
|
37
|
-
Contract.new.tap do |c|
|
38
|
-
c.name = ' will be upcased '
|
39
|
-
c.notes = ' will be stripped '
|
40
|
-
end
|
41
|
-
}
|
42
|
-
|
43
|
-
it 'can clean itself' do
|
44
|
-
the_contract.sweep_up!
|
45
|
-
expect(the_contract.name).to eq ' WILL BE UPCASED '
|
46
|
-
expect(the_contract.notes).to eq 'will be stripped'
|
47
|
-
end
|
48
|
-
|
49
|
-
it 'can be cleaned from the class' do
|
50
|
-
Contract.sweep_up!(the_contract)
|
51
|
-
expect(the_contract.name).to eq ' WILL BE UPCASED '
|
52
|
-
expect(the_contract.notes).to eq 'will be stripped'
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
32
|
it 'will bark if you try to re-define a field twice' do
|
57
33
|
some_class = Class.new
|
58
34
|
some_class.send(:include, TinySweeper)
|
@@ -64,7 +40,7 @@ describe 'cleaning fields' do
|
|
64
40
|
|
65
41
|
expect {
|
66
42
|
some_class.send(:sweep, :name, &:upcase)
|
67
|
-
}.to raise_error
|
43
|
+
}.to raise_error("Don't sweep name twice!")
|
68
44
|
end
|
69
45
|
|
70
46
|
it "will let you sweep an inherited method" do
|
@@ -84,11 +60,11 @@ describe 'cleaning fields' do
|
|
84
60
|
end
|
85
61
|
end
|
86
62
|
|
87
|
-
describe '
|
63
|
+
RSpec.describe 'defining the same sweep rule on many fields at once' do
|
88
64
|
class Address
|
89
65
|
attr_accessor :address1, :address2, :city, :state, :zip
|
90
66
|
include TinySweeper
|
91
|
-
sweep :address1, :address2, :city, :state, :zip, &:strip
|
67
|
+
sweep [:address1, :address2, :city, :state, :zip], &:strip
|
92
68
|
end
|
93
69
|
|
94
70
|
it 'can do it' do
|
@@ -107,3 +83,104 @@ describe 'sweeping many fields at once, in the same way' do
|
|
107
83
|
expect(address.zip ).to eq('06510')
|
108
84
|
end
|
109
85
|
end
|
86
|
+
|
87
|
+
RSpec.describe 'defining sweep rules with built-in brooms' do
|
88
|
+
describe 'the simple case' do
|
89
|
+
class Sundae
|
90
|
+
attr_accessor :ice_cream
|
91
|
+
include TinySweeper
|
92
|
+
sweep :ice_cream, :blanks_to_nil
|
93
|
+
end
|
94
|
+
|
95
|
+
it 'can do it' do
|
96
|
+
sundae = Sundae.new
|
97
|
+
sundae.ice_cream = ''
|
98
|
+
expect(sundae.ice_cream).to be_nil
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
describe 'using multiple brooms' do
|
103
|
+
it 'calls them all, left-to-right' do
|
104
|
+
class Sundae
|
105
|
+
attr_accessor :topping
|
106
|
+
include TinySweeper
|
107
|
+
sweep :topping, :strip, :blanks_to_nil
|
108
|
+
end
|
109
|
+
sundae = Sundae.new
|
110
|
+
sundae.topping = ' '
|
111
|
+
expect(sundae.topping).to be_nil
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
describe 'using multiple brooms, and a block at the end' do
|
116
|
+
it 'calls the brooms, left-to-right, and then the block' do
|
117
|
+
class Sundae
|
118
|
+
attr_accessor :nuts
|
119
|
+
include TinySweeper
|
120
|
+
# NB: your block could get passed a nil value.
|
121
|
+
sweep(:nuts, :strip, :blanks_to_nil) { |v| v && v.upcase }
|
122
|
+
end
|
123
|
+
sundae = Sundae.new
|
124
|
+
sundae.nuts = ' '
|
125
|
+
expect(sundae.nuts).to be_nil
|
126
|
+
sundae.nuts = ' walnuts '
|
127
|
+
expect(sundae.nuts).to eq('WALNUTS')
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
context "when you name a broom that doesn't exist" do
|
132
|
+
it "warns when you define the rule, and raises when you sweep a value" do
|
133
|
+
class Milkshake
|
134
|
+
attr_accessor :flavor
|
135
|
+
include TinySweeper
|
136
|
+
end
|
137
|
+
|
138
|
+
expect {
|
139
|
+
class Milkshake
|
140
|
+
sweep :flavor, :make_more_delicious
|
141
|
+
end
|
142
|
+
}.to output(/TinySweeper doesn't have.*make_more_delicious/).to_stderr
|
143
|
+
|
144
|
+
milkshake = Milkshake.new
|
145
|
+
expect {
|
146
|
+
milkshake.flavor = 'cherries jubilee'
|
147
|
+
}.to raise_exception(TinySweeper::MissingBroomException)
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
describe 'adding a custom broom' do
|
152
|
+
it 'lets the broom be used' do
|
153
|
+
TinySweeper::Brooms.add(:sanitize_sizes) { |v| v.downcase[0] }
|
154
|
+
class Milkshake
|
155
|
+
attr_accessor :size
|
156
|
+
include TinySweeper
|
157
|
+
sweep :size, :sanitize_sizes
|
158
|
+
end
|
159
|
+
|
160
|
+
milkshake = Milkshake.new
|
161
|
+
milkshake.size = 'LARGE'
|
162
|
+
expect(milkshake.size).to eq('l')
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
RSpec.describe 'Using #sweep_up! to sweep up all the fields at once' do
|
168
|
+
let(:the_contract) {
|
169
|
+
Contract.new.tap do |c|
|
170
|
+
c.name = ' will be upcased '
|
171
|
+
c.notes = ' will be stripped '
|
172
|
+
end
|
173
|
+
}
|
174
|
+
|
175
|
+
it 'can clean itself' do
|
176
|
+
the_contract.sweep_up!
|
177
|
+
expect(the_contract.name).to eq ' WILL BE UPCASED '
|
178
|
+
expect(the_contract.notes).to eq 'will be stripped'
|
179
|
+
end
|
180
|
+
|
181
|
+
it 'can be cleaned from the class' do
|
182
|
+
Contract.sweep_up!(the_contract)
|
183
|
+
expect(the_contract.name).to eq ' WILL BE UPCASED '
|
184
|
+
expect(the_contract.notes).to eq 'will be stripped'
|
185
|
+
end
|
186
|
+
end
|
data/tiny-sweeper.png
ADDED
Binary file
|
data/tiny_sweeper.gemspec
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tiny_sweeper
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dan Bernier
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2016-08-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -24,6 +24,34 @@ dependencies:
|
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '1.5'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
27
55
|
description: |-
|
28
56
|
Tiny Sweeper is a handy way to clean attributes on your Rails models,
|
29
57
|
though it's independent of Rails, and can be used in any Ruby project.
|
@@ -40,14 +68,19 @@ files:
|
|
40
68
|
- ".ruby-gemset"
|
41
69
|
- ".ruby-version"
|
42
70
|
- ".travis.yml"
|
71
|
+
- ChangeLog
|
43
72
|
- Gemfile
|
44
73
|
- Gemfile.lock
|
45
74
|
- README.md
|
46
75
|
- Rakefile
|
47
76
|
- lib/tiny_sweeper.rb
|
77
|
+
- lib/tiny_sweeper/broom_closet.rb
|
78
|
+
- lib/tiny_sweeper/brooms.rb
|
48
79
|
- lib/tiny_sweeper/version.rb
|
49
80
|
- spec/spec_helper.rb
|
81
|
+
- spec/tiny_sweeper/broom_closet_spec.rb
|
50
82
|
- spec/tiny_sweeper_spec.rb
|
83
|
+
- tiny-sweeper.png
|
51
84
|
- tiny_sweeper.gemspec
|
52
85
|
homepage: https://github.com/ContinuityControl/tiny_sweeper
|
53
86
|
licenses:
|
@@ -69,10 +102,11 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
69
102
|
version: '0'
|
70
103
|
requirements: []
|
71
104
|
rubyforge_project:
|
72
|
-
rubygems_version: 2.
|
105
|
+
rubygems_version: 2.5.1
|
73
106
|
signing_key:
|
74
107
|
specification_version: 4
|
75
108
|
summary: A tiny helper to clean your inputs
|
76
109
|
test_files:
|
77
110
|
- spec/spec_helper.rb
|
111
|
+
- spec/tiny_sweeper/broom_closet_spec.rb
|
78
112
|
- spec/tiny_sweeper_spec.rb
|