parse-ruby-client 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
data/.travis.yml ADDED
@@ -0,0 +1,11 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.8.7
4
+ - 1.9.2
5
+ - 1.9.3
6
+ - jruby-18mode # JRuby in 1.8 mode
7
+ - jruby-19mode # JRuby in 1.9 mode
8
+ - rbx-18mode
9
+ # - rbx-19mode # currently in active development, may or may not work for your project
10
+ # uncomment this line if your project needs to run something other than `rake`:
11
+ # script: bundle exec rspec spec
data/README.md CHANGED
@@ -15,16 +15,37 @@ This currently depends on the gems 'json' and 'patron' for JSON support and HTTP
15
15
 
16
16
  # Getting Started
17
17
 
18
+ ## Installation
19
+
20
+ `gem "parse-ruby-client", "~> 0.0.3"`
21
+
18
22
  ---
19
23
 
20
24
  To get started, load the parse.rb file and call Parse.init to initialize the client object with
21
25
  your application ID and API key values, which you can obtain from the parse.com dashboard.
22
26
 
23
27
  ```ruby
28
+ require 'parse-ruby-client'
29
+
24
30
  Parse.init :application_id => "<your_app_id>",
25
31
  :api_key => "<your_api_key>"
26
32
  ```
27
33
 
34
+ If you don't like pasting this stuff in every time you fire up irb, save your api keys to `.bash_profile` or similar:
35
+
36
+ ```bash
37
+ export PARSE_APPLICATION_ID="12345678"
38
+ export PARSE_REST_API_KEY="ABCDEFGH"
39
+ ```
40
+
41
+ Now you can just do this:
42
+
43
+ ```ruby
44
+ Parse.init
45
+ ```
46
+
47
+ The test folder assumes this naming convention for environment variables, so if you want to run the tests, you *must* do this. But it's easy. And good for you, too.
48
+
28
49
  ## Creating and Saving Objects
29
50
 
30
51
  Create an instance of ```Parse::Object``` with your class name supplied as a string, set some keys, and call ```save()```.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.2
1
+ 0.0.3
data/lib/parse/client.rb CHANGED
@@ -18,6 +18,7 @@ module Parse
18
18
  @application_id = data[:application_id]
19
19
  @api_key = data[:api_key]
20
20
  @session = Patron::Session.new
21
+ @session.timeout = 10
21
22
 
22
23
  @session.base_url = "https://#{host}"
23
24
  @session.headers["Content-Type"] = "application/json"
@@ -42,9 +43,9 @@ module Parse
42
43
 
43
44
  response = @session.request(method, uri, {}, options)
44
45
  if response.status >= 400
45
- raise ParseProtocolError, response
46
+ raise ParseError, "#{JSON.parse(response.body)['code']}: #{JSON.parse(response.body)['error']}"
46
47
  else
47
- if response.body
48
+ if response
48
49
  return JSON.parse response.body
49
50
  end
50
51
  end
@@ -79,9 +80,15 @@ module Parse
79
80
  # Initialize the singleton instance of Client which is used
80
81
  # by all API methods. Parse.init must be called before saving
81
82
  # or retrieving any objects.
82
- def Parse.init(data)
83
+ def Parse.init(data = {:application_id => ENV["PARSE_APPLICATION_ID"], :api_key => ENV["PARSE_REST_API_KEY"]})
83
84
  @@client = Client.new(data)
84
85
  end
86
+
87
+ # Used mostly for testing. Lets you delete the api key global vars.
88
+ def Parse.destroy
89
+ @@client = nil
90
+ self
91
+ end
85
92
 
86
93
  def Parse.client
87
94
  if !@@client
@@ -60,15 +60,77 @@ module Parse
60
60
 
61
61
  def initialize(data)
62
62
  bytes = data["base64"]
63
- value = Base64.decode(bytes)
63
+ @value = Base64.decode64(bytes)
64
64
  end
65
65
 
66
66
  def to_json(*a)
