core_data_motion 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 3e43ee672ce2dc673a4951a7ac21071239d6957e
4
+ data.tar.gz: 8f6809833848968eafb51aead7a72b5336a0f3f7
5
+ SHA512:
6
+ metadata.gz: 0f1763ed6b184e7dd9f1c86bdfd7cfdb7571b47ab3e0def65881a2d850f91110572001649d231da78cb0fa1e174b898055a341e3fd2bfd6b37890f4f92739fc3
7
+ data.tar.gz: f13f79453d4ea0fd9ce0714f8849efa040f9f7d893f41406bd9f5388fed9dea691ac92ab836eb551eb1433d107e5f0f5e8c9f41aae29a1cebb203586fe7a47f9
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ .repl_history
2
+ build
3
+ pkg
4
+ tags
5
+ app/pixate_code.rb
6
+ resources/*.nib
7
+ resources/*.momd
8
+ resources/*.storyboardc
9
+ .DS_Store
10
+ nbproject
11
+ .redcar
12
+ #*#
13
+ *~
14
+ *.sw[po]
15
+ .eprj
16
+ .sass-cache
17
+ .idea
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,27 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ core_data_motion (0.0.1)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ diff-lcs (1.2.4)
10
+ rake (10.1.0)
11
+ rspec (2.14.1)
12
+ rspec-core (~> 2.14.0)
13
+ rspec-expectations (~> 2.14.0)
14
+ rspec-mocks (~> 2.14.0)
15
+ rspec-core (2.14.3)
16
+ rspec-expectations (2.14.0)
17
+ diff-lcs (>= 1.1.3, < 2.0)
18
+ rspec-mocks (2.14.1)
19
+
20
+ PLATFORMS
21
+ ruby
22
+
23
+ DEPENDENCIES
24
+ bundler (~> 1.3)
25
+ core_data_motion!
26
+ rake
27
+ rspec
data/README.md ADDED
@@ -0,0 +1,135 @@
1
+ # CoreData Motion
2
+
3
+ This project aims to provide a ruby-like way of creating CoreData models
4
+ using a DSL, avoiding the need to create them using the XCode GUI
5
+ builder.
6
+
7
+ ##Installation
8
+
9
+ ###Using bundler:
10
+
11
+ If you are using bundler for managing dependencies, you will need to add
12
+ the gem to your project's Gemfile:
13
+
14
+ # Gemfile
15
+ source "https://rubygems.org"
16
+
17
+ gem "rake"
18
+ gem "core_data_motion"
19
+ # Some other gems for your poject
20
+
21
+ and setup your Rakefile to properly require bundler's dependencies:
22
+
23
+ # -*- coding: utf-8 -*-
24
+ # Rakefile
25
+ $:.unshift("/Library/RubyMotion/lib")
26
+ require 'motion/project/template/ios'
27
+ require 'rubygems'
28
+ require 'bundler'
29
+
30
+ Bundler.setup
31
+ Bundler.require
32
+
33
+ Motion::Project::App.setup do |app|
34
+ # Use `rake config' to see complete project settings.
35
+ app.name = 'your_app_name'
36
+
37
+ app.frameworks += %w(CoreData)
38
+
39
+ app.files.unshift(*Dir.glob(File.join(app.project_dir, 'app/lib/**/*.rb')))
40
+ end
41
+
42
+ ###Without bundler
43
+
44
+ If you are not managing dependencies with bundler, you will need to
45
+ install the gem with:
46
+
47
+ gem install core_data_motion
48
+
49
+ And then require it in your Rakefile:
50
+
51
+ # -*- coding: utf-8 -*-
52
+ # Rakefile
53
+ $:.unshift("/Library/RubyMotion/lib")
54
+ require 'motion/project/template/ios'
55
+ require 'rubygems'
56
+ require 'core_data_motion'
57
+
58
+ Motion::Project::App.setup do |app|
59
+ # Use `rake config' to see complete project settings.
60
+ app.name = 'your_app_name'
61
+
62
+ app.frameworks += %w(CoreData)
63
+
64
+ app.files.unshift(*Dir.glob(File.join(app.project_dir, 'app/lib/**/*.rb')))
65
+ end
66
+
67
+
68
+ ##Usage example:
69
+
70
+ Create a file under your `settings/` directory and define the
71
+ ModelDefinition class as follows:
72
+
73
+ class ModelDefinition < CDM::EntityDefinition
74
+ def define_model
75
+ create_entity :project do |e|
76
+ e.string :name
77
+ e.string :description_text
78
+ e.date :start_date
79
+ e.double :budget
80
+ end
81
+
82
+ create_entity :task do |e|
83
+ e.int16 :project_id, optional: false
84
+ e.string :name
85
+ e.string :details
86
+ end
87
+
88
+ create_entity :comment do |e|
89
+ e.int16 :owner_id, optional: false
90
+ e.string :owner_type
91
+ e.string :content
92
+ end
93
+ end
94
+ end
95
+
96
+ Run the following rake task to create the files needed to create the
97
+ data model:
98
+
99
+ rake coredata:setup
100
+
101
+ If you are using MagicalRecord, you can initialize your database in your
102
+ application delegate by running:
103
+
104
+ MagicalRecord.setupCoreDataStackWithStoreNamed('database.sqlite')
105
+
106
+ You can use any CoreData wrapper you want (or none at all) to query for
107
+ records and save them to the device's local database.
108
+
109
+ ## Available data-types
110
+
111
+ The available data types in a CoreData model are:
112
+
113
+ - Binary `e.binary :binary_field`
114
+ - Boolean `e.boolean :boolean_field`
115
+ - Date `e.date :date_field`
116
+ - Decimal `e.decimal :decimal_field`
117
+ - Double `e.double :double_field`
118
+ - Float `e.float :float_field`
119
+ - Integer 16 `e.int16 :int_field`
120
+ - Integer 32 `e.int32 :int_field`
121
+ - Integer 64 `e.int64 :int_field`
122
+ - String `e.string :string_field`
123
+ - Transformable `e.transformable :transformable_field`
124
+
125
+ ## Contributing
126
+
127
+ This is a work in progress and help is greatly appreciated! If you want
128
+ to add a feature, fix a bug or help with documentation, you are very
129
+ welcome to do so. Just follow the usual way of contributing:
130
+
131
+ - Fork the repo.
132
+ - Create a feature branch.
133
+ - Make tests for the feature you want to add.
134
+ - Make the tests pass.
135
+ - Send a pull request.
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require "bundler"
2
+ Bundler::GemHelper.install_tasks
@@ -0,0 +1,2 @@
1
+ class FakeDelegate
2
+ end
@@ -0,0 +1,23 @@
1
+ lib = File.expand_path("../lib", __FILE__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require "core_data_motion/version"
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "core_data_motion"
7
+ spec.version = CoreDataMotion::VERSION
8
+ spec.authors = ["Sergio Morales"]
9
+ spec.email = ["i.serge23@gmail.com"]
10
+ spec.description = %q{RubyMotion tools for easily interacting with the CoreData framework}
11
+ spec.summary = %q{RubyMotion tools to work with CoreData}
12
+ spec.homepage = "https://github.com/sergelerator/data-core-motion"
13
+ spec.license = "MIT"
14
+
15
+ spec.files = `git ls-files`.split($/)
16
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
17
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
+ spec.require_paths = ["lib"]
19
+
20
+ spec.add_development_dependency "bundler", "~> 1.3"
21
+ spec.add_development_dependency "rake"
22
+ spec.add_development_dependency "rspec"
23
+ end
@@ -0,0 +1,17 @@
1
+ require "rake"
2
+
3
+ module CoreDataMotion
4
+ autoload :EntityDefinition, "core_data_motion/entity_definition"
5
+ autoload :EntityDescriptor, "core_data_motion/entity_descriptor"
6
+ autoload :Attribute, "core_data_motion/attribute"
7
+ autoload :FileWriter, "core_data_motion/file_writer"
8
+ autoload :VERSION, "core_data_motion/version"
9
+ autoload :DATA_TYPES, "core_data_motion/data_types"
10
+ autoload :DEFAULT_ATTRIBUTE_OPTIONS, "core_data_motion/data_types"
11
+ end
12
+
13
+ CDM = CoreDataMotion
14
+
15
+ Dir.glob(File.join(File.dirname(__FILE__), "tasks/**/*.rake")) do |filename|
16
+ load filename
17
+ end
@@ -0,0 +1,38 @@
1
+ class CDM::Attribute
2
+ attr_reader :type,
3
+ :name,
4
+ :syncable,
5
+ :optional,
6
+ :defaultValueString
7
+
8
+ def initialize(type_key, name, options = {})
9
+ defaults = CDM::DEFAULT_ATTRIBUTE_OPTIONS
10
+ type_defaults = CDM::DATA_TYPES[type_key][:default_options]
11
+ options = defaults.merge type_defaults.merge options
12
+
13
+ @type = CDM::DATA_TYPES[type_key][:descriptor].to_s
14
+ @name = name.to_s
15
+ @syncable = options[:syncable]
16
+ @optional = options[:optional]
17
+ @defaultValueString = options[:defaultValueString]
18
+ end
19
+
20
+ def xml_attributes
21
+ attrs = {
22
+ type: type,
23
+ name: name,
24
+ syncable: syncable,
25
+ optional: optional,
26
+ defaultValueString: defaultValueString
27
+ }
28
+ attrs.reject { |k, v| v.nil? }
29
+ end
30
+
31
+ def xml_attributes_as_string
32
+ xml_attributes.map { |k, v| "#{k}=\"#{v}\"" }.join(" ")
33
+ end
34
+
35
+ def to_xml
36
+ " <attribute #{xml_attributes_as_string}/>"
37
+ end
38
+ end
@@ -0,0 +1,63 @@
1
+ CDM::DATA_TYPES = {
2
+ binary: {
3
+ descriptor: "Binary",
4
+ default_options: {}
5
+ },
6
+ boolean: {
7
+ descriptor: "Boolean",
8
+ default_options: {}
9
+ },
10
+ date: {
11
+ descriptor: "Date",
12
+ default_options: {}
13
+ },
14
+ decimal: {
15
+ descriptor: "Decimal",
16
+ default_options: {
17
+ defaultValueString: "0.0"
18
+ }
19
+ },
20
+ double: {
21
+ descriptor: "Double",
22
+ default_options: {
23
+ defaultValueString: "0.0"
24
+ }
25
+ },
26
+ float: {
27
+ descriptor: "Float",
28
+ default_options: {
29
+ defaultValueString: "0.0"
30
+ }
31
+ },
32
+ int16: {
33
+ descriptor: "Integer 16",
34
+ default_options: {
35
+ defaultValueString: "0"
36
+ }
37
+ },
38
+ int32: {
39
+ descriptor: "Integer 32",
40
+ default_options: {
41
+ defaultValueString: "0"
42
+ }
43
+ },
44
+ int64: {
45
+ descriptor: "Integer 64",
46
+ default_options: {
47
+ defaultValueString: "0"
48
+ }
49
+ },
50
+ string: {
51
+ descriptor: "String",
52
+ default_options: {}
53
+ },
54
+ transformable: {
55
+ descriptor: "Transformable",
56
+ default_options: {}
57
+ },
58
+ }
59
+
60
+ CDM::DEFAULT_ATTRIBUTE_OPTIONS = {
61
+ syncable: "YES",
62
+ optional: "YES"
63
+ }
@@ -0,0 +1,64 @@
1
+ class CDM::EntityDefinition
2
+ attr_accessor :name,
3
+ :version_id,
4
+ :type,
5
+ :document_version,
6
+ :last_saved_tools_version,
7
+ :system_version,
8
+ :minimum_tools_version,
9
+ :mac_os_version,
10
+ :i_os_version
11
+
12
+ def initialize
13
+ @name = ""
14
+ @version_id = ""
15
+ @type = "com.apple.IDECoreDataModeler.DataModel"
16
+ @document_version = "1.0"
17
+ @last_saved_tools_version = "2061"
18
+ @system_version = "12D78"
19
+ @minimum_tools_version = "Automatic"
20
+ @mac_os_version = "Automatic"
21
+ @i_os_version = "Automatic"
22
+ end
23
+
24
+ def entities
25
+ @entities ||= []
26
+ end
27
+
28
+ def create_entity(entity_name, &b)
29
+ entity = CDM::EntityDescriptor.new(entity_name)
30
+ if block_given?
31
+ yield(entity)
32
+ end
33
+ entities.push entity
34
+ end
35
+
36
+ def xml_attributes
37
+ attrs = {
38
+ name: name,
39
+ userDefinedModelVersionIdentifier: version_id,
40
+ type: type,
41
+ documentVersion: document_version,
42
+ lastSavedToolsVersion: last_saved_tools_version,
43
+ systemVersion: system_version,
44
+ minimumToolsVersion: minimum_tools_version,
45
+ macOSVersion: mac_os_version,
46
+ iOSVersion: i_os_version
47
+ }
48
+ attrs.reject { |k, v| v.nil? }
49
+ end
50
+
51
+ def xml_attributes_as_string
52
+ xml_attributes.map { |k, v| "#{k}=\"#{v}\"" }.join(" ")
53
+ end
54
+
55
+ def to_xml
56
+ xml = [
57
+ "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>",
58
+ "<model #{xml_attributes_as_string}>",
59
+ entities.map(&:to_xml),
60
+ "</model>"
61
+ ]
62
+ xml.flatten.join("\n")
63
+ end
64
+ end
@@ -0,0 +1,52 @@
1
+ class CDM::EntityDescriptor
2
+ DEFAULT_OPTIONS = {
3
+ syncable: "YES"
4
+ }
5
+ attr_reader :name,
6
+ :syncable
7
+
8
+ def initialize(name, options = {})
9
+ options = DEFAULT_OPTIONS.merge options
10
+
11
+ @name = name.to_s
12
+ @syncable = options[:syncable]
13
+ end
14
+
15
+ def fields
16
+ @fields ||= []
17
+ end
18
+
19
+ def method_missing(method_name, *args, &b)
20
+ if CDM::DATA_TYPES.keys.include?(method_name)
21
+ self.class.instance_eval do
22
+ define_method(method_name) do |attribute_name, options = {}|
23
+ fields.push CDM::Attribute.new(method_name, attribute_name, options)
24
+ end
25
+ end
26
+ method(method_name).call(args)
27
+ else
28
+ super(method_name, args, b)
29
+ end
30
+ end
31
+
32
+ def xml_attributes
33
+ attrs = {
34
+ name: name,
35
+ syncable: syncable
36
+ }
37
+ attrs.reject { |k, v| v.nil? }
38
+ end
39
+
40
+ def xml_attributes_as_string
41
+ xml_attributes.map { |k, v| "#{k}=\"#{v}\"" }.join(" ")
42
+ end
43
+
44
+ def to_xml
45
+ xml = [
46
+ " <entity #{xml_attributes_as_string}>",
47
+ fields.map { |f| f.to_xml },
48
+ " </entity>"
49
+ ]
50
+ xml.flatten.join("\n")
51
+ end
52
+ end
@@ -0,0 +1,35 @@
1
+ class CDM::FileWriter
2
+
3
+ def entity_definition_class_name
4
+ @entity_definition_class_name ||= begin
5
+ Object.const_get file_prefix.split("_").map(&:capitalize).join
6
+ end
7
+ end
8
+
9
+ def file_prefix
10
+ @file_prefix ||= "model_definition"
11
+ end
12
+
13
+ def path_to_model_contents
14
+ @path_to_model_contents ||=
15
+ "./resources/#{file_prefix}.xcdatamodeld/#{file_prefix}.xcdatamodel"
16
+ end
17
+
18
+ def model_contents_path
19
+ @model_contents_path ||= "#{path_to_model_contents}/contents"
20
+ end
21
+
22
+ def model_xml_content
23
+ tmp_instance = entity_definition_class_name.new
24
+ tmp_instance.define_model
25
+ tmp_instance.to_xml
26
+ end
27
+
28
+ def create_model_definition
29
+ Dir.glob("./settings/*.rb") { |filename| load filename }
30
+ FileUtils.mkpath path_to_model_contents
31
+ File.open(model_contents_path, "w") do |f|
32
+ f.puts model_xml_content
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,3 @@
1
+ module CoreDataMotion
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,6 @@
1
+ namespace :coredata do
2
+ desc "Sets up the CoreData model definition file"
3
+ task :setup do
4
+ CDM::FileWriter.new.create_model_definition
5
+ end
6
+ end
@@ -0,0 +1,259 @@
1
+ require "./spec/spec_helper"
2
+
3
+ describe "Attribute" do
4
+ before :all do
5
+ @subject = CDM::Attribute
6
+ end
7
+
8
+ describe "when initialized with a string type and no options" do
9
+ context "with no options" do
10
+ before :each do
11
+ @dummy = @subject.new(:string, "lorem_ipsum")
12
+ end
13
+
14
+ it "has the name 'lorem_ipsum'" do
15
+ @dummy.name.should eq "lorem_ipsum"
16
+ end
17
+
18
+ it "has the type 'String'" do
19
+ @dummy.type.should eq "String"
20
+ end
21
+
22
+ it "is syncable" do
23
+ @dummy.syncable.should eq "YES"
24
+ end
25
+
26
+ it "is optional" do
27
+ @dummy.optional.should eq "YES"
28
+ end
29
+ end
30
+
31
+ context "with options" do
32
+ before do
33
+ @dummy = @subject.new(:string,
34
+ "lorem_ipsum_dolor_sit_amet",
35
+ syncable: "NO",
36
+ optional: "NO"
37
+ )
38
+ end
39
+
40
+ it "has the name 'lorem_ipsum_dolor_sit_amet'" do
41
+ @dummy.name.should eq "lorem_ipsum_dolor_sit_amet"
42
+ end
43
+
44
+ it "has the type 'String'" do
45
+ @dummy.type.should eq "String"
46
+ end
47
+
48
+ it "is syncable" do
49
+ @dummy.syncable.should eq "NO"
50
+ end
51
+
52
+ it "is optional" do
53
+ @dummy.optional.should eq "NO"
54
+ end
55
+ end
56
+ end
57
+
58
+ describe "when initialized with a double type" do
59
+ context "with no options" do
60
+ before do
61
+ @dummy = @subject.new(:double, "double_field")
62
+ end
63
+
64
+ it "has the name 'double_field'" do
65
+ @dummy.name.should eq "double_field"
66
+ end
67
+
68
+ it "has the type 'Double'" do
69
+ @dummy.type.should eq "Double"
70
+ end
71
+
72
+ it "is syncable" do
73
+ @dummy.syncable.should eq "YES"
74
+ end
75
+
76
+ it "is optional" do
77
+ @dummy.optional.should eq "YES"
78
+ end
79
+
80
+ it "has a defaultValueString equal to '0.0'" do
81
+ @dummy.defaultValueString.should eq "0.0"
82
+ end
83
+ end
84
+
85
+ context "with options" do
86
+ before do
87
+ @dummy = @subject.new(:double, "dd", defaultValueString: "0.00")
88
+ end
89
+
90
+ it "has the name 'dd'" do
91
+ @dummy.name.should eq "dd"
92
+ end
93
+
94
+ it "has the type 'Double'" do
95
+ @dummy.type.should eq "Double"
96
+ end
97
+
98
+ it "is syncable" do
99
+ @dummy.syncable.should eq "YES"
100
+ end
101
+
102
+ it "is optional" do
103
+ @dummy.optional.should eq "YES"
104
+ end
105
+
106
+ it "has a defaultValueString equal to '0.0'" do
107
+ @dummy.defaultValueString.should eq "0.00"
108
+ end
109
+ end
110
+ end
111
+
112
+ describe "when initialized with an 'Integer 32' type" do
113
+ context "with no options" do
114
+ before do
115
+ @dummy = @subject.new(:int32, "fixnum")
116
+ end
117
+
118
+ it "has the name 'fixnum'" do
119
+ @dummy.name.should eq "fixnum"
120
+ end
121
+
122
+ it "has the type 'Integer 32'" do
123
+ @dummy.type.should eq "Integer 32"
124
+ end
125
+
126
+ it "is syncable" do
127
+ @dummy.syncable.should eq "YES"
128
+ end
129
+
130
+ it "is optional" do
131
+ @dummy.optional.should eq "YES"
132
+ end
133
+
134
+ it "has a defaultValueString equal to '0'" do
135
+ @dummy.defaultValueString.should eq "0"
136
+ end
137
+ end
138
+
139
+ context "with options" do
140
+ before do
141
+ @dummy = @subject.new(:int32,
142
+ "fn",
143
+ defaultValueString: "1",
144
+ syncable: "NO"
145
+ )
146
+ end
147
+
148
+ it "has the name 'fn'" do
149
+ @dummy.name.should eq "fn"
150
+ end
151
+
152
+ it "has the type 'Integer 32'" do
153
+ @dummy.type.should eq "Integer 32"
154
+ end
155
+
156
+ it "is not syncable" do
157
+ @dummy.syncable.should eq "NO"
158
+ end
159
+
160
+ it "is optional" do
161
+ @dummy.optional.should eq "YES"
162
+ end
163
+
164
+ it "has a defaultValueString equal to '1'" do
165
+ @dummy.defaultValueString.should eq "1"
166
+ end
167
+ end
168
+ end
169
+
170
+ describe "when initialized with a 'Transformable' type" do
171
+ context "with no options" do
172
+ before do
173
+ @dummy = @subject.new(:transformable, "trans")
174
+ end
175
+
176
+ it "has the name 'trans'" do
177
+ @dummy.name.should eq "trans"
178
+ end
179
+
180
+ it "has the type 'Transformable'" do
181
+ @dummy.type.should eq "Transformable"
182
+ end
183
+
184
+ it "is syncable" do
185
+ @dummy.syncable.should eq "YES"
186
+ end
187
+
188
+ it "is optional" do
189
+ @dummy.optional.should eq "YES"
190
+ end
191
+ end
192
+
193
+ context "with options" do
194
+ before do
195
+ @dummy = @subject.new(:transformable,
196
+ "transform",
197
+ syncable: "NO"
198
+ )
199
+ end
200
+
201
+ it "has the name 'transform'" do
202
+ @dummy.name.should eq "transform"
203
+ end
204
+
205
+ it "has the type 'Transformable'" do
206
+ @dummy.type.should eq "Transformable"
207
+ end
208
+
209
+ it "is not syncable" do
210
+ @dummy.syncable.should eq "NO"
211
+ end
212
+
213
+ it "is optional" do
214
+ @dummy.optional.should eq "YES"
215
+ end
216
+ end
217
+ end
218
+
219
+ describe ".xml_attributes" do
220
+ context "when initialized with a string" do
221
+ context "with no options" do
222
+
223
+ before do
224
+ @serializable = @subject.new(:string, :string)
225
+ end
226
+
227
+ it "returns 4 attributes" do
228
+ @serializable.xml_attributes.keys.length.should eq 4
229
+ end
230
+
231
+ end
232
+ end
233
+ end
234
+
235
+ describe ".xml_attributes_as_string" do
236
+
237
+ context "when adding a string" do
238
+ before do
239
+ @attribute = @subject.new(:string, :attribute)
240
+ end
241
+
242
+ it "returns a string with one xml node attribute" do
243
+ expected = 'type="String" name="attribute" syncable="YES" optional="YES"'
244
+ @attribute.xml_attributes_as_string.should eq(expected)
245
+ end
246
+ end
247
+
248
+ context "when adding an integer" do
249
+ before do
250
+ @attribute = @subject.new(:int32, :attribute)
251
+ end
252
+
253
+ it "returns a string with one xml node attribute" do
254
+ expected = 'type="Integer 32" name="attribute" syncable="YES" optional="YES" defaultValueString="0"'
255
+ @attribute.xml_attributes_as_string.should eq(expected)
256
+ end
257
+ end
258
+ end
259
+ end
@@ -0,0 +1,188 @@
1
+ require "./spec/spec_helper"
2
+
3
+ describe "EntityDefinition" do
4
+ before do
5
+ @subject = CDM::EntityDefinition
6
+ end
7
+
8
+ it "exists" do
9
+ @subject.should be
10
+ end
11
+
12
+ describe ".create_entity" do
13
+ before do
14
+ @dummy = @subject.new
15
+ end
16
+
17
+ context "when adding the :foo entity with no attributes" do
18
+ before do
19
+ @dummy.create_entity :foo do |e|
20
+ end
21
+ end
22
+
23
+ it "has an entities collection of length 1" do
24
+ @dummy.entities.length.should eq 1
25
+ end
26
+
27
+ it "has an entity named 'foo'" do
28
+ @dummy.entities.first.name.should eq "foo"
29
+ end
30
+ end
31
+
32
+ context "when adding the :person entity with a few attributes" do
33
+ before do
34
+ @dummy.create_entity :person do |e|
35
+ e.string :name, optional: "NO"
36
+ e.int16 :age
37
+ end
38
+ end
39
+
40
+ it "has an entities collection of length 1" do
41
+ @dummy.entities.length.should eq 1
42
+ end
43
+
44
+ it "has an entity named 'person'" do
45
+ @dummy.entities.first.name.should eq "person"
46
+ end
47
+
48
+ it "has the 'name' attribute in the first entity" do
49
+ @dummy.entities.first.fields.first.name.should eq "name"
50
+ end
51
+ end
52
+
53
+ context "when adding three entities" do
54
+ before do
55
+ @dummy.create_entity :foo do |e|
56
+ e.string :foo_attribute
57
+ e.date :foo_date_attribute
58
+ e.int16 :foo_int_attribute
59
+ end
60
+
61
+ @dummy.create_entity :bar do |e|
62
+ e.binary :bar_binary_attribute
63
+ e.boolean :bar_boolean_attribute
64
+ e.float :bar_float_attribute
65
+ end
66
+
67
+ @dummy.create_entity :baz do |e|
68
+ e.transformable :baz_transformable_attribute
69
+ e.decimal :baz_decimal_attribute
70
+ end
71
+ end
72
+
73
+ it "has 3 entities in the colection" do
74
+ @dummy.entities.length.should eq 3
75
+ end
76
+
77
+ it "has the foo entity in the first spot of the collection" do
78
+ @dummy.entities.first.name.should eq "foo"
79
+ end
80
+ end
81
+
82
+ end
83
+
84
+ describe ".xml_attributes" do
85
+ before do
86
+ @dummy = @subject.new
87
+ end
88
+
89
+ it "returns 9 attributes" do
90
+ @dummy.xml_attributes.keys.length.should eq 9
91
+ end
92
+
93
+ context "default values" do
94
+ before do
95
+ @result = @dummy.xml_attributes
96
+ end
97
+
98
+ it "returns empty string for name" do
99
+ @result[:name].should eq ""
100
+ end
101
+
102
+ it "returns empty string for userDefinedModelVersionIdentifier" do
103
+ @result[:userDefinedModelVersionIdentifier].should eq ""
104
+ end
105
+
106
+ it "returns 'com.apple.IDECoreDataModeler.DataModel' for type" do
107
+ @result[:type].should eq "com.apple.IDECoreDataModeler.DataModel"
108
+ end
109
+
110
+ it "returns '1.0' for documentVersion" do
111
+ @result[:documentVersion].should eq "1.0"
112
+ end
113
+
114
+ it "returns '2061' for documentVersion" do
115
+ @result[:lastSavedToolsVersion].should eq "2061"
116
+ end
117
+
118
+ it "returns '12D78 for systemVersion'" do
119
+ @result[:systemVersion].should eq "12D78"
120
+ end
121
+
122
+ it "returns 'Automatic for minimumToolsVersion'" do
123
+ @result[:minimumToolsVersion].should eq "Automatic"
124
+ end
125
+
126
+ it "returns 'Automatic for macOSVersion'" do
127
+ @result[:macOSVersion].should eq "Automatic"
128
+ end
129
+
130
+ it "returns 'Automatic for iOSVersion'" do
131
+ @result[:iOSVersion].should eq "Automatic"
132
+ end
133
+ end
134
+
135
+ context "custom values" do
136
+ before do
137
+ @dummy.name = "Lorem Ipsum"
138
+ @dummy.document_version = "2.4"
139
+ @result = @dummy.xml_attributes
140
+ end
141
+
142
+ it "returns 'Lorem Ipsum' for name" do
143
+ @result[:name].should eq "Lorem Ipsum"
144
+ end
145
+
146
+ it "returns '2.4' for documentVersion" do
147
+ @result[:documentVersion].should eq "2.4"
148
+ end
149
+ end
150
+ end
151
+
152
+ describe ".to_xml" do
153
+
154
+ before do
155
+ class ModelDefinition < CDM::EntityDefinition
156
+ def define_model
157
+
158
+ create_entity :foo do |e|
159
+ e.string :foo_string
160
+ e.date :foo_date
161
+ e.int16 :foo_int
162
+ end
163
+
164
+ create_entity :bar do |e|
165
+ e.binary :bar_binary
166
+ e.boolean :bar_boolean
167
+ e.float :bar_float
168
+ end
169
+
170
+ create_entity :baz do |e|
171
+ e.transformable :baz_transformable
172
+ e.decimal :baz_decimal
173
+ end
174
+
175
+ end
176
+ end
177
+
178
+ @model_definition = ModelDefinition.new
179
+ @model_definition.define_model
180
+ @xml_array = @model_definition.to_xml.split("\n")
181
+ end
182
+
183
+ it "contains entity name 'foo' in the line at index 2" do
184
+ @xml_array[2].should eq ' <entity name="foo" syncable="YES">'
185
+ end
186
+
187
+ end
188
+ end
@@ -0,0 +1,200 @@
1
+ require "./spec/spec_helper"
2
+
3
+ describe "Entity descriptor" do
4
+ before :all do
5
+ @subject = CDM::EntityDescriptor
6
+ @dummy = @subject.new(:lorem_ipsum)
7
+ end
8
+
9
+ it "exists" do
10
+ @subject.should be
11
+ end
12
+
13
+ it "has the name 'lorem_ipsum'" do
14
+ @dummy.name.should eq "lorem_ipsum"
15
+ end
16
+
17
+ it "is syncable" do
18
+ @dummy.syncable.should eq "YES"
19
+ end
20
+
21
+ describe "when initialized with options" do
22
+ before :each do
23
+ @optioned = @subject.new(:optioned, syncable: "NO")
24
+ end
25
+
26
+ it "has the name 'optioned'" do
27
+ @optioned.name.should eq "optioned"
28
+ end
29
+
30
+ it "is not syncable" do
31
+ @optioned.syncable.should eq "NO"
32
+ end
33
+ end
34
+
35
+ describe ".binary" do
36
+ before :each do
37
+ @dummy.fields.clear
38
+ end
39
+
40
+ it "has an empty set of fields" do
41
+ @dummy.fields.length.should eq 0
42
+ end
43
+
44
+ context "adding a binary type field" do
45
+ before do
46
+ @dummy.binary :binary
47
+ end
48
+
49
+ it "adds an element to the fields collection" do
50
+ @dummy.fields.length.should eq 1
51
+ end
52
+
53
+ it "adds a string field to the descriptor" do
54
+ @dummy.fields.first.type.should eq "Binary"
55
+ end
56
+
57
+ it "adds a field with the name 'binary'" do
58
+ @dummy.fields.first.name.should eq "binary"
59
+ end
60
+ end
61
+ end
62
+
63
+ describe ".int16" do
64
+ before :each do
65
+ @dummy.fields.clear
66
+ end
67
+
68
+ context "adding an 'Integer 16' type field" do
69
+ before :each do
70
+ @dummy.int16 :age
71
+ end
72
+
73
+ it "adds an 'Integer 16' field to the descriptor" do
74
+ @dummy.fields.first.type.should eq "Integer 16"
75
+ end
76
+
77
+ it "adds a field with the name 'age'" do
78
+ @dummy.fields.first.name.should eq "age"
79
+ end
80
+
81
+ it "adds a field with a defaultValueString equal to '0'" do
82
+ @dummy.fields.first.defaultValueString.should eq "0"
83
+ end
84
+ end
85
+ end
86
+
87
+ describe ".string" do
88
+ before :each do
89
+ @dummy.fields.clear
90
+ end
91
+
92
+ context "adding a string type field" do
93
+ before :each do
94
+ @dummy.string :lorem_ipsum
95
+ end
96
+
97
+ it "adds a string field to the descriptor" do
98
+ @dummy.fields.first.type.should eq "String"
99
+ end
100
+
101
+ it "adds a field with the name 'lorem_ipsum'" do
102
+ @dummy.fields.first.name.should eq "lorem_ipsum"
103
+ end
104
+ end
105
+ end
106
+
107
+ describe ".xml_attributes" do
108
+ context "when initialized with no options" do
109
+ before :each do
110
+ @serializable = @subject.new(:serializable)
111
+ end
112
+
113
+ it "returns a hash with two elements" do
114
+ @serializable.xml_attributes.keys.length.should eq 2
115
+ end
116
+
117
+ it "returns a hash with the name key" do
118
+ @serializable.xml_attributes[:name].should eq "serializable"
119
+ end
120
+
121
+ it "returns a hash with the syncable key pointing to the 'YES' string" do
122
+ @serializable.xml_attributes[:syncable].should eq "YES"
123
+ end
124
+ end
125
+
126
+ describe "when initialized with a few options" do
127
+ before :each do
128
+ @serializable = @subject.new(:serializable, syncable: "NO")
129
+ end
130
+
131
+ it "returns a hash with two elements" do
132
+ @serializable.xml_attributes.keys.length.should eq 2
133
+ end
134
+
135
+ it "returns a hash with the name key" do
136
+ @serializable.xml_attributes[:name].should eq "serializable"
137
+ end
138
+
139
+ it "returns a hash with the syncable key pointing to the 'YES' string" do
140
+ @serializable.xml_attributes[:syncable].should eq "NO"
141
+ end
142
+ end
143
+ end
144
+
145
+ describe ".xml_attributes_as_string" do
146
+ before :each do
147
+ @serializable = @subject.new(:serializable)
148
+ end
149
+
150
+ it "returns a string with two xml node attributes" do
151
+ expected = 'name="serializable" syncable="YES"'
152
+ @serializable.xml_attributes_as_string.should eq(expected)
153
+ end
154
+ end
155
+
156
+ describe ".to_xml" do
157
+ context "when the entity descriptor has no fields" do
158
+ before :each do
159
+ @serializable = @subject.new(:serializable)
160
+ end
161
+
162
+ it "returns an xml snippet of two lines" do
163
+ @serializable.to_xml.split("\n").length.should eq 2
164
+ end
165
+
166
+ it "returns an expected first line" do
167
+ expected = ' <entity name="serializable" syncable="YES">'
168
+ @serializable.to_xml.split("\n").first.should eq(expected)
169
+ end
170
+
171
+ it "returns an expected last line" do
172
+ expected = ' </entity>'
173
+ @serializable.to_xml.split("\n").last.should eq(expected)
174
+ end
175
+ end
176
+
177
+ context "when the entity descriptor has two fields" do
178
+ before :each do
179
+ @fielded = @subject.new(:fielded)
180
+ @fielded.string :name
181
+ @fielded.int32 :age
182
+ end
183
+
184
+ it "returns an xml snippet of four lines" do
185
+ @fielded.to_xml.split("\n").length.should eq 4
186
+ end
187
+
188
+ it "returns an expected line at index 1" do
189
+ expected = ' <attribute type="String" name="name" syncable="YES" optional="YES"/>'
190
+ @fielded.to_xml.split("\n")[1].should eq(expected)
191
+ end
192
+
193
+ it "returns an expected line at index 2" do
194
+ expected = ' <attribute type="Integer 32" name="age" syncable="YES" optional="YES" defaultValueString="0"/>'
195
+ @fielded.to_xml.split("\n")[2].should eq(expected)
196
+ end
197
+ end
198
+ end
199
+
200
+ end
@@ -0,0 +1,46 @@
1
+ describe CDM::FileWriter do
2
+ OUTPUT_PATH = "./resources/model_definition.xcdatamodeld/model_definition.xcdatamodel/contents"
3
+
4
+ context "test sample 1" do
5
+ before :each do
6
+ class ModelDefinition < CDM::EntityDefinition
7
+
8
+ def define_model
9
+ create_entity :foo do |e|
10
+ e.string :foo_string
11
+ e.date :foo_date
12
+ e.int16 :foo_int
13
+ end
14
+ end
15
+
16
+ end
17
+
18
+ subject.create_model_definition
19
+ @result = File.open(OUTPUT_PATH, "r") { |f| f.read }.split("\n")
20
+ end
21
+
22
+ after :all do
23
+ File.unlink(OUTPUT_PATH)
24
+ end
25
+
26
+ it "defines the 'foo' entity" do
27
+ @result[2].should eq ' <entity name="foo" syncable="YES">'
28
+ end
29
+
30
+ it "defines the 'foo_string' attribute" do
31
+ @result[3].should eq ' <attribute type="String" name="foo_string" syncable="YES" optional="YES"/>'
32
+ end
33
+
34
+ it "defines the 'foo_date' attribute" do
35
+ @result[4].should eq ' <attribute type="Date" name="foo_date" syncable="YES" optional="YES"/>'
36
+ end
37
+
38
+ it "defines the 'foo_int' attribute" do
39
+ @result[5].should eq ' <attribute type="Integer 16" name="foo_int" syncable="YES" optional="YES" defaultValueString="0"/>'
40
+ end
41
+
42
+ it "closes the 'foo_entity' definition" do
43
+ @result[6].should eq ' </entity>'
44
+ end
45
+ end
46
+ end
@@ -0,0 +1 @@
1
+ require "./lib/core_data_motion"
@@ -0,0 +1,5 @@
1
+ describe "CoreDataMotion::VERSION" do
2
+ it "is" do
3
+ CDM::VERSION.class.should eq String
4
+ end
5
+ end
metadata ADDED
@@ -0,0 +1,113 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: core_data_motion
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Sergio Morales
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-08-06 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.3'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description: RubyMotion tools for easily interacting with the CoreData framework
56
+ email:
57
+ - i.serge23@gmail.com
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - .gitignore
63
+ - Gemfile
64
+ - Gemfile.lock
65
+ - README.md
66
+ - Rakefile
67
+ - app/app_delegate.rb
68
+ - core_data_motion.gemspec
69
+ - lib/core_data_motion.rb
70
+ - lib/core_data_motion/attribute.rb
71
+ - lib/core_data_motion/data_types.rb
72
+ - lib/core_data_motion/entity_definition.rb
73
+ - lib/core_data_motion/entity_descriptor.rb
74
+ - lib/core_data_motion/file_writer.rb
75
+ - lib/core_data_motion/version.rb
76
+ - lib/tasks/coredata.rake
77
+ - spec/attribute_spec.rb
78
+ - spec/entity_definition_spec.rb
79
+ - spec/entity_descriptor_spec.rb
80
+ - spec/file_writer_spec.rb
81
+ - spec/spec_helper.rb
82
+ - spec/version_spec.rb
83
+ homepage: https://github.com/sergelerator/data-core-motion
84
+ licenses:
85
+ - MIT
86
+ metadata: {}
87
+ post_install_message:
88
+ rdoc_options: []
89
+ require_paths:
90
+ - lib
91
+ required_ruby_version: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - '>='
94
+ - !ruby/object:Gem::Version
95
+ version: '0'
96
+ required_rubygems_version: !ruby/object:Gem::Requirement
97
+ requirements:
98
+ - - '>='
99
+ - !ruby/object:Gem::Version
100
+ version: '0'
101
+ requirements: []
102
+ rubyforge_project:
103
+ rubygems_version: 2.0.3
104
+ signing_key:
105
+ specification_version: 4
106
+ summary: RubyMotion tools to work with CoreData
107
+ test_files:
108
+ - spec/attribute_spec.rb
109
+ - spec/entity_definition_spec.rb
110
+ - spec/entity_descriptor_spec.rb
111
+ - spec/file_writer_spec.rb
112
+ - spec/spec_helper.rb
113
+ - spec/version_spec.rb