redactor 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7930ab02836e02e6b1a54666b637cef619becde9
4
- data.tar.gz: 5005ab98df807eed1cbecb5618b8db60be254629
3
+ metadata.gz: 7a2cd8062ddf0427c5f9e0658c10ca0648773eb4
4
+ data.tar.gz: b991cd754a805b19ad6db954537b0c41ff91a5fc
5
5
  SHA512:
6
- metadata.gz: 1ea215bfc5261dbbb927fe8d72dd0e6f206205ae4ac2e1b502034d14ae9799a045ce2a07c9fe1965e0b5380edcb414ccec58fb077d5bed9ff92e616a2fb6825e
7
- data.tar.gz: 80ea8bbce965ea23c314b6c8e004f98617355dff8af5be3225f544b65d319354b775c7e3310bb9c2650597182d5a06c6d55d9174451df06e4efd5493cfee9ae2
6
+ metadata.gz: cc6e7d25df877a0d796b42b43687c84a9da5213233e72fe8380b1a61a7ad8a192f3c81045f4d4c49dab75e83b1e48397238d9562fe8b7394f66157f51e1701ec
7
+ data.tar.gz: 6a805cb5eeb3470149f2e44bcb7d31d495ecfd7822d7e074918f11d2dc5f10050bcbc21d793bd179b7716ebbeaec8f8a82d6032649d599876316b2974fdc21cf
data/.travis.yml ADDED
@@ -0,0 +1,5 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.1.1
4
+ - 2.2.2
5
+ - ruby-head
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # redactor
1
+ # redactor [![Gem Version](https://badge.fury.io/rb/redactor.svg)](https://rubygems.org/gems/redactor) [![Build Status](https://travis-ci.org/TimPetricola/redactor.svg)](https://travis-ci.org/TimPetricola/redactor)
2
2
 
3
3
  Redact parts of text defined by custom rules (e.g. emails, phone numbers).
4
4
 
@@ -10,7 +10,7 @@ require 'redactor'
10
10
  input = 'To ride a kayak, contact me: tim.petricola@gmail.com or 1 234 567 8901.'
11
11
 
12
12
  # these rules are only good enough for an example
13
- Redactor.define do
13
+ @redactor = Redactor.new do
14
14
  # US phone
15
15
  rule :phone, /(\+?1[ \.-]?)?\(?\d{3}\)?[ \.-]?\d{3}[ \.-]?\d{4}/
16
16
 
@@ -29,24 +29,32 @@ Redactor.define do
29
29
  end
30
30
  end
31
31
 
32
- Redactor.format(input)
32
+ redactor.format(input)
33
33
  # => "To ride a [REDACTED], contact me: [REDACTED] or [REDACTED]."
34
34
 
35
- Redactor.format(input) do |extract|
35
+ redactor.default_replacement = '$#@!&'
36
+ # => "To ride a $\#@!&, contact me: $\#@!& or $\#@!&."
37
+
38
+ redactor.format(input) do |extract|
36
39
  "[#{extract.reason.upcase}]"
37
40
  end
38
41
  # => "To ride a [PALINDROME], contact me: [EMAIL] or [PHONE]."
39
42
 
40
- Redactor.extract(input)
41
- # => [#<Redactor::Extract:0x007fc05c6b25a0
43
+ redactor.extract(input)
44
+ # => [#<Redactor::Extract:0x007ff259586008
42
45
  # @finish=70,
43
- # @rule=#<Redactor::Rule:0x007fc05f203970 @block=nil, @reason=:phone, @regex=/(\+?1[ \.-]?)?\(?\d{3}\)?[ \.-]?\d{3}[ \.-]?\d{4}/>,
46
+ # @rule=#<Redactor::Rule:0x007ff258b5aa20 @block=nil, @reason=:phone, @regex=/(\+?1[ \.-]?)?\(?\d{3}\)?[ \.-]?\d{3}[ \.-]?\d{4}/>,
44
47
  # @start=56,
45
48
  # @value="1 234 567 8901">,