67
67
  {
68
68
  Protocol::KEY_TYPE => Protocol::TYPE_BYTES,
69
- "base64" => Base64.encode(@value)
69
+ "base64" => Base64.encode64(@value)
70
70
  }.to_json(*a)
71
71
  end
72
72
  end
73
+
74
+ # Increment and Decrement
75
+ # ------------------------------------------------------------
76
+
77
+ class Increment
78
+ # '{"score": {"__op": "Increment", "amount": 1 } }'
79
+ attr_accessor :amount
80
+
81
+ def initialize(amount)
82
+ @amount = amount
83
+ end
84
+
85
+ def to_json(*a)
86
+ {
87
+ Protocol::KEY_OP => Protocol::KEY_INCREMENT,
88
+ Protocol::KEY_AMOUNT => @amount
89
+ }.to_json(*a)
90
+ end
91
+ end
92
+
93
+ class Decrement
94
+ # '{"score": {"__op": "Decrement", "amount": 1 } }'
95
+ attr_accessor :amount
96
+
97
+ def initialize(amount)
98
+ @amount = amount
99
+ end
100
+
101
+ def to_json(*a)
102
+ {
103
+ Protocol::KEY_OP => Protocol::KEY_DECREMENT,
104
+ Protocol::KEY_AMOUNT => @amount
105
+ }.to_json(*a)
106
+ end
107
+ end
108
+
109
+ # GeoPoint
110
+ # ------------------------------------------------------------
111
+
112
+ class GeoPoint
113
+ # '{"location": {"__type":"GeoPoint", "latitude":40.0, "longitude":-30.0}}'
114
+ attr_accessor :longitude, :latitude
115
+
116
+ def initialize(data)
117
+ @longitude = data["longitude"]
118
+ @latitude = data["latitude"]
119
+
120
+ if !@longitude && !@latitude
121
+ @longitude = data[:longitude]
122
+ @latitude = data[:latitude]
123
+ end
124
+ end
125
+
126
+ def to_json(*a)
127
+ {
128
+ Protocol::KEY_TYPE => Protocol::TYPE_GEOPOINT,
129
+ "latitude" => @latitude,
130
+ "longitude" => @longitude
131
+ }.to_json(*a)
132
+ end
133
+ end
134
+
73
135
 
74
136
  end
data/lib/parse/error.rb CHANGED
@@ -3,7 +3,7 @@ module Parse
3
3
  # Base exception class for errors thrown by the Parse
4
4
  # client library. ParseError will be raised by any
5
5
  # network operation if Parse.init() has not been called.
6
- class ParseError < Exception
6
+ class ParseError < StandardError #Exception ... why? A:http://www.skorks.com/2009/09/ruby-exceptions-and-exception-handling/
7
7
  end
8
8
 
9
9
  # An exception class raised when the REST API returns an error.
@@ -15,12 +15,14 @@ module Parse
15
15
  attr_accessor :response
16
16
 
17
17
  def initialize(response)
18
- @response = response
19
- if response.body
20
- data = JSON.parse response.body
21
- @code = data["code"]
22
- @message = data["error"]
23
- end
18
+ #@response = response
19
+ #if response.body
20
+ # data = JSON.parse response.body
21
+ # @code = data["code"]
22
+ # @message = data["error"]
23
+ #end
24
+
25
+ #{}"#{@code}: #{@message}"
24
26
  end
25
27
  end
26
28
 
data/lib/parse/object.rb CHANGED
@@ -28,7 +28,7 @@ module Parse
28
28
 
29
29
  # Merge a hash parsed from the JSON representation into
30
30
  # this instance. This will extract the reserved fields,
31
- # merge the hash keys, and then insure that the reserved
31
+ # merge the hash keys, and then ensure that the reserved
32
32
  # fields do not occur in the underlying hash storage.
33
33
  def parse(data)
34
34
  if !data
@@ -45,14 +45,16 @@ module Parse
45
45
  @updated_at = DateTime.parse data[Protocol::KEY_UPDATED_AT]
46
46
  end
47
47
 
