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 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
@@ -1 +1,8 @@
1
1
  require "bundler/gem_tasks"
2
+
3
+ require "rspec/core/rake_task"
4
+
5
+ RSpec::Core::RakeTask.new
6
+
7
+ task :default => :spec
8
+ task :test => :spec
@@ -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
- @options = {:headers => headers}
15
+ self.options = {:headers => headers}
14
16
  end
15
17
 
16
18
  def get_first(class_name)
17
- response = self.class.get("/#{class_name}", @options.merge({:query => {:limit => 1}}))
19
+ response = self.class.get("/#{class_name}", options.merge({:query => {:limit => 1}}))
18
20
 
19
21
  response['results'][0]
20
22
  end
@@ -37,8 +37,6 @@ module Parse
37
37
  # Remove extenstion, and name propertly
38
38
  tmpl_file.gsub!('template', @class_name).gsub!(File.extname(tmpl_file), '')
39
39
 
40
-
41
-
42
40
  File.open(tmpl_file, 'w') { |file| file.write(output) }
43
41
  end
44
42
  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
- class ParseInspector
7
+ PROTECTED_FIELDS = ['objectId', 'createdAt', 'updatedAt', 'ACL']
6
8
 
7
- Attribute = Struct.new :name, :type do
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
- @@protected_fields.each {|x| obj.delete x}
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 = Attribute.new(k, value_type)
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
- return val.class.to_s.to_sym if [String, Array].include? val.class
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
- # Last resort
42
+ # Base case
48
43
  val.class.to_s.to_sym
49
44
  end
50
45
  end
@@ -0,0 +1,11 @@
1
+ ParseClass = Struct.new :name, :attributes do
2
+ def to_s
3
+ self.name
4
+ end
5
+ end
6
+
7
+ ParseAttribute = Struct.new :name, :type do
8
+ def to_s
9
+ self.name
10
+ end
11
+ end
@@ -1,7 +1,7 @@
1
1
  module Parse
2
2
  module Model
3
3
  module Scaffold
4
- VERSION = "0.1.1"
4
+ VERSION = "0.11.0"
5
5
  end
6
6
  end
7
7
  end
@@ -19,4 +19,8 @@ Gem::Specification.new do |gem|
19
19
 
20
20
  gem.add_runtime_dependency 'httparty'
21
21
  gem.add_runtime_dependency 'slop'
22
+
23
+ gem.add_development_dependency 'rake'
24
+ gem.add_development_dependency 'rspec'
25
+ gem.add_development_dependency 'webmock'
22
26
  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
@@ -0,0 +1,2 @@
1
+ require 'parse-model-scaffold'
2
+ require 'webmock/rspec'
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.1.1
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