parse-model-scaffold 0.1.1 → 0.11.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.
- data/README.md +5 -3
- data/Rakefile +7 -0
- data/lib/parse-model-scaffold/parse_api.rb +4 -2
- data/lib/parse-model-scaffold/parse_class_builder.rb +0 -2
- data/lib/parse-model-scaffold/parse_inspector.rb +9 -14
- data/lib/parse-model-scaffold/types.rb +11 -0
- data/lib/parse-model-scaffold/version.rb +1 -1
- data/parse-model-scaffold.gemspec +4 -0
- data/spec/parse_api_spec.rb +42 -0
- data/spec/parse_inspector_spec.rb +118 -0
- data/spec/spec_helper.rb +2 -0
- metadata +63 -3
data/README.md
CHANGED
@@ -1,12 +1,14 @@
|
|
1
1
|
parse-model-scaffold
|
2
2
|
====================
|
3
3
|
|
4
|
-
This project is a work in progress
|
4
|
+
*This project is a work in progress!*
|
5
|
+
|
6
|
+
This project aims to provide a simple way to create concrete subclasses of your Parse.com 'classes' in a variety of languages. This could be used as part of a CI process to keep Parse.com and your codebase in sync or simply as a way to boostrap Parse.com integration in a new environment. Where possible, the code this project generates will extend the PFObject representation in the Parse.com SDK for the given language.
|
5
7
|
|
6
8
|
The following languages are currently supported. If you don't see your preferred language, pull requests are welcome! PFScaffolder will generate all languages by default.
|
7
9
|
|
8
|
-
* Coffee-script ```:coffee```
|
9
|
-
* Objective-C ```:objc```
|
10
|
+
* Coffee-script ```:coffee``` - https://parse.com/docs/js/symbols/Parse.Object.html
|
11
|
+
* Objective-C ```:objc``` - https://parse.com/docs/ios/api/Classes/PFObject.html
|
10
12
|
|
11
13
|
Usage
|
12
14
|
=====
|
data/Rakefile
CHANGED
@@ -8,13 +8,15 @@ module Parse
|
|
8
8
|
include HTTParty
|
9
9
|
base_uri 'https://api.parse.com/1/classes'
|
10
10
|
|
11
|
+
attr_accessor :options
|
12
|
+
|
11
13
|
def initialize(appId, apiKey)
|
12
14
|
headers = {'X-Parse-Application-Id' => appId, 'X-Parse-REST-API-Key' => apiKey}
|
13
|
-
|
15
|
+
self.options = {:headers => headers}
|
14
16
|
end
|
15
17
|
|
16
18
|
def get_first(class_name)
|
17
|
-
response = self.class.get("/#{class_name}",
|
19
|
+
response = self.class.get("/#{class_name}", options.merge({:query => {:limit => 1}}))
|
18
20
|
|
19
21
|
response['results'][0]
|
20
22
|
end
|
@@ -1,26 +1,22 @@
|
|
1
|
+
require 'parse-model-scaffold/types'
|
2
|
+
|
1
3
|
module Parse
|
2
4
|
module Model
|
3
5
|
module Scaffold
|
4
6
|
|
5
|
-
|
7
|
+
PROTECTED_FIELDS = ['objectId', 'createdAt', 'updatedAt', 'ACL']
|
6
8
|
|
7
|
-
|
8
|
-
def to_s
|
9
|
-
self.name
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
13
|
-
@@protected_fields = ['objectId', 'createdAt', 'updatedAt', 'ACL']
|
9
|
+
class ParseInspector
|
14
10
|
|
15
11
|
def self.parse(obj)
|
16
12
|
|
17
|
-
|
13
|
+
PROTECTED_FIELDS.each {|x| obj.delete x}
|
18
14
|
|
19
15
|
attrs = []
|
20
16
|
|
21
17
|
obj.each do |k, v|
|
22
18
|
value_type = determine_type(v)
|
23
|
-
attr =
|
19
|
+
attr = ParseAttribute.new(k, value_type)
|
24
20
|
attrs << attr
|
25
21
|
end
|
26
22
|
|
@@ -30,13 +26,12 @@ module Parse
|
|
30
26
|
# Map Parse types to Ruby types if possible, otherwise, leave them as a
|
31
27
|
def self.determine_type(val)
|
32
28
|
|
33
|
-
|
34
|
-
|
29
|
+
# Parse represents complex types as a JSON object, so we need to inspect it
|
35
30
|
if val.is_a? Hash
|
36
31
|
|
37
32
|
# If we don't see the Parse '__type' key that they use for encoding
|
38
33
|
# complex types, then this is just a simple object
|
39
|
-
return Hash if !val.has_key? '__type'
|
34
|
+
return :Hash if !val.has_key? '__type'
|
40
35
|
|
41
36
|
# Otherwise, this is probably a Parse type (Relation, Pointer, GeoPoint, etc.)
|
42
37
|
return val['__type'].to_sym
|
@@ -44,7 +39,7 @@ module Parse
|
|
44
39
|
|
45
40
|
return :Boolean if [TrueClass, FalseClass].include? val.class
|
46
41
|
|
47
|
-
#
|
42
|
+
# Base case
|
48
43
|
val.class.to_s.to_sym
|
49
44
|
end
|
50
45
|
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
describe Parse::Model::Scaffold::ParseApi do
|
5
|
+
|
6
|
+
subject { Parse::Model::Scaffold::ParseApi.new 'my_app_id', 'my_api_key' }
|
7
|
+
|
8
|
+
it 'should exist after creation' do
|
9
|
+
subject.should_not be_nil
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'should use custom http headers' do
|
13
|
+
subject.options.has_key?(:headers).should be_true
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'should use app_id as an HTTP header' do
|
17
|
+
subject.options[:headers].has_key?('X-Parse-Application-Id').should be_true
|
18
|
+
subject.options[:headers]['X-Parse-Application-Id'].should eql('my_app_id')
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'should use api_key as an HTTP header' do
|
22
|
+
subject.options[:headers].has_key?('X-Parse-REST-API-Key').should be_true
|
23
|
+
subject.options[:headers]['X-Parse-REST-API-Key'].should eql('my_api_key')
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'should return a single object from get_first' do
|
27
|
+
|
28
|
+
stub_request(:get, "https://api.parse.com/1/classes/testclass?limit=1")
|
29
|
+
.to_return(
|
30
|
+
:body => JSON.generate(
|
31
|
+
{ :results => [{:name => 'mr. ding'}] }
|
32
|
+
),
|
33
|
+
:headers => {'Content-Type' => 'application/json'}
|
34
|
+
)
|
35
|
+
|
36
|
+
obj = subject.get_first 'testclass'
|
37
|
+
|
38
|
+
obj.nil?.should be_false
|
39
|
+
obj.has_key?('name').should be_true
|
40
|
+
obj['name'].should eql('mr. ding')
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,118 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Parse::Model::Scaffold::ParseInspector do
|
4
|
+
|
5
|
+
it 'should ignore protected Parse fields' do
|
6
|
+
|
7
|
+
obj = {
|
8
|
+
'ACL' => {},
|
9
|
+
'createdAt' => {},
|
10
|
+
'updatedAt' => {},
|
11
|
+
'objectId' => {}
|
12
|
+
}
|
13
|
+
|
14
|
+
attrs = Parse::Model::Scaffold::ParseInspector.parse(obj)
|
15
|
+
|
16
|
+
attrs.length.should equal(0)
|
17
|
+
end
|
18
|
+
|
19
|
+
describe 'parsing native ruby types' do
|
20
|
+
|
21
|
+
it 'should identify strings' do
|
22
|
+
|
23
|
+
obj = { 'name' => 'testname'}
|
24
|
+
|
25
|
+
attrs = Parse::Model::Scaffold::ParseInspector.parse(obj)
|
26
|
+
|
27
|
+
attrs.length.should equal(1)
|
28
|
+
attrs[0].type.should eql(:String)
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'should identify booleans' do
|
32
|
+
|
33
|
+
obj = { 'active' => false}
|
34
|
+
|
35
|
+
attrs = Parse::Model::Scaffold::ParseInspector.parse(obj)
|
36
|
+
|
37
|
+
attrs.length.should equal(1)
|
38
|
+
attrs[0].type.should eql(:Boolean)
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'should identify numbers' do
|
42
|
+
|
43
|
+
obj = { 'age' => 23}
|
44
|
+
|
45
|
+
attrs = Parse::Model::Scaffold::ParseInspector.parse(obj)
|
46
|
+
|
47
|
+
attrs.length.should equal(1)
|
48
|
+
attrs[0].type.should eql(:Fixnum)
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'should identify arrays' do
|
52
|
+
|
53
|
+
obj = { 'favorites' => [1,2,3]}
|
54
|
+
|
55
|
+
attrs = Parse::Model::Scaffold::ParseInspector.parse(obj)
|
56
|
+
|
57
|
+
attrs.length.should equal(1)
|
58
|
+
attrs[0].type.should eql(:Array)
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'should identify objects' do
|
62
|
+
|
63
|
+
obj = { 'attributes' => {}}
|
64
|
+
|
65
|
+
attrs = Parse::Model::Scaffold::ParseInspector.parse(obj)
|
66
|
+
|
67
|
+
attrs.length.should equal(1)
|
68
|
+
attrs[0].type.should eql(:Hash)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
describe 'parsing Parse attribute types' do
|
73
|
+
|
74
|
+
it 'should identify PFObject pointers' do
|
75
|
+
obj = {
|
76
|
+
"photo" => {
|
77
|
+
"__type" => "Pointer",
|
78
|
+
"className" => "Photo",
|
79
|
+
"objectId" => "xxxxxxxx"
|
80
|
+
}
|
81
|
+
}
|
82
|
+
|
83
|
+
attrs = Parse::Model::Scaffold::ParseInspector.parse(obj)
|
84
|
+
|
85
|
+
attrs.length.should equal(1)
|
86
|
+
attrs[0].type.should eql(:Pointer)
|
87
|
+
end
|
88
|
+
|
89
|
+
it 'should identify PFRelations' do
|
90
|
+
obj = {
|
91
|
+
"categories" => {
|
92
|
+
"__type" => "Relation",
|
93
|
+
"className" => "Category"
|
94
|
+
}
|
95
|
+
}
|
96
|
+
|
97
|
+
attrs = Parse::Model::Scaffold::ParseInspector.parse(obj)
|
98
|
+
|
99
|
+
attrs.length.should equal(1)
|
100
|
+
attrs[0].type.should eql(:Relation)
|
101
|
+
end
|
102
|
+
|
103
|
+
it 'should identify PFGeoPoints' do
|
104
|
+
obj = {
|
105
|
+
"categories" => {
|
106
|
+
"__type" => "GeoPoint",
|
107
|
+
"latitude" => 38.80523194147864,
|
108
|
+
"longitude" => -77.04765558242798
|
109
|
+
}
|
110
|
+
}
|
111
|
+
|
112
|
+
attrs = Parse::Model::Scaffold::ParseInspector.parse(obj)
|
113
|
+
|
114
|
+
attrs.length.should equal(1)
|
115
|
+
attrs[0].type.should eql(:GeoPoint)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: parse-model-scaffold
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.11.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -43,6 +43,54 @@ dependencies:
|
|
43
43
|
- - ! '>='
|
44
44
|
- !ruby/object:Gem::Version
|
45
45
|
version: '0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: rake
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: rspec
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
type: :development
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: webmock
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ! '>='
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
86
|
+
type: :development
|
87
|
+
prerelease: false
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ! '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
46
94
|
description: Tool to generate concrete subclasses of existing Parse.com model objects
|
47
95
|
in a variety of languages.
|
48
96
|
email:
|
@@ -54,7 +102,6 @@ extra_rdoc_files: []
|
|
54
102
|
files:
|
55
103
|
- .gitignore
|
56
104
|
- Gemfile
|
57
|
-
- Gemfile.lock
|
58
105
|
- LICENSE.txt
|
59
106
|
- README.md
|
60
107
|
- Rakefile
|
@@ -66,8 +113,12 @@ files:
|
|
66
113
|
- lib/parse-model-scaffold/templates/coffee/template.coffee.ejs
|
67
114
|
- lib/parse-model-scaffold/templates/objc/template.h.ejs
|
68
115
|
- lib/parse-model-scaffold/templates/objc/template.m.ejs
|
116
|
+
- lib/parse-model-scaffold/types.rb
|
69
117
|
- lib/parse-model-scaffold/version.rb
|
70
118
|
- parse-model-scaffold.gemspec
|
119
|
+
- spec/parse_api_spec.rb
|
120
|
+
- spec/parse_inspector_spec.rb
|
121
|
+
- spec/spec_helper.rb
|
71
122
|
homepage: https://github.com/mhupman/parse-model-scaffold
|
72
123
|
licenses: []
|
73
124
|
post_install_message:
|
@@ -80,16 +131,25 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
80
131
|
- - ! '>='
|
81
132
|
- !ruby/object:Gem::Version
|
82
133
|
version: '0'
|
134
|
+
segments:
|
135
|
+
- 0
|
136
|
+
hash: -3005338959257829923
|
83
137
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
84
138
|
none: false
|
85
139
|
requirements:
|
86
140
|
- - ! '>='
|
87
141
|
- !ruby/object:Gem::Version
|
88
142
|
version: '0'
|
143
|
+
segments:
|
144
|
+
- 0
|
145
|
+
hash: -3005338959257829923
|
89
146
|
requirements: []
|
90
147
|
rubyforge_project:
|
91
148
|
rubygems_version: 1.8.24
|
92
149
|
signing_key:
|
93
150
|
specification_version: 3
|
94
151
|
summary: Can be included as a library or exectued as a binary.
|
95
|
-
test_files:
|
152
|
+
test_files:
|
153
|
+
- spec/parse_api_spec.rb
|
154
|
+
- spec/parse_inspector_spec.rb
|
155
|
+
- spec/spec_helper.rb
|