json-merge_patch 0.1.0 → 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
- data/Gemfile +2 -0
- data/README.md +14 -3
- data/json-merge_patch.gemspec +2 -2
- data/lib/json/merge_patch.rb +96 -19
- data/lib/json/merge_patch/version.rb +6 -3
- data/test/merge_patch_test.rb +2 -14
- data/test/test_helper.rb +10 -0
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9638a01b320666a7b5270d234ddb50acc746c952
|
4
|
+
data.tar.gz: f3a2bd4ecb11392969eb47306df2ce8407d46ce2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 46b929805693acbb5f82575086898a2fe1320b456e8b2f373780bb09bfac2fec6d296fae57a4a30bfaeb6ad15d70cddd3d00823b0de01af120c10705035c8184
|
7
|
+
data.tar.gz: 1670820bea9e3df973c6c2a2572ad2e3df01f6bb376eaeff092b655a233be9e0aa2ddbab8f60e36ddb10c47e7a7637209522b046bd90aa9ac75a9fe6ffee9994
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Json::MergePatch
|
2
2
|
|
3
|
-
[](https://travis-ci.org/steveklabnik/json-merge_patch)
|
3
|
+
[](https://travis-ci.org/steveklabnik/json-merge_patch) [](https://codeclimate.com/github/steveklabnik/json-merge_patch) [](https://coveralls.io/r/steveklabnik/json-merge_patch)
|
4
4
|
|
5
5
|
This gem augments Ruby's built-in JSON library to support merging JSON blobs
|
6
6
|
in accordance with the [draft-snell-merge-patch
|
@@ -59,9 +59,9 @@ JSON
|
|
59
59
|
JSON.merge(document, merge_patch)
|
60
60
|
# =>
|
61
61
|
{
|
62
|
-
"title": "
|
62
|
+
"title": "Hello!",
|
63
|
+
"phoneNumber": "+01-123-456-7890",
|
63
64
|
"author" : {
|
64
|
-
"phoneNumber": "+01-123-456-7890",
|
65
65
|
"givenName" : "John",
|
66
66
|
},
|
67
67
|
"tags":["example"],
|
@@ -69,6 +69,17 @@ JSON.merge(document, merge_patch)
|
|
69
69
|
}
|
70
70
|
```
|
71
71
|
|
72
|
+
If you'd prefer to operate on pure Ruby objects rather than JSON strings, you
|
73
|
+
can construct a `MergePatch` object instead.
|
74
|
+
|
75
|
+
```
|
76
|
+
JSON::MergePatch.new({}, {"foo" => "bar"}).call
|
77
|
+
=> {"foo"=>"bar"}
|
78
|
+
```
|
79
|
+
|
80
|
+
Also check out [http://json-merge-patch.herokuapp.com/](http://json-merge-patch.herokuapp.com/),
|
81
|
+
which is a Rails app that serves up `json-merge-patch` responses.
|
82
|
+
|
72
83
|
## Contributing
|
73
84
|
|
74
85
|
1. Fork it
|
data/json-merge_patch.gemspec
CHANGED
@@ -5,12 +5,12 @@ require 'json/merge_patch/version'
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |spec|
|
7
7
|
spec.name = "json-merge_patch"
|
8
|
-
spec.version =
|
8
|
+
spec.version = JSON::MergePatch::VERSION
|
9
9
|
spec.authors = ["Steve Klabnik"]
|
10
10
|
spec.email = ["steve@steveklabnik.com"]
|
11
11
|
spec.description = %q{An implementation of the json-merge-patch draft.}
|
12
12
|
spec.summary = %q{An implementation of the json-merge-patch draft.}
|
13
|
-
spec.homepage = "
|
13
|
+
spec.homepage = "http://json-merge-patch.herokuapp.com/"
|
14
14
|
spec.license = "MIT"
|
15
15
|
|
16
16
|
spec.files = `git ls-files`.split($/)
|
data/lib/json/merge_patch.rb
CHANGED
@@ -2,35 +2,112 @@ require 'json'
|
|
2
2
|
require "json/merge_patch/version"
|
3
3
|
|
4
4
|
module JSON
|
5
|
+
# This represents an error that occurs during merging.
|
5
6
|
MergeError = Class.new(StandardError)
|
6
7
|
|
8
|
+
# Merges a patch into the existing JSON document.
|
9
|
+
#
|
10
|
+
# @param document [String] the original JSON document.
|
11
|
+
# @param merge_patch [Symbol] the merge-patch JSON document.
|
12
|
+
# @return [String] the final document after applying the patch
|
7
13
|
def self.merge(document, merge_patch)
|
8
|
-
|
9
|
-
|
14
|
+
orig = JSON.parse(document)
|
15
|
+
patch = JSON.parse(merge_patch)
|
16
|
+
JSON.dump(MergePatch.new(orig, patch).call)
|
17
|
+
rescue
|
18
|
+
raise MergeError
|
19
|
+
end
|
10
20
|
|
11
|
-
|
12
|
-
|
21
|
+
# This class represents a merge patch.
|
22
|
+
class MergePatch
|
23
|
+
|
24
|
+
# Sets up a MergePatch.
|
25
|
+
#
|
26
|
+
# @param orig [Object] the original document
|
27
|
+
# @param patch [Object] the patch document
|
28
|
+
def initialize(orig, patch)
|
29
|
+
@orig = orig
|
30
|
+
@patch = patch
|
13
31
|
end
|
14
32
|
|
15
|
-
|
16
|
-
|
33
|
+
# Applies the patch the original object.
|
34
|
+
#
|
35
|
+
# @return [Object] the document after applying the patch.
|
36
|
+
def call
|
37
|
+
if @patch.nil?
|
38
|
+
return @orig
|
39
|
+
elsif @patch.kind_of?(Array) || @orig.kind_of?(Array)
|
40
|
+
@orig = purge_nils(@patch)
|
41
|
+
elsif is_primitive?(@patch) || is_primitive?(@orig)
|
42
|
+
@orig = @patch
|
43
|
+
elsif @patch.kind_of?(Hash)
|
44
|
+
@patch.each_key do |m|
|
45
|
+
if @orig.has_key?(m)
|
46
|
+
if @patch[m].nil?
|
47
|
+
@orig.delete(m)
|
48
|
+
else
|
49
|
+
if is_primitive?(@patch[m])
|
50
|
+
@orig[m] = @patch[m]
|
51
|
+
else
|
52
|
+
if @orig[m].kind_of?(Array)
|
53
|
+
result = purge_nils(@patch[m])
|
54
|
+
if result.nil?
|
55
|
+
@orig.delete(m)
|
56
|
+
else
|
57
|
+
@orig[m] = result
|
58
|
+
end
|
59
|
+
else
|
60
|
+
@orig[m] = self.class.new(@orig[m], @patch[m]).call
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
elsif !(@patch[m].nil?)
|
65
|
+
result = purge_nils(@patch[m])
|
66
|
+
if result.nil?
|
67
|
+
@orig.delete(m)
|
68
|
+
else
|
69
|
+
@orig[m] = result
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
@orig
|
17
75
|
end
|
18
76
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
77
|
+
private
|
78
|
+
|
79
|
+
def is_primitive?(val)
|
80
|
+
case val
|
81
|
+
when String
|
82
|
+
true
|
83
|
+
when Fixnum
|
84
|
+
true
|
85
|
+
when TrueClass
|
86
|
+
true
|
87
|
+
when FalseClass
|
88
|
+
true
|
89
|
+
else
|
90
|
+
false
|
91
|
+
end
|
23
92
|
end
|
24
|
-
rescue
|
25
|
-
raise MergeError
|
26
|
-
end
|
27
93
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
94
|
+
def purge_nils(obj)
|
95
|
+
return nil if obj.nil?
|
96
|
+
return obj.compact if obj.kind_of?(Array)
|
97
|
+
return obj if is_primitive?(obj)
|
98
|
+
|
99
|
+
obj.each do |m|
|
100
|
+
if obj[m].nil?
|
101
|
+
if obj.kind_of?(Array)
|
102
|
+
obj.delete_at(m)
|
103
|
+
else
|
104
|
+
obj.delete(m)
|
105
|
+
end
|
106
|
+
elsif obj[m].kind_of?(Hash)
|
107
|
+
purge_nils(obj[m])
|
108
|
+
end
|
109
|
+
end
|
110
|
+
obj
|
34
111
|
end
|
35
112
|
end
|
36
113
|
end
|
@@ -1,5 +1,8 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
1
|
+
# The Ruby standard Library exports JSON
|
2
|
+
# http://www.ruby-doc.org/stdlib-1.9.3/libdoc/json/rdoc/
|
3
|
+
module JSON
|
4
|
+
class MergePatch
|
5
|
+
# The current version of json-merge_patch
|
6
|
+
VERSION = "1.0.0"
|
4
7
|
end
|
5
8
|
end
|
data/test/merge_patch_test.rb
CHANGED
@@ -207,21 +207,9 @@ describe "README example" do
|
|
207
207
|
}
|
208
208
|
JSON
|
209
209
|
|
210
|
-
expected =
|
211
|
-
{
|
212
|
-
"title": "Goodbye!",
|
213
|
-
"author" : {
|
214
|
-
"phoneNumber": "+01-123-456-7890",
|
215
|
-
"givenName" : "John",
|
216
|
-
},
|
217
|
-
"tags":["example"],
|
218
|
-
"content": "This will be unchanged"
|
219
|
-
}
|
220
|
-
JSON
|
210
|
+
expected = %q'{"title":"Hello!","author":{"givenName":"John"},"tags":["example"],"content":"This will be unchanged","phoneNumber":"+01-123-456-7890"}'
|
221
211
|
|
222
|
-
|
223
|
-
assert_equal expected, JSON.merge(document, merge_patch)
|
224
|
-
end
|
212
|
+
assert_equal expected, JSON.merge(document, merge_patch)
|
225
213
|
end
|
226
214
|
end
|
227
215
|
|
data/test/test_helper.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: json-merge_patch
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Steve Klabnik
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-05-
|
11
|
+
date: 2013-05-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -70,7 +70,7 @@ files:
|
|
70
70
|
- lib/json/merge_patch/version.rb
|
71
71
|
- test/merge_patch_test.rb
|
72
72
|
- test/test_helper.rb
|
73
|
-
homepage:
|
73
|
+
homepage: http://json-merge-patch.herokuapp.com/
|
74
74
|
licenses:
|
75
75
|
- MIT
|
76
76
|
metadata: {}
|