Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Fixes to build gem on ruby 2.0, parse hash values, array operations, and decrement #90

Merged
merged 6 commits into from

4 participants

@ericcj

waiting for official jeweler, but this at least makes "rake build" work on ruby 2.0 for now

fixes #52 and #71

@ericcj ericcj fix unparsed values on save after array operations, fix decrement, re…
…move unnecessary object cache/restore around saves since they don't mutate self anyways except array operations which we actually want to come back as real server value and not a mix of pointers and objects
e1d1262
@bcherry

Ship it!

@jamonholmgren

I can merge, but @adelevie would have to push the new version up anyway, so he should take a look.

@adelevie
Owner
@jamonholmgren

Probably just a minor bump: 0.1.15?

@jamonholmgren

I didn't realize this was parse-ruby-client -- I was thinking it was parse_resource.

@ericcj
@adelevie adelevie merged commit bee5686 into adelevie:master
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on May 20, 2013
  1. @ericcj

    fix coverage for ruby 2.0

    ericcj authored
  2. @ericcj

    more ruby 2.0 stuff

    ericcj authored
  3. @ericcj

    ruby 2.0 jeweler fork

    ericcj authored
  4. @ericcj

    Merge remote-tracking branch 'adelevie/master'

    ericcj authored
    Conflicts:
    	.travis.yml
    	Gemfile
    	Gemfile.lock
    	Rakefile
Commits on May 21, 2013
  1. @ericcj
  2. @ericcj

    fix unparsed values on save after array operations, fix decrement, re…

    ericcj authored
    …move unnecessary object cache/restore around saves since they don't mutate self anyways except array operations which we actually want to come back as real server value and not a mix of pointers and objects
