From 92402d107ee7c13c5266b12de54b4f1c3319a2a3 Mon Sep 17 00:00:00 2001 From: Robert Haines Date: Thu, 3 Jul 2014 22:15:39 +0100 Subject: [PATCH] Add File#add and File#add_aggregate. Also adds write access to the manifest aggregates list. --- lib/ro-bundle/file.rb | 40 ++++++++++++++++++++++++++++++++++++ lib/ro-bundle/ro/manifest.rb | 15 ++++++++++++++ test/helpers/list_tests.rb | 16 +++++++++++++++ test/tc_create.rb | 34 ++++++++++++++++++++++++++++++ 4 files changed, 105 insertions(+) create mode 100644 test/helpers/list_tests.rb diff --git a/lib/ro-bundle/file.rb b/lib/ro-bundle/file.rb index 1b82c59..c730b20 100644 --- a/lib/ro-bundle/file.rb +++ b/lib/ro-bundle/file.rb @@ -55,5 +55,45 @@ def self.create(filename, mimetype = MIMETYPE, &block) super(filename, mimetype, &block) end + # :call-seq: + # add(entry, src_path, options = {}, &continue_on_exists_proc) + # + # Convenience method for adding the contents of a file to the bundle + # file. If asked to add a file with a reserved name, such as the special + # mimetype header file or .ro/manifest.json, this method will raise a + # ReservedNameClashError. + # + # This method automatically adds new entries to the list of bundle + # aggregates unless the :aggregate option is set to false. + # + # See the rubyzip documentation for details of the + # +continue_on_exists_proc+ parameter. + def add(entry, src_path, options = {}, &continue_on_exists_proc) + super(entry, src_path, &continue_on_exists_proc) + + options = { :aggregate => true }.merge(options) + + if options[:aggregate] + @manifest.add_aggregate(entry) + end + end + + # :call-seq: + # add_aggregate(entry, &continue_on_exists_proc) + # add_aggregate(entry, src_path, &continue_on_exists_proc) + # + # The first form of this method adds an already existing entry in the + # bundle to the list of aggregates. Errno:ENOENT is raised if the + # entry does not exist. + # + # The second form is equivalent to File#add called without any options. + def add_aggregate(entry, src_path = nil, &continue_on_exists_proc) + if src_path.nil? + @manifest.add_aggregate(entry) + else + add(entry, src_path, &continue_on_exists_proc) + end + end + end end diff --git a/lib/ro-bundle/ro/manifest.rb b/lib/ro-bundle/ro/manifest.rb index 6581e4c..7474213 100644 --- a/lib/ro-bundle/ro/manifest.rb +++ b/lib/ro-bundle/ro/manifest.rb @@ -128,6 +128,21 @@ def aggregates structure[:aggregates].dup end + # :call-seq: + # add_aggregate(entry) + # + # Add the given entry to the list of aggregates in this manifest. + # Errno:ENOENT is raised if the entry does not exist. + def add_aggregate(entry) + raise Errno::ENOENT if container.find_entry(entry).nil? + + # Mangle the filename according to the RO Bundle specification. + name = "/#{entry_name(entry)}" + + @edited = true + structure[:aggregates] << Aggregate.new(name) + end + # :call-seq: # annotations # diff --git a/test/helpers/list_tests.rb b/test/helpers/list_tests.rb new file mode 100644 index 0000000..c99cafb --- /dev/null +++ b/test/helpers/list_tests.rb @@ -0,0 +1,16 @@ +#------------------------------------------------------------------------------ +# Copyright (c) 2014 The University of Manchester, UK. +# +# BSD Licenced. See LICENCE.rdoc for details. +# +# Author: Robert Haines +#------------------------------------------------------------------------------ + +# Is the given file aggregate in the list of aggregate objects +def file_aggregate_in_list(agg, list) + list.each do |e| + return true if e.file == "/#{agg}" + end + + false +end diff --git a/test/tc_create.rb b/test/tc_create.rb index 4add700..16431a7 100644 --- a/test/tc_create.rb +++ b/test/tc_create.rb @@ -10,6 +10,8 @@ require "tmpdir" require "ro-bundle" +require "helpers/list_tests" + class TestCreation < Test::Unit::TestCase def test_create_empty_bundle @@ -42,4 +44,36 @@ def test_create_empty_bundle end end + def test_add_aggregates + Dir.mktmpdir do |dir| + filename = File.join(dir, "test.bundle") + + entry1 = "test1.json" + entry2 = "test2.json" + entry3 = "test3.json" + + assert_nothing_raised do + ROBundle::File.create(filename) do |b| + assert b.aggregates.empty? + assert_nil b.find_entry(entry1) + + b.add(entry1, $man_ex3, :aggregate => false) + assert b.aggregates.empty? + assert_not_nil b.find_entry(entry1) + + b.add(entry2, $man_ex3) + assert file_aggregate_in_list(entry2, b.aggregates) + assert_not_nil b.find_entry(entry2) + + b.add_aggregate(entry3, $man_ex3) + assert file_aggregate_in_list(entry3, b.aggregates) + assert_not_nil b.find_entry(entry3) + + b.add_aggregate(entry1) + assert file_aggregate_in_list(entry1, b.aggregates) + end + end + end + end + end