bubble-wrap 1.4.0 → 1.5.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +2 -1
  3. data/Gemfile.lock +1 -1
  4. data/README.md +22 -2
  5. data/bubble-wrap.gemspec +7 -7
  6. data/lib/bubble-wrap.rb +1 -1
  7. data/lib/bubble-wrap/core.rb +3 -3
  8. data/lib/bubble-wrap/ext.rb +0 -1
  9. data/lib/bubble-wrap/ext/motion_project_app.rb +4 -3
  10. data/lib/bubble-wrap/loader.rb +3 -3
  11. data/lib/bubble-wrap/media.rb +2 -0
  12. data/lib/bubble-wrap/requirement.rb +1 -1
  13. data/lib/bubble-wrap/version.rb +2 -2
  14. data/motion/core/device/ios/camera.rb +33 -3
  15. data/motion/core/device/ios/camera_wrapper.rb +10 -0
  16. data/motion/core/kvo.rb +18 -2
  17. data/motion/core/ns_notification_center.rb +1 -0
  18. data/motion/core/time.rb +5 -0
  19. data/motion/http/query.rb +15 -9
  20. data/motion/location/location.rb +3 -2
  21. data/motion/mail/mail.rb +2 -1
  22. data/motion/media/player.rb +10 -2
  23. data/motion/reactor.rb +2 -0
  24. data/motion/reactor/periodic_timer.rb +2 -1
  25. data/motion/shortcut.rb +8 -0
  26. data/motion/sms/sms.rb +2 -0
  27. data/motion/ui/ui_alert_view.rb +2 -0
  28. data/motion/ui/ui_bar_button_item.rb +12 -2
  29. data/motion/ui/ui_control_wrapper.rb +1 -0
  30. data/motion/ui/ui_view_wrapper.rb +5 -0
  31. data/samples/osx/Gemfile.lock +7 -3
  32. data/spec/motion/core/device/ios/camera_spec.rb +6 -0
  33. data/spec/motion/core/device/ios/camera_wrapper_spec.rb +51 -2
  34. data/spec/motion/core/kvo_spec.rb +27 -0
  35. data/spec/motion/core/ns_notification_center_spec.rb +3 -3
  36. data/spec/motion/core/time_spec.rb +13 -4
  37. data/spec/motion/core_spec.rb +0 -1
  38. data/spec/motion/http/query_spec.rb +5 -5
  39. data/spec/motion/http_spec.rb +1 -1
  40. data/spec/motion/location/location_spec.rb +2 -2
  41. data/spec/motion/mail/mail_spec.rb +1 -1
  42. data/spec/motion/media/player_spec.rb +34 -12
  43. data/spec/motion/ui/ui_bar_button_item_spec.rb +76 -0
  44. data/spec/motion/ui/ui_control_wrapper_spec.rb +38 -0
  45. data/spec/motion/ui/ui_view_wrapper_spec.rb +42 -0
  46. metadata +4 -6
  47. data/lib/bubble-wrap/ext/motion_project_config.rb +0 -34
@@ -88,7 +88,11 @@ module BubbleWrap
88
88
  if display_modal
89
89
  @presenting_controller = options[:controller]
90
90
  @presenting_controller ||= App.window.rootViewController
91
- @presenting_controller.presentMoviePlayerViewControllerAnimated(@media_player)
91
+ if Device.ios_version < "7.0"
92
+ @presenting_controller.presentMoviePlayerViewControllerAnimated(@media_player)
93
+ else
94
+ @presenting_controller.presentViewController(@media_player, animated:true, completion:nil)
95
+ end
92
96
  else
93
97
  if block.nil?
94
98
  raise Error::NilPlayerCallback, "no block callback given in #play; you need\
@@ -105,7 +109,11 @@ module BubbleWrap
105
109
  # Stops playback for a Media::Player
106
110
  def stop
107
111
  if @media_player.is_a? MPMoviePlayerViewController
108
- @presenting_controller.dismissMoviePlayerViewControllerAnimated
112
+ if Device.ios_version < "7.0"
113
+ @presenting_controller.dismissMoviePlayerViewControllerAnimated
114
+ else
115
+ @presenting_controller.dismissViewControllerAnimated(true, completion:nil)
116
+ end
109
117
  @presenting_controller = nil
