node_query 1.6.1 → 1.7.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 474136c42ade45282559b6e9700faffacdec002f75d8033f00d05639034a3245
4
- data.tar.gz: 1be2a9b18e54c36605468ce8ca5e9ad78c05c698b6f9994c0d6ea18f2270e25c
3
+ metadata.gz: 061470a9033fb08485c03c44c3c41ca6ff0daf6a7db2fbe474d82384f9dd731b
4
+ data.tar.gz: 915e29f0a09147d3b7d06b0e81770b197cd743f4d44cd3da7b7f5ddee8a50a8c
5
5
  SHA512:
6
- metadata.gz: a0d40e1da75eb1a235398b5cddeae0e2378bbb2c92c03f8d7a9e5680b8a2512fa9f8230b713b70d3cc164497451157998520ee5d62e5637cef07e023a6033efb
7
- data.tar.gz: e587ebfd379a4ff909583109ba42d16c572aeaab69bf2303efa5bd92325750c8cddb3a20dd8712e668233691a1cb3eba25250fbbdb936651fd15a9722514a12d
6
+ metadata.gz: b2184539cae7f69fdc3c53d993394fe4a5cb78bf2fb2e92a7183d61c6de4cab4e9117891859ddbd3c09d54f7905de2ea9c3059279e56d7b28c4f3a286f7247a6
7
+ data.tar.gz: e040f8691f7d51c07b6f9a7f7c03de42488a4f02815c683fd1a763eff6f985e4899a91c620d0bc37a4c9942e1c7e294c1e7220e9499a4ee573734cddeeb39acc
data/CHANGELOG.md CHANGED
@@ -1,5 +1,10 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## 1.7.0 (2022-10-01)
4
+
5
+ * Better regexp to match evaluated value
6
+ * Make `base_node` as the root matching node
7
+
3
8
  ## 1.6.1 (2022-09-28)
4
9
 
5
10
  * Do not handle `erange` and `irange` in `actual_value`
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- node_query (1.6.1)
4
+ node_query (1.7.0)
5
5
  activesupport (< 7.0.0)
6
6
 
7
7
  GEM
@@ -78,7 +78,7 @@ GEM
78
78
  thor (1.2.1)
79
79
  tzinfo (2.0.5)
80
80
  concurrent-ruby (~> 1.0)
81
- zeitwerk (2.6.0)
81
+ zeitwerk (2.6.1)
82
82
 
83
83
  PLATFORMS
84
84
  x86_64-darwin-21
@@ -15,10 +15,10 @@ module NodeQuery::Compiler
15
15
 
16
16
  # Get the expected value.
17
17
  # @return [Array]
18
- def expected_value
18
+ def expected_value(base_node)
19
19
  expected = []
20
20
  expected.push(@value) if @value
21
- expected += @rest.expected_value if @rest
21
+ expected += @rest.expected_value(base_node) if @rest
22
22
  expected
23
23
  end
24
24
 
@@ -15,10 +15,10 @@ module NodeQuery::Compiler
15
15
 
16
16
  # Check if the node matches the attribute.
17
17
  # @param node [Node] the node
18
+ # @param base_node [Node] the bae node for evaluated value
18
19
  # @return [Boolean]
19
- def match?(node)
20
- @value.base_node = node if @value.is_a?(String)
21
- node && @value.match?(NodeQuery::Helper.get_target_node(node, @key), @operator)
20
+ def match?(node, base_node)
21
+ node && @value.match?(NodeQuery::Helper.get_target_node(node, @key), base_node, @operator)
22
22
  end
23
23
 
24
24
  def to_s
@@ -13,9 +13,10 @@ module NodeQuery::Compiler
13
13
 
14
14
  # Check if the node matches the attribute list.
15
15
  # @param node [Node] the node
16
+ # @param base_node [Node] the base node for evaluated value
16
17
  # @return [Boolean]
17
- def match?(node)
18
- @attribute.match?(node) && (!@rest || @rest.match?(node))
18
+ def match?(node, base_node)
19
+ @attribute.match?(node, base_node) && (!@rest || @rest.match?(node, base_node))
19
20
  end
