ruby-ole 1.2.1 → 1.2.2
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +159 -13
- data/lib/ole/file_system.rb +311 -71
- data/lib/ole/property_set.rb +85 -0
- data/lib/ole/{io_helpers.rb → ranges_io.rb} +100 -50
- data/lib/ole/storage.rb +248 -285
- data/lib/ole/support.rb +112 -3
- data/lib/ole/types.rb +96 -1
- data/test/test_filesystem.rb +877 -0
- data/test/test_ranges_io.rb +100 -0
- data/test/test_storage.rb +36 -48
- data/test/test_support.rb +121 -0
- metadata +7 -3
@@ -0,0 +1,100 @@
|
|
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, :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, []
|
27
|
+
assert_equal false, f.closed?
|
28
|
+
RangesIO.open(f, [], :close_parent => true) {}
|
29
|
+
assert_equal true, f.closed?
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_basics
|
33
|
+
assert_equal 160, @io.size
|
34
|
+
assert_match %r{size=160,.*range=100\.\.200}, @io.inspect
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_truncate
|
38
|
+
assert_raises(NotImplementedError) { @io.size += 10 }
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_offset_and_size
|
42
|
+
assert_equal [[100, 100], 0], @io.offset_and_size(0)
|
43
|
+
assert_equal [[150, 50], 0], @io.offset_and_size(50)
|
44
|
+
assert_equal [[5, 5], 1], @io.offset_and_size(105)
|
45
|
+
assert_raises(ArgumentError) { @io.offset_and_size 1000 }
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_seek
|
49
|
+
@io.pos = 10
|
50
|
+
@io.seek(-100, IO::SEEK_END)
|
51
|
+
@io.seek(-10, IO::SEEK_CUR)
|
52
|
+
@io.pos += 20
|
53
|
+
assert_equal 70, @io.pos
|
54
|
+
# seeking past the end doesn't throw an exception for normal
|
55
|
+
# files, even in read mode, but RangesIO does
|
56
|
+
assert_raises(Errno::EINVAL) { @io.seek 500 }
|
57
|
+
assert_raises(Errno::EINVAL) { @io.seek(-500, IO::SEEK_END) }
|
58
|
+
assert_raises(Errno::EINVAL) { @io.seek 1, 10 }
|
59
|
+
end
|
60
|
+
|
61
|
+
def test_read
|
62
|
+
# this will map to the start of the file:
|
63
|
+
@io.pos = 100
|
64
|
+
assert_equal '#! /usr/bi', @io.read(10)
|
65
|
+
# test selection of initial range, offset within that range
|
66
|
+
pos = 80
|
67
|
+
@io.seek pos
|
68
|
+
# test advancing of pos properly, by...
|
69
|
+
chunked = (0...10).map { @io.read 10 }.join
|
70
|
+
# given the file is 160 long:
|
71
|
+
assert_equal 80, chunked.length
|
72
|
+
@io.seek pos
|
73
|
+
# comparing with a flat read
|
74
|
+
assert_equal chunked, @io.read(80)
|
75
|
+
end
|
76
|
+
|
77
|
+
# should test gets, lineno, and other IO methods we want to have
|
78
|
+
def test_gets
|
79
|
+
assert_equal "io'\n", @io.gets
|
80
|
+
end
|
81
|
+
|
82
|
+
def test_write
|
83
|
+
str = File.read "#{TEST_DIR}/test_ranges_io.rb"
|
84
|
+
@io = RangesIO.new StringIO.new(str), @io.ranges
|
85
|
+
assert_equal "io'\nrequir", str[100, 10]
|
86
|
+
@io.write 'testing testing'
|
87
|
+
assert_equal 'testing te', str[100, 10]
|
88
|
+
@io.seek 0
|
89
|
+
assert_equal 'testing te', @io.read(10)
|
90
|
+
# lets write over a range barrier
|
91
|
+
assert_equal '#! /usr/bi', str[0, 10]
|
92
|
+
assert_equal "LE__\n\n\tdef", str[195, 10]
|
93
|
+
@io.write 'x' * 100
|
94
|
+
assert_equal 'x' * 10, str[0, 10]
|
95
|
+
assert_equal "xxxxx\n\tdef", str[195, 10]
|
96
|
+
# write enough to overflow the file
|
97
|
+
assert_raises(IOError) { @io.write 'x' * 60 }
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
data/test/test_storage.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
|
-
#! /usr/bin/ruby
|
1
|
+
#! /usr/bin/ruby
|
2
2
|
|
3
|
-
|
4
|
-
$: << "#{TEST_DIR}/../lib"
|
3
|
+
$: << File.dirname(__FILE__) + '/../lib'
|
5
4
|
|
6
5
|
require 'test/unit'
|
7
6
|
require 'ole/storage'
|
@@ -14,44 +13,11 @@ require 'stringio'
|
|
14
13
|
# These tests could be a lot more complete.
|
15
14
|
#
|
16
15
|
|
17
|
-
class TestRangesIO < Test::Unit::TestCase
|
18
|
-
def setup
|
19
|
-
# why not :) ?
|
20
|
-
# repeats too
|
21
|
-
ranges = [100..200, 0..10, 100..150]
|
22
|
-
@io = RangesIO.new open("#{TEST_DIR}/test_storage.rb"), ranges, :close_parent => true
|
23
|
-
end
|
24
|
-
|
25
|
-
def teardown
|
26
|
-
@io.close
|
27
|
-
end
|
28
|
-
|
29
|
-
def test_basic
|
30
|
-
assert_equal 160, @io.size
|
31
|
-
# this will map to the start of the file:
|
32
|
-
@io.pos = 100
|
33
|
-
assert_equal '#! /usr/bi', @io.read(10)
|
34
|
-
end
|
35
|
-
|
36
|
-
# should test range_and_offset specifically
|
37
|
-
|
38
|
-
def test_reading
|
39
|
-
# test selection of initial range, offset within that range
|
40
|
-
pos = 100
|
41
|
-
@io.seek pos
|
42
|
-
# test advancing of pos properly, by...
|
43
|
-
chunked = (0...10).map { @io.read 10 }.join
|
44
|
-
# given the file is 160 long:
|
45
|
-
assert_equal 60, chunked.length
|
46
|
-
@io.seek pos
|
47
|
-
# comparing with a flat read
|
48
|
-
assert_equal chunked, @io.read(60)
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
16
|
# should test resizeable and migrateable IO.
|
53
17
|
|
54
18
|
class TestStorageRead < Test::Unit::TestCase
|
19
|
+
TEST_DIR = File.dirname __FILE__
|
20
|
+
|
55
21
|
def setup
|
56
22
|
@ole = Ole::Storage.open "#{TEST_DIR}/test_word_6.doc", 'rb'
|
57
23
|
end
|
@@ -60,6 +26,10 @@ class TestStorageRead < Test::Unit::TestCase
|
|
60
26
|
@ole.close
|
61
27
|
end
|
62
28
|
|
29
|
+
def test_invalid
|
30
|
+
assert_raises(Ole::Storage::FormatError) { Ole::Storage.open StringIO.new(0.chr * 1024) }
|
31
|
+
end
|
32
|
+
|
63
33
|
def test_header
|
64
34
|
# should have further header tests, testing the validation etc.
|
65
35
|
assert_equal 17, @ole.header.to_a.length
|
@@ -72,9 +42,9 @@ class TestStorageRead < Test::Unit::TestCase
|
|
72
42
|
def test_fat
|
73
43
|
# the fat block has all the numbers from 5..118 bar 117
|
74
44
|
bbat_table = [112] + ((5..118).to_a - [112, 117])
|
75
|
-
assert_equal bbat_table, @ole.bbat.
|
45
|
+
assert_equal bbat_table, @ole.bbat.reject { |i| i >= (1 << 32) - 3 }, 'bbat'
|
76
46
|
sbat_table = (1..43).to_a - [2, 3]
|
77
|
-
assert_equal sbat_table, @ole.sbat.
|
47
|
+
assert_equal sbat_table, @ole.sbat.reject { |i| i >= (1 << 32) - 3 }, 'sbat'
|
78
48
|
end
|
79
49
|
|
80
50
|
def test_directories
|
@@ -88,10 +58,10 @@ class TestStorageRead < Test::Unit::TestCase
|
|
88
58
|
assert_equal 'WordDocument', @ole.root.children[2].name
|
89
59
|
end
|
90
60
|
|
91
|
-
def
|
61
|
+
def test_read
|
92
62
|
# test the ole storage type
|
93
63
|
type = 'Microsoft Word 6.0-Dokument'
|
94
|
-
assert_equal type, @ole.root
|
64
|
+
assert_equal type, (@ole.root/"\001CompObj").read[/^.{32}([^\x00]+)/m, 1]
|
95
65
|
# i was actually not loading data correctly before, so carefully check everything here
|
96
66
|
hashes = [-482597081, 285782478, 134862598, -863988921]
|
97
67
|
assert_equal hashes, @ole.root.children.map { |child| child.read.hash }
|
@@ -99,9 +69,15 @@ class TestStorageRead < Test::Unit::TestCase
|
|
99
69
|
end
|
100
70
|
|
101
71
|
class TestStorageWrite < Test::Unit::TestCase
|
72
|
+
TEST_DIR = File.dirname __FILE__
|
73
|
+
|
102
74
|
def sha1 str
|
103
75
|
Digest::SHA1.hexdigest str
|
104
76
|
end
|
77
|
+
|
78
|
+
# try and test all the various things the #flush function does
|
79
|
+
def test_flush
|
80
|
+
end
|
105
81
|
|
106
82
|
# FIXME
|
107
83
|
# don't really want to lock down the actual internal api's yet. this will just
|
@@ -111,29 +87,41 @@ class TestStorageWrite < Test::Unit::TestCase
|
|
111
87
|
def test_write_hash
|
112
88
|
io = StringIO.open File.read("#{TEST_DIR}/test_word_6.doc")
|
113
89
|
assert_equal '9974e354def8471225f548f82b8d81c701221af7', sha1(io.string)
|
114
|
-
Ole::Storage.open(io) { }
|
90
|
+
Ole::Storage.open(io, :update_timestamps => false) { }
|
115
91
|
assert_equal 'efa8cfaf833b30b1d1d9381771ddaafdfc95305c', sha1(io.string)
|
116
92
|
# add a repack test here
|
117
|
-
Ole::Storage.open io, &:repack
|
93
|
+
Ole::Storage.open io, :update_timestamps => false, &:repack
|
118
94
|
assert_equal 'c8bb9ccacf0aaad33677e1b2a661ee6e66a48b5a', sha1(io.string)
|
119
95
|
end
|
120
96
|
|
121
97
|
def test_plain_repack
|
122
98
|
io = StringIO.open File.read("#{TEST_DIR}/test_word_6.doc")
|
123
99
|
assert_equal '9974e354def8471225f548f82b8d81c701221af7', sha1(io.string)
|
124
|
-
Ole::Storage.open io, &:repack
|
100
|
+
Ole::Storage.open io, :update_timestamps => false, &:repack
|
125
101
|
# note equivalence to the above flush, repack, flush
|
126
102
|
assert_equal 'c8bb9ccacf0aaad33677e1b2a661ee6e66a48b5a', sha1(io.string)
|
127
103
|
end
|
128
104
|
|
129
105
|
def test_create_from_scratch_hash
|
130
106
|
io = StringIO.new
|
131
|
-
Ole::Storage.
|
107
|
+
Ole::Storage.open(io) { }
|
132
108
|
assert_equal '6bb9d6c1cdf1656375e30991948d70c5fff63d57', sha1(io.string)
|
133
109
|
# more repack test, note invariance
|
134
|
-
Ole::Storage.open io, &:repack
|
110
|
+
Ole::Storage.open io, :update_timestamps => false, &:repack
|
135
111
|
assert_equal '6bb9d6c1cdf1656375e30991948d70c5fff63d57', sha1(io.string)
|
136
112
|
end
|
137
|
-
end
|
138
113
|
|
114
|
+
def test_create_dirent
|
115
|
+
Ole::Storage.open StringIO.new do |ole|
|
116
|
+
dirent = Ole::Storage::Dirent.new ole, :name => 'test name', :type => :dir
|
117
|
+
assert_equal 'test name', dirent.name
|
118
|
+
assert_equal :dir, dirent.type
|
119
|
+
# for a dirent created from scratch, type_id is currently not set until serialization:
|
120
|
+
assert_equal 0, dirent.type_id
|
121
|
+
dirent.to_s
|
122
|
+
assert_equal 1, dirent.type_id
|
123
|
+
assert_raises(ArgumentError) { Ole::Storage::Dirent.new ole, :type => :bogus }
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
139
127
|
|
@@ -0,0 +1,121 @@
|
|
1
|
+
#! /usr/bin/ruby
|
2
|
+
|
3
|
+
$: << File.dirname(__FILE__) + '/../lib'
|
4
|
+
|
5
|
+
require 'test/unit'
|
6
|
+
require 'ole/support'
|
7
|
+
|
8
|
+
class TestSupport < Test::Unit::TestCase
|
9
|
+
TEST_DIR = File.dirname __FILE__
|
10
|
+
|
11
|
+
def test_file
|
12
|
+
assert_equal 4096, open("#{TEST_DIR}/oleWithDirs.ole") { |f| f.size }
|
13
|
+
# point is to have same interface as:
|
14
|
+
assert_equal 4096, StringIO.open(File.read("#{TEST_DIR}/oleWithDirs.ole")).size
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_enumerable
|
18
|
+
expect = {0 => [2, 4], 1 => [1, 3]}
|
19
|
+
assert_equal expect, [1, 2, 3, 4].group_by { |i| i & 1 }
|
20
|
+
assert_equal 10, [1, 2, 3, 4].sum
|
21
|
+
assert_equal %w[1 2 3 4], [1, 2, 3, 4].map(&:to_s)
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_logger
|
25
|
+
io = StringIO.new
|
26
|
+
log = Logger.new_with_callstack io
|
27
|
+
log.warn 'test'
|
28
|
+
expect = %r{^\[\d\d:\d\d:\d\d \./test/test_support\.rb:\d+:test_logger\]\nWARN test$}
|
29
|
+
assert_match expect, io.string.chomp
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_io
|
33
|
+
str = 'a' * 5000 + 'b'
|
34
|
+
src, dst = StringIO.new(str), StringIO.new
|
35
|
+
IO.copy src, dst
|
36
|
+
assert_equal str, dst.string
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_string
|
40
|
+
str = "aa aa ||| aa aa"
|
41
|
+
assert_equal [0, 3, 10, 13], str.indexes('aa')
|
42
|
+
# this is mostly a check that regexp quote is used.
|
43
|
+
assert_equal [6, 7, 8], str.indexes('|')
|
44
|
+
# note not [6, 7] - no overlaps
|
45
|
+
assert_equal [6], str.indexes('||')
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
class TestRecursivelyEnumerable < Test::Unit::TestCase
|
50
|
+
class Container
|
51
|
+
include RecursivelyEnumerable
|
52
|
+
|
53
|
+
def initialize *children
|
54
|
+
@children = children
|
55
|
+
end
|
56
|
+
|
57
|
+
def each_child(&block)
|
58
|
+
@children.each(&block)
|
59
|
+
end
|
60
|
+
|
61
|
+
def inspect
|
62
|
+
"#<Container>"
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def setup
|
67
|
+
@root = Container.new(
|
68
|
+
Container.new(1),
|
69
|
+
Container.new(2,
|
70
|
+
Container.new(
|
71
|
+
Container.new(3)
|
72
|
+
)
|
73
|
+
),
|
74
|
+
4,
|
75
|
+
Container.new()
|
76
|
+
)
|
77
|
+
end
|
78
|
+
|
79
|
+
def test_find
|
80
|
+
i = 0
|
81
|
+
found = @root.recursive.find do |obj|
|
82
|
+
i += 1
|
83
|
+
obj == 4
|
84
|
+
end
|
85
|
+
assert_equal found, 4
|
86
|
+
assert_equal 9, i
|
87
|
+
|
88
|
+
i = 0
|
89
|
+
found = @root.recursive(:breadth_first).find do |obj|
|
90
|
+
i += 1
|
91
|
+
obj == 4
|
92
|
+
end
|
93
|
+
assert_equal found, 4
|
94
|
+
assert_equal 4, i
|
95
|
+
|
96
|
+
# this is to make sure we hit the breadth first child cache
|
97
|
+
i = 0
|
98
|
+
found = @root.recursive(:breadth_first).find do |obj|
|
99
|
+
i += 1
|
100
|
+
obj == 3
|
101
|
+
end
|
102
|
+
assert_equal found, 3
|
103
|
+
assert_equal 10, i
|
104
|
+
end
|
105
|
+
|
106
|
+
def test_to_tree
|
107
|
+
assert_equal <<-'end', @root.to_tree
|
108
|
+
- #<Container>
|
109
|
+
|- #<Container>
|
110
|
+
| \- 1
|
111
|
+
|- #<Container>
|
112
|
+
| |- 2
|
113
|
+
| \- #<Container>
|
114
|
+
| \- #<Container>
|
115
|
+
| \- 3
|
116
|
+
|- 4
|
117
|
+
\- #<Container>
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
metadata
CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.0
|
|
3
3
|
specification_version: 1
|
4
4
|
name: ruby-ole
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 1.2.
|
7
|
-
date: 2007-
|
6
|
+
version: 1.2.2
|
7
|
+
date: 2007-11-06 00:00:00 +11:00
|
8
8
|
summary: Ruby OLE library.
|
9
9
|
require_paths:
|
10
10
|
- lib
|
@@ -31,13 +31,17 @@ authors:
|
|
31
31
|
files:
|
32
32
|
- Rakefile
|
33
33
|
- bin/oletool
|
34
|
+
- lib/ole/ranges_io.rb
|
35
|
+
- lib/ole/property_set.rb
|
34
36
|
- lib/ole/types.rb
|
35
37
|
- lib/ole/file_system.rb
|
36
38
|
- lib/ole/support.rb
|
37
39
|
- lib/ole/storage.rb
|
38
|
-
- lib/ole/io_helpers.rb
|
39
40
|
- lib/ole/base.rb
|
41
|
+
- test/test_ranges_io.rb
|
42
|
+
- test/test_support.rb
|
40
43
|
- test/test_storage.rb
|
44
|
+
- test/test_filesystem.rb
|
41
45
|
- test/test_word_6.doc
|
42
46
|
- test/test_word_95.doc
|
43
47
|
- test/test_word_97.doc
|