mutations 0.5.3 → 0.5.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -2,30 +2,17 @@ module Mutations
2
2
  class HashFilter < InputFilter
3
3
  @default_options = {
4
4
  nils: false, # true allows an explicit nil to be valid. Overrides any other options
5
- key_class: nil, # Can be a string or Class. If present, all keys must be of this class. Note that this field can't be set if a block is passed.
6
- value_class: nil # Can be a string or Class. If present, all values must be of this class. Note that this field can't be set if a block is passed.
7
5
  }
8
6
 
9
- attr_accessor :general_inputs # defaults to false
10
7
  attr_accessor :optional_inputs
11
8
  attr_accessor :required_inputs
12
9
 
13
- # There's two types of Hash filters:
14
- # - those that accept specific inputs (eg, the hash needs to have an email key with a string value matching %r{...})
15
- # - those that accept general hashes (eg, the hash needs to have String keys and values, but can have any such k/v's)
16
10
  def initialize(opts = {}, &block)
17
11
  super(opts)
18
12
 
19
- raise ArgumentError, "Can't use key_class/value_class with a block." if block_given? && (options[:key_class] || options[:value_class])
20
-
21
- if options[:key_class] || options[:value_class]
22
- @general_inputs = true
23
- else
24
- @general_inputs = false
25
- @optional_inputs = {}
26
- @required_inputs = {}
27
- @current_inputs = @required_inputs
28
- end
13
+ @optional_inputs = {}
14
+ @required_inputs = {}
15
+ @current_inputs = @required_inputs
29
16
 
30
17
  if block_given?
31
18
  instance_eval &block
@@ -40,21 +27,16 @@ module Mutations
40
27
  @required_inputs.each_pair do |k, v|
41
28
  dupped.required_inputs[k] = v
42
29
  end
43
- dupped.general_inputs = @general_inputs
44
30
  dupped
45
31
  end
46
32
 
47
33
  def required(&block)
48
- raise ArgumentError, "Can't use specific filters if you're filtering by key." if general_inputs
49
-
50
34
  # TODO: raise if nesting is wrong
51
35
  @current_inputs = @required_inputs
52
36
  instance_eval &block
53
37
  end
54
38
 
55
39
  def optional(&block)
56
- raise ArgumentError, "Can't use specific filters if you're filtering by key." if general_inputs
57
-
58
40
  # TODO: raise if nesting is wrong
59
41
  @current_inputs = @optional_inputs
60
42
  instance_eval &block
@@ -82,9 +64,6 @@ module Mutations
82
64
  end
83
65
 
84
66
  def hash(name, options = {}, &block)
85
- unless block_given?
86
- options.reverse_merge!(key_class: String, value_class: String)
87
- end
88
67
  @current_inputs[name.to_sym] = HashFilter.new(options, &block)
89
68
  end
90
69
 
@@ -117,47 +96,50 @@ module Mutations
117
96
 
118
97
  errors = ErrorHash.new
119
98
  filtered_data = HashWithIndifferentAccess.new
99
+ wildcard_filterer = nil
120
100
 
121
- if @general_inputs
122
- key_class_const = options[:key_class] || raise
123
- key_class_const = key_class_const.constantize if key_class_const.is_a?(String)
124
-
125
- value_class_const = options[:value_class] || raise
126
- value_class_const = value_class_const.constantize if value_class_const.is_a?(String)
127
- data.each_pair do |k, v|
128
- if k.is_a?(key_class_const) && v.is_a?(value_class_const)
129
- filtered_data[k] = v
130
- else
131
- k_string = k.to_s
132
- if !k.is_a?(key_class_const)
133
- errors[k_string] = ErrorAtom.new(k_string, :key_class)
101
+ [[@required_inputs, true], [@optional_inputs, false]].each do |(inputs, is_required)|
102
+ inputs.each_pair do |key, filterer|
103
+
104
+ # If we are doing wildcards, then record so and move on
105
+ if key == :*
106
+ wildcard_filterer = filterer
107
+ next
108
+ end
109
+
110
+ data_element = data[key]
111
+ default_used = false
112
+ if !data.has_key?(key) && filterer.has_default?
113
+ data_element = filterer.default
114
+ default_used = true
115
+ end
116
+
117
+ if data.has_key?(key) || default_used
118
+ sub_data, sub_error = filterer.filter(data_element)
119
+
120
+ if sub_error.nil?
121
+ filtered_data[key] = sub_data
134
122
  else
