ucf 0.1.0 → 0.5.0

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.
@@ -0,0 +1,101 @@
1
+ # Copyright (c) 2013 The University of Manchester, UK.
2
+ #
3
+ # All rights reserved.
4
+ #
5
+ # Redistribution and use in source and binary forms, with or without
6
+ # modification, are permitted provided that the following conditions are met:
7
+ #
8
+ # * Redistributions of source code must retain the above copyright notice,
9
+ # this list of conditions and the following disclaimer.
10
+ #
11
+ # * Redistributions in binary form must reproduce the above copyright notice,
12
+ # this list of conditions and the following disclaimer in the documentation
13
+ # and/or other materials provided with the distribution.
14
+ #
15
+ # * Neither the names of The University of Manchester nor the names of its
16
+ # contributors may be used to endorse or promote products derived from this
17
+ # software without specific prior written permission.
18
+ #
19
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20
+ # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22
+ # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23
+ # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24
+ # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25
+ # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26
+ # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27
+ # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28
+ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29
+ # POSSIBILITY OF SUCH DAMAGE.
30
+ #
31
+ # Author: Robert Haines
32
+
33
+ #
34
+ module UCF
35
+
36
+ # A ManagedFile is used to reserve a filename in a Container namespace.
37
+ class ManagedFile < ManagedEntry
38
+
39
+ # :call-seq:
40
+ # new(name, required = false, validation_proc = nil) -> ManagedFile
41
+ #
42
+ # Create a new ManagedFile with the supplied name and whether it is
43
+ # required to exist or not.
44
+ #
45
+ # If supplied <tt>validation_proc</tt> should be a Proc that takes a
46
+ # single parameter and returns +true+ or +false+ depending on whether the
47
+ # contents of the file were validated or not.
48
+ #
49
+ # For more complex content validation subclasses may override the validate
50
+ # method.
51
+ #
52
+ # The following example creates a ManagedFile that is not required to be
53
+ # present in the container, but if it is, its contents must be the single
54
+ # word "Boo!".
55
+ #
56
+ # valid = Proc.new { |contents| contents == "Boo!" }
57
+ # ManagedFile.new("Surprize.txt", false, valid)
58
+ def initialize(name, required = false, validation_proc = nil)
59
+ super(name, required)
60
+
61
+ @validation_proc = validation_proc.is_a?(Proc) ? validation_proc : nil
62
+ end
63
+
64
+ # :call-seq:
65
+ # verify!
66
+ #
67
+ # Verify this ManagedFile for correctness. The contents are validated if
68
+ # required.
69
+ #
70
+ # A MalformedUCFError is raised if it does not pass verification.
71
+ def verify!
72
+ super
73
+ unless (exists? ? validate : true)
74
+ raise MalformedUCFError.new("The contents of file '#{full_name}' do "\
75
+ "not pass validation.")
76
+ end
77
+ end
78
+
79
+ protected
80
+
81
+ # :call-seq:
82
+ # validate -> boolean
83
+ #
84
+ # Validate the contents of this ManagedFile. By default this methods uses
85
+ # the validation Proc supplied on object initialization if there is one.
86
+ # If not it simply returns true (no validation was required).
87
+ #
88
+ # For complex validations of content subclasses can override this method.
89
+ def validate
90
+ @validation_proc.nil? ? true : @validation_proc.call(contents)
91
+ end
92
+
93
+ private
94
+
95
+ # Grab the contents of this ManagedFile
96
+ def contents
97
+ container.read(full_name)
98
+ end
99
+
100
+ end
101
+ end
@@ -0,0 +1,183 @@
1
+ # Copyright (c) 2013 The University of Manchester, UK.
2
+ #
3
+ # All rights reserved.
4
+ #
5
+ # Redistribution and use in source and binary forms, with or without
6
+ # modification, are permitted provided that the following conditions are met:
7
+ #
8
+ # * Redistributions of source code must retain the above copyright notice,
9
+ # this list of conditions and the following disclaimer.
10
+ #
11
+ # * Redistributions in binary form must reproduce the above copyright notice,
12
+ # this list of conditions and the following disclaimer in the documentation
13
+ # and/or other materials provided with the distribution.
14
+ #
15
+ # * Neither the names of The University of Manchester nor the names of its
16
+ # contributors may be used to endorse or promote products derived from this
17
+ # software without specific prior written permission.
18
+ #
19
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20
+ # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22
+ # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23
+ # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24
+ # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25
+ # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26
+ # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27
+ # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28
+ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29
+ # POSSIBILITY OF SUCH DAMAGE.
30
+ #
31
+ # Author: Robert Haines
32
+
33
+ require 'zip/zip_entry'
34
+
35
+ module UCF
36
+
37
+ # This module provides support for managed file and directory entries.
38
+ #
39
+ # <b>Note!</b> If you mix this module in you *must* call
40
+ # +initialize_managed_entries+ in your constructor to ensure that the
41
+ # internal lists of managed entries are correctly assigned.
42
+ module ManagedEntries
43
+
44
+ # :call-seq:
45
+ # managed_directories -> Array
46
+ #
47
+ # Return the list of managed directories.
48
+ def managed_directories
49
+ @directories.values
50
+ end
51
+
52
+ # :call-seq:
53
+ # managed_directory_names -> Array
54
+ #
55
+ # Return the list of managed directory names.
56
+ def managed_directory_names
57
+ expand_names(@directories.keys)
58
+ end
59
+
60
+ # :call-seq:
61
+ # managed_directory?(entry) -> boolean
62
+ #
63
+ # Is the supplied entry/name a managed directory?
64
+ def managed_directory?(entry)
65
+ managed_entry?(entry, managed_directory_names)
66
+ end
67
+
68
+ # :call-seq:
69
+ # managed_entries -> Array
70
+ #
71
+ # Return the list of managed files and directories.
72
+ def managed_entries
73
+ managed_files + managed_directories
74
+ end
75
+
76
+ # :call-seq:
77
+ # managed_entry_names -> Array
78
+ #
79
+ # Return the list of managed file and directory names.
80
+ def managed_entry_names
81
+ managed_file_names + managed_directory_names
82
+ end
83
+
84
+ # :call-seq:
85
+ # managed_entry?(entry) -> boolean
86
+ #
87
+ # Is the supplied entry/name a managed entry?
88
+ def managed_entry?(entry, list = managed_entry_names)
89
+ name = entry.kind_of?(::Zip::ZipEntry) ? entry.name : entry
90
+ name.chop! if name.end_with? "/"
91
+ list.map { |n| n.downcase }.include? name.downcase
92
+ end
93
+
94
+ # :call-seq:
95
+ # managed_file?(entry) -> boolean
96
+ #
97
+ # Is the supplied entry/name a managed file?
98
+ def managed_file?(entry)
99
+ managed_entry?(entry, managed_file_names)
100
+ end
101
+
102
+ # :call-seq:
103
+ # managed_files -> Array
104
+ #
105
+ # Return the list of managed files.
106
+ def managed_files
107
+ @files.values + managed_directories.map { |d| d.managed_files }.flatten
108
+ end
109
+
110
+ # :call-seq:
111
+ # managed_file_names -> Array
112
+ #
113
+ # Return the list of managed file names.
114
+ def managed_file_names
115
+ expand_names(@files.keys) +
116
+ managed_directories.map { |d| d.managed_file_names }.flatten
117
+ end
118
+
119
+ # :call-seq:
120
+ # verify_managed_entries!
121
+ #
122
+ # All managed files and directories are checked to make sure that they
123
+ # exist, if required.
124
+ def verify_managed_entries!
125
+ @directories.each_value do |dir|
126
+ dir.verify!
127
+ end
128
+
129
+ @files.each_value do |file|
130
+ file.verify!
131
+ end
132
+
133
+ true
134
+ end
135
+
136
+ protected
137
+
138
+ # :call-seq:
139
+ # initialize_managed_entries
140
+ # initialize_managed_entries(entry)
141
+ # initialize_managed_entries(entries)
142
+ #
143
+ # Initialize the managed entries and register any that are supplied. A
144
+ # single ManagedFile or ManagedDirectory or a list of them can be
145
+ # provided.
146
+ def initialize_managed_entries(entries = [])
147
+ list = [*entries]
148
+ @directories ||= {}
149
+ @files ||= {}
150
+
151
+ list.each { |item| register_managed_entry(item) }
152
+ end
153
+
154
+ # :call-seq:
155
+ # register_managed_entry(entry)
156
+ #
157
+ # Register a ManagedFile or ManagedDirectory.
158
+ #
159
+ # A ManagedFile is used to reserve the name of a file in the container
160
+ # namespace and can describe how to verify the contents of it if required.
161
+ #
162
+ # A ManagedDirectory is used to both reserve the name of a directory in
163
+ # the container namespace and act as an interface to the (possibly)
164
+ # managed files within it.
165
+ def register_managed_entry(entry)
166
+ unless entry.is_a?(ManagedDirectory) || entry.is_a?(ManagedFile)
167
+ raise ArgumentError.new("The supplied entry must be of type "\
168
+ "ManagedDirectory or ManagedFile or a subclass of either.")
169
+ end
170
+
171
+ entry.parent = self
172
+ @directories[entry.name] = entry if entry.is_a? ManagedDirectory
173
+ @files[entry.name] = entry if entry.is_a? ManagedFile
174
+ end
175
+
176
+ private
177
+
178
+ def expand_names(names)
179
+ names.map { |n| self.is_a?(Container) ? n : "#{name}/#{n}" }
180
+ end
181
+
182
+ end
183
+ end
@@ -0,0 +1,88 @@
1
+ # Copyright (c) 2013 The University of Manchester, UK.
2
+ #
3
+ # All rights reserved.
4
+ #
5
+ # Redistribution and use in source and binary forms, with or without
6
+ # modification, are permitted provided that the following conditions are met:
7
+ #
8
+ # * Redistributions of source code must retain the above copyright notice,
9
+ # this list of conditions and the following disclaimer.
10
+ #
11
+ # * Redistributions in binary form must reproduce the above copyright notice,
12
+ # this list of conditions and the following disclaimer in the documentation
13
+ # and/or other materials provided with the distribution.
14
+ #
15
+ # * Neither the names of The University of Manchester nor the names of its
16
+ # contributors may be used to endorse or promote products derived from this
17
+ # software without specific prior written permission.
18
+ #
19
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20
+ # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22
+ # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23
+ # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24
+ # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25
+ # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26
+ # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27
+ # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28
+ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29
+ # POSSIBILITY OF SUCH DAMAGE.
30
+ #
31
+ # Author: Robert Haines
32
+
33
+ require 'zip/zip_entry'
34
+
35
+ module UCF
36
+
37
+ # This module provides support for reserved names.
38
+ module ReservedNames
39
+
40
+ # :call-seq:
41
+ # reserved_names -> Array
42
+ #
43
+ # Return a list of reserved file and directory names for this UCF
44
+ # document.
45
+ #
46
+ # Reserved files and directories must be accessed directly by methods
47
+ # within Container (or subclasses of Container). This is because they are
48
+ # fundamental to the format and might need to exhibit certain properties
49
+ # (such as no compression) that must be preserved. The "mimetype" file is
50
+ # an example of such a reserved entry.
51
+ #
52
+ # To add a reserved name to a subclass of Container simply add it to the
53
+ # list in the constructor (you must call the super constructor first!):
54
+ #
55
+ # class MyContainer < UCF::Container
56
+ # def initialize(filename)
57
+ # super(filename)
58
+ #
59
+ # register_reserved_name("my_reserved_name")
60
+ # end
61
+ # end
62
+ def reserved_names
63
+ @reserved_names ||= []
64
+ end
65
+
66
+ # :call-seq:
67
+ # reserved_entry?(entry) -> boolean
68
+ #
69
+ # Is the given entry in the reserved list of names? A String or a
70
+ # Zip::ZipEntry object can be passed in here.
71
+ def reserved_entry?(entry)
72
+ name = entry.kind_of?(::Zip::ZipEntry) ? entry.name : entry
73
+ name.chop! if name.end_with? "/"
74
+ reserved_names.map { |n| n.downcase }.include? name.downcase
75
+ end
76
+
77
+ protected
78
+
79
+ # :call-seq:
80
+ # register_reserved_name(name)
81
+ #
82
+ # Add a reserved name to the list.
83
+ def register_reserved_name(name)
84
+ @reserved_names ||= []
85
+ @reserved_names << name unless @reserved_names.include? name
86
+ end
87
+ end
88
+ end
@@ -30,6 +30,7 @@
30
30
  #
