hana 1.3.2 → 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 4fb4c95fd3541788a19d1c4b9d7bd1931242191a
4
- data.tar.gz: 83e628bf62efb6e476121837a710c0d64bfc7590
2
+ SHA256:
3
+ metadata.gz: 8f7c301531d8d60e3267883dc0cd34f1366151fd5b876a2439fb296a971248ee
4
+ data.tar.gz: 8aaa875ad968a75b54bfc5526137430c69cbbd1090dc47eb3997ec2557c645aa
5
5
  SHA512:
6
- metadata.gz: 5b60dc61f8c64a99d6595b7b8e8192b2d1f658a47eab4a74bfca692edc4883dc25979b41bc4a68b3f1a5b02f69f832fdfa9ca744aea279ef7480d836b3ba0463
7
- data.tar.gz: 52c58c0d9d5690a9f37c8e24621ae21dba3fd651566730c723c4603ab41c6b843da2f3b13eca22cf31a7bd0eb12e476b1f0c3f5d50a45d4eac57474b0e896480
6
+ metadata.gz: 934c2ddf91379c64cd7b748f940df6fb120fdf79b8667522c7a20e305ed92a92a1ecc01148029c3ddd50b759671aa890a2ecac40bfe1c02b8980dbda7e9086f4
7
+ data.tar.gz: 8d15b436be7dc1c61e6ff6364dfbdc1a5fe09c0962e15efd858bab4143f8725212a6166480be170950eb4908bb38d26075ae64b49e638600c06649cb8ff9f5ca
@@ -1,11 +1,12 @@
1
- .autotest
2
- CHANGELOG.rdoc
3
1
  Manifest.txt
4
2
  README.md
5
3
  Rakefile
6
4
  lib/hana.rb
7
5
  test/helper.rb
6
+ test/json-patch-tests/.editorconfig
7
+ test/json-patch-tests/.npmignore
8
8
  test/json-patch-tests/README.md
9
+ test/json-patch-tests/package.json
9
10
  test/json-patch-tests/spec_tests.json
10
11
  test/json-patch-tests/tests.json
11
12
  test/mine.json
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-2016 Aaron Patterson
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
@@ -1,7 +1,12 @@
1
1
  # -*- ruby -*-
2
2
 
3
3
  require 'rubygems'
4
- require 'hoe'
4
+ begin
5
+ require 'hoe'
6
+ rescue LoadError
7
+ Gem.install 'hoe'
8
+ retry
9
+ end
5
10
 
6
11
  Hoe.plugins.delete :rubyforge
7
12
  Hoe.plugin :minitest
@@ -12,7 +17,6 @@ Hoe.spec 'hana' do
12
17
  developer('Aaron Patterson', 'aaron@tenderlovemaking.com')
13
18
  license 'MIT'
14
19
  self.readme_file = 'README.md'
15
- self.history_file = 'CHANGELOG.rdoc'
16
20
  self.extra_rdoc_files = FileList['*.rdoc']
17
21
  extra_dev_deps << ["minitest", "~> 5.0"]
18
22
  end
@@ -1,9 +1,17 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Hana
2
- VERSION = '1.3.2'
4
+ VERSION = '1.3.7'
3
5
 
4
6
  class Pointer
5
7
  include Enumerable
6
8
 
9
+ class Exception < StandardError
10
+ end
11
+
12
+ class FormatError < Exception
13
+ end
14
+
7
15
  def initialize path
8
16
  @path = Pointer.parse path
9
17
  end
@@ -21,7 +29,7 @@ module Hana
21
29
  return nil unless o
22
30
 
23
31
  if Array === o
24
- raise Patch::IndexError unless part =~ /\A\d+\Z/
32
+ raise Patch::IndexError unless part =~ /\A(?:\d|[1-9]\d+)\Z/
25
33
  part = part.to_i
26
34
  end
27
35
  o[part]
@@ -30,6 +38,11 @@ module Hana
30
38
 
31
39
  def self.parse path
32
40
  return [''] if path == '/'
41
+ return [] if path == ''
42
+
43
+ unless path.start_with? '/'
44
+ raise FormatError, "JSON Pointer should start with a slash"
45
+ end
33
46
 
