summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--lib/axlsx/package.rb2
-rw-r--r--lib/axlsx/rels/relationship.rb18
-rw-r--r--test/tc_package.rb11
3 files changed, 30 insertions, 1 deletions
diff --git a/lib/axlsx/package.rb b/lib/axlsx/package.rb
index a78b5f5d..0a1bceaa 100644
--- a/lib/axlsx/package.rb
+++ b/lib/axlsx/package.rb
@@ -100,6 +100,7 @@ module Axlsx
# File.open('example_streamed.xlsx', 'w') { |f| f.write(s.read) }
def serialize(output, confirm_valid=false)
return false unless !confirm_valid || self.validate.empty?
+ Relationship.clear_cached_instances
Zip::ZipOutputStream.open(output) do |zip|
write_parts(zip)
end
@@ -112,6 +113,7 @@ module Axlsx
# @return [StringIO|Boolean] False if confirm_valid and validation errors exist. rewound string IO if not.
def to_stream(confirm_valid=false)
return false unless !confirm_valid || self.validate.empty?
+ Relationship.clear_cached_instances
zip = write_parts(Zip::ZipOutputStream.new("streamed", true))
stream = zip.close_buffer
stream.rewind
diff --git a/lib/axlsx/rels/relationship.rb b/lib/axlsx/rels/relationship.rb
index 5e75a98a..a6b7bdd2 100644
--- a/lib/axlsx/rels/relationship.rb
+++ b/lib/axlsx/rels/relationship.rb
@@ -11,7 +11,23 @@ module Axlsx
@instances ||= []
end
- # Generate and return a unique id. Used for setting {#Id}.
+ # Clear cached instances.
+ #
+ # This should be called before serializing a package (see {Package#serialize} and
+ # {Package#to_stream}) to make sure that serialization is idempotent (i.e.
+ # Relationship instances are generated with the same IDs everytime the package
+ # is serialized).
+ #
+ # Also, calling this avoids memory leaks (cached instances lingering around
+ # forever).
+ def clear_cached_instances
+ @instances = []
+ end
+
+ # Generate and return a unique id (eg. `rId123`) Used for setting {#Id}.
+ #
+ # The generated id depends on the number of cached instances, so using
+ # {clear_cached_instances} will automatically reset the generated ids, too.
# @return [String]
def next_free_id
"rId#{@instances.size + 1}"
diff --git a/test/tc_package.rb b/test/tc_package.rb
index 86f11dd4..d7aa6904 100644
--- a/test/tc_package.rb
+++ b/test/tc_package.rb
@@ -133,6 +133,17 @@ class TestPackage < Test::Unit::TestCase
assert zip_content_then == zip_content_now, "zip files are not identical"
end
end
+
+ def test_serialization_creates_identical_files_for_identical_packages
+ package_1, package_2 = 2.times.map do
+ Axlsx::Package.new(created_at: Time.utc(2013, 1, 1)).tap do |p|
+ p.workbook.add_worksheet(:name => "Basic Worksheet") do |sheet|
+ sheet.add_row [1, 2, 3]
+ end
+ end
+ end
+ assert package_1.to_stream.string == package_2.to_stream.string, "zip files are not identical"
+ end
def test_validation
assert_equal(@package.validate.size, 0, @package.validate)