20
21
 
21
22
  def to_s
@@ -13,11 +13,12 @@ module NodeQuery::Compiler
13
13
 
14
14
  # Check if node matches the selector.
15
15
  # @param node [Node] the node
16
+ # @param base_node [Node] the base node for evaluated value
16
17
  # @return [Boolean]
17
- def match?(node, _operator = '==')
18
+ def match?(node, base_node, _operator = '==')
18
19
  return false unless node
19
20
 
20
- @node_type.to_sym == NodeQuery.adapter.get_node_type(node) && (!@attribute_list || @attribute_list.match?(node))
21
+ @node_type.to_sym == NodeQuery.adapter.get_node_type(node) && (!@attribute_list || @attribute_list.match?(node, base_node))
21
22
  end
22
23
 
23
24
  def to_s
@@ -12,69 +12,71 @@ module NodeQuery::Compiler
12
12
  # Check if the actual value matches the expected value.
13
13
  #
14
14
  # @param node [Node] node to calculate actual value
15
+ # @param base_node [Node] the base node for evaluated value
15
16
  # @param operator [String] operator to compare with expected value, operator can be <code>'=='</code>, <code>'!='</code>, <code>'>'</code>, <code>'>='</code>, <code>'<'</code>, <code>'<='</code>, <code>'includes'</code>, <code>'in'</code>, <code>'not_in'</code>, <code>'=~'</code>, <code>'!~'</code>
16
17
  # @return [Boolean] true if actual value matches the expected value
17
18
  # @raise [NodeQuery::Compiler::InvalidOperatorError] if operator is invalid
18
- def match?(node, operator)
19
+ def match?(node, base_node, operator)
19
20
  raise InvalidOperatorError, "invalid operator #{operator}" unless valid_operator?(operator)
20
21
 
22
+ actual = actual_value(node)
23
+ expected = expected_value(base_node)
21
24
  case operator
22
25
  when '!='
23
- if expected_value.is_a?(::Array)
24
- actual = actual_value(node)
25
- !actual.is_a?(::Array) || actual.size != expected_value.size ||
26
- actual.zip(expected_value).any? { |actual_node, expected_node| expected_node.match?(actual_node, '!=') }
26
+ if expected.is_a?(::Array)
27
+ !actual.is_a?(::Array) || actual.size != expected.size ||
28
+ actual.zip(expected).any? { |actual_child, expected_child| expected_child.match?(actual_child, base_node, '!=') }
27
29
  else
28
- !is_equal?(node)
30
+ !is_equal?(actual, expected)
29
31
  end
30
32
  when '=~'
31
- actual_value(node) =~ expected_value
33
+ actual =~ expected
32
34
  when '!~'
33
- actual_value(node) !~ expected_value
35
+ actual !~ expected
34
36
  when '^='
35
- actual_value(node).start_with?(expected_value)
37
+ actual.start_with?(expected)
36
38
  when '$='
37
- actual_value(node).end_with?(expected_value)
39
+ actual.end_with?(expected)
38
40
  when '*='
39
- actual_value(node).include?(expected_value)
41
+ actual.include?(expected)
40
42
  when '>'
41
- actual_value(node) > expected_value
43
+ actual > expected
42
44
  when '>='
43
- actual_value(node) >= expected_value
45
+ actual >= expected
44
46
  when '<'
45
- actual_value(node) < expected_value
47
+ actual < expected
46
48
  when '<='
47
- actual_value(node) <= expected_value
49
+ actual <= expected
48
50
  when 'in'
49
51
  if node.is_a?(Array)
50
- node.all? { |child| expected_value.any? { |expected| expected.match?(child, '==') } }
52
+ node.all? { |child| expected.any? { |expected_child| expected_child.match?(child, base_node, '==') } }
51
53
  else
52
- expected_value.any? { |expected| expected.match?(node, '==') }
54
+ expected.any? { |expected_child| expected_child.match?(node, base_node, '==') }
53
55
  end
54
56
  when 'not_in'
55
57
  if node.is_a?(Array)
