jini 1.1.5 → 1.2.5

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: 1cb24e4c751e1f13a8bf330035a607e88f50ad4bd9bfa88716bae22ec9c626b8
4
- data.tar.gz: 8566642f48c9b868b601aef9311a0894982da11ee27f01bc4390b0708169d788
3
+ metadata.gz: '0682d203672579b1d46fdb710ca9a3d43741cd464b22e4f4bf593b6b923eb17b'
4
+ data.tar.gz: 060a615af5fd80421f244696723cef10e719cf34e6ed89dc89d5f2f900767e39
5
5
  SHA512:
6
- metadata.gz: 7b86628c45f695f62b67687a90f1e1baa9147a0557303051ec7c5637d0862071c463964657203ac1729c259921a00b3c912c958d56da5f428934ec5fcc121c7d
7
- data.tar.gz: 191a9dac94b2f19f89d86d1bfc12aa8e0beebe1a13be6953283e5b5f884ea1614b8b837120f975d381a4f2dc9c9626b3263d737269f3cf712f8df1cc184f2739
6
+ metadata.gz: f9d5eecff4e6d44060bf49dbcf929887d316a3d9119a81b3bd141ee03296478209bf506f49c9fe3f3130dd891ad8bddf62c1ab27191de3f38a28afc931abe56d
7
+ data.tar.gz: 4c5937f0ca445df51871d7937096f083c01de586b7bc9d33a11c899f78bbc465ce0fb141344eb020160b2933546d2bd78091bc4abcc1252b1f2f8ab9917fbffd
data/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
 
