bubble-wrap 1.5.0 → 1.6.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
@@ -6,14 +6,16 @@ module BubbleWrap
6
6
  # When `event` is triggered the block will execute
7
7
  # and be passed the arguments that are passed to
8
8
  # `trigger`.
9
- def on(event, &blk)
10
- __events__[event].push blk
9
+ def on(event, method = nil, &blk)
10
+ method_or_block = method ? method : blk
11
+ __events__[event].push method_or_block
11
12
  end
12
13
 
13
14
  # When `event` is triggered, do not call the given
14
15
  # block any more
15
- def off(event, &blk)
16
- __events__[event].delete_if { |b| b == blk }
16
+ def off(event, method = nil, &blk)
17
+ method_or_block = method ? method : blk
18
+ __events__[event].delete_if { |b| b == method_or_block }
17
19
  blk
18
20
  end
19
21
 
@@ -0,0 +1,51 @@
1
+ module BW
2
+ class UIActivityViewController < ::UIActivityViewController
3
+ class << self
4
+ def new(options = {}, presenting_controller = nil, &block)
5
+ options = {
6
+ activities: nil,
7
+ animated: true
8
+ }.merge(options)
9
+
10
+ if options[:item] || options[:items]
11
+ items = Array(options[:item] || options[:items])
12
+ else
13
+ raise ArgumentError, "You must specify at least one item - #{options.inspect}"
14
+ end
15
+
16
+ vc = alloc.initWithActivityItems(items, applicationActivities:options[:activities])
17
+ vc.excludedActivityTypes = BW::Constants.get("UIActivityType", Array(options[:excluded])) if options[:excluded]
18
+
19
+ unless block.nil?
20
+ block.weak! if BubbleWrap.use_weak_callbacks?
21
+ vc.setCompletionHandler block
22
+ end
23
+
24
+ presenting_controller ||= App.window.rootViewController.presentedViewController # May be nil, but handles use case of container views
25
+ presenting_controller ||= App.window.rootViewController
26
+
27
+ presenting_controller.presentViewController(vc, animated:options[:animated], completion: lambda {})
28
+ vc
29
+ end
30
+
31
+ end
32
+ end
33
+
34
+ # UIActivityTypes
35
+ Constants.register(
36
+ UIActivityTypePostToFacebook,
37
+ UIActivityTypePostToTwitter,
38
+ UIActivityTypePostToWeibo,
39
+ UIActivityTypeMessage,
40
+ UIActivityTypeMail,
41
+ UIActivityTypePrint,
42
+ UIActivityTypeCopyToPasteboard,
43
+ UIActivityTypeAssignToContact,
44
+ UIActivityTypeSaveToCameraRoll,
45
+ UIActivityTypeAddToReadingList,
46
+ UIActivityTypePostToFlickr,
47
+ UIActivityTypePostToVimeo,
48
+ UIActivityTypePostToTencentWeibo,
49
+ UIActivityTypeAirDrop
50
+ )
51
+ end
@@ -13,7 +13,7 @@ module BubbleWrap
13
13
  # do nothing, just get the constants in the code
14
14
  end
15
15
 
16
- # @param [String] base of the constant
16
+ # @param [String] base of the constant
17
17
  # @param [Integer, NSArray, String, Symbol] the suffix of the constant
18
18
  # when NSArray, will return the bitmask of all suffixes in the array
19
19
  # @return [Integer] the constant for this base and suffix
@@ -22,19 +22,24 @@ module BubbleWrap
22
22
  # get("UIReturnKey", "done") => UIReturnKeyDone == 9
23
23
  # get("UIReturnKey", 9) => 9
24
24
  # get("UIImagePickerControllerSourceType", ["photo_library", "camera", "saved_photos_album"]) => 3
25
+ # get("UIActivityType", [:air_drop, :print]) => ["com.apple.UIKit.activity.AirDrop", "com.apple.UIKit.activity.Print"]
25
26
  def get(base, *values)
26
27
  value = values.size == 1 ? values.first : values.flatten
27
28
  case value
28
29
  when Numeric
29
30
  value.to_i
