screencaster-gtk 0.0.5.alpha1 → 0.0.6.alpha1
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/screencaster-gtk.rb +9 -11
- data/lib/screencaster-gtk/capture.rb +61 -42
- data/lib/screencaster-gtk/progresstracker.rb +2 -1
- data/lib/screencaster-gtk/savefile.rb +18 -2
- data/test/capture.rb +21 -0
- data/test/screencaster-gtk.rb +6 -0
- data/test/test_capture.rb +180 -0
- data/test/test_screencaster_gtk.rb +65 -0
- data/test/test_utils.rb +17 -0
- metadata +13 -3
data/lib/screencaster-gtk.rb
CHANGED
@@ -174,17 +174,15 @@ class ScreencasterGtk
|
|
174
174
|
#### Done Status Icon
|
175
175
|
|
176
176
|
def quit
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
Gtk.main_quit
|
187
|
-
@@logger.debug "After main_quit."
|
177
|
+
if 0 < @capture_window.raw_files.size && SaveFile.are_you_sure?(@window)
|
178
|
+
@@logger.debug "Quitting"
|
179
|
+
# We don't want to destroy here because the object continues to exist
|
180
|
+
# Just hide everything
|
181
|
+
self.hide_all_including_status
|
182
|
+
# self.status_icon.hide doesn't work/exist
|
183
|
+
Gtk.main_quit
|
184
|
+
@@logger.debug "After main_quit."
|
185
|
+
end
|
188
186
|
end
|
189
187
|
|
190
188
|
public
|
@@ -11,7 +11,7 @@ class Capture
|
|
11
11
|
attr_writer :left, :top, :right, :bottom
|
12
12
|
attr_reader :state
|
13
13
|
attr_accessor :pid
|
14
|
-
attr_accessor :
|
14
|
+
attr_accessor :raw_files
|
15
15
|
|
16
16
|
attr_accessor :capture_fps
|
17
17
|
attr_accessor :encode_fps
|
@@ -24,13 +24,14 @@ class Capture
|
|
24
24
|
|
25
25
|
|
26
26
|
def initialize
|
27
|
-
@tmp_files = []
|
28
27
|
@exit_chain = Signal.trap("EXIT") {
|
29
28
|
self.cleanup
|
30
29
|
$logger.debug "In capture about to chain to trap @exit_chain: #{@exit_chain}"
|
31
30
|
@exit_chain.call unless @exit_chain.nil?
|
32
31
|
}
|
33
32
|
#$logger.debug "@exit_chain: #{@exit_chain.to_s}"
|
33
|
+
|
34
|
+
self.reset_without_cleanup
|
34
35
|
|
35
36
|
@state = :stopped
|
36
37
|
@coprocess = nil
|
@@ -57,11 +58,11 @@ class Capture
|
|
57
58
|
end
|
58
59
|
|
59
60
|
def current_tmp_file
|
60
|
-
@
|
61
|
+
@raw_files.last
|
61
62
|
end
|
62
63
|
|
63
64
|
def new_tmp_file
|
64
|
-
@
|
65
|
+
@raw_files << Capture.tmp_file_name(@raw_files.size)
|
65
66
|
self.current_tmp_file
|
66
67
|
end
|
67
68
|
|
@@ -72,6 +73,10 @@ class Capture
|
|
72
73
|
def self.format_input_files_for_mkvmerge(files)
|
73
74
|
files.drop(1).inject("\"#{files.first}\"") {|a, b| "#{a} + \"#{b}\"" }
|
74
75
|
end
|
76
|
+
|
77
|
+
def video_segments_size
|
78
|
+
@raw_files.size
|
79
|
+
end
|
75
80
|
|
76
81
|
def width
|
77
82
|
@right - @left
|
@@ -121,32 +126,16 @@ class Capture
|
|
121
126
|
end
|
122
127
|
|
123
128
|
def record
|
124
|
-
if @state != :paused
|
125
|
-
@tmp_files = []
|
126
|
-
self.total_amount = 0.0
|
127
|
-
end
|
128
|
-
|
129
129
|
output_file = self.new_tmp_file
|
130
130
|
|
131
131
|
@state = :recording
|
132
|
-
audio_options="-f alsa -ac 1 -ab #{@audio_sample_frequency} -i #{@audio_input} -acodec #{@acodec}"
|
133
132
|
|
134
133
|
# And i should probably popen here, save the pid, then fork and start
|
135
134
|
# reading the input, updating the number of frames saved, or the time
|
136
135
|
# recorded.
|
137
136
|
$logger.debug "Capturing...\n"
|
138
137
|
|
139
|
-
cmd_line =
|
140
|
-
#{audio_options} \
|
141
|
-
-f x11grab \
|
142
|
-
-show_region 1 \
|
143
|
-
-r #{@capture_fps} \
|
144
|
-
-s #{@width}x#{@height} \
|
145
|
-
-i :0.0+#{@left},#{@top} \
|
146
|
-
-qscale #{@qscale} \
|
147
|
-
-vcodec #{@capture_vcodec} \
|
148
|
-
-y \
|
149
|
-
#{output_file}"
|
138
|
+
cmd_line = record_command_line(output_file)
|
150
139
|
|
151
140
|
$logger.debug cmd_line
|
152
141
|
|
@@ -199,29 +188,19 @@ class Capture
|
|
199
188
|
state = :encoding
|
200
189
|
output_file =~ /.mp4$/ || output_file += ".mp4"
|
201
190
|
|
202
|
-
$logger.debug "Encoding #{Capture.format_input_files_for_mkvmerge(@
|
191
|
+
$logger.debug "Encoding #{Capture.format_input_files_for_mkvmerge(@raw_files)}...\n"
|
203
192
|
$logger.debug("Total duration #{self.total_amount.to_s}")
|
204
193
|
|
205
|
-
merge(Capture.tmp_file_name, @
|
194
|
+
merge(Capture.tmp_file_name, @raw_files, feedback)
|
206
195
|
final_encode(output_file, Capture.tmp_file_name, feedback)
|
207
196
|
end
|
208
197
|
|
209
|
-
# This is ugly.
|
210
|
-
# When you open co-processes, they do get stuck together.
|
211
|
-
# It seems the if I don't read what's coming out of the co-process, it waits.
|
212
|
-
# But if I read it, then it goes right to the end until it returns.
|
213
|
-
|
214
198
|
def merge(output_file, input_files, feedback = proc {} )
|
215
199
|
$logger.debug("Merging #{input_files.size.to_s} files: #{Capture.format_input_files_for_mkvmerge(input_files)}")
|
216
200
|
$logger.debug("Feedback #{feedback}")
|
217
201
|
|
218
|
-
|
219
|
-
|
220
|
-
cmd_line = "cp -v #{input_files[0]} #{output_file}"
|
221
|
-
#cmd_line = "sleep 5"
|
222
|
-
else
|
223
|
-
cmd_line = "mkvmerge -v -o #{output_file} #{Capture.format_input_files_for_mkvmerge(input_files)}"
|
224
|
-
end
|
202
|
+
cmd_line = merge_command_line(output_file, input_files)
|
203
|
+
|
225
204
|
$logger.debug "merge: command line: #{cmd_line}"
|
226
205
|
i, oe, @coprocess = Open3.popen2e(cmd_line)
|
227
206
|
$logger.debug "merge: Thread from popen2e: #{@coprocess}"
|
@@ -248,11 +227,7 @@ class Capture
|
|
248
227
|
# updating progress based on what I read, while the main body
|
249
228
|
# returns and carries on.
|
250
229
|
|
251
|
-
cmd_line =
|
252
|
-
-i #{input_file} \
|
253
|
-
-vcodec #{@encode_vcodec} \
|
254
|
-
-y \
|
255
|
-
'#{output_file}'"
|
230
|
+
cmd_line = encode_command_line(output_file, input_file)
|
256
231
|
|
257
232
|
$logger.debug cmd_line
|
258
233
|
|
@@ -271,7 +246,8 @@ class Capture
|
|
271
246
|
$logger.debug "reached end of file"
|
272
247
|
@state = :stopped
|
273
248
|
self.fraction_complete = 1
|
274
|
-
feedback.call self.fraction_complete,
|
249
|
+
feedback.call self.fraction_complete, "Done"
|
250
|
+
reset
|
275
251
|
@coprocess.value # A little bit of a head game here. Either return this, or maybe have to do t.value.value in caller
|
276
252
|
end
|
277
253
|
|
@@ -282,10 +258,53 @@ class Capture
|
|
282
258
|
$logger.error("No encoding to stop.")
|
283
259
|
end
|
284
260
|
end
|
261
|
+
|
262
|
+
def reset
|
263
|
+
cleanup
|
264
|
+
reset_without_cleanup
|
265
|
+
end
|
266
|
+
|
267
|
+
def reset_without_cleanup
|
268
|
+
@raw_files = []
|
269
|
+
self.total_amount = 0.0
|
270
|
+
end
|
285
271
|
|
286
272
|
def cleanup
|
287
|
-
@
|
273
|
+
@raw_files.each { |f| File.delete(f) if File.exists?(f) }
|
288
274
|
File.delete(Capture.tmp_file_name) if File.exists?(Capture.tmp_file_name)
|
289
275
|
end
|
276
|
+
|
277
|
+
def record_command_line(output_file)
|
278
|
+
audio_options="-f alsa -ac 1 -ab #{@audio_sample_frequency} -i #{@audio_input} -acodec #{@acodec}"
|
279
|
+
"avconv \
|
280
|
+
#{audio_options} \
|
281
|
+
-f x11grab \
|
282
|
+
-show_region 1 \
|
283
|
+
-r #{@capture_fps} \
|
284
|
+
-s #{@width}x#{@height} \
|
285
|
+
-i :0.0+#{@left},#{@top} \
|
286
|
+
-qscale #{@qscale} \
|
287
|
+
-vcodec #{@capture_vcodec} \
|
288
|
+
-y \
|
289
|
+
#{output_file}"
|
290
|
+
end
|
291
|
+
|
292
|
+
def merge_command_line(output_file, input_files)
|
293
|
+
# TODO: cp doesn't give feedback like mkvmerge does...
|
294
|
+
if input_files.size == 1
|
295
|
+
"cp -v #{input_files[0]} #{output_file}"
|
296
|
+
#cmd_line = "sleep 5"
|
297
|
+
else
|
298
|
+
"mkvmerge -v -o #{output_file} #{Capture.format_input_files_for_mkvmerge(input_files)}"
|
299
|
+
end
|
300
|
+
end
|
301
|
+
|
302
|
+
def encode_command_line(output_file, input_file)
|
303
|
+
"avconv \
|
304
|
+
-i '#{input_file}' \
|
305
|
+
-vcodec #{@encode_vcodec} \
|
306
|
+
-y \
|
307
|
+
'#{output_file}'"
|
308
|
+
end
|
290
309
|
end
|
291
310
|
|
@@ -10,6 +10,7 @@ module ProgressTracker
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def fraction_complete
|
13
|
+
raise ZeroDivisionError if self.total_amount == 0
|
13
14
|
[ self.current_amount.to_f / self.total_amount.to_f, 1.0 ].min
|
14
15
|
end
|
15
16
|
|
@@ -27,7 +28,7 @@ module ProgressTracker
|
|
27
28
|
end
|
28
29
|
|
29
30
|
def total_amount
|
30
|
-
@total_amount ||
|
31
|
+
@total_amount || 0.0
|
31
32
|
end
|
32
33
|
|
33
34
|
def time_remaining
|
@@ -23,7 +23,7 @@ Create the file chooser dialogue with a default file name.
|
|
23
23
|
end
|
24
24
|
|
25
25
|
=begin rdoc
|
26
|
-
Do the workflow around saving a file, warning the user before
|
26
|
+
Do the workflow around saving a file, warning the user before allowing
|
27
27
|
them to abandon their capture.
|
28
28
|
=end
|
29
29
|
def self.get_file_to_save
|
@@ -38,11 +38,13 @@ them to abandon their capture.
|
|
38
38
|
self.confirm_cancel(@dialog)
|
39
39
|
@dialog.hide
|
40
40
|
else
|
41
|
-
|
41
|
+
$logger.error("Can't happen #{__FILE__} line: #{__LINE__}")
|
42
42
|
@dialog.hide
|
43
43
|
end
|
44
44
|
end
|
45
45
|
|
46
|
+
# TODO: I think it's ugly that I have two different dialogues here.
|
47
|
+
|
46
48
|
=begin rdoc
|
47
49
|
Confirm cancellation when the user has captured something but not
|
48
50
|
saved it.
|
@@ -75,5 +77,19 @@ saved it.
|
|
75
77
|
else
|
76
78
|
end
|
77
79
|
end
|
80
|
+
|
81
|
+
def self.are_you_sure?(parent, verb = "quit")
|
82
|
+
d = Gtk::MessageDialog.new(parent,
|
83
|
+
Gtk::Dialog::DESTROY_WITH_PARENT,
|
84
|
+
Gtk::MessageDialog::QUESTION,
|
85
|
+
Gtk::MessageDialog::BUTTONS_YES_NO,
|
86
|
+
"You have unsaved work")
|
87
|
+
|
88
|
+
d.secondary_text = "If you #{verb} now, you will lose some video that you have captured. Are you sure you want to #{verb}?"
|
89
|
+
|
90
|
+
response = d.run
|
91
|
+
d.destroy
|
92
|
+
response == Gtk::Dialog::RESPONSE_YES
|
93
|
+
end
|
78
94
|
end
|
79
95
|
|
data/test/capture.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
# Redefine some methods in Capture for testing purposes.
|
2
|
+
|
3
|
+
class Capture
|
4
|
+
def get_window_to_capture
|
5
|
+
@left = 100
|
6
|
+
@top = 100
|
7
|
+
@width = 100
|
8
|
+
@height = 100
|
9
|
+
@height += @height % 2
|
10
|
+
@width += @width % 2
|
11
|
+
|
12
|
+
$logger.debug "Capturing #{@left},#{@top} to #{@left+@width},#{@top+@height}. Dimensions #{@width},#{@height}.\n"
|
13
|
+
end
|
14
|
+
|
15
|
+
def define_mock_capture_success
|
16
|
+
def self.record_command_line(output_file)
|
17
|
+
"touch '#{output_file}'"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
@@ -0,0 +1,180 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'screencaster-gtk/capture'
|
3
|
+
require 'logger'
|
4
|
+
require 'fileutils'
|
5
|
+
require File.join(File.expand_path(File.dirname(__FILE__)), 'test_utils')
|
6
|
+
require File.join(File.expand_path(File.dirname(__FILE__)), 'capture')
|
7
|
+
|
8
|
+
# TODO: How to test the actual capture?
|
9
|
+
# There's non-trivial stuff in there, like getting the overall duration.
|
10
|
+
|
11
|
+
class TestCapture < Test::Unit::TestCase
|
12
|
+
include TestUtils
|
13
|
+
|
14
|
+
def test_merge_two_files
|
15
|
+
output = file_name("c-from-two.mkv")
|
16
|
+
File.delete(output) if File.exists?(output)
|
17
|
+
input = [ file_name("a.mkv"), file_name("b.mkv") ]
|
18
|
+
|
19
|
+
c = Capture.new
|
20
|
+
$logger.debug "test_merge_two_files: before merge"
|
21
|
+
assert_equal 0, c.merge(output, input)
|
22
|
+
assert File.exists?(output), "Output file #{output} not found."
|
23
|
+
assert_equal 1, Thread.list.size
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_merge_one_file
|
27
|
+
output = file_name("c-from-one.mkv")
|
28
|
+
File.delete(output) if File.exists?(output)
|
29
|
+
input = [ file_name("a.mkv") ]
|
30
|
+
|
31
|
+
c = Capture.new
|
32
|
+
assert_equal 0, c.merge(output, input)
|
33
|
+
assert File.exists?(output), "Output file #{output} not found."
|
34
|
+
assert File.exists?(input[0]), "Input file #{input[0]} gone."
|
35
|
+
# Process should be gone by now
|
36
|
+
Thread.list.each { |t| puts t }
|
37
|
+
assert_equal 1, Thread.list.size
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_block_merge
|
41
|
+
output = file_name("c-from-one.mkv")
|
42
|
+
File.delete(output) if File.exists?(output)
|
43
|
+
input = [ file_name("a.mkv") ]
|
44
|
+
|
45
|
+
amount_done = 0.0
|
46
|
+
c = Capture.new
|
47
|
+
r = c.merge(output, input) do | fraction, message |
|
48
|
+
puts "+++++++++++++++++ #{fraction}, #{message}"
|
49
|
+
amount_done = fraction
|
50
|
+
end
|
51
|
+
assert_equal 0, r
|
52
|
+
assert_equal 1.0, amount_done
|
53
|
+
assert_equal 1, Thread.list.size
|
54
|
+
end
|
55
|
+
|
56
|
+
def test_final_encode
|
57
|
+
o = "test-final-encode.mp4"
|
58
|
+
i = "c-from-two.mkv"
|
59
|
+
baseline = file_name(File.join("baseline", o))
|
60
|
+
output = file_name(o)
|
61
|
+
File.delete(output) if File.exists?(output)
|
62
|
+
input = file_name(i)
|
63
|
+
FileUtils.cp(file_name(File.join("baseline", i)), input)
|
64
|
+
|
65
|
+
c = Capture.new
|
66
|
+
c.total_amount = 1.0
|
67
|
+
assert_equal 0, c.final_encode(output, input)
|
68
|
+
assert File.exists?(output), "Output file #{output} not found."
|
69
|
+
`diff #{baseline} #{output}`
|
70
|
+
assert_equal 0, $?.exitstatus, "Output file different from baseline"
|
71
|
+
assert_equal 1, Thread.list.size
|
72
|
+
end
|
73
|
+
|
74
|
+
def test_record_failure
|
75
|
+
# This will fail since the capture area isn't set up
|
76
|
+
c = Capture.new
|
77
|
+
assert_not_equal 0, c.record
|
78
|
+
assert_equal 1, Thread.list.size
|
79
|
+
end
|
80
|
+
|
81
|
+
def test_merge_failure
|
82
|
+
output = file_name("c-from-one.mkv")
|
83
|
+
File.delete(output) if File.exists?(output)
|
84
|
+
input = [ file_name("file-does-not-exist.mkv") ]
|
85
|
+
|
86
|
+
c = Capture.new
|
87
|
+
assert_not_equal 0, c.merge(output, input)
|
88
|
+
assert_equal 1, Thread.list.size
|
89
|
+
end
|
90
|
+
|
91
|
+
def test_final_encode_failure
|
92
|
+
o = "test-final-encode.mp4"
|
93
|
+
i = "file-does-not-exist.mkv"
|
94
|
+
baseline = file_name(File.join("baseline", o))
|
95
|
+
output = file_name(o)
|
96
|
+
File.delete(output) if File.exists?(output)
|
97
|
+
input = file_name(i)
|
98
|
+
|
99
|
+
c = Capture.new
|
100
|
+
c.total_amount = 1.0
|
101
|
+
assert_not_equal 0, c.final_encode(output, input)
|
102
|
+
assert_equal 1, Thread.list.size
|
103
|
+
end
|
104
|
+
|
105
|
+
def test_default_total
|
106
|
+
c = Capture.new
|
107
|
+
assert_equal 0.0, c.total_amount
|
108
|
+
end
|
109
|
+
|
110
|
+
def test_total
|
111
|
+
c = Capture.new
|
112
|
+
c.total_amount = 2.0
|
113
|
+
assert_equal 2.0, c.total_amount
|
114
|
+
end
|
115
|
+
|
116
|
+
def test_current
|
117
|
+
c = Capture.new
|
118
|
+
c.total_amount = 1.0
|
119
|
+
c.current_amount = 0.25
|
120
|
+
assert_equal 0.25, c.current_amount
|
121
|
+
assert_equal 0.25, c.fraction_complete
|
122
|
+
assert_equal 25, c.percent_complete
|
123
|
+
|
124
|
+
c.total_amount = 0.5
|
125
|
+
assert_equal 0.5, c.fraction_complete
|
126
|
+
end
|
127
|
+
|
128
|
+
def test_time_remaining
|
129
|
+
c = Capture.new
|
130
|
+
c.total_amount = 1.0
|
131
|
+
c.start_time = Time.new
|
132
|
+
c.current_amount = 0.25
|
133
|
+
assert_in_delta(0.1, 0.1, c.time_remaining)
|
134
|
+
sleep 1
|
135
|
+
assert_in_delta(3, 0.1, c.time_remaining)
|
136
|
+
end
|
137
|
+
|
138
|
+
def test_time_remaining_none_done_yet
|
139
|
+
c = Capture.new
|
140
|
+
c.total_amount = 1.0
|
141
|
+
c.start_time = Time.new
|
142
|
+
assert_in_delta(0.1, 0.1, c.time_remaining)
|
143
|
+
end
|
144
|
+
|
145
|
+
def test_time_remaining_s
|
146
|
+
c = Capture.new
|
147
|
+
c.total_amount = 1.0
|
148
|
+
c.current_amount = 0.5
|
149
|
+
c.start_time = Time.new - 3661
|
150
|
+
assert_equal("1h 01m 01s remaining", c.time_remaining_s)
|
151
|
+
end
|
152
|
+
|
153
|
+
def test_set_fraction_complete
|
154
|
+
c = Capture.new
|
155
|
+
c.total_amount = 4
|
156
|
+
c.fraction_complete = 1
|
157
|
+
assert_not_nil c.current_amount
|
158
|
+
assert_equal 4, c.current_amount
|
159
|
+
end
|
160
|
+
|
161
|
+
def test_format_seconds
|
162
|
+
assert_equal "1h 01m 01s", Capture::ProgressTracker.format_seconds(3661)
|
163
|
+
end
|
164
|
+
|
165
|
+
def test_record_with_mock
|
166
|
+
c = Capture.new
|
167
|
+
c.get_window_to_capture
|
168
|
+
c.define_mock_capture_success
|
169
|
+
assert_equal 0, c.record.exitstatus
|
170
|
+
assert File.exists?("/tmp/screencaster_#{$$}_#{"%04d" % 0}.mkv"), "Record didn't create output file"
|
171
|
+
assert_equal 1, c.video_segments_size
|
172
|
+
assert_equal 0, c.record.exitstatus
|
173
|
+
assert File.exists?("/tmp/screencaster_#{$$}_#{"%04d" % 1}.mkv"), "Record didn't create output file"
|
174
|
+
assert_equal 2, c.video_segments_size
|
175
|
+
c.reset
|
176
|
+
assert_equal 0, c.video_segments_size
|
177
|
+
assert_equal 0, Dir.glob("/tmp/screencaster_#{$$}*").size
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'screencaster-gtk'
|
3
|
+
require File.join(File.expand_path(File.dirname(__FILE__)), 'test_utils')
|
4
|
+
require File.join(File.expand_path(File.dirname(__FILE__)), 'capture')
|
5
|
+
require File.join(File.expand_path(File.dirname(__FILE__)), 'screencaster-gtk')
|
6
|
+
|
7
|
+
class TestScreencasterGtk < Test::Unit::TestCase
|
8
|
+
include TestUtils
|
9
|
+
|
10
|
+
ScreencasterGtk.logger = STDOUT
|
11
|
+
ScreencasterGtk.logger.formatter = proc do |severity, datetime, progname, msg|
|
12
|
+
"#{msg}\n"
|
13
|
+
end
|
14
|
+
|
15
|
+
def setup
|
16
|
+
@sc = ScreencasterGtk.new
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_record
|
20
|
+
ScreencasterGtk.logger.debug("Thread exception: #{Thread.abort_on_exception}")
|
21
|
+
ScreencasterGtk.logger.debug("test_record")
|
22
|
+
# Uses the test definition of select defined in the local version of capture.rb
|
23
|
+
@sc.select
|
24
|
+
ScreencasterGtk.logger.debug("selected")
|
25
|
+
@sc.spawn_record
|
26
|
+
ScreencasterGtk.logger.debug("about to sleep")
|
27
|
+
sleep 2
|
28
|
+
ScreencasterGtk.logger.debug("woke up")
|
29
|
+
assert @sc.check_background, "check_background 1 failed"
|
30
|
+
ScreencasterGtk.logger.debug("About to stop")
|
31
|
+
@sc.stop_recording
|
32
|
+
ScreencasterGtk.logger.debug("Stopped (in test_record)")
|
33
|
+
assert @sc.check_background, "check_background 2 failed"
|
34
|
+
assert @sc.background_exitstatus, "Unexpected background failure"
|
35
|
+
assert @sc.check_background, "check_background 3 failed"
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_encode
|
39
|
+
output = file_name("c.mkv")
|
40
|
+
File.delete output if File.exists? output
|
41
|
+
# Uses the test definition of select defined in the local version of capture.rb
|
42
|
+
@sc.select
|
43
|
+
@sc.capture_window.tmp_files = [file_name("a.mkv")]
|
44
|
+
@sc.capture_window.total_amount = 1
|
45
|
+
assert @sc.spawn_encode(output), "spawn_encode failed"
|
46
|
+
assert @sc.check_background, "check_background failed"
|
47
|
+
assert @sc.background_exitstatus, "Unexpected background failure"
|
48
|
+
end
|
49
|
+
|
50
|
+
def test_no_background_process
|
51
|
+
assert @sc.check_background, "check_background failed when no background process"
|
52
|
+
assert @sc.background_exitstatus, "Unexpected background failure"
|
53
|
+
end
|
54
|
+
|
55
|
+
def test_background_fails
|
56
|
+
# Uses the test definition of select defined in the local version of capture.rb
|
57
|
+
@sc.select
|
58
|
+
# Force a failure by giving a bogus sound device
|
59
|
+
@sc.capture_window.audio_input = 'bogus_audio'
|
60
|
+
@sc.spawn_record
|
61
|
+
sleep 1
|
62
|
+
assert ! @sc.check_background, "check_background should have returned false"
|
63
|
+
assert @sc.check_background, "check_background should not have returned false"
|
64
|
+
end
|
65
|
+
end
|
data/test/test_utils.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
module TestUtils
|
2
|
+
Thread.abort_on_exception = true
|
3
|
+
TEST_FILE_PATH = File.dirname(__FILE__)
|
4
|
+
|
5
|
+
$logger = Logger.new(STDOUT)
|
6
|
+
$logger.formatter = proc do |severity, datetime, progname, msg|
|
7
|
+
"#{msg}\n"
|
8
|
+
end
|
9
|
+
|
10
|
+
def file_name(f)
|
11
|
+
File.join(TEST_FILE_PATH, f)
|
12
|
+
end
|
13
|
+
|
14
|
+
def baseline_file_name(f)
|
15
|
+
file_name(File.join('baseline', f))
|
16
|
+
end
|
17
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: screencaster-gtk
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.6.alpha1
|
5
5
|
prerelease: 6
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-12-
|
12
|
+
date: 2013-12-18 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: gdk_pixbuf2
|
@@ -110,6 +110,11 @@ files:
|
|
110
110
|
- lib/screencaster-gtk/savefile.rb
|
111
111
|
- lib/screencaster-gtk/capture.rb
|
112
112
|
- lib/screencaster-gtk/progresstracker.rb
|
113
|
+
- test/test_screencaster_gtk.rb
|
114
|
+
- test/capture.rb
|
115
|
+
- test/screencaster-gtk.rb
|
116
|
+
- test/test_utils.rb
|
117
|
+
- test/test_capture.rb
|
113
118
|
- bin/screencaster
|
114
119
|
homepage: http://github.org/lcreid/screencaster
|
115
120
|
licenses:
|
@@ -140,5 +145,10 @@ rubygems_version: 1.8.24
|
|
140
145
|
signing_key:
|
141
146
|
specification_version: 3
|
142
147
|
summary: Screencaster
|
143
|
-
test_files:
|
148
|
+
test_files:
|
149
|
+
- test/test_screencaster_gtk.rb
|
150
|
+
- test/capture.rb
|
151
|
+
- test/screencaster-gtk.rb
|
152
|
+
- test/test_utils.rb
|
153
|
+
- test/test_capture.rb
|
144
154
|
has_rdoc:
|