ws_discovery 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. data/Gemfile +2 -0
  2. data/History.rdoc +3 -0
  3. data/README.rdoc +77 -0
  4. data/Rakefile +16 -0
  5. data/lib/ws_discovery/core_ext/socket_patch.rb +16 -0
  6. data/lib/ws_discovery/error.rb +4 -0
  7. data/lib/ws_discovery/multicast_connection.rb +77 -0
  8. data/lib/ws_discovery/network_constants.rb +13 -0
  9. data/lib/ws_discovery/response.rb +95 -0
  10. data/lib/ws_discovery/searcher.rb +91 -0
  11. data/lib/ws_discovery/version.rb +3 -0
  12. data/lib/ws_discovery.rb +61 -0
  13. data/spec/spec_helper.rb +26 -0
  14. data/spec/ws_discovery/coverage/assets/0.7.1/application.css +1110 -0
  15. data/spec/ws_discovery/coverage/assets/0.7.1/application.js +626 -0
  16. data/spec/ws_discovery/coverage/assets/0.7.1/fancybox/blank.gif +0 -0
  17. data/spec/ws_discovery/coverage/assets/0.7.1/fancybox/fancy_close.png +0 -0
  18. data/spec/ws_discovery/coverage/assets/0.7.1/fancybox/fancy_loading.png +0 -0
  19. data/spec/ws_discovery/coverage/assets/0.7.1/fancybox/fancy_nav_left.png +0 -0
  20. data/spec/ws_discovery/coverage/assets/0.7.1/fancybox/fancy_nav_right.png +0 -0
  21. data/spec/ws_discovery/coverage/assets/0.7.1/fancybox/fancy_shadow_e.png +0 -0
  22. data/spec/ws_discovery/coverage/assets/0.7.1/fancybox/fancy_shadow_n.png +0 -0
  23. data/spec/ws_discovery/coverage/assets/0.7.1/fancybox/fancy_shadow_ne.png +0 -0
  24. data/spec/ws_discovery/coverage/assets/0.7.1/fancybox/fancy_shadow_nw.png +0 -0
  25. data/spec/ws_discovery/coverage/assets/0.7.1/fancybox/fancy_shadow_s.png +0 -0
  26. data/spec/ws_discovery/coverage/assets/0.7.1/fancybox/fancy_shadow_se.png +0 -0
  27. data/spec/ws_discovery/coverage/assets/0.7.1/fancybox/fancy_shadow_sw.png +0 -0
  28. data/spec/ws_discovery/coverage/assets/0.7.1/fancybox/fancy_shadow_w.png +0 -0
  29. data/spec/ws_discovery/coverage/assets/0.7.1/fancybox/fancy_title_left.png +0 -0
  30. data/spec/ws_discovery/coverage/assets/0.7.1/fancybox/fancy_title_main.png +0 -0
  31. data/spec/ws_discovery/coverage/assets/0.7.1/fancybox/fancy_title_over.png +0 -0
  32. data/spec/ws_discovery/coverage/assets/0.7.1/fancybox/fancy_title_right.png +0 -0
  33. data/spec/ws_discovery/coverage/assets/0.7.1/fancybox/fancybox-x.png +0 -0
  34. data/spec/ws_discovery/coverage/assets/0.7.1/fancybox/fancybox-y.png +0 -0
  35. data/spec/ws_discovery/coverage/assets/0.7.1/fancybox/fancybox.png +0 -0
  36. data/spec/ws_discovery/coverage/assets/0.7.1/favicon_green.png +0 -0
  37. data/spec/ws_discovery/coverage/assets/0.7.1/favicon_red.png +0 -0
  38. data/spec/ws_discovery/coverage/assets/0.7.1/favicon_yellow.png +0 -0
  39. data/spec/ws_discovery/coverage/assets/0.7.1/loading.gif +0 -0
  40. data/spec/ws_discovery/coverage/assets/0.7.1/magnify.png +0 -0
  41. data/spec/ws_discovery/coverage/assets/0.7.1/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  42. data/spec/ws_discovery/coverage/assets/0.7.1/smoothness/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
  43. data/spec/ws_discovery/coverage/assets/0.7.1/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
  44. data/spec/ws_discovery/coverage/assets/0.7.1/smoothness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  45. data/spec/ws_discovery/coverage/assets/0.7.1/smoothness/images/ui-bg_glass_75_dadada_1x400.png +0 -0
  46. data/spec/ws_discovery/coverage/assets/0.7.1/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
  47. data/spec/ws_discovery/coverage/assets/0.7.1/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
  48. data/spec/ws_discovery/coverage/assets/0.7.1/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
  49. data/spec/ws_discovery/coverage/assets/0.7.1/smoothness/images/ui-icons_222222_256x240.png +0 -0
  50. data/spec/ws_discovery/coverage/assets/0.7.1/smoothness/images/ui-icons_2e83ff_256x240.png +0 -0
  51. data/spec/ws_discovery/coverage/assets/0.7.1/smoothness/images/ui-icons_454545_256x240.png +0 -0
  52. data/spec/ws_discovery/coverage/assets/0.7.1/smoothness/images/ui-icons_888888_256x240.png +0 -0
  53. data/spec/ws_discovery/coverage/assets/0.7.1/smoothness/images/ui-icons_cd0a0a_256x240.png +0 -0
  54. data/spec/ws_discovery/coverage/index.html +72 -0
  55. data/spec/ws_discovery/multicast_connection_spec.rb +108 -0
  56. data/spec/ws_discovery/response_spec.rb +118 -0
  57. data/spec/ws_discovery/searcher_spec.rb +85 -0
  58. data/spec/ws_discovery_spec.rb +43 -0
  59. data/ws_discovery.gemspec +32 -0
  60. metadata +296 -0