30
31
  when NSArray
31
- value.reduce { |i, j|
32
- get(base, i) | get(base, j)
33
- }
32
+ unless get(base, value.first).is_a? Fixnum
33
+ value.map { |v| get(base, v) }
34
+ else
35
+ value.reduce { |i, j|
36
+ get(base, i) | get(base, j)
37
+ }
38
+ end
34
39
  else
35
40
  value = value.to_s.camelize
36
41
  Kernel.const_get("#{base}#{value}")
37
42
  end
38
43
  end
39
44
  end
40
- end
45
+ end
@@ -205,5 +205,32 @@ describe BubbleWrap::App do
205
205
  end
206
206
 
207
207
  end
208
+
209
+ describe ".can_open_url" do
210
+
211
+ it "uses NSURL or converts NSString in NSURL and opens it" do
212
+ application = UIApplication.sharedApplication
213
+ def application.url; @url end
214
+ def application.canOpenURL(url); @url = url; super; end
215
+
216
+ url = NSURL.URLWithString('http://localhost')
217
+ App.can_open_url(url)
218
+ application.url.should.equal url
219
+
220
+ url = 'http://localhost'
221
+ App.can_open_url(url)
222
+ application.url.class.should.equal NSURL
223
+ application.url.description.should.equal url
224
+ end
225
+
226
+ it "returns false when it can't open the given url" do
227
+ App.can_open_url("inexistent_schema://").should.equal false
228
+ end
229
+
230
+ it "returns true when it can open the given url" do
231
+ App.can_open_url("http://google.com").should.equal true
232
+ App.can_open_url("rdar:").should.equal true
233
+ end
234
+ end
208
235
  end
209
236
  end
@@ -93,12 +93,23 @@ describe BubbleWrap::String do
93
93
 
94
94
  before do
95
95
  @blue_color = App.osx? ? NSColor.colorWithDeviceRed(0,green:0,blue:1,alpha:1) : UIColor.blueColor
96
- r,g,b,a = [1, (138.0/255.0), (25.0/255.0), 1]
97
- @orange_color = App.osx? ? NSColor.colorWithDeviceRed(r, green:g, blue:b, alpha: a) :
96
+ r,g,b,a = [1, (0x8A.to_f/0xFF.to_f), (0x19/0xFF.to_f), (0x88.to_f/0xFF.to_f)]
97
+ @orange_color = App.osx? ? NSColor.colorWithDeviceRed(r, green:g, blue:b, alpha: 1.0) :
98
+ UIColor.colorWithRed(r, green:g, blue:b, alpha:1.0)
99
+ @orange_alpha_color = App.osx? ? NSColor.colorWithDeviceRed(r, green:g, blue:b, alpha: a) :
98
100
  UIColor.colorWithRed(r, green:g, blue:b, alpha:a)
99
101
  end
100
102
 
101
103
  describe "A UIColor should be created from a String with a hex color" do
104
+ it "with 8 digits" do
105
+ @orange_color_from_hex = '88FF8A19'.to_color
106
+ @orange_color_from_hex.should == @orange_alpha_color
107
+ end
108
+
109
+ it "with 8 digits and # sign" do
110
+ @orange_color_from_hex = '#88FF8A19'.to_color
111
+ @orange_color_from_hex.should == @orange_alpha_color
112
+ end
102
113
 
103
114
  it "with 6 digits" do
104
115
  @orange_color_from_hex= '#FF8A19'.to_color
@@ -7,6 +7,10 @@ describe "CLLocationWrap" do
7
7
  end
8
8
 
9
9
  # monkey patch for testing
10
+ class BWCLHeading
11
+ attr_accessor :timestamp, :z, :y, :x, :headingAccuracy, :trueHeading, :magneticHeading
12
+ end
13
+
10
14
  class CLLocationManager
11
15
  def self.enable(enable)
12
16
  @enabled = enable
@@ -25,6 +29,14 @@ class CLLocationManager
25
29
  @stopUpdatingLocation = true
26
30
  end
27
31
 
32
+ def startUpdatingHeading
33
+ @startUpdatingHeading = true
34
+ end
35
+
36
+ def stopUpdatingHeading
37
+ @stopUpdatingHeading = true
38
+ end
39
+
28
40
  def startMonitoringSignificantLocationChanges
29
41
  @startMonitoringSignificantLocationChanges = true
30
42
  end
@@ -88,6 +100,13 @@ describe BubbleWrap::Location do
88
100
  location_manager.instance_variable_get("@startUpdatingLocation").should == true
89
101
  end
90
102
 
103
+ it "should use compass update functions" do
104
+ BW::Location.get_compass do
105
+ end
106
+
107
+ location_manager.instance_variable_get("@startUpdatingHeading").should == true
108
+ end
109
+
91
110
  it "should have correct location when succeeding" do
92
111
  to = CLLocation.alloc.initWithLatitude(100, longitude: 50)
93
112
  from = CLLocation.alloc.initWithLatitude(100, longitude: 49)
@@ -122,6 +141,38 @@ describe BubbleWrap::Location do
122
141
  end
123
142
  end
124
143
 
144
+ describe ".get_compass" do
145
+ before do
146
+ reset
147
+ end
148
+
149
+ it "should use compass functions" do
150
+ BW::Location.get_compass do |result|
151
+ end
152
+
153
+ location_manager.instance_variable_get("@startUpdatingHeading").should == true
154
+ end
155
+
156
+ it "should have correct heading when succeeding" do
157
+ timestamp = Time.now
158
+ heading = BWCLHeading.new.tap do |h|
159
+ h.timestamp = timestamp
160
+ h.headingAccuracy = 4
161
+ h.trueHeading = 220
162
+ h.magneticHeading = 270
163
+ end
164
+
165
+ BW::Location.get_compass do |heading|
166
+ heading[:magnetic_heading].should == 270
167
+ heading[:true_heading].should == 220
168
+ heading[:accuracy].should == 4
169
+ heading[:timestamp].should == timestamp
170
+ end
171
+
172
+ BW::Location.locationManager(location_manager, didUpdateHeading: heading)
173
+ end
174
+ end
175
+
125
176
  describe ".get_significant" do
126
177
  before do
127
178
  reset
@@ -161,6 +212,15 @@ describe BubbleWrap::Location do
161
212
  location_manager.instance_variable_get("@stopUpdatingLocation").should == true
162
213
  end
163
214
 
215
+ it "should use compass update functions" do
216
+ BW::Location.get_compass do |result|
217
+ end
218
+
219
+ BW::Location.stop
220
+
221
+ location_manager.instance_variable_get("@stopUpdatingHeading").should == true
222
+ end
223
+
164
224
  it "should use significant update functions with get_significant" do
165
225
  BW::Location.get_significant do
166
226
  end
@@ -169,5 +229,10 @@ describe BubbleWrap::Location do
169
229
 
170
230
  location_manager.instance_variable_get("@stopMonitoringSignificantLocationChanges").should == true
171
231
  end
232
+
233
+ it "should not throw an error stopping before it was started" do
234
+ Proc.new { BW::Location.stop }.should.not.raise Exception
235
+ end
236
+
172
237
  end
173
238
  end