110
118
  else
111
119
  @media_player.stop
data/motion/reactor.rb CHANGED
@@ -86,6 +86,7 @@ module BubbleWrap
86
86
  # Schedule a block for execution on the reactor queue.
87
87
  def schedule(*args, &blk)
88
88
  @queue ||= ::Dispatch::Queue.concurrent("#{NSBundle.mainBundle.bundleIdentifier}.reactor")
89
+ blk.weak! if blk && BubbleWrap.use_weak_callbacks?
89
90
 
90
91
  cb = proc do
91
92
  blk.call(*args)
@@ -98,6 +99,7 @@ module BubbleWrap
98
99
  # This is useful as UI updates need to be executed from the main
99
100
  # thread.
100
101
  def schedule_on_main(*args, &blk)
102
+ blk.weak! if blk && BubbleWrap.use_weak_callbacks?
101
103
  cb = proc do
102
104
  blk.call(*args)
103
105
  end
@@ -10,7 +10,8 @@ module BubbleWrap
10
10
  def initialize(interval, *args, &blk)
11
11
  callback = args.first.respond_to?(:call) ? args.first : blk
12
12
  raise ArgumentError, "No callback or block supplied to periodic timer" unless callback
13
-
13
+ callback.weak! if callback && BubbleWrap.use_weak_callbacks?
14
+
14
15
  options = args.last.is_a?(Hash) ? args.last : {}
15
16
  if options[:common_modes]
16
17
  NSLog "[DEPRECATED - Option :common_modes] a Run Loop Mode is no longer needed."
data/motion/shortcut.rb CHANGED
@@ -13,6 +13,14 @@ module BubbleWrap
13
13
  BubbleWrap::SETTINGS[:debug]
14
14
  end
15
15
 
16
+ def self.use_weak_callbacks=(val)
17
+ BubbleWrap::SETTINGS[:use_weak_callbacks] = val
18
+ end
19
+
20
+ def self.use_weak_callbacks?
21
+ BubbleWrap::SETTINGS[:use_weak_callbacks]
22
+ end
23
+
16
24
  end
17
25
 
18
26
  BW = BubbleWrap unless defined?(BW)
data/motion/sms/sms.rb CHANGED
@@ -22,6 +22,8 @@ module BubbleWrap
22
22
  def compose(options={}, &callback)
23
23
  @delegate = options[:delegate] || App.window.rootViewController
24
24
  @callback = callback
25
+ @callback.weak! if @callback && BubbleWrap.use_weak_callbacks?
26
+
25
27
  @message_controller = create_message_controller(options)
26
28
  @message_is_animated = options[:animated] == false ? false : true
27
29
  @delegate.presentModalViewController(@message_controller, animated: @message_is_animated)
@@ -28,6 +28,8 @@ module BW
28
28
  view.cancel_button_index = options[:cancel_button_index]
29
29
 
30
30
  view.instance_variable_set(:@handlers, {})
31
+ block.weak! if block && BubbleWrap.use_weak_callbacks?
32
+
31
33
  options[:on_click] ||= block
32
34
 
33
35
  callbacks.each do |callback|
@@ -2,7 +2,12 @@ module BW
2
2
  class UIBarButtonItem < ::UIBarButtonItem
3
3
  class << self
4
4
  def styled(type, *objects, &block)
5
- action = block ? :call : nil
5
+ if block.nil?
6
+ action = nil
7
+ else
8
+ block.weak! if BubbleWrap.use_weak_callbacks?
9
+ action = :call
10
+ end
6
11
  object = objects.size == 1 ? objects.first : objects
7
12
  style = Constants.get("UIBarButtonItemStyle", type)
8
13
 
@@ -34,7 +39,12 @@ module BW
34
39
  end
35
40
 
36
41
  def system(type, &block)
37
- action = block ? :call : nil
42
+ if block.nil?
43
+ action = nil
44
+ else
45
+ block.weak! if BubbleWrap.use_weak_callbacks?
46
+ action = :call
47
+ end
38
48
  system_item = Constants.get("UIBarButtonSystemItem", type)