56
- node.all? { |child| expected_value.all? { |expected| expected.match?(child, '!=') } }
58
+ node.all? { |child| expected.all? { |expected_child| expected_child.match?(child, base_node, '!=') } }
57
59
  else
58
- expected_value.all? { |expected| expected.match?(node, '!=') }
60
+ expected.all? { |expected_child| expected_child.match?(node, base_node, '!=') }
59
61
  end
60
62
  when 'includes'
61
- actual_value(node).any? { |actual| actual == expected_value }
63
+ actual.any? { |actual_child| actual_child == expected }
62
64
  else
63
- if expected_value.is_a?(::Array)
64
- actual = actual_value(node)
65
- actual.is_a?(::Array) && actual.size == expected_value.size &&
66
- actual.zip(expected_value).all? { |actual_node, expected_node| expected_node.match?(actual_node, '==') }
65
+ if expected.is_a?(::Array)
66
+ actual.is_a?(::Array) && actual.size == expected.size &&
67
+ actual.zip(expected).all? { |actual_child, expected_child| expected_child.match?(actual_child, base_node, '==') }
67
68
  else
68
- is_equal?(node)
69
+ is_equal?(actual, expected)
69
70
  end
70
71
  end
71
72
  end
72
73
 
73
- # Check if the actual value equals the node value.
74
- # @param node [Node] the node
75
- # @return [Boolean] true if the actual value equals the node value.
76
- def is_equal?(node)
77
- actual_value(node) == expected_value
74
+ # Check if the actual value equals the expected value.
75
+ # @param acutal
76
+ # @param expected
77
+ # @return [Boolean] true if the actual value equals the expected value.
78
+ def is_equal?(actual, expected)
79
+ actual == expected
78
80
  end
79
81
 
80
82
  # Get the actual value from ast node.
@@ -104,8 +106,9 @@ module NodeQuery::Compiler
104
106
  end
105
107
 
106
108
  # Get the expected value
109
+ # @param base_node [Node] the base node for evaluated value
107
110
  # @return expected value, could be integer, float, string, boolean, nil, range, and etc.
108
- def expected_value
111
+ def expected_value(base_node)
109
112
  @value
110
113
  end
111
114
 
@@ -13,9 +13,10 @@ module NodeQuery::Compiler
13
13
 
14
14
  # Check if the regexp value matches the node value.
15
15
  # @param node [Node] the node
16
+ # @param _base_node [Node] the base node for evaluated value
16
17
  # @param operator [String] the operator
17
18
  # @return [Boolean] true if the regexp value matches the node value, otherwise, false.
18
- def match?(node, operator = '=~')
19
+ def match?(node, _base_node, operator = '=~')
19
20
  match =
20
21
  if NodeQuery.adapter.is_node?(node)
21
22
  @value.match(NodeQuery.adapter.get_source(node))
@@ -22,8 +22,9 @@ module NodeQuery::Compiler
22
22
 
23
23
  # Check if node matches the selector.
24
24
  # @param node [Parser::AST::Node] the node
25
- def match?(node)
26
- NodeQuery.adapter.is_node?(node) && (!@basic_selector || @basic_selector.match?(node)) && match_pseudo_class?(node)
25
+ # @param base_node [Parser::AST::Node] the base node for evaluated node
26
+ def match?(node, base_node)
27
+ NodeQuery.adapter.is_node?(node) && (!@basic_selector || @basic_selector.match?(node, base_node)) && match_pseudo_class?(node)
27
28
  end
28
29
 
29
30
  # Query nodes by the selector.
@@ -49,25 +50,25 @@ module NodeQuery::Compiler
49
50
  return find_nodes_by_goto_scope(node) if @goto_scope
50
51
 
51
52
  if options[:including_self] && !options[:recursive]
52
- return match?(node) ? [node] : []
53
+ return match?(node, node) ? [node] : []
53
54
  end
54
55
 
55
56
  nodes = []
56
- if options[:including_self] && match?(node)
57
+ if options[:including_self] && match?(node, node)
57
58
  nodes << node
58
59
  return nodes if options[:stop_at_first_match]
59
60
  end
60
61
  if @basic_selector
61
62
  if options[:recursive]