@@ -0,0 +1,112 @@
1
+ describe BW::NetworkIndicator do
2
+
3
+ before do
4
+ BW::NetworkIndicator.reset!
5
+ end
6
+
7
+ after do
8
+ BW::NetworkIndicator.instance_variable_set(:@counter, 0)
9
+ UIApplication.sharedApplication.networkActivityIndicatorVisible = false
10
+ end
11
+
12
+ it 'should show the indicator immediately' do
13
+ BW::NetworkIndicator.show
14
+ UIApplication.sharedApplication.networkActivityIndicatorVisible?.should == true
15
+ end
16
+
17
+ it 'should have a counter' do
18
+ BW::NetworkIndicator.show
19
+ BW::NetworkIndicator.counter.should == 1
20
+ BW::NetworkIndicator.hide
21
+ BW::NetworkIndicator.counter.should == 0
22
+ end
23
+
24
+ it 'should show the indicator from any thread' do
25
+ Dispatch::Queue.concurrent.async do
26
+ BW::NetworkIndicator.show
27
+ end
28
+ wait BW::NetworkIndicator::DELAY do
29
+ UIApplication.sharedApplication.networkActivityIndicatorVisible?.should == true
30
+ end
31
+ end
32
+
33
+ it 'should hide the indicator' do
34
+ BW::NetworkIndicator.show
35
+ BW::NetworkIndicator.hide
36
+ wait BW::NetworkIndicator::DELAY do
37
+ UIApplication.sharedApplication.networkActivityIndicatorVisible?.should == false
38
+ end
39
+ end
40
+
41
+ it 'should hide the indicator after a delay' do
42
+ BW::NetworkIndicator.show
43
+ BW::NetworkIndicator.hide
44
+ UIApplication.sharedApplication.networkActivityIndicatorVisible?.should == true
45
+ wait BW::NetworkIndicator::DELAY do
46
+ UIApplication.sharedApplication.networkActivityIndicatorVisible?.should == false
47
+ end
48
+ end
49
+
50
+ it 'should not hide the indicator if show/hide/show is called quickly' do
51
+ BW::NetworkIndicator.show
52
+ BW::NetworkIndicator.hide
53
+ UIApplication.sharedApplication.networkActivityIndicatorVisible?.should == true
54
+ wait BW::NetworkIndicator::DELAY/2 do
55
+ UIApplication.sharedApplication.networkActivityIndicatorVisible?.should == true
56
+ BW::NetworkIndicator.show
57
+ wait BW::NetworkIndicator::DELAY do
58
+ UIApplication.sharedApplication.networkActivityIndicatorVisible?.should == true
59
+ end
60
+ end
61
+ end
62
+
63
+ it 'should keep track of how many times `show` was called' do
64
+ BW::NetworkIndicator.show
65
+ BW::NetworkIndicator.show
66
+ UIApplication.sharedApplication.networkActivityIndicatorVisible?.should == true
67
+ BW::NetworkIndicator.hide
68
+ wait BW::NetworkIndicator::DELAY do
69
+ UIApplication.sharedApplication.networkActivityIndicatorVisible?.should == true
70
+ BW::NetworkIndicator.hide
71
+ wait BW::NetworkIndicator::DELAY do
72
+ UIApplication.sharedApplication.networkActivityIndicatorVisible?.should == false
73
+ end
74
+ end
75
+ end
76
+
77
+ it 'should allow `hide` to be called too many times' do
78
+ BW::NetworkIndicator.show
79
+ BW::NetworkIndicator.show
80
+ BW::NetworkIndicator.hide
81
+ BW::NetworkIndicator.hide
82
+ wait BW::NetworkIndicator::DELAY do
83
+ UIApplication.sharedApplication.networkActivityIndicatorVisible?.should == false
84
+
85
+ BW::NetworkIndicator.hide
86
+ BW::NetworkIndicator.hide
87
+ wait BW::NetworkIndicator::DELAY do
88
+ UIApplication.sharedApplication.networkActivityIndicatorVisible?.should == false
89
+
90
+ BW::NetworkIndicator.show
91
+ UIApplication.sharedApplication.networkActivityIndicatorVisible?.should == true
92
+ end
93
+ end
94
+ end
95
+
96
+ it 'should reset the counter when `reset!` is called' do
97
+ BW::NetworkIndicator.show
98
+ BW::NetworkIndicator.show
99
+ BW::NetworkIndicator.reset!
100
+ UIApplication.sharedApplication.networkActivityIndicatorVisible?.should == false
101
+ end
102
+
103
+ it 'should have `visible?` method' do
104
+ BW::NetworkIndicator.show
105
+ BW::NetworkIndicator.visible?.should == true
106
+ BW::NetworkIndicator.hide
107
+ wait BW::NetworkIndicator::DELAY do
108
+ BW::NetworkIndicator.visible?.should == false
109
+ end
110
+ end
111
+
112
+ end
@@ -9,13 +9,21 @@ describe BubbleWrap::Reactor::Eventable do
9
9
  end