39
49
 
40
50
  item = alloc.initWithBarButtonSystemItem(system_item, target:block, action:action)
@@ -10,6 +10,7 @@ module BubbleWrap
10
10
  end
11
11
 
12
12
  @callback[events] << block
13
+ block.weak! if BubbleWrap.use_weak_callbacks?
13
14
  addTarget(@callback[events].last, action:'call', forControlEvents: events)
14
15
  end
15
16
  end
@@ -20,6 +20,10 @@ module BubbleWrap
20
20
  add_gesture_recognizer_helper(UIPanGestureRecognizer.alloc.initWithTarget(self, action:'handle_gesture:'), enableInteraction, proc)
21
21
  end
22
22
 
23
+ def when_screen_edge_panned(enableInteraction=true, &proc)
24
+ add_gesture_recognizer_helper(UIScreenEdgePanGestureRecognizer.alloc.initWithTarget(self, action:'handle_gesture:'), enableInteraction, proc)
25
+ end
26
+
23
27
  def when_pressed(enableInteraction=true, &proc)
24
28
  add_gesture_recognizer_helper(UILongPressGestureRecognizer.alloc.initWithTarget(self, action:'handle_gesture:'), enableInteraction, proc)
25
29
  end
@@ -47,6 +51,7 @@ module BubbleWrap
47
51
  self.addGestureRecognizer(recognizer)
48
52
 
49
53
  @recognizers = {} unless @recognizers
54
+ proc.weak! if !proc.nil? && BubbleWrap.use_weak_callbacks?
50
55
  @recognizers[recognizer] = proc
51
56
 
52
57
  recognizer
@@ -1,10 +1,14 @@
1
+ PATH
2
+ remote: ../../
3
+ specs:
4
+ bubble-wrap (1.4.0)
5
+
1
6
  GEM
2
- remote: http://rubygems.org/
7
+ remote: https://rubygems.org/
3
8
  specs:
4
- bubble-wrap (1.3.0.osx)
5
9
 
6
10
  PLATFORMS
7
11
  ruby
8
12
 
9
13
  DEPENDENCIES
10
- bubble-wrap (~> 1.3.0.osx)
14
+ bubble-wrap!
@@ -93,6 +93,12 @@ describe BubbleWrap::Device::Camera do
93
93
  camera.imagePickerController(camera.instance_variable_get("@picker"), didFinishPickingMediaWithInfo: info)
94
94
  image_view.nil?.should == false
95
95
  end
96
+
97
+ it 'should set popover' do
98
+ uiview = UIView.alloc
99
+ camera = BW::Device.camera.photo_library.popover_from(uiview)
100
+ camera.instance_variable_get("@popover_in_view").should == uiview
101
+ end
96
102
  end
97
103
  end
98
104
 
@@ -1,16 +1,19 @@
1
1
  describe BubbleWrap::Device::CameraWrapper do
2
-
2
+
3
3
  before do
4
4
  BW::Device.camera.instance_variable_set(:@front, nil)
5
5
  BW::Device.camera.instance_variable_set(:@rear, nil)
6
6
  end
7
-
7
+
8
8
  describe 'on device with only front facing camera' do
9
9
  before do
10
10
  UIImagePickerController.instance_eval do
11
11
  def isCameraDeviceAvailable(c)
12
12
  c == UIImagePickerControllerCameraDeviceFront
13
13
  end
14
+ def isSourceTypeAvailable(c)
15
+ c == UIImagePickerControllerSourceTypeCamera
16
+ end
14
17
  end
15
18
  end
16
19
 
@@ -25,6 +28,12 @@ describe BubbleWrap::Device::CameraWrapper do
25
28
  BW::Device.camera.rear?.should == false
26
29
  end
27
30
  end
31
+
32
+ describe '.available?' do
33
+ it 'returns true' do
34
+ BW::Device.camera.available?.should == true
35
+ end
36
+ end
28
37
  end
29
38
 
30
39
  describe 'on device with only rear facing camera' do
