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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6ce09ddf6d3610381e68fbb86d8ccf6874573007
4
- data.tar.gz: 15046d860a25fc45329f784fd3a9a639534be7d2
3
+ metadata.gz: 9638a01b320666a7b5270d234ddb50acc746c952
4
+ data.tar.gz: f3a2bd4ecb11392969eb47306df2ce8407d46ce2
5
5
  SHA512:
6
- metadata.gz: 3afcecc326503602ae67a18db19bc3d34596543ffe68e57a0284eb22c4b7bb4bbc5d7e2d70b03d8000e7077e0bf5bdd11ef14fd55b266939b5da4f6ee7255641
7
- data.tar.gz: fadeda3faadfbe333ad0e9da52a0301d17b008936d3a41f46d6345ad1bca05487988947ae7d1208577438bd5e867904b61b3ad6a27547db157cd60b95a408c4d
6
+ metadata.gz: 46b929805693acbb5f82575086898a2fe1320b456e8b2f373780bb09bfac2fec6d296fae57a4a30bfaeb6ad15d70cddd3d00823b0de01af120c10705035c8184
7
+ data.tar.gz: 1670820bea9e3df973c6c2a2572ad2e3df01f6bb376eaeff092b655a233be9e0aa2ddbab8f60e36ddb10c47e7a7637209522b046bd90aa9ac75a9fe6ffee9994
data/Gemfile CHANGED
@@ -2,3 +2,5 @@ source 'https://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in json-merge_patch.gemspec
4
4
  gemspec
5
+
6
+ gem 'coveralls', require: false
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Json::MergePatch
2
2
 
3
- [![Build Status](https://travis-ci.org/steveklabnik/json-merge_patch.png)](https://travis-ci.org/steveklabnik/json-merge_patch)
3
+ [![Build Status](https://travis-ci.org/steveklabnik/json-merge_patch.png)](https://travis-ci.org/steveklabnik/json-merge_patch) [![Code Climate](https://codeclimate.com/github/steveklabnik/json-merge_patch.png)](https://codeclimate.com/github/steveklabnik/json-merge_patch) [![Coverage Status](https://coveralls.io/repos/steveklabnik/json-merge_patch/badge.png)](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": "Goodbye!",
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
@@ -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 = Json::MergePatch::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 = "https://github.com/steveklabnik/json-merge_patch"
13
+ spec.homepage = "http://json-merge-patch.herokuapp.com/"
14
14
  spec.license = "MIT"
15
15
 
16
16
  spec.files = `git ls-files`.split($/)
@@ -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
- document = JSON.parse(document)
9
- merge_patch = JSON.parse(merge_patch)
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
- if merge_patch.is_a? Array
12
- return JSON.dump(merge_patch)
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
- if document.is_a? Array
16
- return JSON.dump(merge_patch)
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
- if merge_patch.is_a? Hash
20
- document.merge!(merge_patch)
21
- document.delete_if(&method(:recursive_delete_if))
22
- return JSON.dump(document)
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
- def self.recursive_delete_if(key, value)
29
- if value.kind_of?(Hash)
30
- value.delete_if(&method(:recursive_delete_if))
31
- nil
32
- else
33
- value.nil?
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
- module Json
2
- module MergePatch
3
- VERSION = "0.1.0"
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
@@ -207,21 +207,9 @@ describe "README example" do
207
207
  }
208
208
  JSON
209
209
 
210
- expected = <<-JSON.strip_heredoc.gsub(/\s/, "")
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
- pending do
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
 
@@ -1,3 +1,13 @@
1
+ require 'simplecov'
2
+ SimpleCov.start do
3
+ add_filter do |source_file|
4
+ source_file.filename =~ /test/
5
+ end
6
+ end
7
+
8
+ require 'coveralls'
9
+ Coveralls.wear!
10
+
1
11
  require 'minitest/autorun'
2
12
 
3
13
  def pending
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: 0.1.0
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-13 00:00:00.000000000 Z
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: https://github.com/steveklabnik/json-merge_patch
73
+ homepage: http://json-merge-patch.herokuapp.com/
74
74
  licenses:
75
75
  - MIT
76
76
  metadata: {}