proptest/arbitrary/_std/
io.rs

1//-
2// Copyright 2017, 2018 The proptest developers
3//
4// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
5// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
6// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
7// option. This file may not be copied, modified, or distributed
8// except according to those terms.
9
10//! Arbitrary implementations for `std::io`.
11
12use crate::std_facade::String;
13#[cfg(test)]
14use crate::std_facade::Vec;
15use std::io::ErrorKind::*;
16use std::io::*;
17
18use crate::arbitrary::*;
19use crate::strategy::statics::static_map;
20use crate::strategy::*;
21
22// TODO: IntoInnerError
23// Consider: std::io::Initializer
24
25macro_rules! buffer {
26    ($type: ident, $bound: path) => {
27        arbitrary!(
28            [A: Arbitrary + $bound] $type<A>,
29            SMapped<(A, Option<u16>), Self>, A::Parameters;
30            args => static_map(
31                arbitrary_with(product_pack![args, Default::default()]),
32                |(inner, cap)| {
33                    if let Some(cap) = cap {
34                        $type::with_capacity(cap as usize, inner)
35                    } else {
36                        $type::new(inner)
37                    }
38                }
39            )
40        );
41
42        lift1!([$bound] $type<A>; base =>
43            (base, any::<Option<u16>>()).prop_map(|(inner, cap)| {
44                if let Some(cap) = cap {
45                    $type::with_capacity(cap as usize, inner)
46                } else {
47                    $type::new(inner)
48                }
49            })
50        );
51    };
52}
53
54buffer!(BufReader, Read);
55buffer!(BufWriter, Write);
56buffer!(LineWriter, Write);
57
58arbitrary!(
59    [A: Read + Arbitrary, B: Read + Arbitrary] Chain<A, B>,
60    SMapped<(A, B), Self>, product_type![A::Parameters, B::Parameters];
61    args => static_map(arbitrary_with(args), |(a, b)| a.chain(b))
62);
63
64wrap_ctor!(Cursor);
65
66lazy_just!(
67      Empty, empty
68    ; Sink, sink
69    ; Stderr, stderr
70    ; Stdin, stdin
71    ; Stdout, stdout
72);
73
74wrap_ctor!([BufRead] Lines, BufRead::lines);
75
76arbitrary!(Repeat, SMapped<u8, Self>; static_map(any::<u8>(), repeat));
77
78arbitrary!(
79    [A: BufRead + Arbitrary] Split<A>, SMapped<(A, u8), Self>, A::Parameters;
80    args => static_map(
81        arbitrary_with(product_pack![args, Default::default()]),
82        |(a, b)| a.split(b)
83    )
84);
85lift1!(['static + BufRead] Split<A>;
86    base => (base, any::<u8>()).prop_map(|(a, b)| a.split(b)));
87
88arbitrary!(
89    [A: Read + Arbitrary] Take<A>, SMapped<(A, u64), Self>, A::Parameters;
90    args => static_map(
91        arbitrary_with(product_pack![args, Default::default()]),
92        |(a, b)| a.take(b)
93    )
94);
95lift1!(['static + Read] Take<A>;
96    base => (base, any::<u64>()).prop_map(|(a, b)| a.take(b)));
97
98arbitrary!(ErrorKind, Union<Just<Self>>;
99    Union::new(
100    [ NotFound
101    , PermissionDenied
102    , ConnectionRefused
103    , ConnectionReset
104    , ConnectionAborted
105    , NotConnected
106    , AddrInUse
107    , AddrNotAvailable
108    , BrokenPipe
109    , AlreadyExists
110    , WouldBlock
111    , InvalidInput
112    , InvalidData
113    , TimedOut
114    , WriteZero
115    , Interrupted
116    , Other
117    , UnexpectedEof
118    // TODO: watch this type for variant-additions.
119    ].iter().cloned().map(Just))
120);
121
122arbitrary!(
123    SeekFrom,
124    TupleUnion<(
125        WA<SMapped<u64, SeekFrom>>,
126        WA<SMapped<i64, SeekFrom>>,
127        WA<SMapped<i64, SeekFrom>>,
128    )>;
129    prop_oneof![
130        static_map(any::<u64>(), SeekFrom::Start),
131        static_map(any::<i64>(), SeekFrom::End),
132        static_map(any::<i64>(), SeekFrom::Current)
133    ]
134);
135
136arbitrary!(Error, SMapped<(ErrorKind, Option<String>), Self>;
137    static_map(arbitrary(), |(k, os)|
138        if let Some(s) = os { Error::new(k, s) } else { k.into() }
139    )
140);
141
142#[cfg(test)]
143mod test {
144
145    no_panic_test!(
146        buf_reader  => BufReader<Repeat>,
147        buf_writer  => BufWriter<Sink>,
148        line_writer => LineWriter<Sink>,
149        chain       => Chain<Empty, BufReader<Repeat>>,
150        cursor      => Cursor<Empty>,
151        empty       => Empty,
152        sink        => Sink,
153        stderr      => Stderr,
154        stdin       => Stdin,
155        stdout      => Stdout,
156        lines       => Lines<Empty>,
157        repeat      => Repeat,
158        split       => Split<Cursor<Vec<u8>>>,
159        take        => Take<Repeat>,
160        error_kind  => ErrorKind,
161        seek_from   => SeekFrom,
162        error       => Error
163    );
164}