motion-prime 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
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