48
- data.each { |k,v|
49
- if k.is_a? Symbol
50
- k = k.to_s
51
- end
52
- if !Protocol::RESERVED_KEYS.include? k
53
- self[k] = v
54
- end
55
- }
48
+ self.merge! data
49
+
50
+ #data.each { |k,v|
51
+ # if k.is_a? Symbol
52
+ # k = k.to_s
53
+ # end
54
+ # if !Protocol::RESERVED_KEYS.include? k
55
+ # self[k] = v
56
+ # end
57
+ #}
56
58
  end
57
59
  private :parse
58
60
 
@@ -61,6 +63,7 @@ module Parse
61
63
  # a new object, otherwise it will update the existing stored object.
62
64
  def save
63
65
  method = @parse_object_id ? :put : :post
66
+ Protocol::RESERVED_KEYS.each { |k| self.delete(k) }
64
67
  body = self.to_json
65
68
 
66
69
  data = Parse.client.request(self.uri, method, body)
@@ -92,26 +95,34 @@ module Parse
92
95
 
93
96
  # Increment the given field by an amount, which defaults to 1.
94
97
  def increment(field, amount = 1)
95
- value = (self[field] || 0) + amount
96
- self[field] = value
97
- if !@parse_object_id
98
- # TODO - warn that the object must be stored first
99
- return nil
100
- end
101
-
102
- if amount != 0
103
- op = amount > 0 ? Protocol::OP_INCREMENT : Protocol::OP_DECREMENT
104
- body = "{\"#{field}\": {\"#{Protocol::KEY_OP}\": \"#{op}\", \"#{Protocol::KEY_AMOUNT}\" : #{amount.abs}}}"
105
- data = Parse.client.request( self.uri, :put, body)
106
- parse data
107
- end
98
+ #value = (self[field] || 0) + amount
99
+ #self[field] = value
100
+ #if !@parse_object_id
101
+ # # TODO - warn that the object must be stored first
102
+ # return nil
103
+ #end
104
+
105
+ #if amount != 0
106
+ # op = amount > 0 ? Protocol::OP_INCREMENT : Protocol::OP_DECREMENT
107
+ # body = "{\"#{field}\": {\"#{Protocol::KEY_OP}\": \"#{op}\", \"#{Protocol::KEY_AMOUNT}\" : #{amount.abs}}}"
108
+ # data = Parse.client.request( self.uri, :put, body)
109
+ # parse data
110
+ #end
111
+ #self
112
+ body = {field => Parse::Increment.new(amount)}.to_json
113
+ data = Parse.client.request(self.uri, :put, body)
114
+ parse data
108
115
  self
109
116
  end
110
117
 
111
118
  # Decrement the given field by an amount, which defaults to 1.
112
119
  # A synonym for increment(field, -amount).
113
120
  def decrement(field, amount = 1)
114
- increment field, -amount
121
+ #increment field, -amount
122
+ body = {field => Parse::Decrement.new(amount)}.to_json
123
+ data = Parse.client.request(self.uri, :put, body)
124
+ parse data
125
+ self
115
126
  end
116
127
 
117
128
  end
@@ -49,6 +49,8 @@ module Parse
49
49
  # The JSON key used to identify an operator in the increment/decrement
50
50
  # API call.
51
51
  KEY_OP = "__op"
52
+ KEY_INCREMENT = "Increment"
53
+ KEY_DECREMENT = "Decrement"
52
54
 
53
55
  # The JSON key used to identify the datatype of a special value.
54
56
  KEY_TYPE = "__type"
data/lib/parse/query.rb CHANGED
@@ -24,7 +24,7 @@ module Parse
24
24
  where[field] = constraint
25
25
  end
26
26
  end
27
- private :add_constraint
27
+ #private :add_constraint
28
28
 
29
29
  def eq(field, value)
30
30
  add_constraint field, value
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "parse-ruby-client"
8
- s.version = "0.0.2"
8
+ s.version = "0.0.3"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Alan deLevie", "Adam Alpern"]
12
- s.date = "2012-02-05"
12
+ s.date = "2012-02-20"
13
13
  s.description = "A simple Ruby client for the parse.com REST API"
