msfl 1.1.0 → 1.1.1

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: 51e5ed15234f2119cf9a96d709f7cb15505f6e75
4
- data.tar.gz: b31ccaeae664a0d09c359322875a892d55808e71
3
+ metadata.gz: 8b2132d5eaec0ac5b4a2055174d6f40685580f40
4
+ data.tar.gz: 0ff98ee3c34b4225a43c8e9433b0c08b87e2521f
5
5
  SHA512:
6
- metadata.gz: 6b8cdc31ca60efdbb600107dfd98c10580eac574c3677c2a24b34fdbf7933de5c488d719340a3a8d048c9b4be520b06ad456df80f7413c803f8cae607f24c391
7
- data.tar.gz: 1a41e178d9b1230eeb16503b4411bc85a6daebc8260df764aea726c7880ee1fb11f608e316654bbfc64a433b46ee4e1675dfb2d15b114cd97d903f1a13258ab9
6
+ metadata.gz: cdacb790d452b5343363f7b8e420f4a37aabd3e5e16f2005031545f79389c06f528c42601ef8f537350a993cfce5b1af745b5607142c041af50df784930091ba
7
+ data.tar.gz: 5c429cf64452914f271a8ad7513627e009c1d8ea33c1a5f9768277df9f2c660f62c02615a4823bb434fed98c1c9478383e8337495646b8f93579390cc54f8fd0
@@ -49,22 +49,28 @@ module MSFL
49
49
  def implicit_and_to_explicit_recursively(obj, parent_key = nil)
50
50
  if obj.is_a? Hash
51
51
  first_key = obj.keys.first
52
- if hash_key_operators.include?(first_key)
53
- # the first key an operator
54
- raise ArgumentError, "#implicit_and_to_explicit requires that all or none of a hash's keys be operators" unless all_operators?(obj.keys)
55
- # all keys are operators
56
- raise ArgumentError, "#implicit_and_to_explicit requires that parent_key be specified when converting operators" if parent_key.nil?
57
- # parent key is non nil
58
- and_array = []
59
- obj.each do |k, v|
60
- and_array << { parent_key => { k => implicit_and_to_explicit_recursively(v, k) } }
61
- end
52
+ if binary_operators.include?(first_key)
53
+ result = i_to_e_bin_op obj, parent_key
54
+ elsif logical_operators.include?(first_key)
55
+ result = i_to_e_log_op obj, parent_key
62
56
  else
63
57
  # the first key is not an operator
64
58
  # if there is only one key just assign the result of calling this method recursively on the value to the result for the key
65
59
  if obj.keys.count == 1
66
60
  if obj[first_key].is_a?(Hash)
67
61
  result = implicit_and_to_explicit_recursively obj[first_key], first_key
62
+ elsif obj[first_key].is_a? MSFL::Types::Set
63
+ # This situation occurs when there are nested logical operators
64
+ # obj is a hash, with one key that is not a binary operator which has a value that is a MSFL::Types::Set
65
+ result = { }
66
+ and_array = MSFL::Types::Set.new
67
+ obj[first_key].each do |v|
68
+ # byebug
69
+ and_array << implicit_and_to_explicit_recursively(v)
70
+ end
71
+ result[first_key] = and_array
72
+ elsif obj[first_key].is_a? Array
73
+ raise ArgumentError, "#implicit_and_to_explicit requires that it does not contain any Arrays - its argument should preprocessed by .arrays_to_sets and .convert_keys_to_symbols"
68
74
  end
69
75
  else
70
76
  raise ArgumentError, "#implicit_and_to_explicit requires that all or none of a hash's keys be operators" if any_operators?(obj.keys)
@@ -77,14 +83,11 @@ module MSFL
77
83
  and_array << { k => v }
78
84
  end
79
85
  end
86
+ result = { and: MSFL::Types::Set.new(and_array) }
80
87
  end
81
88
  end
82
- result ||= { and: MSFL::Types::Set.new(and_array) }
83
89
  elsif obj.is_a? MSFL::Types::Set
84
- result = Types::Set.new
85
- obj.each do |v|
86
- result << implicit_and_to_explicit_recursively(v)
87
- end
90
+ result = i_to_e_set obj, parent_key
88
91
  elsif obj.is_a? Array
89
92
  raise ArgumentError, "#implicit_and_to_explicit requires that it does not contain any Arrays - its argument should preprocessed by .arrays_to_sets and .convert_keys_to_symbols"
90
93
  end
@@ -92,23 +95,51 @@ module MSFL
92
95
  end
93
96
 
94
97
  private
95
- # Use this method for converting implicit and hashes to explicit ones when the keys are operators
96
- def implicit_to_explicit_for_ops(hash)
97
- and_array = []
98
- field = hash.keys.first
99
- if hash[field].is_a? Hash
100
- hash[field].each do |k, v|
101
- and_array << { field => { k => v } }
98
+ # Recursively handle a hash containing keys that are all logical operators
99
+ def i_to_e_log_op(hash, parent_key = nil)
100
+ raise ArgumentError, "#implicit_and_to_explicit requires that all or none of a hash's keys be logical operators" unless all_logical_operators?(hash.keys)
101
+ result = {}
102
+ hash.each do |key, value|
103
+ result[key] = implicit_and_to_explicit_recursively value
104
+ end
105
+ result
106
+ end
107
+
108
+ # Recursively handle a hash containing keys that are all binary operators
109
+ def i_to_e_bin_op(hash, parent_key = nil)
110
+ # the first key an operator
111
+ raise ArgumentError, "#implicit_and_to_explicit requires that all or none of a hash's keys be operators" unless all_operators?(hash.keys)
112
+ # all keys are operators
113
+
114
+ first_key = hash.keys.first
115
+ if hash.keys.count == 1
116
+ # There's only one key so there cannot be an implied AND at this level
117
+ if parent_key && (! binary_operators.include?(parent_key)) # this needs more testing - I'm not entirely sure if I should check for this esoteric case of immediately nested explicit ANDs inside of an implied AND
118
+ # The parent_key argument was provided which means that the caller expects the result to be a hash of at least two levels
119
+ # where the first level has a key of the parent_key with a value of a hash
120
+ # first_key is passed in the recursive call
121
+ { parent_key => { first_key => implicit_and_to_explicit_recursively(hash[first_key], first_key)}}
122
+ else
123
+ { first_key => implicit_and_to_explicit_recursively(hash[first_key]) }
102
124
  end
125
+
126
+ else
127
+ raise ArgumentError, "#implicit_and_to_explicit requires that parent_key be specified when converting operators" if parent_key.nil?
128
+ # parent key is non nil
129
+ and_array = []
130
+ hash.each do |k, v|
131
+ and_array << { parent_key => { k => implicit_and_to_explicit_recursively(v, k) } }
132
+ end
133
+ { and: MSFL::Types::Set.new(and_array) }
103
134
  end
104
- { and: MSFL::Types::Set.new(and_array) }
105
135
  end
106
136
 
107
- # Use this method for converting implicit and hashes to explicit ones when the keys are properties
108
- def implicit_to_explicit_for_field(hash)
109
- and_array = []
110
- hash.each { |key, value| and_array << { key => value } }
111
- { and: MSFL::Types::Set.new(and_array) }
137
+ def i_to_e_set(set, parent_key = nil)
138
+ result = MSFL::Types::Set.new
139
+ set.each do |v|
140
+ result << implicit_and_to_explicit_recursively(v)
141
+ end
142
+ result
112
143
  end
113
144
  end
114
145
  end
@@ -13,9 +13,11 @@ module MSFL
13
13
 
14
14
  # Operators still needing parsing: ellipsis2, tilda
15
15
  def hash_key_operators
16
+ binary_operators.concat(logical_operators)
17
+ end
18
+
19
+ def binary_operators
16
20
  [
17
- :and, # logical AND
18
- :or, # logical OR
19
21
  :in, # IN
20
22
  :between, # inclusive range for integers, dates, and date times
21
23
  :start, # a range bound inclusively to the left
@@ -31,6 +33,10 @@ module MSFL
31
33
  ]
32
34
  end
33
35
 
36
+ def logical_operators
37
+ [:and, :or]
38
+ end
39
+
34
40
  # Returns true if all elements of arr are operators, false otherwise
35
41
  #
36
42
  # @param arr [Array<Symbol>] the Array of Symbols to be checked against the operators list
@@ -42,6 +48,18 @@ module MSFL
42
48
  true
43
49
  end
44
50
 
51
+
52
+ # Returns true if all elements of arr are logical operators, false otherwise
53
+ #
54
+ # @param arr [Array<Symbol>] and array of symbols to check to see if all elements are logical operators
55
+ # @return [Bool] it is true if all the elements are logical operators, otherwise false
56
+ def all_logical_operators?(arr)
57
+ arr.each do |e|
58
+ return false unless logical_operators.include?(e)
59
+ end
60
+ true
61
+ end
62
+
45
63
  # Returns true if any of the elements in arr are operators, otherwise false
46
64
  #
47
65
  # @param arr [Array] the array of elements to check for the presence of operators
data/msfl.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'msfl'
3
- s.version = '1.1.0'
3
+ s.version = '1.1.1'
4
4
  s.date = '2015-04-01'
5
5
  s.summary = "MSFL in Ruby"
6
6
  s.description = "Serializers, validators, and other tasty goodness for the Mattermark Semantic Filter Language in Ruby."
@@ -12,6 +12,40 @@ describe "MSFL::Converters::Operator" do
12
12
 
13
13
  let(:expected) { raise ArgumentError, "You are expected to define the expected value" }
14
14
 
15
+ context "when there is not an implicit AND" do
16
+
17
+ let(:expected) { arg }
18
+
19
+ context "when the arg is a scalar" do
20
+
21
+ let(:arg) { 50 }
22
+
23
+ it "is the arg unchanged" do
24
+ expect(mut).to eq expected
25
+ end
26
+ end
27
+
28
+ context "when the arg is single level" do
29
+
30
+ let(:arg) { { gte: 1000 } }
31
+
32
+ it "is the arg unchanged" do
33
+ expect(mut).to eq expected
34
+ end
35
+ end
36
+
37
+ context "when the arg is multi level" do
38
+
39
+ let(:arg) { { value: { gte: 1000 } } }
40
+
41
+ it "is the arg unchanged" do
42
+ expect(mut).to eq expected
43
+ end
44
+ end
45
+
46
+
47
+ end
48
+
15
49
  context "when the implicit AND exists on a Hash whose keys are fields" do
16
50
 
17
51
  # TYPE 1 --- { make: "chevy", year: 2010 } => { and: [ { make: "chevy" }, { year: 2010 }] }
@@ -64,6 +98,33 @@ describe "MSFL::Converters::Operator" do
64
98
  end
65
99
  end
66
100
  end
101
+
102
+ context "when the implicit AND is within a MSFL::Types::Set" do
103
+
104
+ let(:arg) do
105
+ { and: MSFL::Types::Set.new([
106
+ { make: "chevy", year: { gte: 2010, lte: 2012 } },
107
+ { value: { gte: 1000 } }
108
+ ])}
109
+ end
110
+
111
+ let(:expected) do
112
+ { and: MSFL::Types::Set.new([
113
+ { and: MSFL::Types::Set.new([
114
+ { make: "chevy" },
115
+ { and: MSFL::Types::Set.new([
116
+ { year: { gte: 2010 } },
117
+ { year: { lte: 2012 } }
118
+ ])}
119
+ ])},
120
+ { value: { gte: 1000 } }
121
+ ])}
122
+ end
123
+
124
+ it "converts all of the implicit ANDs" do
125
+ expect(mut).to eq expected
126
+ end
127
+ end
67
128
  end
68
129
 
69
130
  describe "#between_to_gte_lte_recursively" do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: msfl
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Courtland Caldwell