core_data_motion 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.
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