We can get the same strength of assertions with less code. Also, by
using assert_equal instead of assert, we get better feedback when
assertion does not meet expectations.
This change has several benefits:
* When errors occur, the test provides useful feedback, showing you
expected vs. actual.
* We no longer need to open and modify the Enumerable module.
* The test is more readable.
Having a specific 'does this instance equal another instance' method is
kind of annoying and breaks a number of things. Most obviously it breaks
comparing to `nil`: `nil.dos_equals(other)` will fail where
`nil == other` does not.
So this commit overrides `<=>` in `Zip::DOSTime` and deprecates
`dos_equals`.
Previously, only the extra fields stored in the central directory were
being read in. In reality it is often the case that the extra field in
the central directory is just a marker, and the full data is in the
local header. So we need to read both in and merge the two into the
final correct extra field. This merging infrastructure was already
implemented in the extra field code but we never actually read the
local extra fields in until now.
Reading the central directory headers and local entry headers seems
rather fragile, so we can't just read one over the other and hope to end
up with a correctly merged set of extra fields because this breaks other
things. So we need to specifically read the local extra field data and
merge just those bits.
This commit also fixes a couple of tests that were 'broken' by us now
reading extra fields in correctly!
Whatever the compression method that is set by the user, if the
compression level is set to 0 (no compression), then the entry should be
STORED. This mimics commandline tool behaviour and matches user
expectations.
This greatly simplifies the creation of `Entry` objects when only a
couple of fields are not set to their defaults, while at the same time
allowing an `Entry` to be fully configured at creation time if
appropriate.
This fundamentally changes the `Entry` API and means that some
convenience methods in `OutputStream` and `File` have needed to be
refactored.
There was some fairly odd stuff going on in `put_next_entry` that
allowed for data within an `Entry` to be overridden and prevented an
`Entry` from being a single point of truth. Fixing this also simplifies
the code within `File` and still passes all tests.
Also, fixing the above means we can stop passing the compression level
around as a parameter and use the value stored in each `Entry` directly.
Let's keep `compression_level` out of the `Entry` public API though as
it only makes sense when writing an `Entry`: there doesn't seem to be an
obvious way to read what level of compression was used when reading an
`Entry` from a zip file.
It looks like it needs to be surfaced in `add` and `get_output_stream`.
The compression level defaults to whatever the global default is unless
it is overridden on opening the Zip::File.
Also needed to reorder some of the requires in the top-level module file
now that we are using defaults in the File class.
Allow an Entry to specify a compression level and pass this down to the
underlying OutputStream infrastructure. OutputStream has been able to
specify a compression level for a while but this has, up until now, only
ever been set to the default.
This fundamentally changes the API so will need a major version bump.
Using the current pack directives makes test_extract_incorrect_size fail
in s390x architecture because of the endian probably. This is the output
of the command executed by the test in amd64:
irb(main):001:0> [501, 500000, 1].pack('LLS')
=> "\xF5\x01\x00\x00 \xA1\a\x00\x01\x00"
And the output of the same command in s390x:
irb(main):001:0> [501, 500000, 1].pack('LLS')
=> "\x00\x00\x01\xF5\x00\a\xA1 \x00\x01"
Changing to 'VVv' pack directives like is used in
lib/zib/entry.rb fixes the test in s390x and does not add a
regression in amd64.
There has been an option in `Zip::File` (`:restore_times`) for a long
time, but it seems it has never worked. Firstly the actual timestamp of
an added file wasn't being saved, and secondly an extracted file wasn't
having its timestamp set correctly.
This commit fixes both of those issues, and adds tests to make sure.
StringIO objects created within File.open_buffer were not being switched into
binmode, but those passed in were. Fix this inconsistency and add a test.
Things are now more carefully set up, and if a buffer is passed in which
represents a file that already exists then this is taken into account. All
initialization is now done in File.new, rather than being split between there
and File.open_buffer.
This has also needed a bit of a re-write of Zip::File.initialize. I've tried to
bring some logic to it as a result, and have added comments to explain what is
now happening.
if you need to work with existing zip files which contain names with
non-ascii characters then you can specify this option.
Without this option find_entry will not work properly
Make the internal @create varible more consistent and actually match the
documentation.
Zip::File::CREATE is now true, rather than 1.
A new test is added to check if passing 1 in still works to ensure backwards
compatibility.
After running the tests there was a file left in the project directory,
'empty.zip', which was simply 'touch'ed to use as a null file. Switch to create
this as one of the generated test files so it's cleaned up automatically.
Also, use 'null.zip' as the name as there is already an 'empty.zip' generated
that is a zip file, but empty.
This test fails because in *NIX when the umask is 0027, files are created with 0640 permissions. The current implementation of Zip::File.create_file_permissions does a simple subtraction of 0666 - 0027 == 0637
Instead of inheriting the permissions from the tmp directory, new files should
have permissions that reflect the defaults on the system taking umask into
account.
It seems that (unix) permissions of 666 - umask are as close to a standard as
anything [1] and that 'touch' uses this. On Windows it seems sensible to just
use 644 directly [2].
[1] http://unix.stackexchange.com/a/102080
[2] http://ruby-doc.org/core-1.9.3/File.html