keeguon-ruby-ole 1.2.11.7
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.
- checksums.yaml +7 -0
- data/COPYING +20 -0
- data/ChangeLog +140 -0
- data/README +116 -0
- data/Rakefile +91 -0
- data/bin/oletool +40 -0
- data/lib/ole/base.rb +10 -0
- data/lib/ole/file_system.rb +7 -0
- data/lib/ole/ranges_io.rb +267 -0
- data/lib/ole/storage.rb +3 -0
- data/lib/ole/storage/base.rb +945 -0
- data/lib/ole/storage/file_system.rb +394 -0
- data/lib/ole/storage/meta_data.rb +150 -0
- data/lib/ole/storage/version.rb +8 -0
- data/lib/ole/support.rb +248 -0
- data/lib/ole/types.rb +2 -0
- data/lib/ole/types/base.rb +314 -0
- data/lib/ole/types/property_set.rb +202 -0
- data/ruby-ole.gemspec +32 -0
- data/test/oleWithDirs.ole +0 -0
- data/test/test.doc +0 -0
- data/test/test_SummaryInformation +0 -0
- data/test/test_filesystem.rb +932 -0
- data/test/test_mbat.rb +40 -0
- data/test/test_meta_data.rb +43 -0
- data/test/test_property_set.rb +40 -0
- data/test/test_ranges_io.rb +113 -0
- data/test/test_storage.rb +221 -0
- data/test/test_support.rb +155 -0
- data/test/test_types.rb +68 -0
- data/test/test_word_6.doc +0 -0
- data/test/test_word_95.doc +0 -0
- data/test/test_word_97.doc +0 -0
- metadata +92 -0
data/test/test_mbat.rb
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
#! /usr/bin/ruby
|
2
|
+
|
3
|
+
$: << File.dirname(__FILE__) + '/../lib'
|
4
|
+
|
5
|
+
require 'test/unit'
|
6
|
+
require 'ole/storage'
|
7
|
+
require 'tempfile'
|
8
|
+
|
9
|
+
class TestWriteMbat < Test::Unit::TestCase
|
10
|
+
def test_write_mbat
|
11
|
+
Tempfile.open 'myolefile' do |temp|
|
12
|
+
temp.binmode
|
13
|
+
|
14
|
+
# this used to raise an error at flush time, due to failure to write the mbat
|
15
|
+
Ole::Storage.open temp do |ole|
|
16
|
+
# create a 10mb file
|
17
|
+
ole.file.open 'myfile', 'w' do |f|
|
18
|
+
s = 0.chr * 1_000_000
|
19
|
+
10.times { f.write s }
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
assert((10_000_000..10_100_000) === temp.size, 'check file size')
|
24
|
+
|
25
|
+
Ole::Storage.open temp do |ole|
|
26
|
+
assert_equal 10_000_000, ole.file.size('myfile')
|
27
|
+
compare = ole.bbat.truncate[(0...ole.bbat.length).find { |i| ole.bbat[i] > 50_000 }..-1]
|
28
|
+
c = Ole::Storage::AllocationTable
|
29
|
+
# 10_000_000 * 4 / 512 / 512 rounded up is 153. but then there is room needed to store the
|
30
|
+
# bat in the bat, and the mbat too. hence 154.
|
31
|
+
expect = [c::EOC] * 2 + [c::BAT] * 154 + [c::META_BAT]
|
32
|
+
assert_equal expect, compare, 'allocation table structure'
|
33
|
+
# the sbat should be empty. in fact the file shouldn't exist at all, so the root's first
|
34
|
+
# block should be EOC
|
35
|
+
assert ole.sbat.empty?
|
36
|
+
assert_equal c::EOC, ole.root.first_block
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
#! /usr/bin/ruby
|
2
|
+
|
3
|
+
$: << File.dirname(__FILE__) + '/../lib'
|
4
|
+
|
5
|
+
require 'test/unit'
|
6
|
+
require 'ole/storage'
|
7
|
+
|
8
|
+
class TestMetaData < Test::Unit::TestCase
|
9
|
+
def test_meta_data
|
10
|
+
Ole::Storage.open File.dirname(__FILE__) + '/test.doc', 'rb' do |ole|
|
11
|
+
assert_equal 'Charles Lowe', ole.meta_data[:doc_author]
|
12
|
+
assert_equal 'Charles Lowe', ole.meta_data['doc_author']
|
13
|
+
assert_equal 'Charles Lowe', ole.meta_data.to_h[:doc_author]
|
14
|
+
assert_equal 'Title', ole.meta_data.doc_title
|
15
|
+
assert_equal 'MSWordDoc', ole.meta_data.file_format
|
16
|
+
assert_equal 'application/msword', ole.meta_data.mime_type
|
17
|
+
assert_raises NotImplementedError do
|
18
|
+
ole.meta_data[:doc_author] = 'New Author'
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
# this tests the other ways of getting the mime_type, than using "\001CompObj",
|
24
|
+
# ie, relying on root clsid, and on the heuristics
|
25
|
+
def test_mime_type
|
26
|
+
ole = Ole::Storage.new StringIO.new
|
27
|
+
ole.root.clsid = Ole::Storage::MetaData::CLSID_EXCEL97.to_s
|
28
|
+
assert_equal nil, ole.meta_data.file_format
|
29
|
+
assert_equal 'application/vnd.ms-excel', ole.meta_data.mime_type
|
30
|
+
|
31
|
+
ole.root.clsid = 0.chr * Ole::Types::Clsid::SIZE
|
32
|
+
assert_equal nil, ole.meta_data.file_format
|
33
|
+
assert_equal 'application/x-ole-storage', ole.meta_data.mime_type
|
34
|
+
|
35
|
+
ole.file.open('Book', 'w') { |f| }
|
36
|
+
assert_equal 'application/vnd.ms-excel', ole.meta_data.mime_type
|
37
|
+
ole.file.open('WordDocument', 'w') { |f| }
|
38
|
+
assert_equal 'application/msword', ole.meta_data.mime_type
|
39
|
+
ole.file.open('__properties_version1.0', 'w') { |f| }
|
40
|
+
assert_equal 'application/vnd.ms-outlook', ole.meta_data.mime_type
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
@@ -0,0 +1,40 @@
|
|
1
|
+
#! /usr/bin/ruby
|
2
|
+
|
3
|
+
$: << File.dirname(__FILE__) + '/../lib'
|
4
|
+
|
5
|
+
require 'test/unit'
|
6
|
+
require 'ole/types'
|
7
|
+
|
8
|
+
class TestPropertySet < Test::Unit::TestCase
|
9
|
+
include Ole::Types
|
10
|
+
|
11
|
+
def setup
|
12
|
+
@io = open File.dirname(__FILE__) + '/test_SummaryInformation', 'rb'
|
13
|
+
end
|
14
|
+
|
15
|
+
def teardown
|
16
|
+
@io.close
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_property_set
|
20
|
+
propset = PropertySet.new @io
|
21
|
+
assert_equal :mac, propset.os
|
22
|
+
assert_equal 1, propset.sections.length
|
23
|
+
section = propset.sections.first
|
24
|
+
assert_equal 14, section.length
|
25
|
+
assert_equal 'f29f85e0-4ff9-1068-ab91-08002b27b3d9', section.guid.format
|
26
|
+
assert_equal PropertySet::FMTID_SummaryInformation, section.guid
|
27
|
+
assert_equal 'Charles Lowe', section.to_a.assoc(4).last
|
28
|
+
assert_equal 'Charles Lowe', propset.doc_author
|
29
|
+
assert_equal 'Charles Lowe', propset.to_h[:doc_author]
|
30
|
+
|
31
|
+
# knows the difference between existent and non-existent properties
|
32
|
+
assert_raise(NoMethodError) { propset.non_existent_key }
|
33
|
+
assert_raise(NotImplementedError) { propset.doc_author = 'New Author'}
|
34
|
+
assert_raise(NoMethodError) { propset.non_existent_key = 'Value'}
|
35
|
+
|
36
|
+
# a valid property that has no value in this property set
|
37
|
+
assert_equal nil, propset.security
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
@@ -0,0 +1,113 @@
|
|
1
|
+
#! /usr/bin/ruby
|
2
|
+
|
3
|
+
$: << File.dirname(__FILE__) + '/../lib'
|
4
|
+
|
5
|
+
require 'test/unit'
|
6
|
+
require 'ole/ranges_io'
|
7
|
+
require 'stringio'
|
8
|
+
|
9
|
+
class TestRangesIO < Test::Unit::TestCase
|
10
|
+
TEST_DIR = File.dirname __FILE__
|
11
|
+
|
12
|
+
def setup
|
13
|
+
# read from ourself, also using overlaps.
|
14
|
+
ranges = [100..200, 0..10, 100..150]
|
15
|
+
@io = RangesIO.new open("#{TEST_DIR}/test_ranges_io.rb"), :ranges => ranges, :close_parent => true
|
16
|
+
end
|
17
|
+
|
18
|
+
def teardown
|
19
|
+
@io.close
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_open
|
23
|
+
# block form
|
24
|
+
f = open("#{TEST_DIR}/test_ranges_io.rb")
|
25
|
+
assert_equal false, f.closed?
|
26
|
+
RangesIO.open f, :ranges => []
|
27
|
+
assert_equal false, f.closed?
|
28
|
+
RangesIO.open(f, :ranges => [], :close_parent => true) {}
|
29
|
+
assert_equal true, f.closed?
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_combine
|
33
|
+
ranges = [[0, 100], 100...200, [200, 100]]
|
34
|
+
io = RangesIO.new STDOUT, 'r+', :ranges => ranges
|
35
|
+
assert_equal [[0, 300]], io.ranges
|
36
|
+
io = RangesIO.new STDOUT, 'r+', :ranges => ranges, :combine => false
|
37
|
+
assert_equal [[0, 100], [100, 100], [200, 100]], io.ranges
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_basics
|
41
|
+
assert_equal 160, @io.size
|
42
|
+
assert_match %r{size=160}, @io.inspect
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_truncate
|
46
|
+
assert_raises(NotImplementedError) { @io.size += 10 }
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_seek
|
50
|
+
@io.pos = 10
|
51
|
+
@io.seek(-100, IO::SEEK_END)
|
52
|
+
@io.seek(-10, IO::SEEK_CUR)
|
53
|
+
@io.pos += 20
|
54
|
+
assert_equal 70, @io.pos
|
55
|
+
@io.rewind
|
56
|
+
assert_equal 0, @io.pos
|
57
|
+
# seeking past the end doesn't throw an exception for normal
|
58
|
+
# files, even in read mode, but RangesIO does
|
59
|
+
assert_raises(Errno::EINVAL) { @io.seek 500 }
|
60
|
+
assert_raises(Errno::EINVAL) { @io.seek(-500, IO::SEEK_END) }
|
61
|
+
assert_raises(Errno::EINVAL) { @io.seek 1, 10 }
|
62
|
+
end
|
63
|
+
|
64
|
+
def test_read
|
65
|
+
# this will map to the start of the file:
|
66
|
+
@io.pos = 100
|
67
|
+
assert_equal '#! /usr/bi', @io.read(10)
|
68
|
+
# test selection of initial range, offset within that range
|
69
|
+
pos = 80
|
70
|
+
@io.seek pos
|
71
|
+
# test advancing of pos properly, by...
|
72
|
+
chunked = (0...10).map { @io.read 10 }.join
|
73
|
+
# given the file is 160 long:
|
74
|
+
assert_equal 80, chunked.length
|
75
|
+
@io.seek pos
|
76
|
+
# comparing with a flat read
|
77
|
+
assert_equal chunked, @io.read(80)
|
78
|
+
end
|
79
|
+
|
80
|
+
# should test gets, lineno, and other IO methods we want to have
|
81
|
+
def test_gets
|
82
|
+
assert_equal "io'\n", @io.gets
|
83
|
+
end
|
84
|
+
|
85
|
+
def test_write
|
86
|
+
str = File.read "#{TEST_DIR}/test_ranges_io.rb"
|
87
|
+
@io = RangesIO.new StringIO.new(str), :ranges => @io.ranges
|
88
|
+
assert_equal "io'\nrequir", str[100, 10]
|
89
|
+
@io.write 'testing testing'
|
90
|
+
assert_equal 'testing te', str[100, 10]
|
91
|
+
@io.seek 0
|
92
|
+
assert_equal 'testing te', @io.read(10)
|
93
|
+
# lets write over a range barrier
|
94
|
+
assert_equal '#! /usr/bi', str[0, 10]
|
95
|
+
assert_equal "LE__\n\n\tdef", str[195, 10]
|
96
|
+
@io.write 'x' * 100
|
97
|
+
assert_equal 'x' * 10, str[0, 10]
|
98
|
+
assert_equal "xxxxx\n\tdef", str[195, 10]
|
99
|
+
# write enough to overflow the file
|
100
|
+
assert_raises(IOError) { @io.write 'x' * 60 }
|
101
|
+
end
|
102
|
+
|
103
|
+
def test_non_resizeable
|
104
|
+
# will try to truncate, which will fail
|
105
|
+
assert_raises NotImplementedError do
|
106
|
+
@io = RangesIO.new(StringIO.new, 'w', :ranges => [])
|
107
|
+
end
|
108
|
+
# will be fine
|
109
|
+
@io = RangesIONonResizeable.new(StringIO.new, 'w', :ranges => [])
|
110
|
+
assert_equal '#<Ole::IOMode wronly|creat>', @io.instance_variable_get(:@mode).inspect
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
@@ -0,0 +1,221 @@
|
|
1
|
+
#! /usr/bin/ruby
|
2
|
+
# coding: utf-8
|
3
|
+
|
4
|
+
$: << File.dirname(__FILE__) + '/../lib'
|
5
|
+
#require 'rubygems'
|
6
|
+
|
7
|
+
require 'test/unit'
|
8
|
+
require 'ole/storage'
|
9
|
+
require 'digest/sha1'
|
10
|
+
require 'stringio'
|
11
|
+
require 'tempfile'
|
12
|
+
|
13
|
+
#
|
14
|
+
# = TODO
|
15
|
+
#
|
16
|
+
# These tests could be a lot more complete.
|
17
|
+
#
|
18
|
+
|
19
|
+
# should test resizeable and migrateable IO.
|
20
|
+
|
21
|
+
class TestStorageRead < Test::Unit::TestCase
|
22
|
+
TEST_DIR = File.dirname __FILE__
|
23
|
+
|
24
|
+
def setup
|
25
|
+
@ole = Ole::Storage.open "#{TEST_DIR}/test_word_6.doc", 'rb'
|
26
|
+
end
|
27
|
+
|
28
|
+
def teardown
|
29
|
+
@ole.close
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_header
|
33
|
+
# should have further header tests, testing the validation etc.
|
34
|
+
assert_equal 17, @ole.header.to_a.length
|
35
|
+
assert_equal 117, @ole.header.dirent_start
|
36
|
+
assert_equal 1, @ole.header.num_bat
|
37
|
+
assert_equal 1, @ole.header.num_sbat
|
38
|
+
assert_equal 0, @ole.header.num_mbat
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_new_without_explicit_mode
|
42
|
+
open "#{TEST_DIR}/test_word_6.doc", 'rb' do |f|
|
43
|
+
assert_equal false, Ole::Storage.new(f).writeable
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def capture_warnings
|
48
|
+
@warn = []
|
49
|
+
outer_warn = @warn
|
50
|
+
old_log = Ole::Log
|
51
|
+
old_verbose = $VERBOSE
|
52
|
+
begin
|
53
|
+
$VERBOSE = nil
|
54
|
+
Ole.const_set :Log, Object.new
|
55
|
+
# restore for the yield
|
56
|
+
$VERBOSE = old_verbose
|
57
|
+
(class << Ole::Log; self; end).send :define_method, :warn do |message|
|
58
|
+
outer_warn << message
|
59
|
+
end
|
60
|
+
yield
|
61
|
+
ensure
|
62
|
+
$VERBOSE = nil
|
63
|
+
Ole.const_set :Log, old_log
|
64
|
+
$VERBOSE = old_verbose
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def test_invalid
|
69
|
+
assert_raises Ole::Storage::FormatError do
|
70
|
+
Ole::Storage.open StringIO.new(0.chr * 1024)
|
71
|
+
end
|
72
|
+
assert_raises Ole::Storage::FormatError do
|
73
|
+
Ole::Storage.open StringIO.new(Ole::Storage::Header::MAGIC + 0.chr * 1024)
|
74
|
+
end
|
75
|
+
capture_warnings do
|
76
|
+
head = Ole::Storage::Header.new
|
77
|
+
head.threshold = 1024
|
78
|
+
assert_raises NoMethodError do
|
79
|
+
Ole::Storage.open StringIO.new(head.to_s + 0.chr * 1024)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
assert_equal ['may not be a valid OLE2 structured storage file'], @warn
|
83
|
+
end
|
84
|
+
|
85
|
+
def test_inspect
|
86
|
+
assert_match(/#<Ole::Storage io=#<File:.*?test_word_6.doc> root=#<Dirent:"Root Entry">>/, @ole.inspect)
|
87
|
+
end
|
88
|
+
|
89
|
+
def test_fat
|
90
|
+
# the fat block has all the numbers from 5..118 bar 117
|
91
|
+
bbat_table = [112] + ((5..118).to_a - [112, 117])
|
92
|
+
assert_equal bbat_table, @ole.bbat.reject { |i| i >= (1 << 32) - 3 }, 'bbat'
|
93
|
+
sbat_table = (1..43).to_a - [2, 3]
|
94
|
+
assert_equal sbat_table, @ole.sbat.reject { |i| i >= (1 << 32) - 3 }, 'sbat'
|
95
|
+
end
|
96
|
+
|
97
|
+
def test_directories
|
98
|
+
assert_equal 5, @ole.dirents.length, 'have all directories'
|
99
|
+
# a more complicated one would be good for this
|
100
|
+
assert_equal 4, @ole.root.children.length, 'properly nested directories'
|
101
|
+
end
|
102
|
+
|
103
|
+
def test_utf16_conversion
|
104
|
+
assert_equal 'Root Entry', @ole.root.name
|
105
|
+
assert_equal 'WordDocument', @ole.root.children[2].name
|
106
|
+
end
|
107
|
+
|
108
|
+
def test_read
|
109
|
+
# the regular String#hash was different on the mac, so asserting
|
110
|
+
# against full strings. switch this to sha1 instead of this fugly blob
|
111
|
+
sha1sums = %w[
|
112
|
+
d3d1cde9eb43ed4b77d197af879f5ca8b8837577
|
113
|
+
65b75cbdd1f94ade632baeeb0848dec2a342c844
|
114
|
+
cfc230ec7515892cfdb85e4a173e0ce364094970
|
115
|
+
ffd859d94647a11b693f06f092d1a2bccc59d50d
|
116
|
+
]
|
117
|
+
|
118
|
+
# test the ole storage type
|
119
|
+
type = 'Microsoft Word 6.0-Dokument'
|
120
|
+
assert_equal type, (@ole.root/"\001CompObj").read[32..-1][/([^\x00]+)/m, 1]
|
121
|
+
# i was actually not loading data correctly before, so carefully check everything here
|
122
|
+
assert_equal sha1sums, @ole.root.children.map { |child| Digest::SHA1.hexdigest child.read }
|
123
|
+
end
|
124
|
+
|
125
|
+
def test_dirent
|
126
|
+
dirent = @ole.root.children.first
|
127
|
+
assert_equal "\001Ole", dirent.name
|
128
|
+
assert_equal 20, dirent.size
|
129
|
+
assert_equal '#<Dirent:"Root Entry">', @ole.root.inspect
|
130
|
+
|
131
|
+
# exercise Dirent#[]. note that if you use a number, you get the Struct
|
132
|
+
# fields.
|
133
|
+
assert_equal dirent, @ole.root["\001Ole"]
|
134
|
+
assert_equal dirent.name_utf16, dirent[0]
|
135
|
+
assert_equal nil, @ole.root.time
|
136
|
+
|
137
|
+
assert_equal @ole.root.children, @ole.root.to_enum(:each_child).to_a
|
138
|
+
|
139
|
+
dirent.open('r') { |f| assert_equal 2, f.first_block }
|
140
|
+
dirent.open('w') { |f| }
|
141
|
+
dirent.open('a') { |f| }
|
142
|
+
end
|
143
|
+
|
144
|
+
def test_delete
|
145
|
+
dirent = @ole.root.children.first
|
146
|
+
assert_raises(ArgumentError) { @ole.root.delete nil }
|
147
|
+
assert_equal [dirent], @ole.root.children & [dirent]
|
148
|
+
assert_equal 20, dirent.size
|
149
|
+
@ole.root.delete dirent
|
150
|
+
assert_equal [], @ole.root.children & [dirent]
|
151
|
+
assert_equal 0, dirent.size
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
class TestStorageWrite < Test::Unit::TestCase
|
156
|
+
TEST_DIR = File.dirname __FILE__
|
157
|
+
|
158
|
+
def sha1 str
|
159
|
+
Digest::SHA1.hexdigest str
|
160
|
+
end
|
161
|
+
|
162
|
+
# try and test all the various things the #flush function does
|
163
|
+
def test_flush
|
164
|
+
end
|
165
|
+
|
166
|
+
# FIXME
|
167
|
+
# don't really want to lock down the actual internal api's yet. this will just
|
168
|
+
# ensure for the time being that #flush continues to work properly. need a host
|
169
|
+
# of checks involving writes that resize their file bigger/smaller, that resize
|
170
|
+
# the bats to more blocks, that resizes the sb_blocks, that has migration etc.
|
171
|
+
def test_write_hash
|
172
|
+
io = StringIO.open open("#{TEST_DIR}/test_word_6.doc", 'rb', &:read)
|
173
|
+
assert_equal '9974e354def8471225f548f82b8d81c701221af7', sha1(io.string)
|
174
|
+
Ole::Storage.open(io, :update_timestamps => false) { }
|
175
|
+
# hash changed. used to be efa8cfaf833b30b1d1d9381771ddaafdfc95305c
|
176
|
+
# thats because i now truncate the io, and am probably removing some trailing
|
177
|
+
# allocated available blocks.
|
178
|
+
assert_equal 'a39e3c4041b8a893c753d50793af8d21ca8f0a86', sha1(io.string)
|
179
|
+
# add a repack test here
|
180
|
+
Ole::Storage.open io, :update_timestamps => false, &:repack
|
181
|
+
assert_equal 'c8bb9ccacf0aaad33677e1b2a661ee6e66a48b5a', sha1(io.string)
|
182
|
+
end
|
183
|
+
|
184
|
+
def test_plain_repack
|
185
|
+
io = StringIO.open open("#{TEST_DIR}/test_word_6.doc", 'rb', &:read)
|
186
|
+
assert_equal '9974e354def8471225f548f82b8d81c701221af7', sha1(io.string)
|
187
|
+
Ole::Storage.open io, :update_timestamps => false, &:repack
|
188
|
+
# note equivalence to the above flush, repack, flush
|
189
|
+
assert_equal 'c8bb9ccacf0aaad33677e1b2a661ee6e66a48b5a', sha1(io.string)
|
190
|
+
# lets do it again using memory backing
|
191
|
+
Ole::Storage.open(io, :update_timestamps => false) { |ole| ole.repack :mem }
|
192
|
+
# note equivalence to the above flush, repack, flush
|
193
|
+
assert_equal 'c8bb9ccacf0aaad33677e1b2a661ee6e66a48b5a', sha1(io.string)
|
194
|
+
assert_raises ArgumentError do
|
195
|
+
Ole::Storage.open(io, :update_timestamps => false) { |ole| ole.repack :typo }
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
def test_create_from_scratch_hash
|
200
|
+
io = StringIO.new('')
|
201
|
+
Ole::Storage.open(io) { }
|
202
|
+
assert_equal '6bb9d6c1cdf1656375e30991948d70c5fff63d57', sha1(io.string)
|
203
|
+
# more repack test, note invariance
|
204
|
+
Ole::Storage.open io, :update_timestamps => false, &:repack
|
205
|
+
assert_equal '6bb9d6c1cdf1656375e30991948d70c5fff63d57', sha1(io.string)
|
206
|
+
end
|
207
|
+
|
208
|
+
def test_create_dirent
|
209
|
+
Ole::Storage.open StringIO.new do |ole|
|
210
|
+
dirent = Ole::Storage::Dirent.new ole, :name => 'test name', :type => :dir
|
211
|
+
assert_equal 'test name', dirent.name
|
212
|
+
assert_equal :dir, dirent.type
|
213
|
+
# for a dirent created from scratch, type_id is currently not set until serialization:
|
214
|
+
assert_equal 0, dirent.type_id
|
215
|
+
dirent.to_s
|
216
|
+
assert_equal 1, dirent.type_id
|
217
|
+
assert_raises(ArgumentError) { Ole::Storage::Dirent.new ole, :type => :bogus }
|
218
|
+
end
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|