json-merge_patch 0.1.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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: {}