diff options
Diffstat (limited to 'gfx/wr/peek-poke/tests/round_trip.rs')
-rw-r--r-- | gfx/wr/peek-poke/tests/round_trip.rs | 275 |
1 files changed, 275 insertions, 0 deletions
diff --git a/gfx/wr/peek-poke/tests/round_trip.rs b/gfx/wr/peek-poke/tests/round_trip.rs new file mode 100644 index 0000000000..3134c207ec --- /dev/null +++ b/gfx/wr/peek-poke/tests/round_trip.rs @@ -0,0 +1,275 @@ +// Copyright 2019 The Servo Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use peek_poke::{Peek, PeekPoke, Poke}; +use std::{fmt::Debug, marker::PhantomData}; + +fn poke_into<V: Peek + Poke>(a: &V) -> Vec<u8> { + let mut v = <Vec<u8>>::with_capacity(<V>::max_size()); + let end_ptr = unsafe { a.poke_into(v.as_mut_ptr()) }; + let new_size = end_ptr as usize - v.as_ptr() as usize; + assert!(new_size <= v.capacity()); + unsafe { + v.set_len(new_size); + } + v +} + +#[cfg(not(feature = "option_copy"))] +fn the_same<V>(a: V) +where + V: Debug + Default + PartialEq + Peek + Poke, +{ + let v = poke_into(&a); + let (b, end_ptr) = unsafe { peek_poke::peek_from_default(v.as_ptr()) }; + let size = end_ptr as usize - v.as_ptr() as usize; + assert_eq!(size, v.len()); + assert_eq!(a, b); +} + +#[cfg(feature = "option_copy")] +fn the_same<V>(a: V) +where + V: Copy + Debug + PartialEq + Peek + Poke, +{ + let v = poke_into(&a); + let mut b = a; + let end_ptr = unsafe { b.peek_from(v.as_ptr()) }; + let size = end_ptr as usize - v.as_ptr() as usize; + assert_eq!(size, v.len()); + assert_eq!(a, b); +} + +#[test] +fn test_numbers() { + // unsigned positive + the_same(5u8); + the_same(5u16); + the_same(5u32); + the_same(5u64); + the_same(5usize); + // signed positive + the_same(5i8); + the_same(5i16); + the_same(5i32); + the_same(5i64); + the_same(5isize); + // signed negative + the_same(-5i8); + the_same(-5i16); + the_same(-5i32); + the_same(-5i64); + the_same(-5isize); + // floating + the_same(-100f32); + the_same(0f32); + the_same(5f32); + the_same(-100f64); + the_same(5f64); +} + +#[test] +fn test_bool() { + the_same(true); + the_same(false); +} + +#[cfg(any(feature = "option_copy", feature = "option_default"))] +#[test] +fn test_option() { + the_same(Some(5usize)); + //the_same(Some("foo bar".to_string())); + the_same(None::<usize>); +} + +#[test] +fn test_fixed_size_array() { + the_same([24u32; 32]); + the_same([1u64, 2, 3, 4, 5, 6, 7, 8]); + the_same([0u8; 19]); +} + +#[test] +fn test_tuple() { + the_same((1isize, )); + the_same((1isize, 2isize, 3isize)); + the_same((1isize, ())); +} + +#[test] +fn test_basic_struct() { + #[derive(Copy, Clone, Debug, Default, PartialEq, PeekPoke)] + struct Bar { + a: u32, + b: u32, + c: u32, + #[cfg(any(feature = "option_copy", feature = "option_default"))] + d: Option<u32>, + } + + the_same(Bar { + a: 2, + b: 4, + c: 42, + #[cfg(any(feature = "option_copy", feature = "option_default"))] + d: None, + }); +} + +#[test] +fn test_enum() { + #[derive(Clone, Copy, Debug, PartialEq, PeekPoke)] + enum TestEnum { + NoArg, + OneArg(usize), + Args(usize, usize), + AnotherNoArg, + StructLike { x: usize, y: f32 }, + } + + impl Default for TestEnum { + fn default() -> Self { + TestEnum::NoArg + } + } + + the_same(TestEnum::NoArg); + the_same(TestEnum::OneArg(4)); + the_same(TestEnum::Args(4, 5)); + the_same(TestEnum::AnotherNoArg); + the_same(TestEnum::StructLike { x: 4, y: 3.14159 }); +} + +#[test] +fn test_enum_cstyle() { + #[repr(u32)] + #[derive(Clone, Copy, Debug, PartialEq, Eq, PeekPoke)] + enum BorderStyle { + None = 0, + Solid = 1, + Double = 2, + Dotted = 3, + Dashed = 4, + Hidden = 5, + Groove = 6, + Ridge = 7, + Inset = 8, + Outset = 9, + } + + impl Default for BorderStyle { + fn default() -> Self { + BorderStyle::None + } + } + + the_same(BorderStyle::None); + the_same(BorderStyle::Solid); + the_same(BorderStyle::Double); + the_same(BorderStyle::Dotted); + the_same(BorderStyle::Dashed); + the_same(BorderStyle::Hidden); + the_same(BorderStyle::Groove); + the_same(BorderStyle::Ridge); + the_same(BorderStyle::Inset); + the_same(BorderStyle::Outset); +} + +#[test] +fn test_phantom_data() { + struct Bar; + #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PeekPoke)] + struct Foo { + x: u32, + y: u32, + _marker: PhantomData<Bar>, + } + the_same(Foo { + x: 19, + y: 42, + _marker: PhantomData, + }); +} + +#[test] +fn test_generic() { + #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PeekPoke)] + struct Foo<T> { + x: T, + y: T, + } + the_same(Foo { x: 19.0, y: 42.0 }); +} + +#[test] +fn test_generic_enum() { + #[derive(Clone, Copy, Debug, Default, PartialEq, PeekPoke)] + pub struct PropertyBindingKey<T> { + pub id: usize, + _phantom: PhantomData<T>, + } + + #[derive(Clone, Copy, Debug, PartialEq, PeekPoke)] + pub enum PropertyBinding<T> { + Value(T), + Binding(PropertyBindingKey<T>, T), + } + + impl<T: Default> Default for PropertyBinding<T> { + fn default() -> Self { + PropertyBinding::Value(Default::default()) + } + } +} + +#[cfg(all(feature = "extras", feature = "option_copy"))] +mod extra_tests { + use super::*; + use euclid::{Point2D, Rect, SideOffsets2D, Size2D, Transform3D, Vector2D}; + use std::mem::size_of; + + #[test] + fn euclid_types() { + the_same(Point2D::<f32>::new(1.0, 2.0)); + assert_eq!(Point2D::<f32>::max_size(), 2 * size_of::<f32>()); + + the_same(Rect::<f32>::new( + Point2D::<f32>::new(0.0, 0.0), + Size2D::<f32>::new(100.0, 80.0), + )); + assert_eq!(Rect::<f32>::max_size(), 4 * size_of::<f32>()); + + the_same(SideOffsets2D::<f32>::new(0.0, 10.0, -1.0, -10.0)); + assert_eq!(SideOffsets2D::<f32>::max_size(), 4 * size_of::<f32>()); + + the_same(Transform3D::<f32>::identity()); + assert_eq!(Transform3D::<f32>::max_size(), 16 * size_of::<f32>()); + + the_same(Vector2D::<f32>::new(1.0, 2.0)); + assert_eq!(Vector2D::<f32>::max_size(), 2 * size_of::<f32>()); + } + + #[test] + fn webrender_api_types() { + type PipelineSourceId = i32; + #[derive(Clone, Copy, Debug, PartialEq, PeekPoke)] + struct PipelineId(pub PipelineSourceId, pub u32); + + #[derive(Clone, Copy, Debug, PartialEq, PeekPoke)] + struct ClipChainId(pub u64, pub PipelineId); + + #[derive(Clone, Copy, Debug, PartialEq, PeekPoke)] + struct SpatialId(pub usize, pub PipelineId); + + the_same(PipelineId(42, 2)); + the_same(ClipChainId(19u64, PipelineId(42, 2))); + the_same(SpatialId(19usize, PipelineId(42, 2))); + } +} |