node_query 1.8.0 → 1.9.0

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: 3638d51ca40eb891535cc2320377e3492023439946460a1c0a81af02f211c3ce
4
- data.tar.gz: 4919be334676677f9ad144db4358be354ca81f8244294e3ea1fbf07d6d0a9845
3
+ metadata.gz: ac9505065daaa42db8776813e028b75fb79ba48a72482bf35eb9cc5d79ac8994
4
+ data.tar.gz: 5d844d6c156a48c1412f66268cfd7c5c33f59a06c4f168a3bba323a06ec28ff6
5
5
  SHA512:
6
- metadata.gz: af54774545d5b284e3d6bd1977094f108553526fc9613ceebe0c96e46be9ac26c5c66db2e4301cef483cf66e4c02f04f19e1e8180e8025d360e5c2b0437c2efa
7
- data.tar.gz: ca74ee091e6ec5d603ce4efaed4927e4d08a123563f95f7e09807e7c8433447ef53390ba727f7500037d60fc74ea5fb1601dfeba52e2cc569e54bd25eea14fc9
6
+ metadata.gz: d08239f6b06b6ee91b8d0de6bb446c85134bab339b7d1b2a02c42030c8ca5d4fba18e4fffd8753b178b60e27f8adcefc759fb61b8f525b81d1cf6926082e0c23
7
+ data.tar.gz: e3526ce4933636ba5dca462df668a66f5e9fc92c63bb92a2ef655a9fa16d598997ae1aa7e9eb036d3896b08cf363a04ad3ea296bf7935708228eefa3731ce3c3
data/CHANGELOG.md CHANGED
@@ -1,5 +1,14 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## 1.9.0 (2022-10-23)
4
+
5
+ * Support `NOT INCLUDES` operator
6
+ * `includes` / `not_includes` a selector
7
+
8
+ ## 1.8.1 (2022-10-15)
9
+
10
+ * Fix `filter_by_position` with empty nodes
11
+
3
12
  ## 1.8.0 (2022-10-14)
4
13
 
5
14
  * Support `:first-child` and `:last-child`
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- node_query (1.8.0)
4
+ node_query (1.9.0)
5
5
  activesupport (< 7.0.0)
6
6
 
7
7
  GEM
data/README.md CHANGED
@@ -210,6 +210,12 @@ Value of name is neither User nor Account
210
210
 
211
211
  Value of arguments includes id
212
212
 
213
+ ```
214
+ .def[arguments NOT INCLUDES id]
215
+ ```
216
+
217
+ Value of arguments not includes id
218
+
213
219
  ```
214
220
  .class[name=~/User/]
215
221
  ```
@@ -434,6 +440,12 @@ Value of name is neither User nor Account
434
440
 
435
441
  Value of arguments includes id
436
442
 
443
+ ```
444
+ { node_type: 'def', arguments: { not_includes: 'id' } }
445
+ ```
446
+
447
+ Value of arguments not includes id
448
+
437
449
  ```
438
450
  { node_type: 'class', name: /User/ }
439
451
  ```
@@ -31,6 +31,8 @@ module NodeQuery::Compiler
31
31
  "#{@key} not in (#{@value})"
32
32
  when 'includes'
33
33
  "#{@key} includes #{@value}"
34
+ when 'not_includes'
35
+ "#{@key} not includes #{@value}"
34
36
  else
35
37
  "#{@key}=#{@value}"
36
38
  end
@@ -3,9 +3,9 @@
3
3
  module NodeQuery::Compiler
4
4
  # Compare acutal value with expected value.
5
5
  module Comparable
6
- SIMPLE_VALID_OPERATORS = ['==', '!=', 'includes']
7
- STRING_VALID_OPERATORS = ['==', '!=', '^=', '$=', '*=', 'includes']
8
- NUMBER_VALID_OPERATORS = ['==', '!=', '>', '>=', '<', '<=', 'includes']
6
+ SIMPLE_VALID_OPERATORS = ['==', '!=', 'includes', 'not_includes']
7
+ STRING_VALID_OPERATORS = ['==', '!=', '^=', '$=', '*=', 'includes', 'not_includes']
8
+ NUMBER_VALID_OPERATORS = ['==', '!=', '>', '>=', '<', '<=', 'includes', 'not_includes']
9
9
  ARRAY_VALID_OPERATORS = ['==', '!=', 'in', 'not_in']
10
10
  REGEXP_VALID_OPERATORS = ['=~', '!~']
11
11
 
@@ -60,7 +60,9 @@ module NodeQuery::Compiler
60
60
  expected.all? { |expected_child| expected_child.match?(node, base_node, '!=') }
61
61
  end
62
62
  when 'includes'
63
- actual.any? { |actual_child| actual_child == expected }
63
+ actual.any? { |actual_child| expected.match?(actual_child) }
64
+ when 'not_includes'
65
+ actual.none? { |actual_child| expected.match?(actual_child) }
64
66
  else
65
67
  if expected.is_a?(::Array)