14
14
  s.email = "adelevie@gmail.com"
15
15
  s.extra_rdoc_files = [
@@ -17,6 +17,7 @@ Gem::Specification.new do |s|
17
17
  "README.md"
18
18
  ]
19
19
  s.files = [
20
+ ".travis.yml",
20
21
  "Gemfile",
21
22
  "Gemfile.lock",
22
23
  "LICENSE.txt",
@@ -34,11 +35,14 @@ Gem::Specification.new do |s|
34
35
  "lib/parse/util.rb",
35
36
  "parse-ruby-client.gemspec",
36
37
  "pkg/parse-ruby-client-0.0.1.gem",
38
+ "pkg/parse-ruby-client-0.0.2.gem",
37
39
  "pkg/parse-ruby-client-1-0.0.1.gem",
38
40
  "pkg/parse-ruby-client.gem",
39
41
  "test/helper.rb",
40
42
  "test/test_client.rb",
41
- "test/test_parse-ruby-client.rb"
43
+ "test/test_datatypes.rb",
44
+ "test/test_init.rb",
45
+ "test/test_query.rb"
42
46
  ]
43
47
  s.homepage = "http://github.com/adelevie/parse-ruby-client"
44
48
  s.licenses = ["MIT"]
Binary file
data/test/test_client.rb CHANGED
@@ -1,7 +1,32 @@
1
1
  require 'helper'
2
2
 
3
3
  class TestClient < Test::Unit::TestCase
4
- should "probably rename this file and start testing for real" do
5
- flunk "hey buddy, you should probably rename this file and start testing for real"
4
+ def setup
5
+ Parse.init
6
+ end
7
+
8
+ def test_simple_save
9
+ test_save = Parse::Object.new "TestSave"
10
+ test_save["foo"] = "bar"
11
+ test_save.save
12
+
13
+ assert_equal test_save["foo"], "bar"
14
+ assert_equal test_save[Parse::Protocol::KEY_CREATED_AT].class, String
15
+ assert_equal test_save[Parse::Protocol::KEY_OBJECT_ID].class, String
16
+ end
17
+
18
+ def test_update
19
+ foo = Parse::Object.new "TestSave"
20
+ foo["age"] = 20
21
+ foo.save
22
+
23
+ assert_equal foo["age"], 20
24
+ assert_equal foo[Parse::Protocol::KEY_UPDATED_AT], nil
25
+
26
+ foo["age"] = 40
27
+ foo.save
28
+
29
+ assert_equal foo["age"], 40
30
+ assert_equal foo[Parse::Protocol::KEY_UPDATED_AT].class, String
6
31
  end
7
32
  end