This page is out of date. Refresh to see the latest.
View
4 Gemfile
@@ -10,11 +10,11 @@ group :development do
gem 'shoulda', '>= 0'
gem 'test-unit', '= 2.5.0'
gem 'mocha', '= 0.12.0', :require => false
- gem 'jeweler', '~> 1.6.4'
+ gem 'jeweler', :git => 'https://github.com/foxnewsnetwork/jeweler.git', :branch => 'ruby-2.0.0-ifying'
gem 'simplecov', :require => false
gem 'webmock'
gem 'vcr'
end
gem 'patron'
-gem 'iron_mq'
+gem 'iron_mq'
View
26 Gemfile.lock
@@ -1,3 +1,14 @@
+GIT
+ remote: https://github.com/foxnewsnetwork/jeweler.git
+ revision: f05c62e168cfc29bd82cebe06df8fd11e1ef09ee
+ branch: ruby-2.0.0-ifying
+ specs:
+ jeweler (1.8.4)
+ bundler (~> 1.3.0.pre)
+ git (>= 1.2.5)
+ rake
+ rdoc
+
GEM
remote: https://rubygems.org/
specs:
@@ -8,18 +19,17 @@ GEM
rest (>= 2.2.0)
iron_mq (2.1.3)
iron_core (>= 0.4.2)
- jeweler (1.6.4)
- bundler (~> 1.0)
- git (>= 1.2.5)
- rake
+ json (1.8.0)
metaclass (0.0.1)
- mime-types (1.22)
+ mime-types (1.20.1)
mocha (0.12.0)
metaclass (~> 0.0.1)
- multi_json (1.7.2)
+ multi_json (1.7.3)
net-http-persistent (2.8)
patron (0.4.18)
- rake (0.9.2.2)
+ rake (10.0.4)
+ rdoc (4.0.1)
+ json (~> 1.4)
rest (2.2.0)
net-http-persistent
rest-client (>= 0.3.0)
@@ -42,7 +52,7 @@ PLATFORMS
DEPENDENCIES
bundler
iron_mq
- jeweler (~> 1.6.4)
+ jeweler!
mocha (= 0.12.0)
patron
shoulda
View
22 README.md
@@ -183,7 +183,7 @@ game_score["score"] = Parse::Increment.new(1)
game_score.save
```
-You can also use `Parse::Decrement.new(amount)`.
+You can also use a negative amount to decrement.
#### Arrays
@@ -247,7 +247,7 @@ You can delete a single field from an object by using the `Parse::Object#delete_
To reduce the amount of time spent on network round trips, you can create, update, or delete several objects in one call, using the batch endpoint.
-parse-ruby-client provides a "manual" way to construct Batch Operations, as well as some convenience methods. The commands are run in the order they are given. For example, to create a couple of GameScore objects using the "manual" style, use `Parse::Batch#add_request`. `#add_request` takes a `Hash` with `"method"`, `"path"`, and `"body"` keys that specify the HTTP command that would normally be used for that command.
+parse-ruby-client provides a "manual" way to construct Batch Operations, as well as some convenience methods. The commands are run in the order they are given. For example, to create a couple of GameScore objects using the "manual" style, use `Parse::Batch#add_request`. `#add_request` takes a `Hash` with `"method"`, `"path"`, and `"body"` keys that specify the HTTP command that would normally be used for that command.
```ruby
batch = Parse::Batch.new
@@ -458,7 +458,7 @@ Other constraint methods include:
<tr>
<td>`Parse::Query#select`</td>
<td>TODO: `$select` not yet implemented. This matches a value for a key in the result of a different query</td>
- </tr>
+ </tr>
</table>
For example, to retrieve scores between 1000 and 3000, including the endpoints, we could issue:
@@ -704,7 +704,7 @@ To sign up a new user, create a new `Parse::User` object and then call `#save` o
```ruby
user = Parse::User.new({
- :username => "cooldude6",
+ :username => "cooldude6",
:password => "p_n7!-e8",
:phone => "415-392-0202"
})
@@ -828,7 +828,7 @@ All of the options for queries that work for regular objects also work for user
### Deleting Users
-TODO: Implement this!
+TODO: Implement this!
Proposed api:
@@ -1014,8 +1014,8 @@ To upload a file to Parse, use `Parse::File`. You must include the `"Content-Typ
```ruby
file = Parse::File.new({
- :body => "Hello World!",
- :local_filename => "hello.txt",
+ :body => "Hello World!",
+ :local_filename => "hello.txt",
:content_type => "text/plain"
})
file.save
@@ -1033,8 +1033,8 @@ To upload an image, the syntax is a little bit different. Here's an example that
```ruby
photo = Parse::File.new({
- :body => IO.read("test/parsers.jpg"),
- :local_filename => "parsers.jpg",
+ :body => IO.read("test/parsers.jpg"),
+ :local_filename => "parsers.jpg",
:content_type => "image/jpeg"
})
photo.save
@@ -1046,8 +1046,8 @@ After files are uploaded, you can associate them with Parse objects:
```ruby
photo = Parse::File.new({
- :body => IO.read("test/parsers.jpg"),
- :local_filename => "parsers.jpg",
+ :body => IO.read("test/parsers.jpg"),
+ :local_filename => "parsers.jpg",
:content_type => "image/jpeg"
})
photo.save
View
2  Rakefile
@@ -35,7 +35,7 @@ end
task :default => :test
require 'rdoc/task'
-Rake::RDocTask.new do |rdoc|
+RDoc::Task.new do |rdoc|
version = File.exist?('VERSION') ? File.read('VERSION') : ""
rdoc.rdoc_dir = 'rdoc'
View
22 features.md
@@ -179,7 +179,7 @@ game_score["score"] = Parse::Increment.new(1)
game_score.save
```
-You can also use `Parse::Decrement.new(amount)`.
+Use a negative amount to decrement.
#### Arrays
@@ -243,7 +243,7 @@ You can delete a single field from an object by using the `Parse::Object#delete_
To reduce the amount of time spent on network round trips, you can create, update, or delete several objects in one call, using the batch endpoint.
-parse-ruby-client provides a "manual" way to construct Batch Operations, as well as some convenience methods. The commands are run in the order they are given. For example, to create a couple of GameScore objects using the "manual" style, use `Parse::Batch#add_request`. `#add_request` takes a `Hash` with `"method"`, `"path"`, and `"body"` keys that specify the HTTP command that would normally be used for that command.
+parse-ruby-client provides a "manual" way to construct Batch Operations, as well as some convenience methods. The commands are run in the order they are given. For example, to create a couple of GameScore objects using the "manual" style, use `Parse::Batch#add_request`. `#add_request` takes a `Hash` with `"method"`, `"path"`, and `"body"` keys that specify the HTTP command that would normally be used for that command.
```ruby
batch = Parse::Batch.new
@@ -454,7 +454,7 @@ Other constraint methods include:
<tr>
<td>`Parse::Query#select`</td>
<td>TODO: `$select` not yet implemented. This matches a value for a key in the result of a different query</td>
- </tr>
+ </tr>
</table>
For example, to retrieve scores between 1000 and 3000, including the endpoints, we could issue:
@@ -700,7 +700,7 @@ To sign up a new user, create a new `Parse::User` object and then call `#save` o
```ruby
user = Parse::User.new({
- :username => "cooldude6",
+ :username => "cooldude6",
:password => "p_n7!-e8",
:phone => "415-392-0202"
})
@@ -824,7 +824,7 @@ All of the options for queries that work for regular objects also work for user
### Deleting Users
-TODO: Implement this!
+TODO: Implement this!
Proposed api:
@@ -1010,8 +1010,8 @@ To upload a file to Parse, use `Parse::File`. You must include the `"Content-Typ
```ruby
file = Parse::File.new({
- :body => "Hello World!",
- :local_filename => "hello.txt",
+ :body => "Hello World!",
+ :local_filename => "hello.txt",
:content_type => "text/plain"
})
file.save
@@ -1029,8 +1029,8 @@ To upload an image, the syntax is a little bit different. Here's an example that
```ruby
photo = Parse::File.new({
- :body => IO.read("test/parsers.jpg"),
- :local_filename => "parsers.jpg",
+ :body => IO.read("test/parsers.jpg"),
+ :local_filename => "parsers.jpg",
:content_type => "image/jpeg"
})
photo.save
@@ -1042,8 +1042,8 @@ After files are uploaded, you can associate them with Parse objects:
```ruby
photo = Parse::File.new({
- :body => IO.read("test/parsers.jpg"),
- :local_filename => "parsers.jpg",
+ :body => IO.read("test/parsers.jpg"),
+ :local_filename => "parsers.jpg",
:content_type => "image/jpeg"
})
photo.save
View
180 fixtures/vcr_cassettes/test_acls_arent_objects.yml
@@ -0,0 +1,180 @@
+---
+http_interactions:
+- request:
+ method: post
+ uri: https://api.parse.com/1/classes/Post
+ body:
+ encoding: UTF-8
+ string: '{"ACL":{"*":{"read":true}}}'
+ headers:
+ Content-Type:
+ - application/json
+ Accept:
+ - application/json
+ User-Agent:
+ - Parse for Ruby, 0.0
+ X-Parse-Master-Key:
+ - ''
+ X-Parse-Rest-Api-Key:
+ - <X-Parse-REST-API-Key>
+ X-Parse-Application-Id:
+ - <X-Parse-Application-Id>
+ X-Parse-Session-Token:
+ - ''
+ Expect:
+ - ''
+ response:
+ status:
+ code: 201
+ message: Created
+ headers:
+ Access-Control-Allow-Origin:
+ - '*'
+ Access-Control-Request-Method:
+ - '*'
+ Cache-Control:
+ - no-cache
+ Content-Type:
+ - application/json; charset=utf-8
+ Date:
+ - Tue, 21 May 2013 14:21:15 GMT
+ Location:
+ - https://api.parse.com/1/classes/Post/OHGnBvPDXq
+ Server:
+ - nginx/1.2.2
+ Set-Cookie:
+ - <COOKIE-KEY>
+ Status:
+ - 201 Created
+ X-Runtime:
+ - '0.078743'
+ X-Ua-Compatible:
+ - IE=Edge,chrome=1
+ Content-Length:
+ - '64'
+ Connection:
+ - keep-alive
+ body:
+ encoding: ASCII-8BIT
+ string: '{"createdAt":"2013-05-21T14:21:15.405Z","objectId":"OHGnBvPDXq"}'
+ http_version:
+ recorded_at: Tue, 21 May 2013 14:21:15 GMT
+- request:
+ method: get
+ uri: https://api.parse.com/1/classes/Post/OHGnBvPDXq
+ body:
+ encoding: US-ASCII
+ string: ''
+ headers:
+ Content-Type:
+ - application/json
+ Accept:
+ - application/json
+ User-Agent:
+ - Parse for Ruby, 0.0
+ X-Parse-Master-Key:
+ - ''
+ X-Parse-Rest-Api-Key:
+ - <X-Parse-REST-API-Key>
+ X-Parse-Application-Id:
+ - <X-Parse-Application-Id>
+ X-Parse-Session-Token:
+ - ''
+ Expect:
+ - ''
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ Access-Control-Allow-Origin:
+ - '*'
+ Access-Control-Request-Method:
+ - '*'
+ Cache-Control:
+ - max-age=0, private, must-revalidate
+ Content-Type:
+ - application/json; charset=utf-8
+ Date:
+ - Tue, 21 May 2013 14:21:38 GMT
+ Etag:
+ - '"3e2ff5392c54b720e94d94f7a4a418fa"'
+ Server:
+ - nginx/1.2.2
+ Set-Cookie:
+ - <COOKIE-KEY>
+ Status:
+ - 200 OK
+ X-Runtime:
+ - '0.028265'
+ X-Ua-Compatible:
+ - IE=Edge,chrome=1
+ Content-Length:
+ - '129'
+ Connection:
+ - keep-alive
+ body:
+ encoding: ASCII-8BIT
+ string: '{"createdAt":"2013-05-21T14:21:15.405Z","updatedAt":"2013-05-21T14:21:15.405Z","objectId":"OHGnBvPDXq","ACL":{"*":{"read":true}}}'
+ http_version:
+ recorded_at: Tue, 21 May 2013 14:21:38 GMT
+- request:
+ method: get
+ uri: https://api.parse.com/1/classes/Post/OHGnBvPDXq
+ body:
+ encoding: US-ASCII
+ string: ''
+ headers:
+ Content-Type:
+ - application/json
+ Accept:
+ - application/json
+ User-Agent:
+ - Parse for Ruby, 0.0
+ X-Parse-Master-Key:
+ - ''
+ X-Parse-Rest-Api-Key:
+ - <X-Parse-REST-API-Key>
+ X-Parse-Application-Id:
+ - <X-Parse-Application-Id>
+ X-Parse-Session-Token:
+ - ''
+ Expect:
+ - ''
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ Access-Control-Allow-Origin:
+ - '*'
+ Access-Control-Request-Method:
+ - '*'
+ Cache-Control:
+ - max-age=0, private, must-revalidate
+ Content-Type:
+ - application/json; charset=utf-8
+ Date:
+ - Tue, 21 May 2013 14:21:38 GMT
+ Etag:
+ - '"3e2ff5392c54b720e94d94f7a4a418fa"'
+ Server:
+ - nginx/1.2.2
+ Set-Cookie:
+ - <COOKIE-KEY>
+ Status:
+ - 200 OK
+ X-Runtime:
+ - '0.023049'
+ X-Ua-Compatible:
+ - IE=Edge,chrome=1
+ Content-Length:
+ - '129'
+ Connection:
+ - keep-alive
+ body:
+ encoding: ASCII-8BIT
+ string: '{"createdAt":"2013-05-21T14:21:15.405Z","updatedAt":"2013-05-21T14:21:15.405Z","objectId":"OHGnBvPDXq","ACL":{"*":{"read":true}}}'
+ http_version:
+ recorded_at: Tue, 21 May 2013 14:21:38 GMT
+recorded_with: VCR 2.4.0
View
180 fixtures/vcr_cassettes/test_array_add_unique.yml
@@ -0,0 +1,180 @@
+---
+http_interactions:
+- request:
+ method: post
+ uri: https://api.parse.com/1/classes/Post
+ body:
+ encoding: UTF-8
+ string: '{}'
+ headers:
+ Content-Type:
+ - application/json
+ Accept:
+ - application/json
+ User-Agent:
+ - Parse for Ruby, 0.0
+ X-Parse-Master-Key:
+ - ''
+ X-Parse-Rest-Api-Key:
+ - <X-Parse-REST-API-Key>
+ X-Parse-Application-Id:
+ - <X-Parse-Application-Id>
+ X-Parse-Session-Token:
+ - ''
+ Expect:
+ - ''
+ response:
+ status:
+ code: 201
+ message: Created
+ headers:
+ Access-Control-Allow-Origin:
+ - '*'
+ Access-Control-Request-Method:
+ - '*'
+ Cache-Control:
+ - no-cache
+ Content-Type:
+ - application/json; charset=utf-8
+ Date:
+ - Tue, 21 May 2013 17:44:02 GMT
+ Location:
+ - https://api.parse.com/1/classes/Post/SNcYuo3t5K
+ Server:
+ - nginx/1.2.2
+ Set-Cookie:
+ - <COOKIE-KEY>
+ Status:
+ - 201 Created
+ X-Runtime:
+ - '0.289539'
+ X-Ua-Compatible:
+ - IE=Edge,chrome=1
+ Content-Length:
+ - '64'
+ Connection:
+ - keep-alive
+ body:
+ encoding: ASCII-8BIT
+ string: '{"createdAt":"2013-05-21T17:44:02.504Z","objectId":"SNcYuo3t5K"}'
+ http_version:
+ recorded_at: Tue, 21 May 2013 17:44:02 GMT
+- request:
+ method: post
+ uri: https://api.parse.com/1/classes/Comment
+ body:
+ encoding: UTF-8
+ string: '{"text":"great post!"}'
+ headers:
+ Content-Type:
+ - application/json
+ Accept:
+ - application/json
+ User-Agent:
+ - Parse for Ruby, 0.0
+ X-Parse-Master-Key:
+ - ''
+ X-Parse-Rest-Api-Key:
+ - <X-Parse-REST-API-Key>
+ X-Parse-Application-Id:
+ - <X-Parse-Application-Id>
+ X-Parse-Session-Token:
+ - ''
+ Expect:
+ - ''
+ response:
+ status:
+ code: 201
+ message: Created
+ headers:
+ Access-Control-Allow-Origin:
+ - '*'
+ Access-Control-Request-Method:
+ - '*'
+ Cache-Control:
+ - no-cache
+ Content-Type:
+ - application/json; charset=utf-8
+ Date:
+ - Tue, 21 May 2013 17:44:02 GMT
+ Location:
+ - https://api.parse.com/1/classes/Comment/lJjuzuDd6H
+ Server:
+ - nginx/1.2.2
+ Set-Cookie:
+ - <COOKIE-KEY>
+ Status:
+ - 201 Created
+ X-Runtime:
+ - '0.107052'
+ X-Ua-Compatible:
+ - IE=Edge,chrome=1
+ Content-Length:
+ - '64'
+ Connection:
+ - keep-alive
+ body:
+ encoding: ASCII-8BIT
+ string: '{"createdAt":"2013-05-21T17:44:02.601Z","objectId":"lJjuzuDd6H"}'
+ http_version:
+ recorded_at: Tue, 21 May 2013 17:44:02 GMT
+- request:
+ method: put
+ uri: https://api.parse.com/1/classes/Post/SNcYuo3t5K
+ body:
+ encoding: UTF-8
+ string: '{"comments":{"__op":"AddUnique","objects":[{"__type":"Pointer","className":"Comment","objectId":"lJjuzuDd6H"}]}}'
+ headers:
+ Content-Type:
+ - application/json
+ Accept:
+ - application/json
+ User-Agent:
+ - Parse for Ruby, 0.0
+ X-Parse-Master-Key:
+ - ''
+ X-Parse-Rest-Api-Key:
+ - <X-Parse-REST-API-Key>
+ X-Parse-Application-Id:
+ - <X-Parse-Application-Id>
+ X-Parse-Session-Token:
+ - ''
+ Expect:
+ - ''
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ Access-Control-Allow-Origin:
+ - '*'
+ Access-Control-Request-Method:
+ - '*'
+ Cache-Control:
+ - max-age=0, private, must-revalidate
+ Content-Type:
+ - application/json; charset=utf-8
+ Date:
+ - Tue, 21 May 2013 17:44:02 GMT
+ Etag:
+ - '"08c4a7d37dd1d79503cdfba1d649a71b"'
+ Server:
+ - nginx/1.2.2
+ Set-Cookie:
+ - <COOKIE-KEY>
+ Status:
+ - 200 OK
+ X-Runtime:
+ - '0.109572'
+ X-Ua-Compatible:
+ - IE=Edge,chrome=1
+ Content-Length:
+ - '120'
+ Connection:
+ - keep-alive
+ body:
+ encoding: ASCII-8BIT
+ string: '{"comments":[{"__type":"Pointer","className":"Comment","objectId":"lJjuzuDd6H"}],"updatedAt":"2013-05-21T17:44:02.779Z"}'
+ http_version:
+ recorded_at: Tue, 21 May 2013 17:44:02 GMT
+recorded_with: VCR 2.4.0
View
121 fixtures/vcr_cassettes/test_decrement.yml
@@ -0,0 +1,121 @@
+---
+http_interactions:
+- request:
+ method: post
+ uri: https://api.parse.com/1/classes/Post
+ body:
+ encoding: UTF-8
+ string: '{"count":1}'
+ headers:
+ Content-Type:
+ - application/json
+ Accept:
+ - application/json
+ User-Agent:
+ - Parse for Ruby, 0.0
+ X-Parse-Master-Key:
+ - ''
+ X-Parse-Rest-Api-Key:
+ - <X-Parse-REST-API-Key>
+ X-Parse-Application-Id:
+ - <X-Parse-Application-Id>
+ X-Parse-Session-Token:
+ - ''
+ Expect:
+ - ''
+ response:
+ status:
+ code: 201
+ message: Created
+ headers:
+ Access-Control-Allow-Origin:
+ - '*'
+ Access-Control-Request-Method:
+ - '*'
+ Cache-Control:
+ - no-cache
+ Content-Type:
+ - application/json; charset=utf-8
+ Date:
+ - Tue, 21 May 2013 17:44:02 GMT
+ Location:
+ - https://api.parse.com/1/classes/Post/mbi9hgIA8z
+ Server:
+ - nginx/1.2.2
+ Set-Cookie:
+ - <COOKIE-KEY>
+ Status:
+ - 201 Created
+ X-Runtime:
+ - '0.036852'
+ X-Ua-Compatible:
+ - IE=Edge,chrome=1
+ Content-Length:
+ - '64'
+ Connection:
+ - keep-alive
+ body:
+ encoding: ASCII-8BIT
+ string: '{"createdAt":"2013-05-21T17:44:02.950Z","objectId":"mbi9hgIA8z"}'
+ http_version:
+ recorded_at: Tue, 21 May 2013 17:44:02 GMT
+- request:
+ method: put
+ uri: https://api.parse.com/1/classes/Post/mbi9hgIA8z
+ body:
+ encoding: UTF-8
+ string: '{"count":{"__op":"Increment","amount":-1}}'
+ headers:
+ Content-Type:
+ - application/json
+ Accept:
+ - application/json
+ User-Agent:
+ - Parse for Ruby, 0.0
+ X-Parse-Master-Key:
+ - ''
+ X-Parse-Rest-Api-Key:
+ - <X-Parse-REST-API-Key>
+ X-Parse-Application-Id:
+ - <X-Parse-Application-Id>
+ X-Parse-Session-Token:
+ - ''
+ Expect:
+ - ''
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ Access-Control-Allow-Origin:
+ - '*'
+ Access-Control-Request-Method:
+ - '*'
+ Cache-Control:
+ - max-age=0, private, must-revalidate
+ Content-Type:
+ - application/json; charset=utf-8
+ Date:
+ - Tue, 21 May 2013 17:44:03 GMT
+ Etag:
+ - '"801ca6262d69a0dcff8d69e7f078aaca"'
+ Server:
+ - nginx/1.2.2
+ Set-Cookie:
+ - <COOKIE-KEY>
+ Status:
+ - 200 OK
+ X-Runtime:
+ - '0.104988'
+ X-Ua-Compatible:
+ - IE=Edge,chrome=1
+ Transfer-Encoding:
+ - chunked
+ Connection:
+ - keep-alive
+ body:
+ encoding: ASCII-8BIT
+ string: '{"count":0,"updatedAt":"2013-05-21T17:44:03.131Z"}'
+ http_version:
+ recorded_at: Tue, 21 May 2013 17:44:03 GMT
+recorded_with: VCR 2.4.0
View
31 lib/parse/datatypes.rb
@@ -202,37 +202,6 @@ def to_json(*a)
end
end
- class Decrement
- # '{"score": {"__op": "Decrement", "amount": 1 } }'
- attr_accessor :amount
-
- def initialize(amount)
- @amount = amount
- end
-
- def eql?(other)
- self.class.equal?(other.class) &&
- amount == other.amount
- end
-
- alias == eql?
-
- def hash
- amount.hash
- end
-
- def as_json(*a)
- {
- Protocol::KEY_OP => Protocol::KEY_DECREMENT,
- Protocol::KEY_AMOUNT => @amount
- }
- end
-
- def to_json(*a)
- as_json.to_json(*a)
- end
- end
-
class ArrayOp
# '{"myArray": {"__op": "Add", "objects": ["something", "something else"] } }'
attr_accessor :operation
View
20 lib/parse/object.rb
@@ -116,17 +116,14 @@ def save
method = :post
end
- object_store = Parse.store_objects_by_pointer(self)
-
body = safe_json
data = Parse.client.request(self.uri, method, body)
if data
- parse data
+ # array operations can return mutated view of array which needs to be parsed
+ parse Parse.parse_json(class_name, data)
end
- Parse.restore_objects!(self, object_store)
-
if @class_name == Parse::Protocol::CLASS_USER
self.delete("password")
self.delete(:username)
@@ -209,13 +206,6 @@ def increment(field, amount = 1)
# return nil
#end
- #if amount != 0
- # op = amount > 0 ? Protocol::OP_INCREMENT : Protocol::OP_DECREMENT
- # body = "{\"#{field}\": {\"#{Protocol::KEY_OP}\": \"#{op}\", \"#{Protocol::KEY_AMOUNT}\" : #{amount.abs}}}"
- # data = Parse.client.request( self.uri, :put, body)
- # parse data
- #end
- #self
body = {field => Parse::Increment.new(amount)}.to_json
data = Parse.client.request(self.uri, :put, body)
parse data
@@ -225,11 +215,7 @@ def increment(field, amount = 1)
# Decrement the given field by an amount, which defaults to 1. Saves immediately to reflect decremented
# A synonym for increment(field, -amount).
def decrement(field, amount = 1)
- #increment field, -amount
- body = {field => Parse::Decrement.new(amount)}.to_json
- data = Parse.client.request(self.uri, :put, body)
- parse data
- self
+ increment(field, -amount)
end
private
View
4 lib/parse/protocol.rb
@@ -59,7 +59,6 @@ module Protocol
KEY_OP = "__op"
KEY_INCREMENT = "Increment"
- KEY_DECREMENT = "Decrement"
KEY_DELETE = "Delete"
# array ops
@@ -86,9 +85,6 @@ module Protocol
# Operation name for incrementing an objects field value remotely
OP_INCREMENT = "Increment"
- # Operation name for decrementing an objects field value remotely
- OP_DECREMENT = "Decrement"
-
# The data type name for special JSON objects representing a full object
TYPE_OBJECT = "Object"
View
57 lib/parse/util.rb
@@ -1,4 +1,3 @@
-require 'pp'
module Parse
# Parse a JSON representation into a fully instantiated
@@ -22,8 +21,10 @@ def Parse.parse_json(class_name, obj)
parse_datatype obj
elsif obj.size == 1 && obj.has_key?(Protocol::KEY_RESULTS) && obj[Protocol::KEY_RESULTS].is_a?(Array)
obj[Protocol::KEY_RESULTS].collect { |o| parse_json(class_name, o) }
- else # otherwise it must be a regular object, so deep parse it avoiding re-JSON.parsing raw Strings
+ elsif class_name # otherwise it must be a regular object, so deep parse it avoiding re-JSON.parsing raw Strings
Parse::Object.new class_name, Hash[obj.map{|k,v| [k, parse_json(nil, v)]}]
+ else # plain old hash
+ obj
end
# primitive
@@ -51,12 +52,8 @@ def Parse.parse_datatype(obj)
end
end
- def Parse.can_pointerize?(value)
- value.kind_of?(Parse::Object) && value.class_name
- end
-
def Parse.pointerize_value(obj)
- if Parse.can_pointerize?(obj)
+ if obj.kind_of?(Parse::Object)
obj.pointer
elsif obj.is_a?(Array)
obj.map do |v|
@@ -87,50 +84,4 @@ def Parse.object_pointer_hash(v)
v.class_name.hash ^ v.id.hash
end
end
-
- def Parse.store_objects_by_pointer(obj, store={})
- if obj.is_a?(Parse::Object) && !obj.new?
- if store[obj.pointer] # don't recurse if you have circular objects
- return store
- end
-
- store[obj.pointer] = obj
- end
-
- if obj.is_a?(Array)
- obj.each do |v|
- Parse.store_objects_by_pointer(v, store)
- end
- elsif obj.is_a?(Hash)
- obj.each do |k, v|
- Parse.store_objects_by_pointer(v, store)
- end
- end
-
- store
- end
-
- def Parse.restore_objects!(obj, store, already_restored={})
- if already_restored[obj]
- return obj
- end
-
- already_restored[obj] = true
-
- if obj.is_a?(Hash) # Parse::Object or Hash, we'll actually modify the object
- obj.each do |k, v|
- obj[k] = Parse.restore_objects!(v, store, already_restored)
- end
-
- obj
- elsif obj.is_a?(Parse::Pointer) && store[obj]
- store[obj]
- elsif obj.is_a?(Array)
- obj.map do |v|
- Parse.restore_objects!(v, store, already_restored)
- end
- else
- obj
- end
- end
end
View
3  test/helper.rb
@@ -19,6 +19,9 @@
require 'vcr'
require 'webmock/test_unit'
+require 'simplecov'
+SimpleCov.start if ENV['COVERAGE']
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
$LOAD_PATH.unshift(File.dirname(__FILE__))
require 'parse-ruby-client'
View
7 test/test_datatypes.rb
@@ -55,13 +55,6 @@ def test_increment
assert_equal increment.to_json, "{\"__op\":\"Increment\",\"amount\":#{amount}}"
end
- def test_decrement
- amount = 5
- increment = Parse::Decrement.new amount
-
- assert_equal increment.to_json, "{\"__op\":\"Decrement\",\"amount\":#{amount}}"
- end
-
def test_geopoint
# '{"location": {"__type":"GeoPoint", "latitude":40.0, "longitude":-30.0}}'
data = {
View
42 test/test_object.rb
@@ -112,6 +112,18 @@ def test_deep_parse
end
end
+ def test_acls_arent_objects
+ VCR.use_cassette('test_acls_arent_objects', :record => :new_episodes) do
+ post = Parse::Object.new("Post", "ACL" => {"*" => {"read"=>true}})
+ assert_equal Hash, post['ACL'].class
+ post.save
+ assert_equal Hash, post.refresh['ACL'].class
+
+ post = Parse.get("Post", post.id)
+ assert_equal Hash, post['ACL'].class
+ end
+ end
+
def test_deep_as_json
VCR.use_cassette('test_deep_as_json', :record => :new_episodes) do
other = Parse::Object.new "Post"
@@ -138,7 +150,7 @@ def test_boolean_values_as_json
safe_json_hash = JSON.parse post.safe_json
assert_equal false, safe_json_hash["read"]
assert_equal true, safe_json_hash["published"]
- end
+ end
def test_saving_boolean_values
VCR.use_cassette('test_saving_boolean_values', :record => :new_episodes) do
@@ -151,7 +163,7 @@ def test_saving_boolean_values
assert_equal false, retrieved_post["read"]
assert_equal true, retrieved_post["published"]
end
- end
+ end
def test_array_add
VCR.use_cassette('test_array_add', :record => :new_episodes) do
@@ -186,6 +198,32 @@ def test_array_add_pointerizing
end
end
+ def test_array_add_unique
+ VCR.use_cassette('test_array_add_unique', :record => :new_episodes) do
+ post = Parse::Object.new "Post"
+ post.save
+
+ comment = Parse::Object.new("Comment", "text" => "great post!")
+ comment.save
+
+ post.array_add_unique("comments", comment)
+ assert_equal "great post!", post['comments'][0]['text']
+ post.save
+ assert_equal comment, post['comments'][0]
+ assert post['comments'][0].instance_of?(Parse::Pointer) # save returns array pointerized
+ end
+ end
+
+ def test_decrement
+ VCR.use_cassette('test_decrement', :record => :new_episodes) do
+ post = Parse::Object.new "Post", 'count' => 1
+ post.save
+
+ post.decrement('count')
+ assert_equal 0, post['count']
+ end
+ end
+
def test_array_add_relation
omit("broken test, saving Post results in ParseProtocolError: 111: can't add a relation to an non-relation field")
Something went wrong with that request. Please try again.