135
- errors[k_string] = ErrorAtom.new(k_string, :value_class)
123
+ sub_error = ErrorAtom.new(key, sub_error) if sub_error.is_a?(Symbol)
124
+ errors[key] = sub_error
136
125
  end
126
+ elsif is_required
127
+ errors[key] = ErrorAtom.new(key, :required)
137
128
  end
138
129
  end
139
- else
140
- [[@required_inputs, true], [@optional_inputs, false]].each do |(inputs, is_required)|
141
- inputs.each_pair do |key, filterer|
142
- data_element = data[key]
143
- default_used = false
144
- if !data.has_key?(key) && filterer.has_default?
145
- data_element = filterer.default
146
- default_used = true
147
- end
148
-
149
- if data.has_key?(key) || default_used
150
- sub_data, sub_error = filterer.filter(data_element)
130
+ end
151
131
 
152
- if sub_error.nil?
153
- filtered_data[key] = sub_data
154
- else
155
- sub_error = ErrorAtom.new(key, sub_error) if sub_error.is_a?(Symbol)
156
- errors[key] = sub_error
157
- end
158
- elsif is_required
159
- errors[key] = ErrorAtom.new(key, :required)
160
- end
132
+ if wildcard_filterer
133
+ filtered_keys = data.keys - filtered_data.keys
134
+
135
+ filtered_keys.each do |key|
136
+ data_element = data[key]
137
+ sub_data, sub_error = wildcard_filterer.filter(data_element)
138
+ if sub_error.nil?
139
+ filtered_data[key] = sub_data
140
+ else
141
+ sub_error = ErrorAtom.new(key, sub_error) if sub_error.is_a?(Symbol)
142
+ errors[key] = sub_error
161
143
  end
162
144
  end
163
145
  end
@@ -1,3 +1,3 @@
1
1
  module Mutations
2
- VERSION = "0.5.3"
2
+ VERSION = "0.5.4"
3
3
  end
@@ -19,23 +19,31 @@ describe "Mutations::HashFilter" do
19
19
  assert_equal :hash, errors
20
20
  end
21
21
 
22
- it 'allows general hashes' do
23
- hf = Mutations::HashFilter.new(key_class: String, value_class: Symbol)
24
- filtered, errors = hf.filter("f1" => :v1, "f2" => :v2)
25
- assert_equal ({"f1" => :v1, "f2" => :v2}), filtered
22
+ it "allows wildcards in hashes" do
23
+ hf = Mutations::HashFilter.new do
24
+ string :*
25
+ end
26
+ filtered, errors = hf.filter(foo: "bar", baz: "ban")
27
+ assert_equal ({"foo" => "bar", "baz" => "ban"}), filtered
26
28
  assert_equal nil, errors
27
29
  end
28
30
 
29
- it 'doesnt allows invalid general hashes (wrong value type)' do
30
- hf = Mutations::HashFilter.new(key_class: String, value_class: Symbol)
31
- filtered, errors = hf.filter("f1" => "v1", "f2" => :v2)
32
- assert_equal ({"f1" => :value_class}), errors.symbolic
31
+ it "doesn't allow wildcards in hashes" do
32
+ hf = Mutations::HashFilter.new do
33
+ string :*
34
+ end
35
+ filtered, errors = hf.filter(foo: nil)
36
+ assert_equal ({"foo" => :nils}), errors.symbolic
33
37
  end
34
38
 
35
- it 'doesnt allows invalid general hashes (wrong key type)' do
36
- hf = Mutations::HashFilter.new(key_class: Fixnum, value_class: Symbol)
37
- filtered, errors = hf.filter("f1" => :v1)
38
- assert_equal ({"f1" => :key_class}), errors.symbolic
39
+ it "allows a mix of specific keys and then wildcards" do
40
+ hf = Mutations::HashFilter.new do
41
+ string :foo
42
+ integer :*
43
+ end
44
+ filtered, errors = hf.filter(foo: "bar", baz: "4")
45
+ assert_equal ({"foo" => "bar", "baz" => 4}), filtered
46
+ assert_equal nil, errors
39
47
  end
40
48
 
41
49
  end
data/spec/spec_helper.rb CHANGED
@@ -1,5 +1,4 @@
1
1
  require 'minitest/unit'
2
- #require 'minitest/pride'
3
2
  require 'minitest/autorun'
4
3
  require 'pp'
5
4
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mutations
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.3
4
+ version: 0.5.4
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors: