tag_options 1.3.0 → 1.3.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
  SHA256:
3
- metadata.gz: 5cee8f74f051ffc41909e62f0a613904ce5f342a6be1fd8d961b8f7663d66087
4
- data.tar.gz: 5e8c5f2b69fe32e13330a99f4d112a412bc4e6b3a78a5233d66f11a3ad032e7c
3
+ metadata.gz: 416b4a714b85d92ffe1d81481749e7e75f3ebb6a5ef2f9c40330a544dd3cd774
4
+ data.tar.gz: ef14412ef73a773aaec41c5f2cd7f9a715e7f3368b5d1338d4d85dfaf6af0d4c
5
5
  SHA512:
6
- metadata.gz: d6613c09fbf756a9a15e3a4001e478a0c225f643c1dd3f8b58be3e63fe8c3afb0dab00bed9d8984ca75ae58b37ae4fbb4e26d0410b7d36bb0cf59f52fecbd869
7
- data.tar.gz: ed905332c293482cd3610c5374bb9a7b27328cd1c245bb55c6d69fc10b4c36e7c67f6a38ca3a32ef3a0f879344c9751b9a22ae18f91f1ed21d4bf5a6b7a8cac4
6
+ metadata.gz: 664555bb319ec2add3dc7887b80b3e8e4ce84e288707c2a73eb003e72474549505bd401cebab4adc3eae78ed624a60ff28f9f50af9b431bae2322a5038a5b821
7
+ data.tar.gz: 0c5693a2ab6f3ad7ed39a1f4b29a0b0683394cfd6b1895f8d9a33379aa72c63d241f0285055296c7cd228a8741d482f5fee030cc5dd8751e07ad128119fb213c
data/CHANGELOG.md CHANGED
@@ -2,6 +2,12 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [1.3.1] - 2023-03-06
6
+
7
+ - Fixed a bug where keys with empty values were being populated when using
8
+ `at()` against a non-existant key and the values passed to `combine!`, `set!`,
9
+ or `default` resolved to no values or where `remove!` removed all values.
10
+
5
11
  ## [1.3.0] - 2023-03-03
6
12
 
7
13
  - Added `at().remove!` option for removing values.
data/README.md CHANGED
@@ -65,7 +65,7 @@ bundle install
65
65
 
66
66
  ## General Usage
67
67
 
68
- Initialize a `TagOptions::Hash` directly or by passing an existing `Hash`.
68
+ Instantiate a `TagOptions::Hash` directly or by passing an existing `Hash`.
69
69
 
70
70
  ```ruby
71
71
  TagOptions::Hash.new
@@ -76,6 +76,24 @@ TagOptions::Hash.new(hash)
76
76
  => {:class=>"flex"}
77
77
  ```
78
78
 
79
+ Similar to `Array()`, you can also instantiate a new `TagOptions::Hash` by
80
+ passing a has to `TagOptions::Hash()`.
81
+
82
+ ```ruby
83
+ hash = {class: "flex"}
84
+ TagOptions::Hash(hash)
85
+ => {:class=>"flex"}
86
+ ```
87
+
88
+ The values of the hash passed to `TagOptions::Hash.new` or `TagOptions::Hash()`
89
+ are automatically converted to strings.
90
+
91
+ ```ruby
92
+ hash = {disabled: true}
93
+ TagOptions::Hash.new(hash)
94
+ => {:disabled=>"true"}
95
+ ```
96
+
79
97
  `TagOptions::Hash` inherits from `ActiveSupport::HashWithIndifferentAccess`,
80
98
  implementing a hash where keys `:foo` and `"foo"` are considered to be the same.
81
99
  It differs from `ActiveSupport::HashWithIndifferentAccess`, however, by storing
@@ -1,5 +1,6 @@
1
1
  require "active_support/callbacks"
2
2
  require "active_support/core_ext/hash/indifferent_access"
3
+ require "active_support/core_ext/object/blank"
3
4
  require "tag_options/convert_key"
4
5
  require "tag_options/hash_at"
5
6
  require "tag_options/errors/not_hash_error"
@@ -14,8 +15,9 @@ module TagOptions
14
15
  def initialize(hash = {})
15
16
  run_callbacks :initialize do
16
17
  hash.each do |key, value|
17
- self[convert_key(key)] = value.is_a?(::Hash) ? self.class.new(value) : value
18
+ self[convert_key(key)] = value.is_a?(::Hash) ? self.class.new(value) : value.to_s
18
19
  end
20
+ remove_blank!
19
21
  end
20
22
  end
21
23
 
@@ -24,21 +26,50 @@ module TagOptions
24
26
  end
25
27
 
26
28
  def dig(*keys)
27
- keys = keys.map { |key| convert_key(key) }
28
- keys.size.zero? ? self : super(*keys)
29
+ return self if keys.size.zero?
30
+
31
+ dug_keys = []
32
+ data = self
33
+ keys.each_with_index do |key, index|
34
+ key = convert_key(key)
35
+ return nil unless data.key?(key)
36
+
37
+ data = data[key]
38
+ dug_keys << key
39
+ last_key = index == keys.size - 1
40
+ unless last_key || data.is_a?(self.class)
41
+ raise TagOptions::Errors::NotHashError.new(dug_keys, type: data.class)
42
+ end
43
+ end
44
+ data
29
45
  end
30
46
 
31
47
  def populate!(*keys)
32
48
  populated_keys = []
33
49
  data = self
34
50
  keys.each do |key|
35
- data[convert_key(key)] ||= self.class.new
36
- data = data[convert_key(key)]
51
+ key = convert_key(key)
52
+ data[key] ||= self.class.new
53
+ data = data[key]
54
+ populated_keys << key
37
55
  unless data.is_a?(self.class)
38
56
  raise TagOptions::Errors::NotHashError.new(populated_keys, type: data.class)
39
57
  end
40
58
  end
41
59
  self
42
60
  end
61
+
62
+ def remove_blank!(hash = self, parent_hash: nil)
63
+ hash.each do |key, value|
64
+ if value.blank?
65
+ hash.delete(key)
66
+ remove_blank!(parent_hash, parent_hash: nil) if parent_hash
67
+ elsif value.is_a?(Hash)
68
+ remove_blank!(value, parent_hash: hash)
69
+ remove_blank!(parent_hash, parent_hash: nil) if parent_hash
70
+ end
71
+ end
72
+ hash
73
+ end
43
74
  end
44
75
  end
@@ -13,23 +13,19 @@ module TagOptions
13
13
  end
14
14
 
15
15
  def combine!(*values, **conditions)
16
- @opt_hash.populate!(*@keys)
17
16
  current_value = @opt_hash.dig(*@keys, @value_key)
18
17
  set_value! @resolver.call(current_value, *values, **conditions)
19
18
  end
20
19
 
21
20
  def default!(*values, **conditions)
22
- @opt_hash.populate!(*@keys)
23
21
  set_default! @resolver.call(*values, **conditions)
24
22
  end
25
23
 
26
24
  def set!(*values, **conditions)
27
- @opt_hash.populate!(*@keys)
28
25
  set_value! @resolver.call(*values, **conditions)
29
26
  end
30
27
 
31
28
  def remove!(*values, **conditions)
32
- @opt_hash.populate!(*@keys)
33
29
  regex_values, values = values.flatten.partition { |v| v.is_a?(Regexp) }
34
30
  remove_values!(*regex_values, *@resolver.values(*values, **conditions))
35
31
  end
@@ -37,7 +33,7 @@ module TagOptions
37
33
  private
38
34
 
39
35
  def remove_values!(*values_to_remove)
40
- values = @resolver.values(@opt_hash.dig(*@keys)[@value_key])
36
+ values = @resolver.values(@opt_hash.dig(*@keys)&.[](@value_key))
41
37
  values_to_remove.each do |value|
42
38
  if value.is_a?(Regexp)
43
39
  values.reject! { |current_value| value.match?(current_value) }
@@ -45,17 +41,25 @@ module TagOptions
45
41
  values.reject! { |current_value| value == current_value }
46
42
  end
47
43
  end
44
+ @opt_hash.populate!(*@keys)
48
45
  @opt_hash.dig(*@keys)[@value_key] = @resolver.call(*values)
46
+ @opt_hash.remove_blank!
49
47
  @opt_hash
50
48
  end
51
49
 
52
50
  def set_default!(value)
51
+ return @opt_hash if value.blank?
52
+
53
+ @opt_hash.populate!(*@keys)
53
54
  root = @opt_hash.dig(*@keys)
54
55
  root[@value_key] = value unless root.key?(@value_key)
55
56
  @opt_hash
56
57
  end
57
58
 
58
59
  def set_value!(value)
60
+ return @opt_hash if value.blank?
61
+
62
+ @opt_hash.populate!(*@keys)
59
63
  @opt_hash.dig(*@keys)[@value_key] = value
60
64
  @opt_hash
61
65
  end
@@ -1,3 +1,3 @@
1
1
  module TagOptions
2
- VERSION = "1.3.0"
2
+ VERSION = "1.3.1"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tag_options
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.0
4
+ version: 1.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alex Monroe
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-03-03 00:00:00.000000000 Z
11
+ date: 2023-03-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport