<commit_before>// pest. The Elegant Parser
// Copyright (C) 2017  Dragoș Tiselice
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

#[doc(hidden)]
#[macro_export]
macro_rules! consumes_to {
    ( $_rules:ident, $tokens:expr, [] ) => ();
    ( $rules:ident, $tokens:expr, [ $name:ident ( $start:expr, $end:expr ) ] ) => {
        let expected = format!("expected Start {{ rule: {:?}, pos: Position {{ pos: {} }} }}",
                               $rules::$name, $start);
        match $tokens.next().expect(&format!("{} but found nothing", expected)) {
            $crate::Token::Start { rule, pos } => {
                let message = format!("{} but found Start {{ rule: {:?}, pos: Position {{ {} }} }}",
                                      expected, rule, pos.pos());

                if rule != $rules::$name || pos.pos() != $start {
                    panic!("{}", message);
                }
            },
            token => panic!("{}", format!("{} but found {:?}", expected, token))
        };

        let expected = format!("expected End {{ rule: {:?}, pos: Position {{ pos: {} }} }}",
                               $rules::$name, $end);
        match $tokens.next().expect(&format!("{} but found nothing", expected)) {
            $crate::Token::End { rule, pos } => {
                let message = format!("{} but found End {{ rule: {:?}, pos: Position {{ {} }} }}",
                                      expected, rule, pos.pos());

                if rule != $rules::$name || pos.pos() != $end {
                    panic!("{}", message);
                }
            },
            token => panic!("{}", format!("{} but found {:?}", expected, token))
        };
    };
    ( $rules:ident, $tokens:expr, [ $name:ident ( $start:expr, $end:expr ),
                                    $( $names:ident $calls:tt ),* ] ) => {

        let expected = format!("expected Start {{ rule: {:?}, pos: Position {{ pos: {} }} }}",
                               $rules::$name, $start);
        match $tokens.next().expect(&format!("{} but found nothing", expected)) {
            $crate::Token::Start { rule, pos } => {
                let message = format!("{} but found Start {{ rule: {:?}, pos: Position {{ {} }} }}",
                                      expected, rule, pos.pos());

                if rule != $rules::$name || pos.pos() != $start {
                    panic!("{}", message);
                }
            },
            token => panic!("{}", format!("{} but found {:?}", expected, token))
        };

        let expected = format!("expected End {{ rule: {:?}, pos: Position {{ pos: {} }} }}",
                               $rules::$name, $end);
        match $tokens.next().expect(&format!("{} but found nothing", expected)) {
            $crate::Token::End { rule, pos } => {
                let message = format!("{} but found End {{ rule: {:?}, pos: Position {{ {} }} }}",
                                      expected, rule, pos.pos());

                if rule != $rules::$name || pos.pos() != $end {
                    panic!("{}", message);
                }
            },
            token => panic!("{}", format!("{} but found {:?}", expected, token))
        };

        consumes_to!($rules, $tokens, [ $( $names $calls ),* ]);
    };
    ( $rules:ident, $tokens:expr, [ $name:ident ( $start:expr, $end:expr,
                                                  [ $( $names:ident $calls:tt ),* ] ) ] ) => {
        let expected = format!("expected Start {{ rule: {:?}, pos: Position {{ pos: {} }} }}",
                               $rules::$name, $start);
        match $tokens.next().expect(&format!("{} but found nothing", expected)) {
            $crate::Token::Start { rule, pos } => {
                let message = format!("{} but found Start {{ rule: {:?}, pos: Position {{ {} }} }}",
                                      expected, rule, pos.pos());

                if rule != $rules::$name || pos.pos() != $start {
                    panic!("{}", message);
                }
            },
            token => panic!("{}", format!("{} but found {:?}", expected, token))
        };

        consumes_to!($rules, $tokens, [ $( $names $calls ),* ]);

        let expected = format!("expected End {{ rule: {:?}, pos: Position {{ pos: {} }} }}",
                               $rules::$name, $end);
        match $tokens.next().expect(&format!("{} but found nothing", expected)) {
            $crate::Token::End { rule, pos } => {
                let message = format!("{} but found End {{ rule: {:?}, pos: Position {{ {} }} }}",
                                      expected, rule, pos.pos());

                if rule != $rules::$name || pos.pos() != $end {
                    panic!("{}", message);
                }
            },
            token => panic!("{}", format!("{} but found {:?}", expected, token))
        };
    };
    ( $rules:ident, $tokens:expr, [ $name:ident ( $start:expr, $end:expr,
                                                  [ $( $nested_names:ident $nested_calls:tt ),* ] ),
                                    $( $names:ident $calls:tt ),* ] ) => {

        let expected = format!("expected Start {{ rule: {:?}, pos: Position {{ pos: {} }} }}",
                               $rules::$name, $start);
        match $tokens.next().expect(&format!("{} but found nothing", expected)) {
            $crate::Token::Start { rule, pos } => {
                let message = format!("{} but found Start {{ rule: {:?}, pos: Position {{ {} }} }}",
                                      expected, rule, pos.pos());

                if rule != $rules::$name || pos.pos() != $start {
                    panic!("{}", message);
                }
            },
            token => panic!("{}", format!("{} but found {:?}", expected, token))
        };

        consumes_to!($rules, $tokens, [ $( $nested_names $nested_calls ),* ]);

        let expected = format!("expected End {{ rule: {:?}, pos: Position {{ pos: {} }} }}",
                               $rules::$name, $end);
        match $tokens.next().expect(&format!("{} but found nothing", expected)) {
            $crate::Token::End { rule, pos } => {
                let message = format!("{} but found End {{ rule: {:?}, pos: Position {{ {} }} }}",
                                      expected, rule, pos.pos());

                if rule != $rules::$name || pos.pos() != $end {
                    panic!("{}", message);
                }
            },
            token => panic!("{}", format!("{} but found {:?}", expected, token))
        };

        consumes_to!($rules, $tokens, [ $( $names $calls ),* ]);
    };
}

/// A `macro` which facilitates grammar testing and debugging.
///
/// # Examples
///
/// ```
/// # #[macro_use]
/// # extern crate pest;
/// # use std::rc::Rc;
/// # use pest::{Error, Parser};
/// # use pest::inputs::Input;
/// # use pest::iterators::Pairs;
/// # fn main() {
/// # #[allow(non_camel_case_types)]
/// # #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
/// # enum Rule {
/// #     a,
/// #     b,
/// #     c
/// # }
/// #
/// # struct AbcParser;
/// #
/// # impl Parser<Rule> for AbcParser {
/// #     fn parse<I: Input>(_: Rule, input: Rc<I>) -> Result<Pairs<Rule, I>, Error<Rule, I>> {
/// #         pest::state(input, |state, pos| {
/// #             state.rule(Rule::a, pos, |state, pos| {
/// #                 state.rule(Rule::b, pos.skip(1).unwrap(), |_, pos| {
/// #                     pos.skip(1)
/// #                 }).unwrap().skip(1)
/// #             }).and_then(|p| {
/// #                 state.rule(Rule::c, p.skip(1).unwrap(), |_, pos| {
/// #                     pos.skip(1)
/// #                 })
/// #             })
/// #         })
/// #     }
/// # }
/// parses_to! {
///     parser: AbcParser,
///     input:  "abcde",
///     rule:   Rule::a,
///     tokens: [
///         a(0, 3, [
///             b(1, 2)
///         ]),
///         c(4, 5)
///     ]
/// };
/// # }
/// ```
#[macro_export]
macro_rules! parses_to {
    ( parser: $parser:ident, input: $string:expr, rule: $rules:tt :: $rule:tt,
      tokens: [ $( $names:ident $calls:tt ),* ] ) => {

        #[allow(unused_mut)]
        {
            use $crate::Parser;

            let mut tokens = $parser::parse_str($rules::$rule, $string).unwrap().tokens();

            consumes_to!($rules, &mut tokens, [ $( $names $calls ),* ]);

            let rest: Vec<_> = tokens.collect();

            assert!(rest.is_empty(), format!("expected end of stream, but found {:?}", rest));
        }
    };
}

#[cfg(test)]
mod tests {
    use std::rc::Rc;

    use super::super::error::Error;
    use super::super::inputs::Input;
    use super::super::{Parser, state};
    use super::super::iterators::Pairs;

    #[allow(non_camel_case_types)]
    #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
    enum Rule {
        a,
        b,
        c
    }

    struct AbcParser;

    impl Parser<Rule> for AbcParser {
        fn parse<I: Input>(_: Rule, input: Rc<I>) -> Result<Pairs<Rule, I>, Error<Rule, I>> {
            state(input, |state, pos| {
                state.rule(Rule::a, pos, |state, pos| {
                    state.rule(Rule::b, pos.skip(1).unwrap(), |_, pos| {
                        pos.skip(1)
                    }).unwrap().skip(1)
                }).and_then(|p| {
                    state.rule(Rule::c, p.skip(1).unwrap(), |_, pos| {
                        pos.skip(1)
                    })
                })
            })
        }
    }

    #[test]
    fn parses_to() {
        parses_to! {
            parser: AbcParser,
            input: "abcde",
            rule: Rule::a,
            tokens: [
                a(0, 3, [
                    b(1, 2)
                ]),
                c(4, 5)
            ]
        };
    }

    #[test]
    #[should_panic]
    fn missing_end() {
        parses_to! {
            parser: AbcParser,
            input: "abcde",
            rule: Rule::a,
            tokens: [
                a(0, 3, [
                    b(1, 2)
                ])
            ]
        };
    }

    #[test]
    #[should_panic]
    fn empty() {
        parses_to! {
            parser: AbcParser,
            input: "abcde",
            rule: Rule::a,
            tokens: []
        };
    }
}
<commit_msg>Added fail testing macro.<commit_after>// pest. The Elegant Parser
// Copyright (C) 2017  Dragoș Tiselice
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

#[doc(hidden)]
#[macro_export]
macro_rules! consumes_to {
    ( $_rules:ident, $tokens:expr, [] ) => ();
    ( $rules:ident, $tokens:expr, [ $name:ident ( $start:expr, $end:expr ) ] ) => {
        let expected = format!("expected Start {{ rule: {:?}, pos: Position {{ pos: {} }} }}",
                               $rules::$name, $start);
        match $tokens.next().expect(&format!("{} but found nothing", expected)) {
            $crate::Token::Start { rule, pos } => {
                let message = format!("{} but found Start {{ rule: {:?}, pos: Position {{ {} }} }}",
                                      expected, rule, pos.pos());

                if rule != $rules::$name || pos.pos() != $start {
                    panic!("{}", message);
                }
            },
            token => panic!("{}", format!("{} but found {:?}", expected, token))
        };

        let expected = format!("expected End {{ rule: {:?}, pos: Position {{ pos: {} }} }}",
                               $rules::$name, $end);
        match $tokens.next().expect(&format!("{} but found nothing", expected)) {
            $crate::Token::End { rule, pos } => {
                let message = format!("{} but found End {{ rule: {:?}, pos: Position {{ {} }} }}",
                                      expected, rule, pos.pos());

                if rule != $rules::$name || pos.pos() != $end {
                    panic!("{}", message);
                }
            },
            token => panic!("{}", format!("{} but found {:?}", expected, token))
        };
    };
    ( $rules:ident, $tokens:expr, [ $name:ident ( $start:expr, $end:expr ),
                                    $( $names:ident $calls:tt ),* ] ) => {

        let expected = format!("expected Start {{ rule: {:?}, pos: Position {{ pos: {} }} }}",
                               $rules::$name, $start);
        match $tokens.next().expect(&format!("{} but found nothing", expected)) {
            $crate::Token::Start { rule, pos } => {
                let message = format!("{} but found Start {{ rule: {:?}, pos: Position {{ {} }} }}",
                                      expected, rule, pos.pos());

                if rule != $rules::$name || pos.pos() != $start {
                    panic!("{}", message);
                }
            },
            token => panic!("{}", format!("{} but found {:?}", expected, token))
        };

        let expected = format!("expected End {{ rule: {:?}, pos: Position {{ pos: {} }} }}",
                               $rules::$name, $end);
        match $tokens.next().expect(&format!("{} but found nothing", expected)) {
            $crate::Token::End { rule, pos } => {
                let message = format!("{} but found End {{ rule: {:?}, pos: Position {{ {} }} }}",
                                      expected, rule, pos.pos());

                if rule != $rules::$name || pos.pos() != $end {
                    panic!("{}", message);
                }
            },
            token => panic!("{}", format!("{} but found {:?}", expected, token))
        };

        consumes_to!($rules, $tokens, [ $( $names $calls ),* ]);
    };
    ( $rules:ident, $tokens:expr, [ $name:ident ( $start:expr, $end:expr,
                                                  [ $( $names:ident $calls:tt ),* ] ) ] ) => {
        let expected = format!("expected Start {{ rule: {:?}, pos: Position {{ pos: {} }} }}",
                               $rules::$name, $start);
        match $tokens.next().expect(&format!("{} but found nothing", expected)) {
            $crate::Token::Start { rule, pos } => {
                let message = format!("{} but found Start {{ rule: {:?}, pos: Position {{ {} }} }}",
                                      expected, rule, pos.pos());

                if rule != $rules::$name || pos.pos() != $start {
                    panic!("{}", message);
                }
            },
            token => panic!("{}", format!("{} but found {:?}", expected, token))
        };

        consumes_to!($rules, $tokens, [ $( $names $calls ),* ]);

        let expected = format!("expected End {{ rule: {:?}, pos: Position {{ pos: {} }} }}",
                               $rules::$name, $end);
        match $tokens.next().expect(&format!("{} but found nothing", expected)) {
            $crate::Token::End { rule, pos } => {
                let message = format!("{} but found End {{ rule: {:?}, pos: Position {{ {} }} }}",
                                      expected, rule, pos.pos());

                if rule != $rules::$name || pos.pos() != $end {
                    panic!("{}", message);
                }
            },
            token => panic!("{}", format!("{} but found {:?}", expected, token))
        };
    };
    ( $rules:ident, $tokens:expr, [ $name:ident ( $start:expr, $end:expr,
                                                  [ $( $nested_names:ident $nested_calls:tt ),* ] ),
                                    $( $names:ident $calls:tt ),* ] ) => {

        let expected = format!("expected Start {{ rule: {:?}, pos: Position {{ pos: {} }} }}",
                               $rules::$name, $start);
        match $tokens.next().expect(&format!("{} but found nothing", expected)) {
            $crate::Token::Start { rule, pos } => {
                let message = format!("{} but found Start {{ rule: {:?}, pos: Position {{ {} }} }}",
                                      expected, rule, pos.pos());

                if rule != $rules::$name || pos.pos() != $start {
                    panic!("{}", message);
                }
            },
            token => panic!("{}", format!("{} but found {:?}", expected, token))
        };

        consumes_to!($rules, $tokens, [ $( $nested_names $nested_calls ),* ]);

        let expected = format!("expected End {{ rule: {:?}, pos: Position {{ pos: {} }} }}",
                               $rules::$name, $end);
        match $tokens.next().expect(&format!("{} but found nothing", expected)) {
            $crate::Token::End { rule, pos } => {
                let message = format!("{} but found End {{ rule: {:?}, pos: Position {{ {} }} }}",
                                      expected, rule, pos.pos());

                if rule != $rules::$name || pos.pos() != $end {
                    panic!("{}", message);
                }
            },
            token => panic!("{}", format!("{} but found {:?}", expected, token))
        };

        consumes_to!($rules, $tokens, [ $( $names $calls ),* ]);
    };
}

/// A `macro` which facilitates grammar testing and debugging by comparing produced tokens.
///
/// # Examples
///
/// ```
/// # #[macro_use]
/// # extern crate pest;
/// # use std::rc::Rc;
/// # use pest::{Error, Parser};
/// # use pest::inputs::Input;
/// # use pest::iterators::Pairs;
/// # fn main() {
/// # #[allow(non_camel_case_types)]
/// # #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
/// # enum Rule {
/// #     a,
/// #     b,
/// #     c
/// # }
/// #
/// # struct AbcParser;
/// #
/// # impl Parser<Rule> for AbcParser {
/// #     fn parse<I: Input>(_: Rule, input: Rc<I>) -> Result<Pairs<Rule, I>, Error<Rule, I>> {
/// #         pest::state(input, |state, pos| {
/// #             state.rule(Rule::a, pos, |state, pos| {
/// #                 state.rule(Rule::b, pos.skip(1).unwrap(), |_, pos| {
/// #                     pos.skip(1)
/// #                 }).unwrap().skip(1)
/// #             }).and_then(|p| {
/// #                 state.rule(Rule::c, p.skip(1).unwrap(), |_, pos| {
/// #                     pos.skip(1)
/// #                 })
/// #             })
/// #         })
/// #     }
/// # }
/// parses_to! {
///     parser: AbcParser,
///     input:  "abcde",
///     rule:   Rule::a,
///     tokens: [
///         a(0, 3, [
///             b(1, 2)
///         ]),
///         c(4, 5)
///     ]
/// };
/// # }
/// ```
#[macro_export]
macro_rules! parses_to {
    ( parser: $parser:ident, input: $string:expr, rule: $rules:tt :: $rule:tt,
      tokens: [ $( $names:ident $calls:tt ),* ] ) => {

        #[allow(unused_mut)]
        {
            use $crate::Parser;

            let mut tokens = $parser::parse_str($rules::$rule, $string).unwrap().tokens();

            consumes_to!($rules, &mut tokens, [ $( $names $calls ),* ]);

            let rest: Vec<_> = tokens.collect();

            assert!(rest.is_empty(), format!("expected end of stream, but found {:?}", rest));
        }
    };
}

/// A `macro` which facilitates grammar testing and debugging by comparing produced errors.
///
/// # Examples
///
/// ```
/// # #[macro_use]
/// # extern crate pest;
/// # use std::rc::Rc;
/// # use pest::{Error, Parser};
/// # use pest::inputs::Input;
/// # use pest::iterators::Pairs;
/// # fn main() {
/// # #[allow(non_camel_case_types)]
/// # #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
/// # enum Rule {
/// #     a,
/// #     b,
/// #     c
/// # }
/// #
/// # struct AbcParser;
/// #
/// # impl Parser<Rule> for AbcParser {
/// #     fn parse<I: Input>(_: Rule, input: Rc<I>) -> Result<Pairs<Rule, I>, Error<Rule, I>> {
/// #         pest::state(input, |state, pos| {
/// #             state.rule(Rule::a, pos, |state, pos| {
/// #                 state.rule(Rule::b, pos.skip(1).unwrap(), |_, pos| {
/// #                     pos.skip(1)
/// #                 }).unwrap().skip(1)
/// #             }).and_then(|p| {
/// #                 state.rule(Rule::c, p.skip(1).unwrap(), |_, pos| {
/// #                     pos.match_string("e")
/// #                 })
/// #             })
/// #         })
/// #     }
/// # }
/// fails_with! {
///     parser: AbcParser,
///     input: "abcdf",
///     rule: Rule::a,
///     positives: vec![Rule::c],
///     negatives: vec![],
///     pos: 4
/// };
/// # }
/// ```
#[macro_export]
macro_rules! fails_with {
    ( parser: $parser:ident, input: $string:expr, rule: $rules:tt :: $rule:tt,
      positives: $positives:expr, negatives: $negatives:expr, pos: $pos:expr ) => {

        #[allow(unused_mut)]
        {
            use $crate::Parser;

            let error = $parser::parse_str($rules::$rule, $string).unwrap_err();

            match error {
                Error::ParsingError { positives, negatives, pos } => {
                    assert_eq!(positives, $positives);
                    assert_eq!(negatives, $negatives);
                    assert_eq!(pos.pos(), $pos);
                }
                _ => unreachable!()
            };
        }
    };
}

#[cfg(test)]
mod tests {
    use std::rc::Rc;

    use super::super::error::Error;
    use super::super::inputs::Input;
    use super::super::{Parser, state};
    use super::super::iterators::Pairs;

    #[allow(non_camel_case_types)]
    #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
    enum Rule {
        a,
        b,
        c
    }

    struct AbcParser;

    impl Parser<Rule> for AbcParser {
        fn parse<I: Input>(_: Rule, input: Rc<I>) -> Result<Pairs<Rule, I>, Error<Rule, I>> {
            state(input, |state, pos| {
                state.rule(Rule::a, pos, |state, pos| {
                    state.rule(Rule::b, pos.skip(1).unwrap(), |_, pos| {
                        pos.skip(1)
                    }).unwrap().skip(1)
                }).and_then(|p| {
                    state.rule(Rule::c, p.skip(1).unwrap(), |_, pos| {
                        pos.match_string("e")
                    })
                })
            })
        }
    }

    #[test]
    fn parses_to() {
        parses_to! {
            parser: AbcParser,
            input: "abcde",
            rule: Rule::a,
            tokens: [
                a(0, 3, [
                    b(1, 2)
                ]),
                c(4, 5)
            ]
        };
    }

    #[test]
    #[should_panic]
    fn missing_end() {
        parses_to! {
            parser: AbcParser,
            input: "abcde",
            rule: Rule::a,
            tokens: [
                a(0, 3, [
                    b(1, 2)
                ])
            ]
        };
    }

    #[test]
    #[should_panic]
    fn empty() {
        parses_to! {
            parser: AbcParser,
            input: "abcde",
            rule: Rule::a,
            tokens: []
        };
    }

    #[test]
    fn fails_with() {
        fails_with! {
            parser: AbcParser,
            input: "abcdf",
            rule: Rule::a,
            positives: vec![Rule::c],
            negatives: vec![],
            pos: 4
        };
    }

    #[test]
    #[should_panic]
    fn wrong_positives() {
        fails_with! {
            parser: AbcParser,
            input: "abcdf",
            rule: Rule::a,
            positives: vec![Rule::a],
            negatives: vec![],
            pos: 4
        };
    }

    #[test]
    #[should_panic]
    fn wrong_negatives() {
        fails_with! {
            parser: AbcParser,
            input: "abcdf",
            rule: Rule::a,
            positives: vec![Rule::c],
            negatives: vec![Rule::c],
            pos: 4
        };
    }

    #[test]
    #[should_panic]
    fn wrong_pos() {
        fails_with! {
            parser: AbcParser,
            input: "abcdf",
            rule: Rule::a,
            positives: vec![Rule::c],
            negatives: vec![],
            pos: 3
        };
    }
}
<|endoftext|>


<commit_before>//! Data types and utility function for units:
//! Implemet a poor man's unit type system for now...
//!
//! Maybe we can have s.th. like this (F#) for Rust: https://en.wikibooks.org/wiki/F_Sharp_Programming/Units_of_Measure
//! Alternatively, see here:
//! https://www.reddit.com/r/rust/comments/37qut9/typesafe_userdefined_units_of_measure_for_rust/
//! https://blog.mozilla.org/research/2014/06/23/static-checking-of-units-in-servo/

use std::ops::Add;
use std::ops::Sub;
use std::ops::Mul;
use std::ops::Div;
use std::cmp::PartialEq;

macro_rules! init_unit {
    ($i:ident) => {
        #[derive(Debug)]
        pub struct $i(pub f64);

        impl PartialEq for $i {
            fn eq(self: &$i, &$i(rhs): &$i) -> bool {
                let $i(lhs) = *self;
                lhs == rhs
            }
        }

        impl Add for $i {
            type Output = $i;

            fn add(self: $i, $i(rhs): $i) -> $i {
                let $i(lhs) = self;
                $i(lhs + rhs)
            }
        }

        impl Sub for $i {
            type Output = $i;

            fn sub(self: $i, $i(rhs): $i) -> $i {
                let $i(lhs) = self;
                $i(lhs - rhs)
            }
        }

        impl Mul<f64> for $i {
            type Output = $i;

            fn mul(self: $i, rhs: f64) -> $i {
                let $i(lhs) = self;
                $i(lhs * rhs)
            }
        }

        impl Div<f64> for $i {
            type Output = $i;

            fn div(self: $i, rhs: f64) -> $i {
                let $i(lhs) = self;
                $i(lhs / rhs)
            }
        }

        impl Div<$i> for $i {
            type Output = f64;

            fn div(self: $i, $i(rhs): $i) -> f64 {
                let $i(lhs) = self;
                lhs / rhs
            }
        }
    }
}

macro_rules! mul_unit {
    ($i1:ident, $i2:ident, $i3:ident) => {
        impl Mul<$i2> for $i1 {
            type Output = $i3;

            fn mul(self: $i1, $i2(rhs): $i2) -> $i3 {
                let $i1(lhs) = self;
                $i3(lhs * rhs)
            }
        }
    }
}

macro_rules! div_unit {
    ($i1:ident, $i2:ident, $i3:ident) => {
        impl Div<$i2> for $i1 {
            type Output = $i3;

            fn div(self: $i1, $i2(rhs): $i2) -> $i3 {
                let $i1(lhs) = self;
                $i3(lhs / rhs)
            }
        }
    }
}

init_unit!(Meter);

init_unit!(Meter2);

mul_unit!(Meter, Meter, Meter2);

init_unit!(Second);

init_unit!(Second2);

mul_unit!(Second, Second, Second2);

init_unit!(MeterPerSecond);

div_unit!(Meter, Second, MeterPerSecond);

mul_unit!(MeterPerSecond, Second, Meter);
<commit_msg>refactoring, improve macro, add more units<commit_after>//! Data types and utility function for units:
//! Implemet a poor man's unit type system for now...
//!
//! Maybe we can have s.th. like this (F#) for Rust: https://en.wikibooks.org/wiki/F_Sharp_Programming/Units_of_Measure
//! Alternatively, see here:
//! https://www.reddit.com/r/rust/comments/37qut9/typesafe_userdefined_units_of_measure_for_rust/
//! https://blog.mozilla.org/research/2014/06/23/static-checking-of-units-in-servo/

use std::ops::Add;
use std::ops::Sub;
use std::ops::Mul;
use std::ops::Div;
use std::cmp::PartialEq;

macro_rules! init_unit {
    ($i:ident) => {
        #[derive(Debug)]
        pub struct $i(pub f64);

        impl PartialEq for $i {
            fn eq(self: &$i, &$i(rhs): &$i) -> bool {
                let $i(lhs) = *self;
                lhs == rhs
            }
        }

        impl Add for $i {
            type Output = $i;

            fn add(self: $i, $i(rhs): $i) -> $i {
                let $i(lhs) = self;
                $i(lhs + rhs)
            }
        }

        impl Sub for $i {
            type Output = $i;

            fn sub(self: $i, $i(rhs): $i) -> $i {
                let $i(lhs) = self;
                $i(lhs - rhs)
            }
        }

        impl Mul<f64> for $i {
            type Output = $i;

            fn mul(self: $i, rhs: f64) -> $i {
                let $i(lhs) = self;
                $i(lhs * rhs)
            }
        }

        impl Div<f64> for $i {
            type Output = $i;

            fn div(self: $i, rhs: f64) -> $i {
                let $i(lhs) = self;
                $i(lhs / rhs)
            }
        }

        impl Div<$i> for $i {
            type Output = f64;

            fn div(self: $i, $i(rhs): $i) -> f64 {
                let $i(lhs) = self;
                lhs / rhs
            }
        }
    }
}

macro_rules! mul_div_unit {
    // $i1 * $i2 = $i3
    // $i2 * $i1 = $i3
    // $i1 = $i3 / $i2
    // $i2 = $i3 / $i1
    ($i1:ident, $i2:ident, $i3:ident) => {
        impl Mul<$i2> for $i1 {
            type Output = $i3;

            fn mul(self: $i1, $i2(rhs): $i2) -> $i3 {
                let $i1(lhs) = self;
                $i3(lhs * rhs)
            }
        }

        impl Mul<$i1> for $i2 {
            type Output = $i3;

            fn mul(self: $i2, $i1(rhs): $i1) -> $i3 {
                let $i2(lhs) = self;
                $i3(lhs * rhs)
            }
        }

        impl Div<$i2> for $i3 {
            type Output = $i1;

            fn div(self: $i3, $i2(rhs): $i2) -> $i1 {
                let $i3(lhs) = self;
                $i1(lhs / rhs)
            }
        }

        impl Div<$i1> for $i3 {
            type Output = $i2;

            fn div(self: $i3, $i1(rhs): $i1) -> $i2 {
                let $i3(lhs) = self;
                $i2(lhs / rhs)
            }
        }
    };

    // $i1 * $i1 = $i2
    // $i1 = $i2 / $i1
    ($i1:ident, $i2:ident) => {
        impl Mul<$i1> for $i1 {
            type Output = $i2;

            fn mul(self: $i1, $i1(rhs): $i1) -> $i2 {
                let $i1(lhs) = self;
                $i2(lhs * rhs)
            }
        }

        impl Div<$i1> for $i2 {
            type Output = $i1;

            fn div(self: $i2, $i1(rhs): $i1) -> $i1 {
                let $i2(lhs) = self;
                $i1(lhs / rhs)
            }
        }
    };
}

init_unit!(Meter);

init_unit!(Meter2);

init_unit!(Meter3);

mul_div_unit!(Meter, Meter2);

mul_div_unit!(Meter, Meter2, Meter3);

init_unit!(Second);

init_unit!(Second2);

init_unit!(Second3);

mul_div_unit!(Second, Second2);

mul_div_unit!(Second, Second2, Second3);

init_unit!(MeterPerSecond);

mul_div_unit!(MeterPerSecond, Second, Meter);

init_unit!(MeterPerSecond2);

mul_div_unit!(MeterPerSecond2, Second, MeterPerSecond);

mul_div_unit!(MeterPerSecond2, Second2, Meter);

init_unit!(Meter2PerSecond);

mul_div_unit!(MeterPerSecond, Meter, Meter2PerSecond);

init_unit!(Meter2PerSecond2);

mul_div_unit!(Meter2PerSecond2, Second, Meter2PerSecond);

mul_div_unit!(Meter2PerSecond2, Second2, Meter2);

mul_div_unit!(MeterPerSecond, Meter2PerSecond2);

init_unit!(KG);

init_unit!(Newton);

mul_div_unit!(KG, MeterPerSecond2, Newton);
<|endoftext|>


<commit_before>//! Statuses interface

use self::super::Github;
use rep::{Status, StatusReq};
use rustc_serialize::json;
use std::io::Result;

pub struct Statuses<'a> {
  github: &'a Github<'a>,
  owner: &'static str,
  repo: &'static str
}

impl<'a> Statuses<'a> {
  pub fn new(github: &'a Github<'a>, owner: &'static str, repo: &'static str) -> Statuses<'a> {
    Statuses {
      github: github,
      owner: owner,
      repo: repo
    }
  }

  fn path(&self, more: &str) -> String {
    format!("/repos/{}/{}/statuses{}", self.owner, self.repo, more)
  }

  fn create(&self, sha: &'static str, status: &StatusReq) -> Result<Status> {
    let data = json::encode(&status).unwrap();
    let body = try!(
      self.github.post(
        &self.path(&format!("/{}", sha)),
        data.as_bytes()
      )
    );
    Ok(json::decode::<Status>(&body).unwrap())
  }

  pub fn list(&self, sha: &'static str) -> Result<Vec<Status>> {
    let body = try!(
      self.github.get(
        &format!(
          "/repos/{}/{}/commit/{}/statuses", self.owner, self.repo, sha
        )
      )
    );
    Ok(json::decode::<Vec<Status>>(&body).unwrap())
  }

}
<commit_msg>Start combined interface<commit_after>//! Statuses interface

use self::super::Github;
use rep::{Status, StatusReq};
use rustc_serialize::json;
use std::io::Result;

pub struct Statuses<'a> {
  github: &'a Github<'a>,
  owner: &'static str,
  repo: &'static str
}

impl<'a> Statuses<'a> {
  pub fn new(github: &'a Github<'a>, owner: &'static str, repo: &'static str) -> Statuses<'a> {
    Statuses {
      github: github,
      owner: owner,
      repo: repo
    }
  }

  fn path(&self, more: &str) -> String {
    format!("/repos/{}/{}/statuses{}", self.owner, self.repo, more)
  }

  fn create(&self, sha: &'static str, status: &StatusReq) -> Result<Status> {
    let data = json::encode(&status).unwrap();
    let body = try!(
      self.github.post(
        &self.path(&format!("/{}", sha)),
        data.as_bytes()
      )
    );
    Ok(json::decode::<Status>(&body).unwrap())
  }

  pub fn list(&self, sha: &'static str) -> Result<Vec<Status>> {
    let body = try!(
      self.github.get(
        &format!(
          "/repos/{}/{}/commit/{}/statuses", self.owner, self.repo, sha
        )
      )
    );
    Ok(json::decode::<Vec<Status>>(&body).unwrap())
  }

  pub fn combined(&self, sha: &'static str) -> Result<String> {
    let body = try!(
      self.github.get(
        &format!(
          "/repos/{}/{}/commit/{}/status", self.owner, self.repo, sha
        )
      )
    );
    Ok(body)
//    Ok(json::decode::<Vec<Status>>(&body).unwrap())
  }

}
<|endoftext|>


<commit_before>extern crate libc;
extern crate time;

use api::ErrorCode;
use utils::cstring::CStringUtils;
use utils::json::{JsonDecodable, JsonEncodable};
use utils::sequence::SequenceUtils;

use self::libc::c_char;
use self::time::Timespec;

use std::collections::HashMap;
use std::ffi::CString;
use std::sync::Mutex;
use std::ops::Sub;

#[derive(Deserialize)]
struct InmemWalletRuntimeConfig {
    freshness_time: i64
}

impl<'a> JsonDecodable<'a> for InmemWalletRuntimeConfig {}

impl Default for InmemWalletRuntimeConfig {
    fn default() -> Self {
        InmemWalletRuntimeConfig { freshness_time: 1000 }
    }
}

#[derive(Debug)]
struct InmemWalletContext {
    name: String,
    freshness_time: i64
}

#[derive(Debug)]
struct InmemWalletRecord {
    key: String,
    value: String,
    time_created: Timespec
}

#[derive(Debug, Serialize)]
pub struct InmemWalletJSONValue {
    pub key: String,
    pub value: String
}

#[derive(Debug, Serialize)]
pub struct InmemWalletJSONValues {
    pub values: Vec<InmemWalletJSONValue>
}

impl JsonEncodable for InmemWalletJSONValues {}

lazy_static! {
    static ref INMEM_WALLETS: Mutex<HashMap<String, HashMap<String, InmemWalletRecord>>> = Default::default();
}

lazy_static! {
    static ref INMEM_WALLET_HANDLES: Mutex<HashMap<i32, InmemWalletContext>> = Default::default();
}

pub struct InmemWallet {}

impl InmemWallet {
    pub extern "C" fn create(name: *const c_char,
                             _: *const c_char,
                             _: *const c_char) -> ErrorCode {
        check_useful_c_str!(name, ErrorCode::CommonInvalidStructure);

        let mut wallets = INMEM_WALLETS.lock().unwrap();

        if wallets.contains_key(&name) {
            // Invalid state as "already exists" case must be checked on service layer
            return ErrorCode::CommonInvalidState;
        }
        wallets.insert(name.clone(), HashMap::new());
        ErrorCode::Success
    }

    pub extern "C" fn open(name: *const c_char,
                           _: *const c_char,
                           runtime_config: *const c_char,
                           _: *const c_char,
                           handle: *mut i32) -> ErrorCode {
        check_useful_c_str!(name, ErrorCode::CommonInvalidStructure);
        check_useful_opt_c_str!(runtime_config, ErrorCode::CommonInvalidStructure);

        let runtime_config = match runtime_config {
            Some(config) => InmemWalletRuntimeConfig::from_json(config.as_str()).unwrap(), // FIXME: parse error!!!
            None => InmemWalletRuntimeConfig::default()
        };

        let wallets = INMEM_WALLETS.lock().unwrap();

        if !wallets.contains_key(&name) {
            return ErrorCode::CommonInvalidState;
        }

        let mut handles = INMEM_WALLET_HANDLES.lock().unwrap();
        let xhandle = SequenceUtils::get_next_id();
        handles.insert(xhandle, InmemWalletContext {
            name,
            freshness_time: runtime_config.freshness_time
        });

        unsafe { *handle = xhandle };
        ErrorCode::Success
    }

    pub extern "C" fn set(xhandle: i32,
                          key: *const c_char,
                          value: *const c_char) -> ErrorCode {
        check_useful_c_str!(key, ErrorCode::CommonInvalidStructure);
        check_useful_c_str!(value, ErrorCode::CommonInvalidStructure);

        let handles = INMEM_WALLET_HANDLES.lock().unwrap();

        if !handles.contains_key(&xhandle) {
            return ErrorCode::CommonInvalidState;
        }

        let wallet_context = handles.get(&xhandle).unwrap();

        let mut wallets = INMEM_WALLETS.lock().unwrap();

        if !wallets.contains_key(&wallet_context.name) {
            return ErrorCode::CommonInvalidState;
        }

        let wallet = wallets.get_mut(&wallet_context.name).unwrap();

        wallet.insert(key.clone(), InmemWalletRecord {
            key: key,
            value: value,
            time_created: time::get_time()
        });
        ErrorCode::Success
    }

    pub extern "C" fn get(xhandle: i32,
                          key: *const c_char,
                          value_ptr: *mut *const c_char) -> ErrorCode {
        check_useful_c_str!(key, ErrorCode::CommonInvalidStructure);

        let handles = INMEM_WALLET_HANDLES.lock().unwrap();

        if !handles.contains_key(&xhandle) {
            return ErrorCode::CommonInvalidState;
        }

        let wallet_context = handles.get(&xhandle).unwrap();

        let wallets = INMEM_WALLETS.lock().unwrap();

        if !wallets.contains_key(&wallet_context.name) {
            return ErrorCode::CommonInvalidState;
        }

        let wallet = wallets.get(&wallet_context.name).unwrap();

        if !wallet.contains_key(&key) {
            return ErrorCode::WalletNotFoundError;
        }

        let ref value = wallet.get(&key).unwrap().value;
        unsafe { *value_ptr = CString::new(value.as_str()).unwrap().into_raw(); }
        ErrorCode::Success
    }

    pub extern "C" fn get_not_expied(xhandle: i32,
                                     key: *const c_char,
                                     value_ptr: *mut *const c_char) -> ErrorCode {
        check_useful_c_str!(key, ErrorCode::CommonInvalidStructure);

        let handles = INMEM_WALLET_HANDLES.lock().unwrap();

        if !handles.contains_key(&xhandle) {
            return ErrorCode::CommonInvalidState;
        }

        let wallet_context = handles.get(&xhandle).unwrap();

        let wallets = INMEM_WALLETS.lock().unwrap();

        if !wallets.contains_key(&wallet_context.name) {
            return ErrorCode::CommonInvalidState;
        }

        let wallet = wallets.get(&wallet_context.name).unwrap();

        if !wallet.contains_key(&key) {
            return ErrorCode::WalletNotFoundError;
        }

        let ref record = wallet.get(&key).unwrap();

        if time::get_time().sub(record.time_created).num_seconds() > wallet_context.freshness_time {
            return ErrorCode::WalletNotFoundError;
        }

        unsafe { *value_ptr = CString::new(record.value.as_str()).unwrap().into_raw(); }
        ErrorCode::Success
    }

    pub extern "C" fn list(xhandle: i32,
                           key_prefix: *const c_char,
                           values_json_ptr: *mut *const c_char) -> ErrorCode {
        check_useful_c_str!(key_prefix, ErrorCode::CommonInvalidStructure);

        let handles = INMEM_WALLET_HANDLES.lock().unwrap();

        if !handles.contains_key(&xhandle) {
            return ErrorCode::CommonInvalidState;
        }

        let wallet_context = handles.get(&xhandle).unwrap();

        let wallets = INMEM_WALLETS.lock().unwrap();

        if !wallets.contains_key(&wallet_context.name) {
            return ErrorCode::CommonInvalidState;
        }

        let wallet = wallets.get(&wallet_context.name).unwrap();

        let values = InmemWalletJSONValues {
            values: wallet
                .keys()
                .filter(|&ref key| key.starts_with(&key_prefix))
                .map(|&ref key| InmemWalletJSONValue {
                    key: key.clone(),
                    value: wallet.get(key).unwrap().value.clone()
                })
                .collect()
        }
            .to_json()
            .unwrap();

        unsafe { *values_json_ptr = CString::new(values.as_str()).unwrap().into_raw(); }
        ErrorCode::Success
    }

    pub extern "C" fn close(xhandle: i32) -> ErrorCode {
        let mut handles = INMEM_WALLET_HANDLES.lock().unwrap();

        if !handles.contains_key(&xhandle) {
            return ErrorCode::CommonInvalidState;
        }

        handles.remove(&xhandle);
        ErrorCode::Success
    }

    pub extern "C" fn delete(name: *const c_char,
                             _: *const c_char,
                             _: *const c_char) -> ErrorCode {
        check_useful_c_str!(name, ErrorCode::CommonInvalidStructure);

        let mut wallets = INMEM_WALLETS.lock().unwrap();

        if !wallets.contains_key(&name) {
            return ErrorCode::CommonInvalidState;
        }

        wallets.remove(&name);
        ErrorCode::Success
    }

    pub extern "C" fn free(_: i32,
                           value: *const c_char) -> ErrorCode {
        unsafe { CString::from_raw(value as *mut c_char); }
        ErrorCode::Success
    }

    pub fn cleanup() {
        let mut wallets = INMEM_WALLETS.lock().unwrap();
        wallets.clear();

        let mut handles = INMEM_WALLET_HANDLES.lock().unwrap();
        handles.clear();
    }
}<commit_msg>Fix compatibility with old rust compiler<commit_after>extern crate libc;
extern crate time;

use api::ErrorCode;
use utils::cstring::CStringUtils;
use utils::json::{JsonDecodable, JsonEncodable};
use utils::sequence::SequenceUtils;

use self::libc::c_char;
use self::time::Timespec;

use std::collections::HashMap;
use std::ffi::CString;
use std::sync::Mutex;
use std::ops::Sub;

#[derive(Deserialize)]
struct InmemWalletRuntimeConfig {
    freshness_time: i64
}

impl<'a> JsonDecodable<'a> for InmemWalletRuntimeConfig {}

impl Default for InmemWalletRuntimeConfig {
    fn default() -> Self {
        InmemWalletRuntimeConfig { freshness_time: 1000 }
    }
}

#[derive(Debug)]
struct InmemWalletContext {
    name: String,
    freshness_time: i64
}

#[derive(Debug)]
struct InmemWalletRecord {
    key: String,
    value: String,
    time_created: Timespec
}

#[derive(Debug, Serialize)]
pub struct InmemWalletJSONValue {
    pub key: String,
    pub value: String
}

#[derive(Debug, Serialize)]
pub struct InmemWalletJSONValues {
    pub values: Vec<InmemWalletJSONValue>
}

impl JsonEncodable for InmemWalletJSONValues {}

lazy_static! {
    static ref INMEM_WALLETS: Mutex<HashMap<String, HashMap<String, InmemWalletRecord>>> = Default::default();
}

lazy_static! {
    static ref INMEM_WALLET_HANDLES: Mutex<HashMap<i32, InmemWalletContext>> = Default::default();
}

pub struct InmemWallet {}

impl InmemWallet {
    pub extern "C" fn create(name: *const c_char,
                             _: *const c_char,
                             _: *const c_char) -> ErrorCode {
        check_useful_c_str!(name, ErrorCode::CommonInvalidStructure);

        let mut wallets = INMEM_WALLETS.lock().unwrap();

        if wallets.contains_key(&name) {
            // Invalid state as "already exists" case must be checked on service layer
            return ErrorCode::CommonInvalidState;
        }
        wallets.insert(name.clone(), HashMap::new());
        ErrorCode::Success
    }

    pub extern "C" fn open(name: *const c_char,
                           _: *const c_char,
                           runtime_config: *const c_char,
                           _: *const c_char,
                           handle: *mut i32) -> ErrorCode {
        check_useful_c_str!(name, ErrorCode::CommonInvalidStructure);
        check_useful_opt_c_str!(runtime_config, ErrorCode::CommonInvalidStructure);

        let runtime_config = match runtime_config {
            Some(config) => InmemWalletRuntimeConfig::from_json(config.as_str()).unwrap(), // FIXME: parse error!!!
            None => InmemWalletRuntimeConfig::default()
        };

        let wallets = INMEM_WALLETS.lock().unwrap();

        if !wallets.contains_key(&name) {
            return ErrorCode::CommonInvalidState;
        }

        let mut handles = INMEM_WALLET_HANDLES.lock().unwrap();
        let xhandle = SequenceUtils::get_next_id();
        handles.insert(xhandle, InmemWalletContext {
            name: name,
            freshness_time: runtime_config.freshness_time
        });

        unsafe { *handle = xhandle };
        ErrorCode::Success
    }

    pub extern "C" fn set(xhandle: i32,
                          key: *const c_char,
                          value: *const c_char) -> ErrorCode {
        check_useful_c_str!(key, ErrorCode::CommonInvalidStructure);
        check_useful_c_str!(value, ErrorCode::CommonInvalidStructure);

        let handles = INMEM_WALLET_HANDLES.lock().unwrap();

        if !handles.contains_key(&xhandle) {
            return ErrorCode::CommonInvalidState;
        }

        let wallet_context = handles.get(&xhandle).unwrap();

        let mut wallets = INMEM_WALLETS.lock().unwrap();

        if !wallets.contains_key(&wallet_context.name) {
            return ErrorCode::CommonInvalidState;
        }

        let wallet = wallets.get_mut(&wallet_context.name).unwrap();

        wallet.insert(key.clone(), InmemWalletRecord {
            key: key,
            value: value,
            time_created: time::get_time()
        });
        ErrorCode::Success
    }

    pub extern "C" fn get(xhandle: i32,
                          key: *const c_char,
                          value_ptr: *mut *const c_char) -> ErrorCode {
        check_useful_c_str!(key, ErrorCode::CommonInvalidStructure);

        let handles = INMEM_WALLET_HANDLES.lock().unwrap();

        if !handles.contains_key(&xhandle) {
            return ErrorCode::CommonInvalidState;
        }

        let wallet_context = handles.get(&xhandle).unwrap();

        let wallets = INMEM_WALLETS.lock().unwrap();

        if !wallets.contains_key(&wallet_context.name) {
            return ErrorCode::CommonInvalidState;
        }

        let wallet = wallets.get(&wallet_context.name).unwrap();

        if !wallet.contains_key(&key) {
            return ErrorCode::WalletNotFoundError;
        }

        let ref value = wallet.get(&key).unwrap().value;
        unsafe { *value_ptr = CString::new(value.as_str()).unwrap().into_raw(); }
        ErrorCode::Success
    }

    pub extern "C" fn get_not_expied(xhandle: i32,
                                     key: *const c_char,
                                     value_ptr: *mut *const c_char) -> ErrorCode {
        check_useful_c_str!(key, ErrorCode::CommonInvalidStructure);

        let handles = INMEM_WALLET_HANDLES.lock().unwrap();

        if !handles.contains_key(&xhandle) {
            return ErrorCode::CommonInvalidState;
        }

        let wallet_context = handles.get(&xhandle).unwrap();

        let wallets = INMEM_WALLETS.lock().unwrap();

        if !wallets.contains_key(&wallet_context.name) {
            return ErrorCode::CommonInvalidState;
        }

        let wallet = wallets.get(&wallet_context.name).unwrap();

        if !wallet.contains_key(&key) {
            return ErrorCode::WalletNotFoundError;
        }

        let ref record = wallet.get(&key).unwrap();

        if time::get_time().sub(record.time_created).num_seconds() > wallet_context.freshness_time {
            return ErrorCode::WalletNotFoundError;
        }

        unsafe { *value_ptr = CString::new(record.value.as_str()).unwrap().into_raw(); }
        ErrorCode::Success
    }

    pub extern "C" fn list(xhandle: i32,
                           key_prefix: *const c_char,
                           values_json_ptr: *mut *const c_char) -> ErrorCode {
        check_useful_c_str!(key_prefix, ErrorCode::CommonInvalidStructure);

        let handles = INMEM_WALLET_HANDLES.lock().unwrap();

        if !handles.contains_key(&xhandle) {
            return ErrorCode::CommonInvalidState;
        }

        let wallet_context = handles.get(&xhandle).unwrap();

        let wallets = INMEM_WALLETS.lock().unwrap();

        if !wallets.contains_key(&wallet_context.name) {
            return ErrorCode::CommonInvalidState;
        }

        let wallet = wallets.get(&wallet_context.name).unwrap();

        let values = InmemWalletJSONValues {
            values: wallet
                .keys()
                .filter(|&ref key| key.starts_with(&key_prefix))
                .map(|&ref key| InmemWalletJSONValue {
                    key: key.clone(),
                    value: wallet.get(key).unwrap().value.clone()
                })
                .collect()
        }
            .to_json()
            .unwrap();

        unsafe { *values_json_ptr = CString::new(values.as_str()).unwrap().into_raw(); }
        ErrorCode::Success
    }

    pub extern "C" fn close(xhandle: i32) -> ErrorCode {
        let mut handles = INMEM_WALLET_HANDLES.lock().unwrap();

        if !handles.contains_key(&xhandle) {
            return ErrorCode::CommonInvalidState;
        }

        handles.remove(&xhandle);
        ErrorCode::Success
    }

    pub extern "C" fn delete(name: *const c_char,
                             _: *const c_char,
                             _: *const c_char) -> ErrorCode {
        check_useful_c_str!(name, ErrorCode::CommonInvalidStructure);

        let mut wallets = INMEM_WALLETS.lock().unwrap();

        if !wallets.contains_key(&name) {
            return ErrorCode::CommonInvalidState;
        }

        wallets.remove(&name);
        ErrorCode::Success
    }

    pub extern "C" fn free(_: i32,
                           value: *const c_char) -> ErrorCode {
        unsafe { CString::from_raw(value as *mut c_char); }
        ErrorCode::Success
    }

    pub fn cleanup() {
        let mut wallets = INMEM_WALLETS.lock().unwrap();
        wallets.clear();

        let mut handles = INMEM_WALLET_HANDLES.lock().unwrap();
        handles.clear();
    }
}
<|endoftext|>


<commit_before>pub const NEWTON_ITER: usize = 1000;
pub const SETLEN: usize = 100000;
pub const THREADS: usize = 4;

pub fn generate_data(count: usize) -> Vec<f64> {
    (0..count).map(|x| x as f64 / count as f64).collect::<Vec<f64>>()
}

pub fn newton(n: f64, iterations: usize) -> f64 {
    const START: f64 = 1.0;
    let mut x = START;
    for _ in 0..iterations {
        x = x - (x*x - n) / (2.0*x);
    }
    x
}
<commit_msg>Reduce number of items<commit_after>pub const NEWTON_ITER: usize = 1000;
pub const SETLEN: usize = 10000;
pub const THREADS: usize = 4;

pub fn generate_data(count: usize) -> Vec<f64> {
    (0..count).map(|x| x as f64 / count as f64).collect::<Vec<f64>>()
}

pub fn newton(n: f64, iterations: usize) -> f64 {
    const START: f64 = 1.0;
    let mut x = START;
    for _ in 0..iterations {
        x = x - (x*x - n) / (2.0*x);
    }
    x
}
<|endoftext|>


<commit_before>#[macro_use] extern crate serde_json;
#[macro_use] extern crate serde_derive;
extern crate rmp_serde;
extern crate byteorder;
extern crate rust_libindy_wrapper as indy;
#[macro_use]
mod utils;

use indy::did::Did;
use indy::ErrorCode;
use std::sync::mpsc::channel;
use utils::b58::{FromBase58, IntoBase58};
use utils::constants::{DID_1, SEED_1, VERKEY_1};
use utils::wallet::Wallet;

#[cfg(test)]
mod create_new_did {
    use super::*;
    use std::time::Duration;

    const VALID_TIMEOUT: Duration = Duration::from_secs(5);

    #[inline]
    fn assert_did_length(did: &str) {
        assert_eq!(16, did.from_base58().unwrap().len());
    }

    #[inline]
    fn assert_verkey_len(verkey: &str) {
        assert_eq!(32, verkey.from_base58().unwrap().len());
    }

    #[test]
    fn create_did_with_empty_json() {
        let wallet = Wallet::new();

        let (did, verkey) = Did::new(wallet.handle, "{}").unwrap();

        assert_did_length(&did);
        assert_verkey_len(&verkey);
    }

    #[test]
    fn create_did_with_seed() {
        let wallet = Wallet::new();

        let config = json!({
            "seed": SEED_1
        }).to_string();

        let (did, verkey) = Did::new(wallet.handle, &config).unwrap();

        assert_eq!(DID_1, did);
        assert_eq!(VERKEY_1, verkey);
    }

    #[test]
    fn create_did_with_cid() {
        let wallet = Wallet::new();

        let config = json!({
            "seed": SEED_1,
            "cid": true,
        }).to_string();

        let (did, verkey) = Did::new(wallet.handle, &config).unwrap();

        assert_eq!(VERKEY_1, did);
        assert_eq!(VERKEY_1, verkey);
    }

    #[test]
    fn create_did_with_did() {
        let wallet = Wallet::new();

        let config = json!({
            "did": DID_1
        }).to_string();

        let (did, verkey) = Did::new(wallet.handle, &config).unwrap();

        assert_eq!(DID_1, did);
        assert_ne!(VERKEY_1, verkey);
    }

    #[test]
    fn create_did_with_crypto_type() {
        let wallet = Wallet::new();

        let config = json!({
            "crypto_type": "ed25519"
        }).to_string();

        let result = Did::new(wallet.handle, &config);

        assert!(result.is_ok());

    }

    #[test]
    fn create_did_with_invalid_wallet_handle() {
        let result = Did::new(583741, "{}");
        assert_eq!(ErrorCode::WalletInvalidHandle, result.unwrap_err());
    }

    #[test]
    fn create_wallet_empty_config() {
        let wallet = Wallet::new();

        let result = Did::new(wallet.handle, "");

        assert!(result.is_err());
    }

    #[test]
    fn create_did_async_no_config() {
        let wallet = Wallet::new();
        let (sender, receiver) = channel();

        Did::new_async(
            wallet.handle,
            "{}",
            move |ec, did, verkey| { sender.send((ec, did, verkey)).unwrap(); }
        );

        let (ec, did, verkey) = receiver.recv_timeout(VALID_TIMEOUT).unwrap();

        assert_eq!(ErrorCode::Success, ec);
        assert_did_length(&did);
        assert_verkey_len(&verkey);
    }

    #[test]
    fn create_did_async_with_seed() {
        let wallet = Wallet::new();
        let (sender, receiver) = channel();
        let config = json!({
            "seed": SEED_1
        }).to_string();

        Did::new_async(
            wallet.handle,
            &config,
            move |ec, did, key| { sender.send((ec, did, key)).unwrap(); }
        );

        let (ec, did, verkey) = receiver.recv_timeout(VALID_TIMEOUT).unwrap();

        assert_eq!(ErrorCode::Success, ec);
        assert_eq!(DID_1, did);
        assert_eq!(VERKEY_1, verkey);
    }

    #[test]
    fn create_did_async_invalid_wallet() {
        let (sender, receiver) = channel();

        Did::new_async(
            583741,
            "{}",
            move |ec, did, key| sender.send((ec, did, key)).unwrap()
        );

        let result = receiver.recv_timeout(VALID_TIMEOUT).unwrap();

        let expected = (ErrorCode::WalletInvalidHandle, String::new(), String::new());
        assert_eq!(expected, result);
    }

    #[test]
    fn create_did_timeout_no_config() {
        let wallet = Wallet::new();
        let (did, verkey) = Did::new_timeout(
            wallet.handle,
            "{}",
            VALID_TIMEOUT
        ).unwrap();

        assert_did_length(&did);
        assert_verkey_len(&verkey);
    }

    #[test]
    fn create_did_timeout_with_seed() {
        let wallet = Wallet::new();
        let config = json!({"seed": SEED_1}).to_string();
        let (did, verkey) = Did::new_timeout(
            wallet.handle,
            &config,
            VALID_TIMEOUT
        ).unwrap();

        assert_eq!(DID_1, did);
        assert_eq!(VERKEY_1, verkey);
    }

    #[test]
    fn create_did_timeout_invalid_wallet() {
        let result = Did::new_timeout(583741, "{}", VALID_TIMEOUT);
        assert_eq!(ErrorCode::WalletInvalidHandle, result.unwrap_err());
    }

    #[test]
    fn create_did_timeout_timeouts() {
        let wallet = Wallet::new();
        let config = json!({"seed": SEED_1}).to_string();
        let result = Did::new_timeout(
            wallet.handle,
            &config,
            Duration::from_micros(1)
        );

        assert_eq!(ErrorCode::CommonIOError, result.unwrap_err());
    }
}<commit_msg>TOK-393 Add Did::replace_keys_start tests<commit_after>#[macro_use] extern crate serde_json;
#[macro_use] extern crate serde_derive;
extern crate rmp_serde;
extern crate byteorder;
extern crate rust_libindy_wrapper as indy;
#[macro_use]
mod utils;

use indy::did::Did;
use indy::ErrorCode;
use std::sync::mpsc::channel;
use std::time::Duration;
use utils::b58::{FromBase58, IntoBase58};
use utils::constants::{DID_1, SEED_1, VERKEY_1};
use utils::wallet::Wallet;

const VALID_TIMEOUT: Duration = Duration::from_secs(5);
const INVALID_TIMEOUT: Duration = Duration::from_micros(1);
const INVALID_HANDLE: i32 = 583741;

#[inline]
fn assert_verkey_len(verkey: &str) {
    assert_eq!(32, verkey.from_base58().unwrap().len());
}

#[cfg(test)]
mod create_new_did {
    use super::*;

    #[inline]
    fn assert_did_length(did: &str) {
        assert_eq!(16, did.from_base58().unwrap().len());
    }

    #[test]
    fn create_did_with_empty_json() {
        let wallet = Wallet::new();

        let (did, verkey) = Did::new(wallet.handle, "{}").unwrap();

        assert_did_length(&did);
        assert_verkey_len(&verkey);
    }

    #[test]
    fn create_did_with_seed() {
        let wallet = Wallet::new();

        let config = json!({
            "seed": SEED_1
        }).to_string();

        let (did, verkey) = Did::new(wallet.handle, &config).unwrap();

        assert_eq!(DID_1, did);
        assert_eq!(VERKEY_1, verkey);
    }

    #[test]
    fn create_did_with_cid() {
        let wallet = Wallet::new();

        let config = json!({
            "seed": SEED_1,
            "cid": true,
        }).to_string();

        let (did, verkey) = Did::new(wallet.handle, &config).unwrap();

        assert_eq!(VERKEY_1, did);
        assert_eq!(VERKEY_1, verkey);
    }

    #[test]
    fn create_did_with_did() {
        let wallet = Wallet::new();

        let config = json!({
            "did": DID_1
        }).to_string();

        let (did, verkey) = Did::new(wallet.handle, &config).unwrap();

        assert_eq!(DID_1, did);
        assert_ne!(VERKEY_1, verkey);
    }

    #[test]
    fn create_did_with_crypto_type() {
        let wallet = Wallet::new();

        let config = json!({
            "crypto_type": "ed25519"
        }).to_string();

        let result = Did::new(wallet.handle, &config);

        assert!(result.is_ok());

    }

    #[test]
    fn create_did_with_invalid_wallet_handle() {
        let result = Did::new(INVALID_HANDLE, "{}");
        assert_eq!(ErrorCode::WalletInvalidHandle, result.unwrap_err());
    }

    #[test]
    fn create_wallet_empty_config() {
        let wallet = Wallet::new();

        let result = Did::new(wallet.handle, "");

        assert!(result.is_err());
    }

    #[test]
    fn create_did_async_no_config() {
        let wallet = Wallet::new();
        let (sender, receiver) = channel();

        Did::new_async(
            wallet.handle,
            "{}",
            move |ec, did, verkey| { sender.send((ec, did, verkey)).unwrap(); }
        );

        let (ec, did, verkey) = receiver.recv_timeout(VALID_TIMEOUT).unwrap();

        assert_eq!(ErrorCode::Success, ec);
        assert_did_length(&did);
        assert_verkey_len(&verkey);
    }

    #[test]
    fn create_did_async_with_seed() {
        let wallet = Wallet::new();
        let (sender, receiver) = channel();
        let config = json!({
            "seed": SEED_1
        }).to_string();

        Did::new_async(
            wallet.handle,
            &config,
            move |ec, did, key| { sender.send((ec, did, key)).unwrap(); }
        );

        let (ec, did, verkey) = receiver.recv_timeout(VALID_TIMEOUT).unwrap();

        assert_eq!(ErrorCode::Success, ec);
        assert_eq!(DID_1, did);
        assert_eq!(VERKEY_1, verkey);
    }

    #[test]
    fn create_did_async_invalid_wallet() {
        let (sender, receiver) = channel();

        Did::new_async(
            INVALID_HANDLE,
            "{}",
            move |ec, did, key| sender.send((ec, did, key)).unwrap()
        );

        let result = receiver.recv_timeout(VALID_TIMEOUT).unwrap();

        let expected = (ErrorCode::WalletInvalidHandle, String::new(), String::new());
        assert_eq!(expected, result);
    }

    #[test]
    fn create_did_timeout_no_config() {
        let wallet = Wallet::new();
        let (did, verkey) = Did::new_timeout(
            wallet.handle,
            "{}",
            VALID_TIMEOUT
        ).unwrap();

        assert_did_length(&did);
        assert_verkey_len(&verkey);
    }

    #[test]
    fn create_did_timeout_with_seed() {
        let wallet = Wallet::new();
        let config = json!({"seed": SEED_1}).to_string();
        let (did, verkey) = Did::new_timeout(
            wallet.handle,
            &config,
            VALID_TIMEOUT
        ).unwrap();

        assert_eq!(DID_1, did);
        assert_eq!(VERKEY_1, verkey);
    }

    #[test]
    fn create_did_timeout_invalid_wallet() {
        let result = Did::new_timeout(INVALID_HANDLE, "{}", VALID_TIMEOUT);
        assert_eq!(ErrorCode::WalletInvalidHandle, result.unwrap_err());
    }

    #[test]
    fn create_did_timeout_timeouts() {
        let wallet = Wallet::new();
        let config = json!({"seed": SEED_1}).to_string();
        let result = Did::new_timeout(
            wallet.handle,
            &config,
            INVALID_TIMEOUT
        );

        assert_eq!(ErrorCode::CommonIOError, result.unwrap_err());
    }
}

#[cfg(test)]
mod replace_keys_start {
    use super::*;

    #[test]
    fn replace_keys_start() {
        let wallet = Wallet::new();
        let (did, verkey) = Did::new(wallet.handle, "{}").unwrap();

        let new_verkey = Did::replace_keys_start(wallet.handle, &did, "{}").unwrap();

        assert_verkey_len(&new_verkey);
        assert_ne!(verkey, new_verkey);
    }

    #[test]
    fn replace_keys_start_invalid_wallet() {
        let wallet = Wallet::new();

        let result = Did::replace_keys_start(INVALID_HANDLE, DID_1, "{}");

        assert_eq!(ErrorCode::WalletInvalidHandle, result.unwrap_err());
    }

    #[test]
    fn replace_keys_start_with_seed() {
        let wallet = Wallet::new();
        let (did, verkey) = Did::new(wallet.handle, "{}").unwrap();
        let config = json!({"seed": SEED_1}).to_string();

        let new_verkey = Did::replace_keys_start(wallet.handle, &did, &config).unwrap();

        assert_eq!(VERKEY_1, new_verkey);
        assert_ne!(verkey, new_verkey);
    }

    #[test]
    fn replace_keys_start_valid_crypto_type() {
        let wallet = Wallet::new();
        let (did, verkey) = Did::new(wallet.handle, "{}").unwrap();
        let config = json!({"crypto_type": "ed25519"}).to_string();

        let new_verkey = Did::replace_keys_start(wallet.handle, &did, &config).unwrap();

        assert_verkey_len(&new_verkey);
        assert_ne!(verkey, new_verkey);
    }

    #[test]
    fn replace_keys_start_invalid_crypto_type() {
        let wallet = Wallet::new();
        let (did, verkey) = Did::new(wallet.handle, "{}").unwrap();
        let config = json!({"crypto_type": "ed25518"}).to_string();

        let result = Did::replace_keys_start(wallet.handle, &did, &config);

        assert_eq!(ErrorCode::UnknownCryptoTypeError, result.unwrap_err());
    }

    #[test]
    fn replace_keys_start_invalid_did() {
        let wallet = Wallet::new();
        let result = Did::replace_keys_start(wallet.handle, DID_1, "{}");

        assert_eq!(ErrorCode::WalletItemNotFound, result.unwrap_err());
    }

    #[test]
    fn replace_keys_start_async() {
        let wallet = Wallet::new();
        let (sender, receiver) = channel();
        let (did, verkey) = Did::new(wallet.handle, "{}").unwrap();

        Did::replace_keys_start_async(
            wallet.handle,
            &did,
            "{}",
            move |ec, verkey| sender.send((ec, verkey)).unwrap()
        );

        let (ec, new_verkey) = receiver.recv_timeout(VALID_TIMEOUT).unwrap();

        assert_eq!(ErrorCode::Success, ec);
        assert_verkey_len(&new_verkey);
        assert_ne!(verkey, new_verkey);
    }

    #[test]
    fn replace_keys_start_async_invalid_wallet() {
        let (sender, receiver) = channel();

        Did::replace_keys_start_async(
            INVALID_HANDLE,
            DID_1,
            "{}",
            move |ec, verkey| sender.send((ec, verkey)).unwrap()
        );

        let (ec, new_verkey) = receiver.recv_timeout(VALID_TIMEOUT).unwrap();

        assert_eq!(ErrorCode::WalletInvalidHandle, ec);
    }

    #[test]
    fn replace_keys_start_async_with_seed() {
        let wallet = Wallet::new();
        let (sender, receiver) = channel();
        let (did, verkey) = Did::new(wallet.handle, "{}").unwrap();
        let config = json!({"seed": SEED_1}).to_string();

        Did::replace_keys_start_async(
            wallet.handle,
            &did,
            &config,
            move |ec, verkey| sender.send((ec, verkey)).unwrap()
        );

        let (ec, new_verkey) = receiver.recv_timeout(VALID_TIMEOUT).unwrap();

        assert_eq!(ErrorCode::Success, ec);
        assert_eq!(VERKEY_1, new_verkey);
        assert_ne!(verkey, new_verkey);
    }

    #[test]
    fn replace_keys_start_timeout() {
        let wallet = Wallet::new();
        let (did, verkey) = Did::new(wallet.handle, "{}").unwrap();

        let new_verkey = Did::replace_keys_start_timeout(
            wallet.handle,
            &did,
            "{}",
            VALID_TIMEOUT
        ).unwrap();

        assert_verkey_len(&new_verkey);
        assert_ne!(verkey, new_verkey);
    }

    #[test]
    fn replace_keys_start_timeout_with_seed() {
        let wallet = Wallet::new();
        let (did, verkey) = Did::new(wallet.handle, "{}").unwrap();
        let config = json!({"seed": SEED_1}).to_string();

        let new_verkey = Did::replace_keys_start_timeout(
            wallet.handle,
            &did,
            &config,
            VALID_TIMEOUT
        ).unwrap();

        assert_eq!(VERKEY_1, new_verkey);
        assert_ne!(verkey, new_verkey);
    }

    #[test]
    fn replace_keys_start_timeout_invalid_wallet() {
        let result = Did::replace_keys_start_timeout(
            INVALID_HANDLE,
            DID_1,
            "{}",
            VALID_TIMEOUT
        );

        assert_eq!(ErrorCode::WalletInvalidHandle, result.unwrap_err());
    }

    #[test]
    fn replace_keys_start_timeout_timeouts() {
        let wallet = Wallet::new();
        let (did, verkey) = Did::new(wallet.handle, "{}").unwrap();

        let result = Did::replace_keys_start_timeout(
            wallet.handle,
            &did,
            "{}",
            INVALID_TIMEOUT
        );

        assert_eq!(ErrorCode::CommonIOError, result.unwrap_err());
    }
}<|endoftext|>


<commit_before>//! Parser example for INI files.
extern crate combine;

use std::collections::HashMap;

use combine::*;
use combine::char::space;
use combine::primitives::{Error, SourcePosition};

#[derive(PartialEq, Debug)]
pub struct Ini {
    pub global: HashMap<String, String>,
    pub sections: HashMap<String, HashMap<String, String>>,
}

fn property<I>(input: I) -> ParseResult<(String, String), I>
    where I: Stream<Item = char>
{
    (many1(satisfy(|c| c != '=' && c != '[' && c != ';')),
     token('='),
     many1(satisfy(|c| c != '\n' && c != ';')))
        .map(|(key, _, value)| (key, value))
        .expected("property")
        .parse_stream(input)
}

fn whitespace<I>(input: I) -> ParseResult<(), I>
    where I: Stream<Item = char>
{
    let comment = (token(';'), skip_many(satisfy(|c| c != '\n'))).map(|_| ());
    // Wrap the `spaces().or(comment)` in `skip_many` so that it skips alternating whitespace and
    // comments
    skip_many(skip_many1(space()).or(comment)).parse_stream(input)
}

fn properties<I>(input: I) -> ParseResult<HashMap<String, String>, I>
    where I: Stream<Item = char>
{
    // After each property we skip any whitespace that followed it
    many(parser(property).skip(parser(whitespace))).parse_stream(input)
}

fn section<I>(input: I) -> ParseResult<(String, HashMap<String, String>), I>
    where I: Stream<Item = char>
{
    (between(token('['), token(']'), many(satisfy(|c| c != ']'))),
     parser(whitespace),
     parser(properties))
        .map(|(name, _, properties)| (name, properties))
        .expected("section")
        .parse_stream(input)
}

fn ini<I>(input: I) -> ParseResult<Ini, I>
    where I: Stream<Item = char>
{
    (parser(whitespace), parser(properties), many(parser(section)))
        .map(|(_, global, sections)| {
            Ini {
                global: global,
                sections: sections,
            }
        })
        .parse_stream(input)
}

#[test]
fn ini_ok() {
    let text = r#"
language=rust

[section]
name=combine; Comment
type=LL(1)

"#;
    let mut expected = Ini {
        global: HashMap::new(),
        sections: HashMap::new(),
    };
    expected.global.insert(String::from("language"), String::from("rust"));

    let mut section = HashMap::new();
    section.insert(String::from("name"), String::from("combine"));
    section.insert(String::from("type"), String::from("LL(1)"));
    expected.sections.insert(String::from("section"), section);

    let result = parser(ini)
        .parse(text)
        .map(|t| t.0);
    assert_eq!(result, Ok(expected));
}

#[test]
fn ini_error() {
    let text = "[error";
    let result = parser(ini)
        .parse(State::new(text))
        .map(|t| t.0);
    assert_eq!(result,
               Err(ParseError {
                   position: SourcePosition {
                       line: 1,
                       column: 7,
                   },
                   errors: vec![
            Error::end_of_input(),
            Error::Expected("section".into()),
        ],
               }));
}
<commit_msg>tests/ini.rs: use message instead of expected<commit_after>//! Parser example for INI files.
extern crate combine;

use std::collections::HashMap;

use combine::*;
use combine::char::space;
use combine::primitives::{Error, SourcePosition};

#[derive(PartialEq, Debug)]
pub struct Ini {
    pub global: HashMap<String, String>,
    pub sections: HashMap<String, HashMap<String, String>>,
}

fn property<I>(input: I) -> ParseResult<(String, String), I>
    where I: Stream<Item = char>
{
    (many1(satisfy(|c| c != '=' && c != '[' && c != ';')),
     token('='),
     many1(satisfy(|c| c != '\n' && c != ';')))
        .map(|(key, _, value)| (key, value))
        .message("while parsing property")
        .parse_stream(input)
}

fn whitespace<I>(input: I) -> ParseResult<(), I>
    where I: Stream<Item = char>
{
    let comment = (token(';'), skip_many(satisfy(|c| c != '\n'))).map(|_| ());
    // Wrap the `spaces().or(comment)` in `skip_many` so that it skips alternating whitespace and
    // comments
    skip_many(skip_many1(space()).or(comment)).parse_stream(input)
}

fn properties<I>(input: I) -> ParseResult<HashMap<String, String>, I>
    where I: Stream<Item = char>
{
    // After each property we skip any whitespace that followed it
    many(parser(property).skip(parser(whitespace))).parse_stream(input)
}

fn section<I>(input: I) -> ParseResult<(String, HashMap<String, String>), I>
    where I: Stream<Item = char>
{
    (between(token('['), token(']'), many(satisfy(|c| c != ']'))),
     parser(whitespace),
     parser(properties))
        .map(|(name, _, properties)| (name, properties))
        .message("while parsing section")
        .parse_stream(input)
}

fn ini<I>(input: I) -> ParseResult<Ini, I>
    where I: Stream<Item = char>
{
    (parser(whitespace), parser(properties), many(parser(section)))
        .map(|(_, global, sections)| {
            Ini {
                global: global,
                sections: sections,
            }
        })
        .parse_stream(input)
}

#[test]
fn ini_ok() {
    let text = r#"
language=rust

[section]
name=combine; Comment
type=LL(1)

"#;
    let mut expected = Ini {
        global: HashMap::new(),
        sections: HashMap::new(),
    };
    expected.global.insert(String::from("language"), String::from("rust"));

    let mut section = HashMap::new();
    section.insert(String::from("name"), String::from("combine"));
    section.insert(String::from("type"), String::from("LL(1)"));
    expected.sections.insert(String::from("section"), section);

    let result = parser(ini)
        .parse(text)
        .map(|t| t.0);
    assert_eq!(result, Ok(expected));
}

#[test]
fn ini_error() {
    let text = "[error";
    let result = parser(ini)
        .parse(State::new(text))
        .map(|t| t.0);
    assert_eq!(result,
               Err(ParseError {
                   position: SourcePosition {
                       line: 1,
                       column: 7,
                   },
                   errors: vec![
            Error::end_of_input(),
            Error::Expected(']'.into()),
            Error::Message("while parsing section".into()),
        ],
               }));
}
<|endoftext|>


<commit_before>extern crate fitsio;
extern crate libc;

use libc::c_int;
use std::ffi;
use std::ptr;
use fitsio::raw::*;

#[test]
fn raw_opening_an_existing_file() {
    let mut fptr: *mut fitsfile = ptr::null_mut();
    let mut status: c_int = -1;
    let c_filename = ffi::CString::new("testdata/full_example.fits").unwrap();

    unsafe {
        ffopen(&mut fptr as *mut *mut fitsfile, c_filename.as_ptr(), 0, &mut status);
        ffclos(fptr, &mut status);
    }

    assert_eq!(status, 0);
}

#[test]
fn getting_current_hdu_number() {
    let mut fptr: *mut fitsfile = ptr::null_mut();
    let mut status: c_int = -1;
    let c_filename = ffi::CString::new("testdata/full_example.fits").unwrap();

    let mut hdu_num: c_int = -1;

    unsafe {
        ffopen(&mut fptr as *mut *mut fitsfile, c_filename.as_ptr(), 0, &mut status);
        ffghdn(fptr, &mut hdu_num);
        ffclos(fptr, &mut status);
    }

    assert_eq!(hdu_num, 1);
}

#[test]
fn changing_hdu_by_absolute_number() {
    let mut fptr: *mut fitsfile = ptr::null_mut();
    let mut status: c_int = -1;
    let c_filename = ffi::CString::new("testdata/full_example.fits").unwrap();

    let mut hdu_type: c_int = 0;
    let mut hdu_num: c_int = 0;

    unsafe {
        ffopen(&mut fptr as *mut *mut fitsfile, c_filename.as_ptr(), 0, &mut status);
        ffmahd(fptr, 2, &mut hdu_type, &mut status);
        ffghdn(fptr, &mut hdu_num);
        ffclos(fptr, &mut status);
    }

    assert_eq!(hdu_num, 2);
}
<commit_msg>Add test for creating file<commit_after>extern crate fitsio;
extern crate libc;
extern crate tempdir;

use libc::c_int;
use std::ffi;
use std::ptr;
use fitsio::raw::*;

#[test]
fn raw_opening_an_existing_file() {
    let mut fptr: *mut fitsfile = ptr::null_mut();
    let mut status: c_int = -1;
    let c_filename = ffi::CString::new("testdata/full_example.fits").unwrap();

    unsafe {
        ffopen(&mut fptr as *mut *mut fitsfile, c_filename.as_ptr(), 0, &mut status);
        ffclos(fptr, &mut status);
    }

    assert_eq!(status, 0);
}

#[test]
fn raw_creating_a_new_file() {
    // Set up the test filename
    let tdir = tempdir::TempDir::new("rust-fitsio-").unwrap();
    let filename = tdir.path().join("test.fits");
    assert!(!filename.exists());

    let mut fptr = ptr::null_mut();
    let mut status = 0;
    let c_filename = ffi::CString::new(filename.to_str().unwrap()).unwrap();

    unsafe {
        ffinit(&mut fptr as *mut *mut fitsfile,
               c_filename.as_ptr(),
               &mut status);
    }

    assert!(filename.exists());
}

#[test]
fn getting_current_hdu_number() {
    let mut fptr: *mut fitsfile = ptr::null_mut();
    let mut status: c_int = -1;
    let c_filename = ffi::CString::new("testdata/full_example.fits").unwrap();

    let mut hdu_num: c_int = -1;

    unsafe {
        ffopen(&mut fptr as *mut *mut fitsfile, c_filename.as_ptr(), 0, &mut status);
        ffghdn(fptr, &mut hdu_num);
        ffclos(fptr, &mut status);
    }

    assert_eq!(hdu_num, 1);
}

#[test]
fn changing_hdu_by_absolute_number() {
    let mut fptr: *mut fitsfile = ptr::null_mut();
    let mut status: c_int = -1;
    let c_filename = ffi::CString::new("testdata/full_example.fits").unwrap();

    let mut hdu_type: c_int = 0;
    let mut hdu_num: c_int = 0;

    unsafe {
        ffopen(&mut fptr as *mut *mut fitsfile, c_filename.as_ptr(), 0, &mut status);
        ffmahd(fptr, 2, &mut hdu_type, &mut status);
        ffghdn(fptr, &mut hdu_num);
        ffclos(fptr, &mut status);
    }

    assert_eq!(hdu_num, 2);
}
<|endoftext|>


<commit_before>extern crate sorting;

/// Verify order of input vector as sorted by indices.
///
/// # Details
///
/// This function takes as arguments a vector of data and a vector representing the indices of the
/// first vector making it sorted.
///
/// The elements of the sorted vector are compared to the next ones to make sure they are less
/// or equal.
///
/// # Panics
///
/// The sorting of the data vector is enforced using `assert!()`.
///
/// # Examples
///
/// ```
/// let data: Vec<i32> = vec![4, 2, 3, 1];
/// let sorted_indices: Vec<usize> = vec![3, 1, 2, 0];
/// verify_sorting(&data, &sorted_indices);
/// ```
///
fn verify_sorting<T: PartialOrd>(array: &Vec<T>, sorted_indices: &Vec<usize>) {
    let n = array.len();
    assert_eq!(n , sorted_indices.len());

    if !array.is_empty() {
        for i in 0..n-1 {
            assert!(array[sorted_indices[i]] <= array[sorted_indices[i+1]]);
        }
    }
}

/// Call the specified sorting function on an empty vector of specific type.
///
/// # Details
///
/// This function takes as arguments a pointer to a sorting function acting and call
/// it on an empty vector of type T. The call should succeed and the index vector should
/// be empty as well.
///
/// # Panics
///
/// The emptiness of the sorted list is enforced using `assert!()`.
///
/// # Examples
///
/// ```
/// test_empty_vec::<i8>(sorting::simplesorts::insertion::sort);
/// ```
///
fn test_empty_vec<T: PartialOrd>(sorting_fct: fn(&Vec<T>) -> Vec<usize>) {
    let to_sort: Vec<T> = vec![];
    let sorted_indices = sorting_fct(&to_sort);
    assert_eq!(sorted_indices, vec![]);
    assert!(sorted_indices.is_empty());
}

/// Call the specified sorting function on an specific vector of floats and validate the output.
///
/// # Details
///
/// This function takes as arguments:
///    1. An immutable vector of floats, to be sorted;
///    2. An immutable vector of indices as the reference to compare with;
///    3. A function pointer to be called on the first vector.
///
/// # Panics
///
/// This calls the function `verify_sorting()` which will assert if the result is not in order.
/// It also compares the resulting indices with expected values using asserts.
///
/// # Examples
///
/// ```
/// let to_sort: Vec<f32> = vec![6.0,   5.0,  3.0,  1.0,  2.4, 4.0, 10.0, 7.0,
///                              3.42, 32.2, 44.2, 56.3, 67.9, 3.2, 44.2, 2.0];
///
/// let known_sorted_indices = vec![3, 15, 4, 2, 13, 8, 5, 1, 0, 7, 6, 9, 10, 14, 11, 12];
///
/// test_sort_vec_float::<f32>(&to_sort, &known_sorted_indices,
///                            sorting::simplesorts::insertion::sort);
/// ```
///
fn test_sort_vec_float<T: PartialOrd>(to_sort: &Vec<T>, expected_indices: &Vec<usize>,
                                      sorting_fct: fn(&Vec<T>) -> Vec<usize>) {
    let sorted_indices = sorting_fct(&to_sort);

    verify_sorting(&to_sort, &sorted_indices);

    assert_eq!(sorted_indices.len(), expected_indices.len());

    for i in 0..to_sort.len() {
        assert_eq!(sorted_indices[i], expected_indices[i]);
    }
}

/// Validate against empty vector (i8).
#[test]
fn simple_insertion_empty_vec_i8() {
    test_empty_vec::<i8>(sorting::simplesorts::insertion::sort);
}
/// Validate against empty vector (i32).
#[test]
fn simple_insertion_empty_vec_i16() {
    test_empty_vec::<i16>(sorting::simplesorts::insertion::sort);
}
/// Validate against empty vector (i32).
#[test]
fn simple_insertion_empty_vec_i32() {
    test_empty_vec::<i32>(sorting::simplesorts::insertion::sort);
}
/// Validate against empty vector (i64).
#[test]
fn simple_insertion_empty_vec_i64() {
    test_empty_vec::<i64>(sorting::simplesorts::insertion::sort);
}

/// Validate against empty vector (u8).
#[test]
fn simple_insertion_empty_vec_u8() {
    test_empty_vec::<u8>(sorting::simplesorts::insertion::sort);
}
/// Validate against empty vector (u32).
#[test]
fn simple_insertion_empty_vec_u16() {
    test_empty_vec::<u16>(sorting::simplesorts::insertion::sort);
}
/// Validate against empty vector (u32).
#[test]
fn simple_insertion_empty_vec_u32() {
    test_empty_vec::<u32>(sorting::simplesorts::insertion::sort);
}
/// Validate against empty vector (u64).
#[test]
fn simple_insertion_empty_vec_u64() {
    test_empty_vec::<u64>(sorting::simplesorts::insertion::sort);
}

/// Validate sorting a vector of single precision values (f32).
#[test]
fn simple_insertion_vec_f32() {
    let to_sort: Vec<f32> = vec![6.0,   5.0,  3.0,  1.0,  2.4, 4.0, 10.0, 7.0,
                                 3.42, 32.2, 44.2, 56.3, 67.9, 3.2, 44.2, 2.0];

    let known_sorted_indices = vec![3, 15, 4, 2, 13, 8, 5, 1, 0, 7, 6, 9, 10, 14, 11, 12];

    test_sort_vec_float::<f32>(&to_sort, &known_sorted_indices,
                               sorting::simplesorts::insertion::sort);
}

/// Validate sorting a vector of double precision values (f64).
#[test]
fn simple_insertion_vec_f64() {
    let to_sort: Vec<f64> = vec![6.0,   5.0,  3.0,  1.0,  2.4, 4.0, 10.0, 7.0,
                                 3.42, 32.2, 44.2, 56.3, 67.9, 3.2, 44.2, 2.0];

    let known_sorted_indices = vec![3, 15, 4, 2, 13, 8, 5, 1, 0, 7, 6, 9, 10, 14, 11, 12];

    test_sort_vec_float::<f64>(&to_sort, &known_sorted_indices,
                               sorting::simplesorts::insertion::sort);
}
<commit_msg>Added tests for all integer types.<commit_after>extern crate sorting;

/// Verify order of input vector as sorted by indices.
///
/// # Details
///
/// This function takes as arguments a vector of data and a vector representing the indices of the
/// first vector making it sorted.
///
/// The elements of the sorted vector are compared to the next ones to make sure they are less
/// or equal.
///
/// # Panics
///
/// The sorting of the data vector is enforced using `assert!()`.
///
/// # Examples
///
/// ```
/// let data: Vec<i32> = vec![4, 2, 3, 1];
/// let sorted_indices: Vec<usize> = vec![3, 1, 2, 0];
/// verify_sorting(&data, &sorted_indices);
/// ```
///
fn verify_sorting<T: PartialOrd>(array: &Vec<T>, sorted_indices: &Vec<usize>) {
    let n = array.len();
    assert_eq!(n , sorted_indices.len());

    if !array.is_empty() {
        for i in 0..n-1 {
            assert!(array[sorted_indices[i]] <= array[sorted_indices[i+1]]);
        }
    }
}

/// Call the specified sorting function on an empty vector of specific type.
///
/// # Details
///
/// This function takes as arguments a pointer to a sorting function acting and call
/// it on an empty vector of type T. The call should succeed and the index vector should
/// be empty as well.
///
/// # Panics
///
/// The emptiness of the sorted list is enforced using `assert!()`.
///
/// # Examples
///
/// ```
/// test_empty_vec::<i8>(sorting::simplesorts::insertion::sort);
/// ```
///
fn test_empty_vec<T: PartialOrd>(sorting_fct: fn(&Vec<T>) -> Vec<usize>) {
    let to_sort: Vec<T> = vec![];
    let sorted_indices = sorting_fct(&to_sort);
    assert_eq!(sorted_indices, vec![]);
    assert!(sorted_indices.is_empty());
}

/// Call the specified sorting function on an specific vector of floats and validate the output.
///
/// # Details
///
/// This function takes as arguments:
///    1. An immutable vector of floats, to be sorted;
///    2. An immutable vector of indices as the reference to compare with;
///    3. A function pointer to be called on the first vector.
///
/// # Panics
///
/// This calls the function `verify_sorting()` which will assert if the result is not in order.
/// It also compares the resulting indices with expected values using asserts.
///
/// # Examples
///
/// ```
/// let to_sort: Vec<f32> = vec![6.0,   5.0,  3.0,  1.0,  2.4, 4.0, 10.0, 7.0,
///                              3.42, 32.2, 44.2, 56.3, 67.9, 3.2, 44.2, 2.0];
///
/// let known_sorted_indices = vec![3, 15, 4, 2, 13, 8, 5, 1, 0, 7, 6, 9, 10, 14, 11, 12];
///
/// test_sort_vec_float::<f32>(&to_sort, &known_sorted_indices,
///                            sorting::simplesorts::insertion::sort);
/// ```
///
fn test_sort_vec_float<T: PartialOrd>(to_sort: &Vec<T>, expected_indices: &Vec<usize>,
                                      sorting_fct: fn(&Vec<T>) -> Vec<usize>) {
    let sorted_indices = sorting_fct(&to_sort);

    verify_sorting(&to_sort, &sorted_indices);

    assert_eq!(sorted_indices.len(), expected_indices.len());

    for i in 0..to_sort.len() {
        assert_eq!(sorted_indices[i], expected_indices[i]);
    }
}

/// Validate against empty vector (i8).
#[test]
fn simple_insertion_empty_vec_i8() {
    test_empty_vec::<i8>(sorting::simplesorts::insertion::sort);
}
/// Validate against empty vector (i32).
#[test]
fn simple_insertion_empty_vec_i16() {
    test_empty_vec::<i16>(sorting::simplesorts::insertion::sort);
}
/// Validate against empty vector (i32).
#[test]
fn simple_insertion_empty_vec_i32() {
    test_empty_vec::<i32>(sorting::simplesorts::insertion::sort);
}
/// Validate against empty vector (i64).
#[test]
fn simple_insertion_empty_vec_i64() {
    test_empty_vec::<i64>(sorting::simplesorts::insertion::sort);
}

/// Validate against empty vector (u8).
#[test]
fn simple_insertion_empty_vec_u8() {
    test_empty_vec::<u8>(sorting::simplesorts::insertion::sort);
}
/// Validate against empty vector (u32).
#[test]
fn simple_insertion_empty_vec_u16() {
    test_empty_vec::<u16>(sorting::simplesorts::insertion::sort);
}
/// Validate against empty vector (u32).
#[test]
fn simple_insertion_empty_vec_u32() {
    test_empty_vec::<u32>(sorting::simplesorts::insertion::sort);
}
/// Validate against empty vector (u64).
#[test]
fn simple_insertion_empty_vec_u64() {
    test_empty_vec::<u64>(sorting::simplesorts::insertion::sort);
}

/// Validate against empty vector (isize).
#[test]
fn simple_insertion_empty_vec_isize() {
    test_empty_vec::<isize>(sorting::simplesorts::insertion::sort);
}
/// Validate against empty vector (usize).
#[test]
fn simple_insertion_empty_vec_usize() {
    test_empty_vec::<usize>(sorting::simplesorts::insertion::sort);
}

/// Validate against empty vector (f32).
#[test]
fn simple_insertion_empty_vec_f32() {
    test_empty_vec::<f32>(sorting::simplesorts::insertion::sort);
}
/// Validate against empty vector (f64).
#[test]
fn simple_insertion_empty_vec_f64() {
    test_empty_vec::<f64>(sorting::simplesorts::insertion::sort);
}

/// Validate sorting a vector of single precision values (i8).
#[test]
fn simple_insertion_vec_i8() {
    let to_sort: Vec<i8> = vec![6,  5,  3,  1,  2, 4, 10, 7,
                                3, 32, 44, 56, 67, 3, 44, 2];

    let known_sorted_indices = vec![3, 4, 15, 2, 8, 13, 5, 1, 0, 7, 6, 9, 10, 14, 11, 12];

    test_sort_vec_float::<i8>(&to_sort, &known_sorted_indices,
                               sorting::simplesorts::insertion::sort);
}
/// Validate sorting a vector of single precision values (i16).
#[test]
fn simple_insertion_vec_i16() {
    let to_sort: Vec<i16> = vec![6,  5,  3,  1,  2, 4, 10, 7,
                                 3, 32, 44, 56, 67, 3, 44, 2];

    let known_sorted_indices = vec![3, 4, 15, 2, 8, 13, 5, 1, 0, 7, 6, 9, 10, 14, 11, 12];

    test_sort_vec_float::<i16>(&to_sort, &known_sorted_indices,
                               sorting::simplesorts::insertion::sort);
}
/// Validate sorting a vector of single precision values (i32).
#[test]
fn simple_insertion_vec_i32() {
    let to_sort: Vec<i32> = vec![6,  5,  3,  1,  2, 4, 10, 7,
                                 3, 32, 44, 56, 67, 3, 44, 2];

    let known_sorted_indices = vec![3, 4, 15, 2, 8, 13, 5, 1, 0, 7, 6, 9, 10, 14, 11, 12];

    test_sort_vec_float::<i32>(&to_sort, &known_sorted_indices,
                               sorting::simplesorts::insertion::sort);
}
/// Validate sorting a vector of single precision values (i64).
#[test]
fn simple_insertion_vec_i64() {
    let to_sort: Vec<i64> = vec![6,  5,  3,  1,  2, 4, 10, 7,
                                 3, 32, 44, 56, 67, 3, 44, 2];

    let known_sorted_indices = vec![3, 4, 15, 2, 8, 13, 5, 1, 0, 7, 6, 9, 10, 14, 11, 12];

    test_sort_vec_float::<i64>(&to_sort, &known_sorted_indices,
                               sorting::simplesorts::insertion::sort);
}

/// Validate sorting a vector of single precision values (u8).
#[test]
fn simple_insertion_vec_u8() {
    let to_sort: Vec<u8> = vec![6,  5,  3,  1,  2, 4, 10, 7,
                                3, 32, 44, 56, 67, 3, 44, 2];

    let known_sorted_indices = vec![3, 4, 15, 2, 8, 13, 5, 1, 0, 7, 6, 9, 10, 14, 11, 12];

    test_sort_vec_float::<u8>(&to_sort, &known_sorted_indices,
                               sorting::simplesorts::insertion::sort);
}
/// Validate sorting a vector of single precision values (u16).
#[test]
fn simple_insertion_vec_u16() {
    let to_sort: Vec<u16> = vec![6,  5,  3,  1,  2, 4, 10, 7,
                                 3, 32, 44, 56, 67, 3, 44, 2];

    let known_sorted_indices = vec![3, 4, 15, 2, 8, 13, 5, 1, 0, 7, 6, 9, 10, 14, 11, 12];

    test_sort_vec_float::<u16>(&to_sort, &known_sorted_indices,
                               sorting::simplesorts::insertion::sort);
}
/// Validate sorting a vector of single precision values (u32).
#[test]
fn simple_insertion_vec_u32() {
    let to_sort: Vec<u32> = vec![6,  5,  3,  1,  2, 4, 10, 7,
                                 3, 32, 44, 56, 67, 3, 44, 2];

    let known_sorted_indices = vec![3, 4, 15, 2, 8, 13, 5, 1, 0, 7, 6, 9, 10, 14, 11, 12];

    test_sort_vec_float::<u32>(&to_sort, &known_sorted_indices,
                               sorting::simplesorts::insertion::sort);
}
/// Validate sorting a vector of single precision values (u64).
#[test]
fn simple_insertion_vec_u64() {
    let to_sort: Vec<u64> = vec![6,  5,  3,  1,  2, 4, 10, 7,
                                 3, 32, 44, 56, 67, 3, 44, 2];

    let known_sorted_indices = vec![3, 4, 15, 2, 8, 13, 5, 1, 0, 7, 6, 9, 10, 14, 11, 12];

    test_sort_vec_float::<u64>(&to_sort, &known_sorted_indices,
                               sorting::simplesorts::insertion::sort);
}

/// Validate sorting a vector of single precision values (f32).
#[test]
fn simple_insertion_vec_f32() {
    let to_sort: Vec<f32> = vec![6.0,   5.0,  3.0,  1.0,  2.4, 4.0, 10.0, 7.0,
                                 3.42, 32.2, 44.2, 56.3, 67.9, 3.2, 44.2, 2.0];

    let known_sorted_indices = vec![3, 15, 4, 2, 13, 8, 5, 1, 0, 7, 6, 9, 10, 14, 11, 12];

    test_sort_vec_float::<f32>(&to_sort, &known_sorted_indices,
                               sorting::simplesorts::insertion::sort);
}

/// Validate sorting a vector of double precision values (f64).
#[test]
fn simple_insertion_vec_f64() {
    let to_sort: Vec<f64> = vec![6.0,   5.0,  3.0,  1.0,  2.4, 4.0, 10.0, 7.0,
                                 3.42, 32.2, 44.2, 56.3, 67.9, 3.2, 44.2, 2.0];

    let known_sorted_indices = vec![3, 15, 4, 2, 13, 8, 5, 1, 0, 7, 6, 9, 10, 14, 11, 12];

    test_sort_vec_float::<f64>(&to_sort, &known_sorted_indices,
                               sorting::simplesorts::insertion::sort);
}
<|endoftext|>


<commit_before>use crate::utils::get_test_path;
use cargo_tarpaulin::config::{Config, RunType};
use cargo_tarpaulin::launch_tarpaulin;
use std::env;
use std::time::Duration;

mod compile_fail;
mod doc_coverage;
mod line_coverage;
mod test_types;
mod utils;

pub fn check_percentage_with_config(
    project_name: &str,
    minimum_coverage: f64,
    has_lines: bool,
    mut config: Config,
) {
    config.verbose = true;
    config.test_timeout = Duration::from_secs(60);
    let restore_dir = env::current_dir().unwrap();
    let test_dir = get_test_path(project_name);
    env::set_current_dir(&test_dir).unwrap();
    config.manifest = test_dir;
    config.manifest.push("Cargo.toml");

    let (res, _) = launch_tarpaulin(&config).unwrap();

    env::set_current_dir(restore_dir).unwrap();
    assert!(res.coverage_percentage() >= minimum_coverage);
    if has_lines {
        assert!(res.total_coverable() > 0);
    }
}

pub fn check_percentage(project_name: &str, minimum_coverage: f64, has_lines: bool) {
    let config = Config::default();
    check_percentage_with_config(project_name, minimum_coverage, has_lines, config);
}

#[test]
fn incorrect_manifest_path() {
    let mut config = Config::default();
    config.manifest.push("__invalid_dir__");
    assert!(launch_tarpaulin(&config).is_err());
}

#[test]
fn proc_macro_link() {
    let mut config = Config::default();
    config.test_timeout = Duration::from_secs(60);
    let test_dir = get_test_path("proc_macro");
    config.manifest = test_dir.join("Cargo.toml");
    assert!(launch_tarpaulin(&config).is_ok());
}

#[test]
fn array_coverage() {
    check_percentage("arrays", 1.0f64, true);
}

#[test]
fn lets_coverage() {
    check_percentage("lets", 1.0f64, true);
}

#[test]
fn struct_expr_coverage() {
    check_percentage("structs", 1.0f64, true);
}

#[test]
fn ifelse_expr_coverage() {
    check_percentage("ifelse", 1.0f64, true);
}

#[test]
fn returns_expr_coverage() {
    check_percentage("returns", 1.0f64, true);
}

#[test]
fn loops_expr_coverage() {
    check_percentage("loops", 1.0f64, true);
}

#[test]
fn loops_assigns_coverage() {
    check_percentage("assigns", 1.0f64, true);
}

#[test]
fn paths_coverage() {
    check_percentage("paths", 1.0f64, true);
}

#[test]
fn futures_coverage() {
    check_percentage("futures", 1.0f64, true);
}

#[test]
fn breaks_expr_coverage() {
    check_percentage("breaks", 1.0f64, true);
}

#[test]
fn continues_expr_coverage() {
    check_percentage("continues", 1.0f64, true);
}

#[test]
fn boxes_coverage() {
    check_percentage("boxes", 1.0f64, true);
}

#[test]
fn method_calls_expr_coverage() {
    check_percentage("method_calls", 1.0f64, true);
}

#[test]
fn benchmark_coverage() {
    let test = "benchmark_coverage";
    check_percentage(test, 0.0f64, true);

    let mut config = Config::default();
    config.run_types = vec![RunType::Benchmarks];
    check_percentage_with_config(test, 1.0f64, true, config);
}

#[test]
fn examples_coverage() {
    let test = "example_test";
    check_percentage(test, 0.0f64, true);

    let mut config = Config::default();
    config.run_types = vec![RunType::Examples];
    check_percentage_with_config(test, 1.0f64, true, config);
}
<commit_msg>Reignore benchmark coverage for stable/beta<commit_after>use crate::utils::get_test_path;
use cargo_tarpaulin::config::{Config, RunType};
use cargo_tarpaulin::launch_tarpaulin;
use std::env;
use std::time::Duration;

mod compile_fail;
mod doc_coverage;
mod line_coverage;
mod test_types;
mod utils;

pub fn check_percentage_with_config(
    project_name: &str,
    minimum_coverage: f64,
    has_lines: bool,
    mut config: Config,
) {
    config.verbose = true;
    config.test_timeout = Duration::from_secs(60);
    let restore_dir = env::current_dir().unwrap();
    let test_dir = get_test_path(project_name);
    env::set_current_dir(&test_dir).unwrap();
    config.manifest = test_dir;
    config.manifest.push("Cargo.toml");

    let (res, _) = launch_tarpaulin(&config).unwrap();

    env::set_current_dir(restore_dir).unwrap();
    assert!(res.coverage_percentage() >= minimum_coverage);
    if has_lines {
        assert!(res.total_coverable() > 0);
    }
}

pub fn check_percentage(project_name: &str, minimum_coverage: f64, has_lines: bool) {
    let config = Config::default();
    check_percentage_with_config(project_name, minimum_coverage, has_lines, config);
}

#[test]
fn incorrect_manifest_path() {
    let mut config = Config::default();
    config.manifest.push("__invalid_dir__");
    assert!(launch_tarpaulin(&config).is_err());
}

#[test]
fn proc_macro_link() {
    let mut config = Config::default();
    config.test_timeout = Duration::from_secs(60);
    let test_dir = get_test_path("proc_macro");
    config.manifest = test_dir.join("Cargo.toml");
    assert!(launch_tarpaulin(&config).is_ok());
}

#[test]
fn array_coverage() {
    check_percentage("arrays", 1.0f64, true);
}

#[test]
fn lets_coverage() {
    check_percentage("lets", 1.0f64, true);
}

#[test]
fn struct_expr_coverage() {
    check_percentage("structs", 1.0f64, true);
}

#[test]
fn ifelse_expr_coverage() {
    check_percentage("ifelse", 1.0f64, true);
}

#[test]
fn returns_expr_coverage() {
    check_percentage("returns", 1.0f64, true);
}

#[test]
fn loops_expr_coverage() {
    check_percentage("loops", 1.0f64, true);
}

#[test]
fn loops_assigns_coverage() {
    check_percentage("assigns", 1.0f64, true);
}

#[test]
fn paths_coverage() {
    check_percentage("paths", 1.0f64, true);
}

#[test]
fn futures_coverage() {
    check_percentage("futures", 1.0f64, true);
}

#[test]
fn breaks_expr_coverage() {
    check_percentage("breaks", 1.0f64, true);
}

#[test]
fn continues_expr_coverage() {
    check_percentage("continues", 1.0f64, true);
}

#[test]
fn boxes_coverage() {
    check_percentage("boxes", 1.0f64, true);
}

#[test]
fn method_calls_expr_coverage() {
    check_percentage("method_calls", 1.0f64, true);
}

#[test]
#[ignore]
fn benchmark_coverage() {
    let test = "benchmark_coverage";
    check_percentage(test, 0.0f64, true);

    let mut config = Config::default();
    config.run_types = vec![RunType::Benchmarks];
    check_percentage_with_config(test, 1.0f64, true, config);
}

#[test]
fn examples_coverage() {
    let test = "example_test";
    check_percentage(test, 0.0f64, true);

    let mut config = Config::default();
    config.run_types = vec![RunType::Examples];
    check_percentage_with_config(test, 1.0f64, true, config);
}
<|endoftext|>