hana 1.3.6 → 1.3.7
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
- data/README.md +1 -1
- data/Rakefile +6 -1
- data/lib/hana.rb +49 -42
- data/test/helper.rb +1 -1
- data/test/test_hana.rb +3 -3
- metadata +6 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8f7c301531d8d60e3267883dc0cd34f1366151fd5b876a2439fb296a971248ee
|
4
|
+
data.tar.gz: 8aaa875ad968a75b54bfc5526137430c69cbbd1090dc47eb3997ec2557c645aa
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 934c2ddf91379c64cd7b748f940df6fb120fdf79b8667522c7a20e305ed92a92a1ecc01148029c3ddd50b759671aa890a2ecac40bfe1c02b8980dbda7e9086f4
|
7
|
+
data.tar.gz: 8d15b436be7dc1c61e6ff6364dfbdc1a5fe09c0962e15efd858bab4143f8725212a6166480be170950eb4908bb38d26075ae64b49e638600c06649cb8ff9f5ca
|
data/README.md
CHANGED
@@ -35,7 +35,7 @@ patch.apply('foo' => 'bar') # => {'baz' => 'qux', 'foo' => 'bar'}
|
|
35
35
|
|
36
36
|
(The MIT License)
|
37
37
|
|
38
|
-
Copyright (c) 2012-
|
38
|
+
Copyright (c) 2012-2020 Aaron Patterson
|
39
39
|
|
40
40
|
Permission is hereby granted, free of charge, to any person obtaining
|
41
41
|
a copy of this software and associated documentation files (the
|
data/Rakefile
CHANGED
data/lib/hana.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Hana
|
4
|
-
VERSION = '1.3.
|
4
|
+
VERSION = '1.3.7'
|
5
5
|
|
6
6
|
class Pointer
|
7
7
|
include Enumerable
|
@@ -73,6 +73,9 @@ module Hana
|
|
73
73
|
class ObjectOperationOnArrayException < Exception
|
74
74
|
end
|
75
75
|
|
76
|
+
class InvalidObjectOperationException < Exception
|
77
|
+
end
|
78
|
+
|
76
79
|
class IndexError < Exception
|
77
80
|
end
|
78
81
|
|
@@ -90,7 +93,7 @@ module Hana
|
|
90
93
|
|
91
94
|
def apply doc
|
92
95
|
@is.inject(doc) { |d, ins|
|
93
|
-
send VALID.fetch(ins[
|
96
|
+
send VALID.fetch(ins['op'].strip) { |k|
|
94
97
|
raise Exception, "bad method `#{k}`"
|
95
98
|
}, ins, d
|
96
99
|
}
|
@@ -98,28 +101,17 @@ module Hana
|
|
98
101
|
|
99
102
|
private
|
100
103
|
|
101
|
-
PATH = 'path' # :nodoc:
|
102
104
|
FROM = 'from' # :nodoc:
|
103
105
|
VALUE = 'value' # :nodoc:
|
104
|
-
OP = 'op' # :nodoc:
|
105
106
|
|
106
107
|
def add ins, doc
|
107
|
-
|
108
|
-
raise Hana::Patch::InvalidPath, "missing 'path' parameter"
|
109
|
-
end
|
110
|
-
|
111
|
-
path = ins['path']
|
112
|
-
|
113
|
-
unless path
|
114
|
-
raise Hana::Patch::InvalidPath, "null is not valid value for 'path'"
|
115
|
-
end
|
116
|
-
|
108
|
+
path = get_path ins
|
117
109
|
list = Pointer.parse path
|
118
110
|
key = list.pop
|
119
111
|
dest = Pointer.eval list, doc
|
120
112
|
obj = ins.fetch VALUE
|
121
113
|
|
122
|
-
raise(MissingTargetException, ins['path']) unless dest
|
114
|
+
raise(MissingTargetException, "target location '#{ins['path']}' does not exist") unless dest
|
123
115
|
|
124
116
|
if key
|
125
117
|
add_op dest, key, obj
|
@@ -134,18 +126,15 @@ module Hana
|
|
134
126
|
end
|
135
127
|
|
136
128
|
def move ins, doc
|
129
|
+
path = get_path ins
|
137
130
|
from = Pointer.parse ins.fetch FROM
|
138
|
-
to = Pointer.parse
|
131
|
+
to = Pointer.parse path
|
139
132
|
from_key = from.pop
|
140
133
|
key = to.pop
|
141
134
|
src = Pointer.eval from, doc
|
142
135
|
dest = Pointer.eval to, doc
|
143
136
|
|
144
|
-
|
145
|
-
unless src.key? from_key
|
146
|
-
raise Hana::Patch::MissingTargetException
|
147
|
-
end
|
148
|
-
end
|
137
|
+
raise(MissingTargetException, "target location '#{ins['path']}' does not exist") unless dest
|
149
138
|
|
150
139
|
obj = rm_op src, from_key
|
151
140
|
add_op dest, key, obj
|
@@ -153,68 +142,81 @@ module Hana
|
|
153
142
|
end
|
154
143
|
|
155
144
|
def copy ins, doc
|
145
|
+
path = get_path ins
|
156
146
|
from = Pointer.parse ins.fetch FROM
|
157
|
-
to = Pointer.parse
|
147
|
+
to = Pointer.parse path
|
158
148
|
from_key = from.pop
|
159
149
|
key = to.pop
|
160
150
|
src = Pointer.eval from, doc
|
161
151
|
dest = Pointer.eval to, doc
|
162
152
|
|
163
153
|
if Array === src
|
164
|
-
raise Patch::
|
154
|
+
raise Patch::ObjectOperationOnArrayException, "cannot apply non-numeric key '#{key}' to array" unless from_key =~ /\A\d+\Z/
|
165
155
|
obj = src.fetch from_key.to_i
|
166
156
|
else
|
167
157
|
begin
|
168
158
|
obj = src.fetch from_key
|
169
|
-
rescue KeyError
|
170
|
-
raise Hana::Patch::MissingTargetException,
|
159
|
+
rescue KeyError, NoMethodError
|
160
|
+
raise Hana::Patch::MissingTargetException, "'from' location '#{ins.fetch FROM}' does not exist"
|
171
161
|
end
|
172
162
|
end
|
173
163
|
|
164
|
+
raise(MissingTargetException, "target location '#{ins['path']}' does not exist") unless dest
|
165
|
+
|
174
166
|
add_op dest, key, obj
|
175
167
|
doc
|
176
168
|
end
|
177
169
|
|
178
170
|
def test ins, doc
|
179
|
-
|
171
|
+
path = get_path ins
|
172
|
+
expected = Pointer.new(path).eval doc
|
180
173
|
|
181
174
|
unless expected == ins.fetch(VALUE)
|
182
|
-
raise FailedTestException.new(ins[
|
175
|
+
raise FailedTestException.new(ins['path'], ins[VALUE])
|
183
176
|
end
|
184
177
|
doc
|
185
178
|
end
|
186
179
|
|
187
180
|
def replace ins, doc
|
188
|
-
|
181
|
+
path = get_path ins
|
182
|
+
list = Pointer.parse path
|
189
183
|
key = list.pop
|
190
184
|
obj = Pointer.eval list, doc
|
191
185
|
|
192
186
|
return ins.fetch VALUE unless key
|
193
187
|
|
194
|
-
|
195
|
-
|
196
|
-
obj[key.to_i] = ins.fetch VALUE
|
197
|
-
else
|
198
|
-
raise Patch::MissingTargetException unless obj
|
199
|
-
obj[key] = ins.fetch VALUE
|
200
|
-
end
|
188
|
+
rm_op obj, key
|
189
|
+
add_op obj, key, ins.fetch(VALUE)
|
201
190
|
doc
|
202
191
|
end
|
203
192
|
|
204
193
|
def remove ins, doc
|
205
|
-
|
194
|
+
path = get_path ins
|
195
|
+
list = Pointer.parse path
|
206
196
|
key = list.pop
|
207
197
|
obj = Pointer.eval list, doc
|
208
198
|
rm_op obj, key
|
209
199
|
doc
|
210
200
|
end
|
211
201
|
|
202
|
+
def get_path ins
|
203
|
+
unless ins.key?('path')
|
204
|
+
raise Hana::Patch::InvalidPath, "missing 'path' parameter"
|
205
|
+
end
|
206
|
+
|
207
|
+
unless ins['path']
|
208
|
+
raise Hana::Patch::InvalidPath, "null is not valid value for 'path'"
|
209
|
+
end
|
210
|
+
|
211
|
+
ins['path']
|
212
|
+
end
|
213
|
+
|
212
214
|
def check_index obj, key
|
213
215
|
return -1 if key == '-'
|
214
216
|
|
215
|
-
raise ObjectOperationOnArrayException unless key =~ /\A-?\d+\Z/
|
217
|
+
raise ObjectOperationOnArrayException, "cannot apply non-numeric key '#{key}' to array" unless key =~ /\A-?\d+\Z/
|
216
218
|
idx = key.to_i
|
217
|
-
raise OutOfBoundsException if idx > obj.length || idx < 0
|
219
|
+
raise OutOfBoundsException, "key '#{key}' is out of bounds for array" if idx > obj.length || idx < 0
|
218
220
|
idx
|
219
221
|
end
|
220
222
|
|
@@ -222,19 +224,24 @@ module Hana
|
|
222
224
|
if Array === dest
|
223
225
|
dest.insert check_index(dest, key), obj
|
224
226
|
else
|
227
|
+
raise Patch::InvalidObjectOperationException, "cannot add key '#{key}' to non-object" unless Hash === dest
|
225
228
|
dest[key] = obj
|
226
229
|
end
|
227
230
|
end
|
228
231
|
|
229
232
|
def rm_op obj, key
|
230
233
|
if Array === obj
|
231
|
-
raise Patch::
|
234
|
+
raise Patch::ObjectOperationOnArrayException, "cannot apply non-numeric key '#{key}' to array" unless key =~ /\A\d+\Z/
|
232
235
|
key = key.to_i
|
233
|
-
raise Patch::OutOfBoundsException if key >= obj.length
|
236
|
+
raise Patch::OutOfBoundsException, "key '#{key}' is out of bounds for array" if key >= obj.length
|
234
237
|
obj.delete_at key
|
235
238
|
else
|
236
|
-
|
237
|
-
|
239
|
+
begin
|
240
|
+
raise Patch::MissingTargetException, "key '#{key}' not found" unless obj&.key? key
|
241
|
+
obj.delete key
|
242
|
+
rescue ::NoMethodError
|
243
|
+
raise Patch::InvalidObjectOperationException, "cannot remove key '#{key}' from non-object"
|
244
|
+
end
|
238
245
|
end
|
239
246
|
end
|
240
247
|
end
|
data/test/helper.rb
CHANGED
@@ -60,7 +60,7 @@ module Hana
|
|
60
60
|
when /bad number$/ then
|
61
61
|
[Hana::Patch::IndexError, Hana::Patch::ObjectOperationOnArrayException]
|
62
62
|
when /removing a nonexistent (field|index)/ then
|
63
|
-
[Hana::Patch::
|
63
|
+
[Hana::Patch::MissingTargetException, Hana::Patch::OutOfBoundsException]
|
64
64
|
when /test op should reject the array value, it has leading zeros/ then
|
65
65
|
[Hana::Patch::IndexError]
|
66
66
|
when /missing '(from|value)' parameter/ then
|
data/test/test_hana.rb
CHANGED
@@ -74,7 +74,7 @@ class TestHana < Hana::TestCase
|
|
74
74
|
patch = Hana::Patch.new [
|
75
75
|
{ 'op' => 'remove', 'path' => '/missing_key' }
|
76
76
|
]
|
77
|
-
assert_raises(Hana::Patch::
|
77
|
+
assert_raises(Hana::Patch::MissingTargetException) do
|
78
78
|
patch.apply('foo' => 'bar')
|
79
79
|
end
|
80
80
|
end
|
@@ -83,7 +83,7 @@ class TestHana < Hana::TestCase
|
|
83
83
|
patch = Hana::Patch.new [
|
84
84
|
{ 'op' => 'remove', 'path' => '/missing_key1/missing_key2' }
|
85
85
|
]
|
86
|
-
assert_raises(Hana::Patch::
|
86
|
+
assert_raises(Hana::Patch::MissingTargetException) do
|
87
87
|
patch.apply('foo' => 'bar')
|
88
88
|
end
|
89
89
|
end
|
@@ -101,7 +101,7 @@ class TestHana < Hana::TestCase
|
|
101
101
|
patch = Hana::Patch.new [
|
102
102
|
{ 'op' => 'remove', 'path' => '/1/baz' }
|
103
103
|
]
|
104
|
-
assert_raises(Hana::Patch::
|
104
|
+
assert_raises(Hana::Patch::MissingTargetException) do
|
105
105
|
patch.apply([
|
106
106
|
{ 'foo' => 'bar' },
|
107
107
|
{ 'foo' => 'bar' }
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hana
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.3.
|
4
|
+
version: 1.3.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Aaron Patterson
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-12-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: minitest
|
@@ -86,7 +86,7 @@ licenses:
|
|
86
86
|
- MIT
|
87
87
|
metadata:
|
88
88
|
homepage_uri: http://github.com/tenderlove/hana
|
89
|
-
post_install_message:
|
89
|
+
post_install_message:
|
90
90
|
rdoc_options:
|
91
91
|
- "--main"
|
92
92
|
- README.md
|
@@ -103,8 +103,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
103
103
|
- !ruby/object:Gem::Version
|
104
104
|
version: '0'
|
105
105
|
requirements: []
|
106
|
-
rubygems_version: 3.2.0.
|
107
|
-
signing_key:
|
106
|
+
rubygems_version: 3.2.0.rc.2
|
107
|
+
signing_key:
|
108
108
|
specification_version: 4
|
109
109
|
summary: Implementation of [JSON Patch][1] and [JSON Pointer][2] RFC.
|
110
110
|
test_files: []
|