bubble-wrap 0.3.1 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. data/CHANGELOG.md +5 -0
  2. data/README.md +183 -66
  3. data/Rakefile +6 -6
  4. data/bubble-wrap.gemspec +10 -5
  5. data/lib/bubble-wrap.rb +4 -39
  6. data/lib/bubble-wrap/core.rb +7 -0
  7. data/lib/bubble-wrap/ext.rb +2 -0
  8. data/lib/bubble-wrap/ext/motion_project_app.rb +26 -0
  9. data/lib/bubble-wrap/ext/motion_project_config.rb +21 -0
  10. data/lib/bubble-wrap/http.rb +2 -249
  11. data/lib/bubble-wrap/loader.rb +23 -0
  12. data/lib/bubble-wrap/requirement.rb +88 -0
  13. data/lib/bubble-wrap/requirement/path_manipulation.rb +40 -0
  14. data/lib/bubble-wrap/version.rb +1 -1
  15. data/lib_spec/bubble-wrap/requirement/path_manipulation_spec.rb +51 -0
  16. data/lib_spec/bubble-wrap/requirement_spec.rb +72 -0
  17. data/lib_spec/bubble-wrap_spec.rb +17 -0
  18. data/lib_spec/motion_stub.rb +12 -0
  19. data/{lib/bubble-wrap/module.rb → motion/core.rb} +0 -0
  20. data/{lib/bubble-wrap → motion/core}/app.rb +0 -0
  21. data/{lib/bubble-wrap → motion/core}/device.rb +0 -16
  22. data/{lib/bubble-wrap → motion/core}/device/screen.rb +0 -0
  23. data/{lib/bubble-wrap → motion/core}/gestures.rb +0 -0
  24. data/{lib/bubble-wrap → motion/core}/json.rb +0 -0
  25. data/{lib/bubble-wrap → motion/core}/ns_index_path.rb +0 -0
  26. data/{lib/bubble-wrap → motion/core}/ns_notification_center.rb +0 -0
  27. data/{lib/bubble-wrap → motion/core}/ns_user_defaults.rb +0 -0
  28. data/{lib/bubble-wrap → motion/core}/persistence.rb +0 -0
  29. data/{lib → motion/core}/pollute.rb +1 -1
  30. data/motion/core/string.rb +38 -0
  31. data/{lib/bubble-wrap → motion/core}/time.rb +0 -0
  32. data/{lib/bubble-wrap → motion/core}/ui_control.rb +0 -0
  33. data/{lib/bubble-wrap → motion/core}/ui_view_controller.rb +0 -0
  34. data/motion/http.rb +249 -0
  35. data/spec/{app_spec.rb → core/app_spec.rb} +2 -2
  36. data/spec/{device → core/device}/screen_spec.rb +0 -0
  37. data/spec/{device_spec.rb → core/device_spec.rb} +0 -0
  38. data/spec/{gestures_spec.rb → core/gestures_spec.rb} +0 -0
  39. data/spec/{json_spec.rb → core/json_spec.rb} +0 -0
  40. data/spec/{ns_index_path_spec.rb → core/ns_index_path_spec.rb} +0 -0
  41. data/spec/{ns_notification_center_spec.rb → core/ns_notification_center_spec.rb} +0 -0
  42. data/spec/{persistence_spec.rb → core/persistence_spec.rb} +0 -0
  43. data/spec/core/string_spec.rb +69 -0
  44. data/spec/{time_spec.rb → core/time_spec.rb} +0 -0
  45. data/spec/{ui_control_spec.rb → core/ui_control_spec.rb} +0 -0
  46. data/spec/{module_spec.rb → core_spec.rb} +0 -0
  47. data/spec/http_spec.rb +300 -280
  48. metadata +115 -42
data/CHANGELOG.md CHANGED
@@ -1,3 +1,8 @@
1
+ ## 0.4.0
2
+
3
+ * Refactored the code and test suite to be more modular and to handle
4
+ dependencies. One can now require only a subset of BW such as `require 'bubble-wrap/core'` or 'bubble-wrap/http'
5
+
1
6
  ## 0.3.1
2
7
 
3
8
  * Added App.run_after(delay){ }
data/README.md CHANGED
@@ -1,6 +1,8 @@
1
1
  # BubbleWrap for RubyMotion
2
2
 