@@ -0,0 +1,72 @@
1
+ <!DOCTYPE html>
2
+ <html xmlns='http://www.w3.org/1999/xhtml'>
3
+ <head>
4
+ <title>Code coverage for Ws discovery</title>
5
+ <meta http-equiv="content-type" content="text/html; charset=utf-8" />
6
+ <script src='./assets/0.7.1/application.js' type='text/javascript'></script>
7
+ <link href='./assets/0.7.1/application.css' media='screen, projection, print' rel='stylesheet' type='text/css'>
8
+ <link rel="shortcut icon" type="image/png" href="./assets/0.7.1/favicon_green.png" />
9
+ <link rel="icon" type="image/png" href="./assets/0.7.1/favicon.png" />
10
+ </head>
11
+
12
+ <body>
13
+ <div id="loading">
14
+ <img src="./assets/0.7.1/loading.gif" alt="loading"/>
15
+ </div>
16
+ <div id="wrapper" style="display:none;">
17
+ <div class="timestamp">Generated <abbr class="timeago" title="2012-11-12T13:50:26-08:00">2012-11-12T13:50:26-08:00</abbr></div>
18
+ <ul class="group_tabs"></ul>
19
+
20
+ <div id="content">
21
+ <div class="file_list_container" id="AllFiles">
22
+ <h2>
23
+ <span class="group_name">All Files</span>
24
+ (<span class="covered_percent"><span class="green">100.0%</span></span>
25
+ covered at
26
+ <span class="covered_strength">
27
+ <span class="red">
28
+ 0.0
29
+ </span>
30
+ </span> hits/line)
31
+ </h2>
32
+ <a name="AllFiles"></a>
33
+ <div>
34
+ <b>0</b> files in total.
35
+ <b>0.0</b> relevant lines.
36
+ <span class="green"><b>0.0</b> lines covered</span> and
37
+ <span class="red"><b>0.0</b> lines missed </span>
38
+ </div>
39
+ <table class="file_list">
40
+ <thead>
41
+ <tr>
42
+ <th>File</th>
43
+ <th>% covered</th>
44
+ <th>Lines</th>
45
+ <th>Relevant Lines</th>
46
+ <th>Lines covered</th>
47
+ <th>Lines missed</th>
48
+ <th>Avg. Hits / Line</th>
49
+ </tr>
50
+ </thead>
51
+ <tbody>
52
+
53
+ </tbody>
54
+ </table>
55
+ </div>
56
+
57
+
58
+
59
+ </div>
60
+
61
+ <div id="footer">
62
+ Generated by <a href="http://github.com/colszowka/simplecov">simplecov</a> v0.7.1
63
+ and simplecov-html v0.7.1<br/>
64
+ using RSpec
65
+ </div>
66
+
67
+ <div class="source_files">
68
+
69
+ </div>
70
+ </div>
71
+ </body>
72
+ </html>
@@ -0,0 +1,108 @@
1
+ require 'spec_helper'
2
+ require 'ws_discovery/multicast_connection'
3
+
4
+ describe WSDiscovery::MulticastConnection do
5
+ around(:each) do |example|
6
+ EM.run do
7
+ example.run
8
+ EM.stop
9
+ end
10
+ end
11
+
12
+ subject { WSDiscovery::MulticastConnection.new(1) }
13
+
14
+ describe "#peer_info" do
15
+ before do
16
+ WSDiscovery::MulticastConnection.any_instance.stub(:setup_multicast_socket)
17
+ subject.stub_chain(:get_peername, :[], :unpack).and_return(%w(1234 1 2 3 4))
18
+ end
19
+
20
+ it "returns an Array with IP and port" do
21
+ subject.send(:peer_info).should == ['1.2.3.4', 1234]
22
+ end
23
+
24
+ it "returns IP as a String" do
25
+ subject.send(:peer_info).first.should be_a String
26
+ end
27
+
28
+ it "returns port as a Fixnum" do
29
+ subject.send(:peer_info).last.should be_a Fixnum
30
+ end
31
+ end
32
+
33
+ describe "#setup_multicast_socket" do
34
+ before do
35
+ WSDiscovery::MulticastConnection.any_instance.stub(:set_membership)
36
+ WSDiscovery::MulticastConnection.any_instance.stub(:switch_multicast_loop)
37
+ WSDiscovery::MulticastConnection.any_instance.stub(:set_multicast_ttl)
38
+ WSDiscovery::MulticastConnection.any_instance.stub(:set_ttl)
39
+ end
40
+
41
+ it "adds 0.0.0.0 and 239.255.255.250 to the membership group" do
42
+ subject.should_receive(:set_membership).with(
43
+ IPAddr.new('239.255.255.250').hton + IPAddr.new('0.0.0.0').hton
44
+ )
45
+ subject.send(:setup_multicast_socket)
46
+ end
47
+
48
+ it "sets multicast TTL to 1" do
49
+ subject.should_receive(:set_multicast_ttl).with(1)
50
+ subject.send(:setup_multicast_socket)
51
+ end
52
+
53
+ it "sets TTL to 1" do
54
+ subject.should_receive(:set_ttl).with(1)
55
+ subject.send(:setup_multicast_socket)
56
+ end
57
+
58
+ context "ENV['RUBY_TESTING_ENV'] != testing" do
59
+ after { ENV['RUBY_TESTING_ENV'] = "testing" }
60
+
61
+ it "turns multicast loop off" do
62
+ ENV['RUBY_TESTING_ENV'] = "development"
63
+ subject.should_receive(:switch_multicast_loop).with(:off)
64
+ subject.send(:setup_multicast_socket)
65
+ end
66
+ end
67
+ end
68
+
69
+ describe "#switch_multicast_loop" do
70
+ before do
71
+ WSDiscovery::MulticastConnection.any_instance.stub(:setup_multicast_socket)
72
+ end
73
+
74
+ it "passes '\\001' to the socket option call when param == :on" do
75
+ subject.should_receive(:set_sock_opt).with(
76
+ 0, Socket::IP_MULTICAST_LOOP, "\001"
77
+ )
78
+ subject.send(:switch_multicast_loop, :on)
79
+ end
80
+
81
+ it "passes '\\001' to the socket option call when param == '\\001'" do
82
+ subject.should_receive(:set_sock_opt).with(
83
+ 0, Socket::IP_MULTICAST_LOOP, "\001"
84
+ )
85
+ subject.send(:switch_multicast_loop,"\001")
86
+ end
87
+
88
+ it "passes '\\000' to the socket option call when param == :off" do
89
+ subject.should_receive(:set_sock_opt).with(
90
+ 0, Socket::IP_MULTICAST_LOOP, "\000"
91
+ )
92
+ subject.send(:switch_multicast_loop,:off)
93
+ end
94
+
95
+ it "passes '\\000' to the socket option call when param == '\\000'" do
96
+ subject.should_receive(:set_sock_opt).with(
97
+ 0, Socket::IP_MULTICAST_LOOP, "\000"
98
+ )
99
+ subject.send(:switch_multicast_loop,"\000")
100
+ end
101
+
102
+ it "raises when not :on, :off, '\\000', or '\\001'" do
103
+ expect { subject.send(:switch_multicast_loop, 12312312) }.
104
+ to raise_error(WSDiscovery::Error)
105
+ end
106
+ end
107
+ end
108
+
@@ -0,0 +1,118 @@
1
+ require 'spec_helper'
2
+ require 'ws_discovery/response'
3
+
4
+ describe WSDiscovery::Response do
5
+ let(:probe_response) do
6
+ <<-PROBE
7
+ <s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope"
8
+ xmlns:a="http://schemas.xmlsoap.org/ws/2004/08/addressing"
9
+ xmlns:d="http://schemas.xmlsoap.org/ws/2005/04/discovery">
10
+ <s:Header>
11
+ <a:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:To>
12
+ <a:Action>http://schemas.xmlsoap.org/ws/2005/04/discovery/ProbeMatches</a:Action>
13
+ <a:MessageID>urn:uuid:18523f7e-7a54-d92d-a18d-e7165bec8e7e</a:MessageID>
14
+ <a:RelatesTo>uuid:7dbdede0-0f2b-0130-5861-002564b29b24</a:RelatesTo>
15
+ <d:AppSequence MessageNumber="42" InstanceId="2"/>
16
+ </s:Header>
17
+ <s:Body>
18
+ <d:ProbeMatches>
19
+ <d:ProbeMatch>
20
+ <a:EndpointReference>
21
+ <a:Address>urn:uuid:0b679890-fc54-14ba-d428-f73b3e7c2400</a:Address>
22
+ </a:EndpointReference>
23
+ <d:Types xmlns:dn="http://www.onvif.org/ver10/network/wsdl">dn:NetworkVideoTransmitter</d:Types>
24
+ <d:Scopes>onvif://www.onvif.org/Profile/Streaming onvif://www.onvif.org/hardware/NET5404T onvif://www.onvif.org/type/ptz onvif://www.onvif.org/type/video_encoder onvif://www.onvif.org/location/country/usa onvif://www.onvif.org/name/NET5404T-ABEPZH7</d:Scopes>
25
+ <d:XAddrs>http://10.221.222.74/onvif/device_service</d:XAddrs>
26
+ <d:MetadataVersion>1</d:MetadataVersion>
27
+ </d:ProbeMatch>
28
+ </d:ProbeMatches>
29
+ </s:Body>
30
+ </s:Envelope>
31
+ PROBE
32
+ end
33
+
34
+ let(:probe_body_hash) do
35
+ { probe_matches: {
36
+ probe_match: {
37
+ endpoint_reference: {
38
+ address: "urn:uuid:0b679890-fc54-14ba-d428-f73b3e7c2400" },
39
+ types: "dn:NetworkVideoTransmitter",
40
+ scopes: "onvif://www.onvif.org/Profile/Streaming onvif://www.onvif.org/hardware/NET5404T onvif://www.onvif.org/type/ptz onvif://www.onvif.org/type/video_encoder onvif://www.onvif.org/location/country/usa onvif://www.onvif.org/name/NET5404T-ABEPZH7",
41
+ x_addrs: "http://10.221.222.74/onvif/device_service",
42
+ metadata_version: "1" } } }
43
+ end
44
+
45
+ let(:probe_header_hash) do
46
+ { to: "http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous",
47
+ action: "http://schemas.xmlsoap.org/ws/2005/04/discovery/ProbeMatches",
48
+ message_id: "urn:uuid:18523f7e-7a54-d92d-a18d-e7165bec8e7e",
49
+ relates_to: "uuid:7dbdede0-0f2b-0130-5861-002564b29b24",
50
+ app_sequence: {
51
+ :@message_number => "42",
52
+ :@instance_id => "2" } }
53
+ end
54
+
55
+ let(:probe_full_hash) do
56
+ { envelope: { header: probe_header_hash, body: probe_body_hash,
57
+ :"@xmlns:s" => "http://www.w3.org/2003/05/soap-envelope",
58
+ :"@xmlns:a" => "http://schemas.xmlsoap.org/ws/2004/08/addressing",
59
+ :"@xmlns:d" => "http://schemas.xmlsoap.org/ws/2005/04/discovery" } }
60
+ end
61
+
62
+ subject { WSDiscovery::Response.new(probe_response) }
63
+
64
+ describe "#[]" do
65
+ it "should return the SOAP response body as a Hash" do
66
+ subject[:probe_matches].should == probe_body_hash[:probe_matches]
67
+ end
68
+
69
+ it "should throw an exception when the response body isn't parsable" do
70
+ expect { WSDiscovery::Response.new('').body }.to raise_error WSDiscovery::Error
71
+ end
72
+ end
73
+
74
+ describe "#header" do
75
+ it "should return the SOAP response header as a Hash" do
76
+ subject.header[:app_sequence].should == probe_header_hash[:app_sequence]
77
+ end
78
+
79
+ it "should throw an exception when the response header isn't parsable" do
80
+ expect { WSDiscovery::Response.new('').header }.to raise_error WSDiscovery::Error
81
+ end
82
+ end
83
+
84
+ %w(body to_hash).each do |method|
85
+ describe "##{method}" do
86
+ it "should return the SOAP response body as a Hash" do
87
+ subject.send(method)[:probe_matches].should == probe_body_hash[:probe_matches]
88
+ end
89
+ end
90
+ end
91
+
92
+ describe "#hash" do
93
+ it "should return the complete SOAP response XML as a Hash" do
94
+ subject.hash.should == probe_full_hash
95
+ end
96
+ end
97
+
98
+ describe "#to_xml" do
99
+ it "should return the raw SOAP response body" do
100
+ subject.to_xml.should == probe_response
101
+ end
102
+ end
103
+
104
+ describe "#doc" do
105
+ it "returns a Nokogiri::XML::Document for the SOAP response XML" do
106
+ subject.doc.should be_a(Nokogiri::XML::Document)
107
+ end
108
+ end
109
+
110
+ describe "#xpath" do
111
+ it "permits XPath access to elements in the request" do
112
+ subject.xpath("//a:Address").first.inner_text.
113
+ should == "urn:uuid:0b679890-fc54-14ba-d428-f73b3e7c2400"
114
+ subject.xpath("//d:ProbeMatch/d:XAddrs").first.inner_text.
115
+ should == "http://10.221.222.74/onvif/device_service"
116
+ end
117
+ end
118
+ end
@@ -0,0 +1,85 @@
1
+ require 'spec_helper'
2
+ require 'ws_discovery/searcher'
3
+
4
+ describe WSDiscovery::Searcher do
5
+ let(:default_probe) do
6
+ "<s:Envelope xmlns:a=\"http://schemas.xmlsoap.org/ws/2004/08/addressing\" " +
7
+ "xmlns:d=\"http://schemas.xmlsoap.org/ws/2005/04/discovery\" xmlns:s=\"h" +
8
+ "ttp://www.w3.org/2003/05/soap-envelope\"><s:Header><a:Action>http://sch" +
9
+ "emas.xmlsoap.org/ws/2005/04/discovery/Probe</a:Action><a:MessageID>uuid" +
10
+ ":a-uuid</a:MessageID><a:To>urn:schemas-xmlsoap-org:ws:2005:04:discovery" +
11
+ "</a:To></s:Header><s:Body><d:Types/><d:Scopes/></s:Body></s:Envelope>"
12
+ end
13
+
14
+ around(:each) do |example|
15
+ EM.run do
16
+ example.run
17
+ EM.stop
18
+ end
19
+ end
20
+
21
+ before do
22
+ WSDiscovery::Searcher.log = false
23
+ WSDiscovery::MulticastConnection.any_instance.stub(:setup_multicast_socket)
24
+ UUID.stub(:generate).and_return('a-uuid')
25
+ end
26
+
27
+ subject do
28
+ WSDiscovery::Searcher.new(1)
29
+ end
30
+
31
+ describe "#initialize" do
32
+ it "does a #probe" do
33
+ WSDiscovery::Searcher.any_instance.should_receive(:probe)
34
+
35
+ subject
36
+ end
37
+ end
38
+
39
+ describe "#receive_data" do
40
+ let(:parsed_response) do
41
+ double 'parsed response'
42
+ end
43
+
44
+ it "takes a response and adds it to the list of responses" do
45
+ response = double 'response'
46
+ subject.stub(:peer_info).and_return(['0.0.0.0', 4567])
47
+
48
+ subject.should_receive(:parse).with(response).exactly(1).times.
49
+ and_return(parsed_response)
50
+ subject.instance_variable_get(:@discovery_responses).should_receive(:<<).
51
+ with(parsed_response)
52
+
53
+ subject.receive_data(response)
54
+ end
55
+ end
56
+
57
+ describe "#parse" do
58
+ before do
59
+ WSDiscovery::MulticastConnection.any_instance.stub(:setup_multicast_socket)
60
+ end
61
+
62
+ it "turns probe matches into WSDiscovery::Responses" do
63
+ result = subject.parse "<Envelope />"
64
+ result.should be_a WSDiscovery::Response
65
+ end
66
+ end
67
+
68
+ describe "#post_init" do
69
+ before { WSDiscovery::Searcher.any_instance.stub(:m_search).and_return("hi") }
70
+
71
+ it "sends a probe as a datagram over 239.255.255.250:3702" do
72
+ subject.should_receive(:send_datagram).
73
+ with(default_probe, '239.255.255.250', 3702).
74
+ and_return 0
75
+ subject.post_init
76
+ end
77
+ end
78
+
79
+ describe "#probe" do
80
+ it "builds the MSEARCH string using the given parameters" do
81
+ subject.probe.should == default_probe
82
+ end
83
+ end
84
+ end
85
+
@@ -0,0 +1,43 @@
1
+ require 'spec_helper'
2
+ require 'ws_discovery'
3
+
4
+ describe WSDiscovery do
5
+ subject { WSDiscovery }
6
+
7
+ describe '.search' do
8
+ let(:multicast_searcher) do
9
+ searcher = double "WSDiscovery::Searcher"
10
+ searcher.stub_chain(:discovery_responses, :subscribe).and_yield(%w[one two])
11
+
12
+ searcher
13
+ end
14
+
15
+ before do
16
+ EM.stub(:run).and_yield
17
+ EM.stub(:add_timer)
18
+ EM.stub(:open_datagram_socket).and_return multicast_searcher
19
+ end
20
+
21
+ context "reactor is already running" do
22
+ it "returns a WSDiscovery::Searcher" do
23
+ EM.stub(:reactor_running?).and_return true
24
+ subject.search.should == multicast_searcher
25
+ end
26
+ end
27
+
28
+ context "reactor is not already running" do
29
+ it "returns an Array of responses" do
30
+ EM.stub(:add_shutdown_hook).and_yield
31
+ subject.search.should == %w[one two]
32
+ end
33
+
34
+ it "opens a UDP socket on '0.0.0.0', port 0" do
35
+ EM.stub(:add_shutdown_hook)
36
+ EM.should_receive(:open_datagram_socket).with('0.0.0.0', 0,
37
+ WSDiscovery::Searcher, {})
38
+ subject.search
39
+ end
40
+ end
41
+ end
42
+ end
43
+
@@ -0,0 +1,32 @@
1
+ $:.push File.expand_path("../lib", __FILE__)
2
+ require 'ws_discovery/version'
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = "ws_discovery"
6
+ s.version = WSDiscovery::VERSION
7
+ s.homepage = "https://github.com/pelco-automation/ws-discovery"
8
+ s.author = "tindron"
9
+ s.email = "rstoller@gmail.com"
10
+ s.description = "Perform a multicast search for devices using WS-Discovery"
11
+ s.summary = "Search for devices using WS-Discovery"
12
+
13
+ s.required_rubygems_version = ">=1.8.0"
14
+ s.required_ruby_version = Gem::Requirement.new(">= 1.9.3")
15
+ s.files = Dir.glob("{lib,spec}/**/*") + Dir.glob("*.rdoc") +
16
+ %w(Gemfile ws_discovery.gemspec Rakefile)
17
+ s.require_paths = ["lib"]
18
+
19
+ s.add_dependency("builder")
20
+ s.add_dependency("eventmachine")
21
+ s.add_dependency("log_switch", ">=0.1.4")
22
+ s.add_dependency("nokogiri")
23
+ s.add_dependency("nori")
24
+ s.add_dependency("uuid")
25
+
26
+ s.add_development_dependency("bundler", ">= 1.0.21")
27
+ s.add_development_dependency("rake", ">= 0")
28
+ s.add_development_dependency("rspec", "~> 2.6")
29
+ s.add_development_dependency("simplecov", ">= 0")
30
+ s.add_development_dependency("simplecov-rcov", ">= 0")
31
+ s.add_development_dependency("yard", ">= 0.7.2")
32
+ end