<commit_before>use cssparser::Parser;
use markup5ever::{expanded_name, local_name, namespace_url, ns};
use nalgebra::{Matrix3, Matrix4x5, Matrix5, Vector5};

use crate::document::AcquiredNodes;
use crate::drawing_ctx::DrawingCtx;
use crate::element::{ElementResult, SetAttributes};
use crate::error::*;
use crate::node::{CascadedValues, Node};
use crate::parsers::{NumberList, NumberListLength, Parse, ParseValue};
use crate::property_defs::ColorInterpolationFilters;
use crate::surface_utils::{
    iterators::Pixels, shared_surface::ExclusiveImageSurface, ImageSurfaceDataExt, Pixel,
};
use crate::util::clamp;
use crate::xml::Attributes;

use super::context::{FilterContext, FilterOutput, FilterResult};
use super::{FilterEffect, FilterError, Input, Primitive, PrimitiveParams, ResolvedPrimitive};

/// Color matrix operation types.
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
enum OperationType {
    Matrix,
    Saturate,
    HueRotate,
    LuminanceToAlpha,
}

enum_default!(OperationType, OperationType::Matrix);

/// The `feColorMatrix` filter primitive.
pub struct FeColorMatrix {
    base: Primitive,
    in1: Input,
    matrix: Matrix5<f64>,
}

/// Resolved `feColorMatrix` primitive for rendering.
pub struct ColorMatrix {
    in1: Input,
    matrix: Matrix5<f64>,
    color_interpolation_filters: ColorInterpolationFilters,
}

impl Default for FeColorMatrix {
    /// Constructs a new `ColorMatrix` with empty properties.
    #[inline]
    fn default() -> FeColorMatrix {
        FeColorMatrix {
            base: Default::default(),
            in1: Default::default(),
            matrix: Matrix5::identity(),
        }
    }
}

#[rustfmt::skip]
impl SetAttributes for FeColorMatrix {
    fn set_attributes(&mut self, attrs: &Attributes) -> ElementResult {
        self.in1 = self.base.parse_one_input(attrs)?;

        // First, determine the operation type.
        let mut operation_type = Default::default();
        for (attr, value) in attrs
            .iter()
            .filter(|(attr, _)| attr.expanded() == expanded_name!("", "type"))
        {
            operation_type = attr.parse(value)?;
        }

        // Now read the matrix correspondingly.
        // LuminanceToAlpha doesn't accept any matrix.
        if operation_type == OperationType::LuminanceToAlpha {
            self.matrix = {
                Matrix5::new(
                    0.0,    0.0,    0.0,    0.0, 0.0,
                    0.0,    0.0,    0.0,    0.0, 0.0,
                    0.0,    0.0,    0.0,    0.0, 0.0,
                    0.2125, 0.7154, 0.0721, 0.0, 0.0,
                    0.0,    0.0,    0.0,    0.0, 1.0,
                )
            };
        } else {
            for (attr, value) in attrs
                .iter()
                .filter(|(attr, _)| attr.expanded() == expanded_name!("", "values"))
            {
                let new_matrix = match operation_type {
                    OperationType::LuminanceToAlpha => unreachable!(),
                    OperationType::Matrix => {
                        let NumberList(v) =
                            NumberList::parse_str(value, NumberListLength::Exact(20))
                                .attribute(attr)?;
                        let matrix = Matrix4x5::from_row_slice(&v);
                        let mut matrix = matrix.fixed_resize(0.0);
                        matrix[(4, 4)] = 1.0;
                        matrix
                    }
                    OperationType::Saturate => {
                        let s: f64 = attr.parse(value)?;

                        Matrix5::new(
                            0.213 + 0.787 * s, 0.715 - 0.715 * s, 0.072 - 0.072 * s, 0.0, 0.0,
                            0.213 - 0.213 * s, 0.715 + 0.285 * s, 0.072 - 0.072 * s, 0.0, 0.0,
                            0.213 - 0.213 * s, 0.715 - 0.715 * s, 0.072 + 0.928 * s, 0.0, 0.0,
                            0.0,               0.0,               0.0,               1.0, 0.0,
                            0.0,               0.0,               0.0,               0.0, 1.0,
                        )
                    }
                    OperationType::HueRotate => {
                        let degrees: f64 = attr.parse(value)?;
                        let (sin, cos) = degrees.to_radians().sin_cos();

                        let a = Matrix3::new(
                            0.213, 0.715, 0.072,
                            0.213, 0.715, 0.072,
                            0.213, 0.715, 0.072,
                        );

                        let b = Matrix3::new(
                             0.787, -0.715, -0.072,
                            -0.213,  0.285, -0.072,
                            -0.213, -0.715,  0.928,
                        );

                        let c = Matrix3::new(
                            -0.213, -0.715,  0.928,
                             0.143,  0.140, -0.283,
                            -0.787,  0.715,  0.072,
                        );

                        let top_left = a + b * cos + c * sin;

                        let mut matrix = top_left.fixed_resize(0.0);
                        matrix[(3, 3)] = 1.0;
                        matrix[(4, 4)] = 1.0;
                        matrix
                    }
                };

                self.matrix = new_matrix;
            }
        }

        Ok(())
    }
}

impl ColorMatrix {
    pub fn render(
        &self,
        primitive: &ResolvedPrimitive,
        ctx: &FilterContext,
        acquired_nodes: &mut AcquiredNodes<'_>,
        draw_ctx: &mut DrawingCtx,
    ) -> Result<FilterResult, FilterError> {
        let input_1 = ctx.get_input(
            acquired_nodes,
            draw_ctx,
            &self.in1,
            self.color_interpolation_filters,
        )?;
        let bounds = primitive
            .get_bounds(ctx)?
            .add_input(&input_1)
            .into_irect(ctx, draw_ctx);

        let mut surface = ExclusiveImageSurface::new(
            ctx.source_graphic().width(),
            ctx.source_graphic().height(),
            input_1.surface().surface_type(),
        )?;

        surface.modify(&mut |data, stride| {
            for (x, y, pixel) in Pixels::within(input_1.surface(), bounds) {
                let alpha = f64::from(pixel.a) / 255f64;

                let pixel_vec = if alpha == 0.0 {
                    Vector5::new(0.0, 0.0, 0.0, 0.0, 1.0)
                } else {
                    Vector5::new(
                        f64::from(pixel.r) / 255f64 / alpha,
                        f64::from(pixel.g) / 255f64 / alpha,
                        f64::from(pixel.b) / 255f64 / alpha,
                        alpha,
                        1.0,
                    )
                };
                let mut new_pixel_vec = Vector5::zeros();
                self.matrix.mul_to(&pixel_vec, &mut new_pixel_vec);

                let new_alpha = clamp(new_pixel_vec[3], 0.0, 1.0);

                let premultiply = |x: f64| ((clamp(x, 0.0, 1.0) * new_alpha * 255f64) + 0.5) as u8;

                let output_pixel = Pixel {
                    r: premultiply(new_pixel_vec[0]),
                    g: premultiply(new_pixel_vec[1]),
                    b: premultiply(new_pixel_vec[2]),
                    a: ((new_alpha * 255f64) + 0.5) as u8,
                };

                data.set_pixel(stride, output_pixel, x, y);
            }
        });

        Ok(FilterResult {
            name: primitive.result.clone(),
            output: FilterOutput {
                surface: surface.share()?,
                bounds,
            },
        })
    }
}

impl FilterEffect for FeColorMatrix {
    fn resolve(&self, node: &Node) -> Result<(Primitive, PrimitiveParams), FilterError> {
        let cascaded = CascadedValues::new_from_node(node);
        let values = cascaded.get();

        Ok((
            self.base.clone(),
            PrimitiveParams::ColorMatrix(ColorMatrix {
                in1: self.in1.clone(),
                matrix: self.matrix,
                color_interpolation_filters: values.color_interpolation_filters(),
            }),
        ))
    }
}

impl Parse for OperationType {
    fn parse<'i>(parser: &mut Parser<'i, '_>) -> Result<Self, ParseError<'i>> {
        Ok(parse_identifiers!(
            parser,
            "matrix" => OperationType::Matrix,
            "saturate" => OperationType::Saturate,
            "hueRotate" => OperationType::HueRotate,
            "luminanceToAlpha" => OperationType::LuminanceToAlpha,
        )?)
    }
}
<commit_msg>feColorMatrix: shorten code by implementing Default and Clone for its parameters<commit_after>use cssparser::Parser;
use markup5ever::{expanded_name, local_name, namespace_url, ns};
use nalgebra::{Matrix3, Matrix4x5, Matrix5, Vector5};

use crate::document::AcquiredNodes;
use crate::drawing_ctx::DrawingCtx;
use crate::element::{ElementResult, SetAttributes};
use crate::error::*;
use crate::node::{CascadedValues, Node};
use crate::parsers::{NumberList, NumberListLength, Parse, ParseValue};
use crate::property_defs::ColorInterpolationFilters;
use crate::surface_utils::{
    iterators::Pixels, shared_surface::ExclusiveImageSurface, ImageSurfaceDataExt, Pixel,
};
use crate::util::clamp;
use crate::xml::Attributes;

use super::context::{FilterContext, FilterOutput, FilterResult};
use super::{FilterEffect, FilterError, Input, Primitive, PrimitiveParams, ResolvedPrimitive};

/// Color matrix operation types.
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
enum OperationType {
    Matrix,
    Saturate,
    HueRotate,
    LuminanceToAlpha,
}

enum_default!(OperationType, OperationType::Matrix);

/// The `feColorMatrix` filter primitive.
#[derive(Default)]
pub struct FeColorMatrix {
    base: Primitive,
    params: ColorMatrix,
}

/// Resolved `feColorMatrix` primitive for rendering.
#[derive(Clone)]
pub struct ColorMatrix {
    in1: Input,
    matrix: Matrix5<f64>,
    color_interpolation_filters: ColorInterpolationFilters,
}

impl Default for ColorMatrix {
    fn default() -> ColorMatrix {
        ColorMatrix {
            in1: Default::default(),
            color_interpolation_filters: Default::default(),

            // nalgebra's Default for Matrix5 is all zeroes, so we actually need this :(
            matrix: Matrix5::identity(),
        }
    }
}

#[rustfmt::skip]
impl SetAttributes for FeColorMatrix {
    fn set_attributes(&mut self, attrs: &Attributes) -> ElementResult {
        self.params.in1 = self.base.parse_one_input(attrs)?;

        // First, determine the operation type.
        let mut operation_type = Default::default();
        for (attr, value) in attrs
            .iter()
            .filter(|(attr, _)| attr.expanded() == expanded_name!("", "type"))
        {
            operation_type = attr.parse(value)?;
        }

        // Now read the matrix correspondingly.
        // LuminanceToAlpha doesn't accept any matrix.
        if operation_type == OperationType::LuminanceToAlpha {
            self.params.matrix = {
                Matrix5::new(
                    0.0,    0.0,    0.0,    0.0, 0.0,
                    0.0,    0.0,    0.0,    0.0, 0.0,
                    0.0,    0.0,    0.0,    0.0, 0.0,
                    0.2125, 0.7154, 0.0721, 0.0, 0.0,
                    0.0,    0.0,    0.0,    0.0, 1.0,
                )
            };
        } else {
            for (attr, value) in attrs
                .iter()
                .filter(|(attr, _)| attr.expanded() == expanded_name!("", "values"))
            {
                let new_matrix = match operation_type {
                    OperationType::LuminanceToAlpha => unreachable!(),
                    OperationType::Matrix => {
                        let NumberList(v) =
                            NumberList::parse_str(value, NumberListLength::Exact(20))
                                .attribute(attr)?;
                        let matrix = Matrix4x5::from_row_slice(&v);
                        let mut matrix = matrix.fixed_resize(0.0);
                        matrix[(4, 4)] = 1.0;
                        matrix
                    }
                    OperationType::Saturate => {
                        let s: f64 = attr.parse(value)?;

                        Matrix5::new(
                            0.213 + 0.787 * s, 0.715 - 0.715 * s, 0.072 - 0.072 * s, 0.0, 0.0,
                            0.213 - 0.213 * s, 0.715 + 0.285 * s, 0.072 - 0.072 * s, 0.0, 0.0,
                            0.213 - 0.213 * s, 0.715 - 0.715 * s, 0.072 + 0.928 * s, 0.0, 0.0,
                            0.0,               0.0,               0.0,               1.0, 0.0,
                            0.0,               0.0,               0.0,               0.0, 1.0,
                        )
                    }
                    OperationType::HueRotate => {
                        let degrees: f64 = attr.parse(value)?;
                        let (sin, cos) = degrees.to_radians().sin_cos();

                        let a = Matrix3::new(
                            0.213, 0.715, 0.072,
                            0.213, 0.715, 0.072,
                            0.213, 0.715, 0.072,
                        );

                        let b = Matrix3::new(
                             0.787, -0.715, -0.072,
                            -0.213,  0.285, -0.072,
                            -0.213, -0.715,  0.928,
                        );

                        let c = Matrix3::new(
                            -0.213, -0.715,  0.928,
                             0.143,  0.140, -0.283,
                            -0.787,  0.715,  0.072,
                        );

                        let top_left = a + b * cos + c * sin;

                        let mut matrix = top_left.fixed_resize(0.0);
                        matrix[(3, 3)] = 1.0;
                        matrix[(4, 4)] = 1.0;
                        matrix
                    }
                };

                self.params.matrix = new_matrix;
            }
        }

        Ok(())
    }
}

