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
@@ -0,0 +1,202 @@
|
|
1
|
+
# encoding: ASCII-8BIT
|
2
|
+
|
3
|
+
module Ole
|
4
|
+
module Types
|
5
|
+
#
|
6
|
+
# The PropertySet class currently supports readonly access to the properties
|
7
|
+
# serialized in "property set" streams, such as the file "\005SummaryInformation",
|
8
|
+
# in OLE files.
|
9
|
+
#
|
10
|
+
# Think it has its roots in MFC property set serialization.
|
11
|
+
#
|
12
|
+
# See http://poi.apache.org/hpsf/internals.html for details
|
13
|
+
#
|
14
|
+
class PropertySet
|
15
|
+
HEADER_SIZE = 28
|
16
|
+
HEADER_PACK = "vvVa#{Clsid::SIZE}V"
|
17
|
+
OS_MAP = {
|
18
|
+
0 => :win16,
|
19
|
+
1 => :mac,
|
20
|
+
2 => :win32,
|
21
|
+
0x20001 => :ooffice, # open office on linux...
|
22
|
+
}
|
23
|
+
|
24
|
+
# define a smattering of the property set guids.
|
25
|
+
DATA = {
|
26
|
+
Clsid.parse('{f29f85e0-4ff9-1068-ab91-08002b27b3d9}') => ['FMTID_SummaryInformation', {
|
27
|
+
2 => 'doc_title',
|
28
|
+
3 => 'doc_subject',
|
29
|
+
4 => 'doc_author',
|
30
|
+
5 => 'doc_keywords',
|
31
|
+
6 => 'doc_comments',
|
32
|
+
7 => 'doc_template',
|
33
|
+
8 => 'doc_last_author',
|
34
|
+
9 => 'doc_rev_number',
|
35
|
+
10 => 'doc_edit_time',
|
36
|
+
11 => 'doc_last_printed',
|
37
|
+
12 => 'doc_created_time',
|
38
|
+
13 => 'doc_last_saved_time',
|
39
|
+
14 => 'doc_page_count',
|
40
|
+
15 => 'doc_word_count',
|
41
|
+
16 => 'doc_char_count',
|
42
|
+
18 => 'doc_app_name',
|
43
|
+
19 => 'security'
|
44
|
+
}],
|
45
|
+
Clsid.parse('{d5cdd502-2e9c-101b-9397-08002b2cf9ae}') => ['FMTID_DocSummaryInfo', {
|
46
|
+
2 => 'doc_category',
|
47
|
+
3 => 'doc_presentation_target',
|
48
|
+
4 => 'doc_byte_count',
|
49
|
+
5 => 'doc_line_count',
|
50
|
+
6 => 'doc_para_count',
|
51
|
+
7 => 'doc_slide_count',
|
52
|
+
8 => 'doc_note_count',
|
53
|
+
9 => 'doc_hidden_count',
|
54
|
+
10 => 'mmclips',
|
55
|
+
11 => 'scale_crop',
|
56
|
+
12 => 'heading_pairs',
|
57
|
+
13 => 'doc_part_titles',
|
58
|
+
14 => 'doc_manager',
|
59
|
+
15 => 'doc_company',
|
60
|
+
16 => 'links_up_to_date'
|
61
|
+
}],
|
62
|
+
Clsid.parse('{d5cdd505-2e9c-101b-9397-08002b2cf9ae}') => ['FMTID_UserDefinedProperties', {}]
|
63
|
+
}
|
64
|
+
|
65
|
+
# create an inverted map of names to guid/key pairs
|
66
|
+
PROPERTY_MAP = DATA.inject({}) do |h1, (guid, data)|
|
67
|
+
data[1].inject(h1) { |h2, (id, name)| h2.update name => [guid, id] }
|
68
|
+
end
|
69
|
+
|
70
|
+
module Constants
|
71
|
+
DATA.each { |guid, (name, _)| const_set name, guid }
|
72
|
+
end
|
73
|
+
|
74
|
+
include Constants
|
75
|
+
include Enumerable
|
76
|
+
|
77
|
+
class Section
|
78
|
+
include Variant::Constants
|
79
|
+
include Enumerable
|
80
|
+
|
81
|
+
SIZE = Clsid::SIZE + 4
|
82
|
+
PACK = "a#{Clsid::SIZE}v"
|
83
|
+
|
84
|
+
attr_accessor :guid, :offset
|
85
|
+
attr_reader :length
|
86
|
+
|
87
|
+
def initialize str, property_set
|
88
|
+
@property_set = property_set
|
89
|
+
@guid, @offset = str.unpack PACK
|
90
|
+
self.guid = Clsid.load guid
|
91
|
+
load_header
|
92
|
+
end
|
93
|
+
|
94
|
+
def io
|
95
|
+
@property_set.io
|
96
|
+
end
|
97
|
+
|
98
|
+
def load_header
|
99
|
+
io.seek offset
|
100
|
+
@byte_size, @length = io.read(8).unpack 'V2'
|
101
|
+
end
|
102
|
+
|
103
|
+
def [] key
|
104
|
+
each_raw do |id, property_offset|
|
105
|
+
return read_property(property_offset).last if key == id
|
106
|
+
end
|
107
|
+
nil
|
108
|
+
end
|
109
|
+
|
110
|
+
def []= key, value
|
111
|
+
raise NotImplementedError, 'section writes not yet implemented'
|
112
|
+
end
|
113
|
+
|
114
|
+
def each
|
115
|
+
each_raw do |id, property_offset|
|
116
|
+
yield id, read_property(property_offset).last
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
private
|
121
|
+
|
122
|
+
def each_raw
|
123
|
+
io.seek offset + 8
|
124
|
+
io.read(length * 8).each_chunk(8) { |str| yield(*str.unpack('V2')) }
|
125
|
+
end
|
126
|
+
|
127
|
+
def read_property property_offset
|
128
|
+
io.seek offset + property_offset
|
129
|
+
type, value = io.read(8).unpack('V2')
|
130
|
+
# is the method of serialization here custom?
|
131
|
+
case type
|
132
|
+
when VT_LPSTR, VT_LPWSTR
|
133
|
+
value = Variant.load type, io.read(value)
|
134
|
+
# ....
|
135
|
+
end
|
136
|
+
[type, value]
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
attr_reader :io, :signature, :unknown, :os, :guid, :sections
|
141
|
+
|
142
|
+
def initialize io
|
143
|
+
@io = io
|
144
|
+
load_header io.read(HEADER_SIZE)
|
145
|
+
load_section_list io.read(@num_sections * Section::SIZE)
|
146
|
+
# expect no gap between last section and start of data.
|
147
|
+
#Log.warn "gap between section list and property data" unless io.pos == @sections.map(&:offset).min
|
148
|
+
end
|
149
|
+
|
150
|
+
def load_header str
|
151
|
+
@signature, @unknown, @os_id, @guid, @num_sections = str.unpack HEADER_PACK
|
152
|
+
# should i check that unknown == 0? it usually is. so is the guid actually
|
153
|
+
@guid = Clsid.load @guid
|
154
|
+
@os = OS_MAP[@os_id] || Log.warn("unknown operating system id #{@os_id}")
|
155
|
+
end
|
156
|
+
|
157
|
+
def load_section_list str
|
158
|
+
@sections = str.to_enum(:each_chunk, Section::SIZE).map { |s| Section.new s, self }
|
159
|
+
end
|
160
|
+
|
161
|
+
def [] key
|
162
|
+
pair = PROPERTY_MAP[key.to_s] or return nil
|
163
|
+
section = @sections.find { |s| s.guid == pair.first } or return nil
|
164
|
+
section[pair.last]
|
165
|
+
end
|
166
|
+
|
167
|
+
def []= key, value
|
168
|
+
pair = PROPERTY_MAP[key.to_s] or return nil
|
169
|
+
section = @sections.find { |s| s.guid == pair.first } or return nil
|
170
|
+
section[pair.last] = value
|
171
|
+
end
|
172
|
+
|
173
|
+
def method_missing name, *args, &block
|
174
|
+
if name.to_s =~ /(.*)=$/
|
175
|
+
return super unless args.length == 1
|
176
|
+
return super unless PROPERTY_MAP[$1]
|
177
|
+
self[$1] = args.first
|
178
|
+
else
|
179
|
+
return super unless args.length == 0
|
180
|
+
return super unless PROPERTY_MAP[name.to_s]
|
181
|
+
self[name]
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
def each
|
186
|
+
@sections.each do |section|
|
187
|
+
next unless pair = DATA[section.guid]
|
188
|
+
map = pair.last
|
189
|
+
section.each do |id, value|
|
190
|
+
name = map[id] or next
|
191
|
+
yield name, value
|
192
|
+
end
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
def to_h
|
197
|
+
inject({}) { |hash, (name, value)| hash.update name.to_sym => value }
|
198
|
+
end
|
199
|
+
end
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
data/ruby-ole.gemspec
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
$:.unshift File.dirname(__FILE__) + '/lib'
|
2
|
+
require 'ole/storage/version'
|
3
|
+
|
4
|
+
PKG_NAME = 'keeguon-ruby-ole'
|
5
|
+
PKG_VERSION = Ole::Storage::VERSION
|
6
|
+
|
7
|
+
Gem::Specification.new do |s|
|
8
|
+
s.name = PKG_NAME
|
9
|
+
s.version = PKG_VERSION
|
10
|
+
s.summary = %q{Ruby OLE library.}
|
11
|
+
s.description = %q{A library for easy read/write access to OLE compound documents for Ruby.}
|
12
|
+
s.authors = ['Charles Lowe', 'Félix Bellanger']
|
13
|
+
s.email = %q{aquasync@gmail.com}
|
14
|
+
s.homepage = %q{http://code.google.com/p/ruby-ole}
|
15
|
+
s.rubyforge_project = %q{ruby-ole}
|
16
|
+
|
17
|
+
s.executables = ['oletool']
|
18
|
+
s.files = ['README', 'COPYING', 'Rakefile', 'ChangeLog', 'ruby-ole.gemspec']
|
19
|
+
s.files += Dir.glob('lib/**/*.rb')
|
20
|
+
s.files += Dir.glob('test/{test_*.rb,*.doc,oleWithDirs.ole,test_SummaryInformation}')
|
21
|
+
s.files += Dir.glob('bin/*')
|
22
|
+
s.test_files = Dir.glob('test/test_*.rb')
|
23
|
+
|
24
|
+
s.has_rdoc = true
|
25
|
+
s.extra_rdoc_files = ['README', 'ChangeLog']
|
26
|
+
s.rdoc_options += [
|
27
|
+
'--main', 'README',
|
28
|
+
'--title', "#{PKG_NAME} documentation",
|
29
|
+
'--tab-width', '2'
|
30
|
+
]
|
31
|
+
end
|
32
|
+
|
Binary file
|
data/test/test.doc
ADDED
Binary file
|
Binary file
|
@@ -0,0 +1,932 @@
|
|
1
|
+
#! /usr/bin/ruby
|
2
|
+
# encoding: ASCII-8BIT
|
3
|
+
|
4
|
+
#
|
5
|
+
# = NOTE
|
6
|
+
#
|
7
|
+
# This file was originally called "zipfilesystemtest.rb", and was part of
|
8
|
+
# the test case for the "rubyzip" project.
|
9
|
+
#
|
10
|
+
# As I borrowed the smart idea of using a filesystem style interface, it
|
11
|
+
# only seemed right that I appropriate the test case in addition :). It is
|
12
|
+
# a testament to the cleanliness of the original api & tests as to how
|
13
|
+
# easy it was to repurpose it for this project.
|
14
|
+
#
|
15
|
+
# I have made some modifications to the file due to some differences in the
|
16
|
+
# capabilities of zip vs ole, but the majority of the copyright and credit
|
17
|
+
# still goes to Thomas. His original copyright message:
|
18
|
+
#
|
19
|
+
# Copyright (C) 2002, 2003 Thomas Sondergaard
|
20
|
+
# rubyzip is free software; you can redistribute it and/or
|
21
|
+
# modify it under the terms of the ruby license.
|
22
|
+
#
|
23
|
+
|
24
|
+
TEST_DIR = File.dirname __FILE__
|
25
|
+
$:.unshift "#{TEST_DIR}/../lib"
|
26
|
+
|
27
|
+
require 'ole/storage'
|
28
|
+
require 'test/unit'
|
29
|
+
|
30
|
+
module ExtraAssertions
|
31
|
+
|
32
|
+
def assert_forwarded(anObject, method, retVal, *expectedArgs)
|
33
|
+
callArgs = nil
|
34
|
+
setCallArgsProc = proc { |args| callArgs = args }
|
35
|
+
anObject.instance_eval <<-"end_eval"
|
36
|
+
alias #{method}_org #{method}
|
37
|
+
def #{method}(*args)
|
38
|
+
ObjectSpace._id2ref(#{setCallArgsProc.object_id}).call(args)
|
39
|
+
ObjectSpace._id2ref(#{retVal.object_id})
|
40
|
+
end
|
41
|
+
end_eval
|
42
|
+
|
43
|
+
assert_equal(retVal, yield) # Invoke test
|
44
|
+
assert_equal(expectedArgs, callArgs)
|
45
|
+
ensure
|
46
|
+
anObject.instance_eval "alias #{method} #{method}_org"
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
|
51
|
+
class OleFsNonmutatingTest < Test::Unit::TestCase
|
52
|
+
def setup
|
53
|
+
@ole = Ole::Storage.open TEST_DIR + '/oleWithDirs.ole', 'rb'
|
54
|
+
end
|
55
|
+
|
56
|
+
def teardown
|
57
|
+
@ole.close if @ole
|
58
|
+
end
|
59
|
+
|
60
|
+
=begin
|
61
|
+
def test_umask
|
62
|
+
assert_equal(File.umask, @ole.file.umask)
|
63
|
+
@ole.file.umask(0006)
|
64
|
+
end
|
65
|
+
=end
|
66
|
+
|
67
|
+
def test_exists?
|
68
|
+
assert(! @ole.file.exists?("notAFile"))
|
69
|
+
assert(@ole.file.exists?("file1"))
|
70
|
+
assert(@ole.file.exists?("dir1"))
|
71
|
+
assert(@ole.file.exists?("dir1/"))
|
72
|
+
assert(@ole.file.exists?("dir1/file12"))
|
73
|
+
assert(@ole.file.exist?("dir1/file12")) # notice, tests exist? alias of exists? !
|
74
|
+
|
75
|
+
@ole.dir.chdir "dir1/"
|
76
|
+
assert(!@ole.file.exists?("file1"))
|
77
|
+
assert(@ole.file.exists?("file12"))
|
78
|
+
end
|
79
|
+
|
80
|
+
def test_open_read
|
81
|
+
blockCalled = false
|
82
|
+
@ole.file.open("file1", "r") {
|
83
|
+
|f|
|
84
|
+
blockCalled = true
|
85
|
+
assert_equal("this is the entry 'file1' in my test archive!",
|
86
|
+
f.readline.chomp)
|
87
|
+
}
|
88
|
+
assert(blockCalled)
|
89
|
+
|
90
|
+
blockCalled = false
|
91
|
+
@ole.dir.chdir "dir2"
|
92
|
+
@ole.file.open("file21", "r") {
|
93
|
+
|f|
|
94
|
+
blockCalled = true
|
95
|
+
assert_equal("this is the entry 'dir2/file21' in my test archive!",
|
96
|
+
f.readline.chomp)
|
97
|
+
}
|
98
|
+
assert(blockCalled)
|
99
|
+
@ole.dir.chdir "/"
|
100
|
+
|
101
|
+
assert_raise(Errno::ENOENT) {
|
102
|
+
@ole.file.open("noSuchEntry")
|
103
|
+
}
|
104
|
+
|
105
|
+
begin
|
106
|
+
is = @ole.file.open("file1")
|
107
|
+
assert_equal("this is the entry 'file1' in my test archive!",
|
108
|
+
is.readline.chomp)
|
109
|
+
ensure
|
110
|
+
is.close if is
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
def test_new
|
115
|
+
begin
|
116
|
+
is = @ole.file.new("file1")
|
117
|
+
assert_equal("this is the entry 'file1' in my test archive!",
|
118
|
+
is.readline.chomp)
|
119
|
+
ensure
|
120
|
+
is.close if is
|
121
|
+
end
|
122
|
+
begin
|
123
|
+
is = @ole.file.new("file1") {
|
124
|
+
fail "should not call block"
|
125
|
+
}
|
126
|
+
ensure
|
127
|
+
is.close if is
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
# currently commented out because I've taken the approach of
|
132
|
+
# using implicit NameError rather than explicit NotImplementedError.
|
133
|
+
=begin
|
134
|
+
def test_symlink
|
135
|
+
assert_raise(NotImplementedError) {
|
136
|
+
@ole.file.symlink("file1", "aSymlink")
|
137
|
+
}
|
138
|
+
end
|
139
|
+
=end
|
140
|
+
|
141
|
+
def test_size
|
142
|
+
assert_raise(Errno::ENOENT) { @ole.file.size("notAFile") }
|
143
|
+
assert_equal(72, @ole.file.size("file1"))
|
144
|
+
assert_equal(0, @ole.file.size("dir2/dir21"))
|
145
|
+
|
146
|
+
assert_equal(72, @ole.file.stat("file1").size)
|
147
|
+
assert_equal(0, @ole.file.stat("dir2/dir21").size)
|
148
|
+
end
|
149
|
+
|
150
|
+
def test_size?
|
151
|
+
assert_equal(nil, @ole.file.size?("notAFile"))
|
152
|
+
assert_equal(72, @ole.file.size?("file1"))
|
153
|
+
assert_equal(nil, @ole.file.size?("dir2/dir21"))
|
154
|
+
|
155
|
+
assert_equal(72, @ole.file.stat("file1").size?)
|
156
|
+
assert_equal(nil, @ole.file.stat("dir2/dir21").size?)
|
157
|
+
end
|
158
|
+
|
159
|
+
def test_file?
|
160
|
+
assert(@ole.file.file?("file1"))
|
161
|
+
assert(@ole.file.file?("dir2/file21"))
|
162
|
+
assert(! @ole.file.file?("dir1"))
|
163
|
+
assert(! @ole.file.file?("dir1/dir11"))
|
164
|
+
|
165
|
+
assert(@ole.file.stat("file1").file?)
|
166
|
+
assert(@ole.file.stat("dir2/file21").file?)
|
167
|
+
assert(! @ole.file.stat("dir1").file?)
|
168
|
+
assert(! @ole.file.stat("dir1/dir11").file?)
|
169
|
+
end
|
170
|
+
|
171
|
+
=begin
|
172
|
+
include ExtraAssertions
|
173
|
+
|
174
|
+
def test_dirname
|
175
|
+
assert_forwarded(File, :dirname, "retVal", "a/b/c/d") {
|
176
|
+
@ole.file.dirname("a/b/c/d")
|
177
|
+
}
|
178
|
+
end
|
179
|
+
|
180
|
+
def test_basename
|
181
|
+
assert_forwarded(File, :basename, "retVal", "a/b/c/d") {
|
182
|
+
@ole.file.basename("a/b/c/d")
|
183
|
+
}
|
184
|
+
end
|
185
|
+
|
186
|
+
def test_split
|
187
|
+
assert_forwarded(File, :split, "retVal", "a/b/c/d") {
|
188
|
+
@ole.file.split("a/b/c/d")
|
189
|
+
}
|
190
|
+
end
|
191
|
+
|
192
|
+
def test_join
|
193
|
+
assert_equal("a/b/c", @ole.file.join("a/b", "c"))
|
194
|
+
assert_equal("a/b/c/d", @ole.file.join("a/b", "c/d"))
|
195
|
+
assert_equal("/c/d", @ole.file.join("", "c/d"))
|
196
|
+
assert_equal("a/b/c/d", @ole.file.join("a", "b", "c", "d"))
|
197
|
+
end
|
198
|
+
|
199
|
+
def test_utime
|
200
|
+
t_now = Time.now
|
201
|
+
t_bak = @ole.file.mtime("file1")
|
202
|
+
@ole.file.utime(t_now, "file1")
|
203
|
+
assert_equal(t_now, @ole.file.mtime("file1"))
|
204
|
+
@ole.file.utime(t_bak, "file1")
|
205
|
+
assert_equal(t_bak, @ole.file.mtime("file1"))
|
206
|
+
end
|
207
|
+
|
208
|
+
|
209
|
+
def assert_always_false(operation)
|
210
|
+
assert(! @ole.file.send(operation, "noSuchFile"))
|
211
|
+
assert(! @ole.file.send(operation, "file1"))
|
212
|
+
assert(! @ole.file.send(operation, "dir1"))
|
213
|
+
assert(! @ole.file.stat("file1").send(operation))
|
214
|
+
assert(! @ole.file.stat("dir1").send(operation))
|
215
|
+
end
|
216
|
+
|
217
|
+
def assert_true_if_entry_exists(operation)
|
218
|
+
assert(! @ole.file.send(operation, "noSuchFile"))
|
219
|
+
assert(@ole.file.send(operation, "file1"))
|
220
|
+
assert(@ole.file.send(operation, "dir1"))
|
221
|
+
assert(@ole.file.stat("file1").send(operation))
|
222
|
+
assert(@ole.file.stat("dir1").send(operation))
|
223
|
+
end
|
224
|
+
|
225
|
+
def test_pipe?
|
226
|
+
assert_always_false(:pipe?)
|
227
|
+
end
|
228
|
+
|
229
|
+
def test_blockdev?
|
230
|
+
assert_always_false(:blockdev?)
|
231
|
+
end
|
232
|
+
|
233
|
+
def test_symlink?
|
234
|
+
assert_always_false(:symlink?)
|
235
|
+
end
|
236
|
+
|
237
|
+
def test_socket?
|
238
|
+
assert_always_false(:socket?)
|
239
|
+
end
|
240
|
+
|
241
|
+
def test_chardev?
|
242
|
+
assert_always_false(:chardev?)
|
243
|
+
end
|
244
|
+
|
245
|
+
def test_truncate
|
246
|
+
assert_raise(StandardError, "truncate not supported") {
|
247
|
+
@ole.file.truncate("file1", 100)
|
248
|
+
}
|
249
|
+
end
|
250
|
+
|
251
|
+
def assert_e_n_o_e_n_t(operation, args = ["NoSuchFile"])
|
252
|
+
assert_raise(Errno::ENOENT) {
|
253
|
+
@ole.file.send(operation, *args)
|
254
|
+
}
|
255
|
+
end
|
256
|
+
|
257
|
+
def test_ftype
|
258
|
+
assert_e_n_o_e_n_t(:ftype)
|
259
|
+
assert_equal("file", @ole.file.ftype("file1"))
|
260
|
+
assert_equal("directory", @ole.file.ftype("dir1/dir11"))
|
261
|
+
assert_equal("directory", @ole.file.ftype("dir1/dir11/"))
|
262
|
+
end
|
263
|
+
=end
|
264
|
+
|
265
|
+
def test_directory?
|
266
|
+
assert(! @ole.file.directory?("notAFile"))
|
267
|
+
assert(! @ole.file.directory?("file1"))
|
268
|
+
assert(! @ole.file.directory?("dir1/file11"))
|
269
|
+
assert(@ole.file.directory?("dir1"))
|
270
|
+
assert(@ole.file.directory?("dir1/"))
|
271
|
+
assert(@ole.file.directory?("dir2/dir21"))
|
272
|
+
|
273
|
+
assert(! @ole.file.stat("file1").directory?)
|
274
|
+
assert(! @ole.file.stat("dir1/file11").directory?)
|
275
|
+
assert(@ole.file.stat("dir1").directory?)
|
276
|
+
assert(@ole.file.stat("dir1/").directory?)
|
277
|
+
assert(@ole.file.stat("dir2/dir21").directory?)
|
278
|
+
end
|
279
|
+
|
280
|
+
=begin
|
281
|
+
def test_chown
|
282
|
+
assert_equal(2, @ole.file.chown(1,2, "dir1", "file1"))
|
283
|
+
assert_equal(1, @ole.file.stat("dir1").uid)
|
284
|
+
assert_equal(2, @ole.file.stat("dir1").gid)
|
285
|
+
assert_equal(2, @ole.file.chown(nil, nil, "dir1", "file1"))
|
286
|
+
end
|
287
|
+
|
288
|
+
def test_zero?
|
289
|
+
assert(! @ole.file.zero?("notAFile"))
|
290
|
+
assert(! @ole.file.zero?("file1"))
|
291
|
+
assert(@ole.file.zero?("dir1"))
|
292
|
+
blockCalled = false
|
293
|
+
ZipFile.open("data/generated/5entry.zip") {
|
294
|
+
|zf|
|
295
|
+
blockCalled = true
|
296
|
+
assert(zf.file.zero?("data/generated/empty.txt"))
|
297
|
+
}
|
298
|
+
assert(blockCalled)
|
299
|
+
|
300
|
+
assert(! @ole.file.stat("file1").zero?)
|
301
|
+
assert(@ole.file.stat("dir1").zero?)
|
302
|
+
blockCalled = false
|
303
|
+
ZipFile.open("data/generated/5entry.zip") {
|
304
|
+
|zf|
|
305
|
+
blockCalled = true
|
306
|
+
assert(zf.file.stat("data/generated/empty.txt").zero?)
|
307
|
+
}
|
308
|
+
assert(blockCalled)
|
309
|
+
end
|
310
|
+
=end
|
311
|
+
|
312
|
+
def test_expand_path
|
313
|
+
assert_equal("/", @ole.file.expand_path("."))
|
314
|
+
@ole.dir.chdir "dir1"
|
315
|
+
assert_equal("/dir1", @ole.file.expand_path("."))
|
316
|
+
assert_equal("/dir1/file12", @ole.file.expand_path("file12"))
|
317
|
+
assert_equal("/", @ole.file.expand_path(".."))
|
318
|
+
assert_equal("/dir2/dir21", @ole.file.expand_path("../dir2/dir21"))
|
319
|
+
end
|
320
|
+
|
321
|
+
=begin
|
322
|
+
def test_mtime
|
323
|
+
assert_equal(Time.at(1027694306),
|
324
|
+
@ole.file.mtime("dir2/file21"))
|
325
|
+
assert_equal(Time.at(1027690863),
|
326
|
+
@ole.file.mtime("dir2/dir21"))
|
327
|
+
assert_raise(Errno::ENOENT) {
|
328
|
+
@ole.file.mtime("noSuchEntry")
|
329
|
+
}
|
330
|
+
|
331
|
+
assert_equal(Time.at(1027694306),
|
332
|
+
@ole.file.stat("dir2/file21").mtime)
|
333
|
+
assert_equal(Time.at(1027690863),
|
334
|
+
@ole.file.stat("dir2/dir21").mtime)
|
335
|
+
end
|
336
|
+
|
337
|
+
def test_ctime
|
338
|
+
assert_nil(@ole.file.ctime("file1"))
|
339
|
+
assert_nil(@ole.file.stat("file1").ctime)
|
340
|
+
end
|
341
|
+
|
342
|
+
def test_atime
|
343
|
+
assert_nil(@ole.file.atime("file1"))
|
344
|
+
assert_nil(@ole.file.stat("file1").atime)
|
345
|
+
end
|
346
|
+
|
347
|
+
def test_readable?
|
348
|
+
assert(! @ole.file.readable?("noSuchFile"))
|
349
|
+
assert(@ole.file.readable?("file1"))
|
350
|
+
assert(@ole.file.readable?("dir1"))
|
351
|
+
assert(@ole.file.stat("file1").readable?)
|
352
|
+
assert(@ole.file.stat("dir1").readable?)
|
353
|
+
end
|
354
|
+
|
355
|
+
def test_readable_real?
|
356
|
+
assert(! @ole.file.readable_real?("noSuchFile"))
|
357
|
+
assert(@ole.file.readable_real?("file1"))
|
358
|
+
assert(@ole.file.readable_real?("dir1"))
|
359
|
+
assert(@ole.file.stat("file1").readable_real?)
|
360
|
+
assert(@ole.file.stat("dir1").readable_real?)
|
361
|
+
end
|
362
|
+
|
363
|
+
def test_writable?
|
364
|
+
assert(! @ole.file.writable?("noSuchFile"))
|
365
|
+
assert(@ole.file.writable?("file1"))
|
366
|
+
assert(@ole.file.writable?("dir1"))
|
367
|
+
assert(@ole.file.stat("file1").writable?)
|
368
|
+
assert(@ole.file.stat("dir1").writable?)
|
369
|
+
end
|
370
|
+
|
371
|
+
def test_writable_real?
|
372
|
+
assert(! @ole.file.writable_real?("noSuchFile"))
|
373
|
+
assert(@ole.file.writable_real?("file1"))
|
374
|
+
assert(@ole.file.writable_real?("dir1"))
|
375
|
+
assert(@ole.file.stat("file1").writable_real?)
|
376
|
+
assert(@ole.file.stat("dir1").writable_real?)
|
377
|
+
end
|
378
|
+
|
379
|
+
def test_executable?
|
380
|
+
assert(! @ole.file.executable?("noSuchFile"))
|
381
|
+
assert(! @ole.file.executable?("file1"))
|
382
|
+
assert(@ole.file.executable?("dir1"))
|
383
|
+
assert(! @ole.file.stat("file1").executable?)
|
384
|
+
assert(@ole.file.stat("dir1").executable?)
|
385
|
+
end
|
386
|
+
|
387
|
+
def test_executable_real?
|
388
|
+
assert(! @ole.file.executable_real?("noSuchFile"))
|
389
|
+
assert(! @ole.file.executable_real?("file1"))
|
390
|
+
assert(@ole.file.executable_real?("dir1"))
|
391
|
+
assert(! @ole.file.stat("file1").executable_real?)
|
392
|
+
assert(@ole.file.stat("dir1").executable_real?)
|
393
|
+
end
|
394
|
+
|
395
|
+
def test_owned?
|
396
|
+
assert_true_if_entry_exists(:owned?)
|
397
|
+
end
|
398
|
+
|
399
|
+
def test_grpowned?
|
400
|
+
assert_true_if_entry_exists(:grpowned?)
|
401
|
+
end
|
402
|
+
|
403
|
+
def test_setgid?
|
404
|
+
assert_always_false(:setgid?)
|
405
|
+
end
|
406
|
+
|
407
|
+
def test_setuid?
|
408
|
+
assert_always_false(:setgid?)
|
409
|
+
end
|
410
|
+
|
411
|
+
def test_sticky?
|
412
|
+
assert_always_false(:sticky?)
|
413
|
+
end
|
414
|
+
|
415
|
+
def test_stat
|
416
|
+
s = @ole.file.stat("file1")
|
417
|
+
assert(s.kind_of?(File::Stat)) # It pretends
|
418
|
+
assert_raise(Errno::ENOENT, "No such file or directory - noSuchFile") {
|
419
|
+
@ole.file.stat("noSuchFile")
|
420
|
+
}
|
421
|
+
end
|
422
|
+
|
423
|
+
def test_lstat
|
424
|
+
assert(@ole.file.lstat("file1").file?)
|
425
|
+
end
|
426
|
+
|
427
|
+
|
428
|
+
def test_chmod
|
429
|
+
assert_raise(Errno::ENOENT, "No such file or directory - noSuchFile") {
|
430
|
+
@ole.file.chmod(0644, "file1", "NoSuchFile")
|
431
|
+
}
|
432
|
+
assert_equal(2, @ole.file.chmod(0644, "file1", "dir1"))
|
433
|
+
end
|
434
|
+
|
435
|
+
def test_pipe
|
436
|
+
assert_raise(NotImplementedError) {
|
437
|
+
@ole.file.pipe
|
438
|
+
}
|
439
|
+
end
|
440
|
+
|
441
|
+
def test_foreach
|
442
|
+
ZipFile.open("data/generated/zipWithDir.zip") {
|
443
|
+
|zf|
|
444
|
+
ref = []
|
445
|
+
File.foreach("data/file1.txt") { |e| ref << e }
|
446
|
+
|
447
|
+
index = 0
|
448
|
+
zf.file.foreach("data/file1.txt") {
|
449
|
+
|l|
|
450
|
+
assert_equal(ref[index], l)
|
451
|
+
index = index.next
|
452
|
+
}
|
453
|
+
assert_equal(ref.size, index)
|
454
|
+
}
|
455
|
+
|
456
|
+
ZipFile.open("data/generated/zipWithDir.zip") {
|
457
|
+
|zf|
|
458
|
+
ref = []
|
459
|
+
File.foreach("data/file1.txt", " ") { |e| ref << e }
|
460
|
+
|
461
|
+
index = 0
|
462
|
+
zf.file.foreach("data/file1.txt", " ") {
|
463
|
+
|l|
|
464
|
+
assert_equal(ref[index], l)
|
465
|
+
index = index.next
|
466
|
+
}
|
467
|
+
assert_equal(ref.size, index)
|
468
|
+
}
|
469
|
+
end
|
470
|
+
|
471
|
+
def test_popen
|
472
|
+
cmd = /mswin/i =~ RUBY_PLATFORM ? 'dir' : 'ls'
|
473
|
+
|
474
|
+
assert_equal(File.popen(cmd) { |f| f.read },
|
475
|
+
@ole.file.popen(cmd) { |f| f.read })
|
476
|
+
end
|
477
|
+
|
478
|
+
# Can be added later
|
479
|
+
# def test_select
|
480
|
+
# fail "implement test"
|
481
|
+
# end
|
482
|
+
|
483
|
+
def test_readlines
|
484
|
+
ZipFile.open("data/generated/zipWithDir.zip") {
|
485
|
+
|zf|
|
486
|
+
assert_equal(File.readlines("data/file1.txt"),
|
487
|
+
zf.file.readlines("data/file1.txt"))
|
488
|
+
}
|
489
|
+
end
|
490
|
+
|
491
|
+
def test_read
|
492
|
+
ZipFile.open("data/generated/zipWithDir.zip") {
|
493
|
+
|zf|
|
494
|
+
assert_equal(File.read("data/file1.txt"),
|
495
|
+
zf.file.read("data/file1.txt"))
|
496
|
+
}
|
497
|
+
end
|
498
|
+
=end
|
499
|
+
end
|
500
|
+
|
501
|
+
class OleFsFileStatTest < Test::Unit::TestCase
|
502
|
+
|
503
|
+
def setup
|
504
|
+
@ole = Ole::Storage.open TEST_DIR + '/oleWithDirs.ole', 'rb'
|
505
|
+
end
|
506
|
+
|
507
|
+
def teardown
|
508
|
+
@ole.close if @ole
|
509
|
+
end
|
510
|
+
|
511
|
+
def test_blocks
|
512
|
+
assert_equal(2, @ole.file.stat("file1").blocks)
|
513
|
+
end
|
514
|
+
|
515
|
+
def test_ino
|
516
|
+
assert_equal(0, @ole.file.stat("file1").ino)
|
517
|
+
end
|
518
|
+
|
519
|
+
def test_uid
|
520
|
+
assert_equal(0, @ole.file.stat("file1").uid)
|
521
|
+
end
|
522
|
+
|
523
|
+
def test_gid
|
524
|
+
assert_equal(0, @ole.file.stat("file1").gid)
|
525
|
+
end
|
526
|
+
|
527
|
+
def test_ftype
|
528
|
+
assert_equal("file", @ole.file.stat("file1").ftype)
|
529
|
+
assert_equal("directory", @ole.file.stat("dir1").ftype)
|
530
|
+
end
|
531
|
+
|
532
|
+
=begin
|
533
|
+
def test_mode
|
534
|
+
assert_equal(0600, @ole.file.stat("file1").mode & 0777)
|
535
|
+
assert_equal(0600, @ole.file.stat("file1").mode & 0777)
|
536
|
+
assert_equal(0755, @ole.file.stat("dir1").mode & 0777)
|
537
|
+
assert_equal(0755, @ole.file.stat("dir1").mode & 0777)
|
538
|
+
end
|
539
|
+
=end
|
540
|
+
|
541
|
+
def test_dev
|
542
|
+
assert_equal(0, @ole.file.stat("file1").dev)
|
543
|
+
end
|
544
|
+
|
545
|
+
def test_rdev
|
546
|
+
assert_equal(0, @ole.file.stat("file1").rdev)
|
547
|
+
end
|
548
|
+
|
549
|
+
def test_rdev_major
|
550
|
+
assert_equal(0, @ole.file.stat("file1").rdev_major)
|
551
|
+
end
|
552
|
+
|
553
|
+
def test_rdev_minor
|
554
|
+
assert_equal(0, @ole.file.stat("file1").rdev_minor)
|
555
|
+
end
|
556
|
+
|
557
|
+
def test_nlink
|
558
|
+
assert_equal(1, @ole.file.stat("file1").nlink)
|
559
|
+
end
|
560
|
+
|
561
|
+
def test_blksize
|
562
|
+
assert_equal(64, @ole.file.stat("file1").blksize)
|
563
|
+
end
|
564
|
+
|
565
|
+
# an additional test i added for coverage. i've tried to make the inspect
|
566
|
+
# string on the ole stat match that of the regular one.
|
567
|
+
def test_inspect
|
568
|
+
# normalize, as instance_variables order is undefined
|
569
|
+
normalize = proc { |s| s[/ (.*)>$/, 1].split(', ').sort.join(', ') }
|
570
|
+
assert_match %r{blocks=2.*ftype=file.*size=72}, normalize[@ole.file.stat('file1').inspect]
|
571
|
+
end
|
572
|
+
end
|
573
|
+
|
574
|
+
class OleFsFileMutatingTest < Test::Unit::TestCase
|
575
|
+
def setup
|
576
|
+
# we use an in memory copy of the file instead of the original
|
577
|
+
# file based.
|
578
|
+
@io = StringIO.new open(TEST_DIR + '/oleWithDirs.ole', 'rb', &:read)
|
579
|
+
end
|
580
|
+
|
581
|
+
def teardown
|
582
|
+
@io.close if @io
|
583
|
+
end
|
584
|
+
|
585
|
+
def test_delete
|
586
|
+
do_test_delete_or_unlink(:delete)
|
587
|
+
end
|
588
|
+
|
589
|
+
def test_unlink
|
590
|
+
do_test_delete_or_unlink(:unlink)
|
591
|
+
end
|
592
|
+
|
593
|
+
def test_open_write
|
594
|
+
Ole::Storage.open(@io) {
|
595
|
+
|zf|
|
596
|
+
|
597
|
+
blockCalled = nil
|
598
|
+
zf.file.open("test_open_write_entry", "w") {
|
599
|
+
|f|
|
600
|
+
blockCalled = true
|
601
|
+
f.write "This is what I'm writing"
|
602
|
+
}
|
603
|
+
assert(blockCalled)
|
604
|
+
assert_equal("This is what I'm writing",
|
605
|
+
zf.file.read("test_open_write_entry"))
|
606
|
+
|
607
|
+
blockCalled = nil
|
608
|
+
# Test with existing entry
|
609
|
+
zf.file.open("file1", "w") {
|
610
|
+
|f|
|
611
|
+
blockCalled = true
|
612
|
+
f.write "This is what I'm writing too"
|
613
|
+
}
|
614
|
+
assert(blockCalled)
|
615
|
+
assert_equal("This is what I'm writing too",
|
616
|
+
zf.file.read("file1"))
|
617
|
+
}
|
618
|
+
end
|
619
|
+
|
620
|
+
def test_rename
|
621
|
+
Ole::Storage.open(@io) {
|
622
|
+
|zf|
|
623
|
+
assert_raise(Errno::ENOENT, "") {
|
624
|
+
zf.file.rename("NoSuchFile", "bimse")
|
625
|
+
}
|
626
|
+
zf.file.rename("file1", "newNameForFile1")
|
627
|
+
# lets also try moving a file to a different directory,
|
628
|
+
# and renaming a directory
|
629
|
+
zf.file.rename('/dir1/file11', '/dir1/dir11/file111')
|
630
|
+
zf.file.rename('dir1', 'dir9')
|
631
|
+
}
|
632
|
+
|
633
|
+
Ole::Storage.open(@io) {
|
634
|
+
|zf|
|
635
|
+
assert(! zf.file.exists?("file1"))
|
636
|
+
assert(zf.file.exists?("newNameForFile1"))
|
637
|
+
assert(zf.file.exists?("dir9/dir11/file111"))
|
638
|
+
}
|
639
|
+
end
|
640
|
+
|
641
|
+
def do_test_delete_or_unlink(symbol)
|
642
|
+
Ole::Storage.open(@io) {
|
643
|
+
|zf|
|
644
|
+
assert(zf.file.exists?("dir2/dir21/dir221/file2221"))
|
645
|
+
zf.file.send(symbol, "dir2/dir21/dir221/file2221")
|
646
|
+
assert(! zf.file.exists?("dir2/dir21/dir221/file2221"))
|
647
|
+
|
648
|
+
assert(zf.file.exists?("dir1/file11"))
|
649
|
+
assert(zf.file.exists?("dir1/file12"))
|
650
|
+
zf.file.send(symbol, "dir1/file11", "dir1/file12")
|
651
|
+
assert(! zf.file.exists?("dir1/file11"))
|
652
|
+
assert(! zf.file.exists?("dir1/file12"))
|
653
|
+
|
654
|
+
assert_raise(Errno::ENOENT) { zf.file.send(symbol, "noSuchFile") }
|
655
|
+
assert_raise(Errno::EISDIR) { zf.file.send(symbol, "dir1/dir11") }
|
656
|
+
assert_raise(Errno::EISDIR) { zf.file.send(symbol, "dir1/dir11/") }
|
657
|
+
}
|
658
|
+
|
659
|
+
Ole::Storage.open(@io) {
|
660
|
+
|zf|
|
661
|
+
assert(! zf.file.exists?("dir2/dir21/dir221/file2221"))
|
662
|
+
assert(! zf.file.exists?("dir1/file11"))
|
663
|
+
assert(! zf.file.exists?("dir1/file12"))
|
664
|
+
|
665
|
+
assert(zf.file.exists?("dir1/dir11"))
|
666
|
+
assert(zf.file.exists?("dir1/dir11/"))
|
667
|
+
}
|
668
|
+
end
|
669
|
+
|
670
|
+
end
|
671
|
+
|
672
|
+
class OleFsDirectoryTest < Test::Unit::TestCase
|
673
|
+
def setup
|
674
|
+
# we use an in memory copy of the file instead of the original
|
675
|
+
# file based.
|
676
|
+
@io = StringIO.new open(TEST_DIR + '/oleWithDirs.ole', 'rb', &:read)
|
677
|
+
end
|
678
|
+
|
679
|
+
def teardown
|
680
|
+
@io.close if @io
|
681
|
+
end
|
682
|
+
|
683
|
+
def test_delete
|
684
|
+
Ole::Storage.open(@io) {
|
685
|
+
|zf|
|
686
|
+
assert_raise(Errno::ENOENT, "No such file or directory - NoSuchFile.txt") {
|
687
|
+
zf.dir.delete("NoSuchFile.txt")
|
688
|
+
}
|
689
|
+
# see explanation below, touch a && ruby -e 'Dir.delete "a"' gives ENOTDIR not EINVAL
|
690
|
+
assert_raise(Errno::ENOTDIR, "Invalid argument - file1") {
|
691
|
+
zf.dir.delete("file1")
|
692
|
+
}
|
693
|
+
assert(zf.file.exists?("dir1"))
|
694
|
+
#zf.dir.delete("dir1")
|
695
|
+
#assert(! zf.file.exists?("dir1"))
|
696
|
+
# ^ this was allowed in zipfilesystem, but my code follows Dir.delete, and requires that
|
697
|
+
# the directory be empty first. need to delete recursively if you want other behaviour.
|
698
|
+
assert_raises(Errno::ENOTEMPTY) { zf.dir.delete('dir1') }
|
699
|
+
}
|
700
|
+
end
|
701
|
+
|
702
|
+
def test_mkdir
|
703
|
+
Ole::Storage.open(@io) {
|
704
|
+
|zf|
|
705
|
+
assert_raise(Errno::EEXIST, "File exists - dir1") {
|
706
|
+
zf.dir.mkdir("file1")
|
707
|
+
}
|
708
|
+
assert_raise(Errno::EEXIST, "File exists - dir1") {
|
709
|
+
zf.dir.mkdir("dir1")
|
710
|
+
}
|
711
|
+
assert(!zf.file.exists?("newDir"))
|
712
|
+
zf.dir.mkdir("newDir")
|
713
|
+
assert(zf.file.directory?("newDir"))
|
714
|
+
assert(!zf.file.exists?("newDir2"))
|
715
|
+
# FIXME - mode not supported yet
|
716
|
+
#zf.dir.mkdir("newDir2", 3485)
|
717
|
+
#assert(zf.file.directory?("newDir2"))
|
718
|
+
zf.dir.rmdir 'newDir'
|
719
|
+
assert(!zf.file.exists?("newDir"))
|
720
|
+
}
|
721
|
+
end
|
722
|
+
|
723
|
+
def test_pwd_chdir_entries
|
724
|
+
Ole::Storage.open(@io) {
|
725
|
+
|zf|
|
726
|
+
assert_equal("/", zf.dir.pwd)
|
727
|
+
|
728
|
+
assert_raise(Errno::ENOENT, "No such file or directory - no such dir") {
|
729
|
+
zf.dir.chdir "no such dir"
|
730
|
+
}
|
731
|
+
|
732
|
+
# changed this to ENOTDIR, which is what touch a; ruby -e "Dir.chdir('a')" gives you.
|
733
|
+
assert_raise(Errno::ENOTDIR, "Invalid argument - file1") {
|
734
|
+
zf.dir.chdir "file1"
|
735
|
+
}
|
736
|
+
|
737
|
+
assert_equal(['.', '..', "dir1", "dir2", "file1"].sort, zf.dir.entries(".").sort)
|
738
|
+
zf.dir.chdir "dir1"
|
739
|
+
assert_equal("/dir1", zf.dir.pwd)
|
740
|
+
zf.dir.chdir('dir11') { assert_equal '/dir1/dir11', zf.dir.pwd }
|
741
|
+
assert_equal '/dir1', zf.dir.pwd
|
742
|
+
assert_equal(['.', '..', "dir11", "file11", "file12"], zf.dir.entries(".").sort)
|
743
|
+
|
744
|
+
zf.dir.chdir "../dir2/dir21"
|
745
|
+
assert_equal("/dir2/dir21", zf.dir.pwd)
|
746
|
+
assert_equal(['.', '..', "dir221"].sort, zf.dir.entries(".").sort)
|
747
|
+
}
|
748
|
+
end
|
749
|
+
|
750
|
+
# results here are a bit different from zip/zipfilesystem, as i've chosen to fake '.'
|
751
|
+
# and '..'
|
752
|
+
def test_foreach
|
753
|
+
Ole::Storage.open(@io) {
|
754
|
+
|zf|
|
755
|
+
|
756
|
+
blockCalled = false
|
757
|
+
assert_raise(Errno::ENOENT, "No such file or directory - noSuchDir") {
|
758
|
+
zf.dir.foreach("noSuchDir") { |e| blockCalled = true }
|
759
|
+
}
|
760
|
+
assert(! blockCalled)
|
761
|
+
|
762
|
+
assert_raise(Errno::ENOTDIR, "Not a directory - file1") {
|
763
|
+
zf.dir.foreach("file1") { |e| blockCalled = true }
|
764
|
+
}
|
765
|
+
assert(! blockCalled)
|
766
|
+
|
767
|
+
entries = []
|
768
|
+
zf.dir.foreach(".") { |e| entries << e }
|
769
|
+
assert_equal(['.', '..', "dir1", "dir2", "file1"].sort, entries.sort)
|
770
|
+
|
771
|
+
entries = []
|
772
|
+
zf.dir.foreach("dir1") { |e| entries << e }
|
773
|
+
assert_equal(['.', '..', "dir11", "file11", "file12"], entries.sort)
|
774
|
+
}
|
775
|
+
end
|
776
|
+
|
777
|
+
=begin
|
778
|
+
# i've gone for NoMethodError instead.
|
779
|
+
def test_chroot
|
780
|
+
Ole::Storage.open(@io) {
|
781
|
+
|zf|
|
782
|
+
assert_raise(NotImplementedError) {
|
783
|
+
zf.dir.chroot
|
784
|
+
}
|
785
|
+
}
|
786
|
+
end
|
787
|
+
=end
|
788
|
+
|
789
|
+
# Globbing not supported yet
|
790
|
+
#def test_glob
|
791
|
+
# # test alias []-operator too
|
792
|
+
# fail "implement test"
|
793
|
+
#end
|
794
|
+
|
795
|
+
def test_open_new
|
796
|
+
Ole::Storage.open(@io) {
|
797
|
+
|zf|
|
798
|
+
|
799
|
+
assert_raise(Errno::ENOTDIR, "Not a directory - file1") {
|
800
|
+
zf.dir.new("file1")
|
801
|
+
}
|
802
|
+
|
803
|
+
assert_raise(Errno::ENOENT, "No such file or directory - noSuchFile") {
|
804
|
+
zf.dir.new("noSuchFile")
|
805
|
+
}
|
806
|
+
|
807
|
+
d = zf.dir.new(".")
|
808
|
+
assert_equal(['.', '..', "file1", "dir1", "dir2"].sort, d.entries.sort)
|
809
|
+
d.close
|
810
|
+
|
811
|
+
zf.dir.open("dir1") {
|
812
|
+
|d2|
|
813
|
+
assert_equal(['.', '..', "dir11", "file11", "file12"].sort, d2.entries.sort)
|
814
|
+
}
|
815
|
+
}
|
816
|
+
end
|
817
|
+
|
818
|
+
end
|
819
|
+
|
820
|
+
class OleFsDirIteratorTest < Test::Unit::TestCase
|
821
|
+
|
822
|
+
FILENAME_ARRAY = [ "f1", "f2", "f3", "f4", "f5", "f6" ]
|
823
|
+
|
824
|
+
def setup
|
825
|
+
@dirIt = Ole::Storage::DirClass::Dir.new('/', FILENAME_ARRAY)
|
826
|
+
end
|
827
|
+
|
828
|
+
def test_close
|
829
|
+
@dirIt.close
|
830
|
+
assert_raise(IOError, "closed directory") {
|
831
|
+
@dirIt.each { |e| p e }
|
832
|
+
}
|
833
|
+
assert_raise(IOError, "closed directory") {
|
834
|
+
@dirIt.read
|
835
|
+
}
|
836
|
+
assert_raise(IOError, "closed directory") {
|
837
|
+
@dirIt.rewind
|
838
|
+
}
|
839
|
+
assert_raise(IOError, "closed directory") {
|
840
|
+
@dirIt.seek(0)
|
841
|
+
}
|
842
|
+
assert_raise(IOError, "closed directory") {
|
843
|
+
@dirIt.tell
|
844
|
+
}
|
845
|
+
|
846
|
+
end
|
847
|
+
|
848
|
+
def test_each
|
849
|
+
# Tested through Enumerable.entries
|
850
|
+
assert_equal(FILENAME_ARRAY, @dirIt.entries)
|
851
|
+
end
|
852
|
+
|
853
|
+
def test_read
|
854
|
+
FILENAME_ARRAY.size.times {
|
855
|
+
|i|
|
856
|
+
assert_equal(FILENAME_ARRAY[i], @dirIt.read)
|
857
|
+
}
|
858
|
+
end
|
859
|
+
|
860
|
+
def test_rewind
|
861
|
+
@dirIt.read
|
862
|
+
@dirIt.read
|
863
|
+
assert_equal(FILENAME_ARRAY[2], @dirIt.read)
|
864
|
+
@dirIt.rewind
|
865
|
+
assert_equal(FILENAME_ARRAY[0], @dirIt.read)
|
866
|
+
end
|
867
|
+
|
868
|
+
def test_tell_seek
|
869
|
+
@dirIt.read
|
870
|
+
@dirIt.read
|
871
|
+
pos = @dirIt.tell
|
872
|
+
valAtPos = @dirIt.read
|
873
|
+
@dirIt.read
|
874
|
+
@dirIt.seek(pos)
|
875
|
+
assert_equal(valAtPos, @dirIt.read)
|
876
|
+
end
|
877
|
+
|
878
|
+
end
|
879
|
+
|
880
|
+
class OleUnicodeTest < Test::Unit::TestCase
|
881
|
+
def setup
|
882
|
+
@io = StringIO.new ''
|
883
|
+
end
|
884
|
+
|
885
|
+
def test_unicode
|
886
|
+
# in ruby-1.8, encoding is assumed to be UTF-8 (and converted with iconv).
|
887
|
+
# in ruby-1.9, UTF-8 should work also, but probably shouldn't be using fixed
|
888
|
+
# TO_UTF16 iconv for other encodings.
|
889
|
+
resume = "R\xc3\xa9sum\xc3\xa9"
|
890
|
+
resume.force_encoding Encoding::UTF_8 if resume.respond_to? :encoding
|
891
|
+
Ole::Storage.open @io do |ole|
|
892
|
+
ole.file.open(resume, 'w') { |f| f.write 'Skills: writing bad unit tests' }
|
893
|
+
end
|
894
|
+
Ole::Storage.open @io do |ole|
|
895
|
+
assert_equal ['.', '..', resume], ole.dir.entries('.')
|
896
|
+
# use internal api to verify utf16 encoding
|
897
|
+
assert_equal "R\x00\xE9\x00s\x00u\x00m\x00\xE9\x00", ole.root.children[0].name_utf16[0, 6 * 2]
|
898
|
+
# FIXME: there is a bug in ruby-1.9 (at least in p376), which makes encoded
|
899
|
+
# strings useless as hash keys. identical bytes, identical encodings, identical
|
900
|
+
# according to #==, but different hash.
|
901
|
+
temp = File.expand_path("/#{resume}").split('/').last
|
902
|
+
if resume == temp and resume.hash != temp.hash
|
903
|
+
warn 'skipping assertion due to broken String#hash'
|
904
|
+
else
|
905
|
+
assert_equal 'Skills', ole.file.read(resume).split(': ', 2).first
|
906
|
+
end
|
907
|
+
end
|
908
|
+
end
|
909
|
+
|
910
|
+
def test_write_utf8_string
|
911
|
+
programmer = "programa\xC3\xA7\xC3\xA3o "
|
912
|
+
programmer.force_encoding Encoding::UTF_8 if programmer.respond_to? :encoding
|
913
|
+
Ole::Storage.open @io do |ole|
|
914
|
+
ole.file.open '1', 'w' do |writer|
|
915
|
+
writer.write(programmer)
|
916
|
+
writer.write('ruby')
|
917
|
+
end
|
918
|
+
end
|
919
|
+
Ole::Storage.open @io do |ole|
|
920
|
+
ole.file.open '1', 'r' do |reader|
|
921
|
+
s = reader.read
|
922
|
+
s = s.force_encoding('UTF-8') if s.respond_to?(:encoding)
|
923
|
+
assert_equal(programmer + 'ruby', s)
|
924
|
+
end
|
925
|
+
end
|
926
|
+
end
|
927
|
+
end
|
928
|
+
|
929
|
+
# Copyright (C) 2002, 2003 Thomas Sondergaard
|
930
|
+
# rubyzip is free software; you can redistribute it and/or
|
931
|
+
# modify it under the terms of the ruby license.
|
932
|
+
|