diff options
| -rw-r--r-- | lib/axlsx/package.rb | 2 | ||||
| -rw-r--r-- | lib/axlsx/rels/relationship.rb | 18 | ||||
| -rw-r--r-- | test/tc_package.rb | 11 |
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) |