31
31
  # Author: Robert Haines
32
32
 
33
+ #
33
34
  module UCF
34
35
 
35
36
  # The base class of all other exceptions raised by this library.
@@ -53,7 +54,8 @@ module UCF
53
54
  end
54
55
  end
55
56
 
56
- # This exception is raised when a clash occurs with a reserved name.
57
+ # This exception is raised when a clash occurs with a reserved or managed
58
+ # name.
57
59
  class ReservedNameClashError < UCFError
58
60
 
59
61
  # :call-seq:
@@ -0,0 +1,52 @@
1
+ # Copyright (c) 2013 The University of Manchester, UK.
2
+ #
3
+ # All rights reserved.
4
+ #
5
+ # Redistribution and use in source and binary forms, with or without
6
+ # modification, are permitted provided that the following conditions are met:
7
+ #
8
+ # * Redistributions of source code must retain the above copyright notice,
9
+ # this list of conditions and the following disclaimer.
10
+ #
11
+ # * Redistributions in binary form must reproduce the above copyright notice,
12
+ # this list of conditions and the following disclaimer in the documentation
13
+ # and/or other materials provided with the distribution.
14
+ #
15
+ # * Neither the names of The University of Manchester nor the names of its
16
+ # contributors may be used to endorse or promote products derived from this
17
+ # software without specific prior written permission.
18
+ #
19
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20
+ # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22
+ # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23
+ # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24
+ # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25
+ # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26
+ # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27
+ # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28
+ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29
+ # POSSIBILITY OF SUCH DAMAGE.
30
+ #
31
+ # Author: Robert Haines
32
+
33
+ #
34
+ module UCF
35
+
36
+ # This is a subclass of ManagedDirectory to represent the META-INF directory
37
+ # in a basic UCF Document.
38
+ class MetaInf < ManagedDirectory
39
+
40
+ # :call-seq:
41
+ # new -> MetaInf
42
+ #
43
+ # Create a standard META-INF ManagedDirectory.
44
+ def initialize
45
+ super("META-INF", false,
46
+ [ManagedFile.new("container.xml"), ManagedFile.new("manifest.xml"),
47
+ ManagedFile.new("metadata.xml"), ManagedFile.new("signatures.xml"),
48
+ ManagedFile.new("encryption.xml"), ManagedFile.new("rights.xml")])
49
+ end
50
+
51
+ end
52
+ end
@@ -0,0 +1,206 @@
1
+ # Copyright (c) 2013 The University of Manchester, UK.
2
+ #
3
+ # All rights reserved.
4
+ #
5
+ # Redistribution and use in source and binary forms, with or without
6
+ # modification, are permitted provided that the following conditions are met:
7
+ #
8
+ # * Redistributions of source code must retain the above copyright notice,
9
+ # this list of conditions and the following disclaimer.
10
+ #
11
+ # * Redistributions in binary form must reproduce the above copyright notice,
12
+ # this list of conditions and the following disclaimer in the documentation
13
+ # and/or other materials provided with the distribution.
14
+ #
15
+ # * Neither the names of The University of Manchester nor the names of its
16
+ # contributors may be used to endorse or promote products derived from this
17
+ # software without specific prior written permission.
18
+ #
19
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20
+ # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22
+ # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23
+ # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24
+ # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25
+ # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26
+ # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27
+ # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28
+ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29
+ # POSSIBILITY OF SUCH DAMAGE.
30
+ #
31
+ # Author: Robert Haines
32
+
33
+ require 'tmpdir'
34
+ require 'ucf'
35
+
36
+ # Classes to test managed entries.
37
+ class ManagedUCF < UCF::Container
38
+
39
+ private_class_method :new
40
+
41
+ def initialize(filename)
42
+ super(filename)
43
+ register_managed_entry(UCF::ManagedDirectory.new("src", true))
44
+ register_managed_entry(UCF::ManagedDirectory.new("test"))
45
+ register_managed_entry(UCF::ManagedDirectory.new("lib"))
46
+ register_managed_entry(UCF::ManagedFile.new("index.html", true))
47
+ end
48
+
49
+ end
50
+
51
+ class ExampleUCF < UCF::Container
52
+
53
+ private_class_method :new
54
+
55
+ def initialize(filename)
56
+ super(filename)
57
+ register_managed_entry(UCF::ManagedDirectory.new("dir", true))
58
+ register_managed_entry(UCF::ManagedFile.new("greeting.txt", true))
59
+ end
60
+
61
+ end
62
+
63
+ class ExampleUCF2 < UCF::Container
64
+
65
+ private_class_method :new
66
+
67
+ def initialize(filename)
68
+ super(filename)
69
+
70
+ valid = Proc.new { |contents| contents.match(/[Hh]ello/) }
71
+ register_managed_entry(UCF::ManagedFile.new("greeting.txt", true, valid))
72
+ end
73
+
74
+ end
75
+
76
+ class TestManagedEntries < Test::Unit::TestCase
77
+
78
+ # Check that the example UCF document does not validate as a ManagedUCF.
79
+ def test_fail_verification
80
+ refute(ManagedUCF.verify($ucf_example))
81
+
82
+ assert_raises(UCF::MalformedUCFError) do
83
+ ManagedUCF.verify!($ucf_example)
84
+ end
85
+ end
86
+
87
+ # Check that the example UCF document does validate as an ExampleUCF.
88
+ def test_pass_verification
89
+ assert(ExampleUCF.verify($ucf_example))
90
+
91
+ assert_nothing_raised(UCF::MalformedUCFError) do
92
+ ExampleUCF.verify!($ucf_example)
93
+ end
94
+ end
95
+
96
+ # Check that the example UCF document does validate as an ExampleUCF2.
97
+ def test_pass_verification_2
98
+ assert(ExampleUCF2.verify($ucf_example))
99
+
100
+ assert_nothing_raised(UCF::MalformedUCFError) do
101
+ ExampleUCF2.verify!($ucf_example)
102
+ end
103
+ end
104
+
105
+ # Check that a standard Container can be created
106
+ def test_create_standard_container
107
+ Dir.mktmpdir do |dir|
108
+ filename = File.join(dir, "test.ucf")
109
+
110
+ assert_nothing_raised do
111
+ UCF::Container.create(filename) do |c|
112
+ c.mkdir("META-INF")
113
+ assert(c.file.exists?("META-INF"))
114
+
115
+ c.file.open("META-INF/container.xml", "w") do |f|
116
+ f.puts "<?xml version=\"1.0\"?>"
117
+ end
118
+ assert(c.file.exists?("META-INF/container.xml"))
119
+ end
120
+ end
121
+
122
+ assert_nothing_raised(UCF::MalformedUCFError) do
123
+ UCF::Container.verify!(filename)
124
+ end
125
+ end
126
+ end
127
+
128
+ # Check that a ManagedUCF does not verify immediately after creation.
129
+ def test_create_bad_subclassed_container
130
+ Dir.mktmpdir do |dir|
131
+ filename = File.join(dir, "test.ucf")
132
+
133
+ assert_nothing_raised do
134
+ ManagedUCF.create(filename) do |c|
135
+ assert_raises(UCF::MalformedUCFError) do
136
+ c.verify!
137
+ end
138
+ end
139
+ end
140
+
141
+ refute(ManagedUCF.verify(filename))
142
+ assert_raises(UCF::MalformedUCFError) do
143
+ ManagedUCF.verify!(filename)
144
+ end
145
+ end
146
+ end
147
+
148
+ # Check that a ManagedUCF does verify when required objects are added.
149
+ def test_create_subclassed_container
150
+ Dir.mktmpdir do |dir|
151
+ filename = File.join(dir, "test.ucf")
152
+
153
+ assert_nothing_raised do
154
+ ManagedUCF.create(filename) do |c|
155
+ c.dir.mkdir("src")
156
+ c.file.open("index.html", "w") do |f|
157
+ f.puts "<html />"
158
+ end
159
+ end
160
+ end
161
+
162
+ assert(ManagedUCF.verify(filename))
163
+ assert_nothing_raised(UCF::MalformedUCFError) do
164
+ ManagedUCF.verify!(filename)
165
+ end
166
+ end
167
+ end
168
+
169
+ # Check that a ExampleUCF2 will only verify when required objects are added
170
+ # with the correct contents.
171
+ def test_create_subclassed_container_with_content_verification
172
+ Dir.mktmpdir do |dir|
173
+ filename = File.join(dir, "test.ucf")
174
+
175
+ assert_nothing_raised do
176
+ ExampleUCF2.create(filename) do |c|
177
+ assert_raises(UCF::MalformedUCFError) do
178
+ c.verify!
179
+ end
180
+
181
+ c.file.open("greeting.txt", "w") do |f|
182
+ f.puts "Goodbye!"
183
+ end
184
+
185
+ assert_raises(UCF::MalformedUCFError) do
186
+ c.verify!
187
+ end
188
+
189
+ c.file.open("greeting.txt", "w") do |f|
190
+ f.puts "Hello, Y'All!"
191
+ end
192
+
193
+ assert_nothing_raised(UCF::MalformedUCFError) do
194
+ c.verify!
195
+ end
196
+ end
197
+ end
198
+
199
+ assert(ExampleUCF2.verify(filename))
200
+ assert_nothing_raised(UCF::MalformedUCFError) do
201
+ ExampleUCF2.verify!(filename)
202
+ end
203
+ end
204
+ end
205
+
206
+ end