Skip to content

Commit af7a0b3

Browse files
committed
Add capabilties test for functions reserved to zlib-implementations.
Some of these tests were previously gated and placed in such a way that `zlib-rs` was able to switch from its C-bindings to using its Rust API without implementing all zlib-implementation specific methods. The exstiing tests were unable to see this, and this commit adds a new capabiltiies test that will test these methods in all implementations but the `miniz_oxide`, which truly doesn't support them.
1 parent 22c77ee commit af7a0b3

File tree

2 files changed

+250
-90
lines changed

2 files changed

+250
-90
lines changed

src/mem.rs

Lines changed: 10 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -212,8 +212,8 @@ impl Compress {
212212
/// # Panics
213213
///
214214
/// If `window_bits` does not fall into the range 9 ..= 15,
215-
/// `new_with_window_bits` will panic.
216-
#[cfg(feature = "any_zlib")]
215+
/// this function will panic.
216+
#[cfg(any(feature = "any_zlib", feature = "zlib-rs"))]
217217
pub fn new_with_window_bits(
218218
level: Compression,
219219
zlib_header: bool,
@@ -239,8 +239,8 @@ impl Compress {
239239
/// # Panics
240240
///
241241
/// If `window_bits` does not fall into the range 9 ..= 15,
242-
/// `new_with_window_bits` will panic.
243-
#[cfg(feature = "any_zlib")]
242+
/// this function will panic.
243+
#[cfg(any(feature = "any_zlib", feature = "zlib-rs"))]
244244
pub fn new_gzip(level: Compression, window_bits: u8) -> Compress {
245245
assert!(
246246
window_bits > 8 && window_bits < 16,
@@ -415,8 +415,8 @@ impl Decompress {
415415
/// # Panics
416416
///
417417
/// If `window_bits` does not fall into the range 9 ..= 15,
418-
/// `new_with_window_bits` will panic.
419-
#[cfg(feature = "any_zlib")]
418+
/// this function will panic.
419+
#[cfg(any(feature = "any_zlib", feature = "zlib-rs"))]
420420
pub fn new_with_window_bits(zlib_header: bool, window_bits: u8) -> Decompress {
421421
assert!(
422422
window_bits > 8 && window_bits < 16,
@@ -435,8 +435,8 @@ impl Decompress {
435435
/// # Panics
436436
///
437437
/// If `window_bits` does not fall into the range 9 ..= 15,
438-
/// `new_with_window_bits` will panic.
439-
#[cfg(feature = "any_zlib")]
438+
/// this function will panic.
439+
#[cfg(any(feature = "any_zlib", feature = "zlib-rs"))]
440440
pub fn new_gzip(window_bits: u8) -> Decompress {
441441
assert!(
442442
window_bits > 8 && window_bits < 16,
@@ -663,7 +663,7 @@ mod tests {
663663
use crate::write;
664664
use crate::{Compression, Decompress, FlushDecompress};
665665

666-
#[cfg(feature = "any_zlib")]
666+
#[cfg(any(feature = "any_zlib", feature = "zlib-rs"))]
667667
use crate::{Compress, FlushCompress};
668668

669669
#[test]
@@ -723,87 +723,7 @@ mod tests {
723723
assert!(dst.starts_with(string));
724724
}
725725

726-
#[cfg(feature = "any_zlib")]
727-
#[test]
728-
fn set_dictionary_with_zlib_header() {
729-
let string = "hello, hello!".as_bytes();
730-
let dictionary = "hello".as_bytes();
731-
732-
let mut encoded = Vec::with_capacity(1024);
733-
734-
let mut encoder = Compress::new(Compression::default(), true);
735-
736-
let dictionary_adler = encoder.set_dictionary(&dictionary).unwrap();
737-
738-
encoder
739-
.compress_vec(string, &mut encoded, FlushCompress::Finish)
740-
.unwrap();
741-
742-
assert_eq!(encoder.total_in(), string.len() as u64);
743-
assert_eq!(encoder.total_out(), encoded.len() as u64);
744-
745-
let mut decoder = Decompress::new(true);
746-
let mut decoded = [0; 1024];
747-
let decompress_error = decoder
748-
.decompress(&encoded, &mut decoded, FlushDecompress::Finish)
749-
.expect_err("decompression should fail due to requiring a dictionary");
750-
751-
let required_adler = decompress_error.needs_dictionary()
752-
.expect("the first call to decompress should indicate a dictionary is required along with the required Adler-32 checksum");
753-
754-
assert_eq!(required_adler, dictionary_adler,
755-
"the Adler-32 checksum should match the value when the dictionary was set on the compressor");
756-
757-
let actual_adler = decoder.set_dictionary(&dictionary).unwrap();
758-
759-
assert_eq!(required_adler, actual_adler);
760-
761-
// Decompress the rest of the input to the remainder of the output buffer
762-
let total_in = decoder.total_in();
763-
let total_out = decoder.total_out();
764-
765-
let decompress_result = decoder.decompress(
766-
&encoded[total_in as usize..],
767-
&mut decoded[total_out as usize..],
768-
FlushDecompress::Finish,
769-
);
770-
assert!(decompress_result.is_ok());
771-
772-
assert_eq!(&decoded[..decoder.total_out() as usize], string);
773-
}
774-
775-
#[cfg(feature = "any_zlib")]
776-
#[test]
777-
fn set_dictionary_raw() {
778-
let string = "hello, hello!".as_bytes();
779-
let dictionary = "hello".as_bytes();
780-
781-
let mut encoded = Vec::with_capacity(1024);
782-
783-
let mut encoder = Compress::new(Compression::default(), false);
784-
785-
encoder.set_dictionary(&dictionary).unwrap();
786-
787-
encoder
788-
.compress_vec(string, &mut encoded, FlushCompress::Finish)
789-
.unwrap();
790-
791-
assert_eq!(encoder.total_in(), string.len() as u64);
792-
assert_eq!(encoder.total_out(), encoded.len() as u64);
793-
794-
let mut decoder = Decompress::new(false);
795-
796-
decoder.set_dictionary(&dictionary).unwrap();
797-
798-
let mut decoded = [0; 1024];
799-
let decompress_result = decoder.decompress(&encoded, &mut decoded, FlushDecompress::Finish);
800-
801-
assert!(decompress_result.is_ok());
802-
803-
assert_eq!(&decoded[..decoder.total_out() as usize], string);
804-
}
805-
806-
#[cfg(feature = "any_zlib")]
726+
#[cfg(any(feature = "any_zlib", feature = "zlib-rs"))]
807727
#[test]
808728
fn test_gzip_flate() {
809729
let string = "hello, hello!".as_bytes();

tests/capabilities.rs

Lines changed: 240 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,240 @@
1+
//! Validate that certain feature-gated functionality is still available.
2+
#[cfg(any(feature = "any_zlib", feature = "zlib-rs"))]
3+
use flate2::{Compress, Compression, Decompress, FlushCompress, FlushDecompress};
4+
5+
// Unsupported for `miniz_oxide`.
6+
#[cfg(any(feature = "any_zlib", feature = "zlib-rs"))]
7+
#[test]
8+
fn compress_new_with_window_bits_is_present_and_works() {
9+
let string = "hello world".as_bytes();
10+
11+
// Test with window_bits = 9 (minimum)
12+
let mut encoded = Vec::with_capacity(1024);
13+
let mut encoder = Compress::new_with_window_bits(Compression::default(), true, 9);
14+
encoder
15+
.compress_vec(string, &mut encoded, FlushCompress::Finish)
16+
.unwrap();
17+
assert_ne!(encoded.len(), 0);
18+
19+
let mut decoder = Decompress::new_with_window_bits(true, 9);
20+
let mut decoded = [0; 1024];
21+
decoder
22+
.decompress(&encoded, &mut decoded, FlushDecompress::Finish)
23+
.unwrap();
24+
assert_eq!(&decoded[..string.len()], string);
25+
26+
// Test with window_bits = 15 (maximum)
27+
let mut encoded = Vec::with_capacity(1024);
28+
let mut encoder = Compress::new_with_window_bits(Compression::default(), false, 15);
29+
encoder
30+
.compress_vec(string, &mut encoded, FlushCompress::Finish)
31+
.unwrap();
32+
assert_ne!(encoded.len(), 0);
33+
34+
let mut decoder = Decompress::new_with_window_bits(false, 15);
35+
let mut decoded = [0; 1024];
36+
decoder
37+
.decompress(&encoded, &mut decoded, FlushDecompress::Finish)
38+
.unwrap();
39+
assert_eq!(&decoded[..string.len()], string);
40+
}
41+
42+
// Unsupported for `miniz_oxide`.
43+
#[cfg(any(feature = "any_zlib", feature = "zlib-rs"))]
44+
#[test]
45+
fn decompress_new_gzip_window_bits_is_present_and_works() {
46+
let string = "hello world".as_bytes();
47+
48+
// Test with different window_bits values
49+
for window_bits in [9, 12, 15] {
50+
let mut encoded = Vec::with_capacity(1024);
51+
let mut encoder = Compress::new_gzip(Compression::default(), window_bits);
52+
encoder
53+
.compress_vec(string, &mut encoded, FlushCompress::Finish)
54+
.unwrap();
55+
56+
let mut decoder = Decompress::new_gzip(window_bits);
57+
let mut decoded = [0; 1024];
58+
decoder
59+
.decompress(&encoded, &mut decoded, FlushDecompress::Finish)
60+
.unwrap();
61+
assert_eq!(
62+
&decoded[..string.len()],
63+
string,
64+
"Failed with window_bits={}",
65+
window_bits
66+
);
67+
}
68+
}
69+
70+
// Unsupported for `miniz_oxide`.
71+
#[cfg(any(feature = "any_zlib", feature = "zlib-rs"))]
72+
#[test]
73+
#[should_panic(expected = "window_bits must be within 9 ..= 15")]
74+
fn compress_new_with_window_bits_invalid_low() {
75+
let _ = Compress::new_with_window_bits(Compression::default(), true, 8);
76+
}
77+
78+
// Unsupported for `miniz_oxide`.
79+
#[cfg(any(feature = "any_zlib", feature = "zlib-rs"))]
80+
#[test]
81+
#[should_panic(expected = "window_bits must be within 9 ..= 15")]
82+
fn compress_new_with_window_bits_invalid_high() {
83+
let _ = Compress::new_with_window_bits(Compression::default(), true, 16);
84+
}
85+
86+
// Unsupported for `miniz_oxide`.
87+
#[cfg(any(feature = "any_zlib", feature = "zlib-rs"))]
88+
#[test]
89+
#[should_panic(expected = "window_bits must be within 9 ..= 15")]
90+
fn compress_new_gzip_invalid_low() {
91+
let _ = Compress::new_gzip(Compression::default(), 8);
92+
}
93+
94+
// Unsupported for `miniz_oxide`.
95+
#[cfg(any(feature = "any_zlib", feature = "zlib-rs"))]
96+
#[test]
97+
#[should_panic(expected = "window_bits must be within 9 ..= 15")]
98+
fn compress_new_gzip_invalid_high() {
99+
let _ = Compress::new_gzip(Compression::default(), 16);
100+
}
101+
102+
// Unsupported for `miniz_oxide`.
103+
#[cfg(any(feature = "any_zlib", feature = "zlib-rs"))]
104+
#[test]
105+
fn set_dictionary_with_zlib_header() {
106+
let string = "hello, hello!".as_bytes();
107+
let dictionary = "hello".as_bytes();
108+
109+
let mut encoded = Vec::with_capacity(1024);
110+
111+
let mut encoder = Compress::new(Compression::default(), true);
112+
113+
let dictionary_adler = encoder.set_dictionary(&dictionary).unwrap();
114+
115+
encoder
116+
.compress_vec(string, &mut encoded, FlushCompress::Finish)
117+
.unwrap();
118+
119+
assert_eq!(encoder.total_in(), string.len() as u64);
120+
assert_eq!(encoder.total_out(), encoded.len() as u64);
121+
122+
let mut decoder = Decompress::new(true);
123+
let mut decoded = [0; 1024];
124+
let decompress_error = decoder
125+
.decompress(&encoded, &mut decoded, FlushDecompress::Finish)
126+
.expect_err("decompression should fail due to requiring a dictionary");
127+
128+
let required_adler = decompress_error.needs_dictionary()
129+
.expect("the first call to decompress should indicate a dictionary is required along with the required Adler-32 checksum");
130+
131+
assert_eq!(required_adler, dictionary_adler,
132+
"the Adler-32 checksum should match the value when the dictionary was set on the compressor");
133+
134+
let actual_adler = decoder.set_dictionary(&dictionary).unwrap();
135+
136+
assert_eq!(required_adler, actual_adler);
137+
138+
// Decompress the rest of the input to the remainder of the output buffer
139+
let total_in = decoder.total_in();
140+
let total_out = decoder.total_out();
141+
142+
let decompress_result = decoder.decompress(
143+
&encoded[total_in as usize..],
144+
&mut decoded[total_out as usize..],
145+
FlushDecompress::Finish,
146+
);
147+
assert!(decompress_result.is_ok());
148+
149+
assert_eq!(&decoded[..decoder.total_out() as usize], string);
150+
}
151+
152+
// Unsupported for `miniz_oxide`.
153+
#[cfg(any(feature = "any_zlib", feature = "zlib-rs"))]
154+
#[test]
155+
fn set_dictionary_raw() {
156+
let string = "hello, hello!".as_bytes();
157+
let dictionary = "hello".as_bytes();
158+
159+
let mut encoded = Vec::with_capacity(1024);
160+
161+
let mut encoder = Compress::new(Compression::default(), false);
162+
163+
encoder.set_dictionary(&dictionary).unwrap();
164+
165+
encoder
166+
.compress_vec(string, &mut encoded, FlushCompress::Finish)
167+
.unwrap();
168+
169+
assert_eq!(encoder.total_in(), string.len() as u64);
170+
assert_eq!(encoder.total_out(), encoded.len() as u64);
171+
172+
let mut decoder = Decompress::new(false);
173+
174+
decoder.set_dictionary(&dictionary).unwrap();
175+
176+
let mut decoded = [0; 1024];
177+
let decompress_result = decoder.decompress(&encoded, &mut decoded, FlushDecompress::Finish);
178+
179+
assert!(decompress_result.is_ok());
180+
181+
assert_eq!(&decoded[..decoder.total_out() as usize], string);
182+
}
183+
184+
// Unsupported for `miniz_oxide`.
185+
#[cfg(any(feature = "any_zlib", feature = "zlib-rs"))]
186+
#[test]
187+
fn compression_levels_are_effective() {
188+
let input = b"hello hello hello hello hello hello hello hello";
189+
190+
// Compress with no compression
191+
let mut encoded_none = Vec::new();
192+
Compress::new(Compression::none(), true)
193+
.compress_vec(input, &mut encoded_none, FlushCompress::Finish)
194+
.unwrap();
195+
196+
// Compress with best compression
197+
let mut encoded_best = Vec::new();
198+
Compress::new(Compression::best(), true)
199+
.compress_vec(input, &mut encoded_best, FlushCompress::Finish)
200+
.unwrap();
201+
202+
assert!(
203+
encoded_best.len() <= encoded_none.len(),
204+
"best compression produced larger output than no compression: best={}, none={}",
205+
encoded_best.len(),
206+
encoded_none.len(),
207+
);
208+
}
209+
210+
// Unsupported for `miniz_oxide`.
211+
#[cfg(any(feature = "any_zlib", feature = "zlib-rs"))]
212+
#[test]
213+
fn set_level_is_effective() {
214+
let input = b"hello hello hello hello hello hello hello hello";
215+
let no_compression = Compression::none();
216+
let best_compression = Compression::best();
217+
218+
// Compress with no compression
219+
let mut encoded_none = Vec::new();
220+
let mut compress = Compress::new(best_compression, true);
221+
compress.set_level(no_compression).unwrap();
222+
compress
223+
.compress_vec(input, &mut encoded_none, FlushCompress::Finish)
224+
.unwrap();
225+
226+
// Compress with best compression
227+
let mut encoded_best = Vec::new();
228+
let mut compress = Compress::new(no_compression, true);
229+
compress.set_level(best_compression).unwrap();
230+
compress
231+
.compress_vec(input, &mut encoded_best, FlushCompress::Finish)
232+
.unwrap();
233+
234+
assert!(
235+
encoded_best.len() <= encoded_none.len(),
236+
"best compression produced larger output than no compression: best={}, none={}",
237+
encoded_best.len(),
238+
encoded_none.len(),
239+
);
240+
}

0 commit comments

Comments
 (0)