melitta 0.0.1

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.
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in melitta.gemspec
4
+ gemspec
data/Guardfile ADDED
@@ -0,0 +1,28 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ guard :minitest do
5
+ # with Minitest::Unit
6
+ #watch(%r{^test/(.*)\/?test_(.*)\.rb})
7
+ #watch(%r{^lib/(.*/)?([^/]+)\.rb}) { |m| "test/#{m[1]}test_#{m[2]}.rb" }
8
+ #watch(%r{^test/test_helper\.rb}) { 'test' }
9
+
10
+ # with Minitest::Spec
11
+ watch(%r{^spec/(.*)_spec\.rb})
12
+ watch(%r{^lib/(.+)\.rb}) { |m| "spec/#{m[1]}_spec.rb" }
13
+ watch(%r{^spec/spec_helper\.rb}) { 'spec' }
14
+
15
+ # Rails 4
16
+ # watch(%r{^app/(.+)\.rb}) { |m| "test/#{m[1]}_test.rb" }
17
+ # watch(%r{^app/controllers/application_controller\.rb}) { 'test/controllers' }
18
+ # watch(%r{^app/controllers/(.+)_controller\.rb}) { |m| "test/integration/#{m[1]}_test.rb" }
19
+ # watch(%r{^app/views/(.+)_mailer/.+}) { |m| "test/mailers/#{m[1]}_mailer_test.rb" }
20
+ # watch(%r{^lib/(.+)\.rb}) { |m| "test/lib/#{m[1]}_test.rb" }
21
+ # watch(%r{^test/.+_test\.rb})
22
+ # watch(%r{^test/test_helper\.rb}) { 'test' }
23
+
24
+ # Rails < 4
25
+ # watch(%r{^app/controllers/(.*)\.rb}) { |m| "test/functional/#{m[1]}_test.rb" }
26
+ # watch(%r{^app/helpers/(.*)\.rb}) { |m| "test/helpers/#{m[1]}_test.rb" }
27
+ # watch(%r{^app/models/(.*)\.rb}) { |m| "test/unit/#{m[1]}_test.rb" }
28
+ end
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Michael Dietz
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,29 @@
1
+ # Melitta
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'melitta'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install melitta
18
+
19
+ ## Usage
20
+
21
+ TODO: Write usage instructions here
22
+
23
+ ## Contributing
24
+
25
+ 1. Fork it
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
27
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
28
+ 4. Push to the branch (`git push origin my-new-feature`)
29
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
3
+ require 'rake/testtask'
4
+
5
+ Rake::TestTask.new do |t|
6
+ t.libs << 'lib/melitta'
7
+ t.test_files = FileList['spec/lib/melitta/*_spec.rb']
8
+ t.verbose = true
9
+ end
10
+
11
+ task :default => :test
data/lib/melitta.rb ADDED
@@ -0,0 +1,15 @@
1
+ require 'active_support/core_ext/object/blank'
2
+ require 'melitta/version'
3
+ require 'melitta/filter_dsl'
4
+ require 'melitta/bridges'
5
+ require 'melitta/filters'
6
+ require 'melitta/coercers'
7
+
8
+ module Melitta
9
+
10
+ def self.filter
11
+ Bridges::Base
12
+ end
13
+
14
+ end
15
+
@@ -0,0 +1 @@
1
+ require_relative './bridges/base'
@@ -0,0 +1,24 @@
1
+ module Melitta::Bridges
2
+
3
+ module Base
4
+
5
+ def self.included(base)
6
+ base.send :extend, ClassMethods
7
+ end
8
+
9
+ module ClassMethods
10
+
11
+ def filter field, &block
12
+ filter = Melitta::FilterDsl.evaluate(Melitta::Filters::Tree, &block)
13
+ class_variable_set("@@#{field}_filter", filter)
14
+
15
+ define_method :"#{field}_filter" do |params|
16
+ filter.run(params.fetch(field, {}))
17
+ end
18
+ end
19
+
20
+ end
21
+
22
+ end
23
+
24
+ end
@@ -0,0 +1,168 @@
1
+ module Melitta::Coercers
2
+
3
+ def self.evaluate(coercer)
4
+ coercer = coercer.is_a?(Class) ? coercer.name : coercer
5
+ "Melitta::Coercers::#{coercer}".constantize
6
+ end
7
+
8
+ Identity = Struct.new(:input) do
9
+
10
+ def valid?
11
+ true
12
+ end
13
+
14
+ def output
15
+ input
16
+ end
17
+
18
+ end
19
+
20
+ String = Struct.new(:input) do
21
+
22
+ def valid?
23
+ true
24
+ end
25
+
26
+ def output
27
+ input.to_s
28
+ end
29
+
30
+ end
31
+
32
+ Integer = Struct.new(:input) do
33
+
34
+ def valid?
35
+ !! /\A\d*\z/.match(input)
36
+ end
37
+
38
+ def output
39
+ input.to_i
40
+ end
41
+
42
+ end
43
+
44
+ Float = Struct.new(:input) do
45
+
46
+ def valid?
47
+ !! /\A\d+([,.]\d+)?\z/.match(input)
48
+ end
49
+
50
+ def output
51
+ output = input
52
+ output = input.gsub(',', '.') if /(\d)*,(\d)*/.match(input)
53
+ output.to_f
54
+ end
55
+
56
+ end
57
+
58
+ Boolean = Struct.new(:input) do
59
+
60
+ def valid?
61
+ input.blank? || input =~ (/\A(true|1|false|0)\z/i)
62
+ end
63
+
64
+ def output
65
+ (input =~ (/(true|1)$/i)) === 0
66
+ end
67
+
68
+ end
69
+
70
+ Date = Struct.new(:input) do
71
+
72
+ def valid?
73
+ # valid formats are
74
+ # day[.-/]month[.-/]year or year[.-/]month[.-/]day
75
+ # year has to be 4 digits, due to Date.parse misinterpreting ambiguous values, e.g. "26.02.13" as Feb 13th 2026
76
+ # month [01-12] and day [01-31] can be single or double digits
77
+ if !! /\A((?:\d{4}[-.\/](0?[1-9]|1[012])[-.\/](0?[1-9]|[12][0-9]|3[01]))|(?:(0?[1-9]|[12][0-9]|3[01])[-.\/](0?[1-9]|1[012])[-.\/]\d{4}))\z/.match(input)
78
+ begin
79
+ ::Date.parse(input)
80
+ rescue ArgumentError
81
+ return false
82
+ end
83
+ return true
84
+ else
85
+ return false
86
+ end
87
+ end
88
+
89
+ def output
90
+ ::Date.parse(input)
91
+ end
92
+
93
+ end
94
+
95
+ MonthYear = Struct.new(:input) do
96
+ # valid formats are
97
+ # month[.-/]year or year[.-/]month
98
+ # year has to be 4 digits to force unambiguity
99
+ def valid?
100
+ !! /\A((?:\d{4}[-.\/](0?[1-9]|1[012]))|(?:(0?[1-9]|1[012])[-.\/]\d{4}))\z/.match(input)
101
+ end
102
+
103
+ def output
104
+ month = input.scan(/\b(?:0?[1-9]|1[012])\b/)[0].to_i
105
+ year = input.scan(/\b\d{4}\b/)[0].to_i
106
+
107
+ ::Date.new(year, month)
108
+ end
109
+
110
+ end
111
+
112
+ Tree = Struct.new(:input) do
113
+
114
+ def origin
115
+ input.each_with_object({}) do |(k,v), hsh|
116
+ hsh[k] = v.respond_to?(:origin) ? v.origin : v.input
117
+ end
118
+ end
119
+
120
+ def errors
121
+ input.each_with_object({}) do |(k,v), hsh|
122
+ unless v.valid?
123
+ hsh[k] = v.respond_to?(:errors) ? v.errors : I18n.t("errors.coercers.#{v.class.name.demodulize.downcase}")
124
+ end
125
+ end
126
+ end
127
+
128
+ def valid?
129
+ input.all? { |k,v| v.valid? }
130
+ end
131
+
132
+ def output
133
+ input.each_with_object({}) do |(k,v), hsh|
134
+ hsh[k] = v.output
135
+ end
136
+ end
137
+
138
+ end
139
+
140
+ MissingInput = Struct.new(:input) do
141
+
142
+ def errors
143
+ I18n.t("errors.coercers.missing_input")
144
+ end
145
+
146
+ def valid?
147
+ false
148
+ end
149
+
150
+ def output
151
+ input
152
+ end
153
+
154
+ end
155
+
156
+ OptionalInput = Struct.new(:input) do
157
+
158
+ def valid?
159
+ true
160
+ end
161
+
162
+ def output
163
+ input
164
+ end
165
+
166
+ end
167
+
168
+ end
@@ -0,0 +1,61 @@
1
+ class Melitta::FilterDsl
2
+
3
+ attr_reader :receiver
4
+
5
+ def self.evaluate type, &block
6
+ filter = new(type)
7
+ filter.instance_eval &block
8
+ filter.receiver
9
+ end
10
+
11
+ def initialize(receiver)
12
+ @receiver = receiver.new
13
+ end
14
+
15
+ def keep field, coercer = String, &block
16
+ if block_given?
17
+ filter = evaluate(Melitta::Filters::Tree, block)
18
+ else
19
+ filter = Melitta::Filters::Base.new()
20
+ filter.coercer = evaluate_coercer(coercer)
21
+ end
22
+
23
+ receiver.filter(field, filter)
24
+ end
25
+
26
+ def demand field, coercer = String, &block
27
+ if block_given?
28
+ filter = evaluate(Melitta::Filters::Tree, block)
29
+ filter.required = true
30
+ else
31
+ filter = Melitta::Filters::Base.new
32
+ filter.required = true
33
+ filter.coercer = evaluate_coercer(coercer)
34
+ end
35
+
36
+ receiver.filter(field, filter)
37
+ end
38
+
39
+ def allow field, &block
40
+ if block_given?
41
+ filter = Melitta::Filters::PassThrough.new
42
+ second_level_filter = evaluate(Melitta::Filters::Tre, block)
43
+ filter.filter(field, second_level_filter)
44
+ else
45
+ filter = Melitta::Filters::PassThrough.new
46
+ end
47
+
48
+ receiver.filter(field, filter)
49
+ end
50
+
51
+ protected
52
+
53
+ def evaluate filter, block
54
+ self.class.evaluate(filter, &block)
55
+ end
56
+
57
+ def evaluate_coercer coercer
58
+ Melitta::Coercers.evaluate(coercer)
59
+ end
60
+
61
+ end
@@ -0,0 +1,3 @@
1
+ require_relative './filters/base'
2
+ require_relative './filters/tree'
3
+ require_relative './filters/pass_through'
@@ -0,0 +1,25 @@
1
+ module Melitta::Filters
2
+
3
+ class Base
4
+
5
+ attr_accessor :required, :coercer
6
+
7
+ def run(params)
8
+ if required && params.blank?
9
+ return ::Melitta::Coercers::MissingInput.new(params)
10
+ elsif !required && params.blank?
11
+ return ::Melitta::Coercers::OptionalInput.new(params)
12
+ else
13
+ result(params)
14
+ end
15
+ end
16
+
17
+ protected
18
+
19
+ def result(params)
20
+ coercer.new(params)
21
+ end
22
+
23
+ end
24
+
25
+ end
@@ -0,0 +1,31 @@
1
+ module Melitta::Filters
2
+
3
+ class PassThrough < Base
4
+
5
+ attr_reader :second_level_filter
6
+
7
+ def run(params)
8
+ if second_level_filter && params.respond_to?(:each)
9
+ result(params)
10
+ else
11
+ params
12
+ end
13
+ end
14
+
15
+ def filter(field, filter)
16
+ @second_level_filter = filter
17
+ end
18
+
19
+ protected
20
+
21
+ def result(params)
22
+ result = params.each_with_object({}) do |(key, value), result|
23
+ result[key] = second_level_filter.run(value)
24
+ end
25
+
26
+ ::Melitta::Coercers::Tree.new(result)
27
+ end
28
+
29
+ end
30
+
31
+ end
@@ -0,0 +1,27 @@
1
+ module Melitta::Filters
2
+
3
+ class Tree < Base
4
+
5
+ attr_reader :filters
6
+
7
+ def initialize
8
+ @filters = {}
9
+ end
10
+
11
+ def filter field, filter
12
+ filters[field] = filter
13
+ end
14
+
15
+ protected
16
+
17
+ def result(params)
18
+ result = filters.each_with_object({}) do |(field, filter), result|
19
+ result[field] = filter.run(params.fetch(field, ""))
20
+ end
21
+
22
+ ::Melitta::Coercers::Tree.new(result)
23
+ end
24
+
25
+ end
26
+
27
+ end
@@ -0,0 +1,3 @@
1
+ module Melitta
2
+ VERSION = "0.0.1"
3
+ end
data/melitta.gemspec ADDED
@@ -0,0 +1,28 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'melitta/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "melitta"
8
+ spec.version = Melitta::VERSION
9
+ spec.authors = ["Michael Dietz"]
10
+ spec.email = ["michael.dietz@ivoke.de"]
11
+ spec.description = "Filter user input without loosing state"
12
+ spec.summary = ""
13
+ spec.homepage = "https://github.com/ivoke/melitta"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_dependency "activesupport", ">= 3.2.0"
22
+ spec.add_dependency "i18n"
23
+
24
+ spec.add_development_dependency "bundler", "~> 1.3"
25
+ spec.add_development_dependency "rake"
26
+ spec.add_development_dependency "guard"
27
+ spec.add_development_dependency "guard-minitest"
28
+ end
@@ -0,0 +1,33 @@
1
+ require_relative '../../../spec_helper'
2
+
3
+ describe Melitta::Bridges::Base do
4
+
5
+ describe ".filter" do
6
+
7
+ before(:each) do
8
+ subject.filter :field do; end
9
+ end
10
+
11
+ subject do
12
+ Class.new { include Melitta.filter }
13
+ end
14
+
15
+ it "sets a filter" do
16
+ subject
17
+ .class_variable_get("@@field_filter")
18
+ .must_be_kind_of(Melitta::Filters::Tree)
19
+ end
20
+
21
+ it "has a filter method defined" do
22
+ subject.new.must_respond_to(:field_filter)
23
+ end
24
+
25
+ it "returns an optional input coercer" do
26
+ subject.new
27
+ .field_filter({})
28
+ .must_be_kind_of(Melitta::Coercers::OptionalInput)
29
+ end
30
+
31
+ end
32
+
33
+ end
@@ -0,0 +1,6 @@
1
+ require_relative '../../spec_helper'
2
+
3
+ describe Melitta::Filters do
4
+
5
+
6
+ end
@@ -0,0 +1,9 @@
1
+ require_relative '../../spec_helper'
2
+
3
+ describe Melitta do
4
+
5
+ it "must be defined" do
6
+ Melitta::VERSION.wont_be_nil
7
+ end
8
+
9
+ end
@@ -0,0 +1,24 @@
1
+ require_relative '../spec_helper'
2
+
3
+ describe Melitta do
4
+
5
+ describe "Filter Module" do
6
+ subject { Melitta.filter }
7
+
8
+ it "should be a module" do
9
+ subject.must_be_kind_of(Module)
10
+ end
11
+
12
+ end
13
+
14
+ describe "Including a Filter Module" do
15
+
16
+ subject { Class.new { include Melitta.filter } }
17
+
18
+ it "should have a filter interface defined" do
19
+ subject.must_respond_to(:filter)
20
+ end
21
+
22
+ end
23
+
24
+ end
@@ -0,0 +1,3 @@
1
+ require 'minitest/autorun'
2
+ require 'minitest/pride'
3
+ require File.expand_path('../../lib/melitta.rb', __FILE__)
metadata ADDED
@@ -0,0 +1,169 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: melitta
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Michael Dietz
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-10-21 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: activesupport
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: 3.2.0
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: 3.2.0
30
+ - !ruby/object:Gem::Dependency
31
+ name: i18n
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: bundler
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ~>
52
+ - !ruby/object:Gem::Version
53
+ version: '1.3'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: '1.3'
62
+ - !ruby/object:Gem::Dependency
63
+ name: rake
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ - !ruby/object:Gem::Dependency
79
+ name: guard
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ - !ruby/object:Gem::Dependency
95
+ name: guard-minitest
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ! '>='
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ type: :development
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ description: Filter user input without loosing state
111
+ email:
112
+ - michael.dietz@ivoke.de
113
+ executables: []
114
+ extensions: []
115
+ extra_rdoc_files: []
116
+ files:
117
+ - .gitignore
118
+ - Gemfile
119
+ - Guardfile
120
+ - LICENSE.txt
121
+ - README.md
122
+ - Rakefile
123
+ - lib/melitta.rb
124
+ - lib/melitta/bridges.rb
125
+ - lib/melitta/bridges/base.rb
126
+ - lib/melitta/coercers.rb
127
+ - lib/melitta/filter_dsl.rb
128
+ - lib/melitta/filters.rb
129
+ - lib/melitta/filters/base.rb
130
+ - lib/melitta/filters/pass_through.rb
131
+ - lib/melitta/filters/tree.rb
132
+ - lib/melitta/version.rb
133
+ - melitta.gemspec
134
+ - spec/lib/melitta/bridges/base_spec.rb
135
+ - spec/lib/melitta/filters_spec.rb
136
+ - spec/lib/melitta/version_spec.rb
137
+ - spec/lib/melitta_spec.rb
138
+ - spec/spec_helper.rb
139
+ homepage: https://github.com/ivoke/melitta
140
+ licenses:
141
+ - MIT
142
+ post_install_message:
143
+ rdoc_options: []
144
+ require_paths:
145
+ - lib
146
+ required_ruby_version: !ruby/object:Gem::Requirement
147
+ none: false
148
+ requirements:
149
+ - - ! '>='
150
+ - !ruby/object:Gem::Version
151
+ version: '0'
152
+ required_rubygems_version: !ruby/object:Gem::Requirement
153
+ none: false
154
+ requirements:
155
+ - - ! '>='
156
+ - !ruby/object:Gem::Version
157
+ version: '0'
158
+ requirements: []
159
+ rubyforge_project:
160
+ rubygems_version: 1.8.23
161
+ signing_key:
162
+ specification_version: 3
163
+ summary: ''
164
+ test_files:
165
+ - spec/lib/melitta/bridges/base_spec.rb
166
+ - spec/lib/melitta/filters_spec.rb
167
+ - spec/lib/melitta/version_spec.rb
168
+ - spec/lib/melitta_spec.rb
169
+ - spec/spec_helper.rb