From 759f1261000f125a47e11b58905afc4fea8b72e7 Mon Sep 17 00:00:00 2001 From: Ryan Winograd Date: Thu, 20 Aug 2020 09:16:23 -0500 Subject: Deprecate using `#serialize` with boolean argument Update `Axlsx::Package#serialize` to accept the second argument as a boolean (being deprecated) or an options hash. In order to transition toward using keyword arguments for `Axlsx::Package#serialize`, change the documented method signature to an options hash, while still parsing the second argument as `confirm_valid` if a boolean is provided (in which case we also warn the user that a boolean argument is deprecated). --- lib/axlsx/package.rb | 28 ++++++++++++++++++++++++---- test/tc_package.rb | 26 +++++++++++++++++++++++--- 2 files changed, 47 insertions(+), 7 deletions(-) diff --git a/lib/axlsx/package.rb b/lib/axlsx/package.rb index 3afb6f8d..d9636536 100644 --- a/lib/axlsx/package.rb +++ b/lib/axlsx/package.rb @@ -74,13 +74,14 @@ module Axlsx # Serialize your workbook to disk as an xlsx document. # # @param [String] output The name of the file you want to serialize your package to - # @param [Boolean] confirm_valid Validate the package prior to serialization. - # @param [String, nil] zip_command When `nil`, `#serialize` with RubyZip to + # @param [Hash] options + # @option options [Boolean] :confirm_valid Validate the package prior to serialization. + # @option options [String] :zip_command When `nil`, `#serialize` with RubyZip to # zip the XLSX file contents. When a String, the provided zip command (e.g., # "zip") is used to zip the file contents (may be faster for large files) # @return [Boolean] False if confirm_valid and validation errors exist. True if the package was serialized # @note A tremendous amount of effort has gone into ensuring that you cannot create invalid xlsx documents. - # confirm_valid should be used in the rare case that you cannot open the serialized file. + # options[:confirm_valid] should be used in the rare case that you cannot open the serialized file. # @see Package#validate # @example # # This is how easy it is to create a valid xlsx file. Of course you might want to add a sheet or two, and maybe some data, styles and charts. @@ -99,7 +100,8 @@ module Axlsx # # Serialize to a stream # s = p.to_stream() # File.open('example_streamed.xlsx', 'w') { |f| f.write(s.read) } - def serialize(output, confirm_valid=false, zip_command: nil) + def serialize(output, options = {}) + confirm_valid, zip_command = parse_serialize_options(options) return false unless !confirm_valid || self.validate.empty? zip_provider = if zip_command ZipCommand.new(zip_command) @@ -359,5 +361,23 @@ module Axlsx rels.lock rels end + + # Parse the arguments of `#serialize` + # @return [Boolean, (String or nil)] Returns an array where the first value is + # `confirm_valid` and the second is the `zip_command`. + # @private + def parse_serialize_options(options) + if options.is_a?(Hash) + invalid_keys = options.keys - [:confirm_valid, :zip_command] + if invalid_keys.any? + raise ArgumentError.new("Invalid keyword arguments: #{invalid_keys}") + end + [options.fetch(:confirm_valid, false), options.fetch(:zip_command, nil)] + else + warn "[DEPRECATION] Axlsx::Package#serialize with confirm_valid as a boolean is deprecated. " + + "Use keyword args instead e.g., package.serialize(output, confirm_valid: false)" + [options, nil] + end + end end end diff --git a/test/tc_package.rb b/test/tc_package.rb index 18c08f5c..a6e31f88 100644 --- a/test/tc_package.rb +++ b/test/tc_package.rb @@ -133,21 +133,21 @@ class TestPackage < Test::Unit::TestCase end def test_serialization_with_zip_command - @package.serialize(@fname, false, zip_command: "zip") + @package.serialize(@fname, zip_command: "zip") assert_zip_file_matches_package(@fname, @package) File.delete(@fname) end def test_serialization_with_zip_command_and_absolute_path fname = "#{Dir.tmpdir}/#{@fname}" - @package.serialize(fname, false, zip_command: "zip") + @package.serialize(fname, zip_command: "zip") assert_zip_file_matches_package(fname, @package) File.delete(fname) end def test_serialization_with_invalid_zip_command assert_raises Axlsx::ZipCommand::ZipError do - @package.serialize(@fname, false, zip_command: "invalid_zip") + @package.serialize(@fname, zip_command: "invalid_zip") end end @@ -156,6 +156,26 @@ class TestPackage < Test::Unit::TestCase package.send(:parts).each{ |part| zf.get_entry(part[:entry]) } end + def test_serialization_with_deprecated_argument + warnings = capture_warnings do + @package.serialize(@fname, false) + end + assert_equal 1, warnings.size + assert_includes warnings.first, "confirm_valid as a boolean is deprecated" + end + + def capture_warnings(&block) + original_warn = Kernel.method(:warn) + warnings = [] + Kernel.define_method(:warn){ |string| warnings << string } + block.call + original_verbose = $VERBOSE + $VERBOSE = nil + Kernel.define_method(:warn, &original_warn) + $VERBOSE = original_verbose + warnings + end + # See comment for Package#zip_entry_for_part def test_serialization_creates_identical_files_at_any_time_if_created_at_is_set @package.core.created = Time.now -- cgit v1.2.3