motion_model 0.5.3 → 0.5.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,7 @@
1
1
  ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- YmQ4MDAzNDMxNzQ2MDVhOWZkMDVhNjA0M2JhMWEwMGJmZWM4NTU1MQ==
5
- data.tar.gz: !binary |-
6
- M2UzM2UyYjcyY2JjOWUyMjNhZDRlZmQ1OGE0YTUzZDY5MzY2NDNmOA==
2
+ SHA1:
3
+ metadata.gz: 9fa1c9fe578bfec914279fad0ced2ff4f6df49a1
4
+ data.tar.gz: 9952292bdef965d7ab76ab1f8a8c906a2f69fd67
7
5
  SHA512:
8
- metadata.gz: !binary |-
9
- ZWUxMmM3OGU3ZWM5YzU5YTEwMzVmMWE3OWYwYmNkYzRkYzk2ZTRiM2UzZGYz
10
- ZGFiYTkyYzZiNGNlMjZjNmZlYThiMjM5YzRjNjQ1MTVmYWZhMzAwNGM0NDAy
11
- YjBjOWE0ZjU4NjAwNmRiMjE2OWRiNTFhNDZiZjU1OTM0NmI5ODU=
12
- data.tar.gz: !binary |-
13
- ODZiYjlkNTNhM2MyODBhYTdlN2RiM2I4ZDM4YTAxNGM3ZDk3Y2E3NzBhMjE4
14
- ZGZkZGFjNTcyYmRlZjRhM2ZjZjZkYjM0MGNhODdiZDc3YWEwMzIyNWI2NDli
15
- OTdmYTliODZkNTQ1MmU3YWFmNzQ5ZjRlZmQyZGI1ODk3Y2ZmYjU=
6
+ metadata.gz: 41cb26133a685d546300513985f57e41fa58b4b8eb678689311d2b23bfddb6d9394d66f6f849ad4faff27369f3f95945c1525dcd7fa0105dfd801812236f2c8f
7
+ data.tar.gz: 8a1a29e8a90468f7392b1c9f54281fa3038956ad8776be4e668d5286057fbc164af9d25ca6b59efefdf2b0eb0daedff3481506264d33e9831fc64a1105d70d41
data/README.md CHANGED
@@ -882,12 +882,17 @@ require "~/github/local/MotionModel/lib/motion_model.rb"
882
882
  The `~/github/local` is where I cloned it, but you can put it anyplace. Next, make
883
883
  sure you are following the project on GitHub so you know when there are changes.
884
884
 
885
- Submissions/Patches
885
+ Submissions/Patches/Bug Reports
886
886
  ------------------
887
887
 
888
- Obviously, the ideal patch request is really a pull request from your own fork, complete with passing
889
- specs.
888
+ For a submission, do this:
890
889
 
891
- Really, for a bug report, even a failing spec or some proposed code is fine. I really want to make
892
- this a decent tool for RubyMotion developers who need a straightforward data
893
- modeling and persistence framework.
890
+ 1. Fork it
891
+ 2. Create your feature branch (git checkout -b my-new-feature)
892
+ 3. Commit your changes (git commit -am 'Add some feature')
893
+ 4. Push to the branch (git push origin my-new-feature)
894
+ 5. Create new Pull Request
895
+
896
+ For a bug report, the best bet is follow the above steps, but for #2 and 4,
897
+ use the issue number in the branch. Once you have created the pull request,
898
+ reference it in the issue.
@@ -44,17 +44,24 @@ module MotionModel
44
44
  # will remember the file name, so they may omit that argument.
45
45
  #
46
46
  # Raises a +MotionModel::PersistFileFailureError+ on failure.
47
- def deserialize_from_file(file_name = nil)
47
+ def deserialize_from_file(file_name = nil, directory = nil)
48
48
  if schema_version != '1.0.0'
49
49
  migrate
50
50
  end
51
51
 
52
52
  @file_name = file_name if file_name
53
+ @file_path =
54
+ if directory.nil?
55
+ documents_file(@file_name)
56
+ else
57
+ File.join(directory, @file_name)
58
+ end
59
+
53
60
 
54
- if File.exist? documents_file(@file_name)
61
+ if File.exist? @file_path
55
62
  error_ptr = Pointer.new(:object)
56
63
 
57
- data = NSData.dataWithContentsOfFile(documents_file(@file_name), options:NSDataReadingMappedIfSafe, error:error_ptr)
64
+ data = NSData.dataWithContentsOfFile(@file_path, options:NSDataReadingMappedIfSafe, error:error_ptr)
58
65
 
59
66
  if data.nil?
60
67
  error = error_ptr[0]
