Salut 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2010 Mark Rada
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.markdown ADDED
@@ -0,0 +1,84 @@
1
+ Salut
2
+ =====
3
+
4
+ Salut is just a little bit of example code of using Bonjour with MacRuby.
5
+
6
+ Of course, this is not a substitute for reading the [Bonjour Overview](http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/NetServices/Introduction.html%23//apple_ref/doc/uid/TP40002445-SW1) and related documentation (not even close).
7
+
8
+ Reference Documentation
9
+ =======================
10
+
11
+ Apple's superb documentation of Bonjour and the Bonjour Objective-C interface:
12
+
13
+ - [Bonjour Overview](http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/NetServices/Introduction.html%23//apple_ref/doc/uid/TP40002445-SW1)
14
+ - [NSNetServices Programming Guide](http://developer.apple.com/library/ios/#documentation/Networking/Conceptual/NSNetServiceProgGuide/Introduction.html)
15
+ - [NSNetService](http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSNetService_Class/Reference/Reference.html)
16
+ - [NSNetServiceDelegate Protocol](http://developer.apple.com/library/ios/#documentation/cocoa/reference/NSNetServiceDelegate_Protocol/Reference/Reference.html)
17
+ - [NSNetServiceBrowser](http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSNetServiceBrowser_Class/Reference/Reference.html)
18
+ - [NSNetServiceBrowserDelegate Protocol](http://developer.apple.com/library/ios/#documentation/cocoa/reference/NSNetServiceBrowserDelegate_Protocol/Reference/Reference.html)
19
+
20
+ Example Usage
21
+ =============
22
+
23
+ Advertising a hypothetical service:
24
+
25
+ service = Salut::Service.new({
26
+ service_type:'_http._tcp.',
27
+ instance_name:`hostname s`.chomp,
28
+ port:3000
29
+ })
30
+ service.start_advertising
31
+
32
+ Finding the service using the browser:
33
+
34
+ browser = Salut::Browser.new
35
+ # look at the delegate methods to find out what variables are given to the proc
36
+ browser.delegates[:'netServiceBrowser:didFindService:moreComing:'] = Proc.new {
37
+ |sender, service, more|
38
+ service.resolve # because we want to resolve them all!
39
+ if more
40
+ NSLog('Not up to date yet')
41
+ else
42
+ NSLog('All caught up')
43
+ end
44
+ }
45
+ browser.find_services '_http._tcp.', in_domain:''
46
+
47
+ If you want to stop advertising:
48
+
49
+ service.stop_advertising
50
+
51
+ You might notice that you aren't seeing the results of the callbacks, this is because
52
+ they are waiting for the current run loop to cycle. This would happen automatically with
53
+ a GUI app, but a command line app will have to force the loop to run.
54
+
55
+ NSRunLoop.currentRunLoop.run # => runs indefinitely
56
+ NSRunLoop.currentRunLoop.runUntiDate (Time.now + 5) # => runs for 5 seconds
57
+
58
+ You can only use a Service or Browser for one thing at a time, and the API is designed
59
+ with that assumption in mind.
60
+
61
+ TODO
62
+ ====
63
+
64
+ - Monitoring and TXT record stuff
65
+ - publishWithOptions default argument
66
+ - Do not pass NSNetService or NSNetServiceBrowser to callbacks
67
+
68
+ Contributing to Salut
69
+ =====================
70
+
71
+ * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
72
+ * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
73
+ * Fork the project
74
+ * Start a feature/bugfix branch
75
+ * Commit and push until you are happy with your contribution
76
+ * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
77
+ * Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
78
+
79
+ Copyright
80
+ =========
81
+
82
+ Copyright (c) 2010 Mark Rada. See LICENSE.txt for
83
+ further details.
84
+
@@ -0,0 +1,169 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ module Salut
4
+
5
+ # Browsers are used for searching for services or domains. A single instance
6
+ # should only be used for a single search.
7
+ #
8
+ # You should be careful not to reuse the same instance for multiple
9
+ # searches without calling {#stop_searching}, otherwise you are likely to get
10
+ # an error logged. The reason for this is that a browser never really
11
+ # stops searching (unless you call {#stop_searching}), even if moreComing
12
+ # is false. moreComing is a signal that the browser up to date on the network
13
+ # state for the moment but any new network state changes will trigger the
14
+ # callbacks again.
15
+ class Browser
16
+
17
+ # @return [Boolean]
18
+ attr_reader :searching
19
+ alias_method :searching?, :searching
20
+
21
+ # @return [Array<String>]
22
+ attr_reader :domains
23
+
24
+ # @return [Array<NSNetService>]
25
+ attr_reader :services
26
+
27
+ # Ensure that some instance variables are initialized
28
+ def initialize
29
+ @browser = NSNetServiceBrowser.alloc.init
30
+ @browser.delegate = self
31
+ @domains = []
32
+ @services = []
33
+ @delegates = {}
34
+ @searching = false
35
+ end
36
+
37
+ # Stop searching for things, whether they be domains or services
38
+ def stop_finding
39
+ @browser.stop
40
+ end
41
+
42
+
43
+ # @group Adding callback extensions
44
+
45
+ # @return [Hash{Symbol=>Proc}]
46
+ attr_accessor :delegates
47
+
48
+ # A shortcut for reading from the delegate methods
49
+ # @param [Symbol] key
50
+ # @return [Proc]
51
+ def [] key
52
+ @delegates[key]
53
+ end
54
+
55
+ # A shortcut for writing to the delegate methods hash
56
+ # @param [Symbol] key
57
+ # @param [Proc] value
58
+ # @return [Proc]
59
+ def []= key, value
60
+ @delegates[key] = value
61
+ end
62
+
63
+ # @endgroup
64
+
65
+
66
+ # @group Finding domains
67
+
68
+ # @return [nil]
69
+ def find_browsable_domains
70
+ @browser.searchForBrowsableDomains
71
+ end
72
+
73
+ alias_method :stop_finding_domains, :stop_finding
74
+
75
+ # @endgroup
76
+
77
+
78
+ # @group Finding services
79
+
80
+ # @param [String] service_name
81
+ # @param [String] domain_name
82
+ def find_services service_type, in_domain:domain_name
83
+ @browser.searchForServicesOfType service_type, inDomain:domain_name
84
+ end
85
+
86
+ alias_method :stop_finding_services, :stop_finding
87
+
88
+ # @endgroup
89
+
90
+
91
+ # @group Delegate methods
92
+
93
+ # @yieldparam [NSNetServiceBrowser] sender
94
+ # @yieldparam [String] domain_name
95
+ # @yieldparam [Boolean] more
96
+ # @return [nil]
97
+ def netServiceBrowser sender, didFindDomain:domain_name, moreComing:more
98
+ @domains << domain_name
99
+ @delegates[__method__].call sender, domain_name, more if @delegates[__method__]
100
+ Salut.log.info "Found domain: #{domain_name}"
101
+ end
102
+
103
+ # @yieldparam [NSNetServiceBrowser] sender
104
+ # @yieldparam [String] domain_name
105
+ # @yieldparam [Boolean] more
106
+ # @return [nil]
107
+ def netServiceBrowser sender, didRemoveDomain:domain_name, moreComing:more
108
+ @domains.delete domain_name
109
+ @delegates[__method__].call sender, domain_name, more if @delegates[__method__]
110
+ Salut.log.info "Removing domain: #{domain_name}"
111
+ end
112
+
113
+ # @yieldparam [NSNetServiceBrowser] sender
114
+ # @yieldparam [Salut::Service] service
115
+ # @yieldparam [Boolean] more
116
+ # @return [nil]
117
+ def netServiceBrowser sender, didFindService:service, moreComing:more
118
+ salut_service = Service.new({ service:service })
119
+ @services << salut_service
120
+ @delegates[__method__].call sender, salut_service, more if @delegates[__method__]
121
+ Salut.log.info "Found service (#{service.description})"
122
+ end
123
+
124
+ # @yieldparam [NSNetServiceBrowser] sender
125
+ # @yieldparam [Salut::Service] removed_service
126
+ # @yieldparam [Boolean] more
127
+ # @return [nil]
128
+ def netServiceBrowser sender, didRemoveService:service, moreComing:more
129
+ removed_service
130
+ @services.delete_if { |salut_service|
131
+ if salut_service.service == service
132
+ removed_service = salut_service
133
+ true
134
+ end
135
+ }
136
+ @delegates[__method__].call sender, removed_service, more if @delegates[__method__]
137
+ Salut.log.info "Removing service (#{service.description})"
138
+ end
139
+
140
+ # @yieldparam [NSNetServiceBrowser] sender
141
+ # @return [nil]
142
+ def netServiceBrowserWillSearch sender
143
+ @searching = true
144
+ @delegates[__method__].call sender if @delegates[__method__]
145
+ Salut.log.info "Starting search (#{sender.description})"
146
+ end
147
+
148
+ # @yieldparam [NSNetServiceBrowser] sender
149
+ # @yieldparam [Hash] error_dict
150
+ # @return [nil]
151
+ def netServiceBrowser sender, didNotSearch:error_dict
152
+ @searching = false
153
+ @delegates[__method__].call sender, error_dict if @delegates[__method__]
154
+ Salut.log.info "Failed to search (#{sender.description})\n\t problem was\n#{error_dict.description}"
155
+ end
156
+
157
+ # @yieldparam [NSNetServiceBrowser] sender
158
+ # @return [nil]
159
+ def netServiceBrowserDidStopSearch sender
160
+ @searching = false
161
+ @delegates[__method__].call sender if @delegates[__method__]
162
+ Salut.log.info "Done searching (#{sender.description})"
163
+ end
164
+
165
+ # @endgroup
166
+
167
+ end
168
+
169
+ end
@@ -0,0 +1,188 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ module Salut
4
+
5
+ # Advertises its service on the local network using Bonjour or is
6
+ # a service that was found using Sault::Browser.
7
+ #
8
+ # Note that an instance of the service should be used for one or the
9
+ # other, but not both. Some methods are meant for when you are using
10
+ # Service to advertise a service and other methods are meant for when
11
+ # you are working with services that have been discovered.
12
+ class Service
13
+
14
+ # @return [Boolean]
15
+ attr_reader :advertising
16
+ alias_method :advertising?, :advertising
17
+
18
+ # @return [NSNetService]
19
+ attr_reader :service
20
+
21
+ # @return [String]
22
+ attr_accessor :service_type
23
+
24
+ # @return [String]
25
+ attr_accessor :instance_name
26
+
27
+ # @return [Fixnum]
28
+ attr_accessor :port
29
+
30
+ # @example Initializing with properties
31
+ # service = Advertiser.new({
32
+ # service_type:'_http._tcp.',
33
+ # instance_name:'Test',
34
+ # port:3000
35
+ # })
36
+ # @example Initializing with an existing service
37
+ # service = Advertiser.new({
38
+ # service:NSNetService.alloc.initWithDomain('',
39
+ # type:'_http._tcp.',
40
+ # name:`hostname -s`.chomp,
41
+ # port:3000)
42
+ # })
43
+ # @param [Hash{Symbol=>(String,Fixnum,NSNetService)}] params
44
+ def initialize params = {}
45
+ @service_type = params[:service_type]
46
+ @instance_name = params[:instance_name]
47
+ @port = params[:port]
48
+ @service = params[:service]
49
+ @delegates = {}
50
+ @advertising = false
51
+ end
52
+
53
+
54
+ # @group Adding callback extensions
55
+
56
+ # @return [Hash{Symbol=>Proc}]
57
+ attr_accessor :delegates
58
+
59
+ # A shortcut for reading from the delegate methods
60
+ # @param [Symbol] key
61
+ # @return [Proc]
62
+ def [] key
63
+ @delegates[key]
64
+ end
65
+
66
+ # A shortcut for writing to the delegate methods hash
67
+ # @param [Symbol] key
68
+ # @param [Proc] value
69
+ # @return [Proc]
70
+ def []= key, value
71
+ @delegates[key] = value
72
+ end
73
+
74
+ # @endgroup
75
+
76
+
77
+ # @group Advertising a service
78
+
79
+ # Start advertising the service. If you want to change the service
80
+ # type, instance name, or port, you will have to {#stop_advertising}
81
+ # first.
82
+ #
83
+ # If there is an error creating the underlying NSNetService object
84
+ # (usually because one of @service_type, @instance_name, and @port
85
+ # are not specified) then you will get a NilClass NoMethodError when
86
+ # the method tries to set the delegate.
87
+ # @param [String] domain defaults to all domains
88
+ def start_advertising domain = ''
89
+ @service = NSNetService.alloc.initWithDomain domain,
90
+ type:@service_type,
91
+ name:@instance_name,
92
+ port:@port
93
+ @service.delegate = self
94
+ @service.publish
95
+ end
96
+
97
+ # Stop advertising the service, which is a nice thing to do when you
98
+ # are cleaning up before exiting your code, but the script/program
99
+ # exiting will also cause the service to stop being published.
100
+ def stop_advertising
101
+ @service.stop
102
+ @service = nil
103
+ end
104
+
105
+ # @endgroup
106
+
107
+
108
+ # @group Working with discovered services
109
+
110
+ # A more Ruby-like #resolveWithTimeout by supporting a default argument
111
+ # @param [Float] timeout number of seconds to wait before timing out
112
+ def resolve timeout = 60.0
113
+ @service.resolveWithTimeout timeout
114
+ end
115
+
116
+ # @endgroup
117
+
118
+
119
+ # @group Delegate methods
120
+
121
+ # @yieldparam [NSNetService] sender
122
+ # @return [nil]
123
+ def netServiceWillPublish sender
124
+ @delegates[__method__].call sender if @delegates[__method__]
125
+ Salut.log.info "Starting to advertise service (#{sender.description})"
126
+ end
127
+
128
+ # @yieldparam [NSNetService] sender
129
+ # @yieldparam [Hash] error_dict
130
+ # @return [nil]
131
+ def netService sender, didNotPublish:error_dict
132
+ @advertising = false
133
+ @delegates[__method__].call sender, error_dict if @delegates[__method__]
134
+ Salut.log.info "ERROR: could not advertise service (#{sender.description})\n\t the problem was\n#{error_dict.description}"
135
+ end
136
+
137
+ # @yieldparam [NSNetService] sender
138
+ # @return [nil]
139
+ def netServiceDidPublish sender
140
+ @advertising = true
141
+ @delegates[__method__].call sender if @delegates[__method__]
142
+ Salut.log.info "Successfully advertising service (#{sender.description})"
143
+ end
144
+
145
+ # @yieldparam [NSNetService] sender
146
+ # @return [nil]
147
+ def netServiceWillResolve sender
148
+ @delegates[__method__].call sender if @delegates[__method__]
149
+ Salut.log.info "Resolving service (#{sender.description})"
150
+ end
151
+
152
+ # @yieldparam [NSNetService] sender
153
+ # @yieldparam [Hash] error_dict
154
+ # @return [nil]
155
+ def netService sender, didNotResolve:error_dict
156
+ @delegates[__method__].call sender if @delegates[__method__]
157
+ Salut.log.info "ERROR: could not resolve service (#{sender.description})\n\t the problem was\n#{error_dict.description}"
158
+ end
159
+
160
+ # @yieldparam [NSNetService] sender
161
+ # @return [nil]
162
+ def netServiceDidResolveAddress sender
163
+ @delegates[__method__].call sender if @delegates[__method__]
164
+ Salut.log.info "Resolved address for service (#{sender.description})"
165
+ end
166
+
167
+ # @todo should I process the TXT record before giving it to the proc?
168
+ # @yieldparam [NSNetService] sender
169
+ # @yieldparam [NSData] data the new TXT record
170
+ # @return [nil]
171
+ def netService sender, didUpdateTXTRecordData:data
172
+ @delegates[__method__].call sender, data if @delegates[__method__]
173
+ Salut.log.info "Updated TXT record for service (#{sender.description})"
174
+ end
175
+
176
+ # @yieldparam [NSNetService] sender
177
+ # @return [nil]
178
+ def netServiceDidStop sender
179
+ @advertising = false
180
+ @delegates[__method__].call sender if @delegates[__method__]
181
+ Salut.log.info "Stopped advertising service (#{sender.description})"
182
+ end
183
+
184
+ # @endgroup
185
+
186
+ end
187
+
188
+ end
data/lib/Salut.rb ADDED
@@ -0,0 +1,21 @@
1
+ # -*- coding: utf-8 -*-
2
+ framework 'Foundation'
3
+ require 'logger'
4
+
5
+ require 'Salut/Service'
6
+ require 'Salut/Browser'
7
+
8
+ # A class to help with advertising services using Bonjour and finding
9
+ # other services that are being advertised using Bonjour.
10
+ module Salut
11
+
12
+ class << self
13
+
14
+ # @return [Logger]
15
+ attr_accessor :log
16
+
17
+ end
18
+
19
+ @log = Logger.new STDERR
20
+
21
+ end
@@ -0,0 +1,2 @@
1
+ require './spec_helper'
2
+
@@ -0,0 +1,307 @@
1
+ require './spec_helper'
2
+
3
+ describe Salut::Service do
4
+ before do
5
+ Salut.log.level = Logger::WARN
6
+ end
7
+
8
+ describe '#advertising?' do
9
+ before do
10
+ @service = Salut::Service.new({
11
+ port:3000,
12
+ instance_name:'Test',
13
+ service_type:'_http._tcp.'
14
+ })
15
+ end
16
+
17
+ it 'should be initialized to false' do
18
+ @service.advertising?.should.be.equal false
19
+ end
20
+
21
+ it 'should be false when I start advertising (until #netServiceDidPublish is called)' do
22
+ @service.start_advertising
23
+ @service.advertising?.should.be.equal false
24
+ end
25
+
26
+ it 'should be false after I stop advertising' do
27
+ @service.start_advertising
28
+ NSRunLoop.currentRunLoop.runUntilDate Time.now + 2
29
+ @service.stop_advertising
30
+ NSRunLoop.currentRunLoop.runUntilDate Time.now + 2
31
+ @service.advertising?.should.be.equal false
32
+ end
33
+
34
+ it 'should be false if advertising fails' do
35
+ @other_service = @service.dup
36
+ @service.start_advertising
37
+ NSRunLoop.currentRunLoop.runUntilDate Time.now + 2
38
+ @other_service.start_advertising
39
+ NSRunLoop.currentRunLoop.runUntilDate Time.now + 2
40
+ @other_service.advertising?.should.be.equal false
41
+ end
42
+
43
+ it 'should be true when advertising is successful' do
44
+ @service.start_advertising
45
+ NSRunLoop.currentRunLoop.runUntilDate Time.now + 2
46
+ @service.advertising?.should.be.equal true
47
+ end
48
+ end
49
+
50
+
51
+ describe '#service' do
52
+ it 'is an NSNetService instance' do
53
+ end
54
+
55
+ it 'can be set at initialization' do
56
+ end
57
+
58
+ it 'will be created when advertising starts' do
59
+ end
60
+
61
+ it 'will be set to nil when advertising stops' do
62
+ end
63
+ end
64
+
65
+
66
+ describe '#initialize' do
67
+ it 'will let you initialize the port number' do
68
+ end
69
+
70
+ it 'will let you initialize the instance name' do
71
+ end
72
+
73
+ it 'will let you initialize the service type' do
74
+ end
75
+
76
+ it 'will let you initialize with a service' do
77
+ end
78
+
79
+ it 'will initialize delegates to an empty hash' do
80
+ end
81
+
82
+ it 'will initialize @advertising to false' do
83
+ end
84
+
85
+ it 'will let you initialize with nothing being set' do
86
+ end
87
+ end
88
+
89
+
90
+ describe '#delegates' do
91
+ it 'should be initialized to an empty hash' do
92
+ end
93
+
94
+ it 'should be writable' do
95
+ end
96
+ end
97
+
98
+
99
+ describe '#[]' do
100
+ it 'should be equivalent to #delegates' do
101
+ end
102
+ end
103
+
104
+
105
+ describe '#[]=' do
106
+ it 'should be equivalent to #delegates=' do
107
+ end
108
+ end
109
+
110
+
111
+ describe '#start_advertising' do
112
+ it 'should create a new @service object' do
113
+ end
114
+
115
+ it 'should set the delegate for @service to self' do
116
+ end
117
+
118
+ # a fragile test since it depends on one of the callbacks
119
+ # being called
120
+ it 'should call #publish on @service' do
121
+ end
122
+
123
+ it 'should set domain to an empty string by default' do
124
+ end
125
+
126
+ it 'should allow me to specify a domain' do
127
+ end
128
+ end
129
+
130
+
131
+ describe '#stop_advertising' do
132
+ # a fragile test since it depends on one of the callbacks
133
+ # being called
134
+ it 'should call #stop on @service' do
135
+ end
136
+
137
+ it 'should set @service to nil' do
138
+ end
139
+ end
140
+
141
+
142
+ describe '#resolve' do
143
+ before do
144
+ # need a browser to find stuff to resolve
145
+ end
146
+
147
+ # a fragile test since it depends on one of the callbacks
148
+ # being called
149
+ it 'should cause the resolve callback to be called' do
150
+ end
151
+
152
+ it 'should timeout after 60 seconds' do
153
+ end
154
+
155
+ it 'should allow me to override the timeout' do
156
+ end
157
+ end
158
+
159
+
160
+ describe 'callback skeletons' do
161
+
162
+ before do
163
+ # set the logger to log INFO and log to a stringIO object
164
+ end
165
+
166
+
167
+ describe '#netServiceWillPublish' do
168
+ it 'should call its proc if exists' do
169
+ end
170
+
171
+ it 'should not explode if the proc does not exist' do
172
+ end
173
+
174
+ it 'should log a message at the INFO level' do
175
+ end
176
+
177
+ it 'should pass self to the proc' do
178
+ end
179
+ end
180
+
181
+
182
+ describe '#netService:didNotPublish:' do
183
+ it 'should call its proc if exists' do
184
+ end
185
+
186
+ it 'should not explode if the proc does not exist' do
187
+ end
188
+
189
+ it 'should log a message at the INFO level' do
190
+ end
191
+
192
+ it 'should set @advertising to false' do
193
+ end
194
+
195
+ it 'should pass self to the proc' do
196
+ end
197
+
198
+ it 'should pass the error dict to the proc' do
199
+ end
200
+ end
201
+
202
+
203
+ describe '#netServiceDidPublish' do
204
+ it 'should call its proc if exists' do
205
+ end
206
+
207
+ it 'should not explode if the proc does not exist' do
208
+ end
209
+
210
+ it 'should log a message at the INFO level' do
211
+ end
212
+
213
+ it 'should set @advertising to true' do
214
+ end
215
+
216
+ it 'should pass self to the proc' do
217
+ end
218
+ end
219
+
220
+
221
+ describe '#netServiceWillResolve' do
222
+ it 'should call its proc if exists' do
223
+ end
224
+
225
+ it 'should not explode if the proc does not exist' do
226
+ end
227
+
228
+ it 'should log a message at the INFO level' do
229
+ end
230
+
231
+ it 'should pass self to the proc' do
232
+ end
233
+ end
234
+
235
+
236
+ describe '#netService:didNotResolve:' do
237
+ it 'should call its proc if exists' do
238
+ end
239
+
240
+ it 'should not explode if the proc does not exist' do
241
+ end
242
+
243
+ it 'should log a message at the INFO level' do
244
+ end
245
+
246
+ it 'should pass self to the proc' do
247
+ end
248
+
249
+ it 'should pass the error dict to the proc' do
250
+ end
251
+ end
252
+
253
+
254
+ describe '#netServiceDidResolveAddress' do
255
+ it 'should call its proc if exists' do
256
+ end
257
+
258
+ it 'should not explode if the proc does not exist' do
259
+ end
260
+
261
+ it 'should log a message at the INFO level' do
262
+ end
263
+
264
+ it 'should pass self to the proc' do
265
+ end
266
+ end
267
+
268
+
269
+ describe '#netService:didUpdateTXTRecordData:' do
270
+ it 'should call its proc if exists' do
271
+ end
272
+
273
+ it 'should not explode if the proc does not exist' do
274
+ end
275
+
276
+ it 'should log a message at the INFO level' do
277
+ end
278
+
279
+ it 'should pass self to the proc' do
280
+ end
281
+
282
+ it 'should pass the TXT record data to the proc' do
283
+ end
284
+ end
285
+
286
+
287
+ describe '#netServiceDidStop' do
288
+ it 'should call its proc if exists' do
289
+ end
290
+
291
+ it 'should not explode if the proc does not exist' do
292
+ end
293
+
294
+ it 'should log a message at the INFO level' do
295
+ end
296
+
297
+ it 'should set @advertising to false' do
298
+ end
299
+
300
+ it 'should pass self to the proc' do
301
+ end
302
+ end
303
+
304
+ end
305
+
306
+
307
+ end
@@ -0,0 +1,6 @@
1
+ require 'rubygems'
2
+ require 'mac_bacon'
3
+
4
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
5
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
6
+ require 'Salut'
metadata ADDED
@@ -0,0 +1,146 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: Salut
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 3
8
+ - 0
9
+ version: 0.3.0
10
+ platform: ruby
11
+ authors:
12
+ - Mark Rada
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2011-01-17 00:00:00 -05:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: yard
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ~>
27
+ - !ruby/object:Gem::Version
28
+ segments:
29
+ - 0
30
+ - 6
31
+ - 0
32
+ version: 0.6.0
33
+ type: :development
34
+ version_requirements: *id001
35
+ - !ruby/object:Gem::Dependency
36
+ name: bluecloth
37
+ prerelease: false
38
+ requirement: &id002 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ~>
42
+ - !ruby/object:Gem::Version
43
+ segments:
44
+ - 2
45
+ - 0
46
+ - 0
47
+ version: 2.0.0
48
+ type: :development
49
+ version_requirements: *id002
50
+ - !ruby/object:Gem::Dependency
51
+ name: jeweler
52
+ prerelease: false
53
+ requirement: &id003 !ruby/object:Gem::Requirement
54
+ none: false
55
+ requirements:
56
+ - - ~>
57
+ - !ruby/object:Gem::Version
58
+ segments:
59
+ - 1
60
+ - 5
61
+ - 1
62
+ version: 1.5.1
63
+ type: :development
64
+ version_requirements: *id003
65
+ - !ruby/object:Gem::Dependency
66
+ name: mac_bacon
67
+ prerelease: false
68
+ requirement: &id004 !ruby/object:Gem::Requirement
69
+ none: false
70
+ requirements:
71
+ - - ~>
72
+ - !ruby/object:Gem::Version
73
+ segments:
74
+ - 1
75
+ - 1
76
+ - 21
77
+ version: 1.1.21
78
+ type: :development
79
+ version_requirements: *id004
80
+ - !ruby/object:Gem::Dependency
81
+ name: rcov
82
+ prerelease: false
83
+ requirement: &id005 !ruby/object:Gem::Requirement
84
+ none: false
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ segments:
89
+ - 0
90
+ version: "0"
91
+ type: :development
92
+ version_requirements: *id005
93
+ description: Uses the Objective-C NetService classes to advertise and discover services on the local network
94
+ email: marada@uwaterloo.ca
95
+ executables: []
96
+
97
+ extensions: []
98
+
99
+ extra_rdoc_files:
100
+ - LICENSE.txt
101
+ - README.markdown
102
+ files:
103
+ - lib/Salut.rb
104
+ - lib/Salut/Browser.rb
105
+ - lib/Salut/Service.rb
106
+ - LICENSE.txt
107
+ - README.markdown
108
+ - spec/Browser_spec.rb
109
+ - spec/Service_spec.rb
110
+ - spec/spec_helper.rb
111
+ has_rdoc: true
112
+ homepage: http://github.com/ferrous26/Salut
113
+ licenses:
114
+ - MIT
115
+ post_install_message:
116
+ rdoc_options: []
117
+
118
+ require_paths:
119
+ - lib
120
+ required_ruby_version: !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - ">="
124
+ - !ruby/object:Gem::Version
125
+ segments:
126
+ - 0
127
+ version: "0"
128
+ required_rubygems_version: !ruby/object:Gem::Requirement
129
+ none: false
130
+ requirements:
131
+ - - ">="
132
+ - !ruby/object:Gem::Version
133
+ segments:
134
+ - 0
135
+ version: "0"
136
+ requirements: []
137
+
138
+ rubyforge_project:
139
+ rubygems_version: 1.3.7
140
+ signing_key:
141
+ specification_version: 3
142
+ summary: A simple example of using Bonjour with MacRuby
143
+ test_files:
144
+ - spec/Browser_spec.rb
145
+ - spec/Service_spec.rb
146
+ - spec/spec_helper.rb