ruby-ole 1.2.1 → 1.2.2
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.
- 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
|