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,118 @@
1
+ module MotionPrime
2
+ module ModelMethods
3
+ def save
4
+ raise StoreError, 'No store provided' unless self.store
5
+
6
+ error_ptr = Pointer.new(:id)
7
+ self.store.addObject(self, error: error_ptr)
8
+ raise StoreError, error_ptr[0].description if error_ptr[0]
9
+ self
10
+ end
11
+
12
+ def delete
13
+ raise StoreError, 'No store provided' unless self.store
14
+
15
+ error_ptr = Pointer.new(:id)
16
+ self.store.removeObject(self, error: error_ptr)
17
+ raise StoreError, error_ptr[0].description if error_ptr[0]
18
+ self
19
+ end
20
+
21
+ def store
22
+ super || self.class.store
23
+ end
24
+ end
25
+
26
+ module ModelClassMethods
27
+ # Initialize a new object
28
+ #
29
+ # Examples:
30
+ # User.new(name: "Bob", age: 10)
31
+ #
32
+ # @return MotionPrime::BaseModel unsaved model
33
+ def new(data = {})
34
+ data.keys.each { |k|
35
+ unless self.attributes.member? k.to_sym
36
+ raise StoreError, "'#{k}' is not a defined attribute for this model"
37
+ end
38
+ }
39
+
40
+ object = self.nanoObjectWithDictionary(data)
41
+ object
42
+ end
43
+
44
+ # Initialize a new object and save it
45
+ #
46
+ # Examples:
47
+ # User.create(name: "Bob", age: 10)
48
+ #
49
+ # @return MotionPrime::BaseModel saved model
50
+ def create(data = {})
51
+ object = self.new(data)
52
+ object.save
53
+ end
54
+
55
+ # Define model attribute
56
+ #
57
+ # Examples:
58
+ # class User < MotionPrime::BaseModel
59
+ # attribute :name
60
+ # attribute :age
61
+ # end
62
+ #
63
+ # @return Nil
64
+ def attribute(name)
65
+ attributes << name
66
+
67
+ define_method(name) do |*args, &block|
68
+ self.info[name]
69
+ end
70
+
71
+ define_method((name + "=").to_sym) do |*args, &block|
72
+ self.info[name] = args[0]
73
+ end
74
+ end
75
+
76
+ # Return all model attribute names
77
+ #
78
+ # @return Array array of attribute names
79
+ def attributes(*attrs)
80
+ if attrs.size > 0
81
+ attrs.each{|attr| attribute attr}
82
+ else
83
+ @attributes ||= []
84
+ end
85
+ end
86
+
87
+ # Return store associated with model class, or shared store by default
88
+ #
89
+ # @return MotionPrime::Store store
90
+ def store
91
+ @store ||= MotionPrime::Store.shared_store
92
+ end
93
+
94
+ # Define store associated with model class
95
+ #
96
+ # @param MotionPrime::Store store
97
+ # @return MotionPrime::Store store
98
+ def store=(store)
99
+ @store = store
100
+ end
101
+
102
+ # Count of models
103
+ #
104
+ # @return Fixnum count
105
+ def count
106
+ self.store.count(self)
107
+ end
108
+
109
+ # Delete objects from store
110
+ #
111
+ # @param [Array, MotionPrime::BaseModel] objects to delete
112
+ # @return [Array] result
113
+ def delete(*args)
114
+ keys = find_keys(*args)
115
+ self.store.delete_keys(keys)
116
+ end
117
+ end
118
+ end
@@ -0,0 +1,53 @@
1
+ motion_require '../config/base.rb'
2
+ module MotionPrime
3
+ class Store
4
+ def self.create(type = nil, path = nil)
5
+ error_ptr = Pointer.new(:id)
6
+ case type || MotionPrime::Config.model.store_type.to_sym
7
+ when :memory
8
+ store = NSFNanoStore.createAndOpenStoreWithType(NSFMemoryStoreType, path: nil, error: error_ptr)
9
+ when :temporary, :temp
10
+ store = NSFNanoStore.createAndOpenStoreWithType(NSFTemporaryStoreType, path: nil, error: error_ptr)
11
+ when :persistent, :file
12
+ path ||= begin
13
+ documents_path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, true)[0]
14
+ documents_path + "/nano.db"
15
+ end
16
+ store = NSFNanoStore.createAndOpenStoreWithType(NSFPersistentStoreType, path: path, error: error_ptr)
17
+ else
18
+ raise StoreError.new("unexpected store type (#{type}), must be one of: :memory, :temporary or :persistent")
19
+ end
20
+
21
+ raise StoreError, error_ptr[0].description if error_ptr[0]
22
+ store
23
+ end
24
+
25
+ def self.connect!(type = nil)
26
+ self.shared_store = create(type)
27
+ end
28
+
29
+ def self.connect(type = nil)
30
+ connect!(type) unless connected?
31
+ end
32
+
33
+ def self.connected?
34
+ !!shared_store
35
+ end
36
+
37
+ def self.disconnect
38
+ self.shared_store = nil
39
+ end
40
+
41
+ def self.shared_store
42
+ @shared_store
43
+ end
44
+
45
+ def self.shared_store=(store)
46
+ @shared_store = store
47
+ end
48
+
49
+ def self.debug=(debug)
50
+ NSFSetIsDebugOn(debug)
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,159 @@
1
+ class NSFNanoStore
2
+ def engine
3
+ self.nanoStoreEngine
4
+ end
5
+
6
+ def changed?
7
+ self.hasUnsavedChanges
8
+ end
9
+
10
+ def save_interval=(interval)
11
+ self.setSaveInterval(interval)
12
+ end
13
+
14
+ ## Open and Close store
15
+
16
+ def close
17
+ error_ptr = Pointer.new(:id)
18
+ closed = self.closeWithError(error_ptr)
19
+ raise MotionPrime::StoreError, error_ptr[0].description if error_ptr[0]
20
+ closed
21
+ end
22
+
23
+ def open
24
+ error_ptr = Pointer.new(:id)
25
+ opened = self.openWithError(error_ptr)
26
+ raise MotionPrime::StoreError, error_ptr[0].description if error_ptr[0]
27
+ opened
28
+ end
29
+
30
+ def closed?
31
+ self.isClosed
32
+ end
33
+
34
+ ## Adding and Removing Objects
35
+
36
+ def <<(objects)
37
+ error_ptr = Pointer.new(:id)
38
+ if objects.is_a?(Array)
39
+ self.addObjectsFromArray(objects, error:error_ptr)
40
+ else
41
+ self.addObject(objects, error:error_ptr)
42
+ end
43
+ raise MotionPrime::StoreError, error_ptr[0].description if error_ptr[0]
44
+ self
45
+ end
46
+
47
+ def +(object)
48
+ error_ptr = Pointer.new(:id)
49
+ self.addObject(object, error:error_ptr)
50
+ raise MotionPrime::StoreError, error_ptr[0].description if error_ptr[0]
51
+ self
52
+ end
53
+
54
+ # delete a object or array of objects from the array
55
+ def delete(objects)
56
+ error_ptr = Pointer.new(:id)
57
+ if objects.is_a?(Array)
58
+ result = self.removeObjectsInArray(objects, error:error_ptr)
59
+ else
60
+ result = self.removeObject(objects, error:error_ptr)
61
+ end
62
+ raise MotionPrime::StoreError, error_ptr[0].description if error_ptr[0]
63
+ result
64
+ end
65
+
66
+ # Delete objects by keys
67
+ def delete_keys(keys)
68
+ error_ptr = Pointer.new(:id)
69
+ success = self.store.removeObjectsWithKeysInArray(keys, error: error_ptr)
70
+ raise MotionPrime::StoreError, error_ptr[0].description if error_ptr[0]
71
+ result
72
+ end
73
+
74
+
75
+ # delete all objects from store
76
+ def clear
77
+ error_ptr = Pointer.new(:id)
78
+ result = self.removeAllObjectsFromStoreAndReturnError(error_ptr)
79
+ raise MotionPrime::StoreError, error_ptr[0].description if error_ptr[0]
80
+ result
81
+ end
82
+
83
+ # delete object with keys
84
+ # param: keys - array of key
85
+ def delete_keys(keys)
86
+ error_ptr = Pointer.new(:id)
87
+ result = self.removeObjectsWithKeysInArray(keys, error:error_ptr)
88
+ raise MotionPrime::StoreError, error_ptr[0].description if error_ptr[0]
89
+ result
90
+ end
91
+
92
+ ## Save and Maintenance
93
+
94
+ # Saves the uncommitted changes to the document store.
95
+ def save
96
+ error_ptr = Pointer.new(:id)
97
+ result = saveStoreAndReturnError(error_ptr)
98
+ raise MotionPrime::StoreError, error_ptr[0].description if error_ptr[0]
99
+ result
100
+ end
101
+
102
+ # Discards the uncommitted changes that were added to the document store.
103
+ alias_method :discard, :discardUnsavedChanges
104
+
105
+ # Compact the database file size.
106
+ def compact
107
+ error_ptr = Pointer.new(:id)
108
+ result = self.compactStoreAndReturnError(error_ptr)
109
+ raise MotionPrime::StoreError, error_ptr[0].description if error_ptr[0]
110
+ result
111
+ end
112
+
113
+ # Remove all indexes from the document store.
114
+ def clear_index
115
+ error_ptr = Pointer.new(:id)
116
+ result = self.clearIndexesAndReturnError(error_ptr)
117
+ raise MotionPrime::StoreError, error_ptr[0].description if error_ptr[0]
118
+ result
119
+ end
120
+
121
+ # Recreate all indexes from the document store.
122
+ def rebuild_index
123
+ error_ptr = Pointer.new(:id)
124
+ result = self.rebuildIndexesAndReturnError(error_ptr)
125
+ raise MotionPrime::StoreError, error_ptr[0].description if error_ptr[0]
126
+ result
127
+ end
128
+
129
+ # Makes a copy of the document store to a different location and optionally compacts it to its minimum size.
130
+ def save_store(path, compact=true)
131
+ error_ptr = Pointer.new(:id)
132
+ result = self.saveStoreToDirectoryAtPath(path, compactDatabase:compact, error:error_ptr)
133
+ raise MotionPrime::StoreError, error_ptr[0].description if error_ptr[0]
134
+ result
135
+ end
136
+
137
+ # Count number of this class objects in store
138
+ def count(clazz)
139
+ self.countOfObjectsOfClassNamed(clazz.bare_class_name)
140
+ end
141
+
142
+ # Create a transaction
143
+ def transaction
144
+ error_ptr = Pointer.new(:id)
145
+ beginTransactionAndReturnError(error_ptr)
146
+ raise MotionPrime::StoreError, error_ptr[0].description if error_ptr[0]
147
+
148
+ begin
149
+ yield self
150
+ rescue StandardError => e
151
+ rollbackTransactionAndReturnError(error_ptr)
152
+ raise e
153
+ end
154
+ success = commitTransactionAndReturnError(error_ptr)
155
+ raise MotionPrime::StoreError, error_ptr[0].description if error_ptr[0]
156
+ success
157
+ end
158
+
159
+ end
@@ -1,5 +1,9 @@
1
1
  motion_require '../views/styles.rb'
2
2
  MotionPrime::Styles.define :base do
3
+ # basic screen styles
4
+ style :screen,
5
+ background_color: :white
6
+
3
7
  # basic table styles
4
8
  # ----------
5
9
  style :table,
@@ -1,6 +1,6 @@
1
1
  class DMViewController < UIViewController
2
2
  def self.new(args = {})
3
- s = self.alloc.initWithNibName(nil, bundle:nil)
3
+ s = self.alloc.initWithNibName(nil, bundle: nil)
4
4
  s.on_create(args) if s.respond_to?(:on_create)
5
5
  s
6
6
  end
@@ -1,3 +1,3 @@
1
1
  module MotionPrime
2
- VERSION = "0.1.0"
2
+ VERSION = "0.1.1"
3
3
  end
@@ -0,0 +1,73 @@
1
+ describe MotionPrime::Config do
2
+ before { @config = MotionPrime::Config.new }
3
+
4
+ describe "[]" do
5
+ before { @config = MotionPrime::Config.new(foo: "bar") }
6
+
7
+ it "returns the value if there is one" do
8
+ @config[:foo].should == "bar"
9
+ @config["foo"].should == "bar"
10
+ end
11
+
12
+ it "returns a new Configatron::Store object if there is no value" do
13
+ @config[:unknown].is_a?(MotionPrime::Config).should == true
14
+ @config["unknown"].is_a?(MotionPrime::Config).should == true
15
+ end
16
+ end
17
+
18
+ describe "[]=" do
19
+ it "sets the value" do
20
+ @config[:foo] = "bar"
21
+ @config[:foo].should == "bar"
22
+ @config["foo"].should == "bar"
23
+
24
+ @config[:baz] = "bazzy"
25
+ @config[:baz].should == "bazzy"
26
+ @config["baz"].should == "bazzy"
27
+ end
28
+ end
29
+
30
+ describe "nil?" do
31
+ it "returns true if there is no value set" do
32
+ @config.foo.nil?.should == true
33
+ @config.foo = "bar"
34
+ @config.foo.nil?.should == false
35
+ end
36
+ end
37
+
38
+ describe "class methods" do
39
+ it "should allow to set value for class" do
40
+ MotionPrime::Config.foo.nil?.should == true
41
+ MotionPrime::Config.foo = "bar"
42
+ MotionPrime::Config.foo.should == "bar"
43
+ end
44
+ end
45
+
46
+ describe "has_key?" do
47
+ it "returns true if there is a key" do
48
+ @config.has_key?(:foo).should == false
49
+ @config.foo = "bar"
50
+ @config.has_key?(:foo).should == true
51
+ end
52
+
53
+ it "returns false if the key is a MotionPrime::Config" do
54
+ @config.has_key?(:foo).should == false
55
+ @config.foo = MotionPrime::Config.new
56
+ @config.has_key?(:foo).should == false
57
+ end
58
+ end
59
+
60
+ describe "configuring with a block" do
61
+ before do
62
+ @config.a.b = 'B'
63
+ end
64
+
65
+ it "yields the store to configure" do
66
+ @config.a do |a|
67
+ a.c = 'C'
68
+ end
69
+ @config.a.b.should == 'B'
70
+ @config.a.c.should == 'C'
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,12 @@
1
+ describe "base delegate" do
2
+
3
+ before { @subject = BaseDelegate.new }
4
+
5
+ it 'should call on_load on launch' do
6
+ @subject.mock!(:on_load) do |app, options|
7
+ app.should.be.kind_of(UIApplication)
8
+ end
9
+
10
+ @subject.application(UIApplication.sharedApplication, didFinishLaunchingWithOptions: {})
11
+ end
12
+ end