@@ -33,6 +42,9 @@ describe BubbleWrap::Device::CameraWrapper do
33
42
  def isCameraDeviceAvailable(c)
34
43
  c == UIImagePickerControllerCameraDeviceRear
35
44
  end
45
+ def isSourceTypeAvailable(c)
46
+ c == UIImagePickerControllerSourceTypeCamera
47
+ end
36
48
  end
37
49
  end
38
50
 
@@ -47,5 +59,42 @@ describe BubbleWrap::Device::CameraWrapper do
47
59
  BW::Device.camera.rear?.should == true
48
60
  end
49
61
  end
62
+
63
+ describe '.available?' do
64
+ it 'returns true' do
65
+ BW::Device.camera.available?.should == true
66
+ end
67
+ end
68
+ end
69
+
70
+ describe 'on device with no physical camera' do
71
+ before do
72
+ UIImagePickerController.instance_eval do
73
+ def isCameraDeviceAvailable(c)
74
+ false
75
+ end
76
+ def isSourceTypeAvailable(c)
77
+ false
78
+ end
79
+ end
80
+ end
81
+
82
+ describe '.front?' do
83
+ it 'returns false' do
84
+ BW::Device.camera.front?.should == false
85
+ end
86
+ end
87
+
88
+ describe '.rear?' do
89
+ it 'returns false' do
90
+ BW::Device.camera.rear?.should == false
91
+ end
92
+ end
93
+
94
+ describe '.available?' do
95
+ it 'returns true' do
96
+ BW::Device.camera.available?.should == false
97
+ end
98
+ end
50
99
  end
51
100
  end
@@ -3,11 +3,13 @@ describe BubbleWrap::KVO do
3
3
  class KvoExample
4
4
  include BubbleWrap::KVO
5
5
 
6
+ attr_accessor :age
6
7
  attr_accessor :label
7
8
  attr_accessor :items
8
9
 
9
10
  def initialize
10
11
  @items = [ "Apple", "Banana", "Chickpeas" ]
12
+ @age = 1
11
13
 
12
14
  if App.osx?
13
15
  @label = NSTextField.alloc.initWithFrame [[0,0],[320, 30]]
@@ -187,6 +189,31 @@ describe BubbleWrap::KVO do
187
189
  @example.set_text "Bar"
188
190
  observed.should == false
189
191
  end
192
+
193
+ # without target
194
+
195
+ it "should observe a key path without a target" do
196
+ observed = false
197
+ @example.observe :age do |old_value, new_value|
198
+ observed = true
199
+ old_value.should == 1
200
+ new_value.should == 2
201
+ end
202
+
203
+ @example.age = 2
204
+ observed.should == true
205
+ end
206
+
207
+ it "should unobserve a key path without a target" do
208
+ observed = false
209
+ @example.observe :age do |old_value, new_value|
210
+ observed = true
211
+ end
212
+ @example.unobserve :age
213
+
214
+ @example.age = 2
215
+ observed.should == false
216
+ end
190
217
 
191
218
  end
192
219
 
@@ -14,9 +14,9 @@ describe "NSNotificationCenter" do
14
14
  end
15
15
 
16
16
  it "add observer" do
17
- notified = false
17
+ @notified = false
18
18
  @observer = BW::App.notification_center.observe(SampleNotification) do |note|
19
- notified = true
19
+ @notified = true
20
20
  note.should.is_a NSNotification
21
21
  note.object.class.should == Time
22
22
  note.userInfo.should.not.be.nil
@@ -25,7 +25,7 @@ describe "NSNotificationCenter" do
25
25
 
26
26
  lambda {
27
27
  BW::App.notification_center.post SampleNotification, Time.now, {:status => "ok"}
28
- }.should.change { notified }
28
+ }.should.change { @notified }
29
29
  end
30
30
 
31
31
  it "remove observer" do
@@ -16,13 +16,15 @@ describe "Time" do
16
16
 
17
17
  describe "parsing an iso8601 formatted time to a Time object" do
18
18
  before do