10
10
 
11
11
  describe '.on' do
12
- it 'registers events' do
12
+ it 'registers events passing a block' do
13
13
  proof = proc { }
14
14
  @subject.on(:foo, &proof)
15
15
  events = @subject.instance_variable_get(:@__events__)
16
16
  events[:foo].member?(proof).should == true
17
17
  end
18
18
 
19
+ it 'registers events passing a Method object' do
20
+ def bar; end
21
+ proof = method(:bar)
22
+ @subject.on(:foo, proof)
23
+ events = @subject.instance_variable_get(:@__events__)
24
+ events[:foo].member?(proof).should == true
25
+ end
26
+
19
27
  it 'returns the array of blocks for the event' do
20
28
  proof = proc { }
21
29
  @subject.on(:foo, &proof).should == [proof]
@@ -23,7 +31,7 @@ describe BubbleWrap::Reactor::Eventable do
23
31
  end
24
32
 
25
33
  describe '.off' do
26
- it 'unregisters events' do
34
+ it 'unregisters proc events' do
27
35
  proof = proc { }
28
36
  @subject.on(:foo, &proof)
29
37
  events = @subject.instance_variable_get(:@__events__)
@@ -31,6 +39,15 @@ describe BubbleWrap::Reactor::Eventable do
31
39
  events[:foo].member?(proof).should == false
32
40
  end
33
41
 
42
+ it 'unregisters method events' do
43
+ def bar; end
44
+ proof = method(:bar)
45
+ @subject.on(:foo, proof)
46
+ events = @subject.instance_variable_get(:@__events__)
47
+ @subject.off(:foo, proof)
48
+ events[:foo].member?(proof).should == false
49
+ end
50
+
34
51
  it 'calls other event procs when a proc unregisters itself' do
35
52
  @proxy.proof = 0
36
53
  proof1 = proc do |r|
@@ -57,6 +74,16 @@ describe BubbleWrap::Reactor::Eventable do
57
74
  @proxy.proof.should == true
58
75
  end
59
76
 
77
+ it 'calls event methods' do
78
+ @proxy.proof = false
79
+ def bar(r)
80
+ @proxy.proof = r
81
+ end
82
+ @subject.on(:foo, method(:bar))
83
+ @subject.trigger(:foo, true)
84
+ @proxy.proof.should == true
85
+ end
86
+
60
87
  it 'calls event procs for correct event' do
61
88
  @proxy.proof = false
62
89
  @subject.on(:foo) do |r|
@@ -66,6 +93,16 @@ describe BubbleWrap::Reactor::Eventable do
66
93
  @proxy.proof.should == false
67
94
  end
68
95
 
96
+ it 'calls event methods for correct event' do
97
+ @proxy.proof = false
98
+ def bar(r)
99
+ @proxy.proof = r
100
+ end
101
+ @subject.on(:foo, method(:bar))
102
+ @subject.trigger(:bar, true)
103
+ @proxy.proof.should == false
104
+ end
105
+
69
106
  it 'calls all the event procs' do
70
107
  @proxy.proof = 0
71
108
  @subject.on(:foo) { |r| @proxy.proof += r }
@@ -75,12 +112,27 @@ describe BubbleWrap::Reactor::Eventable do
75
112
  @proxy.proof.should == 6
76
113
  end
77
114
 
115
+ it 'calls all the event methods' do
116
+ def bar(r); @proxy.proof += r; end
117
+ def baz(r); @proxy.proof += r; end
118
+ @proxy.proof = 0
119
+ @subject.on(:foo, method(:baz))
120
+ @subject.on(:foo, method(:bar))
121
+ @subject.trigger(:foo, 2)
122
+ @proxy.proof.should == 4
123
+ end
124
+
78
125
  class TestUIViewControllerWithEventable
79
126
  include BubbleWrap::Reactor::Eventable
80
127
  def test_on
81
128
  on(:foo) do
82
129
  end
130
+ method(:bar)
83
131
  end
132
+
133
+ def bar
134
+ end
135
+
84
136
  def dealloc
85
137
  $test_dealloc = true
86
138
  super