@@ -0,0 +1,60 @@
1
+ require 'helper'
2
+
3
+ class TestDatatypes < Test::Unit::TestCase
4
+ def test_pointer
5
+ data = {
6
+ Parse::Protocol::KEY_CLASS_NAME => "DatatypeTestClass",
7
+ Parse::Protocol::KEY_OBJECT_ID => "12345abcd"
8
+ }
9
+ p = Parse::Pointer.new data
10
+
11
+ assert_equal p.to_json, "{\"__type\":\"Pointer\",\"#{Parse::Protocol::KEY_CLASS_NAME}\":\"DatatypeTestClass\",\"#{Parse::Protocol::KEY_OBJECT_ID}\":\"12345abcd\"}"
12
+ end
13
+
14
+ def test_date
15
+ date_time = DateTime.now
16
+ data = date_time
17
+ parse_date = Parse::Date.new data
18
+
19
+ assert_equal parse_date.value, date_time
20
+ assert_equal JSON.parse(parse_date.to_json)["iso"], date_time.iso8601
21
+ end
22
+
23
+ def test_bytes
24
+ data = {
25
+ "base64" => Base64.encode64("testing bytes!")
26
+ }
27
+ byte = Parse::Bytes.new data
28
+
29
+ assert_equal byte.value, "testing bytes!"
30
+ assert_equal JSON.parse(byte.to_json)[Parse::Protocol::KEY_TYPE], Parse::Protocol::TYPE_BYTES
31
+ assert_equal JSON.parse(byte.to_json)["base64"], Base64.encode64("testing bytes!")
32
+ end
33
+
34
+ def test_increment
35
+ amount = 5
36
+ increment = Parse::Increment.new amount
37
+
38
+ assert_equal increment.to_json, "{\"__op\":\"Increment\",\"amount\":#{amount}}"
39
+ end
40
+
41
+ def test_decrement
42
+ amount = 5
43
+ increment = Parse::Decrement.new amount
44
+
45
+ assert_equal increment.to_json, "{\"__op\":\"Decrement\",\"amount\":#{amount}}"
46
+ end
47
+
48
+ def test_geopoint
49
+ # '{"location": {"__type":"GeoPoint", "latitude":40.0, "longitude":-30.0}}'
50
+ data = {
51
+ "longitude" => 40.0,
52
+ "latitude" => -30.0
53
+ }
54
+ gp = Parse::GeoPoint.new data
55
+
56
+ assert_equal JSON.parse(gp.to_json)["longitude"], data["longitude"]
57
+ assert_equal JSON.parse(gp.to_json)["latitude"], data["latitude"]
58
+ assert_equal JSON.parse(gp.to_json)[Parse::Protocol::KEY_TYPE], Parse::Protocol::TYPE_GEOPOINT
59
+ end
60
+ end
data/test/test_init.rb ADDED
@@ -0,0 +1,23 @@
1
+ require 'helper'
2
+
3
+ #Parse.init :application_id => $PARSE_APPLICATION_ID, :api_key => $PARSE_REST_API_KEY
4
+
5
+ class TestInit < Test::Unit::TestCase
6
+ def setup
7
+ Parse.destroy
8
+ end
9
+
10
+ def test_no_api_keys_error
11
+ fake = Parse::Object.new "shouldNeverExist"
12
+ fake["foo"] = "bar"
13
+
14
+ begin
15
+ fake.save
16
+ rescue
17
+ error_triggered = true
18
+ end
19
+
20
+ assert_equal error_triggered, true
21
+ assert_equal fake[Parse::Protocol::KEY_OBJECT_ID], nil
22
+ end
23
+ end
@@ -0,0 +1,26 @@
1
+ require 'helper'
2
+
3
+ Parse.init
4
+
5
+ class TestQuery < Test::Unit::TestCase
6
+ def test_add_contraint
7
+ # I know this method *should* be private.
8
+ # But then it would be a PITA to test.
9
+ # I'd rather test this one method than pointlessly test many others.
10
+ # Thus is life.
11
+
12
+ q = Parse::Query.new "TestQuery"
13
+ q.add_constraint("points", 5)
14
+ assert_equal q.where["points"], 5
15
+ q.add_constraint("player", { "$regex" => "regex voodoo"})
16
+ assert_equal q.where["player"], { "$regex" => "regex voodoo"}
17
+ end
18
+
19
+ def test_eq
20
+ q = Parse::Query.new "TestQuery"
21
+ q.eq("points", 5)
22
+ assert_equal q.where, {"points" => 5}
23
+ q.eq("player", "michael@jordan.com")
24
+ assert_equal q.where, {"points" => 5, "player" => "michael@jordan.com"}
25
+ end
26
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: parse-ruby-client
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,11 +10,11 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2012-02-05 00:00:00.000000000Z
13
+ date: 2012-02-20 00:00:00.000000000Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: patron
17
- requirement: &70137258765420 !ruby/object:Gem::Requirement
17
+ requirement: &70330439891380 !ruby/object:Gem::Requirement
18
18
  none: false
19
19
  requirements:
20
20
  - - ! '>='
@@ -22,10 +22,10 @@ dependencies:
22
22
  version: '0'
23
23
  type: :runtime
