bubble-wrap 1.0.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. data/.gitignore +0 -1
  2. data/.yardopts +2 -0
  3. data/CHANGELOG.md +15 -0
  4. data/Gemfile +1 -1
  5. data/Gemfile.lock +24 -0
  6. data/HACKING.md +2 -2
  7. data/README.md +363 -21
  8. data/Rakefile +6 -2
  9. data/lib/bubble-wrap.rb +0 -1
  10. data/lib/bubble-wrap/all.rb +4 -0
  11. data/lib/bubble-wrap/camera.rb +7 -0
  12. data/lib/bubble-wrap/core.rb +3 -2
  13. data/lib/bubble-wrap/ext/motion_project_app.rb +2 -2
  14. data/lib/bubble-wrap/http.rb +1 -0
  15. data/lib/bubble-wrap/loader.rb +19 -12
  16. data/lib/bubble-wrap/location.rb +6 -0
  17. data/lib/bubble-wrap/reactor.rb +10 -0
  18. data/lib/bubble-wrap/requirement.rb +11 -3
  19. data/lib/bubble-wrap/rss_parser.rb +2 -0
  20. data/lib/bubble-wrap/ui.rb +4 -0
  21. data/lib/bubble-wrap/version.rb +1 -1
  22. data/motion/core.rb +8 -2
  23. data/motion/core/app.rb +34 -6
  24. data/motion/core/device.rb +10 -1
  25. data/motion/core/device/camera.rb +219 -0
  26. data/motion/core/device/camera_wrapper.rb +45 -0
  27. data/motion/core/ns_url_request.rb +10 -0
  28. data/motion/core/persistence.rb +7 -0
  29. data/motion/core/pollute.rb +1 -2
  30. data/motion/core/string.rb +23 -0
  31. data/motion/http.rb +142 -83
  32. data/motion/location/location.rb +152 -0
  33. data/motion/location/pollute.rb +5 -0
  34. data/motion/reactor.rb +105 -0
  35. data/motion/reactor/default_deferrable.rb +9 -0
  36. data/motion/reactor/deferrable.rb +126 -0
  37. data/motion/reactor/eventable.rb +24 -0
  38. data/motion/reactor/future.rb +22 -0
  39. data/motion/reactor/periodic_timer.rb +27 -0
  40. data/motion/reactor/queue.rb +60 -0
  41. data/motion/reactor/timer.rb +25 -0
  42. data/motion/rss_parser.rb +131 -0
  43. data/motion/shortcut.rb +18 -0
  44. data/motion/{core → ui}/gestures.rb +15 -9
  45. data/motion/ui/pollute.rb +5 -0
  46. data/motion/{core → ui}/ui_control.rb +0 -0
  47. data/motion/{core → ui}/ui_view_controller.rb +0 -0
  48. data/resources/atom.xml +1705 -0
  49. data/spec/lib/bubble-wrap/ext/motion_project_app_spec.rb +7 -11
  50. data/spec/lib/bubble-wrap/requirement_spec.rb +4 -4
  51. data/spec/lib/bubble-wrap_spec.rb +2 -2
  52. data/spec/motion/core/app_spec.rb +118 -14
  53. data/spec/motion/core/device/camera_spec.rb +130 -0
  54. data/spec/motion/core/device/camera_wrapper_spec.rb +45 -0
  55. data/spec/motion/core/device_spec.rb +0 -50
  56. data/spec/motion/core/gestures_spec.rb +5 -0
  57. data/spec/motion/core/persistence_spec.rb +24 -2
  58. data/spec/motion/core/string_spec.rb +55 -0
  59. data/spec/motion/core_spec.rb +72 -1
  60. data/spec/motion/http_spec.rb +100 -65
  61. data/spec/motion/location/location_spec.rb +152 -0
  62. data/spec/motion/reactor/eventable_spec.rb +40 -0
  63. data/spec/motion/reactor_spec.rb +163 -0
  64. data/spec/motion/rss_parser_spec.rb +36 -0
  65. 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(defaults)
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(defaults)
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
- defaults = ['CoreGraphics', 'Foundation', 'UIKit']
110
- @config.stubs(:frameworks).returns(defaults)
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(defaults + ['Addressbook'])
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'] + defaults)
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.paths = {}
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.first.should == 'motion/core.rb'
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.size.should == 1
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.paths = {}
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.paths = {}
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
- it 'returns an alert' do
36
- @alert.class.should == UIAlertView
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
- it 'is displaying the correct title' do
40
- @alert.title.should == '1.21 Gigawatts!'
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 'cancelButton' do
44
- it 'is present' do
45
- @alert.cancelButtonIndex.should == 0
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
- it 'has the correct title' do
49
- @alert.buttonTitleAtIndex(@alert.cancelButtonIndex).should == 'Great Scott!'
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