19
- @time = Time.iso8601("2012-05-31T19:41:33Z")
19
+ @time = Time.iso8601("2012-#{Time.now.month}-#{Time.now.day}T19:41:32Z")
20
20
  @time_with_timezone = Time.iso8601_with_timezone("1987-08-10T06:00:00+02:00")
21
+ @time_with_fractional_seconds = Time.iso8601_with_fractional_seconds("2012-#{Time.now.month}-#{Time.now.day}T19:41:32.123Z")
21
22
  end
22
23
 
23
24
  it "should be a time" do
24
25
  @time.instance_of?(Time).should == true
25
26
  @time_with_timezone.instance_of?(Time).should == true
27
+ @time_with_fractional_seconds.instance_of?(Time).should == true
26
28
  end
27
29
 
28
30
  # Crashes Buggy RubyMotion 1.18
@@ -30,36 +32,43 @@ describe "Time" do
30
32
  local_zone = Time.now.zone
31
33
  @time.zone.should == local_zone
32
34
  @time_with_timezone.zone == local_zone
35
+ @time_with_fractional_seconds.zone.should == local_zone
33
36
  end
34
37
 
35
38
  it "should have a valid year" do
36
39
  @time.utc.year.should == 2012
37
40
  @time_with_timezone.utc.year.should == 1987
41
+ @time_with_fractional_seconds.utc.year.should == 2012
38
42
  end
39
43
 
40
44
  it "should have a valid month" do
41
- @time.utc.month.should == 5
45
+ @time.utc.month.should == Time.now.month
42
46
  @time_with_timezone.utc.month.should == 8
47
+ @time_with_fractional_seconds.utc.month.should == Time.now.month
43
48
  end
44
49
 
45
50
  it "should have a valid day" do
46
- @time.utc.day.should == 31
51
+ @time.utc.day.should == Time.now.day
47
52
  @time_with_timezone.utc.day.should == 10
53
+ @time_with_fractional_seconds.utc.day.should == Time.now.day
48
54
  end
49
55
 
50
56
  it "should have a valid hour" do
51
57
  @time.utc.hour.should == 19
52
58
  @time_with_timezone.utc.hour.should == 4
59
+ @time_with_fractional_seconds.utc.hour.should == 19
53
60
  end
54
61
 
55
62
  it "should have a valid minute" do
56
63
  @time.utc.min.should == 41
57
64
  @time_with_timezone.utc.min.should == 0
65
+ @time_with_fractional_seconds.utc.min.should == 41
58
66
  end
59
67
 
60
68
  it "should have a valid second" do
61
- @time.utc.sec.should == 33
69
+ @time.utc.sec.should == 32
62
70
  @time_with_timezone.utc.sec.should == 0
71
+ @time_with_fractional_seconds.utc.sec.should == 32
63
72
  end
64
73
  end
65
74
 
@@ -28,7 +28,6 @@ describe 'BubbleWrap' do
28
28
  end
29
29
 
30
30
  it "creates color with rgb devided by 255 with alpha=1" do
31
- color = nil
32
31
  r,g,b,a = [(@red/255.0), (@green/255.0), (@blue/255.0), 1]
33
32
  if App.osx?
34
33
  color = NSColor.colorWithDeviceRed(r, green:g, blue:b, alpha: a)
@@ -183,7 +183,7 @@ describe BubbleWrap::HTTP::Query do
183
183
  query = BubbleWrap::HTTP::Query.new(@fake_url, :post, {files: files})
184
184
  uuid = query.instance_variable_get(:@boundary)
185
185
  real_payload = NSString.alloc.initWithData(query.request.HTTPBody, encoding:NSUTF8StringEncoding)
186
- real_payload.should.equal "--#{uuid}\r\nContent-Disposition: form-data; name=\"upload\"; filename=\"test.txt\"\r\nContent-Type: application/octet-stream\r\n\r\ntwitter:@mneorr\r\n--#{uuid}--\r\n"
186
+ real_payload.should.equal "--#{uuid}\r\nContent-Disposition: attachment; name=\"upload\"; filename=\"test.txt\"\r\nContent-Type: application/octet-stream\r\n\r\ntwitter:@mneorr\r\n--#{uuid}--\r\n"
187
187
  end
