motion-prime 0.1.0 → 0.1.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.
Files changed (54) hide show
  1. data/.gitignore +2 -1
  2. data/.travis.yml +6 -0
  3. data/Gemfile +5 -10
  4. data/Gemfile.lock +10 -7
  5. data/README.md +15 -7
  6. data/Rakefile +3 -2
  7. data/files/Gemfile +8 -1
  8. data/files/Rakefile +2 -0
  9. data/files/app/app_delegate.rb +10 -0
  10. data/files/app/config/base.rb +6 -0
  11. data/files/app/models/.gitkeep +0 -0
  12. data/files/app/screens/application_screen.rb +4 -0
  13. data/files/app/screens/help_screen.rb +5 -0
  14. data/files/app/screens/home_screen.rb +5 -0
  15. data/files/app/screens/sidebar_screen.rb +14 -0
  16. data/files/app/sections/sidebar/action.rb +5 -0
  17. data/files/app/sections/sidebar/table.rb +20 -0
  18. data/files/app/styles/sidebar.rb +38 -0
  19. data/files/resources/images/navigation/bg.png +0 -0
  20. data/files/resources/images/navigation/bg@2x.png +0 -0
  21. data/files/resources/images/navigation/button.png +0 -0
  22. data/files/resources/images/navigation/button@2x.png +0 -0
  23. data/lib/motion-prime.rb +1 -1
  24. data/motion-prime.gemspec +3 -0
  25. data/motion-prime/config/base.rb +8 -0
  26. data/motion-prime/config/config.rb +49 -0
  27. data/motion-prime/elements/draw/label.rb +1 -1
  28. data/motion-prime/models/association.rb +115 -0
  29. data/motion-prime/models/bag.rb +129 -0
  30. data/motion-prime/models/base.rb +15 -65
  31. data/motion-prime/models/errors.rb +3 -0
  32. data/motion-prime/models/finder.rb +189 -0
  33. data/motion-prime/models/json.rb +45 -0
  34. data/motion-prime/models/model.rb +118 -0
  35. data/motion-prime/models/store.rb +53 -0
  36. data/motion-prime/models/store_extension.rb +159 -0
  37. data/motion-prime/styles/{forms.rb → base.rb} +4 -0
  38. data/motion-prime/support/dm_view_controller.rb +1 -1
  39. data/motion-prime/version.rb +1 -1
  40. data/spec/config/store_spec.rb +73 -0
  41. data/spec/delegate/base_delegate_spec.rb +12 -0
  42. data/spec/helpers/base_delegate.rb +5 -0
  43. data/spec/helpers/base_screen.rb +9 -0
  44. data/spec/helpers/models.rb +53 -0
  45. data/spec/models/association_spec.rb +49 -0
  46. data/spec/models/bag_spec.rb +92 -0
  47. data/spec/models/base_model_spec.rb +158 -0
  48. data/spec/models/finder_spec.rb +183 -0
  49. data/spec/models/store_extension_spec.rb +120 -0
  50. data/spec/models/store_spec.rb +51 -0
  51. data/spec/screens/base_screen_spec.rb +77 -0
  52. metadata +84 -8
  53. data/lib/view_styler.rb +0 -141
  54. data/spec/main_spec.rb +0 -9
