screencaster-gtk 0.0.5.alpha1 → 0.0.6.alpha1
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/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:
|