@@ -78,12 +85,19 @@ module MotionModel
78
85
  # remembered file name.
79
86
  #
80
87
  # Raises a +MotionModel::PersistFileError+ on failure.
81
- def serialize_to_file(file_name = nil)
88
+ def serialize_to_file(file_name = nil, directory = nil)
82
89
  @file_name = file_name if file_name
90
+ @file_path =
91
+ if directory.nil?
92
+ documents_file(@file_name)
93
+ else
94
+ File.join(directory, @file_name)
95
+ end
96
+
83
97
  error_ptr = Pointer.new(:object)
84
98
 
85
99
  data = NSKeyedArchiver.archivedDataWithRootObject collection
86
- unless data.writeToFile(documents_file(@file_name), options: NSDataWritingAtomic, error: error_ptr)
100
+ unless data.writeToFile(@file_path, options: NSDataWritingAtomic, error: error_ptr)
87
101
  # De-reference the pointer.
88
102
  error = error_ptr[0]
89
103
 
@@ -92,7 +106,6 @@ module MotionModel
92
106
  end
93
107
  end
94
108
 
95
-
96
109
  def documents_file(file_name)
97
110
  file_path = File.join NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, true), file_name
98
111
  file_path
data/motion/ext.rb CHANGED
@@ -300,45 +300,47 @@ class Debug
300
300
  @@silent = false
301
301
  @@colorize = true
302
302
 
303
- # Use silence if you want to keep messages from being echoed
304
- # to the console.
305
- def self.silence
306
- @@silent = true
307
- end
303
+ class << self
304
+ # Use silence if you want to keep messages from being echoed
305
+ # to the console.
306
+ def silence
307
+ @@silent = true
308
+ end
308
309
 
309
- def self.colorize
310
- @@colorize
311
- end
310
+ def colorize
311
+ @@colorize
312
+ end
312
313
 
313
- def self.colorize=(value)
314
- @@colorize = value == true
315
- end
314
+ def colorize=(value)
315
+ @@colorize = value == true
316
+ end
316
317
 
317
- # Use resume when you want messages that were silenced to
318
- # resume displaying.
319
- def self.resume
320
- @@silent = false
321
- end
318
+ # Use resume when you want messages that were silenced to
319
+ # resume displaying.
320
+ def resume
321
+ @@silent = false
322
+ end
322
323
 
323
- def self.put_message(type, message, color = Ansi.reset_color)
324
- open_color = @@colorize ? color : ''
325
- close_color = @@colorize ? Ansi.reset_color : ''
324
+ def put_message(type, message, color = Ansi.reset_color)
325
+ open_color = @@colorize ? color : ''
326
+ close_color = @@colorize ? Ansi.reset_color : ''
326
327
 
327
- NSLog("#{open_color}#{type} #{caller[1]}: #{message}#{close_color}") unless @@silent
328
- end
328
+ NSLog("#{open_color}#{type} #{caller[1]}: #{message}#{close_color}") unless @@silent
329
+ end
329
330
 
330
- def self.info(msg)
331
- put_message 'INFO', msg, Ansi.green_color
332
- end
331
+ def info(msg)
332
+ put_message 'INFO', msg, Ansi.green_color
333
+ end
334
+ alias :log :info
333
335
 
334
- def self.warning(msg)
335
- put_message 'WARNING', msg, Ansi.yellow_color
336
- end
336
+ def warning(msg)
337
+ put_message 'WARNING', msg, Ansi.yellow_color
338
+ end
337
339
 
338
- def self.error(msg)
339
- put_message 'ERROR', msg, Ansi.red_color
340
+ def error(msg)
341
+ put_message 'ERROR', msg, Ansi.red_color
342
+ end
340
343
  end
341
-
342
344
  end
343
345
 
344
346
  # These are C macros in iOS SDK. Not workable for Ruby.
@@ -106,6 +106,28 @@ module MotionModel
106
106
  end
107
107
  end
108
108
 
109
+ # Use at class level, as follows:
110
+ #
111
+ # class Task
112
+ # include MotionModel::Model
113
+ # include MotionModel::ArrayModelAdapter
114
+ #
115
+ # columns :name, :details, :assignees, :created_at, :updated_at
116
+ # has_many :assignees
117
+ # protects_remote_timestamps
118
+ #
119
+ # In this case, creating or updating will not alter the values of the
120
+ # timestamps, preferring to allow the server to be the only authority
121
+ # for assigning timestamp information.
122
+
123
+ def protect_remote_timestamps
124
+ @_protect_remote_timestamps = true
125
+ end
126
+
127
+ def protect_remote_timestamps?
128
+ @_protect_remote_timestamps == true
129
+ end
130
+
109
131
  # Use at class level, as follows:
