rtsp 0.2.2 → 0.3.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.
- data/ChangeLog.rdoc +7 -0
- data/features/step_definitions/client_requests_steps.rb +1 -1
- data/lib/rtsp.rb +1 -3
- data/lib/rtsp/client.rb +7 -8
- data/lib/rtsp/message.rb +7 -5
- data/lib/rtsp/response.rb +8 -7
- data/lib/rtsp/version.rb +1 -1
- data/rtsp.gemspec +18 -22
- data/spec/rtsp/client_spec.rb +3 -3
- data/tasks/roodi.rake +9 -0
- data/tasks/{roodi_config.yml → roodi_config.yaml} +3 -3
- metadata +72 -41
- data/lib/rtsp/capturer.rb +0 -223
- data/spec/rtsp/capturer_spec.rb +0 -258
- data/tasks/metrics.rake +0 -27
data/ChangeLog.rdoc
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
=== 0.3.0 / 2012-03-02
|
2
|
+
|
3
|
+
* Extracted RTP-esque functionality to an +rtp+ gem, on which this gem is now
|
4
|
+
dependent on version 0.0.1 of that.
|
5
|
+
* Laxed dependency requirement on parslet.
|
6
|
+
* Bumped dependency requirement on sdp to ~> 0.2.6, due to parslet conflicts
|
7
|
+
|
1
8
|
=== 0.2.2 / 2011-11-02
|
2
9
|
|
3
10
|
* Added a queue for listening and building the RTP file from the received data.
|
@@ -41,7 +41,7 @@ Then /^I should receive an RTSP response to that OPTIONS request$/ do
|
|
41
41
|
@response.message.should == "OK"
|
42
42
|
@response.cseq.should == 1
|
43
43
|
@response.public.should == "DESCRIBE, SETUP, TEARDOWN, PLAY, PAUSE"
|
44
|
-
@response.body.should
|
44
|
+
@response.body.should be_empty
|
45
45
|
end
|
46
46
|
|
47
47
|
Then /^I should receive an RTSP response to that DESCRIBE request$/ do
|
data/lib/rtsp.rb
CHANGED
data/lib/rtsp/client.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
require 'socket'
|
2
2
|
require 'tempfile'
|
3
3
|
require 'timeout'
|
4
|
+
require 'rtp/receiver'
|
4
5
|
|
5
6
|
require_relative 'transport_parser'
|
6
|
-
require_relative 'capturer'
|
7
7
|
require_relative 'error'
|
8
8
|
require_relative 'global'
|
9
9
|
require_relative 'helpers'
|
@@ -13,7 +13,7 @@ require_relative 'response'
|
|
13
13
|
module RTSP
|
14
14
|
|
15
15
|
# This is the main interface to an RTSP server. A client object uses a couple
|
16
|
-
# main objects for configuration: an +
|
16
|
+
# main objects for configuration: an +RTP::Receiver+ and a Connection Struct.
|
17
17
|
# Use the capturer to configure how to capture the data which is the RTP
|
18
18
|
# stream provided by the RTSP server. Use the connection object to control
|
19
19
|
# the connection to the server.
|
@@ -56,7 +56,6 @@ module RTSP
|
|
56
56
|
include RTSP::Helpers
|
57
57
|
extend RTSP::Global
|
58
58
|
|
59
|
-
DEFAULT_CAPFILE_NAME = "ruby_rtsp_capture.rtsp"
|
60
59
|
MAX_BYTES_TO_RECEIVE = 3000
|
61
60
|
|
62
61
|
# @return [URI] The URI that points to the RTSP server's resource.
|
@@ -80,8 +79,8 @@ module RTSP
|
|
80
79
|
attr_accessor :connection
|
81
80
|
|
82
81
|
# Use to get/set an object for capturing received data.
|
83
|
-
# @param [
|
84
|
-
# @return [
|
82
|
+
# @param [RTP::Receiver]
|
83
|
+
# @return [RTP::Receiver]
|
85
84
|
attr_accessor :capturer
|
86
85
|
|
87
86
|
# @return [Symbol] See {RFC section A.1.}[http://tools.ietf.org/html/rfc2326#page-76]
|
@@ -95,7 +94,7 @@ module RTSP
|
|
95
94
|
|
96
95
|
# @param [String] server_url URL to the resource to stream. If no scheme is
|
97
96
|
# given, "rtsp" is assumed. If no port is given, 554 is assumed.
|
98
|
-
# @yield [Struct::Connection,
|
97
|
+
# @yield [Struct::Connection, RTP::Receiver]
|
99
98
|
# @yieldparam [Struct::Connection] server_url=
|
100
99
|
# @yieldparam [Struct::Connection] timeout=
|
101
100
|
# @yieldparam [Struct::Connection] socket=
|
@@ -111,7 +110,7 @@ module RTSP
|
|
111
110
|
end
|
112
111
|
|
113
112
|
@connection = Struct::Connection.new
|
114
|
-
@capturer =
|
113
|
+
@capturer = RTP::Receiver.new
|
115
114
|
|
116
115
|
yield(connection, capturer) if block_given?
|
117
116
|
|
@@ -124,7 +123,7 @@ module RTSP
|
|
124
123
|
@capturer.rtp_port ||= 9000
|
125
124
|
@capturer.transport_protocol ||= :UDP
|
126
125
|
@capturer.broadcast_type ||= :unicast
|
127
|
-
@capturer.rtp_file ||= Tempfile.new(DEFAULT_CAPFILE_NAME)
|
126
|
+
@capturer.rtp_file ||= Tempfile.new(RTP::Receiver::DEFAULT_CAPFILE_NAME)
|
128
127
|
|
129
128
|
@play_thread = nil
|
130
129
|
@cseq = 1
|
data/lib/rtsp/message.rb
CHANGED
@@ -138,8 +138,8 @@ module RTSP
|
|
138
138
|
end
|
139
139
|
|
140
140
|
# @param [String] value Content to send as the body of the message.
|
141
|
-
#
|
142
|
-
#
|
141
|
+
# Generally this will be a String of some sort, but could be binary data as
|
142
|
+
# well. Also, this adds the Content-Length header to the header list.
|
143
143
|
def body= value
|
144
144
|
add_body value
|
145
145
|
end
|
@@ -201,7 +201,9 @@ module RTSP
|
|
201
201
|
# @return [String]
|
202
202
|
def headers_to_s headers
|
203
203
|
header_string = headers.inject("") do |result, (key, value)|
|
204
|
-
header_name = key.to_s.split(/_/).map
|
204
|
+
header_name = key.to_s.split(/_/).map do |header|
|
205
|
+
header.capitalize
|
206
|
+
end.join('-')
|
205
207
|
|
206
208
|
header_name = "CSeq" if header_name == "Cseq"
|
207
209
|
|
@@ -248,8 +250,8 @@ module RTSP
|
|
248
250
|
# Turns header values into a single string.
|
249
251
|
#
|
250
252
|
# @param [] values The header values to put to string.
|
251
|
-
# @param [String] separator The character to use to separate multiple
|
252
|
-
# that define a header.
|
253
|
+
# @param [String] separator The character to use to separate multiple
|
254
|
+
# values that define a header.
|
253
255
|
# @return [String] The header values as a single string.
|
254
256
|
def values_to_s(values, separator=";")
|
255
257
|
result = values.inject("") do |values_string, (header_field, header_field_value)|
|
data/lib/rtsp/response.rb
CHANGED
@@ -16,7 +16,8 @@ module RTSP
|
|
16
16
|
# server/client.
|
17
17
|
def initialize(raw_response)
|
18
18
|
if raw_response.nil? || raw_response.empty?
|
19
|
-
raise RTSP::Error,
|
19
|
+
raise RTSP::Error,
|
20
|
+
"#{self.class} received nil string--this shouldn't happen."
|
20
21
|
end
|
21
22
|
|
22
23
|
@raw_response = raw_response
|
@@ -77,9 +78,9 @@ module RTSP
|
|
77
78
|
end
|
78
79
|
end
|
79
80
|
|
80
|
-
# Reads through each header line of the RTSP response, extracts the
|
81
|
-
# code, response message, response version, and creates a
|
82
|
-
# accessor with that value set.
|
81
|
+
# Reads through each header line of the RTSP response, extracts the
|
82
|
+
# response code, response message, response version, and creates a
|
83
|
+
# snake-case accessor with that value set.
|
83
84
|
#
|
84
85
|
# @param [String] head The section of headers from the response text.
|
85
86
|
def parse_head head
|
@@ -90,7 +91,7 @@ module RTSP
|
|
90
91
|
extract_status_line(line)
|
91
92
|
next
|
92
93
|
end
|
93
|
-
|
94
|
+
|
94
95
|
if line.include? ": "
|
95
96
|
header_and_value = line.strip.split(":", 2)
|
96
97
|
header_name = header_and_value.first.downcase.gsub(/-/, "_")
|
@@ -119,8 +120,8 @@ module RTSP
|
|
119
120
|
|
120
121
|
private
|
121
122
|
|
122
|
-
# Creates an attr_reader with the name given and sets it to the value
|
123
|
-
# given.
|
123
|
+
# Creates an attr_reader with the name given and sets it to the value
|
124
|
+
# that's given.
|
124
125
|
#
|
125
126
|
# @param [String] name
|
126
127
|
# @param [String] value
|
data/lib/rtsp/version.rb
CHANGED
data/rtsp.gemspec
CHANGED
@@ -8,37 +8,33 @@ Gem::Specification.new do |s|
|
|
8
8
|
s.name = "rtsp"
|
9
9
|
s.version = RTSP::VERSION
|
10
10
|
|
11
|
-
s.
|
12
|
-
s.authors = ["Steve Loveless, Mike Kirby"]
|
13
|
-
s.
|
11
|
+
s.homepage = %q{http://rubygems.org/gems/rtsp}
|
12
|
+
s.authors = ["Steve Loveless, Mike Kirby", "Sujin Philip"]
|
13
|
+
s.summary = %q{Library to allow RTSP streaming from RTSP-enabled devices.}
|
14
14
|
s.description = %q{This library intends to follow the RTSP RFC document (2326)
|
15
15
|
to allow for working with RTSP servers. At this point, it's up to you to parse
|
16
16
|
the data from a play call, but we'll get there. ...eventually.
|
17
17
|
For more information see: http://www.ietf.org/rfc/rfc2326.txt}
|
18
|
-
s.email =
|
19
|
-
s.
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
s.
|
26
|
-
%w(.gemtest rtsp.gemspec) +
|
27
|
-
%w(Gemfile ChangeLog.rdoc LICENSE.rdoc README.rdoc Rakefile)
|
28
|
-
s.homepage = %q{http://rubygems.org/gems/rtsp}
|
29
|
-
s.licenses = ["MIT"]
|
30
|
-
s.require_paths = ["lib"]
|
31
|
-
s.rubyforge_project = %q{rtsp}
|
18
|
+
s.email = %w{steve.loveless@gmail.com}
|
19
|
+
s.licenses = %w{MIT}
|
20
|
+
|
21
|
+
s.executables = %w{rtsp_client}
|
22
|
+
s.files = Dir.glob("{lib,bin,spec,tasks}/**/*") + Dir.glob("*.rdoc") +
|
23
|
+
%w(.gemtest rtsp.gemspec Gemfile Rakefile)
|
24
|
+
s.extra_rdoc_files = %w{ChangeLog.rdoc LICENSE.rdoc README.rdoc}
|
25
|
+
s.require_paths = %w{lib}
|
32
26
|
s.rubygems_version = %q{1.7.2}
|
33
|
-
s.summary = %q{Library to allow RTSP streaming from RTSP-enabled devices.}
|
34
27
|
s.test_files = Dir.glob("{spec,features}/**/*")
|
35
28
|
|
36
|
-
s.add_runtime_dependency(%q<parslet>, ["
|
37
|
-
s.add_runtime_dependency(%q<
|
29
|
+
s.add_runtime_dependency(%q<parslet>, [">= 1.1.0"])
|
30
|
+
s.add_runtime_dependency(%q<rtp>, [">= 0.0.1"])
|
31
|
+
s.add_runtime_dependency(%q<sdp>, ["~> 0.2.6"])
|
38
32
|
|
39
|
-
s.add_development_dependency(%q<bundler
|
33
|
+
s.add_development_dependency(%q<bundler>)
|
40
34
|
s.add_development_dependency(%q<code_statistics>, ["~> 0.2.13"])
|
41
|
-
s.add_development_dependency(%q<
|
35
|
+
s.add_development_dependency(%q<cucumber>, [">= 1.1.0"])
|
36
|
+
s.add_development_dependency(%q<roodi>, [">= 2.1.0"])
|
37
|
+
s.add_development_dependency(%q<rake>, [">= 0.8.7"])
|
42
38
|
s.add_development_dependency(%q<rspec>, [">= 2.5.0"])
|
43
39
|
s.add_development_dependency(%q<simplecov>, [">= 0.4.0"])
|
44
40
|
s.add_development_dependency(%q<yard>, [">= 0.6.0"])
|
data/spec/rtsp/client_spec.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'sdp'
|
2
2
|
require_relative '../spec_helper'
|
3
3
|
require 'rtsp/client'
|
4
|
-
|
4
|
+
require_relative '../support/fake_rtsp_server'
|
5
5
|
|
6
6
|
describe RTSP::Client do
|
7
7
|
def setup_client_at(url)
|
@@ -20,8 +20,8 @@ describe RTSP::Client do
|
|
20
20
|
end
|
21
21
|
|
22
22
|
before do
|
23
|
-
|
24
|
-
|
23
|
+
RTP::Receiver.any_instance.stub(:run)
|
24
|
+
RTP::Receiver.any_instance.stub(:stop)
|
25
25
|
end
|
26
26
|
|
27
27
|
describe "#initialize" do
|
data/tasks/roodi.rake
ADDED
@@ -2,13 +2,13 @@
|
|
2
2
|
AssignmentInConditionalCheck: { }
|
3
3
|
CaseMissingElseCheck: { }
|
4
4
|
ClassLineCountCheck: { line_count: 300 }
|
5
|
-
ClassNameCheck: { pattern: !ruby/regexp /^[A-Z][a-zA-Z0-9]*$/ }
|
5
|
+
ClassNameCheck: { pattern: !ruby/regexp '/^[A-Z][a-zA-Z0-9]*$/' }
|
6
6
|
CyclomaticComplexityBlockCheck: { complexity: 4 }
|
7
7
|
CyclomaticComplexityMethodCheck: { complexity: 8 }
|
8
8
|
EmptyRescueBodyCheck: { }
|
9
9
|
ForLoopCheck: { }
|
10
10
|
MethodLineCountCheck: { line_count: 30 }
|
11
|
-
MethodNameCheck: { pattern: !ruby/regexp /^[_a-z<>=\[\]|+-\/\*`]+[_a-z0-9_<>=~@\[\]]*[=!\?]?$/ }
|
11
|
+
MethodNameCheck: { pattern: !ruby/regexp '/^[_a-z<>=\[\]|+-\/\*`]+[_a-z0-9_<>=~@\[\]]*[=!\?]?$/' }
|
12
12
|
ModuleLineCountCheck: { line_count: 300 }
|
13
|
-
ModuleNameCheck: { pattern: !ruby/regexp /^[A-Z][a-zA-Z0-9]*$/ }
|
13
|
+
ModuleNameCheck: { pattern: !ruby/regexp '/^[A-Z][a-zA-Z0-9]*$/' }
|
14
14
|
ParameterNumberCheck: { parameter_count: 5 }
|
metadata
CHANGED
@@ -1,52 +1,64 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rtsp
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Steve Loveless, Mike Kirby
|
9
|
+
- Sujin Philip
|
9
10
|
autorequire:
|
10
11
|
bindir: bin
|
11
12
|
cert_chain: []
|
12
|
-
date:
|
13
|
+
date: 2012-03-03 00:00:00.000000000 Z
|
13
14
|
dependencies:
|
14
15
|
- !ruby/object:Gem::Dependency
|
15
16
|
name: parslet
|
16
|
-
requirement: &
|
17
|
+
requirement: &70350646954280 !ruby/object:Gem::Requirement
|
17
18
|
none: false
|
18
19
|
requirements:
|
19
|
-
- -
|
20
|
+
- - ! '>='
|
20
21
|
- !ruby/object:Gem::Version
|
21
22
|
version: 1.1.0
|
22
23
|
type: :runtime
|
23
24
|
prerelease: false
|
24
|
-
version_requirements: *
|
25
|
+
version_requirements: *70350646954280
|
26
|
+
- !ruby/object:Gem::Dependency
|
27
|
+
name: rtp
|
28
|
+
requirement: &70350646952740 !ruby/object:Gem::Requirement
|
29
|
+
none: false
|
30
|
+
requirements:
|
31
|
+
- - ! '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 0.0.1
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: *70350646952740
|
25
37
|
- !ruby/object:Gem::Dependency
|
26
38
|
name: sdp
|
27
|
-
requirement: &
|
39
|
+
requirement: &70350646950580 !ruby/object:Gem::Requirement
|
28
40
|
none: false
|
29
41
|
requirements:
|
30
42
|
- - ~>
|
31
43
|
- !ruby/object:Gem::Version
|
32
|
-
version: 0.2.
|
44
|
+
version: 0.2.6
|
33
45
|
type: :runtime
|
34
46
|
prerelease: false
|
35
|
-
version_requirements: *
|
47
|
+
version_requirements: *70350646950580
|
36
48
|
- !ruby/object:Gem::Dependency
|
37
49
|
name: bundler
|
38
|
-
requirement: &
|
50
|
+
requirement: &70350646949960 !ruby/object:Gem::Requirement
|
39
51
|
none: false
|
40
52
|
requirements:
|
41
|
-
- -
|
53
|
+
- - ! '>='
|
42
54
|
- !ruby/object:Gem::Version
|
43
|
-
version:
|
55
|
+
version: '0'
|
44
56
|
type: :development
|
45
57
|
prerelease: false
|
46
|
-
version_requirements: *
|
58
|
+
version_requirements: *70350646949960
|
47
59
|
- !ruby/object:Gem::Dependency
|
48
60
|
name: code_statistics
|
49
|
-
requirement: &
|
61
|
+
requirement: &70350646948280 !ruby/object:Gem::Requirement
|
50
62
|
none: false
|
51
63
|
requirements:
|
52
64
|
- - ~>
|
@@ -54,21 +66,43 @@ dependencies:
|
|
54
66
|
version: 0.2.13
|
55
67
|
type: :development
|
56
68
|
prerelease: false
|
57
|
-
version_requirements: *
|
69
|
+
version_requirements: *70350646948280
|
58
70
|
- !ruby/object:Gem::Dependency
|
59
|
-
name:
|
60
|
-
requirement: &
|
71
|
+
name: cucumber
|
72
|
+
requirement: &70350646946800 !ruby/object:Gem::Requirement
|
61
73
|
none: false
|
62
74
|
requirements:
|
63
75
|
- - ! '>='
|
64
76
|
- !ruby/object:Gem::Version
|
65
|
-
version:
|
77
|
+
version: 1.1.0
|
66
78
|
type: :development
|
67
79
|
prerelease: false
|
68
|
-
version_requirements: *
|
80
|
+
version_requirements: *70350646946800
|
81
|
+
- !ruby/object:Gem::Dependency
|
82
|
+
name: roodi
|
83
|
+
requirement: &70350646945400 !ruby/object:Gem::Requirement
|
84
|
+
none: false
|
85
|
+
requirements:
|
86
|
+
- - ! '>='
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: 2.1.0
|
89
|
+
type: :development
|
90
|
+
prerelease: false
|
91
|
+
version_requirements: *70350646945400
|
92
|
+
- !ruby/object:Gem::Dependency
|
93
|
+
name: rake
|
94
|
+
requirement: &70350646944500 !ruby/object:Gem::Requirement
|
95
|
+
none: false
|
96
|
+
requirements:
|
97
|
+
- - ! '>='
|
98
|
+
- !ruby/object:Gem::Version
|
99
|
+
version: 0.8.7
|
100
|
+
type: :development
|
101
|
+
prerelease: false
|
102
|
+
version_requirements: *70350646944500
|
69
103
|
- !ruby/object:Gem::Dependency
|
70
104
|
name: rspec
|
71
|
-
requirement: &
|
105
|
+
requirement: &70350646943460 !ruby/object:Gem::Requirement
|
72
106
|
none: false
|
73
107
|
requirements:
|
74
108
|
- - ! '>='
|
@@ -76,10 +110,10 @@ dependencies:
|
|
76
110
|
version: 2.5.0
|
77
111
|
type: :development
|
78
112
|
prerelease: false
|
79
|
-
version_requirements: *
|
113
|
+
version_requirements: *70350646943460
|
80
114
|
- !ruby/object:Gem::Dependency
|
81
115
|
name: simplecov
|
82
|
-
requirement: &
|
116
|
+
requirement: &70350646942580 !ruby/object:Gem::Requirement
|
83
117
|
none: false
|
84
118
|
requirements:
|
85
119
|
- - ! '>='
|
@@ -87,10 +121,10 @@ dependencies:
|
|
87
121
|
version: 0.4.0
|
88
122
|
type: :development
|
89
123
|
prerelease: false
|
90
|
-
version_requirements: *
|
124
|
+
version_requirements: *70350646942580
|
91
125
|
- !ruby/object:Gem::Dependency
|
92
126
|
name: yard
|
93
|
-
requirement: &
|
127
|
+
requirement: &70350646941760 !ruby/object:Gem::Requirement
|
94
128
|
none: false
|
95
129
|
requirements:
|
96
130
|
- - ! '>='
|
@@ -98,7 +132,7 @@ dependencies:
|
|
98
132
|
version: 0.6.0
|
99
133
|
type: :development
|
100
134
|
prerelease: false
|
101
|
-
version_requirements: *
|
135
|
+
version_requirements: *70350646941760
|
102
136
|
description: ! 'This library intends to follow the RTSP RFC document (2326)
|
103
137
|
|
104
138
|
to allow for working with RTSP servers. At this point, it''s up to you to parse
|
@@ -107,7 +141,7 @@ description: ! 'This library intends to follow the RTSP RFC document (2326)
|
|
107
141
|
|
108
142
|
For more information see: http://www.ietf.org/rfc/rfc2326.txt'
|
109
143
|
email:
|
110
|
-
- steve.loveless@gmail.com
|
144
|
+
- steve.loveless@gmail.com
|
111
145
|
executables:
|
112
146
|
- rtsp_client
|
113
147
|
extensions: []
|
@@ -117,7 +151,6 @@ extra_rdoc_files:
|
|
117
151
|
- README.rdoc
|
118
152
|
files:
|
119
153
|
- lib/ext/logger.rb
|
120
|
-
- lib/rtsp/capturer.rb
|
121
154
|
- lib/rtsp/client.rb
|
122
155
|
- lib/rtsp/error.rb
|
123
156
|
- lib/rtsp/global.rb
|
@@ -128,17 +161,6 @@ files:
|
|
128
161
|
- lib/rtsp/version.rb
|
129
162
|
- lib/rtsp.rb
|
130
163
|
- bin/rtsp_client
|
131
|
-
- tasks/metrics.rake
|
132
|
-
- tasks/roodi_config.yml
|
133
|
-
- tasks/stats.rake
|
134
|
-
- .gemtest
|
135
|
-
- rtsp.gemspec
|
136
|
-
- Gemfile
|
137
|
-
- ChangeLog.rdoc
|
138
|
-
- LICENSE.rdoc
|
139
|
-
- README.rdoc
|
140
|
-
- Rakefile
|
141
|
-
- spec/rtsp/capturer_spec.rb
|
142
164
|
- spec/rtsp/client_spec.rb
|
143
165
|
- spec/rtsp/helpers_spec.rb
|
144
166
|
- spec/rtsp/message_spec.rb
|
@@ -147,6 +169,16 @@ files:
|
|
147
169
|
- spec/rtsp_spec.rb
|
148
170
|
- spec/spec_helper.rb
|
149
171
|
- spec/support/fake_rtsp_server.rb
|
172
|
+
- tasks/roodi.rake
|
173
|
+
- tasks/roodi_config.yaml
|
174
|
+
- tasks/stats.rake
|
175
|
+
- ChangeLog.rdoc
|
176
|
+
- LICENSE.rdoc
|
177
|
+
- README.rdoc
|
178
|
+
- .gemtest
|
179
|
+
- rtsp.gemspec
|
180
|
+
- Gemfile
|
181
|
+
- Rakefile
|
150
182
|
- features/client_changes_state.feature
|
151
183
|
- features/client_requests.feature
|
152
184
|
- features/control_streams_as_client.feature
|
@@ -173,15 +205,14 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
173
205
|
requirements:
|
174
206
|
- - ! '>='
|
175
207
|
- !ruby/object:Gem::Version
|
176
|
-
version:
|
208
|
+
version: '0'
|
177
209
|
requirements: []
|
178
|
-
rubyforge_project:
|
179
|
-
rubygems_version: 1.8.
|
210
|
+
rubyforge_project:
|
211
|
+
rubygems_version: 1.8.17
|
180
212
|
signing_key:
|
181
213
|
specification_version: 3
|
182
214
|
summary: Library to allow RTSP streaming from RTSP-enabled devices.
|
183
215
|
test_files:
|
184
|
-
- spec/rtsp/capturer_spec.rb
|
185
216
|
- spec/rtsp/client_spec.rb
|
186
217
|
- spec/rtsp/helpers_spec.rb
|
187
218
|
- spec/rtsp/message_spec.rb
|
data/lib/rtsp/capturer.rb
DELETED
@@ -1,223 +0,0 @@
|
|
1
|
-
require 'tempfile'
|
2
|
-
require 'socket'
|
3
|
-
|
4
|
-
require_relative 'error'
|
5
|
-
|
6
|
-
module RTSP
|
7
|
-
|
8
|
-
# Objects of this type can be used with a +RTSP::Client+ object in order to
|
9
|
-
# capture the RTP data transmitted to the client as a result of an RTSP
|
10
|
-
# PLAY call.
|
11
|
-
#
|
12
|
-
# In this version, objects of this type don't do much other than just capture
|
13
|
-
# the data to a file; in later versions, objects of this type will be able
|
14
|
-
# to provide a "sink" and allow for ensuring that the received RTP packets
|
15
|
-
# will be reassembled in the correct order, as they're written to file
|
16
|
-
# (objects of this type don't don't currently allow for checking RTP sequence
|
17
|
-
# numbers on the data that's been received).
|
18
|
-
class Capturer
|
19
|
-
|
20
|
-
# Name of the file the data will be captured to unless #rtp_file is set.
|
21
|
-
DEFAULT_CAPFILE_NAME = "rtsp_capture.rtsp"
|
22
|
-
|
23
|
-
# Maximum number of bytes to receive on the socket.
|
24
|
-
MAX_BYTES_TO_RECEIVE = 3000
|
25
|
-
|
26
|
-
# Maximum times to retry using the next greatest port number.
|
27
|
-
MAX_PORT_NUMBER_RETRIES = 50
|
28
|
-
|
29
|
-
# @param [File] rtp_file The file to capture the RTP data to.
|
30
|
-
# @return [File]
|
31
|
-
attr_accessor :rtp_file
|
32
|
-
|
33
|
-
# @param [Fixnum] rtp_port The port on which to capture the RTP data.
|
34
|
-
# @return [Fixnum]
|
35
|
-
attr_accessor :rtp_port
|
36
|
-
|
37
|
-
# @param [Symbol] transport_protocol +:UDP+ or +:TCP+.
|
38
|
-
# @return [Symbol]
|
39
|
-
attr_accessor :transport_protocol
|
40
|
-
|
41
|
-
# @param [Symbol] broadcast_type +:multicast+ or +:unicast+.
|
42
|
-
# @return [Symbol]
|
43
|
-
attr_accessor :broadcast_type
|
44
|
-
|
45
|
-
# @param [Symbol] transport_protocol The type of socket to use for capturing
|
46
|
-
# the data. +:UDP+ or +:TCP+.
|
47
|
-
# @param [Fixnum] rtp_port The port on which to capture RTP data.
|
48
|
-
# @param [File] capture_file The file object to capture the RTP data to.
|
49
|
-
def initialize(transport_protocol=:UDP, rtp_port=9000, rtp_capture_file=nil)
|
50
|
-
@transport_protocol = transport_protocol
|
51
|
-
@rtp_port = rtp_port
|
52
|
-
@rtp_file = rtp_capture_file || Tempfile.new(DEFAULT_CAPFILE_NAME)
|
53
|
-
@listener = nil
|
54
|
-
@file_builder = nil
|
55
|
-
@queue = Queue.new
|
56
|
-
end
|
57
|
-
|
58
|
-
# Initializes a server of the correct socket type.
|
59
|
-
#
|
60
|
-
# @return [UDPSocket, TCPSocket]
|
61
|
-
# @raise [RTSP::Error] If +@transport_protocol was not set to +:UDP+ or
|
62
|
-
# +:TCP+.
|
63
|
-
def init_server(protocol, port=9000)
|
64
|
-
if protocol == :UDP
|
65
|
-
server = init_udp_server(port)
|
66
|
-
elsif protocol == :TCP
|
67
|
-
server = init_tcp_server(port)
|
68
|
-
else
|
69
|
-
raise RTSP::Error, "Unknown streaming_protocol requested: #{@transport_protocol}"
|
70
|
-
end
|
71
|
-
|
72
|
-
server
|
73
|
-
end
|
74
|
-
|
75
|
-
# Simply calls #start_file_builder and #start_listener.
|
76
|
-
def run
|
77
|
-
log "Starting #{self.class} on port #{@rtp_port}..."
|
78
|
-
|
79
|
-
start_file_builder
|
80
|
-
start_listener
|
81
|
-
end
|
82
|
-
|
83
|
-
# Starts the +@file_builder+ thread that pops data off of the Queue that
|
84
|
-
# #start_listener pushed data on to. It then takes that data and writes it
|
85
|
-
# to +@rtp_file+.
|
86
|
-
#
|
87
|
-
# @return [Thread] The file_builder thread (+@file_builder+)
|
88
|
-
def start_file_builder
|
89
|
-
return @file_builder if @file_builder and @file_builder.alive?
|
90
|
-
|
91
|
-
@file_builder = Thread.start(@rtp_file) do |rtp_file|
|
92
|
-
loop do
|
93
|
-
rtp_file.write @queue.pop until @queue.empty?
|
94
|
-
end
|
95
|
-
end
|
96
|
-
|
97
|
-
@file_builder.abort_on_exception = true
|
98
|
-
end
|
99
|
-
|
100
|
-
# Starts the +@listener+ thread that starts up the server, then takes the
|
101
|
-
# data received from the server and pushes it on to the +@queue+ so
|
102
|
-
# the +@file_builder+ thread can deal with it.
|
103
|
-
#
|
104
|
-
# @return [Thread] The listener thread (+@listener+).
|
105
|
-
def start_listener
|
106
|
-
return @listener if @listener and @listener.alive?
|
107
|
-
|
108
|
-
@listener = Thread.start do
|
109
|
-
server = init_server(@transport_protocol, @rtp_port)
|
110
|
-
|
111
|
-
loop do
|
112
|
-
data = server.recvfrom(MAX_BYTES_TO_RECEIVE).first
|
113
|
-
log "received data with size: #{data.size}"
|
114
|
-
@queue << data
|
115
|
-
end
|
116
|
-
end
|
117
|
-
|
118
|
-
@listener.abort_on_exception = true
|
119
|
-
end
|
120
|
-
|
121
|
-
# @return [Boolean] true if the +@listener+ thread is running; false if not.
|
122
|
-
def listening?
|
123
|
-
if @listener then @listener.alive? else false end
|
124
|
-
end
|
125
|
-
|
126
|
-
# @return [Boolean] true if the +@file_builder+ thread is running; false if
|
127
|
-
# not.
|
128
|
-
def file_building?
|
129
|
-
if @file_builder then @file_builder.alive? else false end
|
130
|
-
end
|
131
|
-
|
132
|
-
# Returns if the #run loop is in action.
|
133
|
-
#
|
134
|
-
# @return [Boolean] true if the run loop is running.
|
135
|
-
def running?
|
136
|
-
listening? || file_building?
|
137
|
-
end
|
138
|
-
|
139
|
-
# Breaks out of the run loop.
|
140
|
-
def stop
|
141
|
-
log "Stopping #{self.class} on port #{@rtp_port}..."
|
142
|
-
stop_listener
|
143
|
-
log "listening? #{listening?}"
|
144
|
-
stop_file_builder
|
145
|
-
log "file building? #{file_building?}"
|
146
|
-
log "running? #{running?}"
|
147
|
-
@queue = Queue.new
|
148
|
-
end
|
149
|
-
|
150
|
-
# Kills the +@listener+ thread and sets the variable to nil.
|
151
|
-
def stop_listener
|
152
|
-
@listener.kill if @listener
|
153
|
-
@listener = nil
|
154
|
-
end
|
155
|
-
|
156
|
-
# Kills the +@file_builder+ thread and sets the variable to nil.
|
157
|
-
def stop_file_builder
|
158
|
-
@file_builder.kill if @file_builder
|
159
|
-
@file_builder = nil
|
160
|
-
end
|
161
|
-
|
162
|
-
# Sets up to receive data on a UDP socket, using +@rtp_port+.
|
163
|
-
#
|
164
|
-
# @param [Fixnum] port Port number to listen for RTP data on.
|
165
|
-
# @return [UDPSocket]
|
166
|
-
def init_udp_server(port)
|
167
|
-
port_retries = 0
|
168
|
-
|
169
|
-
begin
|
170
|
-
server = UDPSocket.open
|
171
|
-
server.bind('0.0.0.0', port)
|
172
|
-
rescue Errno::EADDRINUSE
|
173
|
-
log "RTP port #{port} in use, trying #{port + 1}..."
|
174
|
-
port += 1
|
175
|
-
port_retries += 1
|
176
|
-
retry until port_retries == MAX_PORT_NUMBER_RETRIES + 1
|
177
|
-
port = 9000
|
178
|
-
raise
|
179
|
-
end
|
180
|
-
|
181
|
-
@rtp_port = port
|
182
|
-
log "UDP server setup to receive on port #{@rtp_port}"
|
183
|
-
|
184
|
-
server
|
185
|
-
end
|
186
|
-
|
187
|
-
# Sets up to receive data on a TCP socket, using +@rtp_port+.
|
188
|
-
#
|
189
|
-
# @param [Fixnum] port Port number to listen for RTP data on.
|
190
|
-
# @return [TCPServer]
|
191
|
-
def init_tcp_server(port)
|
192
|
-
port_retries = 0
|
193
|
-
|
194
|
-
begin
|
195
|
-
server = TCPServer.new(port)
|
196
|
-
rescue Errno::EADDRINUSE
|
197
|
-
log "RTP port #{port} in use, trying #{port + 1}..."
|
198
|
-
port += 1
|
199
|
-
port_retries += 1
|
200
|
-
retry until port_retries == MAX_PORT_NUMBER_RETRIES + 1
|
201
|
-
port = 9000
|
202
|
-
raise
|
203
|
-
end
|
204
|
-
|
205
|
-
@rtp_port = port
|
206
|
-
log "TCP server setup to receive on port #{@rtp_port}"
|
207
|
-
|
208
|
-
server
|
209
|
-
end
|
210
|
-
|
211
|
-
# PRIVATES!
|
212
|
-
private
|
213
|
-
|
214
|
-
# Quick wrapper for when not using RTSP::Client (i.e. during tests).
|
215
|
-
#
|
216
|
-
# @param [String] message The String to log.
|
217
|
-
def log(message)
|
218
|
-
if defined? RTSP::Client
|
219
|
-
RTSP::Client.log "<#{self.class}> #{message}"
|
220
|
-
end
|
221
|
-
end
|
222
|
-
end
|
223
|
-
end
|
data/spec/rtsp/capturer_spec.rb
DELETED
@@ -1,258 +0,0 @@
|
|
1
|
-
require_relative '../spec_helper'
|
2
|
-
require 'rtsp/capturer'
|
3
|
-
|
4
|
-
Thread.abort_on_exception = true
|
5
|
-
|
6
|
-
def use_udp_ports(range)
|
7
|
-
sockets = []
|
8
|
-
|
9
|
-
range.each do |port|
|
10
|
-
begin
|
11
|
-
socket = UDPSocket.open
|
12
|
-
socket.bind('0.0.0.0', port)
|
13
|
-
sockets << socket
|
14
|
-
rescue Errno::EADDRINUSE
|
15
|
-
# That's ok
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
sockets
|
20
|
-
end
|
21
|
-
|
22
|
-
describe RTSP::Capturer do
|
23
|
-
before do
|
24
|
-
if defined? RTSP::Client
|
25
|
-
RTSP::Client.log = false
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
describe "#initialize" do
|
30
|
-
context "with default parameters" do
|
31
|
-
it "uses UDP" do
|
32
|
-
subject.instance_variable_get(:@transport_protocol).should == :UDP
|
33
|
-
end
|
34
|
-
|
35
|
-
it "uses port 9000" do
|
36
|
-
subject.instance_variable_get(:@rtp_port).should == 9000
|
37
|
-
end
|
38
|
-
|
39
|
-
it "creates a new Tempfile" do
|
40
|
-
subject.instance_variable_get(:@rtp_file).should be_a Tempfile
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
context "non-default parameters" do
|
45
|
-
it "can use TCP" do
|
46
|
-
capturer = RTSP::Capturer.new(:TCP)
|
47
|
-
capturer.instance_variable_get(:@transport_protocol).should == :TCP
|
48
|
-
end
|
49
|
-
|
50
|
-
it "can take another port" do
|
51
|
-
capturer = RTSP::Capturer.new(:UDP, 12345)
|
52
|
-
capturer.instance_variable_get(:@rtp_port).should == 12345
|
53
|
-
end
|
54
|
-
|
55
|
-
it "can take an IO object" do
|
56
|
-
fd = IO.sysopen("/dev/null", "w")
|
57
|
-
io = IO.new(fd, 'w')
|
58
|
-
capturer = RTSP::Capturer.new(:UDP, 12345, io)
|
59
|
-
capturer.instance_variable_get(:@rtp_file).should be_a IO
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
it "isn't running" do
|
64
|
-
RTSP::Capturer.new.should_not be_running
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
describe "#init_server" do
|
69
|
-
context "UDP" do
|
70
|
-
it "calls #init_udp_server with port 9000" do
|
71
|
-
subject.should_receive(:init_udp_server).with(9000)
|
72
|
-
subject.init_server(:UDP)
|
73
|
-
end
|
74
|
-
|
75
|
-
it "returns a UDPSocket" do
|
76
|
-
subject.init_server(:UDP).should be_a(UDPSocket)
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
|
-
context "TCP" do
|
81
|
-
it "calls #init_tcp_server with port 9000" do
|
82
|
-
subject.should_receive(:init_tcp_server).with(9000)
|
83
|
-
subject.init_server(:TCP)
|
84
|
-
end
|
85
|
-
|
86
|
-
it "returns a TCPServer" do
|
87
|
-
subject.init_server(:TCP).should be_a(TCPServer)
|
88
|
-
end
|
89
|
-
end
|
90
|
-
|
91
|
-
it "raises an RTSP::Error when some other protocol is given" do
|
92
|
-
expect { subject.init_server(:BOBO) }.to raise_error RTSP::Error
|
93
|
-
end
|
94
|
-
end
|
95
|
-
|
96
|
-
describe "#init_udp_server" do
|
97
|
-
after :each do
|
98
|
-
unless @sockets.nil?
|
99
|
-
@sockets.each { |s| s.close }
|
100
|
-
end
|
101
|
-
end
|
102
|
-
|
103
|
-
it "returns a UDPSocket" do
|
104
|
-
server = subject.init_udp_server(subject.rtp_port)
|
105
|
-
server.should be_a UDPSocket
|
106
|
-
end
|
107
|
-
|
108
|
-
it "retries MAX_PORT_NUMBER_RETRIES to get a port" do
|
109
|
-
@sockets = use_udp_ports 9000...(9000 + RTSP::Capturer::MAX_PORT_NUMBER_RETRIES)
|
110
|
-
subject.init_udp_server(subject.rtp_port)
|
111
|
-
|
112
|
-
subject.rtp_port.should == 9000 + RTSP::Capturer::MAX_PORT_NUMBER_RETRIES
|
113
|
-
end
|
114
|
-
|
115
|
-
context "when no available ports, it retries MAX_PORT_NUMBER_RETRIES times, then" do
|
116
|
-
before do
|
117
|
-
@sockets = use_udp_ports 9000..(9000 + RTSP::Capturer::MAX_PORT_NUMBER_RETRIES)
|
118
|
-
end
|
119
|
-
|
120
|
-
it "retries MAX_PORT_NUMBER_RETRIES times then raises" do
|
121
|
-
expect { subject.init_udp_server(subject.rtp_port) }.to raise_error Errno::EADDRINUSE
|
122
|
-
end
|
123
|
-
|
124
|
-
it "sets @rtp_port back to 9000 after trying all" do
|
125
|
-
expect { subject.init_udp_server(subject.rtp_port) }.to raise_error Errno::EADDRINUSE
|
126
|
-
subject.rtp_port.should == 9000
|
127
|
-
end
|
128
|
-
end
|
129
|
-
end
|
130
|
-
|
131
|
-
describe "#init_tcp_server" do
|
132
|
-
it "returns a TCPSocket" do
|
133
|
-
subject.init_tcp_server(3456).should be_a TCPSocket
|
134
|
-
end
|
135
|
-
|
136
|
-
it "uses port a port between 9000 and 9000 + MAX_PORT_NUMBER_RETRIES" do
|
137
|
-
subject.init_tcp_server(9000)
|
138
|
-
subject.rtp_port.should >= 9000
|
139
|
-
subject.rtp_port.should <= 9000 + RTSP::Capturer::MAX_PORT_NUMBER_RETRIES
|
140
|
-
end
|
141
|
-
end
|
142
|
-
|
143
|
-
describe "#run" do
|
144
|
-
after(:each) { subject.stop }
|
145
|
-
|
146
|
-
it "calls #start_file_builder and #start_listener" do
|
147
|
-
subject.should_receive(:start_listener)
|
148
|
-
subject.should_receive(:start_file_builder)
|
149
|
-
subject.run
|
150
|
-
end
|
151
|
-
end
|
152
|
-
|
153
|
-
describe "#running?" do
|
154
|
-
after(:each) { subject.stop }
|
155
|
-
|
156
|
-
it "returns false before issuing #run" do
|
157
|
-
subject.running?.should be_false
|
158
|
-
end
|
159
|
-
|
160
|
-
it "returns true after running" do
|
161
|
-
subject.run
|
162
|
-
subject.running?.should be_true
|
163
|
-
end
|
164
|
-
|
165
|
-
it "returns false after running then stopping" do
|
166
|
-
subject.run
|
167
|
-
subject.running?.should be_true
|
168
|
-
subject.stop
|
169
|
-
subject.running?.should be_false
|
170
|
-
end
|
171
|
-
end
|
172
|
-
|
173
|
-
describe "#stop" do
|
174
|
-
it "calls #stop_listener" do
|
175
|
-
subject.should_receive(:stop_listener)
|
176
|
-
subject.stop
|
177
|
-
end
|
178
|
-
|
179
|
-
it "calls #stop_file_builder" do
|
180
|
-
subject.should_receive(:stop_file_builder)
|
181
|
-
subject.stop
|
182
|
-
end
|
183
|
-
|
184
|
-
it "sets @queue back to a new Queue" do
|
185
|
-
queue = subject.instance_variable_get(:@queue)
|
186
|
-
subject.stop
|
187
|
-
subject.instance_variable_get(:@queue).should_not equal queue
|
188
|
-
subject.instance_variable_get(:@queue).should_not be_nil
|
189
|
-
end
|
190
|
-
end
|
191
|
-
|
192
|
-
[
|
193
|
-
{
|
194
|
-
start_method: "start_file_builder",
|
195
|
-
stop_method: "stop_file_builder",
|
196
|
-
ivar: "@file_builder"
|
197
|
-
},
|
198
|
-
{
|
199
|
-
start_method: "start_listener",
|
200
|
-
stop_method: "stop_listener",
|
201
|
-
ivar: "@listener"
|
202
|
-
}
|
203
|
-
].each do |method_set|
|
204
|
-
describe "##{method_set[:start_method]}" do
|
205
|
-
before(:each) do
|
206
|
-
rtp_file = double "rtp_file"
|
207
|
-
rtp_file.stub(:write)
|
208
|
-
subject.rtp_file = rtp_file
|
209
|
-
|
210
|
-
server = double "A Server"
|
211
|
-
server.stub_chain(:recvfrom, :first).and_return("not nil")
|
212
|
-
subject.stub(:init_server).and_return(server)
|
213
|
-
end
|
214
|
-
|
215
|
-
after(:each) { subject.send(method_set[:stop_method].to_sym) }
|
216
|
-
|
217
|
-
it "starts the #{method_set[:ivar]} thread" do
|
218
|
-
subject.send(method_set[:start_method])
|
219
|
-
subject.instance_variable_get(method_set[:ivar].to_sym).should be_a Thread
|
220
|
-
end
|
221
|
-
|
222
|
-
it "returns the same #{method_set[:ivar]} if already started" do
|
223
|
-
subject.send(method_set[:start_method])
|
224
|
-
original_ivar = subject.instance_variable_get(method_set[:ivar].to_sym)
|
225
|
-
new_ivar = subject.send method_set[:start_method].to_sym
|
226
|
-
original_ivar.should equal new_ivar
|
227
|
-
end
|
228
|
-
|
229
|
-
if method_set[:start_method] == "start_listener"
|
230
|
-
it "pushes data on to the @queue" do
|
231
|
-
subject.start_listener
|
232
|
-
subject.instance_variable_get(:@queue).pop.should == "not nil"
|
233
|
-
end
|
234
|
-
end
|
235
|
-
end
|
236
|
-
|
237
|
-
describe "##{method_set[:stop_method]}" do
|
238
|
-
context "#{method_set[:ivar]} thread is running" do
|
239
|
-
before { subject.send(method_set[:start_method]) }
|
240
|
-
|
241
|
-
it "kills the thread" do
|
242
|
-
original_ivar = subject.instance_variable_get(method_set[:ivar].to_sym)
|
243
|
-
original_ivar.should_receive(:kill)
|
244
|
-
subject.send(method_set[:stop_method])
|
245
|
-
end
|
246
|
-
end
|
247
|
-
|
248
|
-
context "#{method_set[:ivar]} thread isn't running" do
|
249
|
-
it "doesn't try to kill the thread" do
|
250
|
-
allow_message_expectations_on_nil
|
251
|
-
original_ivar = subject.instance_variable_get(method_set[:ivar].to_sym)
|
252
|
-
original_ivar.should_not_receive(:kill)
|
253
|
-
subject.send(method_set[:stop_method])
|
254
|
-
end
|
255
|
-
end
|
256
|
-
end
|
257
|
-
end
|
258
|
-
end
|
data/tasks/metrics.rake
DELETED
@@ -1,27 +0,0 @@
|
|
1
|
-
require 'metric_fu'
|
2
|
-
|
3
|
-
MetricFu::Configuration.run do |config|
|
4
|
-
#define which metrics you want to use
|
5
|
-
#config.metrics = [:churn, :flog, :flay, :reek, :roodi, :rcov, :stats]
|
6
|
-
config.metrics = [:churn, :flay, :reek, :roodi, :rcov, :stats]
|
7
|
-
#config.graphs = [:flog, :flay, :reek, :roodi, :rcov, :stats]
|
8
|
-
config.graphs = [:flay, :reek, :roodi, :rcov, :stats]
|
9
|
-
config.churn = { :start_date => "1 year ago", :minimum_churn_count => 10 }
|
10
|
-
config.flay = { :dirs_to_flay => ['lib'],
|
11
|
-
:minimum_score => 10,
|
12
|
-
:filetypes => ['rb', 'erb'] }
|
13
|
-
config.flog = { :dirs_to_flog => ['lib'] }
|
14
|
-
config.rcov = { :environment => 'test',
|
15
|
-
:test_files => ["spec/**/*_spec.rb"],
|
16
|
-
:rcov_opts => ["--sort coverage",
|
17
|
-
"--no-html",
|
18
|
-
"--text-coverage",
|
19
|
-
"--spec-only",
|
20
|
-
"--no-color",
|
21
|
-
"--profile",
|
22
|
-
"--exclude /gems/,/Library/"]
|
23
|
-
}
|
24
|
-
config.reek = { :dirs_to_reek => ['lib'] }
|
25
|
-
config.roodi = { :dirs_to_roodi => ['lib'], :roodi_config => "tasks/roodi_config.yml" }
|
26
|
-
config.graph_engine = :bluff
|
27
|
-
end
|