impl ColorMatrix {
    pub fn render(
        &self,
        primitive: &ResolvedPrimitive,
        ctx: &FilterContext,
        acquired_nodes: &mut AcquiredNodes<'_>,
        draw_ctx: &mut DrawingCtx,
    ) -> Result<FilterResult, FilterError> {
        let input_1 = ctx.get_input(
            acquired_nodes,
            draw_ctx,
            &self.in1,
            self.color_interpolation_filters,
        )?;
        let bounds = primitive
            .get_bounds(ctx)?
            .add_input(&input_1)
            .into_irect(ctx, draw_ctx);

        let mut surface = ExclusiveImageSurface::new(
            ctx.source_graphic().width(),
            ctx.source_graphic().height(),
            input_1.surface().surface_type(),
        )?;

        surface.modify(&mut |data, stride| {
            for (x, y, pixel) in Pixels::within(input_1.surface(), bounds) {
                let alpha = f64::from(pixel.a) / 255f64;

                let pixel_vec = if alpha == 0.0 {
                    Vector5::new(0.0, 0.0, 0.0, 0.0, 1.0)
                } else {
                    Vector5::new(
                        f64::from(pixel.r) / 255f64 / alpha,
                        f64::from(pixel.g) / 255f64 / alpha,
                        f64::from(pixel.b) / 255f64 / alpha,
                        alpha,
                        1.0,
                    )
                };
                let mut new_pixel_vec = Vector5::zeros();
                self.matrix.mul_to(&pixel_vec, &mut new_pixel_vec);

                let new_alpha = clamp(new_pixel_vec[3], 0.0, 1.0);

                let premultiply = |x: f64| ((clamp(x, 0.0, 1.0) * new_alpha * 255f64) + 0.5) as u8;

                let output_pixel = Pixel {
                    r: premultiply(new_pixel_vec[0]),
                    g: premultiply(new_pixel_vec[1]),
                    b: premultiply(new_pixel_vec[2]),
                    a: ((new_alpha * 255f64) + 0.5) as u8,
                };

                data.set_pixel(stride, output_pixel, x, y);
            }
        });

        Ok(FilterResult {
            name: primitive.result.clone(),
            output: FilterOutput {
                surface: surface.share()?,
                bounds,
            },
        })
    }
}

impl FilterEffect for FeColorMatrix {
    fn resolve(&self, node: &Node) -> Result<(Primitive, PrimitiveParams), FilterError> {
        let cascaded = CascadedValues::new_from_node(node);
        let values = cascaded.get();

        let mut params = self.params.clone();
        params.color_interpolation_filters = values.color_interpolation_filters();

        Ok((self.base.clone(), PrimitiveParams::ColorMatrix(params)))
    }
}

impl Parse for OperationType {
    fn parse<'i>(parser: &mut Parser<'i, '_>) -> Result<Self, ParseError<'i>> {
        Ok(parse_identifiers!(
            parser,
            "matrix" => OperationType::Matrix,
            "saturate" => OperationType::Saturate,
            "hueRotate" => OperationType::HueRotate,
            "luminanceToAlpha" => OperationType::LuminanceToAlpha,
        )?)
    }
}
<|endoftext|>


<commit_before>/*
 * This file is part of the uutils findutils package.
 *
 * (c) Arcterus <arcterus@mail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

use std::env;
use std::fs::{self, FileType};
use std::io::{self, stderr, Write};
use std::path::{Path, PathBuf};

use walkdir::DirEntry;

use find::matchers::{Matcher, MatcherIO};

pub struct DeleteMatcher {
    current_dir: PathBuf,
}

impl DeleteMatcher {
    pub fn new() -> io::Result<DeleteMatcher> {
        Ok(DeleteMatcher {
            current_dir: env::current_dir()?,
        })
    }

    pub fn new_box() -> io::Result<Box<Matcher>> {
        Ok(Box::new(DeleteMatcher::new()?))
    }

    fn delete(&self, file_path: &Path, file_type: FileType) -> io::Result<()> {
        if file_type.is_dir() {
            fs::remove_dir(file_path)
        } else {
            fs::remove_file(file_path)
        }
    }
}

impl Matcher for DeleteMatcher {
    fn matches(&self, file_info: &DirEntry, _: &mut MatcherIO) -> bool {
        let path = file_info.path();
        if path == self.current_dir {
            return false;
        }

        match self.delete(path, file_info.file_type()) {
            Ok(_) => true,
            Err(f) => {
                writeln!(
                    &mut stderr(),
                    "Failed to delete {}: {}",
                    file_info.path().to_string_lossy(),
                    f
                )
                .unwrap();
                false
            }
        }
    }

    fn has_side_effects(&self) -> bool {
        true
    }
}

#[cfg(test)]
mod tests {}
<commit_msg>Fix use declarations in delete matcher<commit_after>/*
 * This file is part of the uutils findutils package.
 *
 * (c) Arcterus <arcterus@mail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

use std::env;
use std::fs::{self, FileType};
use std::io::{self, stderr, Write};
use std::path::{Path, PathBuf};

use walkdir::DirEntry;

use super::{Matcher, MatcherIO};

pub struct DeleteMatcher {
    current_dir: PathBuf,
}

impl DeleteMatcher {
    pub fn new() -> io::Result<DeleteMatcher> {
        Ok(DeleteMatcher {
            current_dir: env::current_dir()?,
        })
    }

    pub fn new_box() -> io::Result<Box<Matcher>> {
        Ok(Box::new(DeleteMatcher::new()?))
    }

    fn delete(&self, file_path: &Path, file_type: FileType) -> io::Result<()> {
        if file_type.is_dir() {
            fs::remove_dir(file_path)
        } else {
            fs::remove_file(file_path)
        }
    }
}

impl Matcher for DeleteMatcher {
    fn matches(&self, file_info: &DirEntry, _: &mut MatcherIO) -> bool {
        let path = file_info.path();
        if path == self.current_dir {
            return false;
        }

        match self.delete(path, file_info.file_type()) {
            Ok(_) => true,
            Err(f) => {
                writeln!(
                    &mut stderr(),
                    "Failed to delete {}: {}",
                    file_info.path().to_string_lossy(),
                    f
                )
                .unwrap();
                false
            }
        }
    }

    fn has_side_effects(&self) -> bool {
        true
    }
}

#[cfg(test)]
mod tests {}
<|endoftext|>


<commit_before>//! Functions for mapping over pixels, colors or subpixels of images.

use image::{
    GenericImage,
    ImageBuffer,
    Luma,
    Pixel,
    Primitive,
    Rgb,
    Rgba
};

use definitions::{
    Image
};

/// The type obtained by replacing the channel type of a given Pixel type.
pub trait WithChannel<C: Primitive>: Pixel {
    /// The new pixel type.
    type Pixel: Pixel<Subpixel=C> + 'static;
}

/// Alias to make uses of `WithChannel` less syntactically noisy.
pub type ChannelMap<Pix, Sub> = <Pix as WithChannel<Sub>>::Pixel;

impl<T, U> WithChannel<U> for Rgb<T>
    where T: Primitive + 'static,
          U: Primitive + 'static {
    type Pixel = Rgb<U>;
}

impl<T, U> WithChannel<U> for Rgba<T>
    where T: Primitive + 'static,
          U: Primitive + 'static {
    type Pixel = Rgba<U>;
}

impl<T, U> WithChannel<U> for Luma<T>
    where T: Primitive + 'static,
          U: Primitive + 'static {
    type Pixel = Luma<U>;
}

/// Applies f to each subpixel of the input image.
pub fn map_subpixels<I, P, F, S>(image: &I, f: F) -> Image<ChannelMap<P, S>>
    where I: GenericImage<Pixel=P>,
          P: WithChannel<S> + 'static,
          S: Primitive + 'static,
          F: Fn(P::Subpixel) -> S
{
    let (width, height) = image.dimensions();
    let mut out: ImageBuffer<ChannelMap<P, S>, Vec<S>> = ImageBuffer::new(width, height);

    for y in 0..height {
        for x in 0..width {
            let mut out_channels = out.get_pixel_mut(x, y).channels_mut();
            for c in 0..P::channel_count() {
                out_channels[c as usize]
                    = f(unsafe {*image.unsafe_get_pixel(x, y)
                        .channels().get_unchecked(c as usize) });
            }
        }
    }

    out
}

/// Applies f to the color of each pixel in the input image.
pub fn map_colors<I, P, Q, F>(image: &I, f: F) -> Image<Q>
    where I: GenericImage<Pixel=P>,
          P: Pixel,
          Q: Pixel + 'static,
          F: Fn(P) -> Q
{
    let (width, height) = image.dimensions();
    let mut out: ImageBuffer<Q, Vec<Q::Subpixel>> = ImageBuffer::new(width, height);

    for y in 0..height {
        for x in 0..width {
            unsafe {
                let pix = image.unsafe_get_pixel(x, y);
                out.unsafe_put_pixel(x, y, f(pix));
            }
        }
    }

    out
}

/// Applies f to each pixel in the input image.
pub fn map_pixels<I, P, Q, F>(image: &I, f: F) -> Image<Q>
    where I: GenericImage<Pixel=P>,
          P: Pixel,
          Q: Pixel + 'static,
          F: Fn(u32, u32, P) -> Q
{
    let (width, height) = image.dimensions();
    let mut out: ImageBuffer<Q, Vec<Q::Subpixel>> = ImageBuffer::new(width, height);

    for y in 0..height {
        for x in 0..width {
            unsafe {
                let pix = image.unsafe_get_pixel(x, y);
                out.unsafe_put_pixel(x, y, f(x, y, pix));
            }
        }
    }

    out
}

macro_rules! implement_channel_extraction {
    ($extract_name: ident, $embed_name: ident, $idx: expr) => (
        /// Create a grayscale image by extracting a channel of an RGB image.
        pub fn $extract_name<I, C>(image: &I) -> Image<Luma<C>>
            where I: GenericImage<Pixel=Rgb<C>>,
                  C: Primitive + 'static
        {
            map_colors(image, |p| Luma([p[$idx]]))
        }

        /// Create an RGB image by embedding a grayscale image in a single channel.
        pub fn $embed_name<I, C>(image: &I) -> Image<Rgb<C>>
            where I: GenericImage<Pixel=Luma<C>>,
                  C: Primitive + 'static
        {
            map_colors(image, |p| {
                let mut cs = [C::zero(); 3];
                cs[$idx] = p[0];
                Rgb(cs)
            })
        }
    )
}

implement_channel_extraction!(red_channel, as_red_channel, 0);
implement_channel_extraction!(green_channel, as_green_channel, 1);
implement_channel_extraction!(blue_channel, as_blue_channel, 2);

#[cfg(test)]
mod test {
    use super::{
        map_colors,
        map_pixels,
        map_subpixels,
        red_channel,
        green_channel,
        blue_channel,
        as_red_channel,
        as_green_channel,
        as_blue_channel
    };
    use image::{
        ImageBuffer,
        Rgb,
        RgbImage
    };

    #[test]
    fn test_map_subpixels() {
        let image = gray_image!(
            1, 2;
            3, 4);

        let expected = gray_image_i16!(
            -2i16, -4i16;
            -6i16, -8i16);

        let mapped = map_subpixels(&image, |x| -2 * (x as i16));
        assert_pixels_eq!(mapped, expected);
    }

    #[test]
    fn test_map_colors() {
        let image = gray_image!(
            1, 2;
            3, 4);

        let expected: ImageBuffer<Rgb<i16>, Vec<i16>> = ImageBuffer::from_raw(2, 2, vec![
            1i16, 2i16, 3i16, 2i16, 4i16, 6i16,
            3i16, 6i16, 9i16, 4i16, 8i16, 12i16]).unwrap();

        let mapped = map_colors(&image, |p| {
            let intensity = p[0] as i16;
            Rgb([intensity, (2 * intensity), (3 * intensity)])
        });
        assert_pixels_eq!(mapped, expected);
    }

    #[test]
    fn test_map_pixels() {
        let image = gray_image!(
            1, 2;
            3, 4);

        let expected: ImageBuffer<Rgb<i16>, Vec<i16>> = ImageBuffer::from_raw(2, 2, vec![
            1i16, 2i16, 3i16, 3i16, 5i16, 7i16,
            4i16, 7i16, 10i16, 6i16, 10i16, 14i16]).unwrap();

        let mapped = map_pixels(&image, |x, y, p| {
            let intensity = p[0] as i16;
            let offset = (x + y) as i16;
            Rgb([intensity + offset, 2 * intensity + offset, 3 * intensity + offset])
        });
        assert_pixels_eq!(mapped, expected);
    }

    #[test]
    fn test_red_channel() {
        let image: RgbImage = ImageBuffer::from_raw(2, 2, vec![
            1, 2, 3, 2, 4, 6,
            3, 6, 9, 4, 8, 12]).unwrap();

        let expected = gray_image!(
            1, 2;
            3, 4);

        let actual = red_channel(&image);
        assert_pixels_eq!(actual, expected);
    }

    #[test]
    fn test_green_channel() {
        let image: RgbImage = ImageBuffer::from_raw(2, 2, vec![
            1, 2, 3, 2, 4, 6,
            3, 6, 9, 4, 8, 12]).unwrap();

        let expected = gray_image!(
            2, 4;
            6, 8);

        let actual = green_channel(&image);
        assert_pixels_eq!(actual, expected);
    }

    #[test]
    fn test_blue_channel() {
        let image: RgbImage = ImageBuffer::from_raw(2, 2, vec![
            1, 2, 3, 2, 4, 6,
            3, 6, 9, 4, 8, 12]).unwrap();

        let expected = gray_image!(
            3, 6;
            9, 12);

        let actual = blue_channel(&image);
        assert_pixels_eq!(actual, expected);
    }

    #[test]
    fn test_as_red_channel() {
        let image = gray_image!(
            1, 2;
            3, 4);

        let expected: RgbImage = ImageBuffer::from_raw(2, 2, vec![
            1, 0, 0, 2, 0, 0,
            3, 0, 0, 4, 0, 0]).unwrap();

        let actual = as_red_channel(&image);
        assert_pixels_eq!(actual, expected);
    }

    #[test]
    fn test_as_green_channel() {
        let image = gray_image!(
            1, 2;
            3, 4);

        let expected: RgbImage = ImageBuffer::from_raw(2, 2, vec![
            0, 1, 0, 0, 2, 0,
            0, 3, 0, 0, 4, 0]).unwrap();

        let actual = as_green_channel(&image);
        assert_pixels_eq!(actual, expected);
    }

    #[test]
    fn test_as_blue_channel() {
        let image = gray_image!(
            1, 2;
            3, 4);

        let expected: RgbImage = ImageBuffer::from_raw(2, 2, vec![
            0, 0, 1, 0, 0, 2,
            0, 0, 3, 0, 0, 4]).unwrap();

        let actual = as_blue_channel(&image);
        assert_pixels_eq!(actual, expected);
    }
}
<commit_msg>Add map_colors2<commit_after>//! Functions for mapping over pixels, colors or subpixels of images.

use image::{
    GenericImage,
    ImageBuffer,
    Luma,
    Pixel,
    Primitive,
    Rgb,
    Rgba
};

use definitions::{
    Image
};

/// The type obtained by replacing the channel type of a given Pixel type.
pub trait WithChannel<C: Primitive>: Pixel {
    /// The new pixel type.
    type Pixel: Pixel<Subpixel=C> + 'static;
}

/// Alias to make uses of `WithChannel` less syntactically noisy.
pub type ChannelMap<Pix, Sub> = <Pix as WithChannel<Sub>>::Pixel;

impl<T, U> WithChannel<U> for Rgb<T>
    where T: Primitive + 'static,
          U: Primitive + 'static {
    type Pixel = Rgb<U>;
}

impl<T, U> WithChannel<U> for Rgba<T>
    where T: Primitive + 'static,
          U: Primitive + 'static {
    type Pixel = Rgba<U>;
}

impl<T, U> WithChannel<U> for Luma<T>
    where T: Primitive + 'static,
          U: Primitive + 'static {
    type Pixel = Luma<U>;
}

/// Applies f to each subpixel of the input image.
pub fn map_subpixels<I, P, F, S>(image: &I, f: F) -> Image<ChannelMap<P, S>>
    where I: GenericImage<Pixel=P>,
          P: WithChannel<S> + 'static,
          S: Primitive + 'static,
          F: Fn(P::Subpixel) -> S
{
    let (width, height) = image.dimensions();
    let mut out: ImageBuffer<ChannelMap<P, S>, Vec<S>> = ImageBuffer::new(width, height);

    for y in 0..height {
        for x in 0..width {
            let mut out_channels = out.get_pixel_mut(x, y).channels_mut();
            for c in 0..P::channel_count() {
                out_channels[c as usize]
                    = f(unsafe {*image.unsafe_get_pixel(x, y)
                        .channels().get_unchecked(c as usize) });
            }
        }
    }

    out
}

/// Applies f to the color of each pixel in the input image.
pub fn map_colors<I, P, Q, F>(image: &I, f: F) -> Image<Q>
    where I: GenericImage<Pixel=P>,
          P: Pixel,
          Q: Pixel + 'static,
          F: Fn(P) -> Q
{
    let (width, height) = image.dimensions();
    let mut out: ImageBuffer<Q, Vec<Q::Subpixel>> = ImageBuffer::new(width, height);

    for y in 0..height {
        for x in 0..width {
            unsafe {
                let pix = image.unsafe_get_pixel(x, y);
                out.unsafe_put_pixel(x, y, f(pix));
            }
        }
    }

    out
}

/// Applies f to the colors of the pixels in the input images.
///
/// Requires `image1` and `image2` to have the same dimensions.
/// # Examples
/// ```
/// # extern crate image;
/// # #[macro_use]
/// # extern crate imageproc;
/// # fn main() {
/// use image::{GrayImage, Luma};
/// use imageproc::map::map_colors2;
///
/// let image1 = gray_image!(
///     1, 2,
///     3, 4
/// );
///
/// let image2 = gray_image!(
///     10, 20,
///     30, 40
/// );
///
/// let sum = gray_image!(
///     11, 22,
///     33, 44
/// );
///
/// assert_pixels_eq!(
///     map_colors2(&image1, &image2, |p, q| Luma([p[0] + q[0]])),
///     sum
/// );
/// # }
/// ```
pub fn map_colors2<I, J, P, Q, R, F>(image1: &I, image2: &J, f: F) -> Image<R>
    where I: GenericImage<Pixel=P>,
          J: GenericImage<Pixel=Q>,
          P: Pixel,
          Q: Pixel,
          R: Pixel + 'static,
          F: Fn(P, Q) -> R
{
    assert_eq!(image1.dimensions(), image2.dimensions());

    let (width, height) = image1.dimensions();
    let mut out: ImageBuffer<R, Vec<R::Subpixel>> = ImageBuffer::new(width, height);

    for y in 0..height {
        for x in 0..width {
            unsafe {
                let p = image1.unsafe_get_pixel(x, y);
                let q = image2.unsafe_get_pixel(x, y);
                out.unsafe_put_pixel(x, y, f(p, q));
            }
        }
    }

    out
}

/// Applies f to each pixel in the input image.
pub fn map_pixels<I, P, Q, F>(image: &I, f: F) -> Image<Q>
    where I: GenericImage<Pixel=P>,
          P: Pixel,
          Q: Pixel + 'static,
          F: Fn(u32, u32, P) -> Q
{
    let (width, height) = image.dimensions();
    let mut out: ImageBuffer<Q, Vec<Q::Subpixel>> = ImageBuffer::new(width, height);

    for y in 0..height {
        for x in 0..width {
            unsafe {
                let pix = image.unsafe_get_pixel(x, y);
                out.unsafe_put_pixel(x, y, f(x, y, pix));
            }
        }
    }

    out
}

macro_rules! implement_channel_extraction {
    ($extract_name: ident, $embed_name: ident, $idx: expr) => (
        /// Create a grayscale image by extracting a channel of an RGB image.
        pub fn $extract_name<I, C>(image: &I) -> Image<Luma<C>>
            where I: GenericImage<Pixel=Rgb<C>>,
                  C: Primitive + 'static
        {
            map_colors(image, |p| Luma([p[$idx]]))
        }

        /// Create an RGB image by embedding a grayscale image in a single channel.
        pub fn $embed_name<I, C>(image: &I) -> Image<Rgb<C>>
            where I: GenericImage<Pixel=Luma<C>>,
                  C: Primitive + 'static
        {
            map_colors(image, |p| {
                let mut cs = [C::zero(); 3];
                cs[$idx] = p[0];
                Rgb(cs)
            })
        }
    )
}

implement_channel_extraction!(red_channel, as_red_channel, 0);
implement_channel_extraction!(green_channel, as_green_channel, 1);
implement_channel_extraction!(blue_channel, as_blue_channel, 2);

#[cfg(test)]
mod test {
    use super::{
        map_colors,
        map_pixels,
        map_subpixels,
        red_channel,
        green_channel,
        blue_channel,
        as_red_channel,
        as_green_channel,
        as_blue_channel
    };
    use image::{
        ImageBuffer,
        Rgb,
        RgbImage
    };

    #[test]
    fn test_map_subpixels() {
        let image = gray_image!(
            1, 2;
            3, 4);

        let expected = gray_image_i16!(
            -2i16, -4i16;
            -6i16, -8i16);

        let mapped = map_subpixels(&image, |x| -2 * (x as i16));
        assert_pixels_eq!(mapped, expected);
    }

    #[test]
    fn test_map_colors() {
        let image = gray_image!(
            1, 2;
            3, 4);

        let expected: ImageBuffer<Rgb<i16>, Vec<i16>> = ImageBuffer::from_raw(2, 2, vec![
            1i16, 2i16, 3i16, 2i16, 4i16, 6i16,
            3i16, 6i16, 9i16, 4i16, 8i16, 12i16]).unwrap();

        let mapped = map_colors(&image, |p| {
            let intensity = p[0] as i16;
            Rgb([intensity, (2 * intensity), (3 * intensity)])
        });
        assert_pixels_eq!(mapped, expected);
    }

    #[test]
    fn test_map_pixels() {
        let image = gray_image!(
            1, 2;
            3, 4);

        let expected: ImageBuffer<Rgb<i16>, Vec<i16>> = ImageBuffer::from_raw(2, 2, vec![
            1i16, 2i16, 3i16, 3i16, 5i16, 7i16,
            4i16, 7i16, 10i16, 6i16, 10i16, 14i16]).unwrap();

        let mapped = map_pixels(&image, |x, y, p| {
            let intensity = p[0] as i16;
            let offset = (x + y) as i16;
            Rgb([intensity + offset, 2 * intensity + offset, 3 * intensity + offset])
        });
        assert_pixels_eq!(mapped, expected);
    }

    #[test]
    fn test_red_channel() {
        let image: RgbImage = ImageBuffer::from_raw(2, 2, vec![
            1, 2, 3, 2, 4, 6,
            3, 6, 9, 4, 8, 12]).unwrap();

        let expected = gray_image!(
            1, 2;
            3, 4);

        let actual = red_channel(&image);
        assert_pixels_eq!(actual, expected);
    }

    #[test]
    fn test_green_channel() {
        let image: RgbImage = ImageBuffer::from_raw(2, 2, vec![
            1, 2, 3, 2, 4, 6,
            3, 6, 9, 4, 8, 12]).unwrap();

        let expected = gray_image!(
            2, 4;
            6, 8);

        let actual = green_channel(&image);
        assert_pixels_eq!(actual, expected);
    }

    #[test]
    fn test_blue_channel() {
        let image: RgbImage = ImageBuffer::from_raw(2, 2, vec![
            1, 2, 3, 2, 4, 6,
            3, 6, 9, 4, 8, 12]).unwrap();

        let expected = gray_image!(
            3, 6;
            9, 12);

        let actual = blue_channel(&image);
        assert_pixels_eq!(actual, expected);
    }

    #[test]
    fn test_as_red_channel() {
        let image = gray_image!(
            1, 2;
            3, 4);

        let expected: RgbImage = ImageBuffer::from_raw(2, 2, vec![
            1, 0, 0, 2, 0, 0,
            3, 0, 0, 4, 0, 0]).unwrap();

        let actual = as_red_channel(&image);
        assert_pixels_eq!(actual, expected);
    }

    #[test]
    fn test_as_green_channel() {
        let image = gray_image!(
            1, 2;
            3, 4);

        let expected: RgbImage = ImageBuffer::from_raw(2, 2, vec![
            0, 1, 0, 0, 2, 0,
            0, 3, 0, 0, 4, 0]).unwrap();

        let actual = as_green_channel(&image);
        assert_pixels_eq!(actual, expected);
    }

    #[test]
    fn test_as_blue_channel() {
        let image = gray_image!(
            1, 2;
            3, 4);

        let expected: RgbImage = ImageBuffer::from_raw(2, 2, vec![
            0, 0, 1, 0, 0, 2,
            0, 0, 3, 0, 0, 4]).unwrap();

        let actual = as_blue_channel(&image);
        assert_pixels_eq!(actual, expected);
    }
}
<|endoftext|>


<commit_before>//! The integration suite for inspecting sessions.

extern crate libc;
extern crate rand;
extern crate regex;

mod helpers;

mod open {
    use rand::{random};
    use std::fs::File;
    use std::fs;
    use std::path::PathBuf;
    use std::io::prelude::*;
    use helpers::*;

    fn setup(contents: &'static [u8]) -> (String, PathBuf) {
        let project_name = format!("muxed_int_test_{}", random::<u16>());
        let project_file = format!("/tmp/muxed_{}/{}.yml", random::<u16>(), project_name);
        let project_path = PathBuf::from(&project_file);

        let muxed_path = project_path.parent().unwrap();
        if !muxed_path.exists() { println!("{:?}", fs::create_dir(muxed_path)) };

        let mut buffer = File::create(&project_path).unwrap();
        let _ = buffer.write(contents);

        (project_name, project_path.clone())
    }

    fn cleanup(project_name: &String, config_path: &PathBuf) -> () {
        let _ = fs::remove_file(config_path);
        let _ = fs::remove_dir(config_path.parent().unwrap());
        kill_session(&project_name);
    }

    fn test_with_contents(contents: &'static [u8]) -> TmuxSession {
        let (project_name, config_path) = setup(contents);
        open_muxed(&project_name, config_path.parent().unwrap());
        let completed = PathBuf::from(format!("/tmp/{}.complete", project_name));
        let exec = format!("touch {}", completed.display());
        send_keys(&project_name, &exec);
        wait_on(&completed);
        let session = TmuxSession::from_string(&list_windows(&project_name.to_string()));
        cleanup(&project_name, &config_path);
        session
    }

    #[test]
    fn opens_3_windows_from_array() {
        let contents = b"---
windows: ['vi', 'ls', 'git']
";
        let session = test_with_contents(contents);
        assert_eq!(session.num_of_windows, 3)
    }

    #[test]
    fn opens_2_windows() {
        let contents = b"---
windows:
  - editor:
      layout: 'main-vertical'
      panes: ['vi', 'ls']
  - stuff: ''
";
        let session = test_with_contents(contents);
        assert_eq!(session.num_of_windows, 2)
    }

    #[test]
    fn opens_3_windows_with_integer_names() {
        let contents = b"---
windows: [1, 'ls', 3]
";
        let session = test_with_contents(contents);
        assert_eq!(session.num_of_windows, 3)
    }

    #[test]
    fn single_window_has_2_panes() {
        let contents = b"---
windows:
  - editor:
      layout: 'main-vertical'
      panes: ['vi', 'ls']
";
        let session = test_with_contents(contents);
        let num = session.windows.get("editor").unwrap().get("Panes").unwrap().to_owned();
        assert_eq!(num, 2)
    }

    #[test]
    fn multiple_windows_with_panes() {
        let contents = b"---
windows:
  - editor:
      layout: 'main-vertical'
      panes: ['vi', 'ls']
  - tests:
      layout: 'main-vertical'
      panes: ['vi', 'ls', 'ls']
";
        let session = test_with_contents(contents);
        let num = session.windows.get("editor").unwrap().get("Panes").unwrap().to_owned();
        let num1 = session.windows.get("tests").unwrap().get("Panes").unwrap().to_owned();
        assert_eq!(num, 2);
        assert_eq!(num1, 3)
    }

    #[test]
    fn window_with_empty_command_is_valid() {
        let contents = b"---
windows:
  - editor:
";
        let session = test_with_contents(contents);
        assert_eq!(session.num_of_windows, 1)
    }

    #[test]
    fn panes_with_empty_commands_are_valid() {
        let contents = b"---
windows:
  - editor:
      layout: 'main-vertical'
      panes:
        -
        -
";
        let session = test_with_contents(contents);
        let num = session.windows.get("editor").unwrap().get("Panes").unwrap().to_owned();
        assert_eq!(num, 2)
    }

    #[test]
    fn expect_to_open_in_directory_containing_spaces() {
        let dir = PathBuf::from("/tmp/Directory With Spaces/");
        if !dir.exists() { println!("{:?}", fs::create_dir(&dir)) };
        let contents = b"---
root: /tmp/Directory With Spaces/
windows:
  - editor: ''
";
        let session = test_with_contents(contents);
        let active_dir = session.active_dir;
        let _ = fs::remove_dir(dir);
        assert_eq!(active_dir, "/tmp/Directory With Spaces");
    }
}
<commit_msg>issue-9 Windows the default focus to vi interupt the creation of the integration completion file.<commit_after>//! The integration suite for inspecting sessions.

extern crate libc;
extern crate rand;
extern crate regex;

mod helpers;

mod open {
    use rand::{random};
    use std::fs::File;
    use std::fs;
    use std::path::PathBuf;
    use std::io::prelude::*;
    use helpers::*;

    fn setup(contents: &'static [u8]) -> (String, PathBuf) {
        let project_name = format!("muxed_int_test_{}", random::<u16>());
        let project_file = format!("/tmp/muxed_{}/{}.yml", random::<u16>(), project_name);
        let project_path = PathBuf::from(&project_file);

        let muxed_path = project_path.parent().unwrap();
        if !muxed_path.exists() { println!("{:?}", fs::create_dir(muxed_path)) };

        let mut buffer = File::create(&project_path).unwrap();
        let _ = buffer.write(contents);

        (project_name, project_path.clone())
    }

    fn cleanup(project_name: &String, config_path: &PathBuf) -> () {
        let _ = fs::remove_file(config_path);
        let _ = fs::remove_dir(config_path.parent().unwrap());
        kill_session(&project_name);
    }

    fn test_with_contents(contents: &'static [u8]) -> TmuxSession {
        let (project_name, config_path) = setup(contents);
        open_muxed(&project_name, config_path.parent().unwrap());
        let completed = PathBuf::from(format!("/tmp/{}.complete", project_name));
        let exec = format!("touch {}", completed.display());
        send_keys(&project_name, &exec);
        wait_on(&completed);
        let session = TmuxSession::from_string(&list_windows(&project_name.to_string()));
        cleanup(&project_name, &config_path);
        session
    }

    #[test]
    fn opens_3_windows_from_array() {
        let contents = b"---
windows: ['ls', 'vi', 'git']
";
        let session = test_with_contents(contents);
        assert_eq!(session.num_of_windows, 3)
    }

    #[test]
    fn opens_2_windows() {
        let contents = b"---
windows:
  - editor:
      layout: 'main-vertical'
      panes: ['ls', 'vi']
  - stuff: ''
";
        let session = test_with_contents(contents);
        assert_eq!(session.num_of_windows, 2)
    }

    #[test]
    fn opens_3_windows_with_integer_names() {
        let contents = b"---
windows: [1, 'ls', 3]
";
        let session = test_with_contents(contents);
        assert_eq!(session.num_of_windows, 3)
    }

    #[test]
    fn single_window_has_2_panes() {
        let contents = b"---
windows:
  - editor:
      layout: 'main-vertical'
      panes: ['ls', 'vi']
";
        let session = test_with_contents(contents);
        let num = session.windows.get("editor").unwrap().get("Panes").unwrap().to_owned();
        assert_eq!(num, 2)
    }

    #[test]
    fn multiple_windows_with_panes() {
        let contents = b"---
windows:
  - editor:
      layout: 'main-vertical'
      panes: ['ls', 'vi']
  - tests:
      layout: 'main-vertical'
      panes: ['ls', 'vi', 'ls']
";
        let session = test_with_contents(contents);
        let num = session.windows.get("editor").unwrap().get("Panes").unwrap().to_owned();
        let num1 = session.windows.get("tests").unwrap().get("Panes").unwrap().to_owned();
        assert_eq!(num, 2);
        assert_eq!(num1, 3)
    }

    #[test]
    fn window_with_empty_command_is_valid() {
        let contents = b"---
windows:
  - editor:
";
        let session = test_with_contents(contents);
        assert_eq!(session.num_of_windows, 1)
    }

    #[test]
    fn panes_with_empty_commands_are_valid() {
        let contents = b"---
windows:
  - editor:
      layout: 'main-vertical'
      panes:
        -
        -
";
        let session = test_with_contents(contents);
        let num = session.windows.get("editor").unwrap().get("Panes").unwrap().to_owned();
        assert_eq!(num, 2)
    }

    #[test]
    fn expect_to_open_in_directory_containing_spaces() {
        let dir = PathBuf::from("/tmp/Directory With Spaces/");
        if !dir.exists() { println!("{:?}", fs::create_dir(&dir)) };
        let contents = b"---
root: /tmp/Directory With Spaces/
windows:
  - editor: ''
";
        let session = test_with_contents(contents);
        let active_dir = session.active_dir;
        let _ = fs::remove_dir(dir);
        assert_eq!(active_dir, "/tmp/Directory With Spaces");
    }
}
<|endoftext|>


<commit_before>use std::cell::{Cell, RefCell};
use std::io::{Read, Seek, SeekFrom, ErrorKind, Result, Error};
use std::fs::File;
use std::str;

extern crate positioned_io;
extern crate byteorder;
use self::byteorder::LittleEndian;

use positioned_io::{ReadAt, WriteAt, Size, Cursor, SizeCursor, ByteIo, Slice};

#[test]
fn test_read_at() {
    let file = File::open("Cargo.toml").unwrap();
    let mut buf = [0; 4];
    file.read_exact_at(10, buf.as_mut()).unwrap();
    let s = str::from_utf8(buf.as_ref()).unwrap();
    assert_eq!(s, "name");
}

#[test]
fn test_mixed_read() {
    let mut file = File::open("tests/pi.txt").unwrap();
    let mut buf = [0; 4];
    file.read_exact(&mut buf[..]).unwrap();
    assert_eq!(&buf, b"3.14");
    file.read_exact_at(764, &mut buf[..]).unwrap();
    assert_eq!(&buf, b"9999");
    file.read_exact(&mut buf[..]).unwrap();
    assert_eq!(&buf, b"1592");
}

// A ReadAt that has weird behavior.
struct ReadCustom<I: ReadAt, F: Fn() -> Result<usize>> {
    i: I,
    fail: Cell<bool>,
    onfail: F,
}
impl<I: ReadAt, F: Fn() -> Result<usize>> ReadCustom<I, F> {
    fn new(i: I, f: F) -> Self {
        ReadCustom {
            i: i,
            fail: Cell::new(true),
            onfail: f,
        }
    }
}
impl<I: ReadAt, F: Fn() -> Result<usize>> ReadAt for ReadCustom<I, F> {
    fn read_at(&self, pos: u64, buf: &mut [u8]) -> Result<usize> {
        let fail = self.fail.get();
        self.fail.set(!fail);
        if fail {
            (self.onfail)()
        } else {
            self.i.read_at(pos, buf)
        }
    }
}

#[test]
fn test_read_fails() {
    // Test interrupts.
    let file = File::open("Cargo.toml").unwrap();
    let mut buf = [0; 4];
    {
        let interrupt = ReadCustom::new(&file,
                                    || Err(Error::new(ErrorKind::Interrupted, "interrupt!")));
        interrupt.read_exact_at(10, buf.as_mut()).unwrap();
        let s = str::from_utf8(buf.as_ref()).unwrap();
        assert_eq!(s, "name");
    }

    // Test errors.
    {
        let fail = ReadCustom::new(&file, || Err(Error::new(ErrorKind::Other, "random fail")));
        assert!(fail.read_exact_at(10, buf.as_mut()).is_err());
    }

    // Test EOF.
    assert!(file.read_exact_at(10000, buf.as_mut()).is_err());
}

#[test]
fn test_size() {
    let file = File::open("Cargo.toml").unwrap();
    let size = file.size().unwrap().unwrap();
    assert!(size > 0);
}

#[test]
fn test_cursor() {
    let file = File::open("Cargo.toml").unwrap();
    let mut curs = Cursor::new_pos(file, 10);
    let mut buf = [0; 4];
    {
        curs.read_exact(&mut buf).unwrap();
        let s = str::from_utf8(buf.as_ref()).unwrap();
        assert_eq!("name", s);
    }
    curs.seek(SeekFrom::Current(4)).unwrap();
    curs.read_exact(&mut buf).unwrap();
    let s = str::from_utf8(buf.as_ref()).unwrap();
    assert_eq!("posi", s);
}

#[test]
fn test_size_cursor() {
    let file = File::open("Cargo.toml").unwrap();
    let mut curs = SizeCursor::new_pos(file, 10);
    let mut buf = [0; 4];
    curs.seek(SeekFrom::End(-2)).unwrap();
    assert_eq!(2, curs.read(&mut buf).unwrap());
    let s = str::from_utf8(buf.as_ref()).unwrap();
    assert!(s.contains("\n"));
}

#[test]
fn test_byteio() {
    let file = File::open("Cargo.toml").unwrap();
    let io: ByteIo<_, LittleEndian> = ByteIo::new(file);
    let r = io.read_i32_at(3).unwrap();
    assert_eq!(0x67616b63, r);
}

#[test]
fn test_vector() {
    // Write past the end.
    let mut v = vec![0, 1, 2, 3];
    let buf = [4, 5, 6, 7];
    (&mut v).write_all_at(2, &buf).unwrap();
    assert_eq!(vec![0, 1, 4, 5, 6, 7], v);
}

#[test]
fn test_slice() {
    let mut v = vec![0, 1, 2, 3, 4, 5];
    {
        // Read too much, limited by size.
        let mut buf = [9; 4];
        let slice = Slice::new(&mut v, 2, Some(3));
        let bytes = slice.read_at(2, &mut buf).unwrap();
        assert_eq!(bytes, 1);
        assert_eq!(buf, [4, 9, 9, 9]);

        // Read too much, limited by buf
        let mut buf = [9; 2];
        let bytes = slice.read_at(1, &mut buf).unwrap();
        assert_eq!(bytes, 2);
        assert_eq!(buf, [3, 4]);
    }

    {
        // Read too much, limited by original vec.
        let slice = Slice::new(&mut v, 2, Some(5));
        let mut buf = [9; 6];
        let bytes = slice.read_at(2, &mut buf).unwrap();
        assert_eq!(bytes, 2);
        assert_eq!(buf, [4, 5, 9, 9, 9, 9]);
    }

    {
        // Read too much of unsized slice.
        let slice = Slice::new(&mut v, 2, None);
        let mut buf = [9; 6];
        let bytes = slice.read_at(2, &mut buf).unwrap();
        assert_eq!(bytes, 2);
        assert_eq!(buf, [4, 5, 9, 9, 9, 9]);
    }

    // Interleaved read/write to same slice.
    let mut v = vec![0, 1, 2, 3, 4, 5];
    {
        let mut slice = Slice::new(&mut v, 2, Some(3));
        let mut buf = [9; 3];
        {
            let bytes = slice.write_at(2, &buf).unwrap();
            assert_eq!(bytes, 1);
        }
        {
            let bytes = slice.read_at(1, &mut buf).unwrap();
            assert_eq!(bytes, 2);
        }
        assert_eq!(buf, [3, 9, 9]);
        {
            let bytes = slice.write_at(0, &buf[..1]).unwrap();
            assert_eq!(bytes, 1);
        }
    }
    assert_eq!(v, vec![0, 1, 3, 3, 9, 5]);

    // Write past end.
    let mut v = vec![0, 1, 2, 3];
    let buf = [9; 6];
    // Limited by size.
    {
        let mut slice = Slice::new(&mut v, 2, Some(5));
        let bytes = slice.write_at(1, &buf).unwrap();
        assert_eq!(bytes, 4);
    }
    assert_eq!(v, vec![0, 1, 2, 9, 9, 9, 9]);
    // No size.
    {
        let mut slice = Slice::new(&mut v, 2, None);
        let bytes = slice.write_at(1, &buf).unwrap();
        assert_eq!(bytes, 6);
    }
    assert_eq!(v, vec![0, 1, 2, 9, 9, 9, 9, 9, 9]);

    // Automatic-size constructor.
    let mut v = vec![0, 1, 2, 3];
    {
        let mut slice = Slice::new_to_end(&mut v, 1).unwrap();
        assert_eq!(slice.size().unwrap().unwrap(), 3);
        let bytes = slice.write_at(0, &buf).unwrap();
        assert_eq!(bytes, 3);
    }
    assert_eq!(v, vec![0, 9, 9, 9]);

    // Slice of slice.
    let mut v = vec![0, 1, 2, 3, 4, 5];
    {
        let mut slice1 = Slice::new(&mut v, 1, Some(4));
        let mut slice2 = Slice::new(&mut slice1, 1, Some(2));
        let bytes = slice2.write_at(0, &buf).unwrap();
        assert_eq!(bytes, 2);
    }
    assert_eq!(v, vec![0, 1, 9, 9, 4, 5]);
}

#[test]
fn test_refcell() {
    let mut buf = [0; 3];

    // Make sure we can instantiate a bunch of combinations.
    let mut a = [0, 1, 2, 3];
    a.as_ref().read_at(0, &mut buf).unwrap();
    a.as_mut().write_at(0, &buf).unwrap();

    let mut v = vec![0, 1, 2, 3];
    v.read_at(0, &mut buf).unwrap();
    v.write_at(0, &buf).unwrap();

    let mut ra = &RefCell::new(a.as_mut());
    ra.read_at(0, &mut buf).unwrap();
    ra.write_at(0, &buf).unwrap();

    let mut rv = &RefCell::new(&mut v);
    rv.read_at(0, &mut buf).unwrap();
    rv.write_at(0, &buf).unwrap();

    // Test writing but still being able to use, thanks to RefCell.
    let mut v = vec![0, 1, 2, 3];
    let mut rv = &RefCell::new(&mut v);
    let buf = [9; 4];
    rv.write_at(0, &buf).unwrap();
    assert_eq!(*rv.borrow(), &vec![9; 4]);
}
<commit_msg>make test_read_at line delimiter independent<commit_after>use std::cell::{Cell, RefCell};
use std::io::{Read, Seek, SeekFrom, ErrorKind, Result, Error};
use std::fs::File;
use std::str;

extern crate positioned_io;
extern crate byteorder;
use self::byteorder::LittleEndian;

use positioned_io::{ReadAt, WriteAt, Size, Cursor, SizeCursor, ByteIo, Slice};

#[test]
fn test_read_at() {
    let file = File::open("tests/pi.txt").unwrap();
    let mut buf = [0; 4];
    file.read_exact_at(10, buf.as_mut()).unwrap();
    assert_eq!(&buf, b"3589");
}

#[test]
fn test_mixed_read() {
    let mut file = File::open("tests/pi.txt").unwrap();
    let mut buf = [0; 4];
    file.read_exact(&mut buf[..]).unwrap();
    assert_eq!(&buf, b"3.14");
    file.read_exact_at(764, &mut buf[..]).unwrap();
    assert_eq!(&buf, b"9999");
    file.read_exact(&mut buf[..]).unwrap();
    assert_eq!(&buf, b"1592");
}

// A ReadAt that has weird behavior.
struct ReadCustom<I: ReadAt, F: Fn() -> Result<usize>> {
    i: I,
    fail: Cell<bool>,
    onfail: F,
}
impl<I: ReadAt, F: Fn() -> Result<usize>> ReadCustom<I, F> {
    fn new(i: I, f: F) -> Self {
        ReadCustom {
            i: i,
            fail: Cell::new(true),
            onfail: f,
        }
    }
}
impl<I: ReadAt, F: Fn() -> Result<usize>> ReadAt for ReadCustom<I, F> {
    fn read_at(&self, pos: u64, buf: &mut [u8]) -> Result<usize> {
        let fail = self.fail.get();
        self.fail.set(!fail);
        if fail {
            (self.onfail)()
        } else {
            self.i.read_at(pos, buf)
        }
    }
}

#[test]
fn test_read_fails() {
    // Test interrupts.
    let file = File::open("Cargo.toml").unwrap();
    let mut buf = [0; 4];
    {
        let interrupt = ReadCustom::new(&file,
                                    || Err(Error::new(ErrorKind::Interrupted, "interrupt!")));
        interrupt.read_exact_at(10, buf.as_mut()).unwrap();
        let s = str::from_utf8(buf.as_ref()).unwrap();
        assert_eq!(s, "name");
    }

    // Test errors.
    {
        let fail = ReadCustom::new(&file, || Err(Error::new(ErrorKind::Other, "random fail")));
        assert!(fail.read_exact_at(10, buf.as_mut()).is_err());
    }

    // Test EOF.
    assert!(file.read_exact_at(10000, buf.as_mut()).is_err());
}

#[test]
fn test_size() {
    let file = File::open("Cargo.toml").unwrap();
    let size = file.size().unwrap().unwrap();
    assert!(size > 0);
}

#[test]
fn test_cursor() {
    let file = File::open("Cargo.toml").unwrap();
    let mut curs = Cursor::new_pos(file, 10);
    let mut buf = [0; 4];
    {
        curs.read_exact(&mut buf).unwrap();
        let s = str::from_utf8(buf.as_ref()).unwrap();
        assert_eq!("name", s);
    }
    curs.seek(SeekFrom::Current(4)).unwrap();
    curs.read_exact(&mut buf).unwrap();
    let s = str::from_utf8(buf.as_ref()).unwrap();
    assert_eq!("posi", s);
}

#[test]
fn test_size_cursor() {
    let file = File::open("Cargo.toml").unwrap();
    let mut curs = SizeCursor::new_pos(file, 10);
    let mut buf = [0; 4];
    curs.seek(SeekFrom::End(-2)).unwrap();
    assert_eq!(2, curs.read(&mut buf).unwrap());
    let s = str::from_utf8(buf.as_ref()).unwrap();
    assert!(s.contains("\n"));
}

#[test]
fn test_byteio() {
    let file = File::open("Cargo.toml").unwrap();
    let io: ByteIo<_, LittleEndian> = ByteIo::new(file);
    let r = io.read_i32_at(3).unwrap();
    assert_eq!(0x67616b63, r);
}

#[test]
fn test_vector() {
    // Write past the end.
    let mut v = vec![0, 1, 2, 3];
    let buf = [4, 5, 6, 7];
    (&mut v).write_all_at(2, &buf).unwrap();
    assert_eq!(vec![0, 1, 4, 5, 6, 7], v);
}

#[test]
fn test_slice() {
    let mut v = vec![0, 1, 2, 3, 4, 5];
    {
        // Read too much, limited by size.
        let mut buf = [9; 4];
        let slice = Slice::new(&mut v, 2, Some(3));
        let bytes = slice.read_at(2, &mut buf).unwrap();
        assert_eq!(bytes, 1);
        assert_eq!(buf, [4, 9, 9, 9]);

        // Read too much, limited by buf
        let mut buf = [9; 2];
        let bytes = slice.read_at(1, &mut buf).unwrap();
        assert_eq!(bytes, 2);
        assert_eq!(buf, [3, 4]);
    }

    {
        // Read too much, limited by original vec.
        let slice = Slice::new(&mut v, 2, Some(5));
        let mut buf = [9; 6];
        let bytes = slice.read_at(2, &mut buf).unwrap();
        assert_eq!(bytes, 2);
        assert_eq!(buf, [4, 5, 9, 9, 9, 9]);
    }

    {
        // Read too much of unsized slice.
        let slice = Slice::new(&mut v, 2, None);
        let mut buf = [9; 6];
        let bytes = slice.read_at(2, &mut buf).unwrap();
        assert_eq!(bytes, 2);
        assert_eq!(buf, [4, 5, 9, 9, 9, 9]);
    }

    // Interleaved read/write to same slice.
    let mut v = vec![0, 1, 2, 3, 4, 5];
    {
        let mut slice = Slice::new(&mut v, 2, Some(3));
        let mut buf = [9; 3];
        {
            let bytes = slice.write_at(2, &buf).unwrap();
            assert_eq!(bytes, 1);
        }
        {
            let bytes = slice.read_at(1, &mut buf).unwrap();
            assert_eq!(bytes, 2);
        }
        assert_eq!(buf, [3, 9, 9]);
        {
            let bytes = slice.write_at(0, &buf[..1]).unwrap();
            assert_eq!(bytes, 1);
        }
    }
    assert_eq!(v, vec![0, 1, 3, 3, 9, 5]);

    // Write past end.
    let mut v = vec![0, 1, 2, 3];
    let buf = [9; 6];
    // Limited by size.
    {
        let mut slice = Slice::new(&mut v, 2, Some(5));
        let bytes = slice.write_at(1, &buf).unwrap();
        assert_eq!(bytes, 4);
    }
    assert_eq!(v, vec![0, 1, 2, 9, 9, 9, 9]);
    // No size.
    {
        let mut slice = Slice::new(&mut v, 2, None);
        let bytes = slice.write_at(1, &buf).unwrap();
        assert_eq!(bytes, 6);
    }
    assert_eq!(v, vec![0, 1, 2, 9, 9, 9, 9, 9, 9]);

    // Automatic-size constructor.
    let mut v = vec![0, 1, 2, 3];
    {
        let mut slice = Slice::new_to_end(&mut v, 1).unwrap();
        assert_eq!(slice.size().unwrap().unwrap(), 3);
        let bytes = slice.write_at(0, &buf).unwrap();
        assert_eq!(bytes, 3);
    }
    assert_eq!(v, vec![0, 9, 9, 9]);

    // Slice of slice.
    let mut v = vec![0, 1, 2, 3, 4, 5];
    {
        let mut slice1 = Slice::new(&mut v, 1, Some(4));
        let mut slice2 = Slice::new(&mut slice1, 1, Some(2));
        let bytes = slice2.write_at(0, &buf).unwrap();
        assert_eq!(bytes, 2);
    }
    assert_eq!(v, vec![0, 1, 9, 9, 4, 5]);
}

#[test]
fn test_refcell() {
    let mut buf = [0; 3];

    // Make sure we can instantiate a bunch of combinations.
    let mut a = [0, 1, 2, 3];
    a.as_ref().read_at(0, &mut buf).unwrap();
    a.as_mut().write_at(0, &buf).unwrap();

    let mut v = vec![0, 1, 2, 3];
    v.read_at(0, &mut buf).unwrap();
    v.write_at(0, &buf).unwrap();

    let mut ra = &RefCell::new(a.as_mut());
    ra.read_at(0, &mut buf).unwrap();
    ra.write_at(0, &buf).unwrap();

    let mut rv = &RefCell::new(&mut v);
    rv.read_at(0, &mut buf).unwrap();
    rv.write_at(0, &buf).unwrap();

    // Test writing but still being able to use, thanks to RefCell.
    let mut v = vec![0, 1, 2, 3];
    let mut rv = &RefCell::new(&mut v);
    let buf = [9; 4];
    rv.write_at(0, &buf).unwrap();
    assert_eq!(*rv.borrow(), &vec![9; 4]);
}
<|endoftext|>


<commit_before>
extern crate nccl;

use nccl::Value;

#[test]
fn from_vec() {
    assert_eq!(Value::from(vec![1, 2, 3]),
               Value::List(vec![Value::Integer(1),
                                Value::Integer(2),
                                Value::Integer(3)]));
}

<commit_msg>update tests<commit_after>
extern crate nccl;

use nccl::{Value, Pair};

#[test]
fn from_vec() {
    assert_eq!(Value::from(vec![1, 2, 3]),
               Value::List(vec![Value::Integer(1),
                                Value::Integer(2),
                                Value::Integer(3)]));
}

#[test]
fn add() {
    let mut p = Pair::new("key");
    p.add("value");
    assert_eq!(p, Pair {
        key: "key".into(),
        value: vec![Pair {
            key: "value".into(),
            value: vec![]
        }]
    });
}

#[test]
fn get() {
    let mut p = Pair::new("key");
    p.add("value");
    p.add("testaroni");
    p.get_mut("value".into()).unwrap().add("Hello!");
    let v = p.get("value".into()).unwrap();
    assert_eq!(v, &Pair {
        key: "value".into(),
        value: vec![Pair {
            key: "Hello!".into(),
            value: vec![]
        }]
    });
}

#[test]
fn index() {
    let mut p = Pair::new("key");
    p.add("value");
    p.add("dj khaled");
    p.get_mut("value".into()).unwrap().add("yes!");
    p.get_mut("dj khaled".into()).unwrap().add("you smart");
    p.get_mut("dj khaled".into()).unwrap().add("you loyal");
}

<|endoftext|>


<commit_before>
extern crate nccl;

use nccl::{Pair, Scanner, NcclError, ErrorKind, Parser};

#[test]
fn pair_new() {
    assert_eq!(Pair::new("hello"), Pair {
        key: "hello".into(),
        value: vec![]
    });
}

#[test]
fn pair_add() {
    let mut p = Pair::new("top_level");
    p.add("key");
    assert_eq!(p, Pair {
        key: "top_level".into(),
        value: vec![Pair {
            key: "key".into(),
            value: vec![]
        }]
    });
}

#[test]
fn pair_get() {
    let mut p = Pair::new("top_level");
    p.add("key");
    assert_eq!(p.get("key").unwrap(), &mut Pair {
        key: "key".into(),
        value: vec![]
    });
}

#[test]
fn pair_index() {
    let mut p = Pair::new("top_level");
    p.add("key");
    assert_eq!(p["key"], Pair {
        key: "key".into(),
        value: vec![]
    });
}

#[test]
fn pair_keys() {
    let mut p = Pair::new("top");
    p.add("numbers");
    p["numbers"].add("1");
    p["numbers"].add("2");
    p["numbers"].add("3");
    p["numbers"].add("4");
    p["numbers"].add("5");
    assert_eq!(p["numbers"].keys(), vec!["1", "2", "3", "4", "5"]);
}

#[test]
fn pair_value_parse() {
    let mut p = Pair::new("top");
    p.add("bools");
    p["bools"].add("true");
    assert!(p["bools"].value_as::<bool>().unwrap());
}

#[test]
fn scanner_literal() {
    let mut s = Scanner::new("\"this: is neato\": burrito 64\n    yes.".into());
    s.scan_tokens().unwrap();
}

#[test]
#[should_panic]
fn error_key_not_found() {
    let mut p = Pair::new("jjj");
    p.get("jwiofiojwaef jio").unwrap();
}

#[test]
fn scan_file() {
    assert!(nccl::parse_file("config.nccl").is_ok());
}

#[test]
fn dos_unix_lines() {
    assert_eq!(nccl::parse_file("config.nccl"), nccl::parse_file("config_dos.nccl"));
}

#[test]
fn string_escape() {
    let mut s = Scanner::new("\"\\\"hello\\\"\\n\"".into());
    assert_eq!(s.scan_tokens().unwrap()[0].lexeme, "\"hello\"\n");
}

#[test]
fn add_pair() {
    // create a new pair
     let mut p1 = Pair::new("happy birthday");

     p1.add("Bobby");
     p1["Bobby"].add("Today!");

     // we think Ron's birthday is the 3rd...
     p1.add("Ron");
     p1["Ron"].add("March 3rd");

     // whoops, we were wrong
     let mut p2 = Pair::new("Ron");
     p2.add("March 2nd");

     // there you go Ron, happy belated birthday
     p1.add_pair(p2);
}

#[test]
fn add_slice_traverse() {
    let mut p = Pair::new("top");
    p.add_slice(&["a".into(), "b".into(), "c".into()]);
    assert_eq!(p.traverse(3), &mut Pair::new("c"));
}

#[test]
fn traverse_path() {
    let mut p = Pair::new("top");
    p.add_slice(&["a".into(), "b".into(), "c".into()]);
    p.traverse_path(&["a".into(), "b".into()]).add("happy");
    assert_eq!(p.traverse_path(&["a".into(), "b".into(), "happy".into()]), &mut Pair::new("happy"));
}

#[test]
fn add_slice() {
    let mut config = Pair::new("top_level");
    config.add("server");
    config["server"].add("domain");
    config["server"].add("port");
    config["server"].add("root");
    config["server"]["domain"].add("example.com");
    config["server"]["domain"].add("www.example.com");
    config["server"]["port"].add("80");
    config["server"]["port"].add("443");
    config["server"]["root"].add("/var/www/html");

    config.add_slice(&["server".into(), "port".into(), "22".into()]);
    assert_eq!(config["server"]["port"].keys(), vec!["80", "443", "22"]);
}

#[test]
#[should_panic]
fn multiple_errors() {
    let mut s = Scanner::new("hey: momma\n   test\n\tjeii\n    oh no!\n".into());
    s.scan_tokens().unwrap();
}

#[test]
fn parser() {
    let mut p = Parser::new(Scanner::new("hello\n    people\n    of\n    the world\n\nthis\n    is neat".into()).scan_tokens().unwrap());
    println!("{:?}", p.parse().unwrap());
    panic!();
}

#[test]
fn readme() {
    let mut config = Pair::new("top_level");

    // server
    //     domain
    //         example.com
    //         www.example.com
    //     port
    //         80
    //         443
    //     root
    //         /var/www/html

    config.add("server");
    config["server"].add("domain");
    config["server"].add("port");
    config["server"].add("root");
    config["server"]["domain"].add("example.com");
    config["server"]["domain"].add("www.example.com");
    config["server"]["port"].add("80");
    config["server"]["port"].add("443");
    config["server"]["root"].add("/var/www/html");

    let ports = config["server"]["port"].keys_as::<i32>().unwrap();
    assert_eq!(ports, vec![80, 443]);
}

<commit_msg>update tests<commit_after>
extern crate nccl;

use nccl::{Pair, Scanner, NcclError, ErrorKind, Parser};

#[test]
fn pair_new() {
    assert_eq!(Pair::new("hello"), Pair {
        key: "hello".into(),
        value: vec![]
    });
}

#[test]
fn pair_add() {
    let mut p = Pair::new("top_level");
    p.add("key");
    assert_eq!(p, Pair {
        key: "top_level".into(),
        value: vec![Pair {
            key: "key".into(),
            value: vec![]
        }]
    });
}

#[test]
fn pair_get() {
    let mut p = Pair::new("top_level");
    p.add("key");
    assert_eq!(p.get("key").unwrap(), &mut Pair {
        key: "key".into(),
        value: vec![]
    });
}

#[test]
fn pair_index() {
    let mut p = Pair::new("top_level");
    p.add("key");
    assert_eq!(p["key"], Pair {
        key: "key".into(),
        value: vec![]
    });
}

#[test]
fn pair_keys() {
    let mut p = Pair::new("top");
    p.add("numbers");
    p["numbers"].add("1");
    p["numbers"].add("2");
    p["numbers"].add("3");
    p["numbers"].add("4");
    p["numbers"].add("5");
    assert_eq!(p["numbers"].keys(), vec!["1", "2", "3", "4", "5"]);
}

#[test]
fn pair_value_parse() {
    let mut p = Pair::new("top");
    p.add("bools");
    p["bools"].add("true");
    assert!(p["bools"].value_as::<bool>().unwrap());
}

#[test]
fn scanner_literal() {
    let mut s = Scanner::new("\"this: is neato\": burrito 64\n    yes.".into());
    s.scan_tokens().unwrap();
}

#[test]
#[should_panic]
fn error_key_not_found() {
    let mut p = Pair::new("jjj");
    p.get("jwiofiojwaef jio").unwrap();
}

#[test]
fn scan_file() {
    assert!(nccl::parse_file("config.nccl").is_ok());
}

#[test]
fn dos_unix_lines() {
    assert_eq!(nccl::parse_file("config.nccl"), nccl::parse_file("config_dos.nccl"));
}

#[test]
fn string_escape() {
    let mut s = Scanner::new("\"\\\"hello\\\"\\n\"".into());
    assert_eq!(s.scan_tokens().unwrap()[0].lexeme, "\"hello\"\n");
}

#[test]
fn add_pair() {
    // create a new pair
     let mut p1 = Pair::new("happy birthday");

     p1.add("Bobby");
     p1["Bobby"].add("Today!");

     // we think Ron's birthday is the 3rd...
     p1.add("Ron");
     p1["Ron"].add("March 3rd");

     // whoops, we were wrong
     let mut p2 = Pair::new("Ron");
     p2.add("March 2nd");

     // there you go Ron, happy belated birthday
     p1.add_pair(p2);
}

#[test]
fn add_slice_traverse() {
    let mut p = Pair::new("top");
    p.add_slice(&["a".into(), "b".into(), "c".into()]);
    assert_eq!(p.traverse(3), &mut Pair::new("c"));
}

#[test]
fn traverse_path() {
    let mut p = Pair::new("top");
    p.add_slice(&["a".into(), "b".into(), "c".into()]);
    p.traverse_path(&["a".into(), "b".into()]).add("happy");
    assert_eq!(p.traverse_path(&["a".into(), "b".into(), "happy".into()]), &mut Pair::new("happy"));
}

#[test]
fn add_slice() {
    let mut config = Pair::new("top_level");
    config.add("server");
    config["server"].add("domain");
    config["server"].add("port");
    config["server"].add("root");
    config["server"]["domain"].add("example.com");
    config["server"]["domain"].add("www.example.com");
    config["server"]["port"].add("80");
    config["server"]["port"].add("443");
    config["server"]["root"].add("/var/www/html");

    config.add_slice(&["server".into(), "port".into(), "22".into()]);
    assert_eq!(config["server"]["port"].keys(), vec!["80", "443", "22"]);
}

#[test]
#[should_panic]
fn multiple_errors() {
    let mut s = Scanner::new("hey: momma\n   test\n\tjeii\n    oh no!\n".into());
    s.scan_tokens().unwrap();
}

#[test]
fn parser() {
    let mut p = Parser::new(Scanner::new("hello\n    people\n    of\n    the world\n\nthis\n    is neat".into()).scan_tokens().unwrap());
    assert!(p.parse().is_ok());
}

#[test]
fn add_vec() {
    let mut p = Pair::new("__top_level__");
    p.add("a");
    p.add_slice(&["a".into(), "hello".into(), "world".into()]);
    p.add_slice(&["a".into(), "hello".into(), "world".into()]);
    assert_eq!(p["a"]["hello"].value.len(), 1);
}

#[test]
fn readme() {
    let mut config = Pair::new("top_level");

    // server
    //     domain
    //         example.com
    //         www.example.com
    //     port
    //         80
    //         443
    //     root
    //         /var/www/html

    config.add("server");
    config["server"].add("domain");
    config["server"].add("port");
    config["server"].add("root");
    config["server"]["domain"].add("example.com");
    config["server"]["domain"].add("www.example.com");
    config["server"]["port"].add("80");
    config["server"]["port"].add("443");
    config["server"]["root"].add("/var/www/html");

    let ports = config["server"]["port"].keys_as::<i32>().unwrap();
    assert_eq!(ports, vec![80, 443]);
}

<|endoftext|>


<commit_before>use mio::net::{TcpListener, TcpStream};
use mio::*;
use std::sync::{Arc, Barrier};
use std::thread;
use std::time::Duration;

mod util;

use util::{init, localhost};

#[test]
fn test_poll_closes_fd() {
    init();

    for _ in 0..2000 {
        let mut poll = Poll::new().unwrap();
        let mut events = Events::with_capacity(4);

        poll.poll(&mut events, Some(Duration::from_millis(0)))
            .unwrap();

        drop(poll);
    }
}

#[test]
fn test_drop_cancels_interest_and_shuts_down() {
    init();

    use mio::net::TcpStream;
    use std::io;
    use std::io::Read;
    use std::net::TcpListener;
    use std::thread;

    let l = TcpListener::bind("127.0.0.1:0").unwrap();
    let addr = l.local_addr().unwrap();

    let t = thread::spawn(move || {
        let mut s = l.incoming().next().unwrap().unwrap();
        s.set_read_timeout(Some(Duration::from_secs(5)))
            .expect("set_read_timeout");
        let r = s.read(&mut [0; 16]);
        match r {
            Ok(_) => (),
            Err(e) => {
                if e.kind() != io::ErrorKind::UnexpectedEof {
                    panic!(e);
                }
            }
        }
    });

    let mut poll = Poll::new().unwrap();
    let mut s = TcpStream::connect(addr).unwrap();

    poll.register(&s, Token(1), Interests::READABLE | Interests::WRITABLE)
        .unwrap();
    let mut events = Events::with_capacity(16);
    'outer: loop {
        poll.poll(&mut events, None).unwrap();
        for event in &events {
            if event.token() == Token(1) {
                // connected
                break 'outer;
            }
        }
    }

    let mut b = [0; 1024];
    match s.read(&mut b) {
        Ok(_) => panic!("unexpected ok"),
        Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => (),
        Err(e) => panic!("unexpected error: {:?}", e),
    }

    drop(s);
    t.join().unwrap();
}

#[test]
fn test_registry_behind_arc() {
    // `Registry` should work behind an `Arc`, being `Sync` and `Send`.
    init();

    let mut poll = Poll::new().unwrap();
    let registry = Arc::new(poll.registry().unwrap());
    let mut events = Events::with_capacity(128);

    let addr = localhost();
    let barrier = Arc::new(Barrier::new(3));

    let registry2 = Arc::clone(&registry);
    let registry3 = Arc::clone(&registry);
    let barrier2 = Arc::clone(&barrier);
    let barrier3 = Arc::clone(&barrier);

    let handle1 = thread::spawn(move || {
        let listener = TcpListener::bind(addr).unwrap();
        registry2
            .register(&listener, Token(0), Interests::READABLE)
            .unwrap();
        barrier2.wait();
    });
    let handle2 = thread::spawn(move || {
        let stream = TcpStream::connect(addr).unwrap();
        registry3
            .register(&stream, Token(1), Interests::READABLE)
            .unwrap();
        barrier3.wait();
    });

    poll.poll(&mut events, Some(Duration::from_millis(100)))
        .unwrap();
    assert!(events.iter().count() >= 1);

    // Let the threads return.
    barrier.wait();

    handle1.join().unwrap();
    handle2.join().unwrap();
}

#[test]
fn assertions() {
    fn assert_sync<T: Sync>() {}
    fn assert_send<T: Send>() {}

    assert_sync::<Poll>();
    assert_send::<Poll>();
    assert_sync::<Registry>();
    assert_send::<Registry>();
}
<commit_msg>Add writable interests in test_registry_behind_arc<commit_after>use mio::net::{TcpListener, TcpStream};
use mio::*;
use std::sync::{Arc, Barrier};
use std::thread;
use std::time::Duration;

mod util;

use util::{init, localhost};

#[test]
fn test_poll_closes_fd() {
    init();

    for _ in 0..2000 {
        let mut poll = Poll::new().unwrap();
        let mut events = Events::with_capacity(4);

        poll.poll(&mut events, Some(Duration::from_millis(0)))
            .unwrap();

        drop(poll);
    }
}

#[test]
fn test_drop_cancels_interest_and_shuts_down() {
    init();

    use mio::net::TcpStream;
    use std::io;
    use std::io::Read;
    use std::net::TcpListener;
    use std::thread;

    let l = TcpListener::bind("127.0.0.1:0").unwrap();
    let addr = l.local_addr().unwrap();

    let t = thread::spawn(move || {
        let mut s = l.incoming().next().unwrap().unwrap();
        s.set_read_timeout(Some(Duration::from_secs(5)))
            .expect("set_read_timeout");
        let r = s.read(&mut [0; 16]);
        match r {
            Ok(_) => (),
            Err(e) => {
                if e.kind() != io::ErrorKind::UnexpectedEof {
                    panic!(e);
                }
            }
        }
    });

    let mut poll = Poll::new().unwrap();
    let mut s = TcpStream::connect(addr).unwrap();

    poll.register(&s, Token(1), Interests::READABLE | Interests::WRITABLE)
        .unwrap();
    let mut events = Events::with_capacity(16);
    'outer: loop {
        poll.poll(&mut events, None).unwrap();
        for event in &events {
            if event.token() == Token(1) {
                // connected
                break 'outer;
            }
        }
    }

    let mut b = [0; 1024];
    match s.read(&mut b) {
        Ok(_) => panic!("unexpected ok"),
        Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => (),
        Err(e) => panic!("unexpected error: {:?}", e),
    }

    drop(s);
    t.join().unwrap();
}

#[test]
fn test_registry_behind_arc() {
    // `Registry` should work behind an `Arc`, being `Sync` and `Send`.
    init();

    let mut poll = Poll::new().unwrap();
    let registry = Arc::new(poll.registry().unwrap());
    let mut events = Events::with_capacity(128);

    let addr = localhost();
    let barrier = Arc::new(Barrier::new(3));

    let registry2 = Arc::clone(&registry);
    let registry3 = Arc::clone(&registry);
    let barrier2 = Arc::clone(&barrier);
    let barrier3 = Arc::clone(&barrier);

    let handle1 = thread::spawn(move || {
        let listener = TcpListener::bind(addr).unwrap();
        registry2
            .register(&listener, Token(0), Interests::READABLE)
            .unwrap();
        barrier2.wait();
    });
    let handle2 = thread::spawn(move || {
        let stream = TcpStream::connect(addr).unwrap();
        registry3
            .register(&stream, Token(1), Interests::READABLE | Interests::WRITABLE)
            .unwrap();
        barrier3.wait();
    });

    poll.poll(&mut events, Some(Duration::from_millis(100)))
        .unwrap();
    assert!(events.iter().count() >= 1);

    // Let the threads return.
    barrier.wait();

    handle1.join().unwrap();
    handle2.join().unwrap();
}

#[test]
fn assertions() {
    fn assert_sync<T: Sync>() {}
    fn assert_send<T: Send>() {}

    assert_sync::<Poll>();
    assert_send::<Poll>();
    assert_sync::<Registry>();
    assert_send::<Registry>();
}
<|endoftext|>


<commit_before>#![cfg(feature = "rand")]

extern crate num_bigint;
extern crate num_traits;
extern crate rand;

mod biguint {
    use num_bigint::{BigUint, RandBigInt, RandomBits};
    use num_traits::Zero;
    use rand::thread_rng;
    use rand::Rng;
    use rand::distributions::Uniform;

    #[test]
    fn test_rand() {
        let mut rng = thread_rng();
        let n: BigUint = rng.gen_biguint(137);
        assert!(n.bits() <= 137);
        assert!(rng.gen_biguint(0).is_zero());
    }

    #[test]
    fn test_rand_bits() {
        let mut rng = thread_rng();
        let n: BigUint = rng.sample(&RandomBits::new(137));
        assert!(n.bits() <= 137);
        let z: BigUint = rng.sample(&RandomBits::new(0));
        assert!(z.is_zero());
    }

    #[test]
    fn test_rand_range() {
        let mut rng = thread_rng();

        for _ in 0..10 {
            assert_eq!(
                rng.gen_biguint_range(&BigUint::from(236u32), &BigUint::from(237u32)),
                BigUint::from(236u32)
            );
        }

        let l = BigUint::from(403469000u32 + 2352);
        let u = BigUint::from(403469000u32 + 3513);
        for _ in 0..1000 {
            let n: BigUint = rng.gen_biguint_below(&u);
            assert!(n < u);

            let n: BigUint = rng.gen_biguint_range(&l, &u);
            assert!(n >= l);
            assert!(n < u);
        }
    }

    #[test]
    #[should_panic]
    fn test_zero_rand_range() {
        thread_rng().gen_biguint_range(&BigUint::from(54u32), &BigUint::from(54u32));
    }

    #[test]
    #[should_panic]
    fn test_negative_rand_range() {
        let mut rng = thread_rng();
        let l = BigUint::from(2352u32);
        let u = BigUint::from(3513u32);
        // Switching u and l should fail:
        let _n: BigUint = rng.gen_biguint_range(&u, &l);
    }

    #[test]
    fn test_rand_uniform() {
        let mut rng = thread_rng();

        let tiny = Uniform::new(BigUint::from(236u32), BigUint::from(237u32));
        for _ in 0..10 {
            assert_eq!(rng.sample(&tiny), BigUint::from(236u32));
        }

        let l = BigUint::from(403469000u32 + 2352);
        let u = BigUint::from(403469000u32 + 3513);
        let below = Uniform::new(BigUint::zero(), u.clone());
        let range = Uniform::new(l.clone(), u.clone());
        for _ in 0..1000 {
            let n: BigUint = rng.sample(&below);
            assert!(n < u);

            let n: BigUint = rng.sample(&range);
            assert!(n >= l);
            assert!(n < u);
        }
    }
}

mod bigint {
    use num_bigint::{BigInt, RandBigInt, RandomBits};
    use num_traits::Zero;
    use rand::thread_rng;
    use rand::Rng;
    use rand::distributions::Uniform;

    #[test]
    fn test_rand() {
        let mut rng = thread_rng();
        let n: BigInt = rng.gen_bigint(137);
        assert!(n.bits() <= 137);
        assert!(rng.gen_bigint(0).is_zero());
    }

    #[test]
    fn test_rand_bits() {
        let mut rng = thread_rng();
        let n: BigInt = rng.sample(&RandomBits::new(137));
        assert!(n.bits() <= 137);
        let z: BigInt = rng.sample(&RandomBits::new(0));
        assert!(z.is_zero());
    }

    #[test]
    fn test_rand_range() {
        let mut rng = thread_rng();

        for _ in 0..10 {
            assert_eq!(
                rng.gen_bigint_range(&BigInt::from(236), &BigInt::from(237)),
                BigInt::from(236)
            );
        }

        fn check(l: BigInt, u: BigInt) {
            let mut rng = thread_rng();
            for _ in 0..1000 {
                let n: BigInt = rng.gen_bigint_range(&l, &u);
                assert!(n >= l);
                assert!(n < u);
            }
        }
        let l: BigInt = BigInt::from(403469000 + 2352);
        let u: BigInt = BigInt::from(403469000 + 3513);
        check(l.clone(), u.clone());
        check(-l.clone(), u.clone());
        check(-u.clone(), -l.clone());
    }

    #[test]
    #[should_panic]
    fn test_zero_rand_range() {
        thread_rng().gen_bigint_range(&BigInt::from(54), &BigInt::from(54));
    }

    #[test]
    #[should_panic]
    fn test_negative_rand_range() {
        let mut rng = thread_rng();
        let l = BigInt::from(2352);
        let u = BigInt::from(3513);
        // Switching u and l should fail:
        let _n: BigInt = rng.gen_bigint_range(&u, &l);
    }

    #[test]
    fn test_rand_uniform() {
        let mut rng = thread_rng();

        let tiny = Uniform::new(BigInt::from(236u32), BigInt::from(237u32));
        for _ in 0..10 {
            assert_eq!(rng.sample(&tiny), BigInt::from(236u32));
        }

        fn check(l: BigInt, u: BigInt) {
            let mut rng = thread_rng();
            let range = Uniform::new(l.clone(), u.clone());
            for _ in 0..1000 {
                let n: BigInt = rng.sample(&range);
                assert!(n >= l);
                assert!(n < u);
            }
        }
        let l: BigInt = BigInt::from(403469000 + 2352);
        let u: BigInt = BigInt::from(403469000 + 3513);
        check(l.clone(), u.clone());
        check(-l.clone(), u.clone());
        check(-u.clone(), -l.clone());
    }
}
<commit_msg>Add tests for PRNG value stability<commit_after>#![cfg(feature = "rand")]

extern crate num_bigint;
extern crate num_traits;
extern crate rand;

mod biguint {
    use num_bigint::{BigUint, RandBigInt, RandomBits};
    use num_traits::Zero;
    use rand::thread_rng;
    use rand::{Rng, SeedableRng};
    use rand::distributions::Uniform;

    #[test]
    fn test_rand() {
        let mut rng = thread_rng();
        let n: BigUint = rng.gen_biguint(137);
        assert!(n.bits() <= 137);
        assert!(rng.gen_biguint(0).is_zero());
    }

    #[test]
    fn test_rand_bits() {
        let mut rng = thread_rng();
        let n: BigUint = rng.sample(&RandomBits::new(137));
        assert!(n.bits() <= 137);
        let z: BigUint = rng.sample(&RandomBits::new(0));
        assert!(z.is_zero());
    }

    #[test]
    fn test_rand_range() {
        let mut rng = thread_rng();

        for _ in 0..10 {
            assert_eq!(
                rng.gen_biguint_range(&BigUint::from(236u32), &BigUint::from(237u32)),
                BigUint::from(236u32)
            );
        }

        let l = BigUint::from(403469000u32 + 2352);
        let u = BigUint::from(403469000u32 + 3513);
        for _ in 0..1000 {
            let n: BigUint = rng.gen_biguint_below(&u);
            assert!(n < u);

            let n: BigUint = rng.gen_biguint_range(&l, &u);
            assert!(n >= l);
            assert!(n < u);
        }
    }

    #[test]
    #[should_panic]
    fn test_zero_rand_range() {
        thread_rng().gen_biguint_range(&BigUint::from(54u32), &BigUint::from(54u32));
    }

    #[test]
    #[should_panic]
    fn test_negative_rand_range() {
        let mut rng = thread_rng();
        let l = BigUint::from(2352u32);
        let u = BigUint::from(3513u32);
        // Switching u and l should fail:
        let _n: BigUint = rng.gen_biguint_range(&u, &l);
    }

    #[test]
    fn test_rand_uniform() {
        let mut rng = thread_rng();

        let tiny = Uniform::new(BigUint::from(236u32), BigUint::from(237u32));
        for _ in 0..10 {
            assert_eq!(rng.sample(&tiny), BigUint::from(236u32));
        }

        let l = BigUint::from(403469000u32 + 2352);
        let u = BigUint::from(403469000u32 + 3513);
        let below = Uniform::new(BigUint::zero(), u.clone());
        let range = Uniform::new(l.clone(), u.clone());
        for _ in 0..1000 {
            let n: BigUint = rng.sample(&below);
            assert!(n < u);

            let n: BigUint = rng.sample(&range);
            assert!(n >= l);
            assert!(n < u);
        }
    }

    fn seeded_value_stability<R: SeedableRng + RandBigInt>(expected: &[&str]) {
        let mut seed = <R::Seed>::default();
        for (i, x) in seed.as_mut().iter_mut().enumerate() {
            *x = (i as u8).wrapping_mul(191);
        }
        let mut rng = R::from_seed(seed);
        for (i, &s) in expected.iter().enumerate() {
            let n: BigUint = s.parse().unwrap();
            let r = rng.gen_biguint((1 << i) + i);
            assert_eq!(n, r);
        }
    }

    #[test]
    fn test_chacha_value_stability() {
        const EXPECTED: &[&str] = &[
            "0",
            "0",
            "52",
            "84",
            "23780",
            "86502865016",
            "187057847319509867386",
            "34045731223080904464438757488196244981910",
            "23813754422987836414755953516143692594193066497413249270287126597896871975915808",
            "57401636903146945411652549098818446911814352529449356393690984105383482703074355\
             67088360974672291353736011718191813678720755501317478656550386324355699624671",
        ];
        use rand::prng::ChaChaRng;
        seeded_value_stability::<ChaChaRng>(EXPECTED);
    }

    #[test]
    fn test_isaac_value_stability() {
        const EXPECTED: &[&str] = &[
            "1",
            "4",
            "3",
            "649",
            "89116",
            "7730042024",
            "20773149082453254949",
            "35999009049239918667571895439206839620281",
            "10191757312714088681302309313551624007714035309632506837271600807524767413673006",
            "37805949268912387809989378008822038725134260145886913321084097194957861133272558\
             43458183365174899239251448892645546322463253898288141861183340823194379722556",
        ];
        use rand::prng::IsaacRng;
        seeded_value_stability::<IsaacRng>(EXPECTED);
    }

    #[test]
    fn test_xorshift_value_stability() {
        const EXPECTED: &[&str] = &[
            "1",
            "0",
            "37",
            "395",
            "181116",
            "122718231117",
            "1068467172329355695001",
            "28246925743544411614293300167064395633287",
            "12750053187017853048648861493745244146555950255549630854523304068318587267293038",
            "53041498719137109355568081064978196049094604705283682101683207799515709404788873\
             53417136457745727045473194367732849819278740266658219147356315674940229288531",
        ];
        use rand::prng::XorShiftRng;
        seeded_value_stability::<XorShiftRng>(EXPECTED);
    }
}

mod bigint {
    use num_bigint::{BigInt, RandBigInt, RandomBits};
    use num_traits::Zero;
    use rand::thread_rng;
    use rand::{Rng, SeedableRng};
    use rand::distributions::Uniform;

    #[test]
    fn test_rand() {
        let mut rng = thread_rng();
        let n: BigInt = rng.gen_bigint(137);
        assert!(n.bits() <= 137);
        assert!(rng.gen_bigint(0).is_zero());
    }

    #[test]
    fn test_rand_bits() {
        let mut rng = thread_rng();
        let n: BigInt = rng.sample(&RandomBits::new(137));
        assert!(n.bits() <= 137);
        let z: BigInt = rng.sample(&RandomBits::new(0));
        assert!(z.is_zero());
    }

    #[test]
    fn test_rand_range() {
        let mut rng = thread_rng();

        for _ in 0..10 {
            assert_eq!(
                rng.gen_bigint_range(&BigInt::from(236), &BigInt::from(237)),
                BigInt::from(236)
            );
        }

        fn check(l: BigInt, u: BigInt) {
            let mut rng = thread_rng();
            for _ in 0..1000 {
                let n: BigInt = rng.gen_bigint_range(&l, &u);
                assert!(n >= l);
                assert!(n < u);
            }
        }
        let l: BigInt = BigInt::from(403469000 + 2352);
        let u: BigInt = BigInt::from(403469000 + 3513);
        check(l.clone(), u.clone());
        check(-l.clone(), u.clone());
        check(-u.clone(), -l.clone());
    }

    #[test]
    #[should_panic]
    fn test_zero_rand_range() {
        thread_rng().gen_bigint_range(&BigInt::from(54), &BigInt::from(54));
    }

    #[test]
    #[should_panic]
    fn test_negative_rand_range() {
        let mut rng = thread_rng();
        let l = BigInt::from(2352);
        let u = BigInt::from(3513);
        // Switching u and l should fail:
        let _n: BigInt = rng.gen_bigint_range(&u, &l);
    }

    #[test]
    fn test_rand_uniform() {
        let mut rng = thread_rng();

        let tiny = Uniform::new(BigInt::from(236u32), BigInt::from(237u32));
        for _ in 0..10 {
            assert_eq!(rng.sample(&tiny), BigInt::from(236u32));
        }

        fn check(l: BigInt, u: BigInt) {
            let mut rng = thread_rng();
            let range = Uniform::new(l.clone(), u.clone());
            for _ in 0..1000 {
                let n: BigInt = rng.sample(&range);
                assert!(n >= l);
                assert!(n < u);
            }
        }
        let l: BigInt = BigInt::from(403469000 + 2352);
        let u: BigInt = BigInt::from(403469000 + 3513);
        check(l.clone(), u.clone());
        check(-l.clone(), u.clone());
        check(-u.clone(), -l.clone());
    }

    fn seeded_value_stability<R: SeedableRng + RandBigInt>(expected: &[&str]) {
        let mut seed = <R::Seed>::default();
        for (i, x) in seed.as_mut().iter_mut().enumerate() {
            *x = (i as u8).wrapping_mul(191);
        }
        let mut rng = R::from_seed(seed);
        for (i, &s) in expected.iter().enumerate() {
            let n: BigInt = s.parse().unwrap();
            let r = rng.gen_bigint((1 << i) + i);
            assert_eq!(n, r);
        }
    }

    #[test]
    fn test_chacha_value_stability() {
        const EXPECTED: &[&str] = &[
            "0",
            "-6",
            "-1",
            "1321",
            "-147247",
            "8486373526",
            "-272736656290199720696",
            "2731152629387534140535423510744221288522",
            "-28820024790651190394679732038637785320661450462089347915910979466834461433196572",
            "501454570554170484799723603981439288209930393334472085317977614690773821680884844\
             8530978478667288338327570972869032358120588620346111979053742269317702532328",
        ];
        use rand::prng::ChaChaRng;
        seeded_value_stability::<ChaChaRng>(EXPECTED);
    }

    #[test]
    fn test_isaac_value_stability() {
        const EXPECTED: &[&str] = &[
            "1",
            "0",
            "5",
            "113",
            "-132240",
            "-36348760761",
            "-365690596708430705434",
            "-14090753008246284277803606722552430292432",
            "-26313941628626248579319341019368550803676255307056857978955881718727601479436059",
            "-14563174552421101848999036239003801073335703811160945137332228646111920972691151\
             88341090358094331641182310792892459091016794928947242043358702692294695845817",
        ];
        use rand::prng::IsaacRng;
        seeded_value_stability::<IsaacRng>(EXPECTED);
    }

    #[test]
    fn test_xorshift_value_stability() {
        const EXPECTED: &[&str] = &[
            "-1",
            "-4",
            "11",
            "-1802",
            "966495",
            "-62592045703",
            "-602281783447192077116",
            "-34335811410223060575607987996861632509125",
            "29156580925282215857325937227200350542000244609280383263289720243118706105351199",
            "49920038676141573457451407325930326489996232208489690499754573826911037849083623\
             24546142615325187412887314466195222441945661833644117700809693098722026764846",
        ];
        use rand::prng::XorShiftRng;
        seeded_value_stability::<XorShiftRng>(EXPECTED);
    }
}
<|endoftext|>