24
24
  prerelease: false
25
- version_requirements: *70137258765420
25
+ version_requirements: *70330439891380
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: shoulda
28
- requirement: &70137258764800 !ruby/object:Gem::Requirement
28
+ requirement: &70330439890500 !ruby/object:Gem::Requirement
29
29
  none: false
30
30
  requirements:
31
31
  - - ! '>='
@@ -33,10 +33,10 @@ dependencies:
33
33
  version: '0'
34
34
  type: :development
35
35
  prerelease: false
36
- version_requirements: *70137258764800
36
+ version_requirements: *70330439890500
37
37
  - !ruby/object:Gem::Dependency
38
38
  name: bundler
39
- requirement: &70137258740360 !ruby/object:Gem::Requirement
39
+ requirement: &70330439889720 !ruby/object:Gem::Requirement
40
40
  none: false
41
41
  requirements:
42
42
  - - ~>
@@ -44,10 +44,10 @@ dependencies:
44
44
  version: 1.0.0
45
45
  type: :development
46
46
  prerelease: false
47
- version_requirements: *70137258740360
47
+ version_requirements: *70330439889720
48
48
  - !ruby/object:Gem::Dependency
49
49
  name: jeweler
50
- requirement: &70137258739700 !ruby/object:Gem::Requirement
50
+ requirement: &70330439889080 !ruby/object:Gem::Requirement
51
51
  none: false
52
52
  requirements:
53
53
  - - ~>
@@ -55,10 +55,10 @@ dependencies:
55
55
  version: 1.6.4
56
56
  type: :development
57
57
  prerelease: false
58
- version_requirements: *70137258739700
58
+ version_requirements: *70330439889080
59
59
  - !ruby/object:Gem::Dependency
60
60
  name: rcov
61
- requirement: &70137258738920 !ruby/object:Gem::Requirement
61
+ requirement: &70330439888560 !ruby/object:Gem::Requirement
62
62
  none: false
63
63
  requirements:
64
64
  - - ! '>='
@@ -66,7 +66,7 @@ dependencies:
66
66
  version: '0'
67
67
  type: :development
68
68
  prerelease: false
69
- version_requirements: *70137258738920
69
+ version_requirements: *70330439888560
70
70
  description: A simple Ruby client for the parse.com REST API
71
71
  email: adelevie@gmail.com
72
72
  executables: []
@@ -75,6 +75,7 @@ extra_rdoc_files:
75
75
  - LICENSE.txt
76
76
  - README.md
77
77
  files:
78
+ - .travis.yml
78
79
  - Gemfile
79
80
  - Gemfile.lock
80
81
  - LICENSE.txt
@@ -92,11 +93,14 @@ files:
92
93
  - lib/parse/util.rb
93
94
  - parse-ruby-client.gemspec
94
95
  - pkg/parse-ruby-client-0.0.1.gem
96
+ - pkg/parse-ruby-client-0.0.2.gem
95
97
  - pkg/parse-ruby-client-1-0.0.1.gem
96
98
  - pkg/parse-ruby-client.gem
97
99
  - test/helper.rb
98
100
  - test/test_client.rb
99
- - test/test_parse-ruby-client.rb
101
+ - test/test_datatypes.rb
102
+ - test/test_init.rb
103
+ - test/test_query.rb
100
104
  homepage: http://github.com/adelevie/parse-ruby-client
101
105
  licenses:
102
106
  - MIT
@@ -112,7 +116,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
112
116
  version: '0'
113
117
  segments:
114
118
  - 0
115
- hash: -1562453630510493430
119
+ hash: -4138204071645448362
116
120
  required_rubygems_version: !ruby/object:Gem::Requirement
117
121
  none: false
118
122
  requirements:
@@ -1,7 +0,0 @@
1
- require 'helper'
2
-
3
- class TestParseRubyClient < Test::Unit::TestCase
4
- should "probably rename this file and start testing for real" do
5
- flunk "hey buddy, you should probably rename this file and start testing for real"
6
- end
7
- end