110
132
  #
111
133
  # class Task
@@ -518,8 +540,10 @@ module MotionModel
518
540
 
519
541
  # Set created_at and updated_at fields
520
542
  def set_auto_date_field(field_name)
521
- method = "#{field_name}="
522
- self.send(method, Time.now) if self.respond_to?(method)
543
+ unless self.class.protect_remote_timestamps?
544
+ method = "#{field_name}="
545
+ self.send(method, Time.now) if self.respond_to?(method)
546
+ end
523
547
  end
524
548
 
525
549
  # Stub methods for hook protocols
@@ -792,7 +816,12 @@ module MotionModel
792
816
  when NilClass
793
817
  {column => value}
794
818
  when Proc
795
- {column => default.call}
819
+ begin
820
+ {column => default.call}
821
+ rescue Exception => ex
822
+ Debug.error "\n\nProblem initializing #{self.class} : #{column} with default and proc.\nException: #{ex.message}\nSorry, your app is pretty much crashing.\n"
823
+ exit
824
+ end
796
825
  when Symbol
797
826
  {column => self.send(column)}
798
827
  else
data/motion/version.rb CHANGED
@@ -4,5 +4,5 @@
4
4
  # or forward port their code to take advantage
5
5
  # of adapters.
6
6
  module MotionModel
7
- VERSION = "0.5.3"
7
+ VERSION = "0.5.4"
8
8
  end
@@ -238,5 +238,21 @@ describe "serialization of relations" do
238
238
  Parent.first.children.first.name.should == 'Fergie'
239
239
  Parent.first.dog.first.name.should == 'Fluffy'
240
240
  end
241
- end
242
241
 
242
+ it "allows to serialize and eserialize from directories" do
243
+ directory_path = '/Library/Caches'
244
+ Parent.serialize_to_file('parents.dat', directory_path)
245
+ Child.serialize_to_file('children.dat', directory_path)
246
+ Dog.serialize_to_file('dogs.dat', directory_path)
247
+ Parent.delete_all
248
+ Child.delete_all
249
+ Dog.delete_all
250
+ Parent.deserialize_from_file('parents.dat', directory_path)
251
+ Child.deserialize_from_file('children.dat', directory_path)
252
+ Dog.deserialize_from_file('dogs.dat', directory_path)
253
+ Parent.first.name.should == 'BoB'
254
+ Parent.first.children.count.should == 2
255
+ Parent.first.children.first.name.should == 'Fergie'
256
+ Parent.first.dog.first.name.should == 'Fluffy'
257
+ end
258
+ end
data/spec/date_spec.rb CHANGED
@@ -27,6 +27,14 @@ describe "time conversions" do
27
27
  :updated_at => :date
28
28
  end
29
29
 
30
+ class ProtectedUpdateable
31
+ include MotionModel::Model
32
+ include MotionModel::ArrayModelAdapter
33
+ columns :name => :string,
34
+ :updated_at => :date
35
+ protect_remote_timestamps
36
+ end
37
+
30
38
  it "Sets created_at when an item is created" do
31
39
  c = Creatable.new(:name => 'test')
32
40
  lambda{c.save}.should.change{c.created_at}
@@ -50,6 +58,12 @@ describe "time conversions" do
50
58
  lambda{ c.save }.should.change{c.updated_at}
51
59
  end
52
60
 
61
+ it "Honors (protects) server side timestamps" do
62
+ c = ProtectedUpdateable.create(:name => 'test')
63
+ sleep 1
64
+ c.name = 'test 1'
65
+ lambda{ c.save }.should.not.change{c.updated_at}
66
+ end
53
67
  end
54
68
 
55
69
  describe "parsing ISO8601 date formats" do
data/spec/model_spec.rb CHANGED
@@ -39,7 +39,7 @@ describe "Creating a model" do
39
39
  a_task = Task.new(:name => 'name', :details => 'details')
40
40
  a_task.name.should.equal('name')
41
41
  end
42
-
42
+
43
43
  it 'creates a model with all attributes even if some omitted' do
44
44
  atask = Task.create(:name => 'bob')
45
45
  atask.should.respond_to(:details)
@@ -177,14 +177,14 @@ describe "Creating a model" do
177
177
  1.upto(10) {|i| Task.create(:name => "task #{i}")}
178
178
  end
179
179
  end
180
-
180
+
181
181
  it 'deletes a row' do
182
182
  target = Task.find(:name).eq('task 3').first
183
183
  target.should.not == nil
184
184
  target.delete
185
185
  Task.find(:name).eq('task 3').count.should.equal 0
