bubble-wrap 1.0.0 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +0 -1
- data/.yardopts +2 -0
- data/CHANGELOG.md +15 -0
- data/Gemfile +1 -1
- data/Gemfile.lock +24 -0
- data/HACKING.md +2 -2
- data/README.md +363 -21
- data/Rakefile +6 -2
- data/lib/bubble-wrap.rb +0 -1
- data/lib/bubble-wrap/all.rb +4 -0
- data/lib/bubble-wrap/camera.rb +7 -0
- data/lib/bubble-wrap/core.rb +3 -2
- data/lib/bubble-wrap/ext/motion_project_app.rb +2 -2
- data/lib/bubble-wrap/http.rb +1 -0
- data/lib/bubble-wrap/loader.rb +19 -12
- data/lib/bubble-wrap/location.rb +6 -0
- data/lib/bubble-wrap/reactor.rb +10 -0
- data/lib/bubble-wrap/requirement.rb +11 -3
- data/lib/bubble-wrap/rss_parser.rb +2 -0
- data/lib/bubble-wrap/ui.rb +4 -0
- data/lib/bubble-wrap/version.rb +1 -1
- data/motion/core.rb +8 -2
- data/motion/core/app.rb +34 -6
- data/motion/core/device.rb +10 -1
- data/motion/core/device/camera.rb +219 -0
- data/motion/core/device/camera_wrapper.rb +45 -0
- data/motion/core/ns_url_request.rb +10 -0
- data/motion/core/persistence.rb +7 -0
- data/motion/core/pollute.rb +1 -2
- data/motion/core/string.rb +23 -0
- data/motion/http.rb +142 -83
- data/motion/location/location.rb +152 -0
- data/motion/location/pollute.rb +5 -0
- data/motion/reactor.rb +105 -0
- data/motion/reactor/default_deferrable.rb +9 -0
- data/motion/reactor/deferrable.rb +126 -0
- data/motion/reactor/eventable.rb +24 -0
- data/motion/reactor/future.rb +22 -0
- data/motion/reactor/periodic_timer.rb +27 -0
- data/motion/reactor/queue.rb +60 -0
- data/motion/reactor/timer.rb +25 -0
- data/motion/rss_parser.rb +131 -0
- data/motion/shortcut.rb +18 -0
- data/motion/{core → ui}/gestures.rb +15 -9
- data/motion/ui/pollute.rb +5 -0
- data/motion/{core → ui}/ui_control.rb +0 -0
- data/motion/{core → ui}/ui_view_controller.rb +0 -0
- data/resources/atom.xml +1705 -0
- data/spec/lib/bubble-wrap/ext/motion_project_app_spec.rb +7 -11
- data/spec/lib/bubble-wrap/requirement_spec.rb +4 -4
- data/spec/lib/bubble-wrap_spec.rb +2 -2
- data/spec/motion/core/app_spec.rb +118 -14
- data/spec/motion/core/device/camera_spec.rb +130 -0
- data/spec/motion/core/device/camera_wrapper_spec.rb +45 -0
- data/spec/motion/core/device_spec.rb +0 -50
- data/spec/motion/core/gestures_spec.rb +5 -0
- data/spec/motion/core/persistence_spec.rb +24 -2
- data/spec/motion/core/string_spec.rb +55 -0
- data/spec/motion/core_spec.rb +72 -1
- data/spec/motion/http_spec.rb +100 -65
- data/spec/motion/location/location_spec.rb +152 -0
- data/spec/motion/reactor/eventable_spec.rb +40 -0
- data/spec/motion/reactor_spec.rb +163 -0
- data/spec/motion/rss_parser_spec.rb +36 -0
- metadata +75 -16
@@ -12,6 +12,7 @@ describe BubbleWrap::Ext::BuildTask do
|
|
12
12
|
end
|
13
13
|
end
|
14
14
|
@subject.extend BubbleWrap::Ext::BuildTask
|
15
|
+
@default_frameworks = ['CoreGraphics', 'Foundation', 'UIKit']
|
15
16
|
end
|
16
17
|
|
17
18
|
describe '.extended' do
|
@@ -88,48 +89,43 @@ describe BubbleWrap::Ext::BuildTask do
|
|
88
89
|
|
89
90
|
describe 'when app.frameworks is empty' do
|
90
91
|
it 'sets the default frameworks' do
|
91
|
-
defaults = ['CoreGraphics', 'Foundation', 'UIKit']
|
92
92
|
@config.stubs(:frameworks).returns(nil)
|
93
|
-
@config.expects(:frameworks=).with(
|
93
|
+
@config.expects(:frameworks=).with(@default_frameworks)
|
94
94
|
@subject.setup
|
95
95
|
end
|
96
96
|
end
|
97
97
|
|
98
98
|
describe 'when app.frameworks is empty' do
|
99
99
|
it 'sets the default frameworks' do
|
100
|
-
defaults = ['CoreGraphics', 'Foundation', 'UIKit']
|
101
100
|
@config.stubs(:frameworks).returns([])
|
102
|
-
@config.expects(:frameworks=).with(
|
101
|
+
@config.expects(:frameworks=).with(@default_frameworks)
|
103
102
|
@subject.setup
|
104
103
|
end
|
105
104
|
end
|
106
105
|
|
107
106
|
describe 'when app.frameworks contains defaults' do
|
108
107
|
it 'sets the default frameworks' do
|
109
|
-
|
110
|
-
@config.
|
111
|
-
@config.expects(:frameworks=).with(defaults)
|
108
|
+
@config.stubs(:frameworks).returns(@default_frameworks)
|
109
|
+
@config.expects(:frameworks=).with(@default_frameworks)
|
112
110
|
@subject.setup
|
113
111
|
end
|
114
112
|
end
|
115
113
|
|
116
114
|
describe 'when app.frameworks contains non-defaults' do
|
117
115
|
it 'sets the default frameworks and the contents' do
|
118
|
-
defaults = ['CoreGraphics', 'Foundation', 'UIKit']
|
119
116
|
@config.stubs(:frameworks).returns(['Addressbook'])
|
120
|
-
@config.expects(:frameworks=).with(
|
117
|
+
@config.expects(:frameworks=).with(['Addressbook'] + @default_frameworks)
|
121
118
|
@subject.setup
|
122
119
|
end
|
123
120
|
end
|
124
121
|
|
125
122
|
describe 'when BW::Requirement.frameworks has contents' do
|
126
123
|
it 'sets the default frameworks and the contents' do
|
127
|
-
defaults = ['CoreGraphics', 'Foundation', 'UIKit']
|
128
124
|
BW.require('motion/core.rb') do
|
129
125
|
file('motion/core.rb').uses_framework('Addressbook')
|
130
126
|
end
|
131
127
|
@config.stubs(:frameworks).returns(nil)
|
132
|
-
@config.expects(:frameworks=).with(['Addressbook'] +
|
128
|
+
@config.expects(:frameworks=).with(['Addressbook'] + @default_frameworks)
|
133
129
|
@subject.setup
|
134
130
|
end
|
135
131
|
end
|
@@ -9,7 +9,7 @@ describe BubbleWrap::Requirement do
|
|
9
9
|
|
10
10
|
describe '.scan' do
|
11
11
|
before do
|
12
|
-
@subject.
|
12
|
+
@subject.clear!
|
13
13
|
@root_path = File.expand_path('../../../../', __FILE__)
|
14
14
|
end
|
15
15
|
|
@@ -21,7 +21,7 @@ describe BubbleWrap::Requirement do
|
|
21
21
|
|
22
22
|
it 'finds the specified file' do
|
23
23
|
@subject.scan(@root_path, 'motion/core.rb')
|
24
|
-
@subject.paths.keys.
|
24
|
+
@subject.paths.keys.should.include 'motion/core.rb'
|
25
25
|
end
|
26
26
|
|
27
27
|
it 'finds multiple files according to spec' do
|
@@ -33,14 +33,14 @@ describe BubbleWrap::Requirement do
|
|
33
33
|
@subject.scan(@root_path, 'motion/core.rb') do
|
34
34
|
file('motion/core.rb').depends_on 'motion/core.rb'
|
35
35
|
end
|
36
|
-
@subject.file('motion/core.rb').file_dependencies.should
|
36
|
+
@subject.file('motion/core.rb').file_dependencies.should.not.include 'motion/core.rb'
|
37
37
|
end
|
38
38
|
|
39
39
|
it 'can depend on another file' do
|
40
40
|
@subject.scan(@root_path, 'motion/*.rb') do
|
41
41
|
file('motion/http.rb').depends_on('motion/core.rb')
|
42
42
|
end
|
43
|
-
@subject.file('motion/http.rb').file_dependencies.
|
43
|
+
@subject.file('motion/http.rb').file_dependencies.should.include @subject.file('motion/core.rb')
|
44
44
|
end
|
45
45
|
|
46
46
|
it 'can use a framework' do
|
@@ -16,13 +16,13 @@ describe BubbleWrap do
|
|
16
16
|
end
|
17
17
|
|
18
18
|
it 'finds files with relative paths' do
|
19
|
-
BW::Requirement.
|
19
|
+
BW::Requirement.clear!
|
20
20
|
BW.require '../motion/core.rb'
|
21
21
|
BW::Requirement.files.member?(File.expand_path('../../../motion/core.rb', __FILE__)).should == true
|
22
22
|
end
|
23
23
|
|
24
24
|
it 'finds files with absolute paths' do
|
25
|
-
BW::Requirement.
|
25
|
+
BW::Requirement.clear!
|
26
26
|
BW.require File.expand_path('../../../motion/core.rb', __FILE__)
|
27
27
|
BW::Requirement.files.member?(File.expand_path('../../../motion/core.rb', __FILE__)).should == true
|
28
28
|
end
|
@@ -5,7 +5,7 @@ describe BubbleWrap::App do
|
|
5
5
|
end
|
6
6
|
end
|
7
7
|
|
8
|
-
describe '.resources_path' do
|
8
|
+
describe '.resources_path' do
|
9
9
|
it 'should end in "/testSuite.app"' do
|
10
10
|
BW::App.resources_path.should =~ /\/testSuite(_spec)?.app$/
|
11
11
|
end
|
@@ -24,29 +24,114 @@ describe BubbleWrap::App do
|
|
24
24
|
end
|
25
25
|
|
26
26
|
describe '.alert' do
|
27
|
-
before do
|
28
|
-
@alert = BW::App.alert('1.21 Gigawatts!', 'Great Scott!')
|
29
|
-
end
|
30
|
-
|
31
27
|
after do
|
32
28
|
@alert.removeFromSuperview
|
33
29
|
end
|
34
30
|
|
35
|
-
|
36
|
-
|
31
|
+
describe "with only one string argument" do
|
32
|
+
before do
|
33
|
+
@alert = BW::App.alert('1.21 Gigawatts!')
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'returns an alert' do
|
37
|
+
@alert.class.should == UIAlertView
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'is displaying the correct title' do
|
41
|
+
@alert.title.should == '1.21 Gigawatts!'
|
42
|
+
end
|
43
|
+
|
44
|
+
describe 'cancelButton' do
|
45
|
+
it 'is present' do
|
46
|
+
@alert.cancelButtonIndex.should == 0
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'has the correct title' do
|
50
|
+
@alert.buttonTitleAtIndex(@alert.cancelButtonIndex).should == 'OK'
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe "with only two string arguments" do
|
56
|
+
before do
|
57
|
+
@alert = BW::App.alert('1.21 Gigawatts!', 'Great Scott!')
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'returns an alert' do
|
61
|
+
@alert.class.should == UIAlertView
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'is displaying the correct title' do
|
65
|
+
@alert.title.should == '1.21 Gigawatts!'
|
66
|
+
end
|
67
|
+
|
68
|
+
describe 'cancelButton' do
|
69
|
+
it 'is present' do
|
70
|
+
@alert.cancelButtonIndex.should == 0
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'has the correct title' do
|
74
|
+
@alert.buttonTitleAtIndex(@alert.cancelButtonIndex).should == 'Great Scott!'
|
75
|
+
end
|
76
|
+
end
|
37
77
|
end
|
38
78
|
|
39
|
-
|
40
|
-
|
79
|
+
describe "with variable args" do
|
80
|
+
before do
|
81
|
+
@alert = BW::App.alert('1.21 Gigawatts!', cancel_button_title: 'Great Scott!',
|
82
|
+
message: 'Some random message')
|
83
|
+
end
|
84
|
+
|
85
|
+
it 'returns an alert' do
|
86
|
+
@alert.class.should == UIAlertView
|
87
|
+
end
|
88
|
+
|
89
|
+
it 'is displaying the correct title' do
|
90
|
+
@alert.title.should == '1.21 Gigawatts!'
|
91
|
+
end
|
92
|
+
|
93
|
+
it 'is displaying the correct message' do
|
94
|
+
@alert.message.should == 'Some random message'
|
95
|
+
end
|
96
|
+
|
97
|
+
describe 'cancelButton' do
|
98
|
+
it 'is present' do
|
99
|
+
@alert.cancelButtonIndex.should == 0
|
100
|
+
end
|
101
|
+
|
102
|
+
it 'has the correct title' do
|
103
|
+
@alert.buttonTitleAtIndex(@alert.cancelButtonIndex).should == 'Great Scott!'
|
104
|
+
end
|
105
|
+
end
|
41
106
|
end
|
42
107
|
|
43
|
-
describe
|
44
|
-
|
45
|
-
@alert.
|
108
|
+
describe "with a block" do
|
109
|
+
before do
|
110
|
+
@alert = BW::App.alert('1.21 Gigawatts!') do |alert|
|
111
|
+
alert.message = 'My message!!'
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
it 'returns an alert' do
|
116
|
+
@alert.class.should == UIAlertView
|
117
|
+
end
|
118
|
+
|
119
|
+
it 'is displaying the correct title' do
|
120
|
+
@alert.title.should == '1.21 Gigawatts!'
|
121
|
+
end
|
122
|
+
|
123
|
+
it 'is displaying the correct message' do
|
124
|
+
@alert.message.should == 'My message!!'
|
46
125
|
end
|
47
126
|
|
48
|
-
|
49
|
-
|
127
|
+
describe 'cancelButton' do
|
128
|
+
it 'is present' do
|
129
|
+
@alert.cancelButtonIndex.should == 0
|
130
|
+
end
|
131
|
+
|
132
|
+
it 'has the correct title' do
|
133
|
+
@alert.buttonTitleAtIndex(@alert.cancelButtonIndex).should == 'OK'
|
134
|
+
end
|
50
135
|
end
|
51
136
|
end
|
52
137
|
end
|
@@ -105,4 +190,23 @@ describe BubbleWrap::App do
|
|
105
190
|
|
106
191
|
end
|
107
192
|
|
193
|
+
describe ".open_url" do
|
194
|
+
|
195
|
+
it "uses NSURL or converts NSString in NSURL and opens it" do
|
196
|
+
application = UIApplication.sharedApplication
|
197
|
+
def application.url; @url end
|
198
|
+
def application.openURL(url); @url = url end
|
199
|
+
|
200
|
+
url = NSURL.URLWithString('http://localhost')
|
201
|
+
App.open_url(url)
|
202
|
+
application.url.should.equal url
|
203
|
+
|
204
|
+
url = 'http://localhost'
|
205
|
+
App.open_url(url)
|
206
|
+
application.url.class.should.equal NSURL
|
207
|
+
application.url.description.should.equal url
|
208
|
+
end
|
209
|
+
|
210
|
+
end
|
211
|
+
|
108
212
|
end
|
@@ -0,0 +1,130 @@
|
|
1
|
+
def camera_picker
|
2
|
+
@camera.instance_variable_get("@picker")
|
3
|
+
end
|
4
|
+
|
5
|
+
def example_info
|
6
|
+
info = { UIImagePickerControllerMediaType => KUTTypeImage,
|
7
|
+
UIImagePickerControllerOriginalImage => UIImage.alloc.init,
|
8
|
+
UIImagePickerControllerMediaURL => NSURL.alloc.init}
|
9
|
+
end
|
10
|
+
|
11
|
+
describe BubbleWrap::Device::Camera do
|
12
|
+
before do
|
13
|
+
@controller = UIViewController.alloc.init
|
14
|
+
@controller.instance_eval do
|
15
|
+
def presentViewController(*args)
|
16
|
+
true
|
17
|
+
end
|
18
|
+
end
|
19
|
+
@camera = BW::Device::Camera.new
|
20
|
+
end
|
21
|
+
|
22
|
+
describe '.flash?' do
|
23
|
+
before do
|
24
|
+
UIImagePickerController.instance_eval do
|
25
|
+
def self.isCameraDeviceAvailable(c)
|
26
|
+
return true
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.isFlashAvailableForCameraDevice(c)
|
30
|
+
return c == UIImagePickerControllerCameraDeviceFront
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'should be true for front cameras' do
|
36
|
+
BW::Device::Camera.front.flash?.should == true
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'should be false for rear cameras' do
|
40
|
+
BW::Device::Camera.rear.flash?.should == false
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe '.picture' do
|
45
|
+
it 'should have correct error for source_type camera' do
|
46
|
+
@camera.picture({source_type: :camera, media_types: [:image]}, @controller) do |result|
|
47
|
+
result[:error].should == BW::Camera::Error::SOURCE_TYPE_NOT_AVAILABLE
|
48
|
+
camera_picker.nil?.should == true
|
49
|
+
end
|
50
|
+
|
51
|
+
@camera.picture({source_type: :saved_photos_album, media_types: [:image]}, @controller) do |result|
|
52
|
+
result[:error].should == BW::Camera::Error::SOURCE_TYPE_NOT_AVAILABLE
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
describe 'under normal conditions' do
|
57
|
+
before do
|
58
|
+
class FakePickerClass
|
59
|
+
def self.isCameraDeviceAvailable(c)
|
60
|
+
c == UIImagePickerControllerCameraDeviceFront
|
61
|
+
end
|
62
|
+
|
63
|
+
def self.isSourceTypeAvailable(c)
|
64
|
+
c == UIImagePickerControllerSourceTypeCamera
|
65
|
+
end
|
66
|
+
|
67
|
+
def self.availableMediaTypesForSourceType(c)
|
68
|
+
[KUTTypeMovie, KUTTypeImage]
|
69
|
+
end
|
70
|
+
|
71
|
+
def dismissViewControllerAnimated(*args)
|
72
|
+
true
|
73
|
+
end
|
74
|
+
|
75
|
+
def self.method_missing(*args)
|
76
|
+
UIImagePickerController.send(*args)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
@picker_klass = FakePickerClass
|
80
|
+
end
|
81
|
+
|
82
|
+
it 'should work' do
|
83
|
+
camera = BW::Device.camera.front
|
84
|
+
camera.instance_variable_set("@picker_klass", @picker_klass)
|
85
|
+
image_view = nil
|
86
|
+
info = example_info
|
87
|
+
|
88
|
+
camera.picture(media_types: [:movie, :image]) do |result|
|
89
|
+
image_view = UIImageView.alloc.initWithImage(result[:original_image])
|
90
|
+
end
|
91
|
+
|
92
|
+
camera.picker
|
93
|
+
camera.imagePickerController(camera.instance_variable_get("@picker"), didFinishPickingMediaWithInfo: info)
|
94
|
+
image_view.nil?.should == false
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
describe '.imagePickerControllerDidCancel' do
|
100
|
+
it 'should yield the correct error when canceled' do
|
101
|
+
callback_ran = false
|
102
|
+
|
103
|
+
@camera.picture({source_type: :photo_library, media_types: [:image]}, @controller) do |result|
|
104
|
+
result[:error].should == BW::Camera::Error::CANCELED
|
105
|
+
callback_ran = true
|
106
|
+
end
|
107
|
+
|
108
|
+
@camera.imagePickerControllerDidCancel(camera_picker)
|
109
|
+
callback_ran.should == true
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
describe '.imagePickerController:didFinishPickingMediaWithInfo:' do
|
114
|
+
it 'should yield the correct results' do
|
115
|
+
|
116
|
+
info = example_info
|
117
|
+
callback_ran = false
|
118
|
+
|
119
|
+
@camera.picture({source_type: :photo_library, media_types: [:image]}, @controller) do |result|
|
120
|
+
result[:error].nil?.should == true
|
121
|
+
result.keys.should == [:media_type, :original_image, :media_url]
|
122
|
+
result[:media_type].should == :image
|
123
|
+
callback_ran = true
|
124
|
+
end
|
125
|
+
|
126
|
+
@camera.imagePickerController(camera_picker, didFinishPickingMediaWithInfo: info)
|
127
|
+
callback_ran.should == true
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
describe BubbleWrap::Device::CameraWrapper do
|
2
|
+
describe 'on device with only front facing camera' do
|
3
|
+
before do
|
4
|
+
UIImagePickerController.instance_eval do
|
5
|
+
def isCameraDeviceAvailable(c)
|
6
|
+
c == UIImagePickerControllerCameraDeviceFront
|
7
|
+
end
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
describe '.front?' do
|
12
|
+
it 'returns true' do
|
13
|
+
BW::Device.camera.front?.should == true
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe '.rear?' do
|
18
|
+
it 'returns false' do
|
19
|
+
BW::Device.camera.rear?.should == false
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe 'on device with only rear facing camera' do
|
25
|
+
before do
|
26
|
+
UIImagePickerController.instance_eval do
|
27
|
+
def isCameraDeviceAvailable(c)
|
28
|
+
c == UIImagePickerControllerCameraDeviceRear
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe '.front?' do
|
34
|
+
it 'returns false' do
|
35
|
+
BW::Device.camera.front?.should == false
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe '.rear?' do
|
40
|
+
it 'returns true' do
|
41
|
+
BW::Device.camera.rear?.should == true
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|