34
47
  parts = path.sub(/^\//, '').split(/(?<!\^)\//).each { |part|
35
48
  part.gsub!(/\^[\/^]|~[01]/) { |m| ESC[m] }
@@ -60,12 +73,18 @@ module Hana
60
73
  class ObjectOperationOnArrayException < Exception
61
74
  end
62
75
 
76
+ class InvalidObjectOperationException < Exception
77
+ end
78
+
63
79
  class IndexError < Exception
64
80
  end
65
81
 
66
82
  class MissingTargetException < Exception
67
83
  end
68
84
 
85
+ class InvalidPath < Exception
86
+ end
87
+
69
88
  def initialize is
70
89
  @is = is
71
90
  end
@@ -74,7 +93,7 @@ module Hana
74
93
 
75
94
  def apply doc
76
95
  @is.inject(doc) { |d, ins|
77
- send VALID.fetch(ins[OP].strip) { |k|
96
+ send VALID.fetch(ins['op'].strip) { |k|
78
97
  raise Exception, "bad method `#{k}`"
79
98
  }, ins, d
80
99
  }
@@ -82,98 +101,122 @@ module Hana
82
101
 
83
102
  private
84
103
 
85
- PATH = 'path' # :nodoc:
86
104
  FROM = 'from' # :nodoc:
87
105
  VALUE = 'value' # :nodoc:
88
- OP = 'op' # :nodoc:
89
106
 
90
107
  def add ins, doc
91
- list = Pointer.parse ins[PATH]
108
+ path = get_path ins
109
+ list = Pointer.parse path
92
110
  key = list.pop
93
111
  dest = Pointer.eval list, doc
94
112
  obj = ins.fetch VALUE
95
113
 
96
- raise(MissingTargetException, ins[PATH]) unless dest
114
+ raise(MissingTargetException, "target location '#{ins['path']}' does not exist") unless dest
97
115
 
98
116
  if key
99
117
  add_op dest, key, obj
100
118
  else
101
- dest.replace obj
119
+ if doc.equal? dest
120
+ doc = obj
121
+ else
122
+ dest.replace obj
123
+ end
102
124
  end
103
125
  doc
104
126
  end
105
127
 
106
128
  def move ins, doc
129
+ path = get_path ins
107
130
  from = Pointer.parse ins.fetch FROM
108
- to = Pointer.parse ins[PATH]
131
+ to = Pointer.parse path
109
132
  from_key = from.pop
110
133
  key = to.pop
111
134
  src = Pointer.eval from, doc
112
135
  dest = Pointer.eval to, doc
113
136
 
137
+ raise(MissingTargetException, "target location '#{ins['path']}' does not exist") unless dest
138
+
114
139
  obj = rm_op src, from_key
115
140
  add_op dest, key, obj
116
141
  doc
117
142
  end
118
143
 
119
144
  def copy ins, doc
145
+ path = get_path ins
120
146
  from = Pointer.parse ins.fetch FROM
121
- to = Pointer.parse ins[PATH]
147
+ to = Pointer.parse path
122
148
  from_key = from.pop
123
149
  key = to.pop
124
150
  src = Pointer.eval from, doc
125
151
  dest = Pointer.eval to, doc
126
152
 
127
153
  if Array === src
128
- raise Patch::IndexError unless from_key =~ /\A\d+\Z/
154
+ raise Patch::ObjectOperationOnArrayException, "cannot apply non-numeric key '#{key}' to array" unless from_key =~ /\A\d+\Z/
129
155
  obj = src.fetch from_key.to_i
130
156
  else
131
- obj = src.fetch from_key
157
+ begin
158
+ obj = src.fetch from_key
159
+ rescue KeyError, NoMethodError
160
+ raise Hana::Patch::MissingTargetException, "'from' location '#{ins.fetch FROM}' does not exist"
161
+ end
132
162
  end
133
163
 
164
+ raise(MissingTargetException, "target location '#{ins['path']}' does not exist") unless dest
165
+
134
166
  add_op dest, key, obj
135
167
  doc
136
168
  end
137
169
 
138
170
  def test ins, doc
139
- expected = Pointer.new(ins[PATH]).eval doc
171
+ path = get_path ins
172
+ expected = Pointer.new(path).eval doc
140
173
 
141
174
  unless expected == ins.fetch(VALUE)
142
- raise FailedTestException.new(ins[VALUE], ins[PATH])
175
+ raise FailedTestException.new(ins['path'], ins[VALUE])
143
176
  end
144
177
  doc
145
178
  end
146
179
 
147
180
  def replace ins, doc
148
- list = Pointer.parse ins[PATH]
181
+ path = get_path ins
182
+ list = Pointer.parse path
149
183
  key = list.pop
150
184
  obj = Pointer.eval list, doc
151
185
 
152
186
  return ins.fetch VALUE unless key
153
187
 
154
- if Array === obj
155
- raise Patch::IndexError unless key =~ /\A\d+\Z/
156
- obj[key.to_i] = ins.fetch VALUE
157
- else
158
- obj[key] = ins.fetch VALUE
159
- end
188
+ rm_op obj, key
189
+ add_op obj, key, ins.fetch(VALUE)
160
190
  doc
161
191
  end
162
192
 
163
193
  def remove ins, doc
164
- list = Pointer.parse ins[PATH]
194
+ path = get_path ins
195
+ list = Pointer.parse path
165
196
  key = list.pop
166
197
  obj = Pointer.eval list, doc
167
198
  rm_op obj, key
168
199
  doc
169
200
  end
170
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
+
171
214
  def check_index obj, key
172
215
  return -1 if key == '-'
173
216
 
174
- raise ObjectOperationOnArrayException unless key =~ /\A-?\d+\Z/
217
+ raise ObjectOperationOnArrayException, "cannot apply non-numeric key '#{key}' to array" unless key =~ /\A-?\d+\Z/
175
218
  idx = key.to_i
176
- 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
177
220
  idx
178
221
  end
179
222
 
@@ -181,16 +224,24 @@ module Hana
181
224
  if Array === dest
182
225
  dest.insert check_index(dest, key), obj
183
226
  else
227
+ raise Patch::InvalidObjectOperationException, "cannot add key '#{key}' to non-object" unless Hash === dest
184
228
  dest[key] = obj
185
229
  end
186
230
  end
187
231
 
188
232
  def rm_op obj, key
189
233
  if Array === obj
190
- raise Patch::IndexError unless key =~ /\A\d+\Z/
191
- obj.delete_at key.to_i
234
+ raise Patch::ObjectOperationOnArrayException, "cannot apply non-numeric key '#{key}' to array" unless key =~ /\A\d+\Z/
235
+ key = key.to_i
236
+ raise Patch::OutOfBoundsException, "key '#{key}' is out of bounds for array" if key >= obj.length
237
+ obj.delete_at key
192
238
  else
193
- obj.delete key
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
194
245
  end
195
246
  end
196
247
  end
@@ -12,7 +12,16 @@ module Hana
12
12
  tests.each_with_index do |test, i|
13
13
  next unless test['doc']
14
14
 
15
- define_method("test_#{test['comment'] || i }") do
15
+ method = "test_#{test['comment'] || i }"
16
+ loop do
17
+ if method_defined? method
18
+ method = "test_#{test['comment'] || i } x"
19
+ else
20
+ break
21
+ end
22
+ end
23
+
24
+ define_method(method) do
16
25
  skip "disabled" if test['disabled']
17
26
 
18
27
  doc = test['doc']
@@ -50,12 +59,20 @@ module Hana
50
59
  [Hana::Patch::IndexError, Hana::Patch::ObjectOperationOnArrayException]
51
60
  when /bad number$/ then
52
61
  [Hana::Patch::IndexError, Hana::Patch::ObjectOperationOnArrayException]
62
+ when /removing a nonexistent (field|index)/ then
63
+ [Hana::Patch::MissingTargetException, Hana::Patch::OutOfBoundsException]
64
+ when /test op should reject the array value, it has leading zeros/ then
65
+ [Hana::Patch::IndexError]
53
66
  when /missing '(from|value)' parameter/ then
54
67
  [KeyError]
55
68
  when /Unrecognized op 'spam'/ then
56
69
  [Hana::Patch::Exception]
70
+ when /missing 'path'|null is not valid value for 'path'/ then
71
+ [Hana::Patch::InvalidPath]
57
72
  when /missing|non-existent/ then
58
73
  [Hana::Patch::MissingTargetException]
74
+ when /JSON Pointer should start with a slash/ then
75
+ [Hana::Pointer::FormatError]
59
76
  else
60
77
  [Hana::Patch::FailedTestException]
61
78
  end
@@ -0,0 +1,10 @@
1
+ # EditorConfig is awesome: http://EditorConfig.org
2
+
3
+ root = true
4
+
5
+ [*]
6
+ end_of_line = lf
7
+ insert_final_newline = true
8
+ charset = utf-8
9
+ trim_trailing_whitespace = true
10
+ indent_style = space
@@ -0,0 +1,2 @@
1
+ .editorconfig
2
+ .gitignore
@@ -0,0 +1,15 @@
1
+ {
2
+ "name": "json-patch-test-suite",
3
+ "version": "1.1.0",
4
+ "description": "JSON Patch RFC 6902 test suite",
5
+ "repository": "github:json-patch/json-patch-tests",
6
+ "homepage": "https://github.com/json-patch/json-patch-tests",
7
+ "bugs": "https://github.com/json-patch/json-patch-tests/issues",
8
+ "keywords": [
9
+ "JSON",
10
+ "Patch",
11
+ "test",
12
+ "suite"
13
+ ],
14
+ "license": "Apache-2.0"
15
+ }
@@ -55,6 +55,21 @@
55
55
  "expected": "bar",
56
56
  "disabled": true },
57
57
 
58
+ { "comment": "replace object document with array document?",
59
+ "doc": {},
60
+ "patch": [{"op": "add", "path": "", "value": []}],
61
+ "expected": [] },
62
+
63
+ { "comment": "replace array document with object document?",
64
+ "doc": [],
65
+ "patch": [{"op": "add", "path": "", "value": {}}],
66
+ "expected": {} },
67
+
68
+ { "comment": "append to root array document?",
69
+ "doc": [],
70
+ "patch": [{"op": "add", "path": "/-", "value": "hi"}],
71
+ "expected": ["hi"] },
72
+
58
73
  { "comment": "Add, / target",
59
74
  "doc": {},
60
75
  "patch": [ {"op": "add", "path": "/", "value":1 } ],
@@ -187,6 +202,11 @@
187
202
  "patch": [{"op": "replace", "path": "", "value": {"baz": "qux"}}],
188
203
  "expected": {"baz": "qux"} },
189
204
 
205
+ { "comment": "test replace with missing parent key should fail",
206
+ "doc": {"bar": "baz"},
207
+ "patch": [{"op": "replace", "path": "/foo/bar", "value": false}],
208
+ "error": "replace op should fail with missing parent key" },
209
+
190
210
  { "comment": "spurious patch properties",
191
211
  "doc": {"foo": 1},
192
212
  "patch": [{"op": "test", "path": "/foo", "value": 1, "spurious": 1}],
@@ -194,6 +214,7 @@
194
214
 
195
215
  { "doc": {"foo": null},
196
216
  "patch": [{"op": "test", "path": "/foo", "value": null}],
217
+ "expected": {"foo": null},
197
218
  "comment": "null value should be valid obj property" },
198
219
 
199
220
  { "doc": {"foo": null},
@@ -223,14 +244,17 @@
223
244
 
224
245
  { "doc": {"foo": {"foo": 1, "bar": 2}},
225
246
  "patch": [{"op": "test", "path": "/foo", "value": {"bar": 2, "foo": 1}}],
247
+ "expected": {"foo": {"foo": 1, "bar": 2}},
226
248
  "comment": "test should pass despite rearrangement" },
227
249
 
228
250
  { "doc": {"foo": [{"foo": 1, "bar": 2}]},
229
251
  "patch": [{"op": "test", "path": "/foo", "value": [{"bar": 2, "foo": 1}]}],
252
+ "expected": {"foo": [{"foo": 1, "bar": 2}]},
230
253
  "comment": "test should pass despite (nested) rearrangement" },
231
254
 
232
255
  { "doc": {"foo": {"bar": [1, 2, 5, 4]}},
233
256
  "patch": [{"op": "test", "path": "/foo", "value": {"bar": [1, 2, 5, 4]}}],
257
+ "expected": {"foo": {"bar": [1, 2, 5, 4]}},
234
258
  "comment": "test should pass - no error" },
235
259
 
236
260
  { "doc": {"foo": {"bar": [1, 2, 5, 4]}},
@@ -244,7 +268,8 @@
244
268
 
245
269
  { "comment": "Empty-string element",
246
270
  "doc": { "": 1 },
247
- "patch": [{"op": "test", "path": "/", "value": 1}] },
271
+ "patch": [{"op": "test", "path": "/", "value": 1}],
272
+ "expected": { "": 1 } },
248
273
 
249
274
  { "doc": {
250
275
  "foo": ["bar", "baz"],
@@ -268,8 +293,23 @@
268
293
  {"op": "test", "path": "/i\\j", "value": 5},
269
294
  {"op": "test", "path": "/k\"l", "value": 6},
270
295
  {"op": "test", "path": "/ ", "value": 7},
271
- {"op": "test", "path": "/m~0n", "value": 8}] },
272
-
296
+ {"op": "test", "path": "/m~0n", "value": 8}],
297
+ "expected": {
298
+ "": 0,
299
+ " ": 7,
300
+ "a/b": 1,
301
+ "c%d": 2,
302
+ "e^f": 3,
303
+ "foo": [
304
+ "bar",
305
+ "baz"
306
+ ],
307
+ "g|h": 4,
308
+ "i\\j": 5,
309
+ "k\"l": 6,
310
+ "m~n": 8
311
+ }
312
+ },
273
313
  { "comment": "Move to same location has no effect",
274
314
  "doc": {"foo": 1},
275
315
  "patch": [{"op": "move", "from": "/foo", "path": "/foo"}],
@@ -343,6 +383,21 @@
343
383
  "patch": [{"op": "add", "path": "/1e0", "value": "bar"}],
344
384
  "error": "add op shouldn't add to array with bad number" },
345
385
 
386
+ { "comment": "missing 'path' parameter",
387
+ "doc": {},
388
+ "patch": [ { "op": "add", "value": "bar" } ],
389
+ "error": "missing 'path' parameter" },
390
+
391
+ { "comment": "'path' parameter with null value",
392
+ "doc": {},
393
+ "patch": [ { "op": "add", "path": null, "value": "bar" } ],
394
+ "error": "null is not valid value for 'path'" },
395
+
396
+ { "comment": "invalid JSON Pointer token",
397
+ "doc": {},
398
+ "patch": [ { "op": "add", "path": "foo", "value": "bar" } ],
399
+ "error": "JSON Pointer should start with a slash" },
400
+
346
401
  { "comment": "missing 'value' parameter to add",
347
402
  "doc": [ 1 ],
348
403
  "patch": [ { "op": "add", "path": "/-" } ],
@@ -368,11 +423,21 @@
368
423
  "patch": [ { "op": "copy", "path": "/-" } ],
369
424
  "error": "missing 'from' parameter" },
370
425
 
426
+ { "comment": "missing from location to copy",
427
+ "doc": { "foo": 1 },
428
+ "patch": [ { "op": "copy", "from": "/bar", "path": "/foo" } ],
429
+ "error": "missing 'from' location" },
430
+
371
431
  { "comment": "missing from parameter to move",
372
432
  "doc": { "foo": 1 },
373
433
  "patch": [ { "op": "move", "path": "" } ],
374
434
  "error": "missing 'from' parameter" },
375
435
 
436
+ { "comment": "missing from location to move",
437
+ "doc": { "foo": 1 },
438
+ "patch": [ { "op": "move", "from": "/bar", "path": "/foo" } ],
439
+ "error": "missing 'from' location" },
440
+
376
441
  { "comment": "duplicate ops",
377
442
  "doc": { "foo": "bar" },
378
443
  "patch": [ { "op": "add", "path": "/baz", "value": "qux",
@@ -383,5 +448,37 @@
383
448
  { "comment": "unrecognized op should fail",
384
449
  "doc": {"foo": 1},
385
450
  "patch": [{"op": "spam", "path": "/foo", "value": 1}],
386
- "error": "Unrecognized op 'spam'" }
451
+ "error": "Unrecognized op 'spam'" },
452
+
453
+ { "comment": "test with bad array number that has leading zeros",
454
+ "doc": ["foo", "bar"],
455
+ "patch": [{"op": "test", "path": "/00", "value": "foo"}],
456
+ "error": "test op should reject the array value, it has leading zeros" },
457
+
458
+ { "comment": "test with bad array number that has leading zeros",
459
+ "doc": ["foo", "bar"],
460
+ "patch": [{"op": "test", "path": "/01", "value": "bar"}],
461
+ "error": "test op should reject the array value, it has leading zeros" },
462
+
463
+ { "comment": "Removing nonexistent field",
464
+ "doc": {"foo" : "bar"},
465
+ "patch": [{"op": "remove", "path": "/baz"}],
466
+ "error": "removing a nonexistent field should fail" },
467
+
468
+ { "comment": "Removing deep nonexistent path",
469
+ "doc": {"foo" : "bar"},
470
+ "patch": [{"op": "remove", "path": "/missing1/missing2"}],
471
+ "error": "removing a nonexistent field should fail" },
472
+
473
+ { "comment": "Removing nonexistent index",
474
+ "doc": ["foo", "bar"],
475
+ "patch": [{"op": "remove", "path": "/2"}],
476
+ "error": "removing a nonexistent index should fail" },
477
+
478
+ { "comment": "Patch with different capitalisation than doc",
479
+ "doc": {"foo":"bar"},
480
+ "patch": [{"op": "add", "path": "/FOO", "value": "BAR"}],
481
+ "expected": {"foo": "bar", "FOO": "BAR"}
482
+ }
483
+
387
484
  ]
@@ -69,4 +69,52 @@ class TestHana < Hana::TestCase
69
69
  pointer = Hana::Pointer.new '/foo/bar/baz'
70
70
  assert_nil pointer.eval('foo' => nil)
71
71
  end
72
+
73
+ def test_remove_missing_object_key
74
+ patch = Hana::Patch.new [
75
+ { 'op' => 'remove', 'path' => '/missing_key' }
76
+ ]
77
+ assert_raises(Hana::Patch::MissingTargetException) do
78
+ patch.apply('foo' => 'bar')
79
+ end
80
+ end
81
+
82
+ def test_remove_deep_missing_path
83
+ patch = Hana::Patch.new [
84
+ { 'op' => 'remove', 'path' => '/missing_key1/missing_key2' }
85
+ ]
86
+ assert_raises(Hana::Patch::MissingTargetException) do
87
+ patch.apply('foo' => 'bar')
88
+ end
89
+ end
90
+
91
+ def test_remove_missing_array_index
92
+ patch = Hana::Patch.new [
93
+ { 'op' => 'remove', 'path' => '/1' }
94
+ ]
95
+ assert_raises(Hana::Patch::OutOfBoundsException) do
96
+ patch.apply([0])
97
+ end
98
+ end
99
+
100
+ def test_remove_missing_object_key_in_array
101
+ patch = Hana::Patch.new [
102
+ { 'op' => 'remove', 'path' => '/1/baz' }
103
+ ]
104
+ assert_raises(Hana::Patch::MissingTargetException) do
105
+ patch.apply([
106
+ { 'foo' => 'bar' },
107
+ { 'foo' => 'bar' }
108
+ ])
109
+ end
110
+ end
111
+
112
+ def test_replace_missing_key
113
+ patch = Hana::Patch.new [
114
+ { 'op' => 'replace', 'path' => '/missing_key/field', 'value' => 'asdf' }
115
+ ]
116
+ assert_raises(Hana::Patch::MissingTargetException) do
117
+ patch.apply('foo' => 'bar')
118
+ end
119
+ end
72
120
  end
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.2
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: 2016-05-29 00:00:00.000000000 Z
11
+ date: 2020-12-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: minitest
@@ -16,60 +16,66 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '5.9'
19
+ version: '5.14'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '5.9'
26
+ version: '5.14'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rdoc
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - "~>"
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
33
  version: '4.0'
34
+ - - "<"
35
+ - !ruby/object:Gem::Version
36
+ version: '7'
34
37
  type: :development
35
38
  prerelease: false
36
39
  version_requirements: !ruby/object:Gem::Requirement
37
40
  requirements:
38
- - - "~>"
41
+ - - ">="
39
42
  - !ruby/object:Gem::Version
40
43
  version: '4.0'
44
+ - - "<"
45
+ - !ruby/object:Gem::Version
46
+ version: '7'
41
47
  - !ruby/object:Gem::Dependency
42
48
  name: hoe
43
49
  requirement: !ruby/object:Gem::Requirement
44
50
  requirements:
45
51
  - - "~>"
46
52
  - !ruby/object:Gem::Version
47
- version: '3.15'
53
+ version: '3.22'
48
54
  type: :development
49
55
  prerelease: false
50
56
  version_requirements: !ruby/object:Gem::Requirement
51
57
  requirements:
52
58
  - - "~>"
53
59
  - !ruby/object:Gem::Version
54
- version: '3.15'
60
+ version: '3.22'
55
61
  description: Implementation of [JSON Patch][1] and [JSON Pointer][2] RFC.
56
62
  email:
57
63
  - aaron@tenderlovemaking.com
58
64
  executables: []
59
65
  extensions: []
60
66
  extra_rdoc_files:
61
- - CHANGELOG.rdoc
62
67
  - Manifest.txt
63
68
  - README.md
64
69
  files:
65
- - ".autotest"
66
- - CHANGELOG.rdoc
67
70
  - Manifest.txt
68
71
  - README.md
69
72
  - Rakefile
70
73
  - lib/hana.rb
71
74
  - test/helper.rb
75
+ - test/json-patch-tests/.editorconfig
76
+ - test/json-patch-tests/.npmignore
72
77
  - test/json-patch-tests/README.md
78
+ - test/json-patch-tests/package.json
73
79
  - test/json-patch-tests/spec_tests.json
74
80
  - test/json-patch-tests/tests.json
75
81
  - test/mine.json
@@ -78,8 +84,9 @@ files:
78
84
  homepage: http://github.com/tenderlove/hana
79
85
  licenses:
80
86
  - MIT
81
- metadata: {}
82
- post_install_message:
87
+ metadata:
88
+ homepage_uri: http://github.com/tenderlove/hana
89
+ post_install_message:
83
90
  rdoc_options:
84
91
  - "--main"
85
92
  - README.md
@@ -96,9 +103,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
96
103
  - !ruby/object:Gem::Version
97
104
  version: '0'
98
105
  requirements: []
99
- rubyforge_project:
100
- rubygems_version: 2.6.4
101
- signing_key:
106
+ rubygems_version: 3.2.0.rc.2
107
+ signing_key:
102
108
  specification_version: 4
103
109
  summary: Implementation of [JSON Patch][1] and [JSON Pointer][2] RFC.
104
110
  test_files: []
data/.autotest DELETED
@@ -1,8 +0,0 @@
1
- # -*- ruby -*-
2
-
3
- require 'autotest/restart'
4
-
5
- Autotest.add_hook :initialize do |at|
6
- at.testlib = 'minitest/autorun'
7
- at.find_directories = ARGV unless ARGV.empty?
8
- end
@@ -1,12 +0,0 @@
1
- Wed May 22 19:28:10 2013 Aaron Patterson <aaron@tenderlovemaking.com>
2
-
3
- * All IETF compliant
4
-
5
- Fri Sep 7 18:54:17 2012 Aaron Patterson <aaron@tenderlovemaking.com>
6
-
7
- * Bumping the version.
8
-
9
- Fri Sep 7 18:53:16 2012 Aaron Patterson <aaron@tenderlovemaking.com>
10
-
11
- * validate commands an raise an exception Just In Case
12
-