redactor 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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