#!/usr/bin/env ruby require 'test/unit' currentPath = File.dirname(__FILE__) require File.join( currentPath, '../../lib/masterview/io' ) class TestFileMIO < Test::Unit::TestCase include MasterView MVTestDir = File.expand_path( File.join(File.dirname(__FILE__), '..' ) ) TemplateDir = "#{MVTestDir}/tmp/template" TemplateErbDir = "#{MVTestDir}/tmp/erb" TestFileMIOTemplatePathname = Pathname.new(TemplateDir) ErbPathname = Pathname.new(TemplateErbDir) HelloWorldPath = 'hello_world.txt' HelloWorldFullPath = "#{TemplateDir}/hello_world.txt" TestWritePath = 'foo.txt' TestWriteFullPath = "#{TemplateDir}/foo.txt" TestWritePathname = Pathname.new(TestWriteFullPath) IOMgr = MIOTrees.new def setup IOMgr.template = FileMIOTree.new(TemplateDir, '.html') IOMgr.erb = FileMIOTree.new(TemplateErbDir, '.rhtml' ) IOMgr.file = FileMIOTree.new() TestFileMIOTemplatePathname.rmtree if TestFileMIOTemplatePathname.exist? ErbPathname.rmtree if ErbPathname.exist? TestFileMIOTemplatePathname.mkpath ErbPathname.mkpath end #------------------------------------------------------------------------------ # Test Cases #------------------------------------------------------------------------------ # ensure that sandbox limits writing to files outside of root path even if dot dot exists in path def test_sandbox_dotdot assert_raise(InvalidPathError){ f = IOMgr.template.path( '../bad') } assert_raise(InvalidPathError){ f = IOMgr.template.path( 'bad/../dog/../../foo') } assert_raise(InvalidPathError){ f = IOMgr.template.path( 'bad/../../foo') } assert_raise(InvalidPathError){ f = IOMgr.template.path( 'bad/cat/../../../dog') } assert_raise(InvalidPathError){ f = IOMgr.template.path( '/bad/foo') } assert_raise(InvalidPathError){ f = IOMgr.template.path( '/bad') } assert_raise(InvalidPathError){ f = IOMgr.template.path( '../bad.cat') } assert_raise(InvalidPathError){ f = IOMgr.template.path( 'bad/../dot/../../foo.cat') } assert_raise(InvalidPathError){ f = IOMgr.template.path( 'bad/../../foo.cat') } assert_raise(InvalidPathError){ f = IOMgr.template.path( 'bad/cat/../../../dog.cat') } assert_raise(InvalidPathError){ f = IOMgr.template.path( '/bad/foo.cat') } assert_raise(InvalidPathError){ f = IOMgr.template.path( '/bad.cat') } end def test_create_foo verify_mio_handler_paths( 'foo', IOMgr.template, TemplateDir ) end def test_create_bar verify_mio_handler_paths( 'bar', IOMgr.erb, TemplateErbDir ) end def test_create_cat verify_mio_handler_paths( 'cat', IOMgr.file, Pathname.getwd.to_str ) end def test_create_foo_w_ext verify_mio_handler_paths( 'foo.txt', IOMgr.template, TemplateDir ) end def test_create_parts verify_mio_handler_paths( 'sub/one/two/three/foo.txt', IOMgr.template, TemplateDir ) end def test_read TestFileMIOTemplatePathname.mkpath unless TestFileMIOTemplatePathname.exist? file_content = "hello\nworld" # write to abs pathname, ensure handler resolves rel pathname properly File.open( HelloWorldFullPath, 'w' ){ |file| file.write(file_content) } verify_mio_handler_read( HelloWorldPath, HelloWorldFullPath, file_content, IOMgr.template ) end def test_read_disable_cache TestFileMIOTemplatePathname.mkpath unless TestFileMIOTemplatePathname.exist? file_content = "hello\nworld" # write to abs pathname, ensure handler resolves rel pathname properly File.open( HelloWorldFullPath, 'w' ){ |file| file.write(file_content) } verify_mio_handler_read( HelloWorldPath, HelloWorldFullPath, file_content, IOMgr.template ) file_content_changed = "foo\nbar" File.open( HelloWorldFullPath, 'w' ){ |file| file.write(file_content_changed) } #verify_mio_handler_read( HelloWorldPath, file_content, IOMgr.template ) # still hitting cache #todo turn this on when caching is ready for testing verify_mio_handler_read_no_cache( HelloWorldPath, HelloWorldFullPath, file_content_changed, IOMgr.template ) end def test_write_string TestWritePathname.delete if TestWritePathname.exist? file_content = "foo\nbar" IOMgr.template.path( TestWritePath ).write(file_content) verify_mio_handler_read( TestWritePath, TestWriteFullPath, file_content, IOMgr.template ) end def test_write_strings TestWritePathname.delete if TestWritePathname.exist? file_content = "foo\nbar" IOMgr.template.path( TestWritePath ).write(file_content) verify_mio_handler_read( TestWritePath, TestWriteFullPath, file_content, IOMgr.template ) end def test_write_block TestWritePathname.delete if TestWritePathname.exist? file_content = "hello" IOMgr.template.path( TestWritePath ).write { |f| f.write(file_content) } verify_mio_handler_read( TestWritePath, TestWriteFullPath, file_content, IOMgr.template ) end def test_write_strings_and_block TestWritePathname.delete if TestWritePathname.exist? file_content_strings = [ 'hello', 'world'] file_content = file_content_strings.join('') IOMgr.template.path( TestWritePath).write do |f| file_content_strings.each { |str| f.write(str) } end verify_mio_handler_read( TestWritePath, TestWriteFullPath, file_content, IOMgr.template ) end def test_write_mkpath TestFileMIOTemplatePathname.rmtree if TestFileMIOTemplatePathname.exist? file_content = "foo\nbar" IOMgr.template.path( TestWritePath ).write(file_content) verify_mio_handler_read( TestWritePath, TestWriteFullPath, file_content, IOMgr.template ) end def test_exist file_content = "foo" TestFileMIOTemplatePathname.rmtree if TestFileMIOTemplatePathname.exist? assert_equal false, IOMgr.template.path( TestWritePath).exist? IOMgr.template.path( TestWritePath).write(file_content) assert_equal true, IOMgr.template.path( TestWritePath).exist? TestWritePathname.delete if TestWritePathname.exist? assert_equal false, IOMgr.template.path( TestWritePath).exist? IOMgr.template.path( TestWritePath).write(file_content) assert_equal true, IOMgr.template.path( TestWritePath).exist? end def test_identical file_content = "hello\nworld" file_content_foo = "foo" TestWritePathname.delete if TestWritePathname.exist? assert_equal false, IOMgr.template.path( TestWritePath ).identical?(file_content) TestFileMIOTemplatePathname.mkpath unless TestFileMIOTemplatePathname.exist? File.open(TestWriteFullPath, 'w'){ |file| file.write(file_content) } assert_equal true, IOMgr.template.path( TestWritePath).identical?(file_content) assert_equal false, IOMgr.template.path( TestWritePath).identical?("foo") end def test_mtime file_content = "hello\nworld" TestWritePathname.delete if TestWritePathname.exist? TestFileMIOTemplatePathname.mkpath unless TestFileMIOTemplatePathname.exist? File.open(TestWriteFullPath, 'w'){ |file| file.write(file_content) } assert_equal TestWritePathname.mtime, IOMgr.template.path( TestWritePath).mtime end def test_findfiles_single_dir TestFileMIOTemplatePathname.rmtree if TestFileMIOTemplatePathname.exist? IOMgr.template.path( 'apple.txt').write('foo') IOMgr.template.path( 'bar.txt').write('foo') File.open(TestFileMIOTemplatePathname+'baz.txt', 'w'){ |file| file.write('foo') } found = IOMgr.template.find assert_equal 3, found.length assert_equal FileMIO, found[0].class assert_equal FileMIO, found[1].class assert_equal FileMIO, found[2].class assert_equal (TestFileMIOTemplatePathname+'apple.txt').to_s, found[0].full_pathname.to_s assert_equal 'apple.txt', found[0].pathname.to_s assert_equal 'bar.txt', found[1].pathname.to_s assert_equal 'baz.txt', found[2].pathname.to_s end def test_findfiles_single_sub_dir TestFileMIOTemplatePathname.rmtree if TestFileMIOTemplatePathname.exist? IOMgr.template.path( 'sub/apple.txt').write('foo') IOMgr.template.path( 'sub/bar.txt').write('foo') File.open(TestFileMIOTemplatePathname+'sub/baz.txt', 'w'){ |file| file.write('foo') } found = IOMgr.template.find(:path => 'sub') assert_equal 3, found.length assert_equal FileMIO, found[0].class assert_equal FileMIO, found[1].class assert_equal FileMIO, found[2].class assert_equal (TestFileMIOTemplatePathname+'sub/apple.txt').to_s, found[0].full_pathname.to_s assert_equal 'sub/apple.txt', found[0].pathname.to_s assert_equal 'sub/bar.txt', found[1].pathname.to_s assert_equal 'sub/baz.txt', found[2].pathname.to_s end def test_findfiles_single_sub2_dir_multi_arg TestFileMIOTemplatePathname.rmtree if TestFileMIOTemplatePathname.exist? IOMgr.template.path( 'sub/two/apple.txt').write('foo') IOMgr.template.path( 'sub/two/bar.txt').write('foo') File.open(TestFileMIOTemplatePathname+'sub/two/baz.txt', 'w'){ |file| file.write('foo') } found = IOMgr.template.find(:path => 'sub/two') assert_equal 3, found.length assert_equal FileMIO, found[0].class assert_equal FileMIO, found[1].class assert_equal FileMIO, found[2].class assert_equal (TestFileMIOTemplatePathname+'sub/two/apple.txt').to_s, found[0].full_pathname.to_s assert_equal 'sub/two/apple.txt', found[0].pathname.to_s assert_equal 'sub/two/bar.txt', found[1].pathname.to_s assert_equal 'sub/two/baz.txt', found[2].pathname.to_s end def test_findfiles_single_sub2_dir_single_arg TestFileMIOTemplatePathname.rmtree if TestFileMIOTemplatePathname.exist? IOMgr.template.path( 'sub/two/apple.txt').write('foo') IOMgr.template.path( 'sub/two/bar.txt').write('foo') File.open(TestFileMIOTemplatePathname+'sub/two/baz.txt', 'w'){ |file| file.write('foo') } found = IOMgr.template.find(:path => 'sub/two') assert_equal 3, found.length assert_equal FileMIO, found[0].class assert_equal FileMIO, found[1].class assert_equal FileMIO, found[2].class assert_equal (TestFileMIOTemplatePathname+'sub/two/apple.txt').to_s, found[0].full_pathname.to_s assert_equal 'sub/two/apple.txt', found[0].pathname.to_s assert_equal 'sub/two/bar.txt', found[1].pathname.to_s assert_equal 'sub/two/baz.txt', found[2].pathname.to_s end def test_findfiles_single_dir_pattern TestFileMIOTemplatePathname.rmtree if TestFileMIOTemplatePathname.exist? IOMgr.template.path( 'sub/two/apple.txt').write('foo') IOMgr.template.path( 'sub/two/bar.log').write('foo') File.open(TestFileMIOTemplatePathname+'sub/two/baz.txt', 'w'){ |file| file.write('foo') } found = IOMgr.template.find(:path => 'sub/two', :pattern => '*.txt') assert_equal 2, found.length assert_equal FileMIO, found[0].class assert_equal FileMIO, found[1].class assert_equal (TestFileMIOTemplatePathname+'sub/two/apple.txt').to_s, found[0].full_pathname.to_s assert_equal 'sub/two/apple.txt', found[0].pathname.to_s assert_equal 'sub/two/baz.txt', found[1].pathname.to_s end def test_findfiles_multi_dir_root TestFileMIOTemplatePathname.rmtree if TestFileMIOTemplatePathname.exist? IOMgr.template.path( 'one/two/three.txt').write('foo') IOMgr.template.path( 'sub/two/apple.txt').write('foo') IOMgr.template.path( 'sub/two/bar.log').write('foo') File.open(TestFileMIOTemplatePathname+'sub/two/baz.txt', 'w'){ |file| file.write('foo') } found = IOMgr.template.find assert_equal 4, found.length assert_equal FileMIO, found[0].class assert_equal FileMIO, found[1].class assert_equal FileMIO, found[2].class assert_equal FileMIO, found[3].class assert_equal (TestFileMIOTemplatePathname+'one/two/three.txt').to_s, found[0].full_pathname.to_s assert_equal 'one/two/three.txt', found[0].pathname.to_s assert_equal 'sub/two/apple.txt', found[1].pathname.to_s assert_equal 'sub/two/bar.log', found[2].pathname.to_s assert_equal 'sub/two/baz.txt', found[3].pathname.to_s end def test_findfiles_multi_dir_pattern TestFileMIOTemplatePathname.rmtree if TestFileMIOTemplatePathname.exist? IOMgr.template.path( 'one/two/three.txt').write('foo') IOMgr.template.path( 'sub/two/apple.txt').write('foo') IOMgr.template.path( 'sub/two/bar.log').write('foo') File.open(TestFileMIOTemplatePathname+'sub/two/baz.txt', 'w'){ |file| file.write('foo') } found = IOMgr.template.find(:pattern => '*.txt') assert_equal 3, found.length assert_equal FileMIO, found[0].class assert_equal FileMIO, found[1].class assert_equal FileMIO, found[2].class assert_equal (TestFileMIOTemplatePathname+'one/two/three.txt').to_s, found[0].full_pathname.to_s assert_equal 'one/two/three.txt', found[0].pathname.to_s assert_equal 'sub/two/apple.txt', found[1].pathname.to_s assert_equal 'sub/two/baz.txt', found[2].pathname.to_s end def test_findfiles_multi_dir_pattern_deep TestFileMIOTemplatePathname.rmtree if TestFileMIOTemplatePathname.exist? IOMgr.template.path( 'one/two/three.txt').write('foo') IOMgr.template.path( 'sub/two/apple.txt').write('foo') IOMgr.template.path( 'sub/two/bar.log').write('foo') File.open(TestFileMIOTemplatePathname+'sub/two/baz.txt', 'w'){ |file| file.write('foo') } found = IOMgr.template.find(:path => 'sub/two', :pattern => '*.txt') assert_equal 2, found.length assert_equal FileMIO, found[0].class assert_equal FileMIO, found[1].class assert_equal (TestFileMIOTemplatePathname+'sub/two/apple.txt').to_s, found[0].full_pathname.to_s assert_equal 'sub/two/apple.txt', found[0].pathname.to_s assert_equal 'sub/two/baz.txt', found[1].pathname.to_s end def test_findfiles_multi_dir_pattern_deep_with_block TestFileMIOTemplatePathname.rmtree if TestFileMIOTemplatePathname.exist? IOMgr.template.path( 'one/two/three.txt').write('foo') IOMgr.template.path( 'sub/two/apple.txt').write('foo') IOMgr.template.path( 'sub/two/bar.log').write('foo') File.open(TestFileMIOTemplatePathname+'sub/two/baz.txt', 'w'){ |file| file.write('foo') } array_of_mio = [] found = IOMgr.template.find(:path => 'sub/two', :pattern => '*.txt'){ |mio| array_of_mio << mio } assert_equal 2, found.length assert_equal FileMIO, found[0].class assert_equal FileMIO, found[1].class assert_equal (TestFileMIOTemplatePathname+'sub/two/apple.txt').to_s, found[0].full_pathname.to_s assert_equal 'sub/two/apple.txt', found[0].pathname.to_s assert_equal 'sub/two/baz.txt', found[1].pathname.to_s assert_equal 2, array_of_mio.length assert_kind_of FileMIO, array_of_mio[0] assert_kind_of FileMIO, array_of_mio[1] assert_equal 'sub/two/apple.txt', array_of_mio[0].pathname.to_s assert_equal 'sub/two/baz.txt', array_of_mio[1].pathname.to_s end #------------------------------------------------------------------------------ # Test helpers #------------------------------------------------------------------------------ # verify that an mio_handler for files anchored on a particular root_directory # produces the expected file reference paths for a relative path within that space def verify_mio_handler_paths( rel_path, mio_handler, root_directory ) assert_equal root_directory, mio_handler.to_str file_path = mio_handler.path( rel_path ) assert_equal FileMIO, file_path.class assert_equal rel_path, file_path.pathname.to_s assert_equal "#{root_directory}/#{rel_path}", file_path.full_pathname.to_s end # verify that the file mio_handler reads the expected file content def verify_mio_handler_read( rel_path, file_abs_path, file_content, mio_handler ) # verify the actual file contents are as expected assert_equal file_abs_path, "#{mio_handler.to_str}/#{rel_path}" assert_equal file_content, File.read( file_abs_path ) # verify that the file MIO handler obtains the expected content file_path = mio_handler.path( rel_path ) assert_equal file_abs_path, file_path.to_str assert_equal file_content, file_path.read end # verify that the file mio_handler reads the expected file content def verify_mio_handler_read_no_cache( rel_path, file_abs_path, file_content, mio_handler ) # verify the actual file contents are as expected assert_equal file_abs_path, "#{mio_handler.to_str}/#{rel_path}" #???assert_equal file_content, File.read( file_abs_path ) # verify that the file MIO handler obtains the expected content file_path = mio_handler.path( rel_path ) assert_equal file_abs_path, file_path.to_str assert_equal file_content, file_path.read(:disable_cache => true) end end