46
- # #<Redactor::Extract:0x007fc05c6b2230 @finish=52, @rule=#<Redactor::Rule:0x007fc05f203948 @block=nil, @reason=:email, @regex=/[\w\.]+(@|at)\w+(\.|dot)\w{1,3}/i>, @start=29, @value="tim.petricola@gmail.com">,
47
- # #<Redactor::Extract:0x007fc05c6b19c0
49
+ # #<Redactor::Extract:0x007ff259585cc0
50
+ # @finish=52,
51
+ # @rule=#<Redactor::Rule:0x007ff258b5a9f8 @block=nil, @reason=:email, @regex=/[\w\.]+(@|at)\w+(\.|dot)\w{1,3}/i>,
52
+ # @start=29,
53
+ # @value="tim.petricola@gmail.com">,
54
+ # #<Redactor::Extract:0x007ff259585518
48
55
  # @finish=15,
49
- # @rule=#<Redactor::Rule:0x007fc05f2038d0 @block=#<Proc:0x007fc05f2038f8@/Users/Tim/Projects/redact/test.rb:13>, @reason=:palindrome, @regex=nil>,
56
+ # @rule=#<Redactor::Rule:0x007ff258b5a980 @block=#<Proc:0x007ff258b5a9a8@/Users/Tim/Projects/redactor/test.rb:14>, @reason=:palindrome, @regex=nil>,
50
57
  # @start=10,
51
58
  # @value="kayak">]
