json_p3 0.4.1 → 1.0.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 +4 -4
- checksums.yaml.gz.sig +0 -0
- data/.rubocop.yml +26 -9
- data/.ruby-version +1 -1
- data/CHANGELOG.md +54 -0
- data/README.md +125 -123
- data/Rakefile +3 -3
- data/certs/jgrp.pem +21 -21
- data/lib/json_p3/errors.rb +51 -43
- data/lib/json_p3/patch/op.rb +23 -0
- data/lib/json_p3/patch/op_add.rb +51 -0
- data/lib/json_p3/patch/op_copy.rb +64 -0
- data/lib/json_p3/patch/op_move.rb +74 -0
- data/lib/json_p3/patch/op_remove.rb +56 -0
- data/lib/json_p3/patch/op_replace.rb +54 -0
- data/lib/json_p3/patch/op_test.rb +31 -0
- data/lib/json_p3/patch.rb +15 -330
- data/lib/json_p3/path/environment.rb +113 -0
- data/lib/json_p3/path/filter.rb +463 -0
- data/lib/json_p3/path/function.rb +12 -0
- data/lib/json_p3/path/function_extensions/count.rb +15 -0
- data/lib/json_p3/path/function_extensions/length.rb +17 -0
- data/lib/json_p3/path/function_extensions/match.rb +62 -0
- data/lib/json_p3/path/function_extensions/pattern.rb +42 -0
- data/lib/json_p3/path/function_extensions/search.rb +44 -0
- data/lib/json_p3/path/function_extensions/value.rb +15 -0
- data/lib/json_p3/path/lexer.rb +220 -0
- data/lib/json_p3/path/node.rb +48 -0
- data/lib/json_p3/path/parser.rb +676 -0
- data/lib/json_p3/path/query.rb +74 -0
- data/lib/json_p3/path/segment.rb +172 -0
- data/lib/json_p3/path/selector.rb +304 -0
- data/lib/json_p3/path/serialize.rb +16 -0
- data/lib/json_p3/path/unescape.rb +134 -0
- data/lib/json_p3/pointer.rb +15 -76
- data/lib/json_p3/relative_pointer.rb +69 -0
- data/lib/json_p3/version.rb +1 -1
- data/lib/json_p3.rb +50 -13
- data/sig/json_p3/cache.rbs +21 -0
- data/sig/json_p3/errors.rbs +55 -0
- data/sig/json_p3/patch.rbs +145 -0
- data/sig/json_p3/path/environment.rbs +81 -0
- data/sig/json_p3/path/filter.rbs +196 -0
- data/sig/json_p3/path/function.rbs +94 -0
- data/sig/json_p3/path/lexer.rbs +62 -0
- data/sig/json_p3/path/node.rbs +46 -0
- data/sig/json_p3/path/parser.rbs +92 -0
- data/sig/json_p3/path/query.rbs +47 -0
- data/sig/json_p3/path/segment.rbs +54 -0
- data/sig/json_p3/path/selector.rbs +100 -0
- data/sig/json_p3/path/serialize.rbs +9 -0
- data/sig/json_p3/path/unescape.rbs +12 -0
- data/sig/json_p3/pointer.rbs +64 -0
- data/sig/json_p3/relative_pointer.rbs +30 -0
- data/sig/json_p3.rbs +24 -1318
- data.tar.gz.sig +0 -0
- metadata +66 -46
- metadata.gz.sig +0 -0
- data/lib/json_p3/environment.rb +0 -111
- data/lib/json_p3/filter.rb +0 -459
- data/lib/json_p3/function.rb +0 -10
- data/lib/json_p3/function_extensions/count.rb +0 -15
- data/lib/json_p3/function_extensions/length.rb +0 -17
- data/lib/json_p3/function_extensions/match.rb +0 -62
- data/lib/json_p3/function_extensions/pattern.rb +0 -39
- data/lib/json_p3/function_extensions/search.rb +0 -44
- data/lib/json_p3/function_extensions/value.rb +0 -15
- data/lib/json_p3/lexer.rb +0 -440
- data/lib/json_p3/node.rb +0 -44
- data/lib/json_p3/parser.rb +0 -553
- data/lib/json_p3/path.rb +0 -72
- data/lib/json_p3/segment.rb +0 -158
- data/lib/json_p3/selector.rb +0 -306
- data/lib/json_p3/serialize.rb +0 -13
- data/lib/json_p3/token.rb +0 -36
- data/lib/json_p3/unescape.rb +0 -112
data/lib/json_p3/errors.rb
CHANGED
|
@@ -1,57 +1,65 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module JSONP3
|
|
4
|
-
#
|
|
5
|
-
class
|
|
4
|
+
# Base class for all errors raised from this gem.
|
|
5
|
+
class Error < StandardError; end
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
module Path
|
|
8
|
+
# Base class for all JSONPath errors.
|
|
9
|
+
class Error < JSONP3::Error
|
|
10
|
+
FULL_MESSAGE = ((RUBY_VERSION.split(".")&.map(&:to_i) <=> [3, 2, 0]) || -1) < 1
|
|
10
11
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
def initialize(msg, token, query)
|
|
13
|
+
super(msg)
|
|
14
|
+
@token = token
|
|
15
|
+
@query = query
|
|
16
|
+
end
|
|
15
17
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
18
|
+
def detailed_message(highlight: true, **_kwargs)
|
|
19
|
+
if @query.strip.empty?
|
|
20
|
+
"empty query"
|
|
21
|
+
else
|
|
22
|
+
value = JSONP3::Path.get_token_value(@token, @query)
|
|
23
|
+
lines = @query[...@token[1]]&.lines or [""] # pleasing the type checker
|
|
24
|
+
lineno = lines.length
|
|
25
|
+
col = lines.last.length
|
|
26
|
+
pad = " " * lineno.to_s.length
|
|
27
|
+
pointer = (" " * col) + ("^" * [value.length, 1].max)
|
|
28
|
+
<<~ENDOFMESSAGE.strip
|
|
29
|
+
#{self.class}: #{message}
|
|
30
|
+
#{pad} -> '#{@query}' #{lineno}:#{col}
|
|
31
|
+
#{pad} |
|
|
32
|
+
#{lineno} | #{@query}
|
|
33
|
+
#{pad} | #{pointer} #{highlight ? "\e[1m#{message}\e[0m" : message}
|
|
34
|
+
ENDOFMESSAGE
|
|
35
|
+
end
|
|
32
36
|
end
|
|
33
|
-
end
|
|
34
37
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
38
|
+
def full_message(highlight: true, order: :top)
|
|
39
|
+
if FULL_MESSAGE
|
|
40
|
+
# For Ruby < 3.2.0
|
|
41
|
+
"#{super}\n#{detailed_message(highlight: highlight, order: order)}"
|
|
42
|
+
else
|
|
43
|
+
super
|
|
44
|
+
end
|
|
41
45
|
end
|
|
42
46
|
end
|
|
43
|
-
end
|
|
44
47
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
48
|
+
class SyntaxError < Error; end
|
|
49
|
+
class TypeError < Error; end
|
|
50
|
+
class NameError < Error; end
|
|
51
|
+
class RecursionError < Error; end
|
|
52
|
+
end
|
|
49
53
|
|
|
50
|
-
class
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
+
class Pointer
|
|
55
|
+
class Error < JSONP3::Error; end
|
|
56
|
+
class IndexError < Error; end
|
|
57
|
+
class SyntaxError < Error; end
|
|
58
|
+
class TypeError < Error; end
|
|
59
|
+
end
|
|
54
60
|
|
|
55
|
-
class
|
|
56
|
-
|
|
61
|
+
class Patch
|
|
62
|
+
class Error < JSONP3::Error; end
|
|
63
|
+
class TestFailure < Error; end
|
|
64
|
+
end
|
|
57
65
|
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module JSONP3
|
|
4
|
+
class Patch
|
|
5
|
+
# Base class for all JSON Patch operations
|
|
6
|
+
class Op
|
|
7
|
+
# Return the name of the patch operation.
|
|
8
|
+
def name
|
|
9
|
+
raise "JSON Patch operations must implement #name"
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
# Apply the patch operation to _value_.
|
|
13
|
+
def apply!(_value, _index)
|
|
14
|
+
raise "JSON Patch operations must implement apply!(value, index)"
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# Return a JSON-like representation of this patch operation.
|
|
18
|
+
def to_h
|
|
19
|
+
raise "JSON Patch operations must implement #to_h"
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module JSONP3
|
|
4
|
+
class Patch
|
|
5
|
+
# The JSON Patch _add_ operation.
|
|
6
|
+
class OpAdd < Op
|
|
7
|
+
# @param pointer [JSONPointer]
|
|
8
|
+
# @param value [JSON-like value]
|
|
9
|
+
def initialize(pointer, value)
|
|
10
|
+
super()
|
|
11
|
+
@pointer = pointer
|
|
12
|
+
@value = value
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def name
|
|
16
|
+
"add"
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def apply!(value, index)
|
|
20
|
+
parent, obj = @pointer.resolve_with_parent(value)
|
|
21
|
+
return @value if parent == JSONP3::Pointer::UNDEFINED && @pointer.tokens.empty?
|
|
22
|
+
|
|
23
|
+
if parent == JSONP3::Pointer::UNDEFINED
|
|
24
|
+
raise JSONP3::Patch::Error,
|
|
25
|
+
"no such property or item '#{@pointer.parent}' (#{name}:#{index})"
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
target = @pointer.tokens.last
|
|
29
|
+
if parent.is_a?(Array)
|
|
30
|
+
if obj == JSONP3::Pointer::UNDEFINED
|
|
31
|
+
raise JSONP3::Patch::Error, "index out of range (#{name}:#{index})" unless target == "-"
|
|
32
|
+
|
|
33
|
+
parent << @value
|
|
34
|
+
else
|
|
35
|
+
parent.insert(target.to_i, @value)
|
|
36
|
+
end
|
|
37
|
+
elsif parent.is_a?(Hash)
|
|
38
|
+
parent[target] = @value
|
|
39
|
+
else
|
|
40
|
+
raise JSONP3::Patch::Error, "unexpected operation on #{parent.class} (#{name}:#{index})"
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
value
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def to_h
|
|
47
|
+
{ "op" => name, "path" => @pointer.to_s, "value" => @value }
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module JSONP3
|
|
4
|
+
class Patch
|
|
5
|
+
# The JSON Patch _copy_ operation.
|
|
6
|
+
class OpCopy < Op
|
|
7
|
+
# @param from [JSONPointer]
|
|
8
|
+
# @param pointer [JSONPointer]
|
|
9
|
+
def initialize(from, pointer)
|
|
10
|
+
super()
|
|
11
|
+
@from = from
|
|
12
|
+
@pointer = pointer
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def name
|
|
16
|
+
"copy"
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def apply!(value, index)
|
|
20
|
+
# Grab the source value.
|
|
21
|
+
_source_parent, source_obj = @from.resolve_with_parent(value)
|
|
22
|
+
if source_obj == JSONP3::Pointer::UNDEFINED
|
|
23
|
+
raise JSONP3::Patch::Error,
|
|
24
|
+
"source object does not exist (#{name}:#{index})"
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Find the parent of the destination pointer.
|
|
28
|
+
dest_parent, _dest_obj = @pointer.resolve_with_parent(value)
|
|
29
|
+
return deep_copy(source_obj) if dest_parent == JSONP3::Pointer::UNDEFINED
|
|
30
|
+
|
|
31
|
+
dest_target = @pointer.tokens.last
|
|
32
|
+
if dest_target == JSONP3::Pointer::UNDEFINED
|
|
33
|
+
raise JSONP3::Patch::Error,
|
|
34
|
+
"unexpected operation (#{name}:#{index})"
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Write the source value to the destination.
|
|
38
|
+
if dest_parent.is_a?(Array)
|
|
39
|
+
if dest_target == "-"
|
|
40
|
+
dest_parent << source_obj
|
|
41
|
+
else
|
|
42
|
+
dest_parent.insert(dest_target.to_i, deep_copy(source_obj))
|
|
43
|
+
end
|
|
44
|
+
elsif dest_parent.is_a?(Hash)
|
|
45
|
+
dest_parent[dest_target] = deep_copy(source_obj)
|
|
46
|
+
else
|
|
47
|
+
raise JSONP3::Patch::Error, "unexpected operation on #{dest_parent.class} (#{name}:#{index})"
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
value
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def to_h
|
|
54
|
+
{ "op" => name, "from" => @from.to_s, "path" => @pointer.to_s }
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
private
|
|
58
|
+
|
|
59
|
+
def deep_copy(obj)
|
|
60
|
+
Marshal.load(Marshal.dump(obj))
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module JSONP3
|
|
4
|
+
class Patch
|
|
5
|
+
# The JSON Patch _move_ operation.
|
|
6
|
+
class OpMove < Op
|
|
7
|
+
# @param from [JSONPointer]
|
|
8
|
+
# @param pointer [JSONPointer]
|
|
9
|
+
def initialize(from, pointer)
|
|
10
|
+
super()
|
|
11
|
+
@from = from
|
|
12
|
+
@pointer = pointer
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def name
|
|
16
|
+
"move"
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def apply!(value, index)
|
|
20
|
+
if @pointer.relative_to?(@from)
|
|
21
|
+
raise JSONP3::Patch::Error,
|
|
22
|
+
"can't move object to one of its children (#{name}:#{index})"
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# Grab the source value.
|
|
26
|
+
source_parent, source_obj = @from.resolve_with_parent(value)
|
|
27
|
+
if source_obj == JSONP3::Pointer::UNDEFINED
|
|
28
|
+
raise JSONP3::Patch::Error,
|
|
29
|
+
"source object does not exist (#{name}:#{index})"
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
source_target = @from.tokens.last
|
|
33
|
+
if source_target == JSONP3::Pointer::UNDEFINED
|
|
34
|
+
raise JSONP3::Patch::Error,
|
|
35
|
+
"unexpected operation (#{name}:#{index})"
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# Delete the target value from the source location.
|
|
39
|
+
if source_parent.is_a?(Array)
|
|
40
|
+
source_parent.delete_at(source_target.to_i)
|
|
41
|
+
elsif source_parent.is_a?(Hash)
|
|
42
|
+
source_parent.delete(source_target)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Find the parent of the destination pointer.
|
|
46
|
+
dest_parent, _dest_obj = @pointer.resolve_with_parent(value)
|
|
47
|
+
return source_obj if dest_parent == JSONP3::Pointer::UNDEFINED
|
|
48
|
+
|
|
49
|
+
dest_target = @pointer.tokens.last
|
|
50
|
+
if dest_target == JSONP3::Pointer::UNDEFINED
|
|
51
|
+
raise JSONP3::Patch::Error,
|
|
52
|
+
"unexpected operation (#{name}:#{index})"
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# Write the source value to the destination.
|
|
56
|
+
if dest_parent.is_a?(Array)
|
|
57
|
+
if dest_target == "-"
|
|
58
|
+
dest_parent << source_obj
|
|
59
|
+
else
|
|
60
|
+
dest_parent[dest_target.to_i] = source_obj
|
|
61
|
+
end
|
|
62
|
+
elsif dest_parent.is_a?(Hash)
|
|
63
|
+
dest_parent[dest_target] = source_obj
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
value
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def to_h
|
|
70
|
+
{ "op" => name, "from" => @from.to_s, "path" => @pointer.to_s }
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module JSONP3
|
|
4
|
+
class Patch
|
|
5
|
+
# The JSON Patch _remove_ operation.
|
|
6
|
+
class OpRemove < Op
|
|
7
|
+
# @param pointer [JSONPointer]
|
|
8
|
+
def initialize(pointer)
|
|
9
|
+
super()
|
|
10
|
+
@pointer = pointer
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def name
|
|
14
|
+
"remove"
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def apply!(value, index)
|
|
18
|
+
parent, obj = @pointer.resolve_with_parent(value)
|
|
19
|
+
|
|
20
|
+
if parent == JSONP3::Pointer::UNDEFINED && @pointer.tokens.empty?
|
|
21
|
+
raise JSONP3::Patch::Error,
|
|
22
|
+
"can't remove root (#{name}:#{index})"
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
if parent == JSONP3::Pointer::UNDEFINED
|
|
26
|
+
raise JSONP3::Patch::Error,
|
|
27
|
+
"no such property or item '#{@pointer.parent}' (#{name}:#{index})"
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
target = @pointer.tokens.last
|
|
31
|
+
if target == JSONP3::Pointer::UNDEFINED
|
|
32
|
+
raise JSONP3::Patch::Error,
|
|
33
|
+
"unexpected operation (#{name}:#{index})"
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
if parent.is_a?(Array)
|
|
37
|
+
raise JSONP3::Patch::Error, "no item to remove (#{name}:#{index})" if obj == JSONP3::Pointer::UNDEFINED
|
|
38
|
+
|
|
39
|
+
parent.delete_at(target.to_i)
|
|
40
|
+
elsif parent.is_a?(Hash)
|
|
41
|
+
raise JSONP3::Patch::Error, "no property to remove (#{name}:#{index})" if obj == JSONP3::Pointer::UNDEFINED
|
|
42
|
+
|
|
43
|
+
parent.delete(target)
|
|
44
|
+
else
|
|
45
|
+
raise JSONP3::Patch::Error, "unexpected operation on #{parent.class} (#{name}:#{index})"
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
value
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def to_h
|
|
52
|
+
{ "op" => name, "path" => @pointer.to_s }
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module JSONP3
|
|
4
|
+
class Patch
|
|
5
|
+
# The JSON Patch _replace_ operation.
|
|
6
|
+
class OpReplace < Op
|
|
7
|
+
# @param pointer [JSONPointer]
|
|
8
|
+
# @param value [JSON-like value]
|
|
9
|
+
def initialize(pointer, value)
|
|
10
|
+
super()
|
|
11
|
+
@pointer = pointer
|
|
12
|
+
@value = value
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def name
|
|
16
|
+
"replace"
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def apply!(value, index)
|
|
20
|
+
parent, obj = @pointer.resolve_with_parent(value)
|
|
21
|
+
return @value if parent == JSONP3::Pointer::UNDEFINED && @pointer.tokens.empty?
|
|
22
|
+
|
|
23
|
+
if parent == JSONP3::Pointer::UNDEFINED
|
|
24
|
+
raise JSONP3::Patch::Error,
|
|
25
|
+
"no such property or item '#{@pointer.parent}' (#{name}:#{index})"
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
target = @pointer.tokens.last
|
|
29
|
+
if target == JSONP3::Pointer::UNDEFINED
|
|
30
|
+
raise JSONP3::Patch::Error,
|
|
31
|
+
"unexpected operation (#{name}:#{index})"
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
if parent.is_a?(Array)
|
|
35
|
+
raise JSONP3::Patch::Error, "no item to replace (#{name}:#{index})" if obj == JSONP3::Pointer::UNDEFINED
|
|
36
|
+
|
|
37
|
+
parent[target.to_i] = @value
|
|
38
|
+
elsif parent.is_a?(Hash)
|
|
39
|
+
raise JSONP3::Patch::Error, "no property to replace (#{name}:#{index})" if obj == JSONP3::Pointer::UNDEFINED
|
|
40
|
+
|
|
41
|
+
parent[target] = @value
|
|
42
|
+
else
|
|
43
|
+
raise JSONP3::Patch::Error, "unexpected operation on #{parent.class} (#{name}:#{index})"
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
value
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def to_h
|
|
50
|
+
{ "op" => name, "path" => @pointer.to_s, "value" => @value }
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module JSONP3
|
|
4
|
+
class Patch
|
|
5
|
+
# The JSON Patch _test_ operation.
|
|
6
|
+
class OpTest < Op
|
|
7
|
+
# @param pointer [JSONPointer]
|
|
8
|
+
# @param value [JSON-like value]
|
|
9
|
+
def initialize(pointer, value)
|
|
10
|
+
super()
|
|
11
|
+
@pointer = pointer
|
|
12
|
+
@value = value
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def name
|
|
16
|
+
"test"
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def apply!(value, index)
|
|
20
|
+
obj = @pointer.resolve(value)
|
|
21
|
+
raise JSONP3::Patch::TestFailure, "test failed (#{name}:#{index})" if obj != @value
|
|
22
|
+
|
|
23
|
+
value
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def to_h
|
|
27
|
+
{ "op" => name, "path" => @pointer.to_s, "value" => @value }
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|