parsecom 0.0.1
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.
- data/.gitignore +19 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +139 -0
- data/Rakefile +1 -0
- data/lib/parse/client.rb +161 -0
- data/lib/parse/cloud_code.rb +2 -0
- data/lib/parse/ext/string.rb +11 -0
- data/lib/parse/file.rb +36 -0
- data/lib/parse/http_client.rb +23 -0
- data/lib/parse/object.rb +176 -0
- data/lib/parse/pointer.rb +25 -0
- data/lib/parse/query.rb +286 -0
- data/lib/parse/user.rb +47 -0
- data/lib/parse/version.rb +3 -0
- data/lib/parsecom.rb +58 -0
- data/parsecom.gemspec +21 -0
- data/spec/parse_object_spec.rb +54 -0
- data/spec/parse_query_spec.rb +176 -0
- data/spec/parse_user_spec.rb +23 -0
- data/spec/spec_helper.rb +14 -0
- metadata +87 -0
data/lib/parse/query.rb
ADDED
@@ -0,0 +1,286 @@
|
|
1
|
+
module Parse
|
2
|
+
class Query
|
3
|
+
attr_reader :keys
|
4
|
+
attr_accessor :parse_class_name, :parse_client
|
5
|
+
|
6
|
+
def initialize parse_class_or_name=nil
|
7
|
+
@parse_class, @parse_class_name, @parse_client =
|
8
|
+
parse_class_or_name === Parse::Object \
|
9
|
+
? [parse_class_or_name, parse_class_or_name.parse_class_name,
|
10
|
+
parse_class_or_name.parse_client]
|
11
|
+
: [nil, parse_class_or_name.to_s, Parse::Client.default_client]
|
12
|
+
@limit = nil
|
13
|
+
@skip = nil
|
14
|
+
@count = false
|
15
|
+
@where = []
|
16
|
+
@order = []
|
17
|
+
@include = []
|
18
|
+
@keys = []
|
19
|
+
end
|
20
|
+
|
21
|
+
def invoke &block
|
22
|
+
block = proc do |body|
|
23
|
+
# TODO: should handle error
|
24
|
+
body['results']
|
25
|
+
end unless block
|
26
|
+
endpoint = %w(User).include?(@parse_class_name) \
|
27
|
+
? "#{@parse_class_name.lowercase}s"
|
28
|
+
: "classes/#{@parse_class_name}"
|
29
|
+
@parse_client.call_api :get, "#{endpoint}?#{to_params}", nil, &block
|
30
|
+
end
|
31
|
+
|
32
|
+
def limit val=nil
|
33
|
+
if val
|
34
|
+
@limit = val
|
35
|
+
else
|
36
|
+
@limit
|
37
|
+
end
|
38
|
+
self
|
39
|
+
end
|
40
|
+
|
41
|
+
def skip val=nil
|
42
|
+
if val
|
43
|
+
@skip = val
|
44
|
+
else
|
45
|
+
@skip
|
46
|
+
end
|
47
|
+
self
|
48
|
+
end
|
49
|
+
|
50
|
+
def count val=nil
|
51
|
+
if val
|
52
|
+
@count = val
|
53
|
+
else
|
54
|
+
@count
|
55
|
+
end
|
56
|
+
self
|
57
|
+
end
|
58
|
+
|
59
|
+
def where hash=nil, &block
|
60
|
+
return @where if hash.nil? && block.nil?
|
61
|
+
|
62
|
+
if hash.is_a? Hash
|
63
|
+
hash.each do |k, v|
|
64
|
+
@where << %Q|"#{k}":"#{v}"|
|
65
|
+
end
|
66
|
+
else
|
67
|
+
block = hash if hash.is_a?(Proc) && block.nil?
|
68
|
+
instance_eval &block if block
|
69
|
+
end
|
70
|
+
self
|
71
|
+
end
|
72
|
+
|
73
|
+
def order *vals
|
74
|
+
return @order if vals.empty?
|
75
|
+
@order += vals
|
76
|
+
self
|
77
|
+
end
|
78
|
+
alias order_asc order
|
79
|
+
|
80
|
+
def order_desc *vals
|
81
|
+
order *(vals.map do |val|
|
82
|
+
val[0] == '-' ? val[1..-1] : "-#{val}"
|
83
|
+
end)
|
84
|
+
end
|
85
|
+
|
86
|
+
def keys *vals
|
87
|
+
return @keys if vals.empty?
|
88
|
+
@keys += vals
|
89
|
+
self
|
90
|
+
end
|
91
|
+
|
92
|
+
def include *vals
|
93
|
+
return @include if vals.empty?
|
94
|
+
@include += vals
|
95
|
+
end
|
96
|
+
|
97
|
+
def to_params
|
98
|
+
params = []
|
99
|
+
|
100
|
+
where = @where.join ','
|
101
|
+
order = @order.join ','
|
102
|
+
keys = @keys.join ','
|
103
|
+
include = @include.join ','
|
104
|
+
params.push "where=#{URI.encode "{#{where}}"}" unless where.empty?
|
105
|
+
params.push "order=#{URI.encode order}" unless order.empty?
|
106
|
+
params.push "keys=#{URI.encode keys}" unless keys.empty?
|
107
|
+
params.push "include=#{URI.encode include}" unless include.empty?
|
108
|
+
params.push "skip=#{URI.encode @skip.to_s}" if @skip
|
109
|
+
params.push "limit=#{URI.encode @limit.to_s}" if @limit
|
110
|
+
|
111
|
+
params.join '&'
|
112
|
+
end
|
113
|
+
|
114
|
+
def inspect
|
115
|
+
"#{@parse_class_name}, #{to_params}"
|
116
|
+
end
|
117
|
+
|
118
|
+
private
|
119
|
+
|
120
|
+
def column name
|
121
|
+
Condition.new(self, name).tap do |condition|
|
122
|
+
@where.push condition
|
123
|
+
end
|
124
|
+
end
|
125
|
+
alias _ column
|
126
|
+
|
127
|
+
def subquery_for parse_class_name
|
128
|
+
Subquery.new parse_class_name
|
129
|
+
end
|
130
|
+
|
131
|
+
def or_condition *conds
|
132
|
+
conds.each do |cond|
|
133
|
+
@where.delete cond
|
134
|
+
end
|
135
|
+
OrCondition.new(conds).tap do |condition|
|
136
|
+
@where.push condition
|
137
|
+
end
|
138
|
+
end
|
139
|
+
alias _or_ or_condition
|
140
|
+
|
141
|
+
class Subquery < Query
|
142
|
+
attr_accessor :parent
|
143
|
+
|
144
|
+
def initialize parse_class_name=nil
|
145
|
+
super
|
146
|
+
@key = nil
|
147
|
+
end
|
148
|
+
|
149
|
+
def key= val
|
150
|
+
@key = val
|
151
|
+
self
|
152
|
+
end
|
153
|
+
alias key key=
|
154
|
+
|
155
|
+
def inspect
|
156
|
+
# TODO should be refactored
|
157
|
+
case @parent
|
158
|
+
when :select
|
159
|
+
%Q|{"query":{"className":#{parse_class_name.to_s.inspect},"where":{#{@where.join ','}}},"key":#{@key.inspect}}|
|
160
|
+
when :in_query, :not_in_query
|
161
|
+
%Q|{"where":{#{@where.join ','}},"className":#{parse_class_name.to_s.inspect}}|
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
class Condition
|
167
|
+
def initialize query, column_name
|
168
|
+
@query = query
|
169
|
+
@column_name = column_name
|
170
|
+
@conditions = []
|
171
|
+
end
|
172
|
+
|
173
|
+
# receive nop
|
174
|
+
%w(eq contains).each do |op|
|
175
|
+
eval %Q{
|
176
|
+
def #{op} val
|
177
|
+
@conditions.push val
|
178
|
+
self
|
179
|
+
end
|
180
|
+
}
|
181
|
+
end
|
182
|
+
alias equal_to eq
|
183
|
+
|
184
|
+
# receive single param
|
185
|
+
%w(lt lte gt gte ne).each do |op|
|
186
|
+
eval %Q{
|
187
|
+
def #{op} val
|
188
|
+
@conditions.push ['$#{op}', val]
|
189
|
+
self
|
190
|
+
end
|
191
|
+
}
|
192
|
+
end
|
193
|
+
alias less_than lt
|
194
|
+
alias less_that_or_equal_to lte
|
195
|
+
alias greater_than gt
|
196
|
+
alias greater_that_or_equal_to gte
|
197
|
+
alias not_equal_to ne
|
198
|
+
|
199
|
+
def exists val=true
|
200
|
+
@conditions.push ['$exists', val]
|
201
|
+
self
|
202
|
+
end
|
203
|
+
|
204
|
+
# receive multi params
|
205
|
+
%w(in nin all).each do |op|
|
206
|
+
eval %Q{
|
207
|
+
def #{op} *vals
|
208
|
+
@conditions.push ['$#{op}', vals]
|
209
|
+
self
|
210
|
+
end
|
211
|
+
}
|
212
|
+
end
|
213
|
+
alias not_in nin
|
214
|
+
|
215
|
+
# receive subquery
|
216
|
+
%w(select dont_select in_query not_in_query).each do |op|
|
217
|
+
eval %Q{
|
218
|
+
def #{op} subquery
|
219
|
+
subquery.parent = :#{op}
|
220
|
+
@conditions.push ['$#{op.camelize :lower}', subquery]
|
221
|
+
self
|
222
|
+
end
|
223
|
+
}
|
224
|
+
end
|
225
|
+
|
226
|
+
def or cond
|
227
|
+
# quite dirty!!
|
228
|
+
@query.where.delete self
|
229
|
+
@query.where.delete cond
|
230
|
+
or_cond = Condition.new @query, '$or'
|
231
|
+
or_cond.eq [self, cond]
|
232
|
+
@query.where.push or_cond
|
233
|
+
end
|
234
|
+
|
235
|
+
def to_s
|
236
|
+
if @conditions.size == 1 && !@conditions[0].is_a?(Array)
|
237
|
+
"#{@column_name.to_s.inspect}:#{condition_to_s @conditions[0]}"
|
238
|
+
elsif @conditions.size == 1 && @conditions[0][0].to_s[0] != '$'
|
239
|
+
# $or
|
240
|
+
"#{@column_name.to_s.inspect}:#{condition_to_s @conditions[0]}"
|
241
|
+
else
|
242
|
+
"#{@column_name.to_s.inspect}:{#{@conditions.map{|c| condition_to_s c}.join ','}}"
|
243
|
+
end
|
244
|
+
end
|
245
|
+
|
246
|
+
private
|
247
|
+
|
248
|
+
def condition_value_to_s val
|
249
|
+
case val
|
250
|
+
when Parse::Object
|
251
|
+
%Q|{"__type":"Pointer","className":"#{val.parse_class_name}","objectId":"#{val.obj_id}"}|
|
252
|
+
else
|
253
|
+
val.inspect
|
254
|
+
end
|
255
|
+
end
|
256
|
+
|
257
|
+
def condition_to_s condition
|
258
|
+
case condition
|
259
|
+
when Array
|
260
|
+
if condition[0].to_s[0] == '$'
|
261
|
+
"#{condition[0].inspect}:#{condition_value_to_s condition[1]}"
|
262
|
+
else
|
263
|
+
# $or
|
264
|
+
"[#{condition.map{|c| "{#{condition_value_to_s c}}"}.join ','}]"
|
265
|
+
end
|
266
|
+
else
|
267
|
+
condition_value_to_s condition
|
268
|
+
end
|
269
|
+
end
|
270
|
+
end
|
271
|
+
|
272
|
+
class OrCondition
|
273
|
+
def initialize conds
|
274
|
+
@conditions = conds
|
275
|
+
end
|
276
|
+
|
277
|
+
def to_s
|
278
|
+
%Q|"$or":[#{@conditions.map {|c| "{#{c.to_s}}"}.join ','}]|
|
279
|
+
end
|
280
|
+
end
|
281
|
+
end
|
282
|
+
|
283
|
+
def Query parse_class_name=nil
|
284
|
+
Query.new parse_class_name
|
285
|
+
end
|
286
|
+
end
|
data/lib/parse/user.rb
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
# coding:utf-8
|
2
|
+
module Parse
|
3
|
+
class User < Object
|
4
|
+
|
5
|
+
class << self
|
6
|
+
def sign_up username, password, hash={}
|
7
|
+
self.new(username, password, hash).sign_up
|
8
|
+
end
|
9
|
+
|
10
|
+
def log_in username, password
|
11
|
+
self.new(username, password).log_in
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def initialize username, password, hash={}
|
16
|
+
super hash
|
17
|
+
@username = username
|
18
|
+
@password = password
|
19
|
+
end
|
20
|
+
|
21
|
+
def sign_up
|
22
|
+
parse_client.sign_up @username, @password, opts do |resp_body|
|
23
|
+
@obj_id = resp_body['objectId']
|
24
|
+
@created_at = resp_body['createdAt']
|
25
|
+
@raw_hash.update(@updated_hash).update resp_body
|
26
|
+
@updated_hash.clear
|
27
|
+
parse_client.session_token = resp_body['sessionToken']
|
28
|
+
self
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def log_in
|
33
|
+
parse_client.log_in @username, @password do |resp_body|
|
34
|
+
@obj_id = resp_body['objectId']
|
35
|
+
@created_at = resp_body['createdAt']
|
36
|
+
@updated_at = resp_body['updatedAt']
|
37
|
+
@raw_hash.update(@updated_hash).update resp_body
|
38
|
+
@updated_hash.clear
|
39
|
+
parse_client.session_token = resp_body['sessionToken']
|
40
|
+
self
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def log_out
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
data/lib/parsecom.rb
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
# coding:utf-8
|
2
|
+
require "parse/version"
|
3
|
+
|
4
|
+
require 'open-uri'
|
5
|
+
require 'fileutils'
|
6
|
+
require 'json'
|
7
|
+
require 'date'
|
8
|
+
require 'net/https'
|
9
|
+
require 'uri'
|
10
|
+
require 'parse/ext/string'
|
11
|
+
require 'parse/http_client'
|
12
|
+
require 'parse/client'
|
13
|
+
require 'parse/query'
|
14
|
+
require 'parse/object'
|
15
|
+
require 'parse/user'
|
16
|
+
require 'parse/pointer'
|
17
|
+
require 'parse/file'
|
18
|
+
|
19
|
+
module Parse
|
20
|
+
@@application_id = nil
|
21
|
+
@@api_key = nil
|
22
|
+
@@auto_snake_case = false
|
23
|
+
|
24
|
+
module_function
|
25
|
+
|
26
|
+
def application_id
|
27
|
+
@@application_id
|
28
|
+
end
|
29
|
+
|
30
|
+
def application_id= application_id
|
31
|
+
@@application_id = application_id
|
32
|
+
end
|
33
|
+
|
34
|
+
def api_key
|
35
|
+
@@api_key
|
36
|
+
end
|
37
|
+
|
38
|
+
def api_key= api_key
|
39
|
+
@@api_key = api_key
|
40
|
+
end
|
41
|
+
|
42
|
+
def credentials hash
|
43
|
+
@@application_id = hash[:application_id]
|
44
|
+
@@api_key = hash[:api_key]
|
45
|
+
end
|
46
|
+
|
47
|
+
def credentials= hash
|
48
|
+
credentials hash
|
49
|
+
end
|
50
|
+
|
51
|
+
def auto_snake_case
|
52
|
+
@@auto_snake_case
|
53
|
+
end
|
54
|
+
|
55
|
+
def auto_snake_case= auto_snake_case
|
56
|
+
@@auto_snake_case = auto_snake_case
|
57
|
+
end
|
58
|
+
end
|
data/parsecom.gemspec
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'parse/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |gem|
|
7
|
+
gem.name = "parsecom"
|
8
|
+
gem.version = Parse::VERSION
|
9
|
+
gem.authors = ["Ando Yasushi"]
|
10
|
+
gem.email = ["andyjpn@gmail.com"]
|
11
|
+
gem.description = %q{Pure Ruby version of parse.com client. This library allow you to access straightforwardly to parse.com REST API.}
|
12
|
+
gem.summary = %q{Pure Ruby version of parse.com client}
|
13
|
+
gem.homepage = "https://github.com/technohippy/parsecom"
|
14
|
+
|
15
|
+
gem.files = `git ls-files`.split($/)
|
16
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
17
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
18
|
+
gem.require_paths = ["lib"]
|
19
|
+
|
20
|
+
gem.add_development_dependency "rspec"
|
21
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
# coding:utf-8
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
# define a parse class
|
5
|
+
class ClassA < Parse::Object; end
|
6
|
+
# you can also write:
|
7
|
+
# Parse::Object(:ClassA)
|
8
|
+
# or
|
9
|
+
# Parse::Object.create :ClassA
|
10
|
+
|
11
|
+
describe Parse::Object, 'when it defines a parse class' do
|
12
|
+
it 'should return a new class' do
|
13
|
+
Parse::Object(:ClassB).should be_a_kind_of(Class)
|
14
|
+
ClassB.should be < Parse::Object
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'should return the existing class' do
|
18
|
+
Parse::Object(:ClassA).should == ClassA
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'should also return a new class' do
|
22
|
+
Parse::Object.create :ClassC
|
23
|
+
ClassC.should be_a_kind_of(Class)
|
24
|
+
ClassC.should be < Parse::Object
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'should raise an error when creating an existing class' do
|
28
|
+
expect {
|
29
|
+
Parse::Object.create :ClassB
|
30
|
+
}.to raise_error
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe Parse::Object, 'when it creates a new parse object' do
|
35
|
+
it 'should create a parse object' do
|
36
|
+
class_a = ClassA.new
|
37
|
+
class_a.columnA = 'Hello, parse.com'
|
38
|
+
class_a.new?.should be_true
|
39
|
+
class_a.save
|
40
|
+
class_a.new?.should be_false
|
41
|
+
|
42
|
+
class_a2 = ClassA.find class_a.obj_id
|
43
|
+
class_a2.columnA.should eql('Hello, parse.com')
|
44
|
+
|
45
|
+
class_as = ClassA.find :where => proc{column(:columnB).gt 5},
|
46
|
+
:order => 'createdAt', :keys => 'columnB', :limit => 3
|
47
|
+
class_as.size.should == 3
|
48
|
+
|
49
|
+
class_a = ClassA.find :where => {'objectId' => 'avp6UKaG1k'},
|
50
|
+
:order => 'createdAt', :keys => 'columnB', :limit => 3
|
51
|
+
class_a.size.should == 1
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
@@ -0,0 +1,176 @@
|
|
1
|
+
# coding:utf-8
|
2
|
+
require 'spec_helper'
|
3
|
+
require 'parsecom'
|
4
|
+
|
5
|
+
describe Parse::Query, 'when it builds conditions' do
|
6
|
+
it 'should build a correct "where" parameter' do
|
7
|
+
query = Parse::Query.new ClassA
|
8
|
+
query.to_params.should be_empty
|
9
|
+
|
10
|
+
query.where :column1 => 'val1'
|
11
|
+
query.to_params.should have_params('where' => '{"column1":"val1"}')
|
12
|
+
|
13
|
+
query.where.clear
|
14
|
+
query.to_params.should be_empty
|
15
|
+
|
16
|
+
query.where :column1 => 'val1', :column2 => 'val2'
|
17
|
+
query.to_params.should have_params('where' => '{"column1":"val1","column2":"val2"}')
|
18
|
+
|
19
|
+
query.where :column3 => 'val3'
|
20
|
+
query.to_params.should have_params('where' => '{"column1":"val1","column2":"val2","column3":"val3"}')
|
21
|
+
|
22
|
+
query.where.clear
|
23
|
+
|
24
|
+
query.where do
|
25
|
+
column(:playerName).eq('Sean Plott')
|
26
|
+
column(:cheatMode).eq(false)
|
27
|
+
end
|
28
|
+
query.to_params.should have_params('where' => '{"playerName":"Sean Plott","cheatMode":false}')
|
29
|
+
query.where.clear
|
30
|
+
|
31
|
+
query.where do
|
32
|
+
column(:score).gte(1000).lte(3000)
|
33
|
+
end
|
34
|
+
query.to_params.should have_params('where' => '{"score":{"$gte":1000,"$lte":3000}}')
|
35
|
+
query.where.clear
|
36
|
+
|
37
|
+
query.where do
|
38
|
+
column(:score).in(1, 3 ,5, 7, 9)
|
39
|
+
end
|
40
|
+
query.to_params.should have_params('where' => '{"score":{"$in":[1, 3, 5, 7, 9]}}')
|
41
|
+
query.where.clear
|
42
|
+
|
43
|
+
query.where do
|
44
|
+
column(:playerName).nin("Jonathan Walsh","Dario Wunsch","Shawn Simon")
|
45
|
+
end
|
46
|
+
query.to_params.should have_params('where' => '{"playerName":{"$nin":["Jonathan Walsh", "Dario Wunsch", "Shawn Simon"]}}')
|
47
|
+
query.where.clear
|
48
|
+
|
49
|
+
query.where do
|
50
|
+
column(:score).exists(true)
|
51
|
+
end
|
52
|
+
query.to_params.should have_params('where' => '{"score":{"$exists":true}}')
|
53
|
+
query.where.clear
|
54
|
+
|
55
|
+
query.where do
|
56
|
+
column(:score).exists(false)
|
57
|
+
end
|
58
|
+
query.to_params.should have_params('where' => '{"score":{"$exists":false}}')
|
59
|
+
query.where.clear
|
60
|
+
|
61
|
+
query.where do
|
62
|
+
subquery = subquery_for :Team
|
63
|
+
subquery.where do
|
64
|
+
column(:winPct).gt(0.5)
|
65
|
+
end
|
66
|
+
subquery.key = 'city'
|
67
|
+
column(:hometown).select(subquery)
|
68
|
+
end
|
69
|
+
query.to_params.should have_params('where' => '{"hometown":{"$select":{"query":{"className":"Team","where":{"winPct":{"$gt":0.5}}},"key":"city"}}}')
|
70
|
+
query.where.clear
|
71
|
+
|
72
|
+
query.where do
|
73
|
+
column(:arrayKey).contains(2)
|
74
|
+
end
|
75
|
+
query.to_params.should have_params('where' => '{"arrayKey":2}')
|
76
|
+
query.where.clear
|
77
|
+
|
78
|
+
query.where do
|
79
|
+
column(:arrayKey).all(2,3,4)
|
80
|
+
end
|
81
|
+
query.to_params.should have_params('where' => '{"arrayKey":{"$all":[2, 3, 4]}}')
|
82
|
+
query.where.clear
|
83
|
+
|
84
|
+
query.where do
|
85
|
+
post = Parse::Object(:Post).new :objectId => '8TOXdXf3tz'
|
86
|
+
column(:post).eq(post)
|
87
|
+
end
|
88
|
+
query.to_params.should have_params('where' => '{"post":{"__type":"Pointer","className":"Post","objectId":"8TOXdXf3tz"}}')
|
89
|
+
query.where.clear
|
90
|
+
|
91
|
+
query.where do
|
92
|
+
subquery = subquery_for :Post
|
93
|
+
subquery.where do
|
94
|
+
column(:image).exists(true)
|
95
|
+
end
|
96
|
+
column(:post).in_query(subquery)
|
97
|
+
end
|
98
|
+
query.to_params.should have_params('where' => '{"post":{"$inQuery":{"where":{"image":{"$exists":true}},"className":"Post"}}}')
|
99
|
+
query.where.clear
|
100
|
+
|
101
|
+
query.where do
|
102
|
+
subquery = subquery_for :Post
|
103
|
+
subquery.where do
|
104
|
+
column(:image).exists(true)
|
105
|
+
end
|
106
|
+
column(:post).not_in_query(subquery)
|
107
|
+
end
|
108
|
+
query.to_params.should have_params('where' => '{"post":{"$notInQuery":{"where":{"image":{"$exists":true}},"className":"Post"}}}')
|
109
|
+
query.where.clear
|
110
|
+
|
111
|
+
# query.where do
|
112
|
+
# #{
|
113
|
+
# # "$relatedTo":{
|
114
|
+
# # "object":{
|
115
|
+
# # "__type":"Pointer",
|
116
|
+
# # "className":"Post",
|
117
|
+
# # "objectId":"8TOXdXf3tz"
|
118
|
+
# # },
|
119
|
+
# # "key":"likes"
|
120
|
+
# # }
|
121
|
+
# #}
|
122
|
+
# # TODO
|
123
|
+
# end
|
124
|
+
# query.to_params.should == 'where={}'
|
125
|
+
# query.where.clear
|
126
|
+
|
127
|
+
query.where do
|
128
|
+
column(:wins).gt(150).or column(:wins).lt(5)
|
129
|
+
end
|
130
|
+
query.to_params.should have_params('where' => '{"$or":[{"wins":{"$gt":150}},{"wins":{"$lt":5}}]}')
|
131
|
+
query.where.clear
|
132
|
+
|
133
|
+
query.where do
|
134
|
+
or_condition column(:wins).gt(150), column(:wins).lt(5)
|
135
|
+
end
|
136
|
+
query.to_params.should have_params('where' => '{"$or":[{"wins":{"$gt":150}},{"wins":{"$lt":5}}]}')
|
137
|
+
query.where.clear
|
138
|
+
|
139
|
+
query.where do
|
140
|
+
or_condition column(:wins).gt(150), column(:wins).lt(5), column(:loses).lt(5)
|
141
|
+
end
|
142
|
+
query.to_params.should have_params('where' => '{"$or":[{"wins":{"$gt":150}},{"wins":{"$lt":5}},{"loses":{"$lt":5}}]}')
|
143
|
+
query.where.clear
|
144
|
+
end
|
145
|
+
|
146
|
+
it 'should build a correct "order" parameter' do
|
147
|
+
query = Parse::Query.new ClassA
|
148
|
+
query.order 'score', '-name'
|
149
|
+
query.to_params.should == 'order=score,-name'
|
150
|
+
query.order.clear
|
151
|
+
|
152
|
+
query.order_desc '-score', 'name'
|
153
|
+
query.to_params.should == 'order=score,-name'
|
154
|
+
query.order.clear
|
155
|
+
|
156
|
+
query.order 'score'
|
157
|
+
query.order_desc 'name'
|
158
|
+
query.to_params.should == 'order=score,-name'
|
159
|
+
query.order.clear
|
160
|
+
end
|
161
|
+
|
162
|
+
it 'should success request' do
|
163
|
+
query = Parse::Query.new(ClassA).
|
164
|
+
order('createdAt').
|
165
|
+
keys('columnB').
|
166
|
+
limit(3).
|
167
|
+
where {column(:columnB).gt 5}
|
168
|
+
# query.invoke
|
169
|
+
query.to_params.should have_params(
|
170
|
+
'order' => 'createdAt',
|
171
|
+
'keys' => 'columnB',
|
172
|
+
'limit' => 3,
|
173
|
+
'where' => '{"columnB":{"$gt":5}}'
|
174
|
+
)
|
175
|
+
end
|
176
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# coding:utf-8
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe Parse::User, 'when it signs up' do
|
5
|
+
it 'should create new user' do
|
6
|
+
user = Parse::User.sign_up "username#{rand 1000}", 'password'
|
7
|
+
user.obj_id.should be_an_instance_of String
|
8
|
+
user.parse_client.session_token.should be_an_instance_of String
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
describe Parse::User, 'when it logs in' do
|
13
|
+
it 'should get the session token' do
|
14
|
+
user = Parse::User.log_in 'username', 'password'
|
15
|
+
user.obj_id.should be_an_instance_of String
|
16
|
+
user.parse_client.session_token.should be_an_instance_of String
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe Parse::User, 'when it logs out' do
|
21
|
+
it 'should get the session token' do
|
22
|
+
end
|
23
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
|
3
|
+
RSpec::Matchers.define :have_params do |expected|
|
4
|
+
match do |actual|
|
5
|
+
expected.to_a.map do |k, v|
|
6
|
+
actual.include? "#{k}=#{URI.encode v.to_s}"
|
7
|
+
end.inject(true) {|s, v| s || v}
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
require 'parsecom'
|
12
|
+
# setup Parse object
|
13
|
+
Parse.credentials application_id: ENV['APPLICATION_ID'], api_key: ENV['API_KEY']
|
14
|
+
#puts('set your credentials in spec/spec_helper.rb and remove this line') || exit
|