59
+
52
60
  ```
data/lib/redactor/dsl.rb CHANGED
@@ -1,12 +1,18 @@
1
- module Redactor
1
+ class Redactor
2
2
  class DSL
3
+ attr_reader :redactor
4
+
5
+ def initialize(redactor)
6
+ @redactor = redactor
7
+ end
8
+
3
9
  def rule(reason, regex = nil, &block)
4
10
  rule = Rule.new(reason, regex, &block)
5
- Redactor.register_rule(rule)
11
+ redactor.register_rule(rule)
6
12
  end
7
13
 
8
- def self.run(block)
9
- new.instance_eval(&block)
14
+ def self.run(redactor, block)
15
+ new(redactor).instance_eval(&block)
10
16
  end
11
17
  end
12
18
  end
@@ -1,4 +1,4 @@
1
- module Redactor
1
+ class Redactor
2
2
  class Extract
3
3
  attr_reader :rule, :value, :start, :finish
4
4
 
data/lib/redactor/rule.rb CHANGED
@@ -1,4 +1,4 @@
1
- module Redactor
1
+ class Redactor
2
2
  class Rule
3
3
  attr_reader :reason, :regex, :block
4
4
 
@@ -1,3 +1,3 @@
1
- module Redactor
2
- VERSION = '0.1.0'
1
+ class Redactor
2
+ VERSION = '0.2.0'
3
3
  end
data/lib/redactor.rb CHANGED
@@ -1,30 +1,22 @@
1
- require 'redactor/clear'
2
- require 'redactor/dsl'
3
- require 'redactor/extract'
4
- require 'redactor/rule'
5
-
6
- module Redactor
1
+ class Redactor
7
2
  DEFAULT_REPLACEMENT = '[REDACTED]'.freeze
8
3
 
9
- class << self
10
- attr_accessor :rules
11
- attr_accessor :default_replacement
12
- end
4
+ attr_accessor :rules, :default_replacement
13
5
 
14
- self.rules = []
15
- self.default_replacement = DEFAULT_REPLACEMENT
6
+ def initialize(rules = [], &block)
7
+ @default_replacement = DEFAULT_REPLACEMENT
8
+ @rules = Array(rules)
16
9
 
17
- def self.define(&block)
18
- DSL.run(block)
10
+ DSL.run(self, block) if block_given?
19
11
  end
20
12
 
21
- def self.register_rule(rule)
13
+ def register_rule(rule)
22
14
  rules.push(rule)
23
15
  end
24
16
 
25
17
  # returns a list of Extract objects (including position and value)
26
18
  # matching predefined rules
27
- def self.extract(from)
19
+ def extract(from)
28
20
  rules.reduce([]) do |extracts, rule|
29
21
  new_extracts = rule.extract(from).select do |extract|
30
22
  # do not consider new extract if colliding with existing one
@@ -36,10 +28,14 @@ module Redactor
36
28
 
37
29
  # replaces parts of text by [REDACTED]. The replacement string can be
38
30
  # customized by passing a block taking the Extract object as an argument
39
- def self.format(text, &block)
31
+ def format(text, &block)
40
32
  extract(text).each_with_object(text.clone) do |extract, redacted_text|
41
33
  sub = block_given? ? block.call(extract) : default_replacement
42
34
  redacted_text[extract.start...extract.finish] = sub
43
35
  end
44
36
  end
45
37
  end
38
+
39
+ require 'redactor/dsl'
40
+ require 'redactor/extract'
41
+ require 'redactor/rule'
@@ -8,13 +8,16 @@ describe Redactor::DSL do
8
8
  rule :foo, /foo/
9
9
  end
10
10
 
11
+ redactor = double
11
12
  rule = double('Redactor::Rule')
13
+
12
14
  expect(Redactor::Rule).to(
13
15
  receive(:new).with(:foo, /foo/).and_return(rule)
14
16
  )
15
- expect(Redactor).to receive(:register_rule).with(rule)
16
17
 
17
- Redactor::DSL.run(definitions)
18
+ expect(redactor).to receive(:register_rule).with(rule)
19
+
20
+ Redactor::DSL.run(redactor, definitions)
18
21
  end
19
22
  end
20
23
 
@@ -26,16 +29,19 @@ describe Redactor::DSL do
26
29
  rule(:foo, &proc)
27
30
  end
28
31
 
32
+ redactor = double
29
33
  rule = double('Redactor::Rule')
34
+
30
35
  expect(Redactor::Rule).to(
31
36
  receive(:new).with(:foo, nil) do |*_args, &block|
32
37
  expect(proc).to be(block)
33
38
  rule
34
39
  end
35
40
  )
36
- expect(Redactor).to receive(:register_rule).with(rule)
37
41
 
38
- Redactor::DSL.run(definitions)
42
+ expect(redactor).to receive(:register_rule).with(rule)
43
+
44
+ Redactor::DSL.run(redactor, definitions)
39
45
  end
40
46
  end
41
47
  end
@@ -1,16 +1,16 @@
1
1
  require 'spec_helper'
2
2
 
3
- RSpec::Matchers.define :be_redacted do |reason|
3
+ RSpec::Matchers.define :be_redacted do |reason, redactor|
4
4
  match do |actual|
5
- Redactor.extract(actual).any? do |extract|
5
+ redactor.extract(actual).any? do |extract|
6
6
  extract.value == actual && extract.reason == reason
7
7
  end
8
8
  end
9
9
  end
10
10
 
11
11
  describe 'Redactor rules' do
12
- before do
13
- Redactor.define do
12
+ let(:redactor) do
13
+ Redactor.new do
14
14
  # US phone
15
15
  rule :phone, /(\+?1[ \.-]?)?\(?\d{3}\)?[ \.-]?\d{3}[ \.-]?\d{4}/
16
16
 
@@ -19,8 +19,6 @@ describe 'Redactor rules' do
19
19
  end
20
20
  end
21
21
 
22
- after { Redactor.clear }
23
-
24
22
  {
25
23
  '1 234 567 8901' => :phone,
26
24
  '12345678901' => :phone,
@@ -36,7 +34,7 @@ describe 'Redactor rules' do
36
34
  'foo AT bar DOT baz' => :email
37
35
  }.each do |value, reason|
38
36
  describe(value) do
39
- it { should be_redacted(reason) }
37
+ it { should be_redacted(reason, redactor) }
40
38
  end
41
39
  end
42
40
  end
@@ -0,0 +1,81 @@
1
+ require 'spec_helper'
2
+
3
+ describe Redactor do
4
+ let(:foobar_rule) { Redactor::Rule.new(:foobar, /foobar/) }
5
+ let(:barbaz_rule) { Redactor::Rule.new(:barbaz, /barbaz/) }
6
+
7
+ it 'accepts a single rule' do
8
+ redactor = Redactor.new(foobar_rule)
9
+ expect(redactor.rules).to eq [foobar_rule]
10
+ end
11
+
12
+ it 'accepts an array of rule' do
13
+ redactor = Redactor.new([foobar_rule])
14
+ expect(redactor.rules).to eq [foobar_rule]
15
+ end
16
+
17
+ it 'accepts a block' do
18
+ redactor = Redactor.new do
19
+ rule :foo, /foo/
20
+ end
21
+ expect(redactor.rules.length).to be 1
22
+ expect(redactor.rules[0].reason).to eq :foo
23
+ end
24
+
25
+ describe '.extract' do
26
+ let(:redactor) do
27
+ redactor = Redactor.new
28
+ redactor.register_rule(foobar_rule)
29
+ redactor.register_rule(barbaz_rule)
30
+ redactor
31
+ end
32
+
33
+ it 'return extracts' do
34
+ text = 'hello barbaz foobar'
35
+ results = redactor.extract(text)
36
+ expect(results.first.rule).to be foobar_rule
37
+ expect(results.first.value).to eq 'foobar'
38
+ expect(results.last.rule).to be barbaz_rule
39
+ expect(results.last.value).to eq 'barbaz'
40
+ end
41
+
42
+ context 'colliding rules' do
43
+ it "only keep first defined rule's match" do
44
+ text = 'hello foobarbaz'
45
+ results = redactor.extract(text)
46
+ expect(results.size).to eq 1
47
+ expect(results.first.rule).to be foobar_rule
48
+ end
49
+ end
50
+ end
51
+
52
+ describe '.format' do
53
+ let(:redactor) do
54
+ redactor = Redactor.new
55
+ redactor.register_rule(foobar_rule)
56
+ redactor.register_rule(barbaz_rule)
57
+ redactor
58
+ end
59
+
60
+ it 'replaces redacted parts' do
61
+ text = 'hello barbaz foobar'
62
+ expect(redactor.format(text)).to eq 'hello [REDACTED] [REDACTED]'
63
+ end
64
+
65
+ it 'accepts a block for redacted strings' do
66
+ text = 'hello barbaz foobar'
67
+
68
+ redacted = redactor.format(text) do |extract|
69
+ "[#{extract.reason.upcase}]"
70
+ end
71
+
72
+ expect(redacted).to eq 'hello [BARBAZ] [FOOBAR]'
73
+ end
74
+
75
+ it 'does not mutate original string' do
76
+ text = 'hello barbaz foobar'
77
+ redactor.format(text)
78
+ expect(text).to eq 'hello barbaz foobar'
79
+ end
80
+ end
81
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: redactor
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tim Petricola
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-10-28 00:00:00.000000000 Z
11
+ date: 2015-10-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec
@@ -46,24 +46,23 @@ extensions: []
46
46
  extra_rdoc_files: []
47
47
  files:
48
48
  - ".gitignore"
49
+ - ".travis.yml"
49
50
  - Gemfile
50
51
  - Gemfile.lock
51
52
  - LICENSE
52
53
  - README.md
53
54
  - Rakefile
54
55
  - lib/redactor.rb
55
- - lib/redactor/clear.rb
56
56
  - lib/redactor/dsl.rb
57
57
  - lib/redactor/extract.rb
58
58
  - lib/redactor/rule.rb
59
59
  - lib/redactor/version.rb
60
60
  - redactor.gemspec
61
- - spec/lib/clear_spec.rb
62
- - spec/lib/dsl_spec.rb
63
- - spec/lib/extract_spec.rb
64
- - spec/lib/redact_spec.rb
65
- - spec/lib/rule_spec.rb
66
- - spec/lib/rules_spec.rb
61
+ - spec/lib/redactor/dsl_spec.rb
62
+ - spec/lib/redactor/extract_spec.rb
63
+ - spec/lib/redactor/rule_spec.rb
64
+ - spec/lib/redactor/rules_spec.rb
65
+ - spec/lib/redactor_spec.rb
67
66
  - spec/spec_helper.rb
68
67
  homepage: https://github.com/TimPetricola/redactor
69
68
  licenses:
@@ -85,15 +84,15 @@ required_rubygems_version: !ruby/object:Gem::Requirement
85
84
  version: '0'
86
85
  requirements: []
87
86
  rubyforge_project:
88
- rubygems_version: 2.2.0
87
+ rubygems_version: 2.2.2
89
88
  signing_key:
90
89
  specification_version: 4
91
90
  summary: Redact parts of text defined by custom rules (e.g. emails, phone numbers)
92
91
  test_files:
93
- - spec/lib/clear_spec.rb
94
- - spec/lib/dsl_spec.rb
95
- - spec/lib/extract_spec.rb
96
- - spec/lib/redact_spec.rb
97
- - spec/lib/rule_spec.rb
98
- - spec/lib/rules_spec.rb
92
+ - spec/lib/redactor/dsl_spec.rb
93
+ - spec/lib/redactor/extract_spec.rb
94
+ - spec/lib/redactor/rule_spec.rb
95
+ - spec/lib/redactor/rules_spec.rb
96
+ - spec/lib/redactor_spec.rb
99
97
  - spec/spec_helper.rb
98
+ has_rdoc:
@@ -1,5 +0,0 @@
1
- module Redactor
2
- def self.clear
3
- self.rules = []
4
- end
5
- end
@@ -1,11 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe 'clear' do
4
- after { Redactor.clear }
5
-
6
- it 'unload all rules' do
7
- Redactor.clear
8
- Redactor.register_rule(double)
9
- expect { Redactor.clear }.to change { Redactor.rules.size }.from(1).to(0)
10
- end
11
- end
@@ -1,55 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Redactor do
4
- before do
5
- @foobar_rule = Redactor::Rule.new(:foobar, /foobar/)
6
- @barbaz_rule = Redactor::Rule.new(:barbaz, /barbaz/)
7
- Redactor.register_rule(@foobar_rule)
8
- Redactor.register_rule(@barbaz_rule)
9
- end
10
-
11
- after { Redactor.clear }
12
-
13
- describe '.extract' do
14
- it 'return extracts' do
15
- text = 'hello barbaz foobar'
16
- results = Redactor.extract(text)
17
- expect(results.first.rule).to be @foobar_rule
18
- expect(results.first.value).to eq 'foobar'
19
- expect(results.last.rule).to be @barbaz_rule
20
- expect(results.last.value).to eq 'barbaz'
21
- end
22
-
23
- context 'colliding rules' do
24
- it "only keep first defined rule's match" do
25
- text = 'hello foobarbaz'
26
- results = Redactor.extract(text)
27
- expect(results.size).to eq 1
28
- expect(results.first.rule).to be @foobar_rule
29
- end
30
- end
31
- end
32
-
33
- describe '.format' do
34
- it 'replaces redacted parts' do
35
- text = 'hello barbaz foobar'
36
- expect(Redactor.format(text)).to eq 'hello [REDACTED] [REDACTED]'
37
- end
38
-
39
- it 'accepts a block for redacted strings' do
40
- text = 'hello barbaz foobar'
41
-
42
- redacted = Redactor.format(text) do |extract|
43
- "[#{extract.reason.upcase}]"
44
- end
45
-
46
- expect(redacted).to eq 'hello [BARBAZ] [FOOBAR]'
47
- end
48
-
49
- it 'does not mutate original string' do
50
- text = 'hello barbaz foobar'
51
- Redactor.format(text)
52
- expect(text).to eq 'hello barbaz foobar'
53
- end
54
- end
55
- end
File without changes