188
188
 
189
189
  it "processes filenames from file hashes, using the name when the filename is missing" do
@@ -193,7 +193,7 @@ describe BubbleWrap::HTTP::Query do
193
193
  query = BubbleWrap::HTTP::Query.new(@fake_url, :post, {files: files})
194
194
  uuid = query.instance_variable_get(:@boundary)
195
195
  real_payload = NSString.alloc.initWithData(query.request.HTTPBody, encoding:NSUTF8StringEncoding)
196
- real_payload.should.equal "--#{uuid}\r\nContent-Disposition: form-data; name=\"upload\"; filename=\"upload\"\r\nContent-Type: application/octet-stream\r\n\r\ntwitter:@mneorr\r\n--#{uuid}--\r\n"
196
+ real_payload.should.equal "--#{uuid}\r\nContent-Disposition: attachment; name=\"upload\"; filename=\"upload\"\r\nContent-Type: application/octet-stream\r\n\r\ntwitter:@mneorr\r\n--#{uuid}--\r\n"
197
197
  end
198
198
 
199
199
  it "throws an error for invalid file parameters" do
@@ -214,7 +214,7 @@ describe BubbleWrap::HTTP::Query do
214
214
  query = BubbleWrap::HTTP::Query.new( @fake_url , method, { payload: payload, files: files } )
215
215
  uuid = query.instance_variable_get(:@boundary)
216
216
  real_payload = NSString.alloc.initWithData(query.request.HTTPBody, encoding:NSUTF8StringEncoding)
217
- real_payload.should.equal "--#{uuid}\r\nContent-Disposition: form-data; name=\"name\"\r\n\r\napple\r\n--#{uuid}\r\nContent-Disposition: form-data; name=\"model\"\r\n\r\nmacbook\r\n--#{uuid}\r\nContent-Disposition: form-data; name=\"twitter\"; filename=\"twitter\"\r\nContent-Type: application/octet-stream\r\n\r\ntwitter:@mneorr\r\n--#{uuid}\r\nContent-Disposition: form-data; name=\"site\"; filename=\"site\"\r\nContent-Type: application/octet-stream\r\n\r\nmneorr.com\r\n--#{uuid}--\r\n"
217
+ real_payload.should.equal "--#{uuid}\r\nContent-Disposition: form-data; name=\"name\"\r\n\r\napple\r\n--#{uuid}\r\nContent-Disposition: form-data; name=\"model\"\r\n\r\nmacbook\r\n--#{uuid}\r\nContent-Disposition: attachment; name=\"twitter\"; filename=\"twitter\"\r\nContent-Type: application/octet-stream\r\n\r\ntwitter:@mneorr\r\n--#{uuid}\r\nContent-Disposition: attachment; name=\"site\"; filename=\"site\"\r\nContent-Type: application/octet-stream\r\n\r\nmneorr.com\r\n--#{uuid}--\r\n"
218
218
  end
219
219
 
220
220
  [:get, :head, :options].each do |method|
@@ -475,7 +475,7 @@ describe BubbleWrap::HTTP::Query do
475
475
 
476
476
  it "should initialize @received_data and append the received data" do
477
477
  query_received_data.should.equal nil
478
- data = NSData.dataWithBytesNoCopy(Pointer.new(:char, 'abc'), length:24, freeWhenDone: false)
478
+ data = NSData.dataWithBytes(Pointer.new(:char, 'abc'), length:24)
479
479
 
480
480
  @query.connection(nil, didReceiveData:nil)
481
481
  query_received_data.should.not.equal nil
@@ -555,7 +555,7 @@ describe BubbleWrap::HTTP::Query do
555
555
  end
556
556
 
557
557
  it "should set response_body to @received data if not nil" do
558
- data = NSData.dataWithBytesNoCopy(Pointer.new(:char, 'abc'), length:24, freeWhenDone: false)
558
+ data = NSData.dataWithBytes(Pointer.new(:char, 'abc'), length:24)
559
559
  headers = { foo: 'bar' }
560
560
  status_code = 234
561
561
  response = FakeURLResponse.new(status_code, headers, 65456)