186
186
  end
187
-
187
+
188
188
  it 'deleting a row changes length' do
189
189
  target = Task.find(:name).eq('task 2').first
190
190
  lambda{target.delete}.should.change{Task.length}
@@ -198,7 +198,7 @@ describe "Creating a model" do
198
198
  Task.find(:name).eq('task 3').count.should.equal 1
199
199
  end
200
200
  end
201
-
201
+
202
202
  describe 'Handling Attribute Implementation' do
203
203
  it 'raises a NoMethodError exception when an unknown attribute it referenced' do
204
204
  task = Task.new
@@ -243,7 +243,7 @@ describe "Creating a model" do
243
243
  end
244
244
  end
245
245
  end
246
-
246
+
247
247
  describe 'defining custom attributes' do
248
248
  before do
249
249
  Task.delete_all
@@ -254,4 +254,49 @@ describe "Creating a model" do
254
254
  @task.custom_attribute_by_method.should == 'Feed the Cat - Get food, pour out'
255
255
  end
256
256
  end
257
+
258
+ describe 'protecting timestamps' do
259
+ class NoTimestamps
260
+ include MotionModel::Model
261
+ include MotionModel::ArrayModelAdapter
262
+ columns name: :string
263
+ protect_remote_timestamps
264
+ end
265
+
266
+ class AutoTimeable
267
+ include MotionModel::Model
268
+ include MotionModel::ArrayModelAdapter
269
+ columns name: :string,
270
+ created_at: :date,
271
+ updated_at: :date
272
+ end
273
+
274
+ class ProtectedTimestamps
275
+ include MotionModel::Model
276
+ include MotionModel::ArrayModelAdapter
277
+ columns name: :string,
278
+ created_at: :date,
279
+ updated_at: :date
280
+ protect_remote_timestamps
281
+ end
282
+
283
+ it 'does nothing to break classes with no timestamps' do
284
+ lambda{NoTimestamps.create!(name: 'no timestamps')}.should.not.raise
285
+ end
286
+
287
+ it "changes the timestamps if they are not protected" do
288
+ auto_timeable = AutoTimeable.new(name: 'auto timeable')
289
+ lambda{auto_timeable.name = 'changed auto timeable'; auto_timeable.save!}.should.change{auto_timeable.updated_at}
290
+ end
291
+
292
+ it "does not change created_at if timestamps are protected" do
293
+ protected_times = ProtectedTimestamps.new(name: 'auto timeable', created_at: Time.now, updated_at: Time.now)
294
+ lambda{protected_times.name = 'changed created at'; protected_times.save!}.should.not.change{protected_times.created_at}
295
+ end
296
+
297
+ it "does not change updated_at if timestamps are protected" do
298
+ protected_times = ProtectedTimestamps.new(name: 'auto timeable', created_at: Time.now, updated_at: Time.now)
299
+ lambda{protected_times.name = 'changed updated at'; protected_times.save!}.should.not.change{protected_times.updated_at}
300
+ end
301
+ end
257
302
  end
metadata CHANGED
@@ -1,41 +1,41 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: motion_model
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.3
4
+ version: 0.5.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Steve Ross
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-04-23 00:00:00.000000000 Z
11
+ date: 2014-07-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bubble-wrap
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ! '>='
17
+ - - '>='
18
18
  - !ruby/object:Gem::Version
19
19
  version: 1.3.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ! '>='
24
+ - - '>='
25
25
  - !ruby/object:Gem::Version
26
26
  version: 1.3.0
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: motion-support
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ! '>='
31
+ - - '>='
32
32
  - !ruby/object:Gem::Version
33
33
  version: 0.1.0
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ! '>='
38
+ - - '>='
39
39
  - !ruby/object:Gem::Version
40
40
  version: 0.1.0
41
41
  description: Simple model and validation mixins for RubyMotion
@@ -95,17 +95,17 @@ require_paths:
95
95
  - lib
96
96
  required_ruby_version: !ruby/object:Gem::Requirement
97
97
  requirements:
98
- - - ! '>='
98
+ - - '>='
99
99
  - !ruby/object:Gem::Version
100
100
  version: '0'
101
101
  required_rubygems_version: !ruby/object:Gem::Requirement
102
102
  requirements:
103
- - - ! '>='
103
+ - - '>='
104
104
  - !ruby/object:Gem::Version
105
105
  version: '0'
106
106
  requirements: []
107
107
  rubyforge_project:
108
- rubygems_version: 2.2.2
108
+ rubygems_version: 2.3.0
109
109
  signing_key:
110
110
  specification_version: 4
111
111
  summary: Simple model and validation mixins for RubyMotion