@@ -0,0 +1,120 @@
1
+ describe "StoreExtension" do
2
+ before do
3
+ MotionPrime::Store.connect
4
+ @store = MotionPrime::Store.shared_store
5
+ @store.clear
6
+ end
7
+
8
+ after do
9
+ @store.clear
10
+ end
11
+
12
+ it "should open and close store" do
13
+ @store.open
14
+ @store.closed?.should.be.false
15
+
16
+ @store.close
17
+ @store.closed?.should.be.true
18
+
19
+ @store.open
20
+ @store.closed?.should.be.false
21
+ end
22
+
23
+ it "should add, delete objects and count them" do
24
+ obj1 = Animal.new
25
+ obj1.name = "Cat"
26
+ obj2 = Animal.new
27
+ obj2.name = "Dog"
28
+ obj3 = Animal.new
29
+ obj3.name = "Cow"
30
+ obj4 = Animal.new
31
+ obj4.name = "Duck"
32
+
33
+ @store << obj1
34
+ @store << [obj2, obj3]
35
+ @store += obj4
36
+
37
+ @store.save
38
+ Animal.count.should == 4
39
+
40
+ @store.delete(obj1)
41
+ Animal.count.should == 3
42
+
43
+ @store.delete_keys([obj2.key])
44
+ Animal.count.should == 2
45
+
46
+ @store.clear
47
+ Animal.count.should == 0
48
+ end
49
+
50
+ it "should discard unsave changes" do
51
+ @store.save_interval = 1000 # must use save_interval= to set auto save interval first
52
+ @store.engine.synchronousMode = SynchronousModeFull
53
+
54
+ Animal.count.should == 0
55
+ obj1 = Animal.new
56
+ obj1.name = "Cat"
57
+ obj2 = Animal.new
58
+ obj2.name = "Dog"
59
+
60
+ @store << [obj1, obj2]
61
+ @store.changed?.should.be.true
62
+ @store.discard
63
+ @store.changed?.should.be.false
64
+ Animal.count.should == 0
65
+ @store.save_interval = 1
66
+ end
67
+
68
+ it "should create a transaction and commit" do
69
+ @store.transaction do |the_store|
70
+ Animal.count.should == 0
71
+ obj1 = Animal.new
72
+ obj1.name = "Cat"
73
+ obj1.save
74
+
75
+ obj2 = Animal.new
76
+ obj2.name = "Dog"
77
+ obj2.save
78
+ Animal.count.should == 2
79
+ end
80
+ @store.save
81
+ Animal.count.should == 2
82
+ end
83
+
84
+ it "should create a transaction and rollback when fail" do
85
+ begin
86
+ @store.transaction do |the_store|
87
+ Animal.count.should == 0
88
+ obj1 = Animal.new
89
+ obj1.name = "Cat"
90
+ obj1.save
91
+
92
+ obj2 = Animal.new
93
+ obj2.name = "Dog"
94
+ obj2.save
95
+ Animal.count.should == 2
96
+ raise "error"
97
+ end
98
+ rescue
99
+ end
100
+ @store.save
101
+ Animal.count.should == 0
102
+ end
103
+
104
+ it "should save in batch" do
105
+ @store.save_interval = 1000
106
+
107
+ Animal.count.should == 0
108
+ obj1 = Animal.new
109
+ obj1.name = "Cat"
110
+ @store << obj1
111
+
112
+ obj2 = Animal.new
113
+ obj2.name = "Dog"
114
+ @store << obj2
115
+ @store.save
116
+
117
+ Animal.count.should == 2
118
+ end
119
+
120
+ end
@@ -0,0 +1,51 @@
1
+ describe "Store" do
2
+ before do
3
+ MotionPrime::Store.disconnect
4
+ end
5
+
6
+ after do
7
+ File.delete(documents_path + "/nano.db") rescue nil
8
+ end
9
+
10
+ it "create :memory store" do
11
+ MotionPrime::Store.disconnect
12
+ store = MotionPrime::Store.create :memory
13
+ store.filePath.should == ":memory:"
14
+ end
15
+
16
+ it "create :persistent store" do
17
+ path = documents_path + "/nano.db"
18
+ store = MotionPrime::Store.create :persistent, path
19
+ store.filePath.should == path
20
+
21
+ path = documents_path + "/nano.db"
22
+ store = MotionPrime::Store.create :file, path
23
+ store.filePath.should == path
24
+ end
25
+
26
+ it "create :temp store" do
27
+ store = MotionPrime::Store.create :temp
28
+ store.filePath.should == ""
29
+
30
+ store = MotionPrime::Store.create :temporary
31
+ store.filePath.should == ""
32
+ end
33
+
34
+ it "should use shared_store if a model has no store defined" do
35
+ Autobot.store = nil
36
+ MotionPrime::Store.connect
37
+ Autobot.store.should.not.be.nil
38
+ MotionPrime::Store.shared_store.should.not.be.nil
39
+ Autobot.store.should == MotionPrime::Store.shared_store
40
+
41
+ Autobot.store = MotionPrime::Store.create :temp
42
+ Autobot.store.should.not == MotionPrime::Store.shared_store
43
+ end
44
+
45
+ it "should enable and disable debug mode" do
46
+ MotionPrime::Store.debug = true
47
+ @store = MotionPrime::Store.create
48
+ MotionPrime::Store.debug = false
49
+ @store.should.not.be.nil
50
+ end
51
+ end
@@ -0,0 +1,77 @@
1
+ describe "BaseScreen" do
2
+
3
+ before do
4
+ @screen = BaseScreen.new()
5
+ @screen.on_load
6
+ end
7
+
8
+ it "should render screen on load" do
9
+ @screen.was_rendered.should == true
10
+ end
11
+
12
+ it "should set default title" do
13
+ @screen.title.should == "Base"
14
+ end
15
+
16
+ it "#modal? should be false by default" do
17
+ @screen.modal?.should == false
18
+ end
19
+
20
+ describe "UIViewController" do
21
+
22
+ it "viewDidLoad" do
23
+ @screen.mock!(:view_did_load) { true }
24
+ @screen.viewDidLoad.should == true
25
+ end
26
+
27
+ it "viewWillAppear" do
28
+ @screen.mock!(:view_will_appear) { |animated| animated.should == true }
29
+ @screen.viewWillAppear(true)
30
+ end
31
+
32
+ it "viewDidAppear" do
33
+ @screen.mock!(:view_did_appear) { |animated| animated.should == true }
34
+ @screen.viewDidAppear(true)
35
+ end
36
+
37
+ it "viewWillDisappear" do
38
+ @screen.mock!(:view_will_disappear) { |animated| animated.should == true }
39
+ @screen.viewWillDisappear(true)
40
+ end
41
+
42
+ it "viewDidDisappear" do
43
+ @screen.mock!(:view_did_disappear) { |animated| animated.should == true }
44
+ @screen.viewDidDisappear(true)
45
+ end
46
+
47
+ it "shouldAutorotateToInterfaceOrientation" do
48
+ @screen.mock!(:should_rotate) { |o| o.should == UIInterfaceOrientationPortrait }
49
+ @screen.shouldAutorotateToInterfaceOrientation(UIInterfaceOrientationPortrait)
50
+ end
51
+
52
+ it "shouldAutorotate" do
53
+ @screen.mock!(:should_autorotate) { true }
54
+ @screen.shouldAutorotate.should == true
55
+ end
56
+
57
+ it "willRotateToInterfaceOrientation" do
58
+ @screen.mock! :will_rotate do |orientation, duration|
59
+ orientation.should == UIInterfaceOrientationPortrait
60
+ duration.should == 0.5
61
+ end
62
+ @screen.willRotateToInterfaceOrientation(UIInterfaceOrientationPortrait, duration: 0.5)
63
+ end
64
+
65
+ it "didRotateFromInterfaceOrientation" do
66
+ @screen.mock!(:on_rotate) { true }
67
+ @screen.didRotateFromInterfaceOrientation(UIInterfaceOrientationPortrait).should == true
68
+ end
69
+
70
+ end
71
+
72
+ describe "navigation" do
73
+ it "should not have navigation by default" do
74
+ @screen.has_navigation?.should == false
75
+ end
76
+ end
77
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: motion-prime
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-07-18 00:00:00.000000000 Z
12
+ date: 2013-07-20 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rake
@@ -27,6 +27,38 @@ dependencies:
27
27
  - - ! '>='
28
28
  - !ruby/object:Gem::Version
29
29
  version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: motion-stump
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: motion-redgreen
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'
30
62
  - !ruby/object:Gem::Dependency
31
63
  name: cocoapods
32
64
  requirement: !ruby/object:Gem::Requirement
@@ -147,6 +179,7 @@ extensions: []
147
179
  extra_rdoc_files: []
148
180
  files:
149
181
  - .gitignore
182
+ - .travis.yml
150
183
  - Gemfile
151
184
  - Gemfile.lock
152
185
  - README.md
@@ -157,11 +190,24 @@ files:
157
190
  - files/Gemfile
158
191
  - files/Rakefile
159
192
  - files/app/app_delegate.rb
193
+ - files/app/config/base.rb
194
+ - files/app/models/.gitkeep
160
195
  - files/app/screens/application_screen.rb
196
+ - files/app/screens/help_screen.rb
197
+ - files/app/screens/home_screen.rb
198
+ - files/app/screens/sidebar_screen.rb
199
+ - files/app/sections/sidebar/action.rb
200
+ - files/app/sections/sidebar/table.rb
201
+ - files/app/styles/sidebar.rb
202
+ - files/resources/images/navigation/bg.png
203
+ - files/resources/images/navigation/bg@2x.png
204
+ - files/resources/images/navigation/button.png
205
+ - files/resources/images/navigation/button@2x.png
161
206
  - lib/motion-prime.rb
162
- - lib/view_styler.rb
163
207
  - motion-prime.gemspec
164
208
  - motion-prime/app_delegate.rb
209
+ - motion-prime/config/base.rb
210
+ - motion-prime/config/config.rb
165
211
  - motion-prime/elements/base.rb
166
212
  - motion-prime/elements/button.rb
167
213
  - motion-prime/elements/draw.rb
@@ -173,7 +219,15 @@ files:
173
219
  - motion-prime/elements/text_view.rb
174
220
  - motion-prime/helpers/has_authorization.rb
175
221
  - motion-prime/helpers/has_search_bar.rb
222
+ - motion-prime/models/association.rb
223
+ - motion-prime/models/bag.rb
176
224
  - motion-prime/models/base.rb
225
+ - motion-prime/models/errors.rb
226
+ - motion-prime/models/finder.rb
227
+ - motion-prime/models/json.rb
228
+ - motion-prime/models/model.rb
229
+ - motion-prime/models/store.rb
230
+ - motion-prime/models/store_extension.rb
177
231
  - motion-prime/screens/_aliases_mixin.rb
178
232
  - motion-prime/screens/_base_mixin.rb
179
233
  - motion-prime/screens/_navigation_bar_mixin.rb
@@ -192,7 +246,7 @@ files:
192
246
  - motion-prime/sections/form/text_field_section.rb
193
247
  - motion-prime/sections/table.rb
194
248
  - motion-prime/sections/table/refresh_mixin.rb
195
- - motion-prime/styles/forms.rb
249
+ - motion-prime/styles/base.rb
196
250
  - motion-prime/support/_key_value_store.rb
197
251
  - motion-prime/support/dm_button.rb
198
252
  - motion-prime/support/dm_cell_with_section.rb
@@ -209,7 +263,18 @@ files:
209
263
  - motion-prime/views/view_builder.rb
210
264
  - motion-prime/views/view_styler.rb
211
265
  - resources/Default-568h@2x.png
212
- - spec/main_spec.rb
266
+ - spec/config/store_spec.rb
267
+ - spec/delegate/base_delegate_spec.rb
268
+ - spec/helpers/base_delegate.rb
269
+ - spec/helpers/base_screen.rb
270
+ - spec/helpers/models.rb
271
+ - spec/models/association_spec.rb
272
+ - spec/models/bag_spec.rb
273
+ - spec/models/base_model_spec.rb
274
+ - spec/models/finder_spec.rb
275
+ - spec/models/store_extension_spec.rb
276
+ - spec/models/store_spec.rb
277
+ - spec/screens/base_screen_spec.rb
213
278
  homepage: ''
214
279
  licenses:
215
280
  - ''
@@ -225,7 +290,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
225
290
  version: '0'
226
291
  segments:
227
292
  - 0
228
- hash: 2230486183734213704
293
+ hash: 2686622756988521932
229
294
  required_rubygems_version: !ruby/object:Gem::Requirement
230
295
  none: false
231
296
  requirements:
@@ -234,7 +299,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
234
299
  version: '0'
235
300
  segments:
236
301
  - 0
237
- hash: 2230486183734213704
302
+ hash: 2686622756988521932
238
303
  requirements: []
239
304
  rubyforge_project:
240
305
  rubygems_version: 1.8.25
@@ -242,4 +307,15 @@ signing_key:
242
307
  specification_version: 3
243
308
  summary: RubyMotion apps development framework
244
309
  test_files:
245
- - spec/main_spec.rb
310
+ - spec/config/store_spec.rb
311
+ - spec/delegate/base_delegate_spec.rb
312
+ - spec/helpers/base_delegate.rb
313
+ - spec/helpers/base_screen.rb
314
+ - spec/helpers/models.rb
315
+ - spec/models/association_spec.rb
316
+ - spec/models/bag_spec.rb
317
+ - spec/models/base_model_spec.rb
318
+ - spec/models/finder_spec.rb
319
+ - spec/models/store_extension_spec.rb
320
+ - spec/models/store_spec.rb
321
+ - spec/screens/base_screen_spec.rb
data/lib/view_styler.rb DELETED
@@ -1,141 +0,0 @@
1
- module MotionPrime
2
- class ViewStyler
3
- attr_reader :view, :options
4
-
5
- def initialize(view, bounds = CGRectZero, options = {})
6
- @options = Styles.extend_and_normalize_options options
7
- @view = view
8
- calculate_frame_for(bounds) if @options.delete(:calculate_frame)
9
- end
10
-
11
- def apply
12
- convert_primitives_to_objects(options)
13
- setValuesForKeysWithDictionary(options)
14
- end
15
-
16
- def convert_primitives_to_objects(options)
17
- options.each do |k,v|
18
- options[k] = STRUCTS_MAP[v.class].call(v) if STRUCTS_MAP.has_key?(v.class)
19
- end
20
- end
21
-
22
- def calculate_frame_for(bounds)
23
- width = options.delete(:width)
24
- height = options.delete(:height)
25
- top = options.delete(:top)
26
- right = options.delete(:right)
27
- bottom = options.delete(:bottom)
28
- left = options.delete(:left)
29
-
30
- if width.nil? && height.nil? && right.nil? && bottom.nil?
31
- options[:frame] = CGRectZero
32
- else
33
- frame = CGRectZero
34
- max_width = bounds.size.width
35
- max_height = bounds.size.height
36
- width = 0.0 if width.nil?
37
- height = 0.0 if height.nil?
38
-
39
- # calculate left and right if width is relative, e.g 0.7
40
- if width > 0 && width <= 1
41
- if right.nil?
42
- left ||= 0
43
- right = max_width - max_width * width
44
- else
45
- left = max_width - max_width * width
46
- end
47
- end
48
-
49
- # calculate top and bottom if height is relative, e.g 0.7
50
- if height > 0 && height <= 1
51
- if bottom.nil?
52
- top ||= 0
53
- bottom = max_height - max_height * height
54
- else
55
- top = max_height - max_height * height
56
- end
57
- end
58
-
59
- mask = UIViewAutoresizingNone
60
- mask |= UIViewAutoresizingFlexibleTopMargin if top.nil?
61
- mask |= UIViewAutoresizingFlexibleLeftMargin if left.nil?
62
- mask |= UIViewAutoresizingFlexibleBottomMargin if bottom.nil?
63
- mask |= UIViewAutoresizingFlexibleRightMargin if right.nil?
64
- mask |= UIViewAutoresizingFlexibleWidth if !left.nil? && !right.nil?
65
- mask |= UIViewAutoresizingFlexibleHeight if !top.nil? && !bottom.nil?
66
-
67
- if !left.nil? && !right.nil?
68
- frame.origin.x = left
69
- frame.size.width = max_width - left - right
70
- elsif !right.nil?
71
- frame.origin.x = max_width - width - right
72
- frame.size.width = width
73
- elsif !left.nil?
74
- frame.origin.x = left
75
- frame.size.width = width
76
- else
77
- frame.origin.x = max_width / 2 - width / 2
78
- frame.size.width = width
79
- end
80
-
81
- if !top.nil? && !bottom.nil?
82
- frame.origin.y = top
83
- frame.size.height = max_height - top - bottom
84
- elsif !bottom.nil?
85
- frame.origin.y = max_height - height - bottom
86
- frame.size.height = height
87
- elsif !top.nil?
88
- frame.origin.y = top
89
- frame.size.height = height
90
- else
91
- frame.origin.y = max_height / 2 - height / 2
92
- frame.size.height = height
93
- end
94
-
95
- options[:frame] = frame
96
- options[:autoresizingMask] = mask
97
- end
98
- end
99
-
100
- def setValue(value, forUndefinedKey: key)
101
- return if value.nil?
102
- # ignore options
103
- return if key == 'size_to_fit' && view.is_a?(UILabel)
104
- return if (key == 'url' || key == 'default') && view.is_a?(UIImageView)
105
-
106
- # apply options
107
- if key.end_with?('title_color')
108
- view.setTitleColor value.uicolor, forState: UIControlStateNormal
109
- elsif key.end_with?('title_shadow_color')
110
- view.setTitleShadowColor value.uicolor, forState: UIControlStateNormal
111
- elsif key.end_with?('color')
112
- color = value.uicolor
113
- color = color.cgcolor if view.is_a?(CALayer)
114
- view.send :"#{key.camelize(:lower)}=", color
115
- elsif key.end_with?('background_image')
116
- if view.is_a?(UIButton)
117
- view.setBackgroundImage value.uiimage, forState: UIControlStateNormal
118
- elsif view.is_a?(UISearchBar) && key == 'search_field_background_image'
119
- view.setSearchFieldBackgroundImage value.uiimage, forState: UIControlStateNormal
120
- else
121
- view.setBackgroundColor value.uiimage.uicolor
122
- end
123
- elsif key.end_with?('image')
124
- view.setValue value.uiimage, forKey: key.camelize
125
- elsif value.is_a?(Hash)
126
- self.class.new(view.send(key.camelize(:lower).to_sym), nil, value).apply
127
- else
128
- view.setValue value, forKey: key.camelize(:lower)
129
- end
130
- end
131
-
132
- STRUCTS_MAP = {
133
- CGAffineTransform => Proc.new {|v| NSValue.valueWithCGAffineTransform(v) },
134
- CGPoint => Proc.new {|v| NSValue.valueWithCGPoint(v) },
135
- CGRect => Proc.new {|v| NSValue.valueWithCGRect(v) },
136
- CGSize => Proc.new {|v| NSValue.valueWithCGSize(v) },
137
- UIEdgeInsets => Proc.new {|v| NSValue.valueWithUIEdgeInsets(v) },
138
- UIOffset => Proc.new {|v| NSValue.valueWithUIOffset(v) }
139
- }
140
- end
141
- end