diff --git a/lib/train/extras/file_common.rb b/lib/train/extras/file_common.rb index 247e9caf..64349db9 100644 --- a/lib/train/extras/file_common.rb +++ b/lib/train/extras/file_common.rb @@ -106,10 +106,23 @@ def mounted? !mounted.nil? && !mounted.stdout.nil? && !mounted.stdout.empty? end + def basename(suffix = nil, sep = '/') + fail 'Not yet supported: Suffix in file.basename' unless suffix.nil? + @basename ||= detect_filename(path, sep || '/') + end + # helper methods provided to any implementing class private + def detect_filename(path, sep) + idx = path.rindex(sep) + return path if idx.nil? + idx += 1 + return detect_filename(path[0..-2], sep) if idx == path.length + path[idx..-1] + end + def target_type # Just return the type unless this is a symlink return type unless type == :symlink diff --git a/lib/train/extras/file_windows.rb b/lib/train/extras/file_windows.rb index 33b1b72b..29efb704 100644 --- a/lib/train/extras/file_windows.rb +++ b/lib/train/extras/file_windows.rb @@ -2,6 +2,7 @@ # author: Dominik Richter # author: Christoph Hartmann +require 'shellwords' require 'train/extras/stat' # PS C:\Users\Administrator> Get-Item -Path C:\test.txt | Select-Object -Property BaseName, FullName, IsReadOnly, Exists, @@ -16,6 +17,10 @@ def initialize(backend, path) @spath = Shellwords.escape(@path) end + def basename(suffix = nil, sep = '\\') + super(suffix, sep) + end + def content return @content if defined?(@content) @content = @backend.run_command( diff --git a/test/unit/extras/file_common_test.rb b/test/unit/extras/file_common_test.rb index b0829216..4e1a423b 100644 --- a/test/unit/extras/file_common_test.rb +++ b/test/unit/extras/file_common_test.rb @@ -130,4 +130,50 @@ def mockup(stubs) fc.unix_mode_mask('all', 'r').must_equal 0444 end end + + describe 'basename helper' do + def fc(path) + mockup(type: :file, path: path) + end + + it 'works with an empty path' do + fc('').basename.must_equal '' + end + + it 'separates a simple path (defaults to unix mode)' do + fc('/dir/file').basename.must_equal 'file' + end + + it 'separates a simple path (Unix mode)' do + fc('/dir/file').basename(nil, '/').must_equal 'file' + end + + it 'separates a simple path (Windows mode)' do + fc('C:\dir\file').basename(nil, '\\').must_equal 'file' + end + + it 'identifies a folder name (Unix mode)' do + fc('/dir/file/').basename(nil, '/').must_equal 'file' + end + + it 'identifies a folder name (Windows mode)' do + fc('C:\dir\file\\').basename(nil, '\\').must_equal 'file' + end + + it 'ignores tailing separators (Unix mode)' do + fc('/dir/file///').basename(nil, '/').must_equal 'file' + end + + it 'ignores tailing separators (Windows mode)' do + fc('C:\dir\file\\\\\\').basename(nil, '\\').must_equal 'file' + end + + it 'doesnt work with backward slashes (Unix mode)' do + fc('C:\dir\file').basename(nil, '/').must_equal 'C:\\dir\file' + end + + it 'doesnt work with forward slashes (Windows mode)' do + fc('/dir/file').basename(nil, '\\').must_equal '/dir/file' + end + end end diff --git a/test/unit/extras/linux_file_test.rb b/test/unit/extras/linux_file_test.rb index 38b48296..71173c3d 100644 --- a/test/unit/extras/linux_file_test.rb +++ b/test/unit/extras/linux_file_test.rb @@ -18,6 +18,14 @@ def mock_stat(path, out, err = '', code = 0) ) end + it 'provides the full path' do + cls.new(backend, '/dir/file').path.must_equal '/dir/file' + end + + it 'provides the basename to a unix path' do + cls.new(backend, '/dir/file').basename.must_equal 'file' + end + it 'reads file contents' do out = rand.to_s backend.mock_command('cat path || echo -n', out) diff --git a/test/unit/extras/windows_file_test.rb b/test/unit/extras/windows_file_test.rb new file mode 100644 index 00000000..56f2a8e3 --- /dev/null +++ b/test/unit/extras/windows_file_test.rb @@ -0,0 +1,29 @@ +# encoding: utf-8 +require 'helper' +require 'train/transports/mock' +require 'train/extras' + +describe 'file common' do + let(:cls) { Train::Extras::WindowsFile } + let(:backend) { + backend = Train::Transports::Mock.new.connection + backend.mock_os({ family: 'windows' }) + backend + } + + it 'provides the full path' do + cls.new(backend, 'C:\dir\file').path.must_equal 'C:\dir\file' + end + + it 'provides the basename to a unix path' do + cls.new(backend, 'C:\dir\file').basename.must_equal 'file' + end + + it 'reads file contents' do + out = rand.to_s + backend.mock_command('Get-Content("path") | Out-String', out) + cls.new(backend, 'path').content.must_equal out + end + + # TODO: add all missing file tests!! +end