=begin
Copyright 2010, Roger Pack
This file is part of Sensible Cinema.
Sensible Cinema is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Sensible Cinema is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Sensible Cinema. If not, see .
=end
require 'ostruct'
require File.expand_path(File.dirname(__FILE__) + '/common')
Dir.chdir '..' # need to run in the main folder, common moves us to spec...
load 'bin/sensible-cinema'
#require_relative 'lib/edl_parser' # to avoid having require_relative collide with autoload
module SensibleSwing
describe MainWindow do
it "should be able to start up" do
MainWindow.new.dispose# doesn't crash :)
end
it "should have working is_dvd method for mac"
Test_DVD_ID = 'deadbeef|8b27d001'
it "should die if you file select a poorly formed edl" do
time_through = 0
EdlParser.stub!(:single_edit_list_matches_dvd) { |dir, md5|
'fake filename doesnt matter what we return here because we fake its parsing later anyway'
}
@subject.stub!(:parse_edl) {
time_through += 1
eval("a-----") # force it to throw a Syntax Error first time
}
proc { @subject.choose_dvd_or_file_and_edl_for_it}.should raise_exception(SyntaxError)
@show_blocking_message_dialog_last_arg.should be nil
time_through.should == 1
end
it "should warn if you don't have enough disk space" do
@subject.get_freespace('.').should be > 0
@subject.get_freespace("c:\\nonexistent").should be > 0
@subject.stub!(:get_freespace) {
0
}
@subject.get_save_to_filename 'dvd_title'
@show_blocking_message_dialog_last_arg.should =~ /may not be enough/
end
it "should not warn if you have enough free disk space" do
@subject.stub!(:get_freespace) {
16_000_000_000
}
@subject.get_save_to_filename 'dvd_title'
@show_blocking_message_dialog_last_arg.should be nil
end
def with_clean_edl_dir_as this
FileUtils.rm_rf 'temp'
Dir.mkdir 'temp'
old_edl = EdlParser::EDL_DIR.dup
EdlParser::EDL_DIR.sub!(/.*/, 'temp')
begin
yield
ensure
EdlParser::EDL_DIR.sub!(/.*/, old_edl)
end
end
it "should modify path to have mencoder available" do
RubyWhich.new.which('mencoder').length.should be > 0
end
it "should not modify path to have mplayer available" do
ENV['PATH'].should_not include("mplayer")
end
before do
File.write('selected_file', '"name" => "a dvd name to satisfy internal assertion", "dvd_title_track" => "2", "mutes" => ["06:10", "06:15"]')
end
before do
@subject = MainWindow.new false # false to speedup tests
# want lots of buttons :)
@subject.setup_advanced_buttons
@subject.setup_normal_buttons
@subject.add_options_that_use_local_files
FileUtils.touch "selected_file.fulli_unedited.tmp.mpg.done" # a few of them need this...
FileUtils.touch 'selected_file.avi'
@subject.stub!(:choose_dvd_drive_or_file) {
["mock_dvd_drive", "Volume", Test_DVD_ID] # happiest baby on the block
}
@subject.stub!(:get_mencoder_commands) { |*args|
args[-5].should == 'selected_file'
@get_mencoder_commands_args = args
'fake get_mencoder_commands'
}
@subject.stub!(:new_existing_file_selector_and_select_file) {
'selected_file'
}
@subject.stub!(:new_nonexisting_filechooser_and_go) {
'selected_file' # TODO do we need FakefileChooser anymore?
}
@subject.stub!(:get_drive_with_most_space_with_slash) {
"e:\\"
}
@subject.stub!(:show_blocking_message_dialog) { |*args|
@show_blocking_message_dialog_last_arg = args[0]
}
@subject.stub!(:get_user_input) {'01:00'}
@subject.stub!(:system_blocking) { |*command|
@system_blocking_command = command[0]
}
@subject.stub!(:system_non_blocking) { |command|
@system_non_blocking_command = command
Thread.new {} # fake out the return...
}
@subject.stub!(:open_file_to_edit_it) {}
PlayAudio.stub!(:play) {
# don't play anything, by default :)
}
@subject.stub!(:get_freespace) {
# during testing, we *always* have enough free space :)
16_000_000_000
}
@subject.stub!(:show_in_explorer) {|filename|}
unless $VERBOSE
# less chatty...
@subject.stub!(:print) {}
@subject.stub!(:p) {}
@subject.stub!(:puts) {}
EdlParser.stub!(:p) {}
end
@subject.stub(:show_non_blocking_message_dialog) {
# don't display the popup message...
fake_window = OpenStruct.new
fake_window.dispose = :ok
fake_window
}
end
before do
EdlParser::EDL_DIR.gsub!(/^.*$/, 'spec/files/edls')
end
after do
# too dangerous...if it ever joins on a swing thread lights out!
#Thread.join_all_others
FileUtils.rm_rf EdlParser::EDL_DIR
Dir.mkdir EdlParser::EDL_DIR
end
class FakeFileChooser
def set_title x; end
def set_file y; end
def set_current_directory x; end
def get_current_directory ; 'a great dir!'; end
def go
'selected_file'
end
end
# name like :@rerun_previous
def click_button(name)
button = @subject.instance_variable_get(name)
raise 'button not found: ' + name.to_s unless button
button.simulate_click
end
it "should be able to run system" do
@subject.system_non_blocking "ls"
end
it "should be able to do a normal copy to hard drive, edited" do
@subject.do_create_edited_copy_via_file(false).should == [false, "selected_file.fulli_unedited.tmp.mpg"]
File.exist?('test_file_to_see_if_we_have_permission_to_write_to_this_folder').should be false
end
it "should only prompt twice for filenames--once for the 'save to' filename, once for the 'from' filename" do
count1=count2=0
@subject.stub!(:new_existing_file_selector_and_select_file) { # get from filename
count2 += 1
'selected_file'
}
@subject.stub!(:new_nonexisting_filechooser_and_go) { # save to filename
count1 += 1
'selected_file'
}
@subject.do_create_edited_copy_via_file(false).should == [false, "selected_file.fulli_unedited.tmp.mpg"]
5.times {
@subject.do_create_edited_copy_via_file(false)
}
count1.should == 1
count2.should == 2 # once for from filename, once for [tell us where you grabbed it to] filename
end
it "should have a good default title of 1" do
@subject.get_title_track({}).should == "1"
descriptors = {"dvd_title_track" => "3"}
@subject.get_title_track(descriptors).should == "3"
end
it "should call through to explorer to display the final output file" do
PlayAudio.stub!(:play) {
@played = true
}
@subject.do_create_edited_copy_via_file(false)
@subject.background_thread.join
@get_mencoder_commands_args[-4].should == nil
@system_blocking_command.should match /explorer/
@system_blocking_command.should_not match /fulli/
@played.should == true
end
it "should be able to return the fulli name if it already exists" do
@subject.do_create_edited_copy_via_file(false,true).should == [true, "selected_file.fulli_unedited.tmp.mpg"]
FileUtils.rm "selected_file.fulli_unedited.tmp.mpg.done"
end
it "should call explorer eventually, even if it has to create the fulli file"
it "should play the edited file" do
@subject.do_create_edited_copy_via_file(true).should == [false, "selected_file.fulli_unedited.tmp.mpg"]
join_background_thread
@get_mencoder_commands_args[-2].should == "2" # title track
@get_mencoder_commands_args[-3].should == "01:00"
@system_blocking_command.should_not match /fulli/
end
def assert_played_mplayer
Thread.join_all_others
if OS.doze?
@system_blocking_command.should =~ /smplayer/
else
@system_blocking_command.should =~ /mplayer/
end
end
def run_preview_section_button_successfully
click_button(:@preview_section)
join_background_thread
@get_mencoder_commands_args[-2].should == "2"
@get_mencoder_commands_args[-3].should == "01:00"
assert_played_mplayer
end
it "should prompt for start and end times" do
run_preview_section_button_successfully
end
temp_dir = Dir.tmpdir
def join_background_thread
@subject.background_thread.join # force it to have been started at least
Thread.join_all_others # just in case...
end
it "should be able to preview unedited" do
@subject.stub!(:get_user_input).and_return('06:00', '07:00')
@subject.stub!(:run_smplayer_blocking) {} # stub this out
@subject.unstub!(:get_mencoder_commands)
click_button(:@preview_section_unedited)
join_background_thread # scary timing spec
temp_file = temp_dir + '/vlc.temp.bat'
File.read(temp_file).should include("59.99")
end
it "should do something for fast preview" do
FileUtils.touch "selected_file.fulli_unedited.tmp.mpg"
click_button(:@fast_preview)
assert_played_mplayer
end
it "should be able to rerun the latest start and end times with the rerun button" do
run_preview_section_button_successfully
old_args = @get_mencoder_commands_args
old_args.should_not == nil
@get_mencoder_commands_args = nil
click_button(:@rerun_preview).join
@get_mencoder_commands_args.should == old_args
join_background_thread
assert_played_mplayer
end
it "should not die if you pass it the same start and end time frames--graceful acceptance" do
@subject.stub!(:get_mencoder_commands) {
raise MencoderWrapper::TimingError
}
click_button(:@rerun_preview)
@show_blocking_message_dialog_last_arg.should =~ /you chose a time frame/
end
it "should not die if you pass it the same start and end time frames--graceful acceptance" do
@subject.stub!(:get_mencoder_commands) {
raise Errno::EACCES
}
click_button(:@rerun_preview) # lodo rspec error: wrong backtrace if no => e!
@show_blocking_message_dialog_last_arg.should =~ /a file/
end
it "should warn if you watch an edited time frame with no edits within thatin it" do
@subject.unstub!(:get_mencoder_commands) # this time through, let it check for existence of edits...
click_button(:@preview_section)
@show_blocking_message_dialog_last_arg.should =~ /unable to find/
end
it "should warn if you give it an mkv file, just in case" do
@subject.stub!(:run_smplayer_blocking) {} # avoid check for file existence
@subject.unstub!(:get_mencoder_commands) # this time through, let it really check for existence of edits...
@subject.stub!(:get_user_input).and_return('06:00', '07:00')
click_button(:@preview_section)
@show_blocking_message_dialog_last_arg.should =~ /is not a/
join_background_thread
end
it "should not warn if a ts file, and has appropriate entries within timeframe" do
@subject.stub!(:get_user_input).and_return('06:00', '07:00')
@subject.stub!(:new_existing_file_selector_and_select_file).and_return('selected_file', 'selected_file.mpg')
click_button(:@preview_section)
@show_blocking_message_dialog_last_arg.should =~ /preview just a portion/
join_background_thread # weird...rspec you should do my after blocks before you'n... LODO
end
it "if the .done files exists, do_copy... should just call smplayer ja" do
require 'tracer'
# Tracer.on
FileUtils.touch "selected_file.fulli_unedited.tmp.mpg.done"
@subject.do_create_edited_copy_via_file(false, true, true).should == [true, "selected_file.fulli_unedited.tmp.mpg"]
end
it "should create a new file based on stats of current disc" do
out = EdlParser::EDL_DIR + "/edls_being_edited/sweetest_disc_ever.txt"
FileUtils.mkdir_p File.dirname(out)
File.exist?( out ).should be_false
@subject.stub!(:get_user_input) {'sweetest disc ever'}
@subject.instance_variable_get(:@create_new_edl_for_current_dvd).simulate_click
begin
File.exist?( out ).should be_true
content = File.read(out)
content.should_not include("\"title\"")
content.should include("disk_unique_id")
content.should include("dvd_title_track")
content.should include("mplayer_dvd_splits")
ensure
FileUtils.rm_rf out
end
end
it "should display unique disc in an input box" do
click_button(:@display_dvd_info).should =~ /deadbeef/
end
it "should create an edl and pass it through to mplayer" do
smplayer_opts = nil
@subject.stub(:set_smplayer_opts) { |to_this, show_subs|
smplayer_opts = to_this
}
click_button(:@mplayer_edl).join
smplayer_opts.should match(/-edl /)
@system_blocking_command.should match(/mock_dvd_drive/) #
@system_blocking_command.should_not =~ /dvdnav/ # file based, so no dvdvnav
@system_blocking_command.should_not =~ /-nocache/ # file based, so no -nocache
end
it "should handle dvd drive -> dvdnav" do
for drive in ['d:', 'e:', 'f:', 'g:']
if File.exist?(drive + '/VIDEO_TS')
@subject.run_smplayer_blocking drive, nil, '', true, true, true
@system_blocking_command.should =~ /dvdnav/
@system_blocking_command.should =~ /-dvd-device/
end
end
end
it 'should handle a/b/VIDEO_TS/yo.vob' do
FileUtils.mkdir_p f = 'a/b/VIDEO_TS/yo.vob'
@subject.run_smplayer_blocking f, 3, '', true, false, true
@system_blocking_command.should =~ /dvdnav:\/\/3/
@system_blocking_command.should =~ /VIDEO_TS\/\.\./
@system_blocking_command.should =~ / -alang/ # preceding space :)
# exercise the yes subtitle options...
@subject.run_smplayer_blocking f, 3, '', true, true, true
@system_blocking_command.should_not =~ /-nosub/
end
it "should play edl with extra time for the mutes because of the EDL aspect" do
click_button(:@mplayer_edl).join
wrote = File.read(MainWindow::EdlTempFile)
wrote.should include("369.0 375.0 1") # right numbers, except first -= 1
end
def should_allow_for_changing_file corrupt_the_file = false
with_clean_edl_dir_as 'temp' do
File.binwrite('temp/a.txt', "\"disk_unique_id\" => \"abcdef1234\"")
@subject.stub!(:choose_dvd_drive_or_file) {
FileUtils.touch 'mock_dvd_drive'
["mock_dvd_drive", "Volume", "abcdef1234"]
}
@subject.choose_dvd_or_file_and_edl_for_it[4]['mutes'].should == []
new_file_contents = '"disk_unique_id" => "abcdef1234","mutes"=>["0:33", "0:34"]'
new_file_contents = '"a syntax error' if corrupt_the_file
File.binwrite('temp/a.txt', new_file_contents)
# file has been modified!
@subject.choose_dvd_or_file_and_edl_for_it[4]['mutes'].should_not == []
end
end
it "should allow for file to change contents while editing it" do
should_allow_for_changing_file
end
it "should prompt you if you re-choose, and your file now has a failure in it" do
@subject.stub(:show_blocking_message_dialog) {
@got_here = true
@subject.stub(:parse_edl) { 'pass the second time through' }
}
should_allow_for_changing_file true
@got_here.should == true
end
describe 'with unstubbed choose_dvd_drive_or_file' do
before do
DriveInfo.stub!(:get_dvd_drives_as_openstruct) {
a = OpenStruct.new
a.VolumeName = 'a dvd name'
a.Name = 'a path location'
[a]
}
@subject.unstub!(:choose_dvd_drive_or_file)
end
def yo select_a_dvd
count = 0
DriveInfo.stub!(:md5sum_disk) {
count += 1
Test_DVD_ID
}
if !select_a_dvd
DriveInfo.stub!(:get_dvd_drives_as_openstruct) { [] } # no DVD disks inserted...
end
@subject.stub(:get_disk_chooser_window) {|names|
a = OpenStruct.new
def a.setSize x,y; end
a.stub(:selected_idx) { 0 } # first entry is either DVD name *or* file, and is apparently "0" weird weird weird
# ruby bug [?] always return nil
# def a.selected_idx; p 'returning', select_this_idx; select_this_idx; end
a
}
@subject.stub(:new_nonexisting_filechooser_and_go) {|a, b|
'selected_filename'
}
@subject.stub(:new_existing_file_selector_and_select_file) {
'selected_edl'
}
FileUtils.touch 'selected_edl' # blank file is ok :P
@subject.choose_dvd_or_file_and_edl_for_it
@subject.choose_dvd_or_file_and_edl_for_it
count
end
it "should only prompt for disk selection once" do
yo( true ).should == 1 # choose the 'a dvd name' DVD
end
it "should only prompt for file selection once" do
prompted = false
@subject.stub(:assert_ownership_dialog) {
prompted = true
}
yo( false ).should == 0 # choose a file, so never dvdid any dvd...
assert prompted
end
it "should prompt you if you need to insert a dvd" do
DriveInfo.stub!(:get_dvd_drives_as_openstruct) {
a = OpenStruct.new
#a.VolumeName = 'a dvd name' # we "don't have a disk in" for this test...
a.Name = 'a path location'
[a]
}
proc {@subject.choose_dvd_drive_or_file true}.should raise_error(/no dvd found/)
@show_blocking_message_dialog_last_arg.should_not be nil
end
end
it "should show additional buttons in create mode" do
MainWindow.new(false).setup_default_buttons.buttons.length.should be > 3
MainWindow.new(false).setup_default_buttons.buttons.length.should be < 10
old_length = MainWindow.new(false).setup_default_buttons.buttons.length
ARGV << "--create-mode"
MainWindow.new(false).setup_default_buttons.buttons.length.should be > (old_length + 5)
ARGV.pop # post-test cleanup--why not :)
end
it "should show upconvert buttons" do
ARGV << "--upconvert-mode"
MainWindow.new(false).setup_default_buttons.buttons.length.should be > 3
ARGV.pop
end
it "should read splits from the file" do
splits1 = nil
MplayerEdl.stub(:convert_to_edl) do |d,s,s2,splits|
splits1 = splits
end
@subject.play_smplayer_edl_non_blocking
splits1.should == []
end
it "should warn if there are no DVD splits and you try to use EDL" do
with_clean_edl_dir_as 'temp' do
File.binwrite('temp/a.txt', "\"disk_unique_id\" => \"abcdef1234\"")
@subject.stub!(:choose_dvd_drive_or_file) {
["mock_dvd_drive", "mockVolume", "abcdef1234"]
}
@subject.play_smplayer_edl_non_blocking
@show_blocking_message_dialog_last_arg.should =~ /does not contain mplayer replay information \[mplayer_dvd_splits\]/
end
end
it "should be able to parse an srt for ya" do
@subject.stub!(:new_existing_file_selector_and_select_file) {
'spec/dragon.srt'
}
file = SensibleSwing::MainWindow::EdlTempFile
FileUtils.rm_rf file
click_button(:@parse_srt)
assert File.read(file).contain? "deitys"
end
it "should have a created play unedited smplayer button" do
click_button(:@play_smplayer)
end
it "should create an sxs file" do
FileUtils.rm_rf 'yo.edl' # nothing up my sleeve.
prompted = false
@subject.stub(:assert_ownership_dialog) {
prompted = true
}
@subject.stub(:new_existing_file_selector_and_select_file).and_return("yo.mpg", "selected_file")
click_button(:@create_dot_edl)
assert File.exist? 'yo.edl'
assert prompted
end
it "should be able to upconvert at all" do
MainWindow.any_instance.stub(:display_current_upconvert_setting_and_close_window) {} # TRY it out
@subject = MainWindow.new(false)
MainWindow::LocalStorage['screen_multiples'] = 2.0 # default so it won't fail us...
@subject.add_change_upconvert_buttons
@subject.stub(:show_mplayer_instructions_once) {}
click_button(:@medium_dvd)
storage = MainWindow::LocalStorage
key = MainWindow::UpConvertKey
storage[key].should =~ /hqdn3d/
click_button(:@none)
storage[key].should be_nil
click_button(:@medium_dvd)
# now it should use them on mplayer
got = nil
@subject.stub(:system_blocking) { |c|
got = c
}
@subject.run_smplayer_blocking 'selected_file.avi', nil, "", true, true, false
assert got =~ /hqdn3d/
# and on smplayer
MainWindow::SMPlayerIniFile.gsub!(/^.*$/, File.expand_path('./smplayer_ini_file')) # don't overwrite the real one...
@subject.run_smplayer_blocking 'selected_file.avi', nil, "", false, true, false
assert got =~ /mplayer/
assert File.read(MainWindow::SMPlayerIniFile) =~ /hqdn3d/
end
it "should be able to play upconverted stuff" do
@subject.add_play_upconvert_buttons
click_button(:@watch_file_upconvert)
assert_played_mplayer
click_button(:@watch_dvd_upconvert)
assert_played_mplayer
end
end # describe MainWindow
end