66
68
  actual.is_a?(::Array) && actual.size == expected.size &&
@@ -25,8 +25,18 @@ module NodeQuery::Compiler
25
25
  # Check if node matches the selector.
26
26
  # @param node [Parser::AST::Node] the node
27
27
  # @param base_node [Parser::AST::Node] the base node for evaluated node
28
- def match?(node, base_node)
29
- NodeQuery.adapter.is_node?(node) && (!@basic_selector || @basic_selector.match?(node, base_node)) && match_pseudo_class?(node)
28
+ def match?(node, base_node, operator = "==")
29
+ if node.is_a?(::Array)
30
+ case operator
31
+ when "not_includes"
32
+ return node.none? { |child_node| match?(child_node, base_node) }
33
+ when "includes"
34
+ return node.any? { |child_node| match?(child_node, base_node) }
35
+ else
36
+ return false
37
+ end
38
+ end
39
+ NodeQuery.adapter.is_node?(node) && (!@basic_selector || (operator == "!=" ? !@basic_selector.match?(node, base_node) : @basic_selector.match?(node, base_node))) && match_pseudo_class?(node)
30
40
  end
31
41
 
32
42
  # Query nodes by the selector.
@@ -98,6 +108,7 @@ module NodeQuery::Compiler
98
108
  # @return [Array<Node>|Node] first node or last node or nodes
99
109
  def filter_by_position(nodes)
100
110
  return nodes unless @position
111
+ return nodes if nodes.empty?
101
112
 
102
113
  case @position
103
114
  when 'first-child'
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class NodeQuery::NodeRules
4
- KEYWORDS = %i[any includes not in not_in gt gte lt lte]
4
+ KEYWORDS = %i[not_includes includes not in not_in gt gte lt lte]
5
5
 
6
6
  # Initialize a NodeRules.
7
7
  # @param rules [Hash] the nod rules
@@ -57,8 +57,10 @@ class NodeQuery::NodeRules
57
57
  expected = expected_value(@rules, multi_keys)
58
58
  expected = NodeQuery::Helper.evaluate_node_value(node, expected) if expected.is_a?(String)
59
59
  case last_key
60
- when :any, :includes
60
+ when :includes
61
61
  actual.any? { |actual_value| match_value?(actual_value, expected) }
62
+ when :not_includes
63
+ actual.all? { |actual_value| !match_value?(actual_value, expected) }
62
64
  when :not
63
65
  !match_value?(actual, expected)
64
66
  when :in
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class NodeQuery
4
- VERSION = "1.8.0"
4
+ VERSION = "1.9.0"
5
5
  end
@@ -50,6 +50,7 @@ rules
50
50
  :KEY />/ { @state = :VALUE; [:tOPERATOR, '>'] }
51
51
  :KEY /</ { @state = :VALUE; [:tOPERATOR, '<'] }
52
52
  :KEY /=/ { @state = :VALUE; [:tOPERATOR, '=='] }
53
+ :KEY /not includes/i { @state = :VALUE; [:tOPERATOR, 'not_includes'] }
53
54
  :KEY /includes/i { @state = :VALUE; [:tOPERATOR, 'includes'] }
54
55
  :KEY /not in/i { @state = :VALUE; [:tOPERATOR, 'not_in'] }
55
56
  :KEY /in/i { @state = :VALUE; [:tOPERATOR, 'in'] }
@@ -179,6 +179,8 @@ class NodeQueryLexer
179
179
  action { @state = :VALUE; [:tOPERATOR, '<'] }
180
180
  when ss.skip(/=/) then
181
181
  action { @state = :VALUE; [:tOPERATOR, '=='] }
182
+ when ss.skip(/not includes/i) then
183
+ action { @state = :VALUE; [:tOPERATOR, 'not_includes'] }
182
184
  when ss.skip(/includes/i) then
183
185
  action { @state = :VALUE; [:tOPERATOR, 'includes'] }
184
186
  when ss.skip(/not in/i) then
@@ -22,31 +22,31 @@ class NodeQueryParser < Racc::Parser
22
22
  ##### State transition tables begin ###
23
23
 
24
24
  racc_action_table = [
25
- 8, 8, 7, 9, 10, 37, 12, 5, 6, 13,
26
- 28, 17, 18, 22, 23, 24, 25, 30, 31, 32,
27
- 33, 34, 35, 36, 8, 17, 8, 7, 41, 37,
28
- nil, 8, 5, 6, nil, 38, 37, nil, nil, nil,
29
- nil, 30, 31, 32, 33, 34, 35, 36, 30, 31,
30
- 32, 33, 34, 35, 36, 8, 7, 8, 7, 8,
31
- 7, 5, 6, 5, 6, 5, 6, 8, 7, nil,
32
- nil, nil, nil, 5, 6 ]
25
+ 8, 7, 8, 7, 9, 37, 5, 6, 5, 6,
26
+ 28, 10, 12, 13, 17, 18, 22, 30, 31, 32,
27
+ 33, 34, 35, 36, 8, 7, 23, 24, 25, 37,
28
+ 5, 6, 8, 7, 17, 38, 41, 37, 5, 6,
29
+ nil, 30, 31, 32, 33, 34, 35, 36, nil, 30,
30
+ 31, 32, 33, 34, 35, 36, 8, 7, 8, 7,
31
+ 8, 7, 5, 6, 5, 6, 5, 6, 8, 7,
32
+ 8, 7, nil, nil, 5, 6, 5, 6 ]
33
33
 
