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,5 @@
1
+ class BaseDelegate < MotionPrime::BaseAppDelegate
2
+ def on_load(app, options)
3
+ self.was_loaded = true
4
+ end
5
+ end
@@ -0,0 +1,9 @@
1
+ class BaseScreen < MotionPrime::BaseScreen
2
+ title "Base"
3
+ attr_accessor :was_rendered
4
+
5
+ def render
6
+ self.was_rendered = true
7
+ set_navigation_right_button "Test", action: :test, type: UIBarButtonItemStyleDone
8
+ end
9
+ end
@@ -0,0 +1,53 @@
1
+ class User < MotionPrime::BaseModel
2
+ attributes :name, :age, :created_at
3
+ end
4
+
5
+ class Plane < MotionPrime::BaseModel
6
+ attributes :name, :age
7
+ end
8
+
9
+ class Listing < MotionPrime::BaseModel
10
+ attribute :name
11
+ end
12
+
13
+ class Todo < MotionPrime::BaseModel
14
+ attribute :title
15
+ bag :items
16
+ end
17
+
18
+ class TodoItem < MotionPrime::BaseModel
19
+ attribute :completed
20
+ attribute :text
21
+ end
22
+
23
+ class Page < MotionPrime::BaseModel
24
+ attribute :text
25
+ attribute :index
26
+ end
27
+
28
+ class Animal < MotionPrime::BaseModel
29
+ attribute :name
30
+ end
31
+
32
+ class Autobot < MotionPrime::BaseModel
33
+ attribute :name
34
+ end
35
+
36
+ module CustomModule; end
37
+ class CustomModule::Car < MotionPrime::BaseModel
38
+ attribute :name
39
+ attribute :created_at
40
+ end
41
+ Car = CustomModule::Car
42
+
43
+ def stub_user(name, age, created_at)
44
+ user = User.new
45
+ user.name = name
46
+ user.age = age
47
+ user.created_at = created_at
48
+ user
49
+ end
50
+
51
+ def documents_path
52
+ NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, true)[0]
53
+ end
@@ -0,0 +1,49 @@
1
+ describe "Associations" do
2
+ before do
3
+ MotionPrime::Store.connect
4
+ end
5
+
6
+ after do
7
+ MotionPrime::Store.shared_store.clear
8
+ end
9
+
10
+ describe "#bag" do
11
+ it "adds a attr reader to the class" do
12
+ todo = Todo.create(:title => "Today Tasks")
13
+ todo.items.is_a?(MotionPrime::Bag).should == true
14
+ todo.items.size.should == 0
15
+ end
16
+
17
+ it "adds a attr writer to the class that can take an Array" do
18
+ todo = Todo.create(:title => "Today Tasks")
19
+ todo.items = [TodoItem.new(:text => "Hi"), TodoItem.new(:text => "Foo"), TodoItem.new(:text => "Bar")]
20
+ todo.items.is_a?(MotionPrime::Bag).should == true
21
+ todo.items.size.should == 3
22
+ end
23
+
24
+ it "adds a writer to the class that can take a Bag" do
25
+ todo = Todo.create(:title => "Today Tasks")
26
+ todo.items = MotionPrime::Bag.bag
27
+ todo.items.is_a?(MotionPrime::Bag).should == true
28
+ todo.items.size.should == 0
29
+ end
30
+ end
31
+
32
+ describe "#save" do
33
+ it "save a model also saves associated bags" do
34
+ todo = Todo.create(:title => "Today Tasks")
35
+ todo.items = [TodoItem.new(:text => "Hi"), TodoItem.new(:text => "Foo"), TodoItem.new(:text => "Bar")]
36
+ todo.items.is_a?(MotionPrime::Bag).should == true
37
+ todo.save
38
+
39
+ todo = Todo.find(:title => "Today Tasks").first
40
+ todo.should.not.be.nil
41
+ todo.items.is_a?(MotionPrime::Bag).should == true
42
+ todo.items.key.should == todo.items.key
43
+ todo.items.size.should == 3
44
+ todo.items.to_a.each do |item|
45
+ item.is_a?(TodoItem).should.be.true
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,92 @@
1
+ describe "Bag" do
2
+ Bag = MotionPrime::Bag
3
+
4
+ before do
5
+ MotionPrime::Store.connect
6
+ end
7
+
8
+ after do
9
+ MotionPrime::Store.shared_store.clear
10
+ end
11
+
12
+ describe "#<<" do
13
+ it "should add objects to bag" do
14
+ bag = Bag.bag
15
+
16
+ # use << method to add object to bag
17
+ bag << Page.new(:text => "Hello", :index => 1)
18
+
19
+ bag.unsaved.count.should.be == 1
20
+ bag.changed?.should.be.true
21
+ bag.save
22
+
23
+ bag.unsaved.count.should.be == 0
24
+ bag.saved.count.should.be == 1
25
+ bag.changed?.should.be.false
26
+ end
27
+ end
28
+
29
+ describe "#+" do
30
+ it "should add objects to bag" do
31
+ bag = Bag.bag
32
+
33
+ # use + method to add object to bag
34
+ bag += Page.new(:text => "World", :index => 2)
35
+
36
+ bag.unsaved.count.should.be == 1
37
+ bag.changed?.should.be.true
38
+ bag.save
39
+
40
+ bag.unsaved.count.should.be == 0
41
+ bag.saved.count.should.be == 1
42
+ bag.changed?.should.be.false
43
+ end
44
+ end
45
+
46
+ describe "#delete" do
47
+ it "should delete object from bag" do
48
+ bag = Bag.bag
49
+
50
+ page = Page.new(:text => "Hello", :index => 1)
51
+ bag << page
52
+ bag << Page.new(:text => "World", :index => 2)
53
+ bag.save
54
+ bag.saved.count.should.be == 2
55
+
56
+ bag.delete(page)
57
+ bag.changed?.should.be.true
58
+ bag.removed.count.should.be == 1
59
+ bag.save
60
+ bag.saved.count.should.be == 1
61
+ end
62
+ end
63
+
64
+ describe "#store=" do
65
+ it "should store bag" do
66
+ store = MotionPrime::Store.create
67
+ bag = Bag.bag
68
+ bag.store = store
69
+ bag << Page.new(:text => "1")
70
+ bag.save
71
+ store.bags.size.should == 1
72
+ store.bags.first.to_a.first.text.should == "1"
73
+ end
74
+ end
75
+
76
+ describe "#to_a" do
77
+ it "convert a bag to array" do
78
+ bag = Bag.bag
79
+ bag << Page.new(:text => "1", :index => 1)
80
+ bag << Page.new(:text => "2", :index => 2)
81
+
82
+ bag.to_a.is_a?(Array).should.be.true
83
+ bag.to_a.size.should == 2
84
+
85
+ # #to_a is not ordered!
86
+ ["1", "2"].include?(bag.to_a[0].text).should.be.true
87
+ ["1", "2"].include?(bag.to_a[1].text).should.be.true
88
+ bag.save
89
+ bag.to_a.size.should == 2
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,158 @@
1
+ describe MotionPrime::BaseModel do
2
+ before do
3
+ MotionPrime::Store.connect
4
+ @store = MotionPrime::Store.shared_store
5
+ end
6
+
7
+ after do
8
+ @store.clear
9
+ end
10
+
11
+ describe "::new" do
12
+ it "create new object" do
13
+ user = stub_user("Bob", 10, Time.now)
14
+ user.save
15
+
16
+ user.info.keys.include?("name").should.be.true
17
+ user.info.keys.include?("age").should.be.true
18
+ user.info.keys.include?("created_at").should.be.true
19
+
20
+ user.info["name"].should == "Bob"
21
+ user.info["age"].should == 10
22
+ user.info["created_at"].should == user.created_at
23
+
24
+ user.name.should == "Bob"
25
+ user.age.should == 10
26
+ User.count.should == 1
27
+ end
28
+
29
+ it "create object with nil field" do
30
+ user = stub_user("Bob", 10, nil)
31
+ user.save
32
+ user.key.should.not.be.nil
33
+ end
34
+
35
+ it "throw error when invalid parameter" do
36
+ lambda {
37
+ user = User.new(:name => "Eddie", :age => 12, :created_at => Time.now, :gender => "m")
38
+ }.should.raise(::MotionPrime::StoreError)
39
+ end
40
+
41
+ end
42
+
43
+ describe "::create" do
44
+ it "create object with hash" do
45
+ name = "Abby"
46
+ age = 30
47
+ created_at = Time.now
48
+ user = User.create(:name => name, :age => age, :created_at => created_at)
49
+ user.name.should == name
50
+ user.age.should == age
51
+ user.created_at.should == created_at
52
+ end
53
+
54
+ it "create object in their class" do
55
+ @store.allObjectClasses.should == []
56
+ Autobot.create(:name => "Bumblebee")
57
+ @store.allObjectClasses.should == ["Autobot"]
58
+ end
59
+ end
60
+
61
+ describe "#save" do
62
+ it "if no store set, create objects using shared store" do
63
+ user = stub_user("Bob", 10, Time.now)
64
+ user.save
65
+ @store.count(User).should == 1
66
+ end
67
+
68
+ # per object store since NanoStore 2.5.1
69
+ it "user per instance store to save" do
70
+ store1 = MotionPrime::Store.create
71
+ user = stub_user("Bob", 10, Time.now)
72
+ user.store = store1
73
+ user.save
74
+ store1.count(User).should == 1
75
+
76
+ store2 = MotionPrime::Store.create
77
+ user2 = stub_user("Lee", 10, Time.now)
78
+ user2.store = store2
79
+ user2.save
80
+ store2.count(User).should == 1
81
+ store1.count(User).should == 1
82
+ end
83
+
84
+ it "update existing objects" do
85
+ user = stub_user("Bob", 10, Time.now)
86
+ user.save
87
+
88
+ user1 = User.find(:name, NSFEqualTo, "Bob").first
89
+ user1.name = "Dom"
90
+ user1.save
91
+
92
+ user2 = User.find(:name, NSFEqualTo, "Dom").first
93
+ user2.key.should == user.key
94
+ end
95
+
96
+ it "create with nil field" do
97
+ user = stub_user("Bob", 10, nil)
98
+ user.save
99
+
100
+ user1 = User.find(:name, NSFEqualTo, "Bob").first
101
+ user1.name.should == "Bob"
102
+ user1.created_at.should.be.nil
103
+ end
104
+
105
+ it "create model in file store" do
106
+ MotionPrime::Store.connect(:file)
107
+
108
+ user = stub_user("Bob", 10, nil)
109
+ user.save
110
+
111
+ user1 = User.find(:name, NSFEqualTo, "Bob").first
112
+ user1.name.should == "Bob"
113
+ user1.created_at.should.be.nil
114
+
115
+ File.delete(path) rescue nil
116
+ end
117
+ end
118
+
119
+ describe "#delete" do
120
+ it "delete object" do
121
+ user = stub_user("Bob", 10, Time.now)
122
+ user.save
123
+
124
+ users = User.find(:name, NSFEqualTo, "Bob")
125
+ users.should.not.be.nil
126
+ users.count.should == 1
127
+
128
+ user.delete
129
+ users = User.find(:name, NSFEqualTo, "Bob")
130
+ users.should.not.be.nil
131
+ users.count.should == 0
132
+ User.count.should == 0
133
+ end
134
+ end
135
+
136
+ describe "::delete" do
137
+ it "bulk delete" do
138
+ user = stub_user("Bob", 10, Time.now)
139
+ user.save
140
+
141
+ user = stub_user("Ken", 12, Time.now)
142
+ user.save
143
+
144
+ user = stub_user("Kyu", 14, Time.now)
145
+ user.save
146
+
147
+ plane = Plane.create(:name => "A730", :age => 20)
148
+
149
+ User.count.should == 3
150
+ User.delete({:age => {NSFGreaterThan => 10}})
151
+ User.count.should == 1
152
+
153
+ User.delete({})
154
+ User.count.should == 0
155
+ Plane.count.should == 1
156
+ end
157
+ end
158
+ end
@@ -0,0 +1,183 @@
1
+ describe "Finder" do
2
+ before do
3
+ MotionPrime::Store.connect
4
+ @store = MotionPrime::Store.shared_store
5
+
6
+ user = stub_user("Bob", 10, Time.now)
7
+ user.save
8
+
9
+ user2 = stub_user("Amy", 11, Time.now)
10
+ user2.save
11
+
12
+ user3 = stub_user("Carl", 4, Time.now)
13
+ user3.save
14
+ end
15
+
16
+ after do
17
+ @store.clear
18
+ end
19
+
20
+ describe "::find" do
21
+ it "search object traditional way: supply key, operator and value" do
22
+ users = User.find(:name, NSFEqualTo, "Bob")
23
+ users.should.not.be.nil
24
+ users.is_a?(Array).should.be.true
25
+
26
+ user = users.first
27
+ user.should.not.be.nil
28
+ user.name.should.be == "Bob"
29
+ user.age.should.be == 10
30
+ end
31
+
32
+ it "search object with simple hash" do
33
+ user = User.find(:name => "Carl").first
34
+ user.name.should.be == "Carl"
35
+ user.age.should.be == 4
36
+ end
37
+
38
+ it "search object with simple hash with two class" do
39
+ Car.create(:name => "Carl")
40
+ users = User.find(:name => "Carl")
41
+ users.size.should.be == 1
42
+ user = users.first
43
+ user.name.should.be == "Carl"
44
+ user.age.should.be == 4
45
+ end
46
+
47
+ it "search object with array (OR)" do
48
+ users = User.find(:name => ["Carl", "Amy"])
49
+ users.size.should == 2
50
+
51
+ users.collect(&:name).include?("Carl").should == true
52
+ users.collect(&:name).include?("Amy").should == true
53
+ users.collect(&:name).include?("Bob").should == false
54
+ end
55
+
56
+ it "search object with multiple parameters" do
57
+ stub_user("Ronald", 18, Time.now).save
58
+ stub_user("Ronald", 29, Time.now).save
59
+ stub_user("Ronald", 36, Time.now).save
60
+ stub_user("Ronald", 39, Time.now).save
61
+ stub_user("Ronald", 49, Time.now).save
62
+ stub_user("Ronald", 59, Time.now).save
63
+
64
+ users = User.find(:name => { NSFEqualTo => "Ronald" }, :age => { NSFGreaterThan => 50 })
65
+ users.size.should == 1
66
+ user = users.first
67
+ user.name.should.be == "Ronald"
68
+ user.age.should.be == 59
69
+
70
+ users = User.find(:name => { NSFEqualTo => "Ronald" }, :age => { NSFLessThan => 30 })
71
+ users.size.should == 2
72
+ user = users.first
73
+ user.name.should.be == "Ronald"
74
+ end
75
+
76
+ it "sort search results" do
77
+ stub_user("Alan", 39, Time.now).save
78
+ stub_user("Cat", 29, Time.now).save
79
+ stub_user("Dan", 36, Time.now).save
80
+ stub_user("Ted", 18, Time.now).save
81
+ stub_user("Zidd", 59, Time.now).save
82
+ stub_user("Sarah", 49, Time.now).save
83
+
84
+ users = User.find({:age => { NSFGreaterThan => 1 }}, {:sort => {:age => :asc}})
85
+ users.size.should == 9
86
+ user = users.first
87
+ user.name.should.be == "Carl"
88
+ user.age.should.be == 4
89
+ user = users.last
90
+ user.name.should.be == "Zidd"
91
+ user.age.should.be == 59
92
+
93
+ users = User.find({:age => { NSFGreaterThan => 1 }}, {:sort => {:age => 'DESC'}})
94
+ users.size.should == 9
95
+ user = users.last
96
+ user.name.should.be == "Carl"
97
+ user.age.should.be == 4
98
+ user = users.first
99
+ user.name.should.be == "Zidd"
100
+ user.age.should.be == 59
101
+ end
102
+
103
+ it "find object" do
104
+ users = User.find(:name, NSFEqualTo, "Bob")
105
+ users.size.should == 1
106
+
107
+ user = users.first
108
+ user.name.should == "Bob"
109
+ user.class.should == User
110
+ end
111
+
112
+ it "find object with quote" do
113
+ stub_user("Bob'd", 49, Time.now).save
114
+
115
+ users = User.find(:name, NSFEqualTo, "Bob'd")
116
+ users.size.should == 1
117
+
118
+ user = users.first
119
+ user.name.should == "Bob'd"
120
+ user.class.should == User
121
+ end
122
+
123
+ it "only return objects of the class" do
124
+ car = Car.create(:name => "Honda")
125
+ Car.find.size.should == 1
126
+ Car.find.first.key.should == car.key
127
+ end
128
+ end
129
+
130
+ describe "::find_by_key" do
131
+ it "should return object by key" do
132
+ name = "Julien"
133
+ age = 32
134
+ created_at = Time.now
135
+ user = stub_user("Julien", 32, Time.now)
136
+ user.save
137
+ user2 = User.find_by_key(user.key)
138
+ user2.should.not.be.nil
139
+ user2.key.should == user.key
140
+ user2.name.should == user.name
141
+ user2.age.should == user.age
142
+ end
143
+
144
+ it "should not find object by inexists key" do
145
+ User.find_by_key("invalid-key").should.be.nil
146
+ end
147
+ end
148
+
149
+ describe "::all" do
150
+ it "find all objects" do
151
+ User.count.should == 3
152
+ users = User.all
153
+ users.size.should == 3
154
+ end
155
+
156
+ it "find all objects, sorted" do
157
+ stub_user("Alan", 39, Time.now).save
158
+ stub_user("Cat", 29, Time.now).save
159
+ stub_user("Dan", 36, Time.now).save
160
+ stub_user("Ted", 18, Time.now).save
161
+ stub_user("Zidd", 59, Time.now).save
162
+ stub_user("Sarah", 49, Time.now).save
163
+
164
+ User.count.should == 9
165
+ users = User.all({:sort => {:age => :asc}})
166
+ users.size.should == 9
167
+ users.first.name.should == "Carl"
168
+ end
169
+
170
+ it "only return objects of the class" do
171
+ car = Car.create(:name => "Honda")
172
+ Car.count.should == 1
173
+ Car.all.size.should == 1
174
+ Car.all.first.key.should == car.key
175
+ end
176
+
177
+ it "only return objects of the class" do
178
+ car = Car.create(:name => "Honda")
179
+ Car.find_keys.size.should == 1
180
+ Car.find_keys.first.should == car.key
181
+ end
182
+ end
183
+ end