4
4
  [![Gem Version](https://badge.fury.io/rb/jini.svg)](https://badge.fury.io/rb/jini)
5
5
 
6
- The class [`Jini`](https://www.rubydoc.info/gems/jini/1.1.5/Jini) helps you build a XPATH.
6
+ The class [`Jini`](https://www.rubydoc.info/gems/jini/1.2.5/Jini) helps you build a XPATH.
7
7
 
8
8
  ```ruby
9
9
  require 'jini'
@@ -17,7 +17,7 @@ xpath = Jini
17
17
  puts(xpath) # -> xpath: /parent[@key="value"]
18
18
  ```
19
19
 
20
- The full list of methods is [here](https://www.rubydoc.info/gems/jini/1.1.5).
20
+ The full list of methods is [here](https://www.rubydoc.info/gems/jini/1.2.5).
21
21
 
22
22
  Install it:
23
23
 
data/jini.gemspec CHANGED
@@ -5,7 +5,7 @@ Gem::Specification.new do |s|
5
5
  s.required_rubygems_version = Gem::Requirement.new('>= 0') if s.respond_to? :required_rubygems_version=
6
6
  s.required_ruby_version = '>=2.6.8'
7
7
  s.name = 'jini'
8
- s.version = '1.1.5'
8
+ s.version = '1.2.5'
9
9
  s.license = 'MIT'
10
10
  s.summary = 'Simple Immutable Ruby XPATH Builder'
11
11
  s.description = 'Class Jini helps you build a XPATH and then modify its parts via a simple fluent interface.'
data/lib/jini.rb CHANGED
@@ -1,5 +1,3 @@
1
- # frozen_string_literal: true
2
-
3
1
  # (The MIT License)
4
2
  #
5
3
  # Copyright (c) 2022 Ivanchuk Ivan
@@ -40,6 +38,9 @@ class Jini
40
38
  # When path not valid
41
39
  class InvalidPath < StandardError; end
42
40
 
41
+ # When method not found
42
+ class UnsupportedOperation < StandardError; end
43
+
43
44
  # Makes new object.
44
45
  # By default it creates an empty path and you can ignore the head parameter.
45
46
  # @param head [String]
@@ -58,6 +59,68 @@ class Jini
58
59
  @head.to_s
59
60
  end
60
61
 
62
+ class << self
63
+ # From.
64
+ # Creates new Jini object from XPATH.
65
+ #
66
+ # @param [String] xpath
67
+ # @raise [InvalidPath] when XPATH is invalid
68
+ # @return [Jini] object
69
+ def from(xpath)
70
+ raise InvalidPath, 'XPATH isn\'t valid' unless xpath_match?(xpath)
71
+ Jini.new(xpath)
72
+ end
73
+
74
+ private
75
+
76
+ # This regex matches general case of XPATH.
77
+ # @param xpath [String]
78
+ # @return [Boolean] matching regex
79
+ def xpath_match?(xpath)
80
+ xpath.match?(xpath_regex)
81
+ end
82
+
83
+ def prefix_regex
84
+ %r{^/?}
85
+ end
86
+
87
+ def tag_regex
88
+ /([a-zA-Z0-9]+:)?[a-zA-Z0-9]+/
89
+ end
90
+
91
+ def bracket_regex
92
+ /(\[[^\[\]]*\])/
93
+ end
94
+
95
+ def attr_regex
96
+ /@\w+=[^\]]+/
97
+ end
98
+
99
+ def or_regex
100
+ /(\|)/
101
+ end
102
+
103
+ def namespace_regex
104
+ /([a-zA-Z0-9]+:)?[a-zA-Z0-9]+/
105
+ end
106
+
107
+ def sub_xpath_regex
108
+ /#{namespace_regex}#{bracket_regex}*(#{attr_regex})*/
109
+ end
110
+
111
+ def or_sub_xpath_regex
112
+ /#{or_regex}#{namespace_regex}#{bracket_regex}*(#{attr_regex})*/
113
+ end
114
+
115
+ def xpath_regex
116
+ %r{\A#{prefix_regex}#{namespace_regex}(/#{sub_xpath_regex})*#{or_sub_xpath_regex}*(/#{sub_xpath_regex})*\Z}
117
+ end
118
+ end
119
+
120
+ def ==(other)
121
+ self.class == other.class && to_s == other.to_s
122
+ end
123
+
61
124
  # Additional node for xpath.
62
125
  # @param node [String] the node
63
126
  # @return [Jini] object with additional node
@@ -237,7 +300,7 @@ class Jini
237
300
 
238
301
  # @param node [String] node for check
239
302
  def space_check(node)
240
- raise InvalidPath, "Nodes can't contain spaces: #{node} – contain space." if valid? node
303
+ raise InvalidPath, "Nodes can't contain spaces: #{node} – contain space." if valid_node? node
241
304
  end
242
305
 
243
306
  # Regex: '[' or ']' or '@' or '//'.
@@ -250,7 +313,7 @@ class Jini
250
313
  # Regex: '[' or ']' or '@' or '=' or '<' or '>'.
251
314
  # @param node [String] node for check
252
315
  # @return [Boolean] matching regex
253
- def valid?(node)
316
+ def valid_node?(node)
254
317
  !node.match(/[|]|@|=|>|</) && node.include?(' ')
255
318
  end
256
319
 
@@ -264,4 +327,12 @@ class Jini
264
327
  def purge_head(token)
265
328
  @head.gsub(token, '')
266
329
  end
330
+
331
+ def method_missing(method_name, *_args)
332
+ raise UnsupportedOperation, "The method #{method_name} was not found!"
333
+ end
334
+
335
+ def respond_to_missing?(_method_name, _include_private = false)
336
+ true
337
+ end
267
338
  end
data/test/jini_test.rb CHANGED
@@ -283,6 +283,14 @@ class JiniTest < Minitest::Test
283
283
  end
284
284
 
285
285
  def test_nodes
286
+ nodes = Jini.new(PARENT)
287
+ .add_node(CHILD)
288
+ .add_attr('key', 'value')
289
+ .add_node('under_attr')
290
+ .add_nodes('many')
291
+ .at(3)
292
+ .nodes
293
+ assert_includes(nodes, 'under_attr')
286
294
  assert_equal(
287
295
  [].append(
288
296
  'parent',
@@ -290,13 +298,7 @@ class JiniTest < Minitest::Test
290
298
  'under_attr',
291
299
  'many[3]'
292
300
  ),
293
- Jini.new(PARENT)
294
- .add_node(CHILD)
295
- .add_attr('key', 'value')
296
- .add_node('under_attr')
297
- .add_nodes('many')
298
- .at(3)
299
- .nodes
301
+ nodes
300
302
  )
301
303
  end
302
304
 
@@ -329,5 +331,26 @@ class JiniTest < Minitest::Test
329
331
  .to_s
330
332
  )
331
333
  end
334
+
335
+ def test_from_xpath_success
336
+ x = '/parent/child[@toy="plane"]'
337
+ jini = Jini.new('/parent').add_node(CHILD).add_attr('toy', 'plane')
338
+ assert_nothing_raised do
339
+ Jini.from x
340
+ Jini.from jini.to_s
341
+ end
342
+ assert_equal Jini.from(x), Jini.from(jini.to_s)
343
+ end
344
+
345
+ def test_from_xpath_fails
346
+ assert_raises(Jini::InvalidPath) { Jini.from '/parent/chld[' }
347
+ assert_raises(Jini::InvalidPath) { Jini.from '' }
348
+ end
349
+
350
+ def test_method_missing_fails
351
+ assert_raises(Jini::UnsupportedOpertaion) do
352
+ Jini.new.bark
353
+ end
354
+ end
332
355
  end
333
356
  # rubocop:enable Metrics/ClassLength
data/test/test_helper.rb CHANGED
@@ -24,6 +24,14 @@ $stdout.sync = true
24
24
 
25
25
  require 'simplecov'
26
26
 
27
+ module Minitest
28
+ module Assertions
29
+ def assert_nothing_raised(*)
30
+ yield
31
+ end
32
+ end
33
+ end
34
+
27
35
  SimpleCov.start
28
36
  if ENV['CI'] == 'true'
29
37
  require 'codecov'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jini
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.5
4
+ version: 1.2.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ivan Ivanchuck