3
- A collection of helpers and wrappers used to wrap CocoaTouch code and provide more Ruby like APIs.
3
+ A collection of (tested) helpers and wrappers used to wrap CocoaTouch code and provide more Ruby like APIs.
4
+
5
+ [BubbleWrap website](http://bubblewrap.io)
4
6
 
5
7
  ## Installation
6
8
 
@@ -10,80 +12,50 @@ gem install bubble-wrap
10
12
 
11
13
  ## Setup
12
14
 
13
- 1. Edit the Rakefile of your RubyMotion project and add the following require line.
15
+ 1. Edit the `Rakefile` of your RubyMotion project and add the following require line.
16
+
14
17
  ```ruby
15
18
  require 'bubble-wrap'
16
19
  ```
17
- Note: **DON'T** use `app.files =` in your Rakefile to set up your files once you've required BubbleWrap.
18
- Make sure to append onto the array or use `+=`.
19
20
 
20
- 2. Now, you can use BubbleWrap extension in your app:
21
+ BubbleWrap is split into multiple modules so that you can easily choose which parts
22
+ are included at compile-time.
23
+
24
+ The above example requires all the wrappers/helpers. If you wish to only
25
+ include the core modules use the following line of code instead:
21
26
 
22
27
  ```ruby
23
- class AppDelegate
24
- def application(application, didFinishLaunchingWithOptions:launchOptions)
25
- puts "#{App.name} (#{documents_path})"
26
- true
27
- end
28
- end
28
+ require 'bubble-wrap/core'
29
29
  ```
30
30
 
31
- For a more complete list of helper/wrapper descriptions and more details, see the [wiki](https://github.com/mattetti/BubbleWrap/wiki).
32
-
33
- ## HTTP
34
-
35
- `BubbleWrap::HTTP` wraps `NSURLRequest`, `NSURLConnection` and friends to provide Ruby developers with a more familiar and easier to use API.
36
- The API uses async calls and blocks to stay as simple as possible.
37
-
38
- Usage example:
31
+ If you wish to only include the `HTTP` wrapper:
39
32
 
40
33
  ```ruby
41
- BubbleWrap::HTTP.get("https://api.github.com/users/mattetti") do |response|
42
- p response.body.to_str
43
- end
34
+ require 'bubble-wrap/http'
44
35
  ```
45
36
 
46
- ```ruby
47
- BubbleWrap::HTTP.get("https://api.github.com/users/mattetti", {credentials: {username: 'matt', password: 'aimonetti'}}) do |response|
48
- p response.body.to_str # prints the response's body
49
- end
50
- ```
37
+
38
+ Note: **DON'T** use `app.files =` in your Rakefile to set up your files once you've required BubbleWrap.
39
+ Make sure to append onto the array or use `+=`.
40
+
41
+ 2. Now, you can use BubbleWrap extension in your app:
51
42
 
52
43
  ```ruby
53
- data = {first_name: 'Matt', last_name: 'Aimonetti'}
54
- BubbleWrap::HTTP.post("http://foo.bar.com/", {payload: data}) do |response|
55
- if response.ok?
56
- json = BubbleWrap::JSON.parse(response.body.to_str)
57
- p json['id']
58
- elsif response.status_code.to_s =~ /40\d/
59
- alert("Login failed") # helper provided by the kernel file in this repo.
60
- else
61
- alert(response.error_message)
44
+ class AppDelegate
45
+ def application(application, didFinishLaunchingWithOptions:launchOptions)
46
+ puts "#{App.name} (#{documents_path})"
47
+ true
62
48
  end
63
49
  end
64
50
  ```
65
51
 
66
- ## JSON
52
+ Note: You can also vendor this repository but the recommended way is to
53
+ use the versioned gem.
67
54
 
68
- `BubbleWrap::JSON` wraps `NSJSONSerialization` available in iOS5 and offers the same API as Ruby's JSON std lib.
69
-
70
- ## Device
71
55
 
72
- A collection of useful methods about the current device:
73
-
74
- Examples:
75
- ```ruby
76
- > Device.iphone?
77
- # true
78
- > Device.ipad?
79
- # false
80
- > Device.orientation
81
- # :portrait
82
- > Device.simulator?
83
- # true
84
- ```
56
+ ## Core
85
57
 
86
- ## App
58
+ ### App
87
59
 
88
60
  A module with useful methods related to the running application
89
61
 
@@ -100,18 +72,53 @@ A module with useful methods related to the running application
100
72
  # creates and shows an alert message.
101
73
  > App.run_after(0.5) { p "It's #{Time.now}" }
102
74
  # Runs the block after 0.5 seconds.
75
+ > App::Persistence['channels'] # application specific persistence storage
76
+ # ['NBC', 'ABC', 'Fox', 'CBS', 'PBS']
77
+ > App::Persistence['channels'] = ['TF1', 'France 2', 'France 3']
78
+ # ['TF1', 'France 2', 'France 3']
103
79
  ```
104
80
 
105
- ## NSUserDefaults
81
+ Other available methods:
106
82
 
107
- Helper methods added to the class repsonsible for user preferences.
83
+ * `App.notification_center`
84
+ * `App.user_cache`
85
+ * `App.states`
86
+ * `App.frame`
87
+ * `App.delegate`
88
+ * `App.current_locale`
108
89
 
109
- ## NSIndexPath
110
90
 
111
- Helper methods added to give `NSIndexPath` a bit more of a Ruby
112
- interface.
91
+ ### Device
92
+
93
+ A collection of useful methods about the current device:
94
+
95
+ Examples:
96
+ ```ruby
97
+ > Device.iphone?
98
+ # true
99
+ > Device.ipad?
100
+ # false
101
+ > Device.front_camera?
102
+ # true
103
+ > Device.rear_camera?
104
+ # true
105
+ > Device.orientation
106
+ # :portrait
107
+ > Device.simulator?
108
+ # true
109
+ > Device.retina?
110
+ # false
111
+ > Device.screen.width
112
+ # 320
113
+ > Device.screen.height
114
+ # 480
115
+ > Device.screen.widthForOrientation(:landscape_left)
116
+ # 480
117
+ > Device.screen.heightForOrientation(:landscape_left)
118
+ # 320
119
+ ```
113
120
 
114
- ## Gestures
121
+ ### Gestures
115
122
 
116
123
  Extra methods on `UIView` for working with gesture recognizers. A gesture recognizer can be added using a normal Ruby block, like so:
117
124
 
@@ -127,17 +134,26 @@ Extra methods on `UIView` for working with gesture recognizers. A gesture recogn
127
134
 
128
135
  There are similar methods for pinched, rotated, swiped, panned, and pressed (for long presses). All of the methods return the actual recognizer object, so it is possible to set the delegate if more fine-grained control is needed.
129
136
 
130
- ## UIButton
131
137
 
132
- Helper methods to give `UIButton` a Ruby-like interface. Ex:
138
+
139
+ ### JSON
140
+
141
+ `BubbleWrap::JSON` wraps `NSJSONSerialization` available in iOS5 and offers the same API as Ruby's JSON std lib.
133
142
 
134
143
  ```ruby
135
- button.when(UIControlEventTouchUpInside) do
136
- self.view.backgroundColor = UIColor.redColor
137
- end
144
+ BW::JSON.generate({'foo => 1, 'bar' => [1,2,3], 'baz => 'awesome'})
145
+ => "{\"foo\":1,\"bar\":[1,2,3],\"baz\":\"awesome\"}"
146
+ BW::JSON.parse "{\"foo\":1,\"bar\":[1,2,3],\"baz\":\"awesome\"}"
147
+ => {"foo"=>1, "bar"=>[1, 2, 3], "baz"=>"awesome"}
138
148
  ```
139
149
 
140
- ## NSNotificationCenter
150
+ ### NSIndexPath
151
+
152
+ Helper methods added to give `NSIndexPath` a bit more of a Ruby
153
+ interface.
154
+
155
+
156
+ ### NSNotificationCenter
141
157
 
142
158
  Helper methods to give NSNotificationCenter a Ruby-like interface:
143
159
 
@@ -161,3 +177,104 @@ def reload
161
177
  notification_center.post ReloadNotification
162
178
  end
163
179
  ```
180
+
181
+
182
+ ### NSUserDefaults
183
+
184
+ Helper methods added to the class repsonsible for user preferences used
185
+ by the `App::Persistence` module shown below.
186
+
187
+ ### Persistence
188
+
189
+ Offers a way to persist application specific information using a very
190
+ simple interface:
191
+
192
+ ``` ruby
193
+ > App::Persistence['channels'] # application specific persistence storage
194
+ # ['NBC', 'ABC', 'Fox', 'CBS', 'PBS']
195
+ > App::Persistence['channels'] = ['TF1', 'France 2', 'France 3']
196
+ # ['TF1', 'France 2', 'France 3']
197
+ ```
198
+
199
+ ### String
200
+
201
+ The Ruby `String` class was extended to add `#camelize` and
202
+ `#underscore` methods.
203
+
204
+ ```ruby
205
+ > "matt_aimonetti".camelize
206
+ => "MattAimonetti"
207
+ > "MattAimonetti".underscore
208
+ => "matt_aimonetti"
209
+ ```
210
+
211
+ ### Time
212
+
213
+ The `Time` Ruby class was added a class level method to convert a
214
+ iso8601 formatted string into a Time instance.
215
+
216
+ ```ruby
217
+ > Time.iso8601("2012-05-31T19:41:33Z")
218
+ => 2012-05-31 21:41:33 +0200
219
+ ```
220
+
221
+ ### UIControl / UIButton
222
+
223
+ Helper methods to give `UIButton` a Ruby-like interface. Ex:
224
+
225
+ ```ruby
226
+ button.when(UIControlEventTouchUpInside) do
227
+ self.view.backgroundColor = UIColor.redColor
228
+ end
229
+ ```
230
+
231
+ ### UIViewController
232
+
233
+ A custom method was added to `UIViewController` to return the content
234
+ frame of a view controller.
235
+
236
+
237
+ ## HTTP
238
+
239
+ `BubbleWrap::HTTP` wraps `NSURLRequest`, `NSURLConnection` and friends to provide Ruby developers with a more familiar and easier to use API.
240
+ The API uses async calls and blocks to stay as simple as possible.
241
+
242
+ To enable it add the following require line to your `Rakefile`:
243
+ ```ruby
244
+ require 'bubble-wrap/http'
245
+ ```
246
+
247
+ Usage example:
248
+
249
+ ```ruby
250
+ BubbleWrap::HTTP.get("https://api.github.com/users/mattetti") do |response|
251
+ p response.body.to_str
252
+ end
253
+ ```
254
+
255
+ ```ruby
256
+ BubbleWrap::HTTP.get("https://api.github.com/users/mattetti", {credentials: {username: 'matt', password: 'aimonetti'}}) do |response|
257
+ p response.body.to_str # prints the response's body
258
+ end
259
+ ```
260
+
261
+ ```ruby
262
+ data = {first_name: 'Matt', last_name: 'Aimonetti'}
263
+ BubbleWrap::HTTP.post("http://foo.bar.com/", {payload: data}) do |response|
264
+ if response.ok?
265
+ json = BubbleWrap::JSON.parse(response.body.to_str)
266
+ p json['id']
267
+ elsif response.status_code.to_s =~ /40\d/
268
+ alert("Login failed") # helper provided by the kernel file in this repo.
269
+ else
270
+ alert(response.error_message)
271
+ end
272
+ end
273
+ ```
274
+
275
+
276
+
277
+ Do you have a suggestion for a specific wrapper? Feel free to open an
278
+ issue/ticket and tell us about what you are after. If you have a
279
+ wrapper/helper you are using and are thinking that others might enjoy,
280
+ please send a pull request (with tests if possible).
data/Rakefile CHANGED
@@ -1,6 +1,12 @@
1
1
  require "bundler/gem_tasks"
2
2
  $:.unshift("/Library/RubyMotion/lib")
3
3
  require 'motion/project'
4
+ require File.expand_path '../lib/bubble-wrap', __FILE__
5
+ require File.expand_path '../lib/bubble-wrap/http', __FILE__
6
+
7
+ task :rspec do
8
+ sh "rspec lib_spec/"
9
+ end
4
10
 
5
11
  Motion::Project::App.setup do |app|
6
12
  app.name = 'testSuite'
@@ -10,10 +16,4 @@ Motion::Project::App.setup do |app|
10
16
  app.files << './lib/tests/test_suite_delegate.rb'
11
17
  app.delegate_class = 'TestSuiteDelegate'
12
18
  end
13
-
14
- app.files += Dir.glob('./lib/bubble-wrap/**/*.rb')
15
- wrapper_files = app.files.dup
16
- pollution_file = Dir.glob('./lib/pollute.rb')[0]
17
- app.files << pollution_file
18
- app.files_dependencies pollution_file => wrapper_files
19
19
  end
data/bubble-wrap.gemspec CHANGED
@@ -2,15 +2,20 @@
2
2
  require File.expand_path('../lib/bubble-wrap/version', __FILE__)
3
3
 
4
4
  Gem::Specification.new do |gem|
5
- gem.authors = ["Matt Aimonetti", "Francis Chong"]
6
- gem.email = ["mattaimonetti@gmail.com", "francis@ignition.hk"]
5
+ gem.authors = ["Matt Aimonetti", "Francis Chong", "James Harton"]
6
+ gem.email = ["mattaimonetti@gmail.com", "francis@ignition.hk", "james@sociable.co.nz"]
7
7
  gem.description = "RubyMotion wrappers and helpers (Ruby for iOS) - Making Cocoa APIs more Ruby like, one API at a time. Fork away and send your pull request."
8
8
  gem.summary = "RubyMotion wrappers and helpers (Ruby for iOS) - Making Cocoa APIs more Ruby like, one API at a time. Fork away and send your pull request."
9
- gem.homepage = "https://github.com/mattetti/BubbleWrap"
9
+ gem.homepage = "http://bubblewrap.io/"
10
10
 
11
11
  gem.files = `git ls-files`.split($\)
12
- gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
12
+ gem.test_files = gem.files.grep(%r{^(test|spec|lib_spec|features)/})
13
13
  gem.name = "bubble-wrap"
14
14
  gem.require_paths = ["lib"]
15
15
  gem.version = BubbleWrap::VERSION
16
- end
16
+
17
+ gem.extra_rdoc_files = gem.files.grep(%r{motion})
18
+
19
+ gem.add_development_dependency 'rspec'
20
+ gem.add_development_dependency 'rake'
21
+ end
data/lib/bubble-wrap.rb CHANGED
@@ -1,39 +1,4 @@
1
- require "bubble-wrap/version"
2
-
3
- unless defined?(Motion::Project::Config)
4
- raise "This file must be required within a RubyMotion project Rakefile."
5
- end
6
-
7
- module Motion
8
- module Project
9
- class Config
10
- # HACK NEEDED since RubyMotion doesn't support full path
11
- # dependencies.
12
- def files_dependencies(deps_hash)
13
- res_path = lambda do |x|
14
- path = /^\.?\//.match(x) ? x : File.join('.', x)
15
- unless @files.include?(path)
16
- App.fail "Can't resolve dependency `#{x}' because #{path} is not in #{@files.inspect}"
17
- end
18
- path
19
- end
20
- deps_hash.each do |path, deps|
21
- deps = [deps] unless deps.is_a?(Array)
22
- @dependencies[res_path.call(path)] = deps.map(&res_path)
23
- end
24
- end
25
- end
26
- end
27
- end
28
-
29
-
30
- Motion::Project::App.setup do |app|
31
- wrapper_files = []
32
- Dir.glob(File.join(File.dirname(__FILE__), 'bubble-wrap/**/*.rb')).each do |file|
33
- app.files << file
34
- wrapper_files << file
35
- end
36
- pollution_file = File.expand_path(File.join(File.dirname(__FILE__), 'pollute.rb'))
37
- app.files.unshift pollution_file
38
- app.files_dependencies pollution_file => wrapper_files
39
- end
1
+ require "bubble-wrap/version" unless defined?(BubbleWrap::VERSION)
2
+ require File.expand_path('../bubble-wrap/loader', __FILE__)
3
+ require File.expand_path('../bubble-wrap/core', __FILE__)
4
+ require File.expand_path('../bubble-wrap/http', __FILE__)
@@ -0,0 +1,7 @@
1
+ require File.expand_path('../loader.rb', __FILE__)
2
+ BubbleWrap.require('motion/core.rb')
3
+ BubbleWrap.require('motion/core/**/*.rb') do
4
+ file('motion/core/device/screen.rb').depends_on 'motion/core/device.rb'
5
+ file('motion/core/pollute.rb').depends_on 'motion/core/ns_index_path.rb'
6
+ file('motion/core/pollute.rb').depends_on 'motion/core/ui_control.rb'
7
+ end
@@ -0,0 +1,2 @@
1
+ require File.expand_path('../ext/motion_project_config', __FILE__)
2
+ require File.expand_path('../ext/motion_project_app', __FILE__)
@@ -0,0 +1,26 @@
1
+ module BubbleWrap
2
+ module Ext
3
+ module BuildTask
4
+
5
+ def self.extended(base)
6
+ base.instance_eval do
7
+ def setup_with_bubblewrap(&block)
8
+ bw_config = proc do |app|
9
+ app.files = ::BubbleWrap::Requirement.files + Dir.glob('./app/**/*.rb')
10
+ app.files_dependencies ::BubbleWrap::Requirement.files_dependencies
11
+ app.frameworks = ::BubbleWrap::Requirement.frameworks
12
+ block.call(app)
13
+ end
14
+ configs.each_value &bw_config
15
+ config.validate
16
+ end
17
+ alias :setup_without_bubblewrap :setup
18
+ alias :setup :setup_with_bubblewrap
19
+ end
20
+ end
21
+
22
+ end
23
+ end
24
+ end
25
+
26
+ Motion::Project::App.extend(BubbleWrap::Ext::BuildTask)