34
34
  racc_action_check = [
35
- 25, 0, 0, 1, 2, 25, 4, 0, 0, 5,
36
- 25, 8, 9, 17, 20, 21, 22, 25, 25, 25,
37
- 25, 25, 25, 25, 28, 24, 3, 3, 39, 28,
38
- nil, 40, 3, 3, nil, 28, 40, nil, nil, nil,
39
- nil, 28, 28, 28, 28, 28, 28, 28, 40, 40,
40
- 40, 40, 40, 40, 40, 6, 6, 7, 7, 10,
41
- 10, 6, 6, 7, 7, 10, 10, 13, 13, nil,
42
- nil, nil, nil, 13, 13 ]
35
+ 25, 25, 0, 0, 1, 25, 25, 25, 0, 0,
36
+ 25, 2, 4, 5, 8, 9, 17, 25, 25, 25,
37
+ 25, 25, 25, 25, 28, 28, 20, 21, 22, 28,
38
+ 28, 28, 40, 40, 24, 28, 39, 40, 40, 40,
39
+ nil, 28, 28, 28, 28, 28, 28, 28, nil, 40,
40
+ 40, 40, 40, 40, 40, 40, 3, 3, 6, 6,
41
+ 7, 7, 3, 3, 6, 6, 7, 7, 10, 10,
42
+ 13, 13, nil, nil, 10, 10, 13, 13 ]
43
43
 
44
44
  racc_action_pointer = [
45
- -2, 3, 2, 23, -11, -6, 52, 54, 0, 12,
46
- 56, nil, nil, 64, nil, nil, nil, 7, nil, nil,
47
- -2, 3, -2, nil, 14, -3, nil, nil, 21, nil,
48
- nil, nil, nil, nil, nil, nil, nil, nil, nil, 14,
49
- 28, nil, nil ]
45
+ -1, 4, 9, 53, -5, -2, 55, 57, 3, 15,
46
+ 65, nil, nil, 67, nil, nil, nil, 10, nil, nil,
47
+ 10, 15, 10, nil, 23, -3, nil, nil, 21, nil,
48
+ nil, nil, nil, nil, nil, nil, nil, nil, nil, 22,
49
+ 29, nil, nil ]
50
50
 
51
51
  racc_action_default = [
52
52
  -28, -28, -2, -4, -6, -28, -28, -28, -10, -28,
@@ -56,15 +56,19 @@ racc_action_default = [
56
56
  -18, -16, -17 ]
57
57
 
58
58
  racc_goto_table = [
59
- 16, 39, 29, 11, 1, 29, 21, 27, 14, 15,
60
- nil, nil, nil, 42, 19, 20, 26, 29 ]
59
+ 14, 15, 16, 39, 1, 11, 21, 20, 27, nil,
60
+ nil, nil, nil, nil, 19, 42, nil, nil, 26, 29,
61
+ nil, nil, 29, nil, nil, nil, nil, nil, nil, nil,
62
+ nil, nil, nil, nil, 29 ]
61
63
 
62
64
  racc_goto_check = [
63
- 5, 8, 4, 2, 1, 4, 6, 7, 3, 3,
64
- nil, nil, nil, 8, 1, 3, 5, 4 ]
65
+ 3, 3, 5, 8, 1, 2, 6, 3, 7, nil,
66
+ nil, nil, nil, nil, 1, 8, nil, nil, 5, 3,
67
+ nil, nil, 3, nil, nil, nil, nil, nil, nil, nil,
68
+ nil, nil, nil, nil, 3 ]
65
69
 
66
70
  racc_goto_pointer = [
67
- nil, 4, 0, 2, -23, -8, -11, -18, -27 ]
71
+ nil, 4, 2, -6, nil, -6, -11, -17, -25 ]
68
72
 
69
73
  racc_goto_default = [
70
74
  nil, nil, 2, 3, 4, nil, nil, 40, nil ]
@@ -37,7 +37,7 @@ rule
37
37
  | value { NodeQuery::Compiler::ArrayValue.new(value: val[0]) }
38
38
 
39
39
  value
40
- : basic_selector
40
+ : selector
41
41
  | tBOOLEAN { NodeQuery::Compiler::Boolean.new(value: val[0]) }
42
42
  | tFLOAT { NodeQuery::Compiler::Float.new(value: val[0]) }
43
43
  | tINTEGER { NodeQuery::Compiler::Integer.new(value: val[0])}
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: node_query
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.8.0
4
+ version: 1.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Richard Huang
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-10-14 00:00:00.000000000 Z
11
+ date: 2022-10-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport