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,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