hash_filter 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +18 -1
- data/CHANGELOG.md +14 -9
- data/Gemfile +4 -0
- data/README.md +41 -28
- data/lib/hash_filter.rb +82 -1
- data/lib/hash_filter/operation.rb +25 -0
- data/lib/hash_filter/operation/delete.rb +1 -0
- data/lib/hash_filter/operation/rename.rb +2 -1
- data/lib/hash_filter/version.rb +1 -1
- data/spec/hash_filter_spec.rb +32 -0
- data/spec/spec_helper.rb +5 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 80b0149bee506b4fa89a5a335dcf391d2ef4b46e
|
4
|
+
data.tar.gz: 9b4f9eb79fa98fd51bb4572b1a0fad591010bad2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a7154e0eb2ff59b51004809604968fed59a431c608982291678fed7013925faf21dd065efb0cc4f3724fd86f92b906eca52a7e888fb73c74b467ad68abea93d8
|
7
|
+
data.tar.gz: dfa89dcd2cbec9a9aefbde9710ecaf513682aa300093f40732a2371d31581674b49dcf58173164edcc2b154da317fa601aafa6e3863c5b5adb3dce92b5043304
|
data/.travis.yml
CHANGED
@@ -1,11 +1,28 @@
|
|
1
|
+
language: ruby
|
2
|
+
sudo: false
|
3
|
+
cache: bundler
|
1
4
|
rvm:
|
2
5
|
- 1.9.3
|
3
6
|
- 2.0
|
4
7
|
- 2.1
|
8
|
+
- 2.2
|
5
9
|
- ruby-head
|
6
10
|
- jruby
|
11
|
+
- jruby-head
|
7
12
|
- rbx-2
|
13
|
+
env:
|
14
|
+
global:
|
15
|
+
- CODECLIMATE_REPO_TOKEN=0a29827fa48b1236e7c27bf9948e3ee3cb05d50630a2896014edd7b7bbf616a2
|
16
|
+
- JRUBY_OPTS='--dev -J-Xmx1024M'
|
8
17
|
matrix:
|
18
|
+
fast_finish: true
|
9
19
|
allow_failures:
|
10
20
|
- rvm: ruby-head
|
11
|
-
|
21
|
+
- rvm: jruby-head
|
22
|
+
notifications:
|
23
|
+
webhooks:
|
24
|
+
urls:
|
25
|
+
- https://webhooks.gitter.im/e/c696eaa01bc1bae73cb2
|
26
|
+
on_success: change # options: [always|never|change] default: always
|
27
|
+
on_failure: always # options: [always|never|change] default: always
|
28
|
+
on_start: false # default: false
|
data/CHANGELOG.md
CHANGED
@@ -1,22 +1,27 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
-
##
|
3
|
+
## v0.1.1
|
4
4
|
|
5
5
|
* Enhancements
|
6
|
+
* Improve docs (@splattael)
|
7
|
+
|
8
|
+
## v0.1.0
|
6
9
|
|
7
10
|
* Bug fixes
|
11
|
+
* Take over `keep` operations via `inject` (@splattael)
|
8
12
|
|
9
|
-
|
13
|
+
## v0.0.1
|
10
14
|
|
11
|
-
*
|
15
|
+
* Enhancements
|
16
|
+
* Initial implementation (@splattael)
|
17
|
+
* Implement `keep` operation (@splattael)
|
12
18
|
|
13
|
-
##
|
19
|
+
## vX.X.X
|
20
|
+
|
21
|
+
* Enhancements
|
14
22
|
|
15
23
|
* Bug fixes
|
16
|
-
* Take over `keep` operations via `inject`
|
17
24
|
|
18
|
-
|
25
|
+
* Deprecations
|
19
26
|
|
20
|
-
*
|
21
|
-
* Initial implementation
|
22
|
-
* Implement `keep` operation
|
27
|
+
* Backwards incompatible changes
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,6 +1,21 @@
|
|
1
|
+
[github]: https://github.com/neopoly/hash_filter
|
2
|
+
[doc]: http://rubydoc.info/github/neopoly/hash_filter/master/file/README.md
|
3
|
+
[gem]: https://rubygems.org/gems/hash_filter
|
4
|
+
[travis]: https://travis-ci.org/neopoly/hash_filter
|
5
|
+
[codeclimate]: https://codeclimate.com/github/neopoly/hash_filter
|
6
|
+
[inchpages]: https://inch-ci.org/github/neopoly/hash_filter
|
7
|
+
|
1
8
|
# HashFilter
|
2
9
|
|
3
|
-
[![
|
10
|
+
[![Travis](https://img.shields.io/travis/neopoly/hash_filter.svg?branch=master)][travis]
|
11
|
+
[![Gem Version](https://img.shields.io/gem/v/hash_filter.svg)][gem]
|
12
|
+
[![Code Climate](https://img.shields.io/codeclimate/github/neopoly/hash_filter.svg)][codeclimate]
|
13
|
+
[![Test Coverage](https://codeclimate.com/github/neopoly/hash_filter/badges/coverage.svg)][codeclimate]
|
14
|
+
[![Inline docs](https://inch-ci.org/github/neopoly/hash_filter.svg?branch=master&style=flat)][inchpages]
|
15
|
+
|
16
|
+
[Gem][gem] |
|
17
|
+
[Source][github] |
|
18
|
+
[Documentation][doc]
|
4
19
|
|
5
20
|
A simple hash filter.
|
6
21
|
|
@@ -21,33 +36,31 @@ Or install it yourself as:
|
|
21
36
|
## Usage
|
22
37
|
|
23
38
|
```ruby
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
# }
|
50
|
-
|
39
|
+
remove_images = HashFilter.new do
|
40
|
+
delete /\.jpg$/
|
41
|
+
delete /\.png$/
|
42
|
+
delete /\.gif$/
|
43
|
+
end
|
44
|
+
|
45
|
+
rename_html = HashFilter.new do
|
46
|
+
rename /(.*?)\.htm$/, '\1.html'
|
47
|
+
end
|
48
|
+
|
49
|
+
filter = HashFilter.new do
|
50
|
+
inject remove_images
|
51
|
+
inject rename_html
|
52
|
+
end
|
53
|
+
|
54
|
+
hash = {
|
55
|
+
"image.jpg" => "/path/to/image.jpg",
|
56
|
+
"image.png" => "/path/to/image.png",
|
57
|
+
"page.htm" => "/path/to/page.html"
|
58
|
+
}
|
59
|
+
|
60
|
+
p filter.apply hash
|
61
|
+
# {
|
62
|
+
# "page.html" => "/path/to/page.html"
|
63
|
+
# }
|
51
64
|
```
|
52
65
|
|
53
66
|
## Contributing
|
data/lib/hash_filter.rb
CHANGED
@@ -1,42 +1,117 @@
|
|
1
1
|
require 'hash_filter/operation'
|
2
2
|
|
3
|
+
# Easy hash filtering via simple operations
|
4
|
+
#
|
5
|
+
# @see README
|
3
6
|
class HashFilter
|
4
|
-
|
7
|
+
# List of operations to be applied
|
8
|
+
attr_reader :operations
|
9
|
+
|
10
|
+
# List of elements to keep before applying operations
|
11
|
+
attr_reader :keeps
|
12
|
+
|
5
13
|
protected :operations, :keeps
|
6
14
|
|
15
|
+
# Initialize a hash filter
|
16
|
+
#
|
17
|
+
# @yield [HashFilter] instance evals self if a block is provided
|
18
|
+
#
|
19
|
+
# @example
|
20
|
+
# filter = HashFilter.new do
|
21
|
+
# rename /(.*?)\.htm$/, '\1.html'
|
22
|
+
# delete /\.(jpg|gif)$/
|
23
|
+
# end
|
24
|
+
#
|
25
|
+
# filter.delete /\.png$/
|
26
|
+
#
|
27
|
+
# filter.apply(some_hash)
|
7
28
|
def initialize(&block)
|
8
29
|
@keeps = []
|
9
30
|
@operations = []
|
10
31
|
instance_eval(&block) if block
|
11
32
|
end
|
12
33
|
|
34
|
+
# Rename a key
|
35
|
+
#
|
36
|
+
# @param from [Regexp, String] rename source
|
37
|
+
# @param to [String] rename target
|
38
|
+
#
|
39
|
+
# @example
|
40
|
+
# HashFilter.new do
|
41
|
+
# rename /(.*?)\.htm$/, '\1.html'
|
42
|
+
# end
|
13
43
|
def rename(from, to)
|
14
44
|
operation Operation::Rename, from, to
|
15
45
|
end
|
16
46
|
|
47
|
+
# Delete a key
|
48
|
+
#
|
49
|
+
# @param key [Regexp, String] key to delete
|
50
|
+
#
|
51
|
+
# @example
|
52
|
+
# remove_images = HashFilter.new do
|
53
|
+
# delete /\.jpg$/
|
54
|
+
# delete /\.png$/
|
55
|
+
# delete /\.gif$/
|
56
|
+
# end
|
17
57
|
def delete(key)
|
18
58
|
operation Operation::Delete, key
|
19
59
|
end
|
20
60
|
|
61
|
+
# Combine other filters
|
62
|
+
#
|
63
|
+
# @param filter [HashFilter] other filter
|
21
64
|
def inject(filter)
|
22
65
|
@keeps.concat filter.keeps
|
23
66
|
@operations.concat filter.operations
|
24
67
|
end
|
25
68
|
|
69
|
+
# Keep given key
|
70
|
+
#
|
71
|
+
# @param key [Regexp, String] key to keep
|
72
|
+
#
|
73
|
+
# @example
|
74
|
+
# # Delete everything but keep GIFs
|
75
|
+
# HashFilter.new do
|
76
|
+
# keep /\.gif$/
|
77
|
+
# delete /.*/
|
78
|
+
# end
|
26
79
|
def keep(key)
|
27
80
|
@keeps << key
|
28
81
|
end
|
29
82
|
|
83
|
+
# Apply this filter to hash
|
84
|
+
#
|
85
|
+
# @param hash [Hash] hash (hash-like) to filter
|
30
86
|
def apply(hash)
|
31
87
|
apply_operations(@operations, hash.dup)
|
32
88
|
end
|
33
89
|
|
90
|
+
# Add a custom operation
|
91
|
+
#
|
92
|
+
# @param class_name [Operation] operation class
|
93
|
+
#
|
94
|
+
# @example
|
95
|
+
# class SwapKeyValue < HashFilter::Operation
|
96
|
+
# def execute(hash, key)
|
97
|
+
# value = hash.delete(key)
|
98
|
+
# hash[value] = key
|
99
|
+
# end
|
100
|
+
# end
|
101
|
+
#
|
102
|
+
# HashFilter.new do
|
103
|
+
# operation SwapKeyValue
|
104
|
+
# end
|
34
105
|
def operation(class_name, *args)
|
35
106
|
@operations << class_name.new(*args)
|
36
107
|
end
|
37
108
|
|
38
109
|
private
|
39
110
|
|
111
|
+
# Applies all operations to target hash
|
112
|
+
#
|
113
|
+
# @param operations [Array<Operation>] a list of operations
|
114
|
+
# @param hash [Hash] target hash
|
40
115
|
def apply_operations(operations, hash)
|
41
116
|
hash.keys.each do |key|
|
42
117
|
next if keep?(key)
|
@@ -47,10 +122,16 @@ class HashFilter
|
|
47
122
|
hash
|
48
123
|
end
|
49
124
|
|
125
|
+
# Should the key be kept?
|
126
|
+
#
|
127
|
+
# @param key [Regexp, String, Object]
|
50
128
|
def keep?(key)
|
51
129
|
@keeps.any? { |keep| keep === key }
|
52
130
|
end
|
53
131
|
|
132
|
+
# Apply a single operation
|
133
|
+
#
|
134
|
+
# @see Operation#execute
|
54
135
|
def apply_operation(operation, hash, key)
|
55
136
|
if operation.matches?(key)
|
56
137
|
operation.execute(hash, key)
|
@@ -1,13 +1,38 @@
|
|
1
1
|
class HashFilter
|
2
|
+
# An abstract operation on a hash during the filter process
|
3
|
+
#
|
4
|
+
# @example
|
5
|
+
# class SwapKeyValue < HashFilter::Operation
|
6
|
+
# def execute(hash, key)
|
7
|
+
# value = hash.delete(key)
|
8
|
+
# hash[value] = key
|
9
|
+
# end
|
10
|
+
# end
|
11
|
+
#
|
12
|
+
# HashFilter.new do
|
13
|
+
# operation SwapKeyValue
|
14
|
+
# end
|
2
15
|
class Operation
|
16
|
+
# A new operation
|
17
|
+
#
|
18
|
+
# @param key [String, Regexp, Object]
|
3
19
|
def initialize(key)
|
4
20
|
@key = key
|
5
21
|
end
|
6
22
|
|
23
|
+
# Execute the defined operation
|
24
|
+
#
|
25
|
+
# @param hash [Hash] target hash
|
26
|
+
# @param key [String] key
|
27
|
+
#
|
28
|
+
# @see matches?
|
7
29
|
def execute(hash, key)
|
8
30
|
raise NotImplementedError
|
9
31
|
end
|
10
32
|
|
33
|
+
# Should this operation be executed?
|
34
|
+
#
|
35
|
+
# @param key [Regexp, String, Object] key
|
11
36
|
def matches?(key)
|
12
37
|
@key === key
|
13
38
|
end
|
data/lib/hash_filter/version.rb
CHANGED
data/spec/hash_filter_spec.rb
CHANGED
@@ -33,6 +33,38 @@ describe HashFilter do
|
|
33
33
|
end
|
34
34
|
end
|
35
35
|
|
36
|
+
describe "abstract" do
|
37
|
+
let(:abstract) do
|
38
|
+
Class.new(HashFilter::Operation) {}
|
39
|
+
end
|
40
|
+
let(:unused) { :unused }
|
41
|
+
|
42
|
+
it "requires execute to be implemented" do
|
43
|
+
assert_raises NotImplementedError do
|
44
|
+
abstract.new(unused).execute(unused, unused)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
it "matches a string key" do
|
49
|
+
operation = abstract.new("key")
|
50
|
+
|
51
|
+
assert operation.matches?("key")
|
52
|
+
|
53
|
+
refute operation.matches?("nope")
|
54
|
+
refute operation.matches?("KEY")
|
55
|
+
end
|
56
|
+
|
57
|
+
it "matches a regexp key" do
|
58
|
+
operation = abstract.new(/key/i)
|
59
|
+
|
60
|
+
assert operation.matches?("key")
|
61
|
+
assert operation.matches?("KEY")
|
62
|
+
assert operation.matches?("subkey")
|
63
|
+
|
64
|
+
refute operation.matches?("nope")
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
36
68
|
describe "delete" do
|
37
69
|
let(:plain_hash) { Hash["key" => "value"] }
|
38
70
|
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hash_filter
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Peter Suschlik
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2015-03-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -94,7 +94,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
94
94
|
version: '0'
|
95
95
|
requirements: []
|
96
96
|
rubyforge_project:
|
97
|
-
rubygems_version: 2.
|
97
|
+
rubygems_version: 2.2.2
|
98
98
|
signing_key:
|
99
99
|
specification_version: 4
|
100
100
|
summary: Filters hashes
|