62
63
  NodeQuery::Helper.handle_recursive_child(node) do |child_node|
63
- if match?(child_node)
64
+ if match?(child_node, child_node)
64
65
  nodes << child_node
65
66
  break if options[:stop_at_first_match]
66
67
  end
67
68
  end
68
69
  else
69
70
  NodeQuery.adapter.get_children(node).each do |child_node|
70
- if match?(child_node)
71
+ if match?(child_node, child_node)
71
72
  nodes << child_node
72
73
  break if options[:stop_at_first_match]
73
74
  end
@@ -106,25 +107,25 @@ module NodeQuery::Compiler
106
107
  when '>'
107
108
  if node.is_a?(::Array)
108
109
  node.each do |child_node|
109
- nodes << child_node if @rest.match?(child_node)
110
+ nodes << child_node if @rest.match?(child_node, child_node)
110
111
  end
111
112
  else
112
113
  node.children.each do |child_node|
113
114
  if NodeQuery.adapter.is_node?(child_node) && :begin == NodeQuery.adapter.get_node_type(child_node)
114
115
  child_node.children.each do |child_child_node|
115
- nodes << child_child_node if @rest.match?(child_child_node)
116
+ nodes << child_child_node if @rest.match?(child_child_node, child_child_node)
116
117
  end
117
- elsif @rest.match?(child_node)
118
+ elsif @rest.match?(child_node, child_node)
118
119
  nodes << child_node
119
120
  end
120
121
  end
121
122
  end
122
123
  when '+'
123
124
  next_sibling = node.siblings.first
124
- nodes << next_sibling if @rest.match?(next_sibling)
125
+ nodes << next_sibling if @rest.match?(next_sibling, next_sibling)
125
126
  when '~'
126
127
  node.siblings.each do |sibling_node|
127
- nodes << sibling_node if @rest.match?(sibling_node)
128
+ nodes << sibling_node if @rest.match?(sibling_node, sibling_node)
128
129
  end
129
130
  end
130
131
  nodes
@@ -5,8 +5,6 @@ module NodeQuery::Compiler
5
5
  class String
6
6
  include Comparable
7
7
 
8
- attr_accessor :base_node
9
-
10
8
  # Initialize a String.
11
9
  # @param value [String] the string value
12
10
  def initialize(value:)
@@ -18,16 +16,18 @@ module NodeQuery::Compiler
18
16
  # if the source code of the node is @id = id,
19
17
  # and the @value is "@{{right_vaue}}",
20
18
  # then it returns "@id".
19
+ # @param base_node [Node] the base node for evaluated value
21
20
  # @return [String] the expected string, if it contains evaluated value, evaluate the node value.
22
- def expected_value
21
+ def expected_value(base_node)
23
22
  NodeQuery::Helper.evaluate_node_value(base_node, @value)
24
23
  end
25
24
 
26
25
  # Check if the actual value equals the node value.
27
26
  # @param node [Node] the node
27
+ # @param base_node [Node] the base node for evaluated value
28
28
  # @return [Boolean] true if the actual value equals the node value.
29
- def is_equal?(node)
30
- NodeQuery::Helper.to_string(actual_value(node)) == expected_value
29
+ def is_equal?(actual, expected)
30
+ NodeQuery::Helper.to_string(actual) == expected
31
31
  end
32
32
 
33
33
  # Get valid operators.
@@ -48,7 +48,7 @@ class NodeQuery::Helper
48
48
  # @param str [String] string to be evaluated
49
49
  # @return [String] evaluated string
50
50
  def evaluate_node_value(node, str)
51
- str.scan(/{{(.*?)}}/).each do |match_data|
51
+ str.scan(/{{(.+?)}}/).each do |match_data|
52
52
  target_node = NodeQuery::Helper.get_target_node(node, match_data.first)
53
53
  str = str.sub("{{#{match_data.first}}}", to_string(target_node))
54
54
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class NodeQuery
4
- VERSION = "1.6.1"
4
+ VERSION = "1.7.0"
5
5
  end
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.6.1
4
+ version: 1.7.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-09-28 00:00:00.